home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume24 / mkid2 / part02 / scan-text.c < prev    next >
C/C++ Source or Header  |  1991-10-09  |  4KB  |  187 lines

  1. /* Copyright (c) 1986, Greg McGary */
  2. /* Assembler scanner hacked into a Text scanner by Tom Horsley 1988 */
  3.  
  4. #include    <bool.h>
  5. #include    <stdio.h>
  6. #include    <string.h>
  7. #include    <ctype.h>
  8. #include    <id.h>
  9.  
  10. char *getTextId();
  11. void setTextArgs();
  12.  
  13. static void clrCtype();
  14. static void setCtype();
  15.  
  16. #define    I1    0x01    /* 1st char of an identifier [a-zA-Z_] */
  17. #define    NM    0x02    /* digit [0-9a-fA-FxX] */
  18. #define SQ    0x04    /* squeeze these out (.,',-) */
  19. #define    EF    0x80    /* EOF */
  20.  
  21. /* Text character classes */
  22. #define    ISID1ST(c)    ((rct)[c]&(I1))
  23. #define    ISIDREST(c)    ((rct)[c]&(I1|NM|SQ))
  24. #define    ISNUMBER(c)    ((rct)[c]&(NM))
  25. #define    ISEOF(c)    ((rct)[c]&(EF))
  26. #define    ISBORING(c)    (!((rct)[c]&(I1|NM|EF)))
  27. #define ISIDSQUEEZE(c)    ((rct)[c]&(SQ))
  28.  
  29. static char idctype[] = {
  30.  
  31.     EF,
  32.  
  33.     /*      0       1       2       3       4       5       6       7   */
  34.     /*    -----   -----   -----   -----   -----   -----   -----   ----- */
  35.  
  36.     /*000*/    0,    0,    0,    0,    0,    0,    0,    0,
  37.     /*010*/    0,    0,    0,    0,    0,    0,    0,    0,
  38.     /*020*/    0,    0,    0,    0,    0,    0,    0,    0,
  39.     /*030*/    0,    0,    0,    0,    0,    0,    0,    0,
  40.     /*040*/    0,    0,    0,    0,    0,    0,    0,    SQ,
  41.     /*050*/    0,    0,    0,    0,    0,    SQ,    SQ,    0,
  42.     /*060*/    NM,    NM,    NM,    NM,    NM,    NM,    NM,    NM,    
  43.     /*070*/    NM,    NM,    0,    0,    0,    0,    0,    0,
  44.     /*100*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  45.     /*110*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  46.     /*120*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  47.     /*130*/    I1|NM,    I1,    I1,    0,    0,    0,    0,    I1,
  48.     /*140*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  49.     /*150*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  50.     /*160*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  51.     /*170*/    I1|NM,    I1,    I1,    0,    0,    0,    0,    0,
  52.  
  53.     /*200*/    0,    0,    0,    0,    0,    0,    0,    0,
  54.     /*210*/    0,    0,    0,    0,    0,    0,    0,    0,
  55.     /*220*/    0,    0,    0,    0,    0,    0,    0,    0,
  56.     /*230*/    0,    0,    0,    0,    0,    0,    0,    0,
  57.     /*240*/    0,    0,    0,    0,    0,    0,    0,    0,
  58.     /*250*/    0,    0,    0,    0,    0,    0,    0,    0,
  59.     /*260*/    0,    0,    0,    0,    0,    0,    0,    0,
  60.     /*270*/    0,    0,    0,    0,    0,    0,    0,    0,
  61.     /*300*/    0,    0,    0,    0,    0,    0,    0,    0,
  62.     /*310*/    0,    0,    0,    0,    0,    0,    0,    0,
  63.     /*320*/    0,    0,    0,    0,    0,    0,    0,    0,
  64.     /*330*/    0,    0,    0,    0,    0,    0,    0,    0,
  65.     /*340*/    0,    0,    0,    0,    0,    0,    0,    0,
  66.     /*350*/    0,    0,    0,    0,    0,    0,    0,    0,
  67.     /*360*/    0,    0,    0,    0,    0,    0,    0,    0,
  68.     /*370*/    0,    0,    0,    0,    0,    0,    0,    0,
  69.  
  70. };
  71.  
  72. /* 
  73.         Grab the next identifier the text source file opened with the
  74.     handle `inFILE'.  This state machine is built for speed, not
  75.     elegance.
  76. */
  77. char *
  78. getTextId(inFILE, flagP)
  79.     FILE        *inFILE;
  80.     int        *flagP;
  81. {
  82.     static char    idBuf[BUFSIZ];
  83.     register char    *rct = &idctype[1];
  84.     register int    c;
  85.     register char    *id = idBuf;
  86.  
  87. top:
  88.     c = getc(inFILE);
  89.     while (ISBORING(c))
  90.         c = getc(inFILE);
  91.     if (ISEOF(c)) {
  92.         return NULL;
  93.     }
  94.     id = idBuf;
  95.     *id++ = c;
  96.     if (ISID1ST(c)) {
  97.         *flagP = IDN_NAME;
  98.         while (ISIDREST(c = getc(inFILE)))
  99.             if (! ISIDSQUEEZE(c)) *id++ = c;
  100.     } else if (ISNUMBER(c)) {
  101.         *flagP = IDN_NUMBER;
  102.         while (ISNUMBER(c = getc(inFILE)))
  103.             *id++ = c;
  104.     } else {
  105.         if (isprint(c))
  106.             fprintf(stderr, "junk: `%c'", c);
  107.         else
  108.             fprintf(stderr, "junk: `\\%03o'", c);
  109.         goto top;
  110.     }
  111.  
  112.     *id = '\0';
  113.     ungetc(c, inFILE);
  114.     *flagP |= IDN_LITERAL;
  115.     return idBuf;
  116. }
  117.  
  118. static void
  119. setCtype(chars, type)
  120.     char        *chars;
  121.     int        type;
  122. {
  123.     char        *rct = &idctype[1];
  124.  
  125.     while (*chars)
  126.         rct[*chars++] |= type;
  127. }
  128. static void
  129. clrCtype(chars, type)
  130.     char        *chars;
  131.     int        type;
  132. {
  133.     char        *rct = &idctype[1];
  134.  
  135.     while (*chars)
  136.         rct[*chars++] &= ~type;
  137. }
  138.  
  139. extern char    *MyName;
  140. static void
  141. usage(lang)
  142.     char        *lang;
  143. {
  144.     fprintf(stderr, "Usage: %s -S%s([(+|-)a<cc>] [(+|-)s<cc>]\n", MyName, lang);
  145.     exit(1);
  146. }
  147. static char *textDocument[] =
  148. {
  149. "The Text scanner arguments take the form -Stext<arg>, where",
  150. "<arg> is one of the following: (<cc> denotes one or more characters)",
  151. "  (+|-)a<cc> . . Include (or exculde) <cc> in ids.",
  152. "  (+|-)s<cc> . . Squeeze (or don't squeeze) <cc> out of ids.",
  153. NULL
  154. };
  155. void
  156. setTextArgs(lang, op, arg)
  157.     char        *lang;
  158.     int        op;
  159.     char        *arg;
  160. {
  161.     if (op == '?') {
  162.         document(textDocument);
  163.         return;
  164.     }
  165.     switch (*arg++)
  166.     {
  167.     case 'a':
  168.         if (op == '+') {
  169.             setCtype(arg, I1) ;
  170.         } else {
  171.             clrCtype(arg, I1) ;
  172.         }
  173.         break;
  174.     case 's':
  175.         if (op == '+') {
  176.             setCtype(arg, SQ) ;
  177.         } else {
  178.             clrCtype(arg, SQ) ;
  179.         }
  180.         break;
  181.     default:
  182.         if (lang)
  183.             usage(lang);
  184.         break;
  185.     }
  186. }
  187.