1: %{#include "defs"
2: %}
3:
4: %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER
5: %union
6: {
7: struct shblock *yshblock;
8: struct depblock *ydepblock;
9: struct nameblock *ynameblock;
10: }
11:
12: %type <yshblock> SHELLINE, shlist, shellist
13: %type <ynameblock> NAME, namelist
14: %type <ydepblock> deplist, dlist
15:
16:
17: %%
18:
19: %{
20: struct depblock *pp;
21: FSTATIC struct shblock *prevshp;
22:
23: FSTATIC struct nameblock *lefts[NLEFTS];
24: struct nameblock *leftp;
25: FSTATIC int nlefts;
26:
27: struct lineblock *lp, *lpp;
28: FSTATIC struct depblock *prevdep;
29: FSTATIC int sepc;
30: %}
31:
32:
33: file:
34: | file comline
35: ;
36:
37: comline: START
38: | MACRODEF
39: | START namelist deplist shellist = {
40: while( --nlefts >= 0)
41: {
42: leftp = lefts[nlefts];
43: if(leftp->septype == 0)
44: leftp->septype = sepc;
45: else if(leftp->septype != sepc)
46: fprintf(stderr, "Inconsistent rules lines for `%s'\n",
47: leftp->namep);
48: else if(sepc==ALLDEPS && *(leftp->namep)!='.' && $4!=0)
49: {
50: for(lp=leftp->linep; lp->nxtlineblock!=0; lp=lp->nxtlineblock)
51: if(lp->shp)
52: fprintf(stderr, "Multiple rules lines for `%s'\n",
53: leftp->namep);
54: }
55:
56: lp = ALLOC(lineblock);
57: lp->nxtlineblock = NULL;
58: lp->depp = $3;
59: lp->shp = $4;
60:
61: if(! unequal(leftp->namep, ".SUFFIXES") && $3==0)
62: leftp->linep = 0;
63: else if(leftp->linep == 0)
64: leftp->linep = lp;
65: else {
66: for(lpp = leftp->linep; lpp->nxtlineblock;
67: lpp = lpp->nxtlineblock) ;
68: if(sepc==ALLDEPS && leftp->namep[0]=='.')
69: lpp->shp = 0;
70: lpp->nxtlineblock = lp;
71: }
72: }
73: }
74: | error
75: ;
76:
77: namelist: NAME = { lefts[0] = $1; nlefts = 1; }
78: | namelist NAME = { lefts[nlefts++] = $2;
79: if(nlefts>NLEFTS) fatal("Too many lefts"); }
80: ;
81:
82: deplist:
83: {
84: char junk[10];
85: sprintf(junk, "%d", yylineno);
86: fatal1("Must be a separator on rules line %s", junk);
87: }
88: | dlist
89: ;
90:
91: dlist: sepchar = { prevdep = 0; $$ = 0; }
92: | dlist NAME = {
93: pp = ALLOC(depblock);
94: pp->nxtdepblock = NULL;
95: pp->depname = $2;
96: if(prevdep == 0) $$ = pp;
97: else prevdep->nxtdepblock = pp;
98: prevdep = pp;
99: }
100: ;
101:
102: sepchar: COLON = { sepc = ALLDEPS; }
103: | DOUBLECOLON = { sepc = SOMEDEPS; }
104: ;
105:
106: shellist: = {$$ = 0; }
107: | shlist = { $$ = $1; }
108: ;
109:
110: shlist: SHELLINE = { $$ = $1; prevshp = $1; }
111: | shlist SHELLINE = { $$ = $1;
112: prevshp->nxtshblock = $2;
113: prevshp = $2;
114: }
115: ;
116:
117: %%
118:
119: char *zznextc; /* zero if need another line; otherwise points to next char */
120: int yylineno;
121: extern FILE * fin;
122:
123: yylex()
124: {
125: register char *p;
126: register char *q;
127: char word[INMAX];
128:
129: if(zznextc == 0)
130: return( nextlin() );
131:
132: while( isspace(*zznextc) )
133: ++zznextc;
134:
135: if(*zznextc == '\0')
136: return( nextlin() );
137:
138: if(*zznextc == ':')
139: {
140: if(*++zznextc == ':')
141: {
142: ++zznextc;
143: return(DOUBLECOLON);
144: }
145: else return(COLON);
146: }
147:
148: if(*zznextc == '>')
149: {
150: ++zznextc;
151: return(GREATER);
152: }
153:
154: if(*zznextc == ';')
155: return( retsh(zznextc) );
156:
157: p = zznextc;
158: q = word;
159:
160: while( ! ( funny[*p] & TERMINAL) )
161: *q++ = *p++;
162:
163: if(p != zznextc)
164: {
165: *q = '\0';
166: if((yylval.ynameblock=srchname(word))==0)
167: yylval.ynameblock = makename(word);
168: zznextc = p;
169: return(NAME);
170: }
171:
172: else {
173: fprintf(stderr,"Bad character %c (octal %o), line %d",
174: *zznextc,*zznextc,yylineno);
175: fatal( (char *) NULL );
176: }
177: return(0); /* never executed */
178: }
179:
180:
181:
182:
183:
184: retsh(q)
185: char *q;
186: {
187: register char *p;
188: struct shblock *sp;
189: char *copys();
190:
191: for(p=q+1 ; *p==' '||*p=='\t' ; ++p) ;
192:
193: sp = ALLOC(shblock);
194: sp->nxtshblock = NULL;
195: sp->shbp = (fin == NULL ? p : copys(p) );
196: yylval.yshblock = sp;
197: zznextc = 0;
198: return(SHELLINE);
199: }
200:
201: nextlin()
202: {
203: static char yytext[INMAX];
204: static char *yytextl = yytext+INMAX;
205: char *text, templin[INMAX];
206: register char c;
207: register char *p, *t;
208: char lastch, *lastchp;
209: extern char **linesptr;
210: int incom;
211: int kc;
212:
213: again:
214:
215: incom = NO;
216: zznextc = 0;
217:
218: if(fin == NULL)
219: {
220: if( (text = *linesptr++) == 0)
221: return(0);
222: ++yylineno;
223: }
224:
225: else {
226: for(p = text = yytext ; p<yytextl ; *p++ = kc)
227: switch(kc = getc(fin))
228: {
229: case '\t':
230: if(p != yytext)
231: break;
232: case ';':
233: incom = YES;
234: break;
235:
236: case '#':
237: if(! incom)
238: kc = '\0';
239: break;
240:
241: case '\n':
242: ++yylineno;
243: if(p==yytext || p[-1]!='\\')
244: {
245: *p = '\0';
246: goto endloop;
247: }
248: p[-1] = ' ';
249: while( (kc=getc(fin))=='\t' || kc==' ' || kc=='\n')
250: if(kc == '\n')
251: ++yylineno;
252:
253: if(kc != EOF)
254: break;
255: case EOF:
256: *p = '\0';
257: return(0);
258: }
259:
260: fatal("line too long");
261: }
262:
263: endloop:
264:
265: if((c = text[0]) == '\t')
266: return( retsh(text) );
267:
268: if(isalpha(c) || isdigit(c) || c==' ' || c=='.')
269: for(p=text+1; *p!='\0'; )
270: if(*p == ':')
271: break;
272: else if(*p++ == '=')
273: {
274: eqsign(text);
275: return(MACRODEF);
276: }
277:
278: /* substitute for macros on dependency line up to the semicolon if any */
279:
280: for(t = yytext ; *t!='\0' && *t!=';' ; ++t)
281: ;
282:
283: lastchp = t;
284: lastch = *t;
285: *t = '\0';
286:
287: subst(yytext, templin); /* Substitute for macros on dependency lines */
288:
289: if(lastch)
290: {
291: for(t = templin ; *t ; ++t)
292: ;
293: *t = lastch;
294: while( *++t = *++lastchp ) ;
295: }
296:
297: p = templin;
298: t = yytext;
299: while( *t++ = *p++ )
300: ;
301:
302: for(p = zznextc = text ; *p ; ++p )
303: if(*p!=' ' && *p!='\t')
304: return(START);
305: goto again;
306: }
Defined functions
Defined variables