Commit | Line | Data |
---|---|---|
e7c9d954 TL |
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 | \f | |
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 | \f | |
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 | } |