|
|
1.1 ! root 1: %{#include "defs" ! 2: static char *sccsid = "@(#)gram.y 8th Edition (Bell Labs) 85/05/14"; ! 3: %} ! 4: ! 5: %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER AMPER AMPERAMPER ! 6: %union ! 7: { ! 8: struct shblock *yshblock; ! 9: depblkp ydepblock; ! 10: nameblkp ynameblock; ! 11: } ! 12: ! 13: %type <yshblock> SHELLINE, shlist, shellist ! 14: %type <ynameblock> NAME, namelist ! 15: %type <ydepblock> deplist, dlist ! 16: ! 17: ! 18: %% ! 19: ! 20: %{ ! 21: struct depblock *pp; ! 22: FSTATIC struct shblock *prevshp; ! 23: ! 24: FSTATIC struct nameblock *lefts[NLEFTS]; ! 25: struct nameblock *leftp; ! 26: FSTATIC int nlefts; ! 27: ! 28: struct lineblock *lp, *lpp; ! 29: FSTATIC struct depblock *prevdep; ! 30: FSTATIC int sepc; ! 31: FSTATIC int allnowait; ! 32: ! 33: FSTATIC struct fstack ! 34: { ! 35: FILE *fin; ! 36: char *fname; ! 37: int lineno; ! 38: } filestack[MAXINCLUDE]; ! 39: FSTATIC int ninclude = 0; ! 40: %} ! 41: ! 42: ! 43: file: ! 44: | file comline ! 45: ; ! 46: ! 47: comline: START ! 48: | MACRODEF ! 49: | START namelist deplist shellist = { ! 50: while( --nlefts >= 0) ! 51: { ! 52: wildp iswild(), wp; ! 53: ! 54: leftp = lefts[nlefts]; ! 55: if(wp = iswild(leftp->namep)) ! 56: { ! 57: leftp->septype = SOMEDEPS; ! 58: if(lastwild) ! 59: lastwild->next = wp; ! 60: else ! 61: firstwild = wp; ! 62: lastwild = wp; ! 63: } ! 64: ! 65: if(leftp->septype == 0) ! 66: leftp->septype = sepc; ! 67: else if(leftp->septype != sepc) ! 68: { ! 69: if(! wp) ! 70: fprintf(stderr, ! 71: "Inconsistent rules lines for `%s'\n", ! 72: leftp->namep); ! 73: } ! 74: else if(sepc==ALLDEPS && leftp->namep[0]!='.' && $4!=0) ! 75: { ! 76: for(lp=leftp->linep; lp->nxtlineblock; lp=lp->nxtlineblock) ! 77: if(lp->shp) ! 78: fprintf(stderr, ! 79: "Multiple rules lines for `%s'\n", ! 80: leftp->namep); ! 81: } ! 82: ! 83: lp = ALLOC(lineblock); ! 84: lp->nxtlineblock = NULL; ! 85: lp->depp = $3; ! 86: lp->shp = $4; ! 87: if(wp) ! 88: wp->linep = lp; ! 89: ! 90: if(equal(leftp->namep, ".SUFFIXES") && $3==0) ! 91: leftp->linep = 0; ! 92: else if(leftp->linep == 0) ! 93: leftp->linep = lp; ! 94: else { ! 95: for(lpp = leftp->linep; lpp->nxtlineblock; ! 96: lpp = lpp->nxtlineblock) ; ! 97: if(sepc==ALLDEPS && leftp->namep[0]=='.') ! 98: lpp->shp = 0; ! 99: lpp->nxtlineblock = lp; ! 100: } ! 101: } ! 102: } ! 103: | error ! 104: ; ! 105: ! 106: namelist: NAME = { lefts[0] = $1; nlefts = 1; } ! 107: | namelist NAME = { lefts[nlefts++] = $2; ! 108: if(nlefts>=NLEFTS) fatal("Too many lefts"); } ! 109: ; ! 110: ! 111: deplist: ! 112: { ! 113: char junk[10]; ! 114: sprintf(junk, "%d", yylineno); ! 115: fatal1("Must be a separator on rules line %s", junk); ! 116: } ! 117: | dlist ! 118: ; ! 119: ! 120: dlist: sepchar = { prevdep = 0; $$ = 0; allnowait = NO; } ! 121: | sepchar AMPER = { prevdep = 0; $$ = 0; allnowait = YES; } ! 122: | dlist NAME = { ! 123: pp = ALLOC(depblock); ! 124: pp->nxtdepblock = NULL; ! 125: pp->depname = $2; ! 126: pp->nowait = allnowait; ! 127: if(prevdep == 0) $$ = pp; ! 128: else prevdep->nxtdepblock = pp; ! 129: prevdep = pp; ! 130: } ! 131: | dlist AMPER = { if(prevdep) prevdep->nowait = YES; } ! 132: | dlist AMPERAMPER ! 133: ; ! 134: ! 135: sepchar: COLON = { sepc = ALLDEPS; } ! 136: | DOUBLECOLON = { sepc = SOMEDEPS; } ! 137: ; ! 138: ! 139: shellist: = {$$ = 0; } ! 140: | shlist = { $$ = $1; } ! 141: ; ! 142: ! 143: shlist: SHELLINE = { $$ = $1; prevshp = $1; } ! 144: | shlist SHELLINE = { $$ = $1; ! 145: prevshp->nxtshblock = $2; ! 146: prevshp = $2; ! 147: } ! 148: ; ! 149: ! 150: %% ! 151: ! 152: FSTATIC char *zznextc; /* null if need another line; ! 153: otherwise points to next char */ ! 154: FSTATIC int yylineno; ! 155: FSTATIC FILE * fin; ! 156: ! 157: parse(name) ! 158: char *name; ! 159: { ! 160: extern int yylineno; ! 161: FILE *stream; ! 162: extern char *zznextc; ! 163: ! 164: if(name == CHNULL) ! 165: { ! 166: stream = NULL; ! 167: name = "(builtin-rules)"; ! 168: } ! 169: else if(equal(name, "-")) ! 170: { ! 171: stream = stdin; ! 172: name = "(stdin)"; ! 173: } ! 174: else if( (stream = fopen(name, "r")) == NULL) ! 175: return NO; ! 176: filestack[0].fname = copys(name); ! 177: ninclude = 1; ! 178: fin = stream; ! 179: yylineno = 0; ! 180: zznextc = 0; ! 181: ! 182: if( yyparse() ) ! 183: fatal("Description file error"); ! 184: ! 185: if(fin) ! 186: fclose(fin); ! 187: return YES; ! 188: } ! 189: ! 190: ! 191: yylex() ! 192: { ! 193: register char *p; ! 194: register char *q; ! 195: char word[INMAX]; ! 196: ! 197: if(! zznextc ) ! 198: return nextlin() ; ! 199: ! 200: while( isspace(*zznextc) ) ! 201: ++zznextc; ! 202: switch(*zznextc) ! 203: { ! 204: case '\0': ! 205: return nextlin() ; ! 206: ! 207: case '|': ! 208: if(zznextc[1]==':') ! 209: { ! 210: zznextc += 2; ! 211: return DOUBLECOLON; ! 212: } ! 213: break; ! 214: case ':': ! 215: if(*++zznextc == ':') ! 216: { ! 217: ++zznextc; ! 218: return DOUBLECOLON; ! 219: } ! 220: return COLON; ! 221: case '>': ! 222: ++zznextc; ! 223: return GREATER; ! 224: case '&': ! 225: if(*++zznextc == '&') ! 226: { ! 227: ++zznextc; ! 228: return AMPERAMPER; ! 229: } ! 230: return AMPER; ! 231: case ';': ! 232: return retsh(zznextc) ; ! 233: } ! 234: ! 235: p = zznextc; ! 236: q = word; ! 237: ! 238: while( ! ( funny[*p] & TERMINAL) ) ! 239: *q++ = *p++; ! 240: ! 241: if(p != zznextc) ! 242: { ! 243: *q = '\0'; ! 244: if((yylval.ynameblock=srchname(word))==0) ! 245: yylval.ynameblock = makename(word); ! 246: zznextc = p; ! 247: return NAME; ! 248: } ! 249: ! 250: else { ! 251: char junk[100]; ! 252: sprintf(junk, "Bad character %c (octal %o), line %d of file %s", ! 253: *zznextc, *zznextc, yylineno, filestack[ninclude-1].fname); ! 254: fatal(junk); ! 255: } ! 256: return 0; /* never executed */ ! 257: } ! 258: ! 259: ! 260: ! 261: ! 262: ! 263: retsh(q) ! 264: char *q; ! 265: { ! 266: register char *p; ! 267: struct shblock *sp; ! 268: char *copys(); ! 269: ! 270: for(p=q+1 ; *p==' '||*p=='\t' ; ++p) ; ! 271: ! 272: sp = ALLOC(shblock); ! 273: sp->nxtshblock = NULL; ! 274: sp->shbp = (fin ? copys(p) : p ); ! 275: yylval.yshblock = sp; ! 276: zznextc = 0; ! 277: return SHELLINE; ! 278: } ! 279: ! 280: nextlin() ! 281: { ! 282: static char yytext[INMAX]; ! 283: static char *yytextl = yytext+INMAX; ! 284: char *text, templin[INMAX]; ! 285: register char c; ! 286: register char *p, *t; ! 287: char lastch, *lastchp; ! 288: extern char **linesptr; ! 289: int incom; ! 290: int kc; ! 291: ! 292: again: ! 293: ! 294: incom = NO; ! 295: zznextc = 0; ! 296: ! 297: if(fin == NULL) ! 298: { ! 299: if( (text = *linesptr++) == 0) ! 300: return 0; ! 301: ++yylineno; ! 302: } ! 303: ! 304: else { ! 305: for(p = text = yytext ; p<yytextl ; *p++ = kc) ! 306: switch(kc = getc(fin)) ! 307: { ! 308: case '\t': ! 309: if(p == yytext) ! 310: incom = YES; ! 311: break; ! 312: ! 313: case ';': ! 314: incom = YES; ! 315: break; ! 316: ! 317: case '#': ! 318: if(! incom) ! 319: kc = '\0'; ! 320: break; ! 321: ! 322: case '\n': ! 323: ++yylineno; ! 324: if(p==yytext || p[-1]!='\\') ! 325: { ! 326: *p = '\0'; ! 327: goto endloop; ! 328: } ! 329: p[-1] = ' '; ! 330: while( (kc=getc(fin))=='\t' || kc==' ' || kc=='\n') ! 331: if(kc == '\n') ! 332: ++yylineno; ! 333: ! 334: if(kc != EOF) ! 335: break; ! 336: case EOF: ! 337: *p = '\0'; ! 338: if(ninclude > 1) ! 339: { ! 340: register struct fstack *stp; ! 341: fclose(fin); ! 342: --ninclude; ! 343: stp = filestack + ninclude; ! 344: fin = stp->fin; ! 345: yylineno = stp->lineno; ! 346: free(stp->fname); ! 347: goto again; ! 348: } ! 349: return 0; ! 350: } ! 351: ! 352: fatal("line too long"); ! 353: } ! 354: ! 355: endloop: ! 356: ! 357: if((c = text[0]) == '\t') ! 358: return retsh(text) ; ! 359: ! 360: if(isalpha(c) || isdigit(c) || c==' ' || c=='.') ! 361: for(p=text+1; *p!='\0'; ) ! 362: if(*p == ':') ! 363: break; ! 364: else if(*p++ == '=') ! 365: { ! 366: eqsign(text); ! 367: return MACRODEF; ! 368: } ! 369: ! 370: ! 371: if(!strncmp(text, "include", 7) && isinclude(text+7)) ! 372: goto again; ! 373: ! 374: /* substitute for macros on dependency line up to the semicolon if any */ ! 375: ! 376: for(t = yytext ; *t!='\0' && *t!=';' ; ++t) ! 377: ; ! 378: ! 379: lastchp = t; ! 380: lastch = *t; ! 381: *t = '\0'; /* replace the semi with a null so subst will stop */ ! 382: ! 383: subst(yytext, templin); /* Substitute for macros on dependency lines */ ! 384: ! 385: if(lastch) /* copy the stuff after the semicolon */ ! 386: { ! 387: *lastchp = lastch; ! 388: strcat(templin, lastchp); ! 389: } ! 390: ! 391: strcpy(yytext, templin); ! 392: ! 393: for(p = zznextc = text ; *p ; ++p ) ! 394: if(*p!=' ' && *p!='\t') ! 395: return START; ! 396: goto again; ! 397: } ! 398: ! 399: ! 400: ! 401: isinclude(s) ! 402: register char *s; ! 403: { ! 404: register char *t; ! 405: register struct fstack *p; ! 406: ! 407: for(t=s; *t==' ' || *t=='\t' ; ++t) ! 408: ; ! 409: if(t == s) ! 410: return NO; ! 411: ! 412: for(s = t; *s!='\n' && *s!='#' && *s!='\0' ; ++s) ! 413: if(*s == ':') ! 414: return NO; ! 415: *s = '\0'; ! 416: ! 417: if(ninclude >= MAXINCLUDE) ! 418: fatal("include depth exceeded"); ! 419: p = filestack + ninclude; ! 420: p->fin = fin; ! 421: p->lineno = yylineno; ! 422: p->fname = copys(t); ! 423: if( (fin = fopen(t, "r")) == NULL) ! 424: fatal1("Cannot open include file %s", t); ! 425: yylineno = 0; ! 426: ++ninclude; ! 427: return YES; ! 428: } ! 429: ! 430: ! 431: ! 432: yyerror(s) ! 433: char *s; ! 434: { ! 435: char buf[100]; ! 436: ! 437: sprintf(buf, "line %d of file %s: %s", ! 438: yylineno, filestack[ninclude-1].fname, s); ! 439: fatal(buf); ! 440: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.