Annotation of researchv10no/cmd/usgmake/gram.y, revision 1.1.1.1

1.1       root        1: 
                      2: /*      @(#)gram.y      3.6     */
                      3: %{#include "defs"
                      4: %}
                      5: 
                      6: %term NAME SHELLINE START COLON DOUBLECOLON EQUAL A_STRING VERSION
                      7: 
                      8: %union
                      9:         {
                     10:         SHBLOCK yshblock;
                     11:         DEPBLOCK ydepblock;
                     12:         NAMEBLOCK ynameblock;
                     13:         CHARSTAR ycharstring;
                     14:         }
                     15: 
                     16: %type   <yshblock>      SHELLINE, shlist, shellist
                     17: %type   <ynameblock>    NAME, namelist, name
                     18: %type   <ydepblock>     deplist, dlist
                     19: %type   <ycharstring>   A_STRING
                     20: 
                     21: 
                     22: %%
                     23: 
                     24: %{
                     25: DEPBLOCK pp;
                     26: FSTATIC SHBLOCK prevshp;
                     27: 
                     28: FSTATIC NAMEBLOCK lefts[NLEFTS];
                     29: NAMEBLOCK leftp;
                     30: FSTATIC int nlefts;
                     31: 
                     32: LINEBLOCK lp, lpp;
                     33: FSTATIC DEPBLOCK prevdep;
                     34: FSTATIC int sepc;
                     35: %}
                     36: 
                     37: 
                     38: file:
                     39:         | file comline
                     40:         ;
                     41: 
                     42: comline:  START
                     43:         | START macrodef
                     44:         | START namelist deplist shellist = {
                     45:             if(mainname == NULL && IS_OFF(INTRULE))
                     46:                 if(lefts[0]->namep[0] != DOT || any(lefts[0]->namep, SLASH) )
                     47:                         mainname = lefts[0];
                     48:             while( --nlefts >= 0)
                     49:             {
                     50:                 leftp = lefts[nlefts];
                     51:                 if(leftp->septype == 0)
                     52:                         leftp->septype = sepc;
                     53:                 else if(leftp->septype != sepc)
                     54:                         fprintf(stderr, "Inconsistent rules lines for `%s'\n",
                     55:                                 leftp->namep);
                     56:                 else if(sepc==ALLDEPS && *(leftp->namep)!=DOT && $4!=0)
                     57:                 {
                     58:                         for(lp=leftp->linep; lp->nextline!=0; lp=lp->nextline)
                     59:                             if(lp->shp)
                     60:                                 fprintf(stderr, "Multiple rules lines for `%s'\n",
                     61:                                     leftp->namep);
                     62:                 }
                     63: 
                     64:                 lp = ALLOC(lineblock);
                     65:                 lp->nextline = 0;
                     66:                 lp->depp = $3;
                     67:                 lp->shp = $4;
                     68: 
                     69:                 if(equal(leftp->namep, ".SUFFIXES") && $3==0)
                     70:                         leftp->linep = 0;
                     71:                 else if(leftp->linep == 0)
                     72:                         leftp->linep = lp;
                     73:                 else
                     74:                 {
                     75:                         for(lpp = leftp->linep; lpp->nextline!=0;
                     76:                                 lpp = lpp->nextline) ;
                     77:                                 if(sepc==ALLDEPS && leftp->namep[0]==DOT)
                     78:                                         lpp->shp = 0;
                     79:                         lpp->nextline = lp;
                     80:                 }
                     81:             }
                     82:         }
                     83:         | error
                     84:         ;
                     85: 
                     86: macrodef:       NAME EQUAL A_STRING =
                     87:         {
                     88:                 setvar($1, $3);
                     89:         }
                     90:         ;
                     91: 
                     92: namelist: name  = { lefts[0] = $1; nlefts = 1; }
                     93:         | namelist name = { lefts[nlefts++] = $2;
                     94:                 if(nlefts>NLEFTS) fatal("Too many lefts"); }
                     95:         ;
                     96: 
                     97: name:   NAME =
                     98:         {
                     99:         if(($$ = srchname($1)) == 0)
                    100:                 $$ = makename($1);
                    101:         }
                    102:         | NAME VERSION = 
                    103:         {
                    104:         if(($$ = srchname($1)) == 0)
                    105:                 $$ = makename($1);
                    106:         }
                    107:         ;
                    108: 
                    109: deplist:        = { fatal1("Must be a separator on rules line %d", yylineno); }
                    110:         | dlist
                    111:         ;
                    112: 
                    113: dlist:  sepchar = { prevdep = 0;  $$ = 0; }
                    114:         | dlist name    = {
                    115:                           pp = ALLOC(depblock);
                    116:                           pp->nextdep = 0;
                    117:                           pp->depname = $2;
                    118:                           if(prevdep == 0) $$ = pp;
                    119:                           else  prevdep->nextdep = pp;
                    120:                           prevdep = pp;
                    121:                           }
                    122:         ;
                    123: 
                    124: sepchar:  COLON         = { sepc = ALLDEPS; }
                    125:         | DOUBLECOLON   = { sepc = SOMEDEPS; }
                    126:         ;
                    127: 
                    128: shellist:       = {$$ = 0; }
                    129:         | shlist = { $$ = $1; }
                    130:         ;
                    131: 
                    132: shlist: SHELLINE   = { $$ = $1;  prevshp = $1; }
                    133:         | shlist SHELLINE = { $$ = $1;
                    134:                         prevshp->nextsh = $2;
                    135:                         prevshp = $2;
                    136:                         }
                    137:         ;
                    138: 
                    139: 
                    140: %%
                    141: 
                    142: /*      @(#)lex.c       3.1     */
                    143: 
                    144: #include "ctype.h"
                    145: CHARSTAR zznextc;       /* zero if need another line; otherwise points to next char */
                    146: int yylineno;
                    147: static char inmacro = NO;
                    148: 
                    149: yylex()
                    150: {
                    151:         register CHARSTAR p;
                    152:         register CHARSTAR q;
                    153:         static char word[128];
                    154:         CHARSTAR pword;
                    155: 
                    156:         pword = word;
                    157:         if(zznextc == 0)
                    158:                 return( nextlin() );
                    159: 
                    160:         while( isspace(*zznextc) )
                    161:                 ++zznextc;
                    162: 
                    163:         if(inmacro == YES)
                    164:         {
                    165:                 inmacro = NO;
                    166:                 yylval.ycharstring = copys(zznextc);
                    167:                 zznextc = 0;
                    168:                 return(A_STRING);
                    169:         }
                    170: 
                    171:         if(*zznextc == CNULL)
                    172:                 return( nextlin() );
                    173: 
                    174:         if(*zznextc == KOLON)
                    175:         {
                    176:                 if(*++zznextc == KOLON)
                    177:                 {
                    178:                         ++zznextc;
                    179:                         return(DOUBLECOLON);
                    180:                 }
                    181:                 else
                    182:                         return(COLON);
                    183:         }
                    184: 
                    185:         if(*zznextc == EQUALS)
                    186:         {
                    187:                 inmacro = YES;
                    188:                 ++zznextc;
                    189:                 return(EQUAL);
                    190:         }
                    191: 
                    192:         if(*zznextc == SKOLON)
                    193:                 return( retsh(zznextc) );
                    194: 
                    195:         p = zznextc;
                    196:         q = word;
                    197: 
                    198:         while( ! ( funny[*p] & TERMINAL) )
                    199:                 *q++ = *p++;
                    200: 
                    201:         if(p != zznextc)
                    202:         {
                    203:                 *q = CNULL;
                    204:                 yylval.ycharstring = copys(pword);
                    205:                 if(*p == RCURLY)
                    206:                 {
                    207:                         zznextc = p+1;
                    208:                         return(VERSION);
                    209:                 }
                    210:                 if(*p == LCURLY)
                    211:                         p++;
                    212:                 zznextc = p;
                    213:                 return(NAME);
                    214:                 }
                    215: 
                    216:         else
                    217:         {
                    218:                 fprintf(stderr,"Bad character %c (octal %o), line %d",
                    219:                         *zznextc,*zznextc,yylineno);
                    220:                 fatal(Nullstr);
                    221:         }
                    222:         return(0);      /* never executed */
                    223: }
                    224: 
                    225: 
                    226: retsh(q)
                    227: register CHARSTAR q;
                    228: {
                    229:         register CHARSTAR p;
                    230:         register int c;
                    231:         extern CHARSTAR *linesptr;
                    232:         SHBLOCK sp;
                    233: 
                    234:         for(p=q+1 ; *p==BLANK||*p==TAB ; ++p)  ;
                    235: 
                    236:         sp = ALLOC(shblock);
                    237:         sp->nextsh = 0;
                    238:         sp->shbp = (fin == NULL ? p : copys(p) );
                    239:         yylval.yshblock = sp;
                    240:         zznextc = 0;
                    241: /*
                    242:  *      The following if-else "thing" eats up newlines within
                    243:  *      shell blocks.
                    244:  */
                    245:         if(fin == NULL)
                    246:         {
                    247:                 if(linesptr[0])
                    248:                         while(linesptr[1] && equal(linesptr[1], "\n"))
                    249:                         {
                    250:                                 yylineno++;
                    251:                                 linesptr++;
                    252:                         }
                    253:         }
                    254:         else
                    255:         {
                    256:                 while((c = GETC()) == NEWLINE)
                    257:                         yylineno++;
                    258:                 if(c != EOF)
                    259:                         ungetc(c, fin);
                    260:         }
                    261:         return(SHELLINE);
                    262: }
                    263: 
                    264: nextlin()
                    265: {
                    266:         register char c;
                    267:         register CHARSTAR p, t;
                    268:         static char yytext[INMAX];
                    269:         static CHARSTAR yytextl = yytext+INMAX;
                    270:         CHARSTAR text;
                    271:         char templin[INMAX];
                    272:         char lastch;
                    273:         CHARSTAR lastchp;
                    274:         extern CHARSTAR *linesptr;
                    275:         int incom;
                    276:         int kc;
                    277:         int nflg;
                    278:         int poundflg;
                    279: 
                    280: again:
                    281:         incom = 0;
                    282:         zznextc = 0;
                    283:         poundflg = 0;
                    284: 
                    285:         if(fin == NULL)
                    286:         {
                    287:                 if( (text = *linesptr++) == 0)
                    288:                         return(0);
                    289:                 ++yylineno;
                    290:                 copstr(yytext, text);
                    291:         }
                    292: 
                    293:         else
                    294:         {
                    295:                 yytext[0] = CNULL;
                    296:                 for(p=yytext ; ; ++p)
                    297:                 {
                    298:                         if(p > yytextl)
                    299:                                 fatal("line too long");
                    300:                         kc = GETC();
                    301:                         if(kc == EOF)
                    302:                         {
                    303:                                 *p = CNULL;
                    304:                                 return(0);
                    305:                         }
                    306:                         else if(kc == SKOLON)
                    307:                                 ++incom;
                    308:                         else if (kc == TAB && p == yytext)
                    309:                                 ++incom;
                    310:                         else if (kc==POUND && !incom && yytext[0] != TAB)
                    311:                         {
                    312:                                 poundflg++;
                    313:                                 kc = CNULL;
                    314:                         }
                    315:                         else if (kc == NEWLINE)
                    316:                         {
                    317:                                 ++yylineno;
                    318:                                 if(p==yytext || p[-1]!=BACKSLASH)
                    319:                                         break;
                    320:                                 if(incom || yytext[0] == TAB)
                    321:                                         *p++ = NEWLINE;
                    322:                                 else
                    323:                                         p[-1] = BLANK;
                    324:                                 nflg = YES;
                    325:                                 while( kc = GETC())
                    326:                                 {
                    327:                                         if(kc != TAB && kc != BLANK && kc != NEWLINE)
                    328:                                                 break;
                    329:                                         if(incom || yytext[0] == TAB)
                    330:                                         {
                    331:                                                 if(nflg == YES && kc == TAB)
                    332:                                                 {
                    333:                                                         nflg = NO;
                    334:                                                         continue;
                    335:                                                 }
                    336:                                                 if(kc == NEWLINE)
                    337:                                                 {
                    338:                                                         nflg = YES;
                    339:                                                 }
                    340: 
                    341:                                                 *p++ = kc;
                    342:                                         }
                    343:                                         if(kc == NEWLINE)
                    344:                                                 ++yylineno;
                    345:                                 }
                    346: 
                    347:                                 if(kc == EOF)
                    348:                                 {
                    349:                                         *p = CNULL;
                    350:                                         return(0);
                    351:                                 }
                    352:                         }
                    353:                         *p = kc;
                    354:                 }
                    355:                 *p = CNULL;
                    356:                 text = yytext;
                    357:         }
                    358: 
                    359:         c = text[0];
                    360: 
                    361:         if(c == TAB)  
                    362:                 return( retsh(text) );
                    363: 
                    364: /*
                    365:  *      DO include FILES HERE.
                    366:  */
                    367:         if(sindex(text, "include") == 0 && (text[7] == BLANK || text[7] == TAB))
                    368:         {
                    369:                 CHARSTAR pfile;
                    370: 
                    371:                 for(p = &text[8]; *p != CNULL; p++)
                    372:                         if(*p != TAB ||
                    373:                            *p != BLANK)
                    374:                                 break;
                    375:                 pfile = p;
                    376:                 for(;   *p != CNULL     &&
                    377:                         *p != NEWLINE   &&
                    378:                         *p != TAB       &&
                    379:                         *p != BLANK; p++);
                    380:                 if(*p != CNULL)
                    381:                         *p = CNULL;
                    382: 
                    383: /*
                    384:  *      Start using new file.
                    385:  */
                    386:                 fstack(pfile, &fin, &yylineno);
                    387:                 goto again;
                    388:         }
                    389:         if(isalpha(c) || isdigit(c) || c==BLANK || c==DOT)
                    390:                 for(p=text+1; *p!=CNULL; p++)
                    391:                         if(*p == KOLON || *p == EQUALS)
                    392:                                 break;
                    393: 
                    394: /* substtitute for macros on dependency line up to the semicolon if any */
                    395:         if(*p != EQUALS)
                    396:         {
                    397:                 for(t = yytext ; *t!=CNULL && *t!=SKOLON ; ++t);
                    398: 
                    399:                 lastchp = t;
                    400:                 lastch = *t;
                    401:                 *t = CNULL;
                    402: 
                    403:                 subst(yytext, templin); /* Substitute for macros on dep lines */
                    404: 
                    405:                 if(lastch)
                    406:                 {
                    407:                         for(t = templin ; *t ; ++t);
                    408:                         *t = lastch;
                    409:                         while( *++t = *++lastchp ) ;
                    410:                 }
                    411: 
                    412:                 p = templin;
                    413:                 t = yytext;
                    414:                 while( *t++ = *p++ );
                    415:         }
                    416: 
                    417:         if(poundflg == 0 || yytext[0] != CNULL)
                    418:         {
                    419:                 zznextc = text;
                    420:                 return(START);
                    421:         }
                    422:         else
                    423:                 goto again;
                    424: }
                    425: 
                    426: #include "stdio.h"
                    427: 
                    428: /*
                    429:  *      GETC automatically unravels stacked include files. That is,
                    430:  *      during include file processing, when a new file is encountered
                    431:  *      fstack will stack the FILE pointer argument. Subsequent
                    432:  *      calls to GETC with the new FILE pointer will get characters
                    433:  *      from the new file. When an EOF is encountered, GETC will
                    434:  *      check to see if the file pointer has been stacked. If so,
                    435:  *      a character from the previous file will be returned.
                    436:  *      The external references are "GETC()" and "fstack(fname,stream,lno)".
                    437:  *      "Fstack(stfname,ream,lno)" is used to stack an old file pointer before
                    438:  *      the new file is assigned to the same variable. Also stacked are the
                    439:  *      file name and the old current lineno, generally, yylineno.
                    440:  */
                    441: 
                    442: 
                    443: 
                    444: static int morefiles;
                    445: static struct sfiles
                    446: {
                    447:         char sfname[64];
                    448:         FILE *sfilep;
                    449:         int syylno;
                    450: } sfiles[20];
                    451: 
                    452: GETC()
                    453: {
                    454:         register int c;
                    455: 
                    456:         c = getc(fin);
                    457:         while(c == EOF && morefiles)
                    458:         {
                    459:                 fclose(fin);
                    460:                 yylineno = sfiles[--morefiles].syylno;
                    461:                 fin = sfiles[morefiles].sfilep;
                    462:                 c = getc(fin);
                    463:         }
                    464:         return(c);
                    465: }
                    466: fstack(newname, oldfp, oldlno)
                    467: register char *newname;
                    468: register FILE **oldfp;
                    469: register int *oldlno;
                    470: {
                    471:         if(access(newname, 4) != 0)
                    472: /*
                    473:  *      This get line can be removed if used elsewhere than make.
                    474:  */
                    475:         if(get(newname, CD, Nullstr) == NO)
                    476:                 fatal1("Cannot read or get %s", newname);
                    477:         if(IS_ON(DBUG))
                    478:                 printf("Include file: \"%s\"\n", newname);
                    479: /*
                    480:  *      Stack the new file name, the old file pointer and the
                    481:  *      old yylineno;
                    482:  */
                    483:         strcat(sfiles[morefiles].sfname, newname);
                    484:         sfiles[morefiles].sfilep = *oldfp;
                    485:         sfiles[morefiles++].syylno = *oldlno;
                    486:         yylineno = 0;
                    487:         if((*oldfp=fopen(newname, "r")) == NULL)
                    488:                 fatal1("Cannot open %s", newname);
                    489: }
                    490: 

unix.superglobalmegacorp.com

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