Annotation of researchv10no/cmd/cpp/cpp.c, revision 1.1.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.