home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -seriously_amiga- / misc / twged_scanner / source / sql-create.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-27  |  9.6 KB  |  304 lines

  1. ;/* execute me to compile with SAS/C
  2. ;SC SQL-CREATE.c IGNORE 73 DEBUG=SYMBOLFLUSH STRINGMERGE NOSTKCHK LINK
  3. SC SQL-CREATE.c IGNORE 73 CPU=68020 OPT OPTTIME STRINGMERGE NOSTKCHK
  4. SLink FROM SQL-CREATE.o TO SQL-CREATE SC SD STRIPDEBUG NOICONS
  5. Delete SQL-CREATE.(o|lnk) QUIET
  6. QUIT
  7. */
  8. /**************************************************************************
  9.  
  10. SQL-CREATE.c  --  GoldED4-Scanner für SQL CREATE-Anweisungen
  11.  
  12. AUTOR(EN):        Thies Wellpott
  13. ERSTELLUNG:       15.04.1998
  14. COPYRIGHT:        (c) 1998 Thies Wellpott
  15. BETRIEBSSYSTEM:   AmigaOS
  16. COMPILER:         SAS/C 6.58
  17.  
  18. BESCHREIBUNG:
  19.  
  20. Scanner für GoldED Version 4.
  21. Übergabeparameter:
  22. - ULONG len       Länge der aktuellen Textzeile
  23. - STRPTR *text    Zeiger auf aktuelle Textzeile
  24. - ULONG *line     Zeiger auf aktuelle Zeilennummer
  25. Rückgabewerte:
  26. - ULONG return    Länge des gescannten Textes oder 0 für keinen Text
  27. - STRPTR *text    Zeiger auf Text
  28.  
  29. Sucht SQL-CREATE-Anweisungen. Leerzeichen am Zeilenanfang werden ignoriert,
  30. ein "OR REPLACE" (für Trigger, Prozeduren und Packages), "UNIQUE" (für
  31. INDEX), "PUBLIC" (für SYNONYM, ROLLBACK SEGMENT, u. a.), "FORCE" oder
  32. "NOFORCE" (für VIEW) nach dem "CREATE" ebenfalls. Die Groß-/Kleinschreibung
  33. ist egal. Das Wort nach "CREATE [OR REPLACE] [UNIQUE|PUBLIC|[NO]FORCE]"
  34. wird als Objekttyp angesehen, von dem die ersten vier Zeichen als erste
  35. Spalte mitausgegeben werden.
  36.  
  37. Normalerweise werden nur einwortige Objekttypen akzeptiert, behandelte
  38. Ausnahmen sind "PACKAGE [BODY]", "ROLLBACK SEGM[ENT]", "SNAPSHOT [LOG ON]",
  39. "DATABASE LINK" und "SCHEMA AUTH[ORIZATION]". Der Objekttypkürzel wird
  40. jeweils entsprechend angepaßt (z. B. wird aus "PACK" für eine Package
  41. "PABO" für Package Body).
  42.  
  43. Das dann folgende Wort ist der Objektname. Alle aufeinanderfolgenden
  44. SQL-Symbol-Zeichen (A-Z, a-z, 0-9, _, $, #, .) werden als Name angesehen.
  45.  
  46.  
  47.  
  48. FEHLER/EINSCHRÄNKUNGEN:
  49.  
  50. - Kommentare werden nicht berücksichtigt
  51. - die Maximallänge eines gescannten Textes beträgt 60 Zeichen (wird intern
  52.   überprüft und abgefangen)
  53.  
  54.  
  55. ENTWICKLUNGSGESCHICHTE:
  56.  
  57. V1.000   15.04.1998   Thies Wellpott
  58. - erste Version
  59.  
  60. V1.001   16.04.1998   Thies Wellpott
  61. - spezielle Präfixe (PUBLIC, UNIQUE, etc.) und mehrwortige Objekttypen
  62.   werden jetzt abgefangen
  63.  
  64. **************************************************************************/
  65.  
  66. #include "twscanner.h"
  67.  
  68.  
  69.  
  70. ULONG __asm golded_scanner(register __d0 ULONG len, register __a0 STRPTR *text,
  71.       register __a1 ULONG *line)
  72. {
  73.    const char *version = "\0$VER: SQL-CREATE 1.1 " __AMIGADATE__;
  74.    // Stringkonstante (in Code-Hunk) als Puffer mißbrauchen
  75.    STRPTR puffer = "123456789012345678901234567890123456789012345678901234567890";
  76. #define PUFFERLAENGE  60
  77.    STRPTR zeichen = *text;
  78.  
  79.    // führende Leerzeichen ignorieren
  80.    SKIPBLANKS(zeichen, len);
  81.  
  82.    // Minimaltext ist: "CREATE T x" (T für Typ, x für Bezeichner);
  83.    // Leerzeichen nach "CREATE" nicht testen, falls es vergessen wurde
  84.    if ( (len >= 10) && (STRICMP4(zeichen, 'C', 'R', 'E', 'A') && STRICMP2(zeichen, 'T', 'E')) )
  85.    {
  86.       UWORD laenge;                 // UWORD reicht für Länge, ULONG braucht nicht
  87.  
  88.       len -= 6;                     // "CREATE" ist schon übersprungen worden
  89.       SKIPBLANKS(zeichen, len);
  90.  
  91.       // evt. "OR REPLACE" überspringen; prüfe, ob "OR " vorhanden;
  92.       // Minimaltext "OR REPLACE T x"
  93.       if ( (len >= 14) && IPSTRICMP2(zeichen, 'O', 'R') && ISBLANK(zeichen[2]) )
  94.       {
  95.          zeichen += 3;
  96.          len -= 3;
  97.          SKIPBLANKS(zeichen, len);
  98.          // das nächste Wort (müßte "REPLACE" sein) überspringen
  99.          while ( len && ISALPHA(*zeichen) )
  100.          {
  101.             zeichen++;
  102.             len--;
  103.          } // while
  104.       } // if
  105.  
  106.       // evt. "PUBLIC " überspringen; Minimaltext "PUBLIC T x"
  107.       if ( (len >= 10) && IPSTRICMP4(zeichen, 'P', 'U', 'B', 'L') &&
  108.            IPSTRICMP2(zeichen + 4, 'I', 'C') && ISBLANK(zeichen[6]) )
  109.       {
  110.          zeichen += 7;
  111.          len -= 7;
  112.       } // if
  113.       // oder evt. "UNIQUE " überspringen; Minimaltext "UNIQUE T x"
  114.       else if ( (len >= 10) && IPSTRICMP4(zeichen, 'U', 'N', 'I', 'Q') &&
  115.                 IPSTRICMP2(zeichen + 4, 'U', 'E') && ISBLANK(zeichen[6]) )
  116.       {
  117.          zeichen += 7;
  118.          len -= 7;
  119.       } // else if
  120.       // oder evt. "NOFORCE " überspringen; Minimaltext "NOFORCE T x"
  121.       else if ( (len >= 11) && IPSTRICMP4(zeichen, 'N', 'O', 'F', 'O') &&
  122.                 IPSTRICMP3(zeichen + 4, 'R', 'C', 'E') && ISBLANK(zeichen[7]) )
  123.       {
  124.          zeichen += 8;
  125.          len -= 8;
  126.       } // else if
  127.       // oder evt. "FORCE " überspringen; Minimaltext "FORCE T x"
  128.       else if ( (len >= 10) && IPSTRICMP4(zeichen, 'F', 'O', 'R', 'C') &&
  129.                 (UPPER(zeichen[4]) == 'E') && ISBLANK(zeichen[5]) )
  130.       {
  131.          zeichen += 6;
  132.          len -= 6;
  133.       } // else if
  134.  
  135.       SKIPBLANKS(zeichen, len);
  136.       // "zeichen" steht jetzt auf Beginn des Objekttyps
  137.  
  138.       *text = puffer;
  139.       laenge = 0;
  140.  
  141.       // max. erste vier Zeichen des Objekttyps kopieren
  142.       while ( len && (laenge < 4) && ISALPHA(*zeichen) )
  143.       {
  144.          *puffer++ = UPPER(*zeichen++);
  145.          laenge++;
  146.          len--;
  147.       } // while
  148.  
  149.       if (laenge == 0)        // wohl kein Typ angegeben
  150.          return 0;
  151.  
  152.       // restliche Zeichen des Objekttyps überspringen
  153.       while ( len && ISALPHA(*zeichen) )
  154.       {
  155.          zeichen++;
  156.          len--;
  157.       } // while
  158.       SKIPBLANKS(zeichen, len);
  159.       // "zeichen" steht jetzt auf zweitem Objekttypwort oder Objektname
  160.  
  161.       // Sonderfälle von mehrwortigen Typen abfangen; Minimaltext "WORT x" (bei
  162.       // allen möglichen folgenden Wörter sind mind. 4 Buchstaben vorhanden)
  163.       if ( (laenge == 4) && (len >= 6) )
  164.       {
  165.          BOOL skip_alpha = FALSE;   // müssen am Ende nach Buchstaben übersprungen werden?
  166.  
  167.          // prüfe "PACKAGE BODY", mache aus Kürzel "PACK" "PABO"
  168.          if ( IPSTRICMP4(puffer - 4, 'P', 'A', 'C', 'K') &&
  169.               IPSTRICMP4(zeichen, 'B', 'O', 'D', 'Y') && ISBLANK(zeichen[4]) )
  170.          {
  171.             puffer[-2] = 'B';
  172.             puffer[-1] = 'O';
  173.             zeichen += 5;
  174.             len -= 5;
  175.          } // if
  176.          // prüfe "ROLLBACK SEGMENT", mache aus Kürzel "ROLL" "ROBS"
  177.          else if ( IPSTRICMP4(puffer - 4, 'R', 'O', 'L', 'L') &&
  178.                    IPSTRICMP4(zeichen, 'S', 'E', 'G', 'M') )
  179.          {
  180.             puffer[-2] = 'B';
  181.             puffer[-1] = 'S';
  182.             zeichen += 4;
  183.             len -= 4;
  184.             skip_alpha = TRUE;
  185.          } // else if
  186.          // prüfe "SNAPSHOT LOG ON", mache aus Kürzel "SNAP" "SNLO"
  187.          else if ( IPSTRICMP4(puffer - 4, 'S', 'N', 'A', 'P') &&
  188.                    IPSTRICMP3(zeichen, 'L', 'O', 'G') && ISBLANK(zeichen[3]) )
  189.          {
  190.             puffer[-2] = 'L';
  191.             puffer[-1] = 'O';
  192.             zeichen += 4;
  193.             len -= 4;
  194.             SKIPBLANKS(zeichen, len);     // Leerzeichen bis "ON" überspringen
  195.             skip_alpha = TRUE;
  196.          } // else if
  197.          // prüfe "DATABASE LINK", mache aus Kürzel "DATA" "DABL"
  198.          else if ( IPSTRICMP4(puffer - 4, 'D', 'A', 'T', 'A') &&
  199.                    IPSTRICMP4(zeichen, 'L', 'I', 'N', 'K') && ISBLANK(zeichen[4]) )
  200.          {
  201.             puffer[-2] = 'B';
  202.             puffer[-1] = 'L';
  203.             zeichen += 5;
  204.             len -= 5;
  205.          } // if
  206.          // prüfe "SCHEMA AUTOHORIZATION", mache aus Kürzel "SCHE" "SCAU"
  207.          else if ( IPSTRICMP4(puffer - 4, 'S', 'C', 'H', 'E') &&
  208.                    IPSTRICMP4(zeichen, 'A', 'U', 'T', 'H') )
  209.          {
  210.             puffer[-2] = 'A';
  211.             puffer[-1] = 'U';
  212.             zeichen += 4;
  213.             len -= 4;
  214.             skip_alpha = TRUE;
  215.          } // else if
  216.  
  217.          // wenn erforderlich, restliche Zeichen des Objekttyps überspringen
  218.          if (skip_alpha)
  219.          {
  220.             while ( len && ISALPHA(*zeichen) )
  221.             {
  222.                zeichen++;
  223.                len--;
  224.             } // while
  225.          } // if
  226.          SKIPBLANKS(zeichen, len);
  227.       } // if
  228.  
  229.       // "zeichen" steht jetzt auf Objektname
  230.  
  231.       // Objekttypkürzel mit Leerzeichen auffüllen bis insgesamt 5 Zeichen
  232.       // geschrieben wurden
  233.       do
  234.       {
  235.          *puffer++ = ' ';
  236.          laenge++;
  237.       } while (laenge < 5);
  238.  
  239.       if (!ISSQLSYM(*zeichen))      // Name beginnt nicht mit gültigem Zeichen?
  240.          return 0;
  241.  
  242.       // Objektname kopieren
  243.       while ( len && (laenge < PUFFERLAENGE) && ISSQLSYM(*zeichen) )
  244.       {
  245.          *puffer++ = *zeichen++;
  246.          laenge++;
  247.          len--;
  248.       } // while
  249.  
  250.       return (ULONG)laenge;
  251.    } // if
  252.  
  253.    return 0;
  254. } // golded_scanner()
  255.  
  256.  
  257.  
  258. /**
  259. #include <string.h>
  260.  
  261. int main(int argc, char *argv[])
  262. {
  263.    char text[128], *erg, laenge;
  264.    
  265.    strcpy(text, "crEATe table hummel");
  266.    erg = text;
  267.    laenge = golded_scanner(strlen(text), &erg, 0);
  268.    erg[laenge] = 0;
  269.  
  270.    strcpy(text, "CREATE SEQUENCE Seq_Bereich MAXVALUE 999999 CYCLE;");
  271.    erg = text;
  272.    laenge = golded_scanner(strlen(text), &erg, 0);
  273.    erg[laenge] = 0;
  274.  
  275.    strcpy(text, "  CREATE     TABLE        Benutzergruppe_enthaltene_Bgrp$#%&");
  276.    erg = text;
  277.    laenge = golded_scanner(strlen(text), &erg, 0);
  278.    erg[laenge] = 0;
  279.  
  280.    strcpy(text, "    CREATE  uniQUe  INDEX Bgrp_enth_Bgrp_Benutzergruppe ON");
  281.    erg = text;
  282.    laenge = golded_scanner(strlen(text), &erg, 0);
  283.    erg[laenge] = 0;
  284.  
  285.    strcpy(text, "CreATE  snapshot  log   on   asb_Benutzer;");
  286.    erg = text;
  287.    laenge = golded_scanner(strlen(text), &erg, 0);
  288.    erg[laenge] = 0;
  289.  
  290.    strcpy(text, "CREATE USER asb_ODBC_Abwesenheit IDENTIFIED BY asb_ODBC_Abwesenheit");
  291.    erg = text;
  292.    laenge = golded_scanner(strlen(text), &erg, 0);
  293.    erg[laenge] = 0;
  294.  
  295.    strcpy(text, "CREATE OR REPLACE PROCEDURE asb.Exec_DDL(string VARCHAR2) AS");
  296.    erg = text;
  297.    laenge = golded_scanner(strlen(text), &erg, 0);
  298.    erg[laenge] = 0;
  299.  
  300.    return 0;
  301. } // main()
  302. **/
  303.  
  304.