|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.