Annotation of researchv10no/cmd/cpp/cpp.c, revision 1.1

1.1     ! root        1: /*#ident       "@(#)cpp:common/cpp.c   1.44" */
        !             2: 
        !             3: 
        !             4: #ifdef FLEXNAMES
        !             5: #      define NCPS     128
        !             6: #else
        !             7: #      define NCPS     8
        !             8: #endif
        !             9: int ncps = NCPS;               /* default name length */
        !            10: 
        !            11: # include <stdio.h>
        !            12: # include <ctype.h>
        !            13: # include <libc.h>
        !            14: # include <sys/types.h>                /* needed by stat.h */
        !            15: # include <sys/stat.h>         /* needed by option -M */
        !            16: /* C command - C preprocessor */
        !            17: 
        !            18:        /*
        !            19:        * See if necessary defines are given
        !            20:        */
        !            21: #if !defined( PD_MACH ) || !defined( PD_SYS )
        !            22: #      include "*** Must define PD_MACH and PD_SYS ***"
        !            23: #endif
        !            24:        /*
        !            25:        * These defines are used to enter new machines and/or systems
        !            26:        * to the two lists.  To create a new instance of cpp in a cross
        !            27:        * compilation environment, set PD_MY_MACH=\"your-new-machine\"
        !            28:        * and/or PD_MY_SYS=\"your-new-os\" and set PD_MACH=MAX_PD_MACH
        !            29:        * and PD_SYS=MAX_PD_SYS.
        !            30:        */
        !            31: #ifndef PD_MY_MACH
        !            32: #      define PD_MY_MACH       0
        !            33: #endif
        !            34: #ifndef PD_MY_SYS
        !            35: #      define PD_MY_SYS        0
        !            36: #endif
        !            37: 
        !            38: #define STATIC
        !            39: 
        !            40: #define STDIN 0
        !            41: #define STDOUT 1
        !            42: #define STDERR 2
        !            43: 
        !            44: #define CLASSCODE      27      /* exit status if #class seen */
        !            45: 
        !            46: #define READ   "r"
        !            47: #define WRITE  "w"
        !            48: #define SALT   '#'
        !            49: 
        !            50: #ifndef BUFSIZ
        !            51: #      define BUFSIZ 512
        !            52: #endif
        !            53: 
        !            54: char *pbeg, *pbuf, *pend;
        !            55: char *outp, *inp;
        !            56: char *newp;
        !            57: char cinit;
        !            58: 
        !            59: #ifdef CXREF
        !            60: char *xcopy();
        !            61: FILE *outfp;
        !            62: static int ready = 0;
        !            63: int xline;
        !            64: #endif
        !            65: 
        !            66: /* some code depends on whether characters are sign or zero extended */
        !            67: /*     #if '\377' < 0          not used here, old cpp doesn't understand */
        !            68: #if pdp11 | vax
        !            69: #      define COFF 128
        !            70: #else
        !            71: #      define COFF 0
        !            72: #endif
        !            73: 
        !            74: # if gcos
        !            75: #      define ALFSIZ 512       /* alphabet size */
        !            76: # else
        !            77: #      define ALFSIZ 256       /* alphabet size */
        !            78: # endif
        !            79: char macbit[ ALFSIZ + 11 ];
        !            80: char toktyp[ ALFSIZ ];
        !            81: #define BLANK 1
        !            82: #define IDENT 2
        !            83: #define NUMBR 3
        !            84: 
        !            85: /* a superimposed code is used to reduce the number of calls to the
        !            86: /* symbol table lookup routine.  (if the kth character of an identifier
        !            87: /* is 'a' and there are no macro names whose kth character is 'a'
        !            88: /* then the identifier cannot be a macro name, hence there is no need
        !            89: /* to look in the symbol table.)  'scw1' enables the test based on
        !            90: /* single characters and their position in the identifier.  'scw2'
        !            91: /* enables the test based on adjacent pairs of characters and their
        !            92: /* position in the identifier.  scw1 typically costs 1 indexed fetch,
        !            93: /* an AND, and a jump per character of identifier, until the identifier
        !            94: /* is known as a non-macro name or until the end of the identifier.
        !            95: /* scw1 is inexpensive.  scw2 typically costs 4 indexed fetches,
        !            96: /* an add, an AND, and a jump per character of identifier, but it is also
        !            97: /* slightly more effective at reducing symbol table searches.
        !            98: /* scw2 usually costs too much because the symbol table search is
        !            99: /* usually short; but if symbol table search should become expensive,
        !           100: /* the code is here.
        !           101: /* using both scw1 and scw2 is of dubious value.
        !           102: */
        !           103: #define scw1 1
        !           104: #define scw2 0
        !           105: 
        !           106: #if scw2
        !           107: char t21[ ALFSIZ ], t22[ ALFSIZ ], t23[ ALFSIZ + NCPS ];
        !           108: #endif
        !           109: 
        !           110: #if scw1
        !           111: #      define b0 1
        !           112: #      define b1 2
        !           113: #      define b2 4
        !           114: #      define b3 8
        !           115: #      define b4 16
        !           116: #      define b5 32
        !           117: #      define b6 64
        !           118: #      define b7 128
        !           119: #endif
        !           120: 
        !           121: #define IB 1
        !           122: #define SB 2
        !           123: #define NB 4
        !           124: #define CB 8
        !           125: #define QB 16
        !           126: #define WB 32
        !           127: char fastab[ ALFSIZ ];
        !           128: char slotab[ ALFSIZ ];
        !           129: char *ptrtab;
        !           130: #define isslo          ( ptrtab == ( slotab + COFF ) )
        !           131: #define isid(a)                ( ( fastab + COFF )[a] & IB )
        !           132: #define isspc(a)       ( ptrtab[a] & SB )
        !           133: #define isnum(a)       ( ( fastab + COFF )[a] & NB )
        !           134: #define iscom(a)       ( ( fastab + COFF )[a] & CB )
        !           135: #define isquo(a)       ( ( fastab + COFF )[a] & QB )
        !           136: #define iswarn(a)      ( ( fastab + COFF )[a] & WB )
        !           137: 
        !           138: #define eob(a)         ( ( a ) >= pend )
        !           139: #define bob(a)         ( pbeg >= ( a ) )
        !           140: 
        !           141: char buffer[ NCPS + BUFSIZ + BUFSIZ + NCPS ];
        !           142: 
        !           143: # define MAXNEST 12    /* max number of nested #include's */
        !           144: # define MAXFRE 14     /* max buffers of macro pushback */
        !           145: 
        !           146: #ifdef pdp11
        !           147: #      define SBSIZE 24000
        !           148: #else
        !           149: /* The idea here is to define the buffer to have a certain size
        !           150: ** (the literal number) plus enough room for slop and taking side buffers
        !           151: ** out to hold processing interrupted by #include's.  The cost of side
        !           152: ** buffers is particularly noticable on an Amdahl, where BUFSIZ is 4096.
        !           153: */
        !           154: #      define SBSIZE (21000 + (MAXFRE+1)*BUFSIZ)
        !           155: #endif
        !           156: 
        !           157: char   sbf[ SBSIZE ];
        !           158: char   *savch  = sbf;
        !           159: 
        !           160: # define DROP '\376' /* special character not legal ASCII or EBCDIC */
        !           161: # define WARN DROP
        !           162: # define SAME 0
        !           163: # define MAXINC 100    /* max number of directories for -I options */
        !           164: # define MAXFRM 31     /* max number of formals/actuals to a macro */
        !           165: 
        !           166: static char warnc = WARN;
        !           167: 
        !           168: int mactop, fretop;
        !           169: char *instack[ MAXFRE ], *bufstack[ MAXFRE ], *endbuf[ MAXFRE ];
        !           170: 
        !           171: int plvl;      /* parenthesis level during scan for macro actuals */
        !           172: int maclin;    /* line number of macro call requiring actuals */
        !           173: char *macfil;  /* file name of macro call requiring actuals */
        !           174: char *macnam;  /* name of macro requiring actuals */
        !           175: int maclvl;    /* # calls since last decrease in nesting level */
        !           176: char *macforw; /* pointer which must be exceeded to decrease nesting level */
        !           177: int macdam;    /* offset to macforw due to buffer shifting */
        !           178: 
        !           179: #if tgp
        !           180:        int tgpscan;    /* flag for dump(); */
        !           181: #endif
        !           182: 
        !           183: STATIC int     inctop[ MAXNEST ];
        !           184: STATIC char    *fnames[ MAXNEST ];
        !           185: STATIC char    *fdates[ MAXNEST ];     /* for -M option */
        !           186: STATIC char    *dirnams[ MAXNEST ];    /* actual directory of #include files */
        !           187: STATIC FILE    *fins[ MAXNEST ];
        !           188: STATIC int     lineno[ MAXNEST ];
        !           189: 
        !           190: STATIC char    *dirs[ MAXINC ];        /* -I and <> directories */
        !           191: STATIC char    *dfltdir = (char *) 0;  /* user-supplied default (like /usr/include) */
        !           192: char *copy(), *subst(), *trmdir(), *strchr();
        !           193: char *chkend(), *getfdate(), *findfdate();
        !           194: struct symtab *stsym();
        !           195: STATIC FILE    *fin    = stdin;
        !           196: STATIC FILE    *fout   = stdout;
        !           197: STATIC int     nd      = 1;
        !           198: STATIC int     pflag;  /* don't put out lines "# 12 foo.c" */
        !           199: STATIC int     mflag;
        !           200: STATIC int     passcom;        /* don't delete comments */
        !           201: STATIC int     incomm; /* set while in comment so that EOF can be detected */
        !           202: STATIC int     rflag;  /* allow macro recursion */
        !           203: STATIC int     print_incs;     /* set to print out included filenames */
        !           204: STATIC int     ifno;
        !           205: # define NPREDEF 20
        !           206: STATIC char *prespc[ NPREDEF ];
        !           207: STATIC char **predef = prespc;
        !           208: STATIC char *punspc[ NPREDEF ];
        !           209: STATIC char **prund = punspc;
        !           210: STATIC int     exfail;
        !           211: struct symtab
        !           212: {
        !           213:        char    *name;
        !           214:        char    *value;
        !           215: } *lastsym, *lookup(), *slookup();
        !           216: 
        !           217: # if gcos
        !           218: #      include <setjmp.h>
        !           219:        static jmp_buf env;
        !           220: #      define main     mainpp
        !           221: #      undef exit
        !           222: #      define exit(S)  longjmp(env, 1)
        !           223: #      define symsiz 500
        !           224: #      define LINEFORM "# %d %s\n"
        !           225: #      define ERRFORM  "*%c*   %s, line "
        !           226: # else
        !           227: #      define symsiz 2000
        !           228: #      define LINEFORM "# %d \"%s%s\"\n"
        !           229: #      define ERRFORM  "*%c*   \"%s%s\", line "
        !           230: # endif
        !           231: STATIC struct symtab stab[ symsiz ];
        !           232: 
        !           233: STATIC struct symtab *defloc;
        !           234: STATIC struct symtab *udfloc;
        !           235: STATIC struct symtab *incloc;
        !           236: STATIC struct symtab *ifloc;
        !           237: STATIC struct symtab *elsloc;
        !           238: STATIC struct symtab *eifloc;
        !           239: STATIC struct symtab *elifloc;
        !           240: STATIC struct symtab *ifdloc;
        !           241: STATIC struct symtab *ifnloc;
        !           242: STATIC struct symtab *ysysloc;
        !           243: STATIC struct symtab *varloc;
        !           244: STATIC struct symtab *lneloc;
        !           245: STATIC struct symtab *ulnloc;
        !           246: STATIC struct symtab *uflloc;
        !           247: STATIC struct symtab *clsloc;
        !           248: STATIC struct symtab *idtloc;
        !           249: STATIC struct symtab *pragmaloc;
        !           250: STATIC int     trulvl;
        !           251: STATIC int     flslvl;
        !           252: #define MAX_DEPTH      500             /* max of trulvl + flslvl */
        !           253: #define SEEN_ELSE      0x1
        !           254: #define TRUE_ELIF      0x2
        !           255: STATIC char    ifelstk[MAX_DEPTH];
        !           256: 
        !           257:        /*
        !           258:        * To facilitate the handling of different cpp's and cross cpp's,
        !           259:        * the sets of mutually exclusive predefined are placed into lists.
        !           260:        * The value used from these lists are set when building from the
        !           261:        * command line.
        !           262:        */
        !           263: #define MAX_PD_MACH    13      /* set so it is where PD_MY_MACH is at */
        !           264: #define D_tss          0       /*define table indexes */
        !           265: #define D_os           1
        !           266: #define D_mert         2
        !           267: #define D_RT           3
        !           268: #define D_RES          4
        !           269: #define D_interdata    5
        !           270: #define D_pdp11                6
        !           271: #define D_vax          7
        !           272: #define D_u370         8
        !           273: #define D_u3b          9
        !           274: #define D_u3b5         10
        !           275: #define D_u3b2         11
        !           276: #define D_u3b20d       12
        !           277: #define D_newmach      MAX_PD_MACH
        !           278: #define D_nomach       MAX_PD_MACH
        !           279: 
        !           280: char *pdef_mach[MAX_PD_MACH+2] =       /* choose using PD_MACH */
        !           281: {
        !           282:        /*
        !           283:        * The following are ``machines'' for historical reasons only.
        !           284:        */
        !           285:        "tss",          "os",           "mert",
        !           286:        "RT",           "RES",          
        !           287:        /* These are the currently supported machines */
        !           288:        "interdata",    "pdp11",        "vax",
        !           289:        "u370",         "u3b",          "u3b5",
        !           290:        "u3b2",         "u3b20d",
        !           291:        PD_MY_MACH,     /* for adding "own" machine */
        !           292:        0
        !           293: };
        !           294: 
        !           295: #define MAX_PD_SYS     4       /* set so that it is where PD_MY_SYS is at */
        !           296: #define D_unix         0
        !           297: #define D_gcos         1
        !           298: #define D_ibm          2
        !           299: #define D_DMERT                3
        !           300: #define D_newsys       MAX_PD_SYS
        !           301: #define D_nosys                MAX_PD_SYS
        !           302: 
        !           303: char *pdef_sys[MAX_PD_SYS+2] = /* choose using PD_SYS */
        !           304: {
        !           305:        "unix",
        !           306:        "gcos",
        !           307:        "ibm",
        !           308:        "DMERT",
        !           309:        PD_MY_SYS,      /* for adding "own" system */
        !           310:        0
        !           311: };
        !           312: #if PD_MACH < 0 || PD_MACH > MAX_PD_MACH
        !           313: #      include "*** PD_MACH set illegally ***"
        !           314: #endif
        !           315: #if PD_SYS < 0 || PD_SYS > MAX_PD_SYS
        !           316: #      include "*** PD_SYS set illegally ***"
        !           317: #endif
        !           318: 
        !           319: 
        !           320: 
        !           321: sayline()
        !           322: {
        !           323:        if ( pflag == 0 )
        !           324:                fprintf( fout, LINEFORM, lineno[ifno], fnames[ifno] ,fdates[ifno] );
        !           325: }
        !           326: 
        !           327: /* data structure guide
        !           328: /*
        !           329: /* most of the scanning takes place in the buffer:
        !           330: /*
        !           331: /*  (low address)                                             (high address)
        !           332: /*  pbeg                           pbuf                                 pend
        !           333: /*  |      <-- BUFSIZ chars -->      |         <-- BUFSIZ chars -->        |
        !           334: /*  _______________________________________________________________________
        !           335: /* |_______________________________________________________________________|
        !           336: /*          |               |               |
        !           337: /*          |<-- waiting -->|               |<-- waiting -->
        !           338: /*          |    to be      |<-- current -->|    to be
        !           339: /*          |    written    |    token      |    scanned
        !           340: /*          |               |               |
        !           341: /*          outp            inp             p
        !           342: /*
        !           343: /*  *outp   first char not yet written to output file
        !           344: /*  *inp    first char of current token
        !           345: /*  *p      first char not yet scanned
        !           346: /*
        !           347: /* macro expansion: write from *outp to *inp (chars waiting to be written),
        !           348: /* ignore from *inp to *p (chars of the macro call), place generated
        !           349: /* characters in front of *p (in reverse order), update pointers,
        !           350: /* resume scanning.
        !           351: /*
        !           352: /* symbol table pointers point to just beyond the end of macro definitions;
        !           353: /* the first preceding character is the number of formal parameters.
        !           354: /* the appearance of a formal in the body of a definition is marked by
        !           355: /* 2 chars: the char WARN, and a char containing the parameter number.
        !           356: /* the first char of a definition is preceded by a zero character.
        !           357: /*
        !           358: /* when macro expansion attempts to back up over the beginning of the
        !           359: /* buffer, some characters preceding *pend are saved in a side buffer,
        !           360: /* the address of the side buffer is put on 'instack', and the rest
        !           361: /* of the main buffer is moved to the right.  the end of the saved buffer
        !           362: /* is kept in 'endbuf' since there may be nulls in the saved buffer.
        !           363: /*
        !           364: /* similar action is taken when an 'include' statement is processed,
        !           365: /* except that the main buffer must be completely emptied.  the array
        !           366: /* element 'inctop[ifno]' records the last side buffer saved when
        !           367: /* file 'ifno' was included.  these buffers remain dormant while
        !           368: /* the file is being read, and are reactivated at end-of-file.
        !           369: /*
        !           370: /* instack[0 : mactop] holds the addresses of all pending side buffers.
        !           371: /* instack[inctop[ifno]+1 : mactop-1] holds the addresses of the side
        !           372: /* buffers which are "live"; the side buffers instack[0 : inctop[ifno]]
        !           373: /* are dormant, waiting for end-of-file on the current file.
        !           374: /*
        !           375: /* space for side buffers is obtained from 'savch' and is never returned.
        !           376: /* bufstack[0:fretop-1] holds addresses of side buffers which
        !           377: /* are available for use.
        !           378: */
        !           379: 
        !           380: dump()
        !           381: {
        !           382:        /* write part of buffer which lies between  outp  and  inp .
        !           383:        /* this should be a direct call to 'write', but the system slows
        !           384:        /* to a crawl if it has to do an unaligned copy.  thus we buffer.
        !           385:        /*? this silly loop is 15% of the total time, thus even the 'putc'
        !           386:        /*? macro is too slow.
        !           387:        */
        !           388:        register char *p1;
        !           389:        register FILE *f;
        !           390: #if tgp
        !           391:        register char *p2;
        !           392: #endif
        !           393: 
        !           394:        if ( ( p1 = outp ) == inp || flslvl != 0 )
        !           395:                return;
        !           396: #if tgp
        !           397: #      define MAXOUT 80
        !           398:        if ( !tgpscan )         /* scan again to insure <= MAXOUT
        !           399:        {                       /* chars between linefeeds */
        !           400:                register char c, *pblank;
        !           401:                char savc, stopc, brk;
        !           402: 
        !           403:                tgpscan = 1;
        !           404:                brk = stopc = pblank = 0;
        !           405:                p2 = inp;
        !           406:                savc = *p2;
        !           407:                *p2 = '\0';
        !           408:                while ( c = *p1++ )
        !           409:                {
        !           410:                        if ( c == '\\' )
        !           411:                                c = *p1++;
        !           412:                        if ( stopc == c )
        !           413:                                stopc = 0;
        !           414:                        else if ( c == '"' || c == '\'' )
        !           415:                                stopc = c;
        !           416:                        if ( p1 - outp > MAXOUT && pblank != 0 )
        !           417:                        {
        !           418:                                *pblank++ = '\n';
        !           419:                                inp = pblank;
        !           420:                                dump();
        !           421:                                brk = 1;
        !           422:                                pblank = 0;
        !           423:                        }
        !           424:                        if ( c == ' ' && stopc == 0 )
        !           425:                                pblank = p1 - 1;
        !           426:                }
        !           427:                if ( brk )
        !           428:                        sayline();
        !           429:                *p2 = savc;
        !           430:                inp = p2;
        !           431:                p1 = outp;
        !           432:                tgpscan = 0;
        !           433:        }
        !           434: #endif
        !           435:        f = fout;
        !           436: # if gcos
        !           437:        /* filter out "$ program c" card if first line of input */
        !           438:        /* gmatch is a simple pattern matcher in the GCOS Standard Library */
        !           439:        {
        !           440:                static int gmfirst = 0;
        !           441: 
        !           442:                if ( !gmfirst )
        !           443:                {
        !           444:                        ++gmfirst;
        !           445:                        if ( gmatch( p1, "^$*program[ \t]*c*") )
        !           446:                                p1 = strchr( p1, '\n' );
        !           447:                }
        !           448:        }
        !           449: # endif
        !           450:        while (p1 < inp)
        !           451:                putc(*p1++, f);
        !           452:        outp = p1;
        !           453: }
        !           454: 
        !           455: char *
        !           456: refill( p )
        !           457:        register char *p;
        !           458: {
        !           459:        /* dump buffer.  save chars from inp to p.  read into buffer at pbuf,
        !           460:        /* contiguous with p.  update pointers, return new p.
        !           461:        */
        !           462:        register char *np, *op;
        !           463:        register int ninbuf;
        !           464: 
        !           465:        dump();
        !           466:        /* slide current token to left of pbuf */
        !           467:        ninbuf = p - inp;
        !           468:        np = pbuf - ninbuf;
        !           469:        if ( bob( np + 1 ) )
        !           470:        {
        !           471:                pperror( "token too long" );
        !           472:                np = pbeg;
        !           473:                p = inp + BUFSIZ;
        !           474:        }
        !           475:        macdam += np - inp;
        !           476:        memcpy(np, inp, ninbuf);
        !           477:        p = np + ninbuf;                /* usually pbuf - ninbuf */
        !           478:        outp = inp = np;
        !           479:        for ( ;; )
        !           480:        {
        !           481:                        /* retrieve hunk of pushed-back macro text */
        !           482:                if ( mactop > inctop[ifno] )
        !           483:                {
        !           484:                        op = instack[ --mactop ];
        !           485:                        memcpy(pbuf, op, endbuf[mactop] - op);
        !           486:                        pend = pbuf + (endbuf[mactop] - op) - 1;
        !           487:                        /* make buffer space avail for 'include' processing */
        !           488:                        if ( fretop < MAXFRE )
        !           489:                                bufstack[fretop++] = instack[mactop];
        !           490:                        return( p );
        !           491:                }
        !           492:                else    /* get more text from file(s) */
        !           493:                {
        !           494:                        maclvl = 0;
        !           495: #if NOTDEF
        !           496:                        if ( 0 < ( ninbuf = fread( pbuf, sizeof( char ), BUFSIZ, fin ) ) )
        !           497:                        {
        !           498: #else
        !           499:                /*
        !           500:                 * very much faster, but don't remove stdio completely for now
        !           501:                 * in vague search for compatibility
        !           502:                 */
        !           503:                        if ((ninbuf = read(fileno(fin), pbuf, BUFSIZ)) > 0) {
        !           504: #endif
        !           505:                                pend = pbuf + ninbuf;
        !           506:                                *pend = '\0';
        !           507:                                return( p );
        !           508:                        }
        !           509:                        /* end of #include file */
        !           510:                        if ( ifno == 0 )        /* end of input */
        !           511:                        {
        !           512:                                if ( plvl != 0 )
        !           513:                                {
        !           514:                                        int n = plvl, tlin = lineno[ifno];
        !           515:                                        char *tfil = fnames[ifno];
        !           516: 
        !           517:                                        lineno[ifno] = maclin;
        !           518:                                        fnames[ifno] = macfil;
        !           519:                                        pperror( "%s: unterminated macro call",
        !           520:                                                macnam );
        !           521:                                        lineno[ifno] = tlin;
        !           522:                                        fnames[ifno] = tfil;
        !           523:                                        np = p;
        !           524:                                        /*shut off unterminated quoted string*/
        !           525:                                        *np++ = '\n';
        !           526:                                                /* supply missing parens */
        !           527:                                        while ( --n >= 0 )
        !           528:                                                *np++ = ')';
        !           529:                                        pend = np;
        !           530:                                        *np = '\0';
        !           531:                                        if ( plvl < 0 )
        !           532:                                                plvl = 0;
        !           533:                                        return( p );
        !           534:                                }
        !           535:                                if ( incomm ) {
        !           536:                                        pperror( "Unexpected EOF in comment" );
        !           537:                                        /* undo flslvl bump when comment started */
        !           538:                                        if (flslvl) --flslvl;
        !           539:                                }
        !           540:                                if ( trulvl +flslvl > 0 )
        !           541:                                        pperror( "Unexpected EOF within #if, #ifdef or #ifndef" );
        !           542:                                inp = p;
        !           543:                                dump();
        !           544:                                if ( fout && ferror( fout ) )
        !           545:                                        pperror( "Problems with writing output file; probably out of temp space" );
        !           546:                                exit( exfail ? ( exfail ==
        !           547:                                        CLASSCODE ? CLASSCODE : 2 ) : 0 );
        !           548:                        }
        !           549:                        fclose( fin );
        !           550:                        fin = fins[--ifno];
        !           551:                        dirs[0] = dirnams[ifno];
        !           552:                        sayline();
        !           553: #ifdef CXREF
        !           554:                        fprintf(outfp, "\"%s\"\n", fnames[ifno]);
        !           555: #endif
        !           556:                }
        !           557:        }
        !           558: }
        !           559: 
        !           560: #define BEG 0
        !           561: #define LF 1
        !           562: 
        !           563: char *
        !           564: cotoken( p )
        !           565:        register char *p;
        !           566: {
        !           567:        register int c, i;
        !           568:        char quoc;
        !           569:        static int state = BEG;
        !           570:        static int speakup = 0;
        !           571: 
        !           572:        if ( state != BEG )
        !           573:                goto prevlf;
        !           574:        for ( ;; )
        !           575:        {
        !           576:        again:
        !           577:                while ( !isspc( c = *p++ ) )
        !           578:                        ;
        !           579:                inp = p - 1;
        !           580:                switch ( c )
        !           581:                {
        !           582:                case 0:
        !           583:                        if ( eob( --p ) )
        !           584:                        {
        !           585:                                p = refill( p );
        !           586:                                goto again;
        !           587:                        }
        !           588:                        else
        !           589:                                ++p;    /* ignore null byte */
        !           590:                        break;
        !           591:                case '|':
        !           592:                case '&':
        !           593:                        for ( ;; )      /* sloscan only */
        !           594:                        {
        !           595:                                if ( *p++ == *inp )
        !           596:                                        break;
        !           597:                                if ( eob( --p ) )
        !           598:                                        p = refill( p );
        !           599:                                else
        !           600:                                        break;
        !           601:                        }
        !           602:                        break;
        !           603:                case '=':
        !           604:                case '!':
        !           605:                        for ( ;; )      /* sloscan only */
        !           606:                        {
        !           607:                                if ( *p++ == '=' )
        !           608:                                        break;
        !           609:                                if ( eob( --p ) )
        !           610:                                        p = refill( p );
        !           611:                                else
        !           612:                                        break;
        !           613:                        }
        !           614:                        break;
        !           615:                case '<':
        !           616:                case '>':
        !           617:                        for ( ;; )      /* sloscan only */
        !           618:                        {
        !           619:                                if ( *p++ == '=' || p[-2] == p[-1] )
        !           620:                                        break;
        !           621:                                if ( eob( --p ) )
        !           622:                                        p = refill( p );
        !           623:                                else
        !           624:                                        break;
        !           625:                        }
        !           626:                        break;
        !           627:                case '\\':
        !           628:                        for ( ;; )
        !           629:                        {
        !           630:                                if ( *p++ == '\n' )
        !           631:                                {
        !           632:                                        ++lineno[ifno];
        !           633:                                        break;
        !           634:                                }
        !           635:                                if ( eob( --p ) )
        !           636:                                        p = refill( p );
        !           637:                                else
        !           638:                                {
        !           639:                                        ++p;
        !           640:                                        break;
        !           641:                                }
        !           642:                        }
        !           643:                        break;
        !           644:                case '/':
        !           645:                        for ( ;; )
        !           646:                        {
        !           647:                                if ( *p++ == '*' )      /* comment */
        !           648:                                {
        !           649:                                        incomm = 1;
        !           650:                                        if ( !passcom )
        !           651:                                        {
        !           652:                                                inp = p - 2;
        !           653:                                                dump();
        !           654:                                                ++flslvl;
        !           655:                                        }
        !           656:                                        for ( ;; )
        !           657:                                        {
        !           658:                                                while ( !iscom( *p++ ) )
        !           659:                                                        ;
        !           660:                                                if ( p[-1] == '*' )
        !           661:                                                        for ( ;; )
        !           662:                                                        {
        !           663:                                                                if ( *p++ == '/' )
        !           664:                                                                        goto endcom;
        !           665:                                                                if ( eob( --p ) )
        !           666:                                                                {
        !           667:                                                                        if ( !passcom )
        !           668:                                                                        {
        !           669:                                                                                inp = p;
        !           670:                                                                                p = refill( p );
        !           671:                                                                        }
        !           672:                                                                        /* split long comment */
        !           673:                                                                        else if ( ( p - inp ) >= BUFSIZ )
        !           674:                                                                        {
        !           675:                                                                                *p++ = '*';
        !           676:                                                                                *p++ = '/';
        !           677:                                                                                inp = p;
        !           678:                                                                                p = refill( p );
        !           679:                                                                                outp = inp = p -= 2;
        !           680:                                                                                *p++ = '/';
        !           681:                                                                                *p++ = '*';
        !           682:                                                                        }
        !           683:                                                                        else
        !           684:                                                                                p = refill( p );
        !           685:                                                                }
        !           686:                                                                else
        !           687:                                                                        break;
        !           688:                                                        }
        !           689:                                                else if ( p[-1] == '\n' )
        !           690:                                                {
        !           691:                                                        ++lineno[ifno];
        !           692:                                                        if ( !passcom && flslvl <= 1 )
        !           693:                                                                putc( '\n', fout );
        !           694:                                                }
        !           695:                                                else if ( eob( --p ) )
        !           696:                                                {
        !           697:                                                        if ( !passcom )
        !           698:                                                        {
        !           699:                                                                inp = p;
        !           700:                                                                p = refill( p );
        !           701:                                                        }
        !           702:                                                        /* split long comment */
        !           703:                                                        else if ( ( p - inp ) >= BUFSIZ )
        !           704:                                                        {
        !           705:                                                                *p++ = '*';
        !           706:                                                                *p++ = '/';
        !           707:                                                                inp = p;
        !           708:                                                                p = refill( p );
        !           709:                                                                outp = inp = p -= 2;
        !           710:                                                                *p++ = '/';
        !           711:                                                                *p++ = '*';
        !           712:                                                        }
        !           713:                                                        else
        !           714:                                                                p = refill( p );
        !           715:                                                }
        !           716:                                                else
        !           717:                                                        ++p;    /* ignore null byte */
        !           718:                                        }
        !           719:                                endcom:
        !           720:                                        incomm = 0;
        !           721:                                        if ( !passcom )
        !           722:                                        {
        !           723:                                                outp = inp = p;
        !           724:                                                --flslvl;
        !           725:                                                goto again;
        !           726:                                        }
        !           727:                                        break;
        !           728:                                }
        !           729:                                if ( eob( --p ) )
        !           730:                                        p = refill( p );
        !           731:                                else
        !           732:                                        break;
        !           733:                        }
        !           734:                        break;
        !           735: # if gcos
        !           736:                case '`':
        !           737: # endif
        !           738:                case '"':
        !           739:                case '\'':
        !           740:                        quoc = p[-1];
        !           741:                        for ( ;; )
        !           742:                        {
        !           743:                                while ( !isquo( *p++ ) )
        !           744:                                        ;
        !           745:                                if ( p[-1] == quoc )
        !           746:                                        break;
        !           747:                                if ( p[-1] == '\n' )    /* bare \n terminates quotation */
        !           748:                                {
        !           749:                                        --p;
        !           750:                                        break;
        !           751:                                }
        !           752:                                if ( p[-1] == '\\' )
        !           753:                                        for ( ;; )
        !           754:                                        {
        !           755:                                                if ( *p++ == '\n' )     /* escaped \n ignored */
        !           756:                                                {
        !           757:                                                        ++lineno[ifno];
        !           758:                                                        break;
        !           759:                                                }
        !           760:                                                if ( eob( --p ) )
        !           761:                                                        p = refill( p );
        !           762:                                                else
        !           763:                                                {
        !           764:                                                        ++p;
        !           765:                                                        break;
        !           766:                                                }
        !           767:                                        }
        !           768:                                else if ( eob( --p ) )
        !           769:                                        p = refill( p );
        !           770:                                else
        !           771:                                        ++p;    /* it was a different quote character */
        !           772:                        }
        !           773:                        break;
        !           774:                case WARN:
        !           775:                        {
        !           776:                                int ii;
        !           777: 
        !           778:                                dump();
        !           779:                                speakup = 0;
        !           780:                                for ( ii = sizeof(int) / sizeof(char); --ii >= 0; )
        !           781:                                {
        !           782:                                        if ( eob( p ) )
        !           783:                                                p = refill( p );
        !           784:                                        speakup |= ( *p++ & 0xFF ) << ( ii * 8 );
        !           785:                                }
        !           786:                                inp = outp = p;
        !           787:                                break;
        !           788:                        }
        !           789:                case '\n':
        !           790:                        ++lineno[ifno];
        !           791:                        if ( isslo )
        !           792:                        {
        !           793:                                state=LF;
        !           794:                                return( p );
        !           795:                        }
        !           796:                prevlf:
        !           797:                        if ( speakup )
        !           798:                        {
        !           799:                                inp = p;
        !           800:                                dump();
        !           801:                                lineno[ifno] = speakup + 1;
        !           802:                                sayline();
        !           803:                                speakup = 0;
        !           804:                        }
        !           805:                        state = BEG;
        !           806:                        for ( ;; )
        !           807:                        {
        !           808:                                /*
        !           809:                                * ignore formfeeds and vertical tabs
        !           810:                                * which may be just before the SALT
        !           811:                                */
        !           812: #if NOTDEF
        !           813:                                if ( *p == '\f' || *p == '\v' )
        !           814:                                {
        !           815:                                        register char *s = p;
        !           816: 
        !           817:                                        while ( *++s == '\f' || *s == '\v' )
        !           818:                                                ;
        !           819:                                        if ( *s == SALT )
        !           820:                                        {
        !           821:                                                /*
        !           822:                                                * get the SALT to the front!
        !           823:                                                */
        !           824:                                                *s = *p;
        !           825:                                                *p = SALT;
        !           826:                                        }
        !           827:                                }
        !           828: #endif
        !           829:                                if ( *p++ == SALT )
        !           830:                                        return( p );
        !           831:                                if ( eob( inp = --p ) )
        !           832:                                        p = refill( p );
        !           833:                                else
        !           834:                                        goto again;
        !           835:                        }
        !           836:                case '0': case '1': case '2': case '3': case '4':
        !           837:                case '5': case '6': case '7': case '8': case '9':
        !           838:                        for ( ;; )
        !           839:                        {
        !           840:                                while ( isnum( *p++ ) )
        !           841:                                        ;
        !           842:                                if ( eob( --p ) )
        !           843:                                        p = refill( p );
        !           844:                                else
        !           845:                                        break;
        !           846:                        }
        !           847:                        break;
        !           848:                case 'A': case 'B': case 'C': case 'D': case 'E':
        !           849:                case 'F': case 'G': case 'H': case 'I': case 'J':
        !           850:                case 'K': case 'L': case 'M': case 'N': case 'O':
        !           851:                case 'P': case 'Q': case 'R': case 'S': case 'T':
        !           852:                case 'U': case 'V': case 'W': case 'X': case 'Y':
        !           853:                case 'Z': case '_':
        !           854:                case 'a': case 'b': case 'c': case 'd': case 'e':
        !           855:                case 'f': case 'g': case 'h': case 'i': case 'j':
        !           856:                case 'k': case 'l': case 'm': case 'n': case 'o':
        !           857:                case 'p': case 'q': case 'r': case 's': case 't':
        !           858:                case 'u': case 'v': case 'w': case 'x': case 'y':
        !           859:                case 'z':
        !           860: #if scw1
        !           861: #      define tmac1( c, bit )          if ( !xmac1( c, bit, & ) ) \
        !           862:                                                goto nomac
        !           863: #      define xmac1( c, bit, op )      ( ( macbit + COFF )[c] op ( bit ) )
        !           864: #else
        !           865: #      define tmac1( c, bit )
        !           866: #      define xmac1( c, bit, op )
        !           867: #endif
        !           868: 
        !           869: #if scw2
        !           870: #      define tmac2( c0, c1, cpos )    if ( !xmac2( c0, c1, cpos, & ) ) \
        !           871:                                                goto nomac
        !           872: #      define xmac2( c0, c1, cpos, op ) \
        !           873:                ( ( macbit + COFF )[ ( t21 + COFF )[c0] + \
        !           874:                ( t22 + COFF )[c1]] op ( t23 + COFF + cpos )[c0] )
        !           875: #else
        !           876: #      define tmac2( c0, c1, cpos )
        !           877: #      define xmac2( c0, c1, cpos, op )
        !           878: #endif
        !           879: 
        !           880:                        if ( flslvl )
        !           881:                                goto nomac;
        !           882:                        for ( ;; )
        !           883:                        {
        !           884:                                c = p[-1];
        !           885:                                tmac1( c, b0 );
        !           886:                                i = *p++;
        !           887:                                if ( !isid( i ) )
        !           888:                                        goto endid;
        !           889:                                tmac1( i, b1 );
        !           890:                                tmac2( c, i, 0 );
        !           891:                                c = *p++;
        !           892:                                if ( !isid( c ) )
        !           893:                                        goto endid;
        !           894:                                tmac1( c, b2 );
        !           895:                                tmac2( i, c, 1 );
        !           896:                                i = *p++;
        !           897:                                if ( !isid( i ) )
        !           898:                                        goto endid;
        !           899:                                tmac1( i, b3 );
        !           900:                                tmac2( c, i, 2 );
        !           901:                                c = *p++;
        !           902:                                if ( !isid( c ) )
        !           903:                                        goto endid;
        !           904:                                tmac1( c, b4 );
        !           905:                                tmac2( i, c, 3 );
        !           906:                                i = *p++;
        !           907:                                if ( !isid( i ) )
        !           908:                                        goto endid;
        !           909:                                tmac1( i, b5 );
        !           910:                                tmac2( c, i, 4 );
        !           911:                                c = *p++;
        !           912:                                if ( !isid( c ) )
        !           913:                                        goto endid;
        !           914:                                tmac1( c, b6 );
        !           915:                                tmac2( i, c, 5 );
        !           916:                                i = *p++;
        !           917:                                if ( !isid( i ) )
        !           918:                                        goto endid;
        !           919:                                tmac1( i, b7 );
        !           920:                                tmac2( c, i, 6 );
        !           921:                                tmac2( i, 0, 7 );
        !           922:                                while ( isid( *p++ ) )
        !           923:                                        ;
        !           924:                                if ( eob( --p ) )
        !           925:                                {
        !           926:                                        refill( p );
        !           927:                                        p = inp + 1;
        !           928:                                        continue;
        !           929:                                }
        !           930:                                goto lokid;
        !           931:                        endid:
        !           932:                                if ( eob( --p ) )
        !           933:                                {
        !           934:                                        refill( p );
        !           935:                                        p = inp + 1;
        !           936:                                        continue;
        !           937:                                }
        !           938:                                tmac2( p[-1], 0, -1 + ( p - inp ) );
        !           939:                        lokid:
        !           940:                                slookup( inp, p, 0 );
        !           941:                                if ( newp )
        !           942:                                {
        !           943:                                        p = newp;
        !           944:                                        goto again;
        !           945:                                }
        !           946:                                else
        !           947:                                        break;
        !           948:                        nomac:
        !           949:                                while ( isid( *p++ ) )
        !           950:                                        ;
        !           951:                                if ( eob( --p ) )
        !           952:                                {
        !           953:                                        p = refill( p );
        !           954:                                        goto nomac;
        !           955:                                }
        !           956:                                else
        !           957:                                        break;
        !           958:                        }
        !           959:                        break;
        !           960:                } /* end of switch */
        !           961:        
        !           962:                if ( isslo )
        !           963:                        return( p );
        !           964:        } /* end of infinite loop */
        !           965: }
        !           966: 
        !           967: char *
        !           968: skipbl( p )            /* get next non-blank token */
        !           969:        register char *p;
        !           970: {
        !           971:        do
        !           972:        {
        !           973:                outp = inp = p;
        !           974:                p = cotoken( p );
        !           975:        }
        !           976:        while ( ( toktyp + COFF )[*inp] == BLANK );
        !           977:        return( p );
        !           978: }
        !           979: 
        !           980: char *
        !           981: unfill( p )
        !           982:        register char *p;
        !           983: {
        !           984:        /* take <= BUFSIZ chars from right end of buffer and put
        !           985:        /* them on instack.  slide rest of buffer to the right,
        !           986:        /* update pointers, return new p.
        !           987:        */
        !           988:        register char *np, *op;
        !           989:        register int d;
        !           990: 
        !           991:        if ( mactop >= MAXFRE )
        !           992:        {
        !           993:                pperror( "%s: too much pushback", macnam );
        !           994:                p = inp = pend;          /* begin flushing pushback */
        !           995:                dump();
        !           996:                while ( mactop > inctop[ifno] )
        !           997:                {
        !           998:                        (void) refill( p );
        !           999:                        p = inp = pend;
        !          1000:                        dump();
        !          1001:                }
        !          1002:        }
        !          1003:        if ( fretop > 0 )
        !          1004:                np = bufstack[--fretop];
        !          1005:        else
        !          1006:        {
        !          1007:                np = savch;
        !          1008:                savch += BUFSIZ;
        !          1009:                if ( savch >= sbf + SBSIZE )
        !          1010:                {
        !          1011:                        pperror( "no space" );
        !          1012:                        exit( exfail ? ( exfail == CLASSCODE ? CLASSCODE : 2 )
        !          1013:                                : 0 );
        !          1014:                }
        !          1015:                *savch++ = '\0';
        !          1016:        }
        !          1017:        instack[mactop] = np;
        !          1018:        op = pend - BUFSIZ;
        !          1019:        if ( op < p )
        !          1020:                op = p;
        !          1021:        memcpy(np, op, pend - op);
        !          1022:        np += pend - op;
        !          1023:        *np++ = 0;
        !          1024:        endbuf[mactop++] = np;  /* mark end of saved text */
        !          1025:        np = pbuf + BUFSIZ;
        !          1026:        op = pend - BUFSIZ;
        !          1027:        pend = np;
        !          1028:        if ( op < p )
        !          1029:                op = p;
        !          1030:        while ( outp < op )             /* slide over new */
        !          1031:                *--np = *--op;
        !          1032:        if ( bob( np ) )
        !          1033:                pperror( "token too long" );
        !          1034:        d = np - outp;
        !          1035:        outp += d;
        !          1036:        inp += d;
        !          1037:        macdam += d;
        !          1038:        return( p + d );
        !          1039: }
        !          1040: 
        !          1041: char *
        !          1042: doincl( p )
        !          1043:        register char *p;
        !          1044: {
        !          1045:        int filok, inctype;
        !          1046:        register char *cp;
        !          1047:        char **dirp, *nfil;
        !          1048:        char filname[BUFSIZ];
        !          1049: 
        !          1050:        p = skipbl( p );
        !          1051:        cp = filname;
        !          1052:        if ( *inp++ == '<' )    /* special <> syntax */
        !          1053:        {
        !          1054:                inctype = 1;
        !          1055:                ++flslvl;       /* prevent macro expansion */
        !          1056:                for ( ;; )
        !          1057:                {
        !          1058:                        outp = inp = p;
        !          1059:                        p = cotoken( p );
        !          1060:                        if ( *inp == '\n' )
        !          1061:                        {
        !          1062:                                --p;
        !          1063:                                *cp = '\0';
        !          1064:                                break;
        !          1065:                        }
        !          1066:                        if ( *inp == '>' )
        !          1067:                        {
        !          1068:                                *cp = '\0';
        !          1069:                                break;
        !          1070:                        }
        !          1071: # ifdef gimpel
        !          1072:                        if ( *inp == '.' && !intss() )
        !          1073:                                *inp = '#';
        !          1074: # endif
        !          1075:                        while ( inp < p )
        !          1076:                                *cp++ = *inp++;
        !          1077:                }
        !          1078:                --flslvl;       /* reenable macro expansion */
        !          1079:        }
        !          1080:        else if ( inp[-1] == '"' )      /* regular "" syntax */
        !          1081:        {
        !          1082:                inctype = 0;
        !          1083: # ifdef gimpel
        !          1084:                while ( inp < p )
        !          1085:                {
        !          1086:                        if ( *inp == '.' && !intss() )
        !          1087:                                *inp = '#';
        !          1088:                                *cp++ = *inp++;
        !          1089:                }
        !          1090: # else
        !          1091:                while ( inp < p )
        !          1092:                        *cp++ = *inp++;
        !          1093: # endif
        !          1094:                if ( *--cp == '"' )
        !          1095:                        *cp = '\0';
        !          1096:        }
        !          1097:        else
        !          1098:        {
        !          1099:                int ppwarn(), pperror();
        !          1100:                /* This is a warning if we're skipping, error if not. */
        !          1101:                (*(flslvl ? ppwarn : pperror))( "bad include syntax", 0 );
        !          1102:                inctype = 2;
        !          1103:        }
        !          1104:        /* flush current file to \n , then write \n */
        !          1105: 
        !          1106:        p = chkend( p, 1 );
        !          1107: 
        !          1108:        outp = inp = p;
        !          1109: 
        !          1110:        dump();
        !          1111:        if ( inctype == 2 || flslvl != 0 )
        !          1112:                return( p );
        !          1113:        /* look for included file */
        !          1114:        if ( ifno + 1 >= MAXNEST )
        !          1115:        {
        !          1116:                pperror( "Unreasonable include nesting", 0 );
        !          1117:                return( p );
        !          1118:        }
        !          1119:        if ( ( nfil = savch ) > sbf + SBSIZE - BUFSIZ )
        !          1120:        {
        !          1121:                pperror( "no space" );
        !          1122:                exit( exfail ? ( exfail == CLASSCODE ? CLASSCODE : 2 ) : 0 );
        !          1123:        }
        !          1124: 
        !          1125:        /* check for #include "/usr/include/..." */
        !          1126:        if (strncmp(filname, "/usr/include/", 13) == 0)
        !          1127:            ppwarn("#include of /usr/include/... may be non-portable");
        !          1128: 
        !          1129:        filok = 0;
        !          1130:        for ( dirp = dirs + inctype; *dirp; ++dirp )
        !          1131:        {
        !          1132:                if (
        !          1133: # if gcos
        !          1134:                        strchr( filname, '/' )
        !          1135: # else
        !          1136:                        filname[0] == '/' 
        !          1137: # endif
        !          1138:                                || **dirp == '\0' )
        !          1139:                {
        !          1140:                        strcpy( nfil, filname );
        !          1141:                }
        !          1142:                else
        !          1143:                {
        !          1144:                        strcpy( nfil, *dirp );
        !          1145: # if unix || gcos || DMERT
        !          1146:                        strcat( nfil, "/" );
        !          1147: # endif
        !          1148: #ifdef ibm
        !          1149: #      ifndef gimpel
        !          1150:                        strcat( nfil, "." );
        !          1151: #      endif
        !          1152: #endif
        !          1153:                        strcat( nfil, filname );
        !          1154:                }
        !          1155:                if ( NULL != ( fins[ifno + 1] = fopen( nfil, READ ) ) )
        !          1156:                {
        !          1157:                        filok = 1;
        !          1158:                        fin = fins[++ifno];
        !          1159:                        if ( print_incs )
        !          1160:                                fprintf( stderr, "%s\n", nfil );
        !          1161:                        break;
        !          1162:                }
        !          1163:        }
        !          1164:        if ( filok == 0 )
        !          1165:                pperror( "Can't find include file %s", filname );
        !          1166:        else
        !          1167:        {
        !          1168:                lineno[ifno] = 1;
        !          1169:                fnames[ifno] = cp = nfil;
        !          1170:                while ( *cp++)
        !          1171:                        ;
        !          1172:                savch = cp;
        !          1173:                fdates[ifno] = getfdate( fin );
        !          1174:                dirnams[ifno] = dirs[0] = trmdir( copy( nfil ) );
        !          1175:                sayline();
        !          1176: #ifdef CXREF
        !          1177:                fprintf(outfp, "\"%s\"\n", fnames[ifno]);
        !          1178: #endif
        !          1179:                /* save current contents of buffer */
        !          1180:                while ( !eob( p ) )
        !          1181:                        p = unfill( p );
        !          1182:                inctop[ifno] = mactop;
        !          1183:        }
        !          1184:        return( p );
        !          1185: }
        !          1186: 
        !          1187: equfrm( a, p1, p2 )
        !          1188:        register char *a, *p1, *p2;
        !          1189: {
        !          1190:        register char c;
        !          1191:        int flag;
        !          1192: 
        !          1193:        c = *p2;
        !          1194:        *p2 = '\0';
        !          1195:        flag = strcmp( a, p1 );
        !          1196:        *p2 = c;
        !          1197:        return( flag == SAME );
        !          1198: }
        !          1199: 
        !          1200: char *
        !          1201: dodef( p )             /* process '#define' */
        !          1202:        char *p;
        !          1203: {
        !          1204:        register char *pin, *psav, *cf;
        !          1205:        char **pf, **qf;
        !          1206:        int b, c, params;
        !          1207:        int ex_blank;   /* used to ignore extra blanks in token-string */
        !          1208:        int sav_passcom = passcom;      /* saved passcom, used to reset it */
        !          1209:        struct symtab *np;
        !          1210:        char *oldval, *oldsavch;
        !          1211:        char *formal[MAXFRM]; /* formal[n] is name of nth formal */
        !          1212:        char formtxt[BUFSIZ]; /* space for formal names */
        !          1213: 
        !          1214:        if ( savch > sbf + SBSIZE - BUFSIZ )
        !          1215:        {
        !          1216:                pperror( "too much defining" );
        !          1217:                return( p );
        !          1218:        }
        !          1219:        oldsavch = savch; /* to reclaim space if redefinition */
        !          1220:        ++flslvl;       /* prevent macro expansion during 'define' */
        !          1221:        p = skipbl( p );
        !          1222:        pin = inp;
        !          1223:        if ( ( toktyp + COFF )[*pin] != IDENT )
        !          1224:        {
        !          1225:                if (*pin == '\n') --lineno[ifno];
        !          1226:                ppwarn( "illegal/missing macro name" );
        !          1227:                if (*pin == '\n') ++lineno[ifno];
        !          1228:                while ( *inp != '\n' )
        !          1229:                        p = skipbl( p );
        !          1230:                --flslvl;               /* restore expansion */
        !          1231:                return( p );
        !          1232:        }
        !          1233:        np = slookup( pin, p, 1 );
        !          1234:        if ( oldval = np->value )       /* was previously defined */
        !          1235:                savch = oldsavch;
        !          1236: #ifdef CXREF
        !          1237:        def(np->name, lineno[ifno]);
        !          1238: #endif
        !          1239:        b = 1;
        !          1240:        cf = pin;
        !          1241:        while ( cf < p )                /* update macbit */
        !          1242:        {
        !          1243:                c = *cf++;
        !          1244:                xmac1( c, b, |= );
        !          1245:                b = ( b + b ) & 0xFF;
        !          1246:                if ( cf != p )
        !          1247:                        xmac2( c, *cf, -1 + ( cf - pin ), |= );
        !          1248:                else
        !          1249:                        xmac2( c, 0, -1 + ( cf - pin ), |= );
        !          1250:        }
        !          1251:        params = 0;
        !          1252:        outp = inp = p;
        !          1253:        p = cotoken( p );
        !          1254:        pin = inp;
        !          1255:        if ( *pin == '(' )      /* with parameters; identify the formals */
        !          1256:        {
        !          1257: #ifdef CXREF
        !          1258:                newf(np->name, lineno[ifno]);
        !          1259: #endif
        !          1260:                cf = formtxt;
        !          1261:                pf = formal;
        !          1262:                for ( ;; )
        !          1263:                {
        !          1264:                        p = skipbl( p );
        !          1265:                        pin = inp;
        !          1266:                        if ( *pin == '\n' )
        !          1267:                        {
        !          1268:                                --lineno[ifno];
        !          1269:                                --p;
        !          1270:                                pperror( "%s: missing )", np->name );
        !          1271:                                break;
        !          1272:                        }
        !          1273:                        if ( *pin == ')' )
        !          1274:                                break;
        !          1275:                        if ( *pin == ',' )
        !          1276:                                continue;
        !          1277:                        if ( ( toktyp + COFF )[*pin] != IDENT )
        !          1278:                        {
        !          1279:                                c = *p;
        !          1280:                                *p = '\0';
        !          1281:                                pperror( "bad formal: %s", pin );
        !          1282:                                *p = c;
        !          1283:                        }
        !          1284:                        else if ( pf >= &formal[MAXFRM] )
        !          1285:                        {
        !          1286:                                c = *p;
        !          1287:                                *p = '\0';
        !          1288:                                pperror( "too many formals: %s", pin );
        !          1289:                                *p = c;
        !          1290:                        }
        !          1291:                        else
        !          1292:                        {
        !          1293:                                *pf++ = cf;
        !          1294:                                while ( pin < p )
        !          1295:                                        *cf++ = *pin++;
        !          1296:                                *cf++ = '\0';
        !          1297:                                ++params;
        !          1298: #ifdef CXREF
        !          1299:                                def(*(pf-1), lineno[ifno]);
        !          1300: #endif
        !          1301:                        }
        !          1302:                }
        !          1303:                if ( params == 0 )      /* #define foo() ... */
        !          1304:                        --params;
        !          1305:        }
        !          1306:        else if ( *pin == '\n' )
        !          1307:        {
        !          1308:                --lineno[ifno];
        !          1309:                --p;
        !          1310:        }
        !          1311:        else
        !          1312:            p = inp;                    /* back up to scan non-blank next token */
        !          1313:        /*
        !          1314:        * remember beginning of macro body, so that we can
        !          1315:        * warn if a redefinition is different from old value.
        !          1316:        */
        !          1317:        oldsavch = psav = savch;
        !          1318:        passcom = 1;    /* make cotoken() return comments as tokens */
        !          1319:        ex_blank = 1;   /* must have some delimiter - might as well be blank */
        !          1320:        for ( ;; )      /* accumulate definition until linefeed */
        !          1321:        {
        !          1322:                outp = inp = p;
        !          1323:                p = cotoken( p );
        !          1324:                pin = inp;
        !          1325:                if ( *pin == '\\' && pin[1] == '\n' )   /* ignore escaped lf */
        !          1326:                {
        !          1327:                        if ( !ex_blank )        /* replace it with a blank */
        !          1328:                        {
        !          1329:                                *psav++ = ' ';
        !          1330:                                ex_blank = 1;
        !          1331:                        }
        !          1332:                        putc( '\n', fout );
        !          1333:                        continue;
        !          1334:                }
        !          1335:                if ( *pin == '\n' )
        !          1336:                        break;
        !          1337:                if ( ( toktyp + COFF )[*pin] == BLANK ) /* skip extra blanks */
        !          1338:                {
        !          1339:                        if ( ex_blank )
        !          1340:                                continue;
        !          1341:                        *pin = ' ';     /* force it to be a "real" blank */
        !          1342:                        ex_blank = 1;
        !          1343:                }
        !          1344:                else
        !          1345:                        ex_blank = 0;
        !          1346:                if ( *pin == '/' && pin[1] == '*' )     /* skip comment */
        !          1347:                {                                       /* except for \n's */
        !          1348:                        while ( pin < p )
        !          1349:                                if ( *pin++ == '\n' )
        !          1350:                                        putc( '\n', fout );
        !          1351:                        continue;
        !          1352:                }
        !          1353:                if ( params )   /* mark the appearance of formals in the definiton */
        !          1354:                {
        !          1355:                        if ( ( toktyp + COFF )[*pin] == IDENT )
        !          1356:                        {
        !          1357:                                for ( qf = pf; --qf >= formal; )
        !          1358:                                {
        !          1359:                                        if ( equfrm( *qf, pin, p ) )
        !          1360:                                        {
        !          1361: #ifdef CXREF
        !          1362: #ifndef NO_MACRO_FORMAL
        !          1363:                                                ref(*qf, lineno[ifno]);
        !          1364: #endif
        !          1365: #endif
        !          1366:                                                *psav++ = qf - formal + 1;
        !          1367:                                                *psav++ = WARN;
        !          1368:                                                pin = p;
        !          1369:                                                break;
        !          1370:                                        }
        !          1371:                                }
        !          1372:                        }
        !          1373:                        /* inside quotation marks, too */
        !          1374:                        else if ( *pin == '"' || *pin == '\''
        !          1375: # if gcos
        !          1376:                                        || *pin == '`'
        !          1377: # endif
        !          1378:                                                )
        !          1379:                        {
        !          1380:                                char quoc = *pin;
        !          1381: 
        !          1382:                                for ( *psav++ = *pin++; pin < p && *pin != quoc; )
        !          1383:                                {
        !          1384:                                        while ( pin < p && !isid( *pin ) )
        !          1385:                                        {
        !          1386:                                                if ( *pin == '\n'
        !          1387:                                                        && pin[-1] == '\\' )
        !          1388:                                                {
        !          1389:                                                        putc( '\n', fout );
        !          1390:                                                        psav--; /* no \ */
        !          1391:                                                        pin++;  /* no \n */
        !          1392:                                                }
        !          1393:                                                else
        !          1394:                                                        *psav++ = *pin++;
        !          1395:                                        }
        !          1396:                                        cf = pin;
        !          1397:                                        while ( cf < p && isid( *cf ) )
        !          1398:                                                ++cf;
        !          1399:                                        for ( qf = pf; --qf >= formal; )
        !          1400:                                        {
        !          1401:                                                if ( equfrm( *qf, pin, cf ) )
        !          1402:                                                {
        !          1403:                                                        *psav++ = qf - formal + 1;
        !          1404:                                                        *psav++ = WARN;
        !          1405:                                                        pin = cf;
        !          1406:                                                        break;
        !          1407:                                                }
        !          1408:                                        }
        !          1409:                                        while ( pin < cf )
        !          1410:                                                *psav++ = *pin++;
        !          1411:                                }
        !          1412:                        }
        !          1413:                }
        !          1414:                while ( pin < p )
        !          1415:                        if ( *pin == '\n' && pin[-1] == '\\' )
        !          1416:                        {
        !          1417:                                putc( '\n', fout );
        !          1418:                                psav--; /* no \ */
        !          1419:                                pin++;  /* no \n */
        !          1420:                        }
        !          1421:                        else
        !          1422:                                *psav++ = *pin++;
        !          1423:        }
        !          1424:        passcom = sav_passcom;  /* restore to "real" value */
        !          1425:        if ( psav[-1] == ' ' )  /* if token-string ended with a blank */
        !          1426:                psav--;         /* then it is unnecessary - throw away */
        !          1427:        *psav++ = params;
        !          1428:        *psav++ = '\0';
        !          1429:        if ( ( cf = oldval ) != NULL )          /* redefinition */
        !          1430:        {
        !          1431:                --cf;   /* skip no. of params, which may be zero */
        !          1432:                while ( *--cf )         /* go back to the beginning */
        !          1433:                        ;
        !          1434:                if ( 0 != strcmp( ++cf, oldsavch ) )    /* redefinition different from old */
        !          1435:                {
        !          1436:                        --lineno[ifno];
        !          1437:                        ppwarn( "%s redefined", np->name );
        !          1438:                        ++lineno[ifno];
        !          1439:                        np->value = psav - 1;
        !          1440:                }
        !          1441:                else
        !          1442:                        psav = oldsavch; /* identical redef.; reclaim space */
        !          1443:        }
        !          1444:        else
        !          1445:                np->value = psav - 1;
        !          1446:        --flslvl;
        !          1447:        inp = pin;
        !          1448:        savch = psav;
        !          1449:        return( p );
        !          1450: }
        !          1451: 
        !          1452: #define fasscan()      ptrtab = fastab + COFF
        !          1453: #define sloscan()      ptrtab = slotab + COFF
        !          1454: /* this macro manages the lookup of a macro name and produces
        !          1455: ** a warning if the name is missing
        !          1456: */
        !          1457: #define LOOKUP(skipblank, flag) \
        !          1458:        ++flslvl; if (skipblank) p = skipbl(p); \
        !          1459:        if ( ( toktyp + COFF )[*inp] != IDENT ) \
        !          1460:        {                                       \
        !          1461:                if (*inp == '\n') --lineno[ifno];\
        !          1462:                ppwarn( "illegal/missing macro name" ); \
        !          1463:                if (*inp == '\n') ++lineno[ifno];\
        !          1464:                while ( *inp != '\n' )          \
        !          1465:                        p = skipbl( p );        \
        !          1466:                --flslvl;                       \
        !          1467:                continue;                       \
        !          1468:        }                                       \
        !          1469:        np = slookup(inp,p,flag); --flslvl
        !          1470: 
        !          1471: control( p )           /* find and handle preprocessor control lines */
        !          1472:        register char *p;
        !          1473: {
        !          1474:        register struct symtab *np;
        !          1475: 
        !          1476:        for ( ;; )
        !          1477:        {
        !          1478:                fasscan();
        !          1479:                p = cotoken( p );
        !          1480:                if ( *inp == '\n' )
        !          1481:                        ++inp;
        !          1482:                dump();
        !          1483:                sloscan();
        !          1484:                p = skipbl( p );
        !          1485:                *--inp = SALT;
        !          1486:                outp = inp;
        !          1487:                ++flslvl;
        !          1488:                np = slookup( inp, p, 0 );
        !          1489:                --flslvl;
        !          1490:                if ( np == defloc )     /* define */
        !          1491:                {
        !          1492:                        if ( flslvl == 0 )
        !          1493:                        {
        !          1494:                                p = dodef( p ); 
        !          1495:                                continue;
        !          1496:                        }
        !          1497:                }
        !          1498:                else if ( np == incloc )        /* include */
        !          1499:                {
        !          1500:                        p = doincl( p );
        !          1501:                        continue;
        !          1502:                }
        !          1503:                else if ( np == ifnloc )        /* ifndef */
        !          1504:                {
        !          1505:                        LOOKUP(1/*skipbl*/, 0/*flag*/); /* sets "np" */
        !          1506:                        if ( flslvl == 0 && np->value == 0 )
        !          1507:                                ++trulvl;
        !          1508:                        else
        !          1509:                                ++flslvl;
        !          1510:                        if ( trulvl + flslvl >= MAX_DEPTH )
        !          1511:                                pperror( "#if,ifdef,ifndef nesting too deep" );
        !          1512:                        else
        !          1513:                                ifelstk[trulvl + flslvl] =
        !          1514:                                        flslvl ? 0 : TRUE_ELIF;
        !          1515: #ifdef CXREF
        !          1516:                        ref(xcopy(inp, p), lineno[ifno]);
        !          1517: #endif
        !          1518:                        p = chkend( p, 1 );
        !          1519:                }
        !          1520:                else if ( np == ifdloc )        /* ifdef */
        !          1521:                {
        !          1522:                        LOOKUP(1/*skipbl*/, 0/*flag*/); /* sets "np" */
        !          1523:                        if ( flslvl == 0 && np->value != 0 )
        !          1524:                                ++trulvl;
        !          1525:                        else
        !          1526:                                ++flslvl;
        !          1527:                        if ( trulvl + flslvl >= MAX_DEPTH )
        !          1528:                                pperror( "#if,ifdef,ifndef nesting too deep" );
        !          1529:                        else
        !          1530:                                ifelstk[trulvl + flslvl] =
        !          1531:                                        flslvl ? 0 : TRUE_ELIF;
        !          1532: #ifdef CXREF
        !          1533:                        ref(xcopy(inp, p), lineno[ifno]);
        !          1534: #endif
        !          1535:                        p = chkend( p, 1 );
        !          1536:                }
        !          1537:                else if ( np == eifloc )        /* endif */
        !          1538:                {
        !          1539:                        if ( flslvl )
        !          1540:                        {
        !          1541:                                if ( --flslvl == 0 )
        !          1542:                                        sayline();
        !          1543:                        }
        !          1544:                        else if ( trulvl )
        !          1545:                                --trulvl;
        !          1546:                        else
        !          1547:                                pperror( "If-less endif", 0 );
        !          1548:                        p = chkend( p, 2 );     /* research mod; summit uses 1 */
        !          1549:                }
        !          1550:                else if ( np == elifloc )       /* elif */
        !          1551:                {
        !          1552:                        if ( ifelstk[trulvl + flslvl] & SEEN_ELSE )
        !          1553:                                pperror( "#elif following #else", 0 );
        !          1554:                        if ( flslvl )
        !          1555:                        {
        !          1556:                                if ( --flslvl != 0 )
        !          1557:                                        ++flslvl;
        !          1558:                                else
        !          1559:                                {
        !          1560:                                        newp = p;
        !          1561: #ifdef CXREF
        !          1562:                                        xline = lineno[ifno];
        !          1563: #endif
        !          1564:                                        if ( ifelstk[trulvl + flslvl + 1] == 0
        !          1565:                                                && yyparse() )
        !          1566:                                        {
        !          1567:                                                ++trulvl;
        !          1568:                                                ifelstk[trulvl + flslvl] =
        !          1569:                                                        TRUE_ELIF;
        !          1570:                                                sayline();
        !          1571:                                        }
        !          1572:                                        else
        !          1573:                                                ++flslvl;
        !          1574:                                        p = newp;
        !          1575:                                }
        !          1576:                        }
        !          1577:                        else if ( trulvl )
        !          1578:                        {
        !          1579:                                ++flslvl;
        !          1580:                                --trulvl;
        !          1581:                        }
        !          1582:                        else
        !          1583:                                pperror( "If-less elif", 0 );
        !          1584:                }
        !          1585:                else if ( np == elsloc )        /* else */
        !          1586:                {
        !          1587:                        if ( ifelstk[trulvl + flslvl] & SEEN_ELSE )
        !          1588:                                pperror( "too many #else's", 0 );
        !          1589:                        if ( flslvl )
        !          1590:                        {
        !          1591:                                if ( --flslvl != 0 )
        !          1592:                                        ++flslvl;
        !          1593:                                else if ( ifelstk[trulvl + flslvl + 1] == 0 )
        !          1594:                                {
        !          1595:                                        ++trulvl;
        !          1596:                                        sayline();
        !          1597:                                }
        !          1598:                                else
        !          1599:                                        ++flslvl;
        !          1600:                        }
        !          1601:                        else if ( trulvl )
        !          1602:                        {
        !          1603:                                ++flslvl;
        !          1604:                                --trulvl;
        !          1605:                        }
        !          1606:                        else
        !          1607:                                pperror( "If-less else", 0 );
        !          1608:                        ifelstk[trulvl + flslvl] |= SEEN_ELSE;
        !          1609:                        p = chkend( p, 1 );
        !          1610:                }
        !          1611:                else if ( np == udfloc )        /* undefine */
        !          1612:                {
        !          1613:                        if ( flslvl == 0 )
        !          1614:                        {
        !          1615:                                LOOKUP(1/*skipbl*/, DROP); /* sets "np" */
        !          1616:                                p = chkend( p, 1 );
        !          1617:                        }
        !          1618:                        else
        !          1619:                                p = chkend( p, 2 );
        !          1620: #ifdef CXREF
        !          1621:                        ref(xcopy(inp, p), lineno[ifno]);
        !          1622: #endif
        !          1623:                }
        !          1624:                else if ( np == ifloc )         /* if */
        !          1625:                {
        !          1626: #if tgp
        !          1627:                        pperror( " IF not implemented, true assumed", 0 );
        !          1628:                        if ( flslvl == 0 )
        !          1629:                                ++trulvl;
        !          1630:                        else
        !          1631:                                ++flslvl;
        !          1632: #else
        !          1633:                        newp = p;
        !          1634: #ifdef CXREF
        !          1635:                        xline = lineno[ifno];
        !          1636: #endif
        !          1637:                        if ( flslvl == 0 && yyparse() )
        !          1638:                                ++trulvl;
        !          1639:                        else
        !          1640:                                ++flslvl;
        !          1641:                        p = newp;
        !          1642:                        if ( trulvl + flslvl >= MAX_DEPTH )
        !          1643:                                pperror( "#if,ifdef,ifndef nesting too deep" );
        !          1644:                        else
        !          1645:                                ifelstk[trulvl + flslvl] =
        !          1646:                                        flslvl ? 0 : TRUE_ELIF;
        !          1647: #endif
        !          1648:                }
        !          1649:                else if ( np == lneloc )        /* line */
        !          1650:                {
        !          1651:                        if ( flslvl == 0 && pflag == 0 )
        !          1652:                        {
        !          1653:                                register char *s;
        !          1654:                                register int ln;
        !          1655: 
        !          1656:                                outp = inp = p;
        !          1657:                        do_line:
        !          1658:                                *--outp = '#';
        !          1659:                                /*
        !          1660:                                * make sure that the whole
        !          1661:                                * directive has been read
        !          1662:                                */
        !          1663:                                s = p;
        !          1664:                                while ( *s && *s != '\n' )
        !          1665:                                        s++;
        !          1666:                                if ( eob( s ) )
        !          1667:                                        p = refill( s );
        !          1668:                                /*
        !          1669:                                * eat the line number
        !          1670:                                */
        !          1671:                                s = inp;
        !          1672:                                while ( ( toktyp + COFF )[*s] == BLANK )
        !          1673:                                        s++;
        !          1674:                                ln = 0;
        !          1675:                                while ( isdigit( *s ) )
        !          1676:                                        ln = ln * 10 + *s++ - '0';
        !          1677:                                if ( ln )
        !          1678:                                        lineno[ifno] = ln - 1;
        !          1679:                                else
        !          1680:                                        pperror( "bad number for #line" );
        !          1681:                                /*
        !          1682:                                * eat the optional "filename"
        !          1683:                                */
        !          1684:                                while ( ( toktyp + COFF )[*s] == BLANK )
        !          1685:                                        s++;
        !          1686:                                if ( *s != '\n' )
        !          1687:                                {
        !          1688:                                        if ( *s != '"' )
        !          1689:                                                pperror( "bad file for #line" );
        !          1690:                                        else
        !          1691:                                        {
        !          1692:                                                register char *t = savch;
        !          1693: 
        !          1694:                                                for ( ;; )
        !          1695:                                                {
        !          1696:                                                        if ( *++s == '"' )
        !          1697:                                                                break;
        !          1698:                                                        else if ( *s == '\n' ||
        !          1699:                                                                *s == '\0' )
        !          1700:                                                        {
        !          1701:                                                                pperror( "bad file for #line" );
        !          1702:                                                                break;
        !          1703:                                                        }
        !          1704:                                                        *t++ = *s;
        !          1705:                                                }
        !          1706:                                                *t++ = '\0';
        !          1707:                                                if ( strcmp( savch, fnames[ifno] ) )
        !          1708:                                                {
        !          1709:                                                        fnames[ifno] = savch;
        !          1710:                                                        fdates[ifno] = findfdate( &fnames[ifno] );
        !          1711:                                                        savch = t;
        !          1712:                                                }
        !          1713:                                        }
        !          1714:                                }
        !          1715:                                /*
        !          1716:                                * push it all along to be eventually printed
        !          1717:                                */
        !          1718:                                while ( *inp != '\n' )
        !          1719:                                        p = cotoken( p );
        !          1720:                                continue;
        !          1721:                        }
        !          1722:                }
        !          1723:                else if ( np == clsloc )        /* class */
        !          1724:                        exfail = CLASSCODE;             /* return value */
        !          1725:                else if ( np == idtloc )        /* ident */
        !          1726:                {
        !          1727:                        if ( pflag == 0 )
        !          1728:                                while ( *inp != '\n' )  /* just pass it along */
        !          1729:                                        p = cotoken( p );
        !          1730:                }
        !          1731: #ifdef PRAGMA
        !          1732:                else if ( np == pragmaloc ) {   /* pragma */
        !          1733:                        while ( *inp != '\n' )  /* pass it all along */
        !          1734:                                p = cotoken( p );
        !          1735:                }
        !          1736: #endif
        !          1737:                else if ( *++inp == '\n' )      /* allows blank line after # */
        !          1738:                        outp = inp;
        !          1739:                else if ( isdigit( *inp ) )     /* pass thru line directives */
        !          1740:                {
        !          1741:                        outp = p = inp;
        !          1742:                        goto do_line;
        !          1743:                }
        !          1744:                else
        !          1745:                        pperror( "undefined control", 0 );
        !          1746:                /* flush to lf */
        !          1747:                ++flslvl;
        !          1748:                while ( *inp != '\n' )
        !          1749:                {
        !          1750:                        outp = inp = p;
        !          1751:                        p = cotoken( p );
        !          1752:                }
        !          1753:                --flslvl;
        !          1754:        }
        !          1755: }
        !          1756: 
        !          1757: struct symtab *
        !          1758: stsym( s )
        !          1759:        register char *s;
        !          1760: {
        !          1761:        char buf[BUFSIZ];
        !          1762:        register char *p;
        !          1763: 
        !          1764:        /* make definition look exactly like end of #define line */
        !          1765:        /* copy to avoid running off end of world when param list is at end */
        !          1766:        p = buf;
        !          1767:        while ( *p++ = *s++ )
        !          1768:                ;
        !          1769:        p = buf;
        !          1770:        while ( isid( *p++ ) )          /* skip first identifier */
        !          1771:                ;
        !          1772:        if ( *--p == '=' )
        !          1773:        {
        !          1774:                *p++ = ' '; 
        !          1775:                while ( *p++ )
        !          1776:                        ;
        !          1777:        }
        !          1778:        else
        !          1779:        {
        !          1780:                s = " 1";
        !          1781:                while ( *p++ = *s++ )
        !          1782:                        ;
        !          1783:        }
        !          1784:        pend = p;
        !          1785:        *--p = '\n';
        !          1786:        sloscan();
        !          1787:        dodef( buf );
        !          1788:        return( lastsym );
        !          1789: }
        !          1790: 
        !          1791: struct symtab *
        !          1792: ppsym( s )             /* kludge */
        !          1793:        char *s;
        !          1794: {
        !          1795:        register struct symtab *sp;
        !          1796: 
        !          1797:        cinit = SALT;
        !          1798:        *savch++ = SALT;
        !          1799:        sp = stsym( s );
        !          1800:        --sp->name;
        !          1801:        cinit = 0;
        !          1802:        return( sp );
        !          1803: }
        !          1804: 
        !          1805: 
        !          1806: int yy_errflag;                /* TRUE when pperror called by yyerror() */
        !          1807: 
        !          1808: /* VARARGS1 */
        !          1809: pperror( s, x, y )
        !          1810:        char *s;
        !          1811: {
        !          1812:        if ( fnames[ifno][0] )
        !          1813: # if gcos
        !          1814:                fprintf( stderr, ERRFORM, exfail >= 0 ? 'F' : 'W',fnames[ifno]);
        !          1815: # else
        !          1816:                fprintf( stderr, "%s: ", fnames[ifno] );
        !          1817: # endif
        !          1818:        fprintf( stderr, "%d: ", lineno[ifno] );
        !          1819:        fprintf( stderr, s, x, y );
        !          1820:        if ( yy_errflag )
        !          1821:                fprintf( stderr, " (in preprocessor if)\n" );
        !          1822:        else
        !          1823:                fprintf( stderr, "\n" );
        !          1824:        if ( exfail < CLASSCODE - 1 )
        !          1825:                ++exfail;
        !          1826: }
        !          1827: 
        !          1828: yyerror( s, a, b )
        !          1829:        char *s;
        !          1830: {
        !          1831:        yy_errflag = 1;
        !          1832:        pperror( s, a, b );
        !          1833:        yy_errflag = 0;
        !          1834: }
        !          1835: 
        !          1836: ppwarn( s, x )
        !          1837:        char *s;
        !          1838: {
        !          1839:        int fail = exfail;
        !          1840: 
        !          1841:        exfail = -1;
        !          1842:        pperror( s, x );
        !          1843:        exfail = fail;
        !          1844: }
        !          1845: 
        !          1846: struct symtab *
        !          1847: lookup( namep, enterf )
        !          1848:        char *namep;
        !          1849: {
        !          1850:        register char *np, *snp;
        !          1851:        register int c, i;
        !          1852:        int around;
        !          1853:        register struct symtab *sp;
        !          1854: 
        !          1855:        /* namep had better not be too long (currently, <=ncps chars) */
        !          1856:        np = namep;
        !          1857:        around = 0;
        !          1858:        i = cinit;
        !          1859:        while ( c = *np++ )
        !          1860:                i += i + c;
        !          1861:        c = i;  /* c=i for register usage on pdp11 */
        !          1862:        c %= symsiz;
        !          1863:        if ( c < 0 )
        !          1864:                c += symsiz;
        !          1865:        sp = &stab[c];
        !          1866:        while ( snp = sp->name )
        !          1867:        {
        !          1868:                np = namep;
        !          1869:                while ( *snp++ == *np )
        !          1870:                        if ( *np++ == '\0' )
        !          1871:                        {
        !          1872:                                if ( enterf == DROP )
        !          1873:                                {
        !          1874:                                        sp->name[0] = DROP;
        !          1875:                                        sp->value = 0;
        !          1876:                                }
        !          1877:                                return( lastsym = sp );
        !          1878:                        }
        !          1879:                if ( --sp < &stab[0] )
        !          1880:                        if ( around )
        !          1881:                        {
        !          1882:                                pperror( "too many defines", 0 );
        !          1883:                                exit( exfail ? ( exfail ==
        !          1884:                                        CLASSCODE ? CLASSCODE : 2 ) : 0 );
        !          1885:                        }
        !          1886:                        else
        !          1887:                        {
        !          1888:                                ++around;
        !          1889:                                sp = &stab[symsiz - 1];
        !          1890:                        }
        !          1891:        }
        !          1892:        if ( enterf == 1 )
        !          1893:                sp->name = namep;
        !          1894:        return( lastsym = sp );
        !          1895: }
        !          1896: 
        !          1897: struct symtab *
        !          1898: slookup( p1, p2, enterf )
        !          1899:        register char *p1, *p2;
        !          1900:        int enterf;
        !          1901: {
        !          1902:        register char *p3;
        !          1903:        char c2, c3;
        !          1904:        struct symtab *np;
        !          1905: 
        !          1906:        c2 = *p2;       /* mark end of token */
        !          1907:        *p2 ='\0';
        !          1908:        if ( ( p2 - p1 ) > ncps )
        !          1909:                p3 = p1 + ncps;
        !          1910:        else
        !          1911:                p3 = p2;
        !          1912:        c3 = *p3;       /* truncate to ncps chars or less */
        !          1913:        *p3 ='\0';
        !          1914:        if ( enterf == 1 )
        !          1915:                p1 = copy( p1 );
        !          1916:        np = lookup( p1, enterf );
        !          1917:        *p3 = c3;
        !          1918:        *p2 = c2;
        !          1919:        if ( np->value != 0 && flslvl == 0 )
        !          1920:                newp = subst( p2, np );
        !          1921:        else
        !          1922:                newp = 0;
        !          1923:        return( np );
        !          1924: }
        !          1925: 
        !          1926: char *
        !          1927: subst( p, sp )
        !          1928:        register char *p;
        !          1929:        struct symtab *sp;
        !          1930: {
        !          1931:        static char match[] = "%s: argument mismatch";
        !          1932:        register char *ca, *vp;
        !          1933:        int params;
        !          1934:        char *actual[MAXFRM]; /* actual[n] is text of nth actual */
        !          1935:        char acttxt[BUFSIZ]; /* space for actuals */
        !          1936: 
        !          1937:        if ( 0 == ( vp = sp->value ) )
        !          1938:                return( p );
        !          1939:        if ( ( p - macforw ) <= macdam )
        !          1940:        {
        !          1941:                if ( ++maclvl > symsiz && !rflag )
        !          1942:                {
        !          1943:                        pperror( "%s: macro recursion", sp->name );
        !          1944:                        return( p );
        !          1945:                }
        !          1946:        }
        !          1947:        else
        !          1948:                maclvl = 0;     /* level decreased */
        !          1949:        macforw = p;    /* new target for decrease in level */
        !          1950:        macdam = 0;
        !          1951:        macnam = sp->name;
        !          1952: #ifdef CXREF
        !          1953:        ref(macnam, lineno[ifno]);
        !          1954: #endif
        !          1955:        dump();
        !          1956:        if ( sp == ulnloc )
        !          1957:        {
        !          1958:                vp = acttxt;
        !          1959:                *vp++ = '\0';
        !          1960:                sprintf( vp, "%d", lineno[ifno] );
        !          1961:                while ( *vp++ )
        !          1962:                        ;
        !          1963:        }
        !          1964:        else if ( sp == uflloc )
        !          1965:        {
        !          1966:                vp = acttxt;
        !          1967:                *vp++ = '\0';
        !          1968:                sprintf( vp, "\"%s\"", fnames[ifno] );
        !          1969:                while ( *vp++ )
        !          1970:                        ;
        !          1971:        }
        !          1972:        if ( 0 != ( params = *--vp & 0xFF ) )   /*definition calls for params */
        !          1973:        {
        !          1974:                register char **pa;
        !          1975:                int dparams;            /* parameters in definition */
        !          1976: 
        !          1977:                ca = acttxt;
        !          1978:                pa = actual;
        !          1979:                if ( params == 0xFF )   /* #define foo() ... */
        !          1980:                        params = 0;
        !          1981:                dparams = params;
        !          1982:                sloscan();
        !          1983:                ++flslvl; /* no expansion during search for actuals */
        !          1984:                plvl = -1;
        !          1985:                maclin = lineno[ifno];
        !          1986:                macfil = fnames[ifno];
        !          1987:                do
        !          1988:                {
        !          1989:                        p = skipbl( p );
        !          1990:                }
        !          1991:                while ( *inp == '\n' );         /* skip \n too */
        !          1992:                if ( *inp == '(' )
        !          1993:                {
        !          1994:                        for ( plvl = 1; plvl != 0; )
        !          1995:                        {
        !          1996:                                *ca++ = '\0';
        !          1997:                                for ( ;; )
        !          1998:                                {
        !          1999:                                        outp = inp = p;
        !          2000:                                        p = cotoken( p );
        !          2001:                                        if ( *inp == '(' )
        !          2002:                                                ++plvl;
        !          2003:                                        if ( *inp == ')' && --plvl == 0 )
        !          2004:                                        {
        !          2005:                                                if ( ca > acttxt+1 )
        !          2006:                                                        --params;
        !          2007:                                                break;
        !          2008:                                        }
        !          2009:                                        if ( plvl == 1 && *inp == ',' )
        !          2010:                                        {
        !          2011:                                                --params;
        !          2012:                                                break;
        !          2013:                                        }
        !          2014:                                        while ( inp < p )
        !          2015:                                        {
        !          2016:                                                /*
        !          2017:                                                *  toss newlines in arguments
        !          2018:                                                *  to macros - keep problems
        !          2019:                                                *  to a minimum.
        !          2020:                                                *  if a backslash is just
        !          2021:                                                *  before the newline, assume
        !          2022:                                                *  it is in a string and
        !          2023:                                                *  leave it in.
        !          2024:                                                */
        !          2025:                                                if ( *inp == '\n'
        !          2026:                                                        && inp[-1] != '\\' )
        !          2027:                                                {
        !          2028:                                                        *inp = ' ';
        !          2029:                                                }
        !          2030:                                                *ca++ = *inp++;
        !          2031:                                        }
        !          2032:                                        if ( ca > &acttxt[BUFSIZ] )
        !          2033:                                                pperror( "%s: actuals too long", sp->name );
        !          2034:                                }
        !          2035:                                if ( pa >= &actual[MAXFRM] )
        !          2036:                                        ppwarn( match, sp->name );
        !          2037:                                else 
        !          2038:                                        *pa++ = ca;
        !          2039:                        }
        !          2040:                }
        !          2041:                else {                          /* should have seen (, because def
        !          2042:                                                ** had args
        !          2043:                                                */
        !          2044:                        ppwarn( match, sp->name );
        !          2045:                        p = inp;                /* back up to current token */
        !          2046:                }
        !          2047:                if ( maclin != lineno[ifno] )   /* embedded linefeeds in macro call */
        !          2048:                {
        !          2049:                        int i, j = lineno[ifno];
        !          2050: 
        !          2051:                        for ( i = sizeof( int ) / sizeof( char ); --i >= 0; )
        !          2052:                        {
        !          2053:                                if ( bob( p ) )
        !          2054:                                {
        !          2055:                                        outp = inp = p;
        !          2056:                                        p = unfill( p );
        !          2057:                                }
        !          2058:                                *--p = j;
        !          2059:                                j >>= 8;
        !          2060:                        }
        !          2061:                        if ( bob( p ) )
        !          2062:                        {
        !          2063:                                outp = inp = p;
        !          2064:                                p = unfill( p );
        !          2065:                        }
        !          2066:                        *--p = warnc;
        !          2067:                }
        !          2068:                /* def with one arg and use with zero args is special ok case */
        !          2069:                if ( params < 0 || (params > 0 && dparams != 1) )
        !          2070:                        ppwarn( match, sp->name );
        !          2071:                while ( --params >= 0 )
        !          2072:                        *pa++ = "" + 1; /* null string for missing actuals */
        !          2073:                --flslvl;
        !          2074:                fasscan();
        !          2075:        }
        !          2076:        for ( ;; )      /* push definition onto front of input stack */
        !          2077:        {
        !          2078:                while ( !iswarn( *--vp ) )
        !          2079:                {
        !          2080:                        if ( bob( p ) )
        !          2081:                        {
        !          2082:                                outp = inp = p;
        !          2083:                                p = unfill( p );
        !          2084:                        }
        !          2085:                        *--p = *vp;
        !          2086:                }
        !          2087:                if ( *vp == warnc )     /* insert actual param */
        !          2088:                {
        !          2089:                        ca = actual[*--vp - 1];
        !          2090:                        while ( *--ca )
        !          2091:                        {
        !          2092:                                if ( bob( p ) )
        !          2093:                                {
        !          2094:                                        outp = inp = p;
        !          2095:                                        p = unfill( p );
        !          2096:                                }
        !          2097:                                *--p = *ca;
        !          2098:                        }
        !          2099:                }
        !          2100:                else
        !          2101:                        break;
        !          2102:        }
        !          2103:        outp = inp = p;
        !          2104:        return( p );
        !          2105: }
        !          2106: 
        !          2107: 
        !          2108: 
        !          2109: 
        !          2110: char *
        !          2111: trmdir( s )
        !          2112:        register char *s;
        !          2113: {
        !          2114:        register char *p = s;
        !          2115: 
        !          2116:        while ( *p++ )
        !          2117:                ;
        !          2118:        --p;
        !          2119:        while ( p > s && *--p != '/' )
        !          2120:                ;
        !          2121: # if unix || DMERT
        !          2122:        if ( p == s )
        !          2123:                *p++ = '.';
        !          2124: # endif
        !          2125:        *p = '\0';
        !          2126:        return( s );
        !          2127: }
        !          2128: 
        !          2129: STATIC char *
        !          2130: copy( s )
        !          2131:        register char *s;
        !          2132: {
        !          2133:        register char *old;
        !          2134: 
        !          2135:        old = savch;
        !          2136:        while ( *savch++ = *s++ )
        !          2137:                ;
        !          2138:        return( old );
        !          2139: }
        !          2140: 
        !          2141: yywrap()
        !          2142: {
        !          2143:        return( 1 );
        !          2144: }
        !          2145: 
        !          2146: main( argc, argv )
        !          2147:        char *argv[];
        !          2148: {
        !          2149:        register int i, c;
        !          2150:        register char *p;
        !          2151:        char *tf, **cp2;
        !          2152:        int forclass = 0;               /* 1 if C-with-classes selected */
        !          2153: 
        !          2154: # if gcos
        !          2155:        if ( setjmp( env ) )
        !          2156:                return( exfail ? ( exfail == CLASSCODE ? CLASSCODE : 2 ) : 0 );
        !          2157: # endif
        !          2158:        p = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        !          2159:        i = 0;
        !          2160:        while ( c = *p++ )
        !          2161:        {
        !          2162:                ( fastab + COFF )[c] |= IB | NB | SB;
        !          2163:                ( toktyp + COFF )[c] = IDENT;
        !          2164: #if scw2
        !          2165:                /* 53 == 63-10; digits rarely appear in identifiers,
        !          2166:                /* and can never be the first char of an identifier.
        !          2167:                /* 11 == 53*53/sizeof(macbit) .
        !          2168:                */
        !          2169:                ++i;
        !          2170:                ( t21 + COFF )[c] = ( 53 * i ) / 11;
        !          2171:                ( t22 + COFF )[c] = i % 11;
        !          2172: #endif
        !          2173:        }
        !          2174:        p = "0123456789.";
        !          2175:        while ( c = *p++ )
        !          2176:        {
        !          2177:                ( fastab + COFF )[c] |= NB | SB;
        !          2178:                 ( toktyp + COFF )[c] = NUMBR;
        !          2179:        }
        !          2180: # if gcos
        !          2181:        p = "\n\"'`/\\";
        !          2182: # else
        !          2183:        p = "\n\"'/\\";
        !          2184: # endif
        !          2185:        while ( c = *p++ )
        !          2186:                ( fastab + COFF )[c] |= SB;
        !          2187: # if gcos
        !          2188:        p = "\n\"'`\\";
        !          2189: # else
        !          2190:        p = "\n\"'\\";
        !          2191: # endif
        !          2192:        while ( c = *p++ )
        !          2193:                ( fastab + COFF )[c] |= QB;
        !          2194:        p = "*\n";
        !          2195:        while ( c = *p++ )
        !          2196:                ( fastab + COFF)[c] |= CB;
        !          2197:        ( fastab + COFF )[warnc] |= WB | SB;
        !          2198:        ( fastab + COFF )['\0'] |= CB | QB | SB | WB;
        !          2199:        for ( i = ALFSIZ; --i >= 0; )
        !          2200:                slotab[i] = fastab[i] | SB;
        !          2201:        p = " \t\v\f\r";        /* note no \n; */
        !          2202:        while ( c = *p++ )
        !          2203:                ( toktyp + COFF )[c] = BLANK;
        !          2204: #if scw2
        !          2205:        for ( ( t23 + COFF )[i = ALFSIZ + 7 - COFF] = 1; --i >= -COFF; )
        !          2206:                if ( ( ( t23 + COFF )[i] = ( t23 + COFF + 1 )[i] << 1 ) == 0 )
        !          2207:                        ( t23 + COFF )[i] = 1;
        !          2208: #endif
        !          2209: 
        !          2210: # if unix || DMERT
        !          2211:        fnames[ifno = 0] = "";
        !          2212:        fdates[ifno = 0] = "";
        !          2213:        dirnams[0] = dirs[0] = ".";
        !          2214: # endif
        !          2215: # if ibm
        !          2216:        fnames[ifno = 0] = "";
        !          2217:        fdates[ifno = 0] = "";
        !          2218: # endif
        !          2219: # if gcos
        !          2220:        if ( inquire( stdin, _TTY ) )
        !          2221:                freopen( "*src", "rt", stdin );
        !          2222: # endif
        !          2223: # if gimpel || gcos
        !          2224:        fnames[ifno = 0] = (char *) inquire( stdin, _FILENAME );
        !          2225:        dirnams[0] = dirs[0] = trmdir( copy( fnames[0] ) );
        !          2226: # endif
        !          2227:        for ( i = 1; i < argc; i++ )
        !          2228:        {
        !          2229:                switch ( argv[i][0] )
        !          2230:                {
        !          2231:                case '-':
        !          2232: # if gcos
        !          2233:                                        /* case-independent on GCOS */
        !          2234:                        switch ( toupper( argv[i][1] ) )
        !          2235: # else
        !          2236:                        switch( argv[i][1] )
        !          2237: # endif
        !          2238:                        {
        !          2239:                        case 'M':       /* research: filename+moddate*/
        !          2240:                                mflag++;
        !          2241:                                continue;
        !          2242:                        case 'P':
        !          2243:                                pflag++;
        !          2244:                        case 'E':
        !          2245:                                continue;
        !          2246:                        case 'R':
        !          2247:                                ++rflag;
        !          2248:                                continue;
        !          2249:                        case 'C':
        !          2250:                                passcom++;
        !          2251:                                continue;
        !          2252: #ifdef CXREF
        !          2253:                        case 'F':
        !          2254:                                if ((outfp = fopen(argv[++i],"w")) == NULL)
        !          2255:                                {
        !          2256:                                        fprintf(stderr, "Can't open %s\n",
        !          2257:                                            argv[i]);
        !          2258:                                        exit(1);
        !          2259:                                }
        !          2260:                                continue;
        !          2261: #endif
        !          2262:                        case 'D':
        !          2263:                                if ( predef > prespc + NPREDEF )
        !          2264:                                {
        !          2265:                                        pperror( "too many -D options, ignoring %s", argv[i] );
        !          2266:                                        continue;
        !          2267:                                }
        !          2268:                                /* ignore plain "-D" (no argument) */
        !          2269:                                if ( *( argv[i] + 2 ) )
        !          2270:                                        *predef++ = argv[i] + 2;
        !          2271:                                continue;
        !          2272:                        case 'U':
        !          2273:                                if ( prund > punspc + NPREDEF )
        !          2274:                                {
        !          2275:                                        pperror( "too many -U options, ignoring %s", argv[i] );
        !          2276:                                        continue;
        !          2277:                                }
        !          2278:                                *prund++ = argv[i] + 2;
        !          2279:                                continue;
        !          2280:                        case 'I':
        !          2281:                                if ( nd > MAXINC - 4 )
        !          2282:                                        pperror( "excessive -I file (%s) ignored", argv[i] );
        !          2283:                                else
        !          2284:                                        dirs[nd++] = argv[i] + 2;
        !          2285:                                continue;
        !          2286:                        case 'Y':
        !          2287:                                dfltdir = argv[i] + 2;
        !          2288:                                continue;
        !          2289:                        case '\0':
        !          2290:                                continue;
        !          2291:                        case 'T':
        !          2292:                                ncps = 8;       /* backward name compatabilty */
        !          2293:                                continue;
        !          2294:                        case 'H':               /* print included filenames */
        !          2295:                                print_incs++;
        !          2296:                                continue;
        !          2297:                        case 'W':               /* enable C with classes */
        !          2298:                                forclass = 1;
        !          2299:                                continue;
        !          2300:                        default: 
        !          2301:                                pperror( "unknown flag %s", argv[i] );
        !          2302:                                continue;
        !          2303:                        }
        !          2304:                default:
        !          2305:                        if ( fin == stdin )
        !          2306:                        {
        !          2307:                                if ( NULL == ( fin = fopen( argv[i], READ ) ) )
        !          2308:                                {
        !          2309:                                        pperror( "No source file %s", argv[i] );
        !          2310:                                        exit(2);
        !          2311:                                }
        !          2312:                                fnames[ifno] = copy( argv[i] );
        !          2313:                                fdates[ifno] = getfdate( fin );
        !          2314: #ifdef CXREF
        !          2315:                                fprintf(outfp,"\"%s\"\n", fnames[ifno]);
        !          2316: #endif
        !          2317:                                dirs[0] = dirnams[ifno] = trmdir( argv[i] );
        !          2318: # ifndef gcos
        !          2319: /* too dangerous to have file name in same syntactic position
        !          2320:    be input or output file depending on file redirections,
        !          2321:    so force output to stdout, willy-nilly
        !          2322:        [i don't see what the problem is.  jfr]
        !          2323: */
        !          2324:                        }
        !          2325:                        else if ( fout == stdout )
        !          2326:                        {
        !          2327:                                static char _sobuf[BUFSIZ];
        !          2328: 
        !          2329:                                if ( NULL == ( fout = fopen( argv[i], WRITE ) ) )
        !          2330:                                {
        !          2331:                                        pperror( "Can't create %s", argv[i] );
        !          2332:                                        exit(2);
        !          2333:                                }
        !          2334:                                else
        !          2335:                                {
        !          2336:                                        fclose( stdout );
        !          2337:                                        setbuf( fout, _sobuf );
        !          2338:                                }
        !          2339: # endif
        !          2340:                        }
        !          2341:                        else
        !          2342:                                pperror( "extraneous name %s", argv[i] );
        !          2343:                }
        !          2344:        }
        !          2345: 
        !          2346:        fins[ifno] = fin;
        !          2347:        exfail = 0;
        !          2348:        /* after user -I files here are the standard include libraries */
        !          2349:        /* use user-supplied default first */
        !          2350:        if (dfltdir != (char *) 0)
        !          2351:                dirs[nd++] = dfltdir;
        !          2352:        else {
        !          2353: # if unix || DMERT
        !          2354: #    if defined(SGSINC) || defined(DMERT)
        !          2355:                if ( strlen( SGSINC ) != 0 )
        !          2356:                        dirs[nd++] = SGSINC;    /* For cross cpp's */
        !          2357: #    endif
        !          2358: #    ifdef USRINC
        !          2359:                if ( strlen( USRINC ) != 0 )
        !          2360:                        dirs[nd++] = USRINC;    /* usually /usr/include */
        !          2361: #    endif
        !          2362: #    if !defined( SGSINC ) && !defined( USRINC )
        !          2363:                dirs[nd++] = "/usr/include";
        !          2364: #    endif
        !          2365: # endif
        !          2366: # if gcos
        !          2367:        dirs[nd++] = "cc/include";
        !          2368: # endif
        !          2369: # if ibm
        !          2370: #      ifndef gimpel
        !          2371:                dirs[nd++] = "BTL$CLIB";
        !          2372: #      endif
        !          2373: # endif
        !          2374: # ifdef gimpel
        !          2375:        dirs[nd++] = intss() ?  "SYS3.C." : "";
        !          2376: # endif
        !          2377: # ifdef compool
        !          2378:        dirs[nd++] = "/compool";
        !          2379: # endif
        !          2380:        }
        !          2381:        dirs[nd++] = 0;
        !          2382:        defloc = ppsym( "define" );
        !          2383:        udfloc = ppsym( "undef" );
        !          2384:        incloc = ppsym( "include" );
        !          2385:        elsloc = ppsym( "else" );
        !          2386:        eifloc = ppsym( "endif" );
        !          2387:        elifloc = ppsym( "elif" );
        !          2388:        ifdloc = ppsym( "ifdef" );
        !          2389:        ifnloc = ppsym( "ifndef" );
        !          2390:        ifloc = ppsym( "if" );
        !          2391:        lneloc = ppsym( "line" );
        !          2392:        if (forclass)                   /* only when C with classes enabled */
        !          2393:            clsloc = ppsym( "class" );
        !          2394:        idtloc = ppsym( "ident" );
        !          2395: #ifdef PRAGMA
        !          2396:        pragmaloc = ppsym( "pragma" );
        !          2397: #endif
        !          2398:        for ( i = sizeof( macbit ) / sizeof( macbit[0] ); --i >= 0; )
        !          2399:                macbit[i] = 0;
        !          2400: 
        !          2401:        if ( pdef_mach[PD_MACH] )
        !          2402:                ysysloc = stsym( pdef_mach[PD_MACH] );
        !          2403:        if ( pdef_sys[PD_SYS] )
        !          2404:                varloc = stsym( pdef_sys[PD_SYS] );
        !          2405: 
        !          2406:        tf = fnames[ifno];              /* do the -D and -U options now */
        !          2407:        fnames[ifno] = "command line";
        !          2408:        lineno[ifno] = 1;
        !          2409:        cp2 = prespc;
        !          2410:        while ( cp2 < predef )
        !          2411:                stsym( *cp2++ );
        !          2412:        cp2 = punspc;
        !          2413:        while ( cp2 < prund )
        !          2414:        {
        !          2415:                if ( p = strchr( *cp2, '=' ) )
        !          2416:                        *p = '\0';
        !          2417:                /*
        !          2418:                * Truncate to ncps characters if needed.
        !          2419:                */
        !          2420:                if ( strlen( *cp2 ) > ncps )
        !          2421:                        (*cp2)[ncps] = '\0';
        !          2422:                lookup( *cp2++, DROP );
        !          2423:        }
        !          2424: 
        !          2425:        ulnloc = stsym( "__LINE__" );
        !          2426:        uflloc = stsym( "__FILE__" );
        !          2427:        fnames[ifno] = tf;
        !          2428:        pbeg = buffer + ncps;
        !          2429:        pbuf = pbeg + BUFSIZ;
        !          2430:        pend = pbuf + BUFSIZ;
        !          2431: 
        !          2432:        trulvl = 0;
        !          2433:        flslvl = 0;
        !          2434:        lineno[0] = 1;
        !          2435:        sayline();
        !          2436:        outp = inp = pend;
        !          2437: #ifdef CXREF
        !          2438:        ready = 1;
        !          2439: #endif
        !          2440:        control( pend );
        !          2441:        if ( fout && ferror( fout ) )
        !          2442:                pperror( "Problems with output file; probably out of temp space" );
        !          2443:        exit( exfail ? ( exfail == CLASSCODE ? CLASSCODE : 2 ) : 0 );
        !          2444: }
        !          2445:  
        !          2446: #ifdef CXREF
        !          2447: ref( name, line )
        !          2448:        char *name;
        !          2449:        int line;
        !          2450: {
        !          2451: #ifdef FLEXNAMES
        !          2452:        fprintf(outfp, "R%s\t%05d\n", name, line);
        !          2453: #else
        !          2454:        fprintf(outfp, "R%.8s\t%05d\n", name, line);
        !          2455: #endif
        !          2456: }
        !          2457: 
        !          2458: def( name, line )
        !          2459:        char *name;
        !          2460:        int line;
        !          2461: {
        !          2462:        if (ready)
        !          2463: #ifdef FLEXNAMES
        !          2464:                fprintf(outfp, "D%s\t%05d\n", name, line);
        !          2465: #else
        !          2466:                fprintf(outfp, "D%.8s\t%05d\n", name, line);
        !          2467: #endif
        !          2468: }
        !          2469: 
        !          2470: newf( name, line )
        !          2471:        char *name;
        !          2472:        int line;
        !          2473: {
        !          2474: #ifdef FLEXNAMES
        !          2475:        fprintf(outfp, "F%s\t%05d\n", name, line);
        !          2476: #else
        !          2477:        fprintf(outfp, "F%.8s\t%05d\n", name, line);
        !          2478: #endif
        !          2479: }
        !          2480: 
        !          2481: char *
        !          2482: xcopy( ptr1, ptr2 )
        !          2483:        register char *ptr1, *ptr2;
        !          2484: {
        !          2485:        static char name[NCPS];
        !          2486:        char *saveptr, ch;
        !          2487:        register char *ptr3 = name;
        !          2488: 
        !          2489:        /* locate end of name; save character there */
        !          2490:        if ((ptr2 - ptr1) > ncps)
        !          2491:        {
        !          2492:                saveptr = ptr1 + ncps;
        !          2493:                ch = *saveptr;
        !          2494:                *saveptr = '\0';
        !          2495:        }
        !          2496:        else {
        !          2497:                ch = *ptr2;
        !          2498:                *ptr2 = '\0';
        !          2499:                saveptr = ptr2;
        !          2500:        }
        !          2501:        while (*ptr3++ = *ptr1++) ;     /* copy name */
        !          2502:        *saveptr = ch;  /* replace character */
        !          2503:        return( name );
        !          2504: }
        !          2505: #endif
        !          2506: 
        !          2507: /* Scan over the end of a directive, making sure there's no
        !          2508: ** residual junk.
        !          2509: **
        !          2510: ** This code is a little messier than you might expect.  To avoid bumping
        !          2511: ** the line number when we hit the newline, print the message the first time
        !          2512: ** we find we've got too many tokens.
        !          2513: */
        !          2514: 
        !          2515: char *
        !          2516: chkend( p, ntoken )
        !          2517: char * p;
        !          2518: int ntoken;                            /* number of tokens at which to warn */
        !          2519: {
        !          2520:     int extratokens = 0;
        !          2521:     int save_passcom = passcom;
        !          2522: 
        !          2523:     passcom = 0;                       /* ignore comments in this context */
        !          2524:     ++flslvl;                          /* don't expand anything */
        !          2525: 
        !          2526:     /* if at newline, force rescan to do end-of-line stuff */
        !          2527:     if (*inp == '\n')
        !          2528:        p = inp;
        !          2529: 
        !          2530:     for (;;) {
        !          2531:        p = skipbl(p);          /* get next token */
        !          2532:        if (*inp == '\n')
        !          2533:            break;                      /* reached end */
        !          2534:        if(++extratokens == ntoken)     /* hit number of extras; flag here */
        !          2535:            ppwarn("extra tokens (ignored) after directive");
        !          2536:     }
        !          2537: 
        !          2538:     /* restore comment flag */
        !          2539:     passcom = save_passcom;
        !          2540:     --flslvl;                          /* back to previous expansion level */
        !          2541: 
        !          2542:     return( p );
        !          2543: }
        !          2544: 
        !          2545: char *
        !          2546: getfdate( fin )
        !          2547: FILE *fin;
        !          2548: {
        !          2549:        char date[ 10 ];
        !          2550:        struct stat sb;
        !          2551:        if ( !mflag )
        !          2552:                return "";
        !          2553:        fstat( fileno( fin ), &sb );
        !          2554:        sprintf( date, "@%ld", sb.st_mtime );
        !          2555:        return copy( date );
        !          2556: }
        !          2557: 
        !          2558: char *
        !          2559: findfdate( fname )
        !          2560: char *fname;
        !          2561: {
        !          2562:        register char *s;
        !          2563:        for ( s = fname; *s; s++ )
        !          2564:                if ( *s == '@' ) {
        !          2565:                        *s++ = 0;
        !          2566:                        break;
        !          2567:                }
        !          2568:        return s;
        !          2569: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.