home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume5 / smallc / part2 / preproc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  5.0 KB  |  341 lines

  1. /*    File preproc.c: 2.3 (84/11/27,11:47:40) */
  2. /*% cc -O -c %
  3.  *
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "defs.h"
  8. #include "data.h"
  9.  
  10. /*
  11.  *    open an include file
  12.  */
  13. doinclude ()
  14. {
  15.     char    *p;
  16.     FILE    *inp2;
  17.  
  18.     blanks ();
  19.     if (inp2 = fixiname ())
  20.         if (inclsp < INCLSIZ) {
  21.             inclstk[inclsp++] = input2;
  22.             input2 = inp2;
  23.         } else {
  24.             fclose (inp2);
  25.             error ("too many nested includes");
  26.         }
  27.     else {
  28.         error ("Could not open include file");
  29.     }
  30.     kill ();
  31. }
  32.  
  33. /*
  34.  *    fixiname - remove "brackets" around include file name
  35.  */
  36. fixiname ()
  37. {
  38.     char    c1, c2, *p, *ibp;
  39.     char buf[20];
  40.     FILE *fp;
  41.     char buf2[100];
  42.  
  43.     ibp = &buf[0];
  44.  
  45.     if ((c1 = gch ()) != '"' && c1 != '<')
  46.         return (NULL);
  47.     for (p = line + lptr; *p ;)
  48.         *ibp++ = *p++;
  49.     c2 = *(--p);
  50.     if (c1 == '"' ? (c2 != '"') : (c2 != '>')) {
  51.         error ("incorrect delimiter");
  52.         return (NULL);
  53.     }
  54.     *(--ibp) = 0;
  55.     fp = NULL;
  56.     if (c1 == '<' || !(fp = fopen(buf, "r"))) {
  57.         strcpy(buf2, DEFLIB);
  58.         strcat(buf2, buf);
  59.         fp = fopen(buf2, "r");
  60.     }
  61.     return(fp);
  62. }
  63.  
  64. /*
  65.  *    "asm" pseudo-statement
  66.  *
  67.  *    enters mode where assembly language statements are passed
  68.  *    intact through parser
  69.  *
  70.  */
  71. doasm ()
  72. {
  73.     cmode = 0;
  74.     FOREVER {
  75.         inline ();
  76.         if (match ("#endasm"))
  77.             break;
  78.         if (feof (input))
  79.             break;
  80.         outstr (line);
  81.         nl ();
  82.     }
  83.     kill ();
  84.     cmode = 1;
  85. }
  86.  
  87. dodefine ()
  88. {
  89.     addmac();
  90. }
  91.  
  92. doundef ()
  93. {
  94.     int    mp;
  95.     char    sname[NAMESIZE];
  96.  
  97.     if (!symname(sname)) {
  98.         illname();
  99.         kill();
  100.         return;
  101.     }
  102.  
  103.     if (mp = findmac(sname))
  104.         delmac(mp);
  105.     kill();
  106. }
  107.  
  108. preprocess ()
  109. {
  110.     if (ifline()) return;
  111.     while (cpp());
  112. }
  113.  
  114. doifdef (ifdef)
  115. int ifdef;
  116. {
  117.     char sname[NAMESIZE];
  118.     int k;
  119.  
  120.     blanks();
  121.     ++iflevel;
  122.     if (skiplevel) return;
  123.     k = symname(sname) && findmac(sname);
  124.     if (k != ifdef) skiplevel = iflevel;
  125. }
  126.  
  127. ifline()
  128. {
  129.     FOREVER {
  130.         inline();
  131.         if (feof(input)) return(1);
  132.         if (match("#ifdef")) {
  133.             doifdef(YES);
  134.             continue;
  135.         } else if (match("#ifndef")) {
  136.             doifdef(NO);
  137.             continue;
  138.         } else if (match("#else")) {
  139.             if (iflevel) {
  140.                 if (skiplevel == iflevel) skiplevel = 0;
  141.                 else if (skiplevel == 0) skiplevel = iflevel;
  142.             } else noiferr();
  143.             continue;
  144.         } else if (match("#endif")) {
  145.             if (iflevel) {
  146.                 if (skiplevel == iflevel) skiplevel = 0;
  147.                 --iflevel;
  148.             } else noiferr();
  149.             continue;
  150.         }
  151.         if (!skiplevel) return(0);
  152.     }
  153. }
  154.  
  155. noiferr()
  156. {
  157.     error("no matching #if...");
  158. }
  159.  
  160.  
  161. cpp ()
  162. {
  163.     int    k;
  164.     char    c, sname[NAMESIZE];
  165.     int    tog;
  166.     int    cpped;        /* non-zero if something expanded */
  167.  
  168.     cpped = 0;
  169.     /* don't expand lines with preprocessor commands in them */
  170.     if (!cmode || line[0] == '#') return(0);
  171.  
  172.     mptr = lptr = 0;
  173.     while (ch ()) {
  174.         if ((ch () == ' ') | (ch () == 9)) {
  175.             keepch (' ');
  176.             while ((ch () == ' ') | (ch () == 9))
  177.                 gch ();
  178.         } else if (ch () == '"') {
  179.             keepch (ch ());
  180.             gch ();
  181.             while (ch () != '"') {
  182.                 if (ch () == 0) {
  183.                     error ("missing quote");
  184.                     break;
  185.                 }
  186.                 if (ch() == '\\') keepch(gch());
  187.                 keepch (gch ());
  188.             }
  189.             gch ();
  190.             keepch ('"');
  191.         } else if (ch () == 39) {
  192.             keepch (39);
  193.             gch ();
  194.             while (ch () != 39) {
  195.                 if (ch () == 0) {
  196.                     error ("missing apostrophe");
  197.                     break;
  198.                 }
  199.                 if (ch() == '\\') keepch(gch());
  200.                 keepch (gch ());
  201.             }
  202.             gch ();
  203.             keepch (39);
  204.         } else if ((ch () == '/') & (nch () == '*')) {
  205.             inchar ();
  206.             inchar ();
  207.             while ((((c = ch ()) == '*') & (nch () == '/')) == 0)
  208.                 if (c == '$') {
  209.                     inchar ();
  210.                     tog = TRUE;
  211.                     if (ch () == '-') {
  212.                         tog = FALSE;
  213.                         inchar ();
  214.                     }
  215.                     if (alpha (c = ch ())) {
  216.                         inchar ();
  217.                         toggle (c, tog);
  218.                     }
  219.                 } else {
  220.                     if (ch () == 0)
  221.                         inline ();
  222.                     else
  223.                         inchar ();
  224.                     if (feof (input))
  225.                         break;
  226.                 }
  227.             inchar ();
  228.             inchar ();
  229.         } else if (an (ch ())) {
  230.             k = 0;
  231.             while (an (ch ())) {
  232.                 if (k < NAMEMAX)
  233.                     sname[k++] = ch ();
  234.                 gch ();
  235.             }
  236.             sname[k] = 0;
  237.             if (k = findmac (sname)) {
  238.                 cpped = 1;
  239.                 while (c = macq[k++])
  240.                     keepch (c);
  241.             } else {
  242.                 k = 0;
  243.                 while (c = sname[k++])
  244.                     keepch (c);
  245.             }
  246.         } else
  247.             keepch (gch ());
  248.     }
  249.     keepch (0);
  250.     if (mptr >= MPMAX)
  251.         error ("line too long");
  252.     lptr = mptr = 0;
  253.     while (line[lptr++] = mline[mptr++]);
  254.     lptr = 0;
  255.     return(cpped);
  256. }
  257.  
  258. keepch (c)
  259. char    c;
  260. {
  261.     mline[mptr] = c;
  262.     if (mptr < MPMAX)
  263.         mptr++;
  264.     return (c);
  265. }
  266.  
  267. defmac(s)
  268. char *s;
  269. {
  270.     kill();
  271.     strcpy(line, s);
  272.     addmac();
  273. }
  274.  
  275. addmac ()
  276. {
  277.     char    sname[NAMESIZE];
  278.     int    k;
  279.     int    mp;
  280.  
  281.     if (!symname (sname)) {
  282.         illname ();
  283.         kill ();
  284.         return;
  285.     }
  286.     if (mp = findmac(sname)) {
  287.         error("Duplicate define");
  288.         delmac(mp);
  289.     }
  290.     k = 0;
  291.     while (putmac (sname[k++]));
  292.     while (ch () == ' ' | ch () == 9)
  293.         gch ();
  294.     while (putmac (gch ()));
  295.     if (macptr >= MACMAX)
  296.         error ("macro table full");
  297. }
  298.  
  299. delmac(mp) int mp; {
  300.     --mp; --mp;    /* step over previous null */
  301.     while (mp >= 0 && macq[mp]) macq[mp--] = '%';
  302. }
  303.     
  304.  
  305. putmac (c)
  306. char    c;
  307. {
  308.     macq[macptr] = c;
  309.     if (macptr < MACMAX)
  310.         macptr++;
  311.     return (c);
  312. }
  313.  
  314. findmac (sname)
  315. char    *sname;
  316. {
  317.     int    k;
  318.  
  319.     k = 0;
  320.     while (k < macptr) {
  321.         if (astreq (sname, macq + k, NAMEMAX)) {
  322.             while (macq[k++]);
  323.             return (k);
  324.         }
  325.         while (macq[k++]);
  326.         while (macq[k++]);
  327.     }
  328.     return (0);
  329. }
  330.  
  331. toggle (name, onoff)
  332. char    name;
  333. int    onoff;
  334. {
  335.     switch (name) {
  336.     case 'C':
  337.         ctext = onoff;
  338.         break;
  339.     }
  340. }
  341.