home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / programming / mkid / src / scan-asm.c < prev    next >
C/C++ Source or Header  |  1991-02-01  |  6KB  |  282 lines

  1. /* Copyright (c) 1986, Greg McGary */
  2. static char sccsid[] = "@(#)scan-asm.c    1.2 86/11/06";
  3.  
  4. #include    "bool.h"
  5. #include    <stdio.h>
  6. #include    "string.h"
  7. #include    <ctype.h>
  8. #include    "id.h"
  9.  
  10. char *getAsmId();
  11. void setAsmArgs();
  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    NL    0x04    /* newline: \n */
  19. #define    CM    0x08    /* assembler comment char: usually # or | */
  20. #define    IG    0x10    /* ignore `identifiers' with these chars in them */
  21. #define    C1    0x20    /* C comment introduction char: / */
  22. #define    C2    0x40    /* C comment termination  char: * */
  23. #define    EF    0x80    /* EOF */
  24.  
  25. /* Assembly Language character classes */
  26. #define    ISID1ST(c)    ((rct)[c]&(I1))
  27. #define    ISIDREST(c)    ((rct)[c]&(I1|NM))
  28. #define    ISNUMBER(c)    ((rct)[c]&(NM))
  29. #define    ISEOF(c)    ((rct)[c]&(EF))
  30. #define    ISCOMMENT(c)    ((rct)[c]&(CM))
  31. #define    ISBORING(c)    (!((rct)[c]&(EF|NL|I1|NM|CM|C1)))
  32. #define    ISCBORING(c)    (!((rct)[c]&(EF|NL)))
  33. #define    ISCCBORING(c)    (!((rct)[c]&(EF|C2)))
  34. #define    ISIGNORE(c)    ((rct)[c]&(IG))
  35.  
  36. static char idctype[] = {
  37.  
  38.     EF,
  39.  
  40.     /*      0       1       2       3       4       5       6       7   */
  41.     /*    -----   -----   -----   -----   -----   -----   -----   ----- */
  42.  
  43.     /*000*/    0,    0,    0,    0,    0,    0,    0,    0,
  44.     /*010*/    0,    0,    NL,    0,    0,    0,    0,    0,
  45.     /*020*/    0,    0,    0,    0,    0,    0,    0,    0,
  46.     /*030*/    0,    0,    0,    0,    0,    0,    0,    0,
  47.     /*040*/    0,    0,    0,    0,    0,    0,    0,    0,
  48.     /*050*/    0,    0,    C2,    0,    0,    0,    0,    C1,
  49.     /*060*/    NM,    NM,    NM,    NM,    NM,    NM,    NM,    NM,    
  50.     /*070*/    NM,    NM,    0,    0,    0,    0,    0,    0,
  51.     /*100*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  52.     /*110*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  53.     /*120*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  54.     /*130*/    I1|NM,    I1,    I1,    0,    0,    0,    0,    I1,
  55.     /*140*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  56.     /*150*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  57.     /*160*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  58.     /*170*/    I1|NM,    I1,    I1,    0,    0,    0,    0,    0,
  59.  
  60.     /*200*/    0,    0,    0,    0,    0,    0,    0,    0,
  61.     /*210*/    0,    0,    0,    0,    0,    0,    0,    0,
  62.     /*220*/    0,    0,    0,    0,    0,    0,    0,    0,
  63.     /*230*/    0,    0,    0,    0,    0,    0,    0,    0,
  64.     /*240*/    0,    0,    0,    0,    0,    0,    0,    0,
  65.     /*250*/    0,    0,    0,    0,    0,    0,    0,    0,
  66.     /*260*/    0,    0,    0,    0,    0,    0,    0,    0,
  67.     /*270*/    0,    0,    0,    0,    0,    0,    0,    0,
  68.     /*300*/    0,    0,    0,    0,    0,    0,    0,    0,
  69.     /*310*/    0,    0,    0,    0,    0,    0,    0,    0,
  70.     /*320*/    0,    0,    0,    0,    0,    0,    0,    0,
  71.     /*330*/    0,    0,    0,    0,    0,    0,    0,    0,
  72.     /*340*/    0,    0,    0,    0,    0,    0,    0,    0,
  73.     /*350*/    0,    0,    0,    0,    0,    0,    0,    0,
  74.     /*360*/    0,    0,    0,    0,    0,    0,    0,    0,
  75.     /*370*/    0,    0,    0,    0,    0,    0,    0,    0,
  76.  
  77. };
  78.  
  79. static bool eatUnder = TRUE;
  80. static bool preProcess = TRUE;
  81.  
  82. /*
  83.     Grab the next identifier the assembly language
  84.     source file opened with the handle `inFILE'.
  85.     This state machine is built for speed, not elegance.
  86. */
  87. char *
  88. getAsmId(inFILE, flagP)
  89.     FILE        *inFILE;
  90.     int        *flagP;
  91. {
  92.     static char    idBuf[BUFSIZ];
  93.     register char    *rct = &idctype[1];
  94.     register int    c;
  95.     register char    *id = idBuf;
  96.     static bool    newLine = TRUE;
  97.  
  98. top:
  99.     c = getc(inFILE);
  100.     if (preProcess > 0 && newLine) {
  101.         newLine = FALSE;
  102.         if (c != '#')
  103.             goto next;
  104.         while (ISBORING(c))
  105.             c = getc(inFILE);
  106.         if (!ISID1ST(c))
  107.             goto next;
  108.         id = idBuf;
  109.         *id++ = c;
  110.         while (ISIDREST(c = getc(inFILE)))
  111.             *id++ = c;
  112.         *id = '\0';
  113.         if (strcmp(idBuf, "include") == 0) {
  114.             while (c != '"' && c != '<')
  115.                 c = getc(inFILE);
  116.             id = idBuf;
  117.             *id++ = c = getc(inFILE);
  118.             while ((c = getc(inFILE)) != '"' && c != '>')
  119.                 *id++ = c;
  120.             *id = '\0';
  121.             *flagP = IDN_STRING;
  122.             return idBuf;
  123.         }
  124.         if (strncmp(idBuf, "if", 2) == 0
  125.         || strcmp(idBuf, "define")  == 0
  126.         || strcmp(idBuf, "undef")   == 0)
  127.             goto next;
  128.         while (c != '\n')
  129.             c = getc(inFILE);
  130.         newLine = TRUE;
  131.         goto top;
  132.     }
  133.  
  134. next:
  135.     while (ISBORING(c))
  136.         c = getc(inFILE);
  137.  
  138.     if (ISCOMMENT(c)) {
  139.         while (ISCBORING(c))
  140.             c = getc(inFILE);
  141.         newLine = TRUE;
  142.     }
  143.  
  144.     if (ISEOF(c)) {
  145.         newLine = TRUE;
  146.         return NULL;
  147.     }
  148.  
  149.     if (c == '\n') {
  150.         newLine = TRUE;
  151.         goto top;
  152.     }
  153.  
  154.     if (c == '/') {
  155.         if ((c = getc(inFILE)) != '*')
  156.             goto next;
  157.         c = getc(inFILE);
  158.         for (;;) {
  159.             while (ISCCBORING(c))
  160.                 c = getc(inFILE);
  161.             if ((c = getc(inFILE)) == '/') {
  162.                 c = getc(inFILE);
  163.                 break;
  164.             } else if (ISEOF(c)) {
  165.                 newLine = TRUE;
  166.                 return NULL;
  167.             }
  168.         }
  169.         goto next;
  170.     }
  171.  
  172.     id = idBuf;
  173.     if (eatUnder && c == '_' && !ISID1ST(c = getc(inFILE))) {
  174.         ungetc(c, inFILE);
  175.         return "_";
  176.     }
  177.     *id++ = c;
  178.     if (ISID1ST(c)) {
  179.         *flagP = IDN_NAME;
  180.         while (ISIDREST(c = getc(inFILE)))
  181.             *id++ = c;
  182.     } else if (ISNUMBER(c)) {
  183.         *flagP = IDN_NUMBER;
  184.         while (ISNUMBER(c = getc(inFILE)))
  185.             *id++ = c;
  186.     } else {
  187.         if (isprint(c))
  188.             fprintf(stderr, "junk: `%c'", c);
  189.         else
  190.             fprintf(stderr, "junk: `\\%03o'", c);
  191.         goto next;
  192.     }
  193.  
  194.     *id = '\0';
  195.     for (id = idBuf; *id; id++)
  196.         if (ISIGNORE(*id))
  197.             goto next;
  198.     ungetc(c, inFILE);
  199.     *flagP |= IDN_LITERAL;
  200.     return idBuf;
  201. }
  202.  
  203. static void
  204. setCtype(chars, type)
  205.     char        *chars;
  206.     int        type;
  207. {
  208.     char        *rct = &idctype[1];
  209.  
  210.     while (*chars)
  211.         rct[*chars++] |= type;
  212. }
  213. static void
  214. clrCtype(chars, type)
  215.     char        *chars;
  216.     int        type;
  217. {
  218.     char        *rct = &idctype[1];
  219.  
  220.     while (*chars)
  221.         rct[*chars++] &= ~type;
  222. }
  223.  
  224. extern char    *MyName;
  225. static void
  226. usage(lang)
  227.     char        *lang;
  228. {
  229.     fprintf(stderr, "Usage: %s -S%s([-c<cc>] [-u] [(+|-)a<cc>] [(+|-)p] [(+|-)C])\n", MyName, lang);
  230.     exit(1);
  231. }
  232. static char *asmDocument[] =
  233. {
  234. "The Assembler scanner arguments take the form -Sasm<arg>, where",
  235. "<arg> is one of the following: (<cc> denotes one or more characters)",
  236. "  -c<cc> . . . . <cc> introduce(s) a comment until end-of-line.",
  237. "  (+|-)u . . . . (Do|Don't) strip a leading `_' from ids.",
  238. "  (+|-)a<cc> . . Allow <cc> in ids, and (keep|ignore) those ids.",
  239. "  (+|-)p . . . . (Do|Don't) handle C-preprocessor directives.",
  240. "  (+|-)C . . . . (Do|Don't) handle C-style comments. (/* */)",
  241. NULL
  242. };
  243. void
  244. setAsmArgs(lang, op, arg)
  245.     char        *lang;
  246.     int        op;
  247.     char        *arg;
  248. {
  249.     if (op == '?') {
  250.         document(asmDocument);
  251.         return;
  252.     }
  253.     switch (*arg++)
  254.     {
  255.     case 'a':
  256.         setCtype(arg, I1|((op == '-') ? IG : 0));
  257.         break;
  258.     case 'c':
  259.         setCtype(arg, CM);
  260.         break;
  261.     case 'u':
  262.         eatUnder = (op == '+');
  263.         break;
  264.     case 'p':
  265.         preProcess = (op == '+');
  266.         break;
  267.     case 'C':
  268.         if (op == '+') {
  269.             setCtype("/", C1);
  270.             setCtype("*", C2);
  271.         } else {
  272.             clrCtype("/", C1);
  273.             clrCtype("*", C2);
  274.         }
  275.         break;
  276.     default:
  277.         if (lang)
  278.             usage(lang);
  279.         break;
  280.     }
  281. }
  282.