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