home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / sozobon / scsrc20 / hcc / pre.c < prev    next >
C/C++ Source or Header  |  1991-02-22  |  15KB  |  983 lines

  1. /* Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    pre.c
  12.  *
  13.  *    preprocessor for the compiler
  14.  *
  15.  *    Handles all preprocessor (#) commands and
  16.  *      looks up keywords
  17.  *
  18.  *    Interface:
  19.  *        getnode()    returns next "token node"
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include "param.h"
  24. #include "tok.h"
  25. #include "nodes.h"
  26.  
  27. #if CC68
  28. FILE *fopenb();
  29. #define fopen fopenb
  30. #endif
  31.  
  32. extern struct tok curtok;
  33. extern char curstr[];
  34.  
  35. #define TK_SEENL    1    /* want to see NL token */
  36. #define TK_SEEWS    2    /* want to see WS token */
  37. #define TK_ONLY1    4    /* only want 1st token on line */
  38. #define TK_LTSTR    8    /* '<' starts a string */
  39. #define TK_NOESC    16    /* dont do '\' escapes in string */
  40.  
  41. extern int tk_flags, sawnl;
  42.  
  43. #ifndef ACK_HOST
  44. NODE *deflist[NHASH];
  45. NODE *holdtok;
  46. int iflevel, iftruth, ifnest, in_if_x, skip_id;
  47. #else
  48. #if PART_1
  49. NODE *deflist[NHASH];
  50. NODE *holdtok;
  51. extern int iflevel, iftruth, ifnest, in_if_x, skip_id;
  52. #else
  53. extern NODE *deflist[NHASH];
  54. extern NODE *holdtok;
  55. int iflevel, iftruth, ifnest, in_if_x, skip_id;
  56. #endif
  57. #endif
  58.  
  59. extern lineno;
  60. extern char *inname;
  61. extern FILE *input;
  62.  
  63. NODE *hlook(), *llook();
  64. NODEP tok_to_node();
  65. NODE *copylist();
  66.  
  67. #ifdef DEBUG
  68. extern int oflags[];
  69. #define debugd    oflags['d'-'a']
  70. #define debugt    oflags['t'-'a']
  71. #endif
  72.  
  73. #ifndef ACK_HOST
  74. #define PART_1    1
  75. #define PART_2    1
  76. #endif
  77.  
  78. #if PART_1
  79.  
  80. NODEP
  81. hi_node()
  82. {
  83.     register NODEP rv;
  84.  
  85.     /* node from hold queue ? */
  86.     if (holdtok) {
  87. #ifdef DEBUG
  88.         if (debugd > 2) {
  89.             printf("Holdqueue");
  90.             printnode(holdtok);
  91.         }
  92. #endif
  93.         rv = holdtok;
  94.         holdtok = rv->n_next;
  95.         rv->n_next = NULL;
  96.         return rv;
  97.     }
  98.     /* node from input */
  99. again:
  100.     while (iflevel && !iftruth)
  101.         skiplines();
  102.     if (nxttok()==0)
  103.         return NULL;
  104.     if (curtok.tnum == '#') {
  105.         dopound(0);
  106.         goto again;
  107.     }
  108.     rv = tok_to_node();
  109.     return rv;
  110. }
  111.  
  112. NODEP
  113. getnode()
  114. {
  115.     register NODEP rv;
  116.     NODEP dp;
  117.  
  118. again:
  119.     rv = hi_node();
  120.     if (rv == NULL) {
  121.         rv = allocnode();
  122.         rv->e_token = EOFTOK;
  123.         strcpy(rv->n_name, "*EOF*");
  124.     } else
  125.     if (rv->e_token == ID) {
  126.         if (in_if_x && strcmp(rv->n_name, "defined") == 0) {
  127.             skip_id = 1;
  128.             goto out;
  129.         }
  130.         if (skip_id) {
  131.             skip_id = 0;
  132.             goto out;
  133.         }
  134.         if ((dp = hlook(deflist, rv)) != NULL) {
  135.             expand(dp);
  136.             freenode(rv);
  137.             goto again;
  138.         } else if (rv->n_name[0] == '_' && builtin(rv))
  139.             return rv;
  140.         else
  141.             kw_tok(rv);
  142.     }
  143. out:
  144. #ifdef DEBUG
  145.     if (debugt) {
  146.         putchar('[');
  147.         put_nnm(rv);
  148.         printf("] ");
  149.     }
  150. #endif
  151.     return rv;
  152. }
  153.  
  154. builtin(np)
  155. register NODEP np;
  156. {
  157.     int rv;
  158.  
  159.     if (strcmp(np->n_name, "__LINE__") == 0) {
  160.         np->e_token = ICON;
  161.         np->e_ival = lineno;
  162.         return 1;
  163.     }
  164.     else if (strcmp(np->n_name, "__FILE__") == 0) {
  165.         np->e_token = SCON;
  166.         nscpy(np, inname);
  167.         return 1;
  168.     }
  169.     return 0;
  170. }
  171.  
  172. skiplines()
  173. {
  174.     for (;;) {
  175.         if (nxttok()== 0)
  176.             return;
  177.         if (curtok.tnum == '#') {
  178.             dopound(1);
  179.             return;
  180.         }
  181.         tk_flags |= TK_ONLY1;
  182.     }
  183. }
  184.  
  185. static defnargs;
  186.  
  187. p_def()
  188. {
  189.     NODE *args;
  190.     NODE *val;
  191.     NODE *def;
  192.     NODE *def_rgs(), *def_val();
  193.  
  194.     defnargs = -1;
  195.     args = NULL;
  196.     val = NULL;
  197.     nxttok();
  198.     if (curtok.tnum != ID) {
  199.         error("bad #define");
  200.         goto flush;
  201.     }
  202.     def = tok_to_node();
  203.  
  204.     tk_flags |= TK_SEEWS;
  205.     nxttok();
  206.     switch (curtok.tnum) {
  207.     case '(':
  208.         defnargs = 0;
  209.         args = def_rgs();
  210.     case WS:
  211.         goto getval;
  212.     case NL:
  213.         goto dodef;
  214.     default:
  215.         error("bad #define");
  216.         goto flush;
  217.     }
  218. getval:
  219.     val = def_val();
  220. dodef:
  221.     def->e_ival = defnargs;
  222.     define(def, val, args);
  223. flush:
  224.     ;
  225. }
  226.  
  227. optdef(s,as)
  228. char *s, *as;
  229. {
  230.     NODEP val;
  231.     NODEP def;
  232.     NODEP id_tok(), def_val();
  233.  
  234.     defnargs = -1;
  235.     val = NULL;
  236.  
  237.     def = id_tok(s);
  238.     chr_push(as);
  239.  
  240.     tk_flags |= TK_SEENL;
  241.  
  242.     val = def_val();
  243.  
  244.     tk_flags = 0;
  245.  
  246.     def->e_ival = defnargs;
  247.     define(def, val, NULL);
  248. }
  249.  
  250. /*
  251. optundef(s)
  252. char *s;
  253. {
  254.     NODEP np, tp, id_tok();
  255.  
  256.     np = id_tok(s);
  257.     tp = hlook(deflist, np);
  258.     if (tp != NULL)
  259.         tp->n_name[0] = '#';
  260.     freenode(np);
  261. }
  262. */
  263.  
  264. samedef(p1, p2)
  265. NODEP p1, p2;
  266. {
  267.     if (p1->e_ival != p2->e_ival)
  268.         return 0;
  269.     return same_list(p1->n_right, p2->n_right);
  270. }
  271.  
  272. same_list(p1, p2)
  273. NODEP p1, p2;
  274. {
  275.     if (p1 == NULL)
  276.         return p2 == NULL;
  277.     if (p2 == NULL)
  278.         return 0;
  279.     if (l_cmp(p1, p2, sizeof(*p1)/sizeof(long)) != 0)
  280.         return 0;
  281.     return same_list(p1->n_left, p2->n_left);
  282. }
  283.  
  284. l_cmp(p1, p2, n)
  285. NODE *p1, *p2;
  286. {
  287.     if (xstrcmp(p1,p2) != 0)
  288.         return 1;
  289.     if (p1->e_token != p2->e_token ||
  290.         p1->e_ival != p2->e_ival)
  291.         return 1;
  292.     return 0;
  293. }
  294.  
  295. define(def, val, args)
  296. NODEP def, val, args;
  297. {
  298.     NODEP oldp;
  299.  
  300.     if (args != NULL) {
  301.         argsmod(val, args);
  302.         freenode(args);
  303.     }
  304.     def->n_right = val;
  305.     if ((oldp = hlook(deflist, def)) != NULL) {
  306.         if (!samedef(oldp, def))
  307.             warnn("redefined", def);
  308.     }
  309. #ifdef DEBUG
  310.     if (debugd) {
  311.         printf("define (%d args)", (int)def->e_ival);
  312.         printnode(def);
  313.     }
  314. #endif
  315.     puthlist(deflist, def);
  316. }
  317.  
  318. argsmod(toks, args)
  319. NODEP toks, args;
  320. {
  321.     register NODE *np, *vp;
  322.  
  323.     for (np=toks; np != NULL; np = np->n_next)
  324.         if (np->e_token == ID) {
  325.             vp = llook(args,np);
  326.             if (vp != NULL) {
  327.                 np->e_token = DPARAM;
  328.                 np->e_ival = vp->e_ival;
  329.                 sprintf(np->n_name, "\\%d", (int)np->e_ival);
  330.             }
  331.         }
  332. }
  333.  
  334. NODE *
  335. def_rgs()
  336. {
  337.     NODE *rv;
  338.     NODE *tail;
  339.     NODE *np;
  340.  
  341.     rv = NULL;
  342.     tail = NULL;
  343.     nxttok();
  344.     if (curtok.tnum == ')') {
  345.         goto out;
  346.     }
  347. more:
  348.     if (curtok.tnum != ID) {
  349.         error("expect ID");
  350.         goto bad;
  351.     }
  352.     np = tok_to_node();
  353.     np->e_ival = defnargs;    /* hold sequence number */
  354.     defnargs++;
  355.     if (tail == NULL) {    /* first one */
  356.         rv = np;
  357.         tail = np;
  358.     } else {            /* more */
  359.         tail->n_next = np;
  360.         tail = np;
  361.     }
  362.     nxttok();
  363.     if (curtok.tnum == ',') {
  364.         nxttok();
  365.         goto more;
  366.     }
  367.     if (curtok.tnum == ')')
  368.         goto out;
  369.     error("define arg syntax");
  370. bad:
  371.     freenode(rv);
  372.     rv = NULL;
  373.     defnargs = 0;
  374. out:
  375.     return rv;
  376. }
  377.  
  378. NODE *
  379. def_val()
  380. {
  381.     NODE *rv;
  382.     NODE *tail;
  383.     NODE *np;
  384.  
  385.     rv = NULL;
  386.     tail = NULL;
  387. more:
  388.     nxttok();
  389.     if (curtok.tnum == NL) {
  390.         goto out;
  391. /*
  392.     } else if (curtok.tnum == '\\') {
  393.         nxttok();
  394.         if (curtok.tnum != NL)
  395.             goto bad;
  396.         goto more;
  397. */
  398.     }
  399.     np = tok_to_node();
  400.     if (tail == NULL) {    /* first one */
  401.         rv = np;
  402.         tail = np;
  403.     } else {            /* more */
  404.         tail->n_next = np;
  405.         tail = np;
  406.     }
  407.     goto more;
  408.  
  409. bad:
  410.     freenode(rv);
  411.     rv = NULL;
  412. out:
  413.     return rv;
  414. }
  415.  
  416. NODE *
  417. gath1(sep)
  418. int *sep;
  419. {
  420.     NODE *np, *rv, *tail;
  421.     int inparen;
  422.  
  423.     inparen = 0;
  424.     rv = NULL;
  425.     tail = NULL;
  426. more:
  427.     np = hi_node();
  428.     if (np == NULL) {
  429.         goto bad;
  430.     }
  431.     switch (np->e_token) {
  432.     case ')':
  433.     case ',':
  434.         if (inparen) {    /* dont end, part of subexpr */
  435.             if (np->e_token == ')')
  436.                 inparen--;
  437.             break;
  438.         }
  439.         *sep = np->e_token;
  440.         freenode(np);
  441.         goto out;
  442.     case '(':
  443.         inparen++;
  444.         break;
  445.     }
  446.     if (tail == NULL) {    /* first one */
  447.         rv = np;
  448.         tail = np;
  449.     } else {            /* more */
  450.         tail->n_next = np;
  451.         tail = np;
  452.     }
  453.     goto more;
  454. bad:
  455.     freenode(rv);
  456.     rv = NULL;
  457.     *sep = 0;
  458. out:
  459.     return rv;
  460. }
  461.  
  462. NODE *
  463. gath_args(n)
  464. {
  465.     NODE *rv;
  466.     NODE *tail;
  467.     NODE *np;
  468.     int sep;
  469.     int getn;
  470.  
  471.     getn = 0;
  472.     rv = NULL;
  473.     tail = NULL;
  474.     np = hi_node();
  475.     if (np->e_token != '(') {
  476.         error("expect (");
  477.         goto bad;
  478.     }
  479.     freenode(np);
  480.     if (n == 0) {
  481.         np = hi_node();
  482.         if (np->e_token != ')') {
  483.             error("expect )");
  484.             goto bad;
  485.         }
  486.         freenode(np);
  487.         return NULL;
  488.     }
  489. more:
  490.     np = gath1(&sep);
  491.     if (np == NULL) {
  492.         error("expect arg");
  493.         goto bad;
  494.     }
  495.     getn++;
  496.     if (tail == NULL) {    /* first one */
  497.         rv = np;
  498.         tail = np;
  499.     } else {            /* more */
  500.         tail->n_right = np;
  501.         tail = np;
  502.     }
  503.     if (sep) switch (sep) {
  504.     case ',':
  505.         goto more;
  506.     case ')':
  507.         if (getn != n) {
  508.             error("arg num mismatch");
  509.             goto bad;
  510.         }
  511.         goto out;
  512.     }
  513.     error("expand arg syntax");
  514. bad:
  515.     freenode(rv);
  516.     rv = NULL;
  517. out:
  518.     return rv;
  519. }
  520.  
  521. NODE *
  522. argfix(val, args, rt)
  523. NODE *val, *args;
  524. NODE **rt;
  525. {
  526.     register NODE *scan, *sub;
  527.     NODE *head;
  528.     NODE *tail, *back;
  529.     NODE *rthnode();
  530.     NODE *copylist();
  531.  
  532.     head = val;
  533.     back = NULL;
  534.     for (scan = val; scan != NULL; back=scan, scan=scan->n_next)
  535.         if (scan->e_token == DPARAM) {
  536.             sub = rthnode(args, (int)scan->e_ival);
  537.             sub = copylist(sub,&tail);
  538.             if (back) {
  539.                 back->n_next = sub;
  540.                 tail->n_next = scan->n_next;
  541.             } else {
  542.                 head = sub;
  543.                 tail->n_next = scan->n_next;
  544.             }
  545.             scan->n_next = NULL;
  546.             freenode(scan);
  547.             scan = tail;
  548.         }
  549.     *rt = back;
  550.     return head;
  551. }
  552.  
  553. expand(dp)
  554. NODEP dp;
  555. {
  556.     int nargs;
  557.     NODEP args;
  558.     register NODEP val;
  559.     NODEP tail;
  560.  
  561.     val = dp->n_right;
  562.     if (val)
  563.         val = copylist(val, &tail);
  564.     nargs = dp->e_ival;
  565.     if (nargs >= 0) {
  566.         args = gath_args(nargs);
  567.         if (args) {
  568.             if (val)
  569.                 val = argfix(val,args,&tail);
  570.             freenode(args);
  571.         }
  572.     }
  573.     if (val == NULL)
  574.         return;
  575. #ifdef DEBUG
  576.     if (debugd > 1) {
  577.         printf("Expand");
  578.         printnode(val);
  579.     }
  580. #endif
  581.     tail->n_next = holdtok;
  582.     holdtok = val;
  583. }
  584.  
  585. p_undef()
  586. {
  587.     NODEP np, tp;
  588.  
  589.     nxttok();
  590.     if (curtok.tnum != ID) {
  591.         error("bad #undef");
  592.         goto out;
  593.     }
  594.     tp = tok_to_node();
  595.     if ((np = hlook(deflist, tp)) != NULL)
  596.         /* quick and dirty */
  597.         np->n_name[0] = '#';
  598.     freenode(tp);
  599. out:
  600.     ;
  601. }
  602.  
  603. #endif
  604. #if PART_2
  605.  
  606. p_inc()
  607. {
  608.     int chkhere;
  609.     FILE *newf, *srch_open();
  610.     char *scopy(), *newnm;
  611.  
  612.     tk_flags |= TK_NOESC|TK_LTSTR;
  613.     nxttok();
  614.     switch (curtok.tnum) {
  615.     case SCON:
  616.         chkhere = 1;
  617.         break;
  618.     case SCON2:
  619.         chkhere = 0;
  620.         break;
  621.     case NL:
  622.     case EOF:
  623.         error("bad #include");
  624.         return;
  625.     }
  626.     newf = srch_open(curstr, chkhere);
  627.     if (newf == NULL) {
  628.         fatals("Cant open ", curstr);
  629.         return;
  630.     }
  631.     newnm = scopy(curstr);
  632.     do 
  633.         nxttok();
  634.     while (curtok.tnum != NL);
  635.     newfile(newf,newnm);
  636. }
  637.  
  638. int inclvl;
  639. struct svinc {
  640.     int lineno;
  641.     FILE *fd;
  642.     char *filenm;
  643. } svincs[MAXINCL];
  644.  
  645. #if NEEDBUF
  646. char p_buf[MAXINCL][BUFSIZ];
  647. #endif
  648.  
  649. static char obuf[MAXSTR];
  650.  
  651. newfile(fd,s)
  652. FILE *fd;
  653. char *s;
  654. {
  655.     register struct svinc *p;
  656.  
  657.     inclvl++;
  658.     if (inclvl > MAXINCL) {
  659.         inclvl--;
  660.         fclose(fd);
  661.         error("too many includes");
  662.         return;
  663.     }
  664.     p = &svincs[inclvl-1];
  665.     p->lineno = lineno;
  666.     p->fd = input;
  667.     p->filenm = inname;
  668.     input = fd;
  669.     lineno = 1;
  670.     inname = s;
  671. #if NEEDBUF
  672.     setbuf(input, p_buf[inclvl-1]);
  673. #endif
  674. }
  675.  
  676. endfile()
  677. {
  678.     register struct svinc *p;
  679.  
  680.     if (inclvl == 0)
  681.         return 0;
  682.     fclose(input);
  683.     inclvl--;
  684.     p = &svincs[inclvl];
  685.     sfree(inname);
  686.     input = p->fd;
  687.     lineno = p->lineno;
  688.     inname = p->filenm;
  689.     return 1;
  690. }
  691.  
  692. #define MAXIDIR    10
  693.  
  694. #ifndef FOR_AMIGA
  695. #ifndef MINIX
  696. #ifndef UNIX
  697. char *srchlist[MAXIDIR] = {
  698.     "",
  699.     "\\include\\",
  700.     "\\sozobon\\include\\",
  701.     "",
  702.     0
  703. };
  704. static int idir_n = 4;        /* number of entries in above table */
  705. #else
  706. char *srchlist[MAXIDIR] = {
  707.     "",
  708.     "/home/hans/sozobon/include/",    /* change this to cross incl dir */
  709.     0
  710. };
  711. static int idir_n = 2;
  712. #endif
  713. #else
  714. char *srchlist[MAXIDIR] = {
  715.     "",
  716.     "/usr/include/",
  717.     0
  718. };
  719. static int idir_n = 2;
  720. #endif
  721. #else
  722. char *srchlist[MAXIDIR] = {
  723.     "",
  724.     "include:",
  725.     0
  726. };
  727. static int idir_n = 2;        /* number of entries in above table */
  728. #endif
  729.  
  730. static int idir_put = 1;    /* where to put -I dirs */
  731.  
  732. optincl(s)
  733. char *s;
  734. {
  735.     register char **pp;
  736.  
  737.     if (idir_n >= MAXIDIR-1) {
  738.         warn("too many -I dirs");
  739.         return;
  740.     }
  741.     for (pp = &srchlist[idir_n]; pp > &srchlist[idir_put]; ) {
  742.         pp--;
  743.         pp[1] = pp[0];
  744.     }
  745.     *pp = s;
  746.     idir_put++;
  747.     idir_n++;
  748. }
  749.  
  750. FILE *
  751. srch_open(s, chkhere)
  752. char *s;
  753. {
  754.     char **dir;
  755.     FILE *fd;
  756.  
  757.     dir = srchlist;
  758.     if (chkhere == 0) dir++;
  759.     while (*dir) {
  760.         strcpy(obuf, *dir);
  761.         strcat(obuf, s);
  762.         fd = fopen(obuf, ROPEN);
  763.         if (fd != NULL) {
  764.             return fd;
  765.         }
  766.         dir++;
  767.     }
  768.     return NULL;
  769. }
  770.  
  771. p_if(kind,skipping)
  772. {
  773.     int truth;
  774.     NODEP tp;
  775.  
  776.     if (skipping) {
  777.         ifnest++;
  778.         return;
  779.     }
  780.     switch (kind) {
  781.     case 0:
  782.         truth = if_expr();
  783.         break;
  784.     case 1:
  785.     case 2:
  786.         nxttok();
  787.         if (curtok.tnum != ID) {
  788.             error("bad #if(n)def");
  789.             goto flush;
  790.         }
  791.         tp = tok_to_node();
  792.         truth = (hlook(deflist, tp) != NULL);
  793.         freenode(tp);
  794.         if (kind == 2)
  795.             truth = !truth;
  796.     }
  797.     iflevel++;
  798.     iftruth = truth;
  799. flush:
  800.     ;
  801. }
  802.  
  803. if_expr()
  804. {
  805.     NODE *tp, *questx();
  806.     extern NODE *cur;
  807.     int rv;
  808.  
  809.     in_if_x = 1;
  810.     skip_id = 0;
  811.     advnode();
  812.     tp = questx();
  813.     in_if_x = 0;
  814.     skip_id = 0;
  815.     if (tp) {
  816.         pnames(tp);
  817.         rv = conxval(tp);
  818.     } else
  819.         rv = 0;
  820.     if (cur->e_token != NL) {
  821.         error("bad #if");
  822.     } else
  823.         freenode(cur);
  824.     return rv;
  825. }
  826.  
  827. pnames(np)
  828. register NODEP np;
  829. {
  830. again:
  831.     if (np->e_token == ID) {
  832.         np->e_token = ICON;
  833.         np->e_ival = 0;
  834.     } else if (np->e_token == '(') {
  835.         NODEP rp, lp;
  836.         int truth;
  837.  
  838.         rp = np->n_right;
  839.         lp = np->n_left;
  840.         if (lp->e_token == ID && strcmp(lp->n_name, "defined") == 0
  841.             && rp && rp->e_token == ID) {
  842.             truth = (hlook(deflist, rp) != NULL);
  843.             freenode(rp);
  844.             freenode(lp);
  845.             np->n_left = NULL;
  846.             np->n_right = NULL;
  847.             np->e_token = ICON;
  848.             np->e_ival = truth;
  849.         }
  850.     }
  851.     if (np->n_right)
  852.         pnames(np->n_right);
  853.     np = np->n_left;
  854.     if (np)
  855.         goto again;
  856. }
  857.  
  858. p_swit(kind,skipping)
  859. {
  860.     if (skipping && ifnest) {
  861.         if (kind == 1)
  862.             ifnest--;
  863.         return;
  864.     }
  865.     if (iflevel == 0) {
  866.         error("not in #if");
  867.         goto out;
  868.     }
  869.     switch (kind) {
  870.     case 0:        /* else */
  871.         iftruth = !iftruth;
  872.         break;
  873.     case 1:        /* endif */
  874.         iflevel--;
  875.         iftruth = 1;
  876.         break;
  877.     }
  878. out:
  879.     ;
  880. }
  881.  
  882. p_line()
  883. {
  884.     char *scopy();
  885.  
  886.     nxttok();
  887.     if (curtok.tnum != ICON) {
  888.         error("bad #line");
  889.         goto flush;
  890.     }
  891.     tk_flags |= TK_NOESC;
  892.     nxttok();
  893.     if (curtok.tnum == SCON) {
  894.         sfree(inname);
  895.         inname = scopy(curtok.name);
  896.     }
  897.     lineno = curtok.ival;
  898. flush:
  899.     ;
  900. }
  901.  
  902. struct cmds {
  903.     char *name;
  904.     int (*fun)();
  905.     int arg;
  906.     int skip;
  907. } pcmds[] = {
  908.     {"define", p_def, 0, 1},
  909.     {"undef", p_undef, 0, 1},
  910.     {"include", p_inc, 0, 1},
  911.     {"if", p_if, 0, 0},
  912.     {"ifdef", p_if, 1, 0},
  913.     {"ifndef", p_if, 2, 0},
  914.     {"else", p_swit, 0, 0},
  915.     {"endif", p_swit, 1, 0},
  916.     {"line", p_line, 0, 1},
  917.     {0}
  918. };
  919.  
  920. dopound(skipping)
  921. {
  922.     register struct cmds *p;
  923.     register char *cname;
  924.  
  925.     tk_flags |= TK_SEENL;
  926.     sawnl = 0;
  927.     nxttok();
  928.     if (curtok.tnum != ID) {
  929.         error("expect name");
  930.         return;
  931.     }
  932.     cname = curtok.name;
  933.     for (p=pcmds; p->name; p++)
  934.         if (strcmp(p->name, cname) == 0) {
  935.             if (!skipping || !p->skip)
  936.                 (*p->fun)(p->arg, skipping);
  937.             tk_flags = 0;
  938.             if (sawnl == 0)
  939.                 tk_flags |= TK_ONLY1;
  940.             return;
  941.         }
  942.     error("bad # command");
  943. }
  944.  
  945. NODEP
  946. tok_to_node()
  947. {
  948.     register struct tok *tp;
  949.     register NODEP np;
  950.  
  951.     tp = &curtok;
  952.     np = allocnode();
  953.     np->e_token = tp->tnum;
  954.     np->e_flags = tp->flags;
  955.     if (tp->prec)    /* binary op */
  956.         np->e_prec = tp->prec;
  957.     else
  958.     switch (np->e_token) {
  959.     case ICON:
  960.         np->e_ival = tp->ival;
  961.         break;
  962.     case FCON:
  963.         np->e_fval = tp->fval;
  964.         break;
  965.     }
  966.     nscpy(np, tp->name);
  967.     return np;
  968. }
  969.  
  970. NODEP
  971. id_tok(s)
  972. char *s;
  973. {
  974.     NODEP np;
  975.  
  976.     np = allocnode();
  977.     np->e_token = ID;
  978.     nscpy(np, s);
  979.     return np;
  980. }
  981.  
  982. #endif
  983.