1219b2ee8SDavid du Colombier %{#include "defs.h"
2219b2ee8SDavid du Colombier %}
3219b2ee8SDavid du Colombier
4219b2ee8SDavid du Colombier %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER AMPER AMPERAMPER
5219b2ee8SDavid du Colombier %union
6219b2ee8SDavid du Colombier {
7219b2ee8SDavid du Colombier struct shblock *yshblock;
8219b2ee8SDavid du Colombier depblkp ydepblock;
9219b2ee8SDavid du Colombier nameblkp ynameblock;
10219b2ee8SDavid du Colombier }
11219b2ee8SDavid du Colombier
12219b2ee8SDavid du Colombier %type <yshblock> SHELLINE, shlist, shellist
13219b2ee8SDavid du Colombier %type <ynameblock> NAME, namelist
14219b2ee8SDavid du Colombier %type <ydepblock> deplist, dlist
15219b2ee8SDavid du Colombier
16219b2ee8SDavid du Colombier
17219b2ee8SDavid du Colombier %%
18219b2ee8SDavid du Colombier
19219b2ee8SDavid du Colombier %{
20219b2ee8SDavid du Colombier struct depblock *pp;
21219b2ee8SDavid du Colombier static struct shblock *prevshp;
22219b2ee8SDavid du Colombier
23219b2ee8SDavid du Colombier static struct nameblock *lefts[NLEFTS];
24219b2ee8SDavid du Colombier struct nameblock *leftp;
25219b2ee8SDavid du Colombier static int nlefts;
26219b2ee8SDavid du Colombier
27219b2ee8SDavid du Colombier struct lineblock *lp, *lpp;
28219b2ee8SDavid du Colombier static struct depblock *prevdep;
29219b2ee8SDavid du Colombier static int sepc;
30219b2ee8SDavid du Colombier static int allnowait;
31219b2ee8SDavid du Colombier
32219b2ee8SDavid du Colombier static struct fstack
33219b2ee8SDavid du Colombier {
34219b2ee8SDavid du Colombier FILE *fin;
35219b2ee8SDavid du Colombier char *fname;
36219b2ee8SDavid du Colombier int lineno;
37219b2ee8SDavid du Colombier } filestack[MAXINCLUDE];
38219b2ee8SDavid du Colombier static int ninclude = 0;
39219b2ee8SDavid du Colombier %}
40219b2ee8SDavid du Colombier
41219b2ee8SDavid du Colombier
42219b2ee8SDavid du Colombier file:
43219b2ee8SDavid du Colombier | file comline
44219b2ee8SDavid du Colombier ;
45219b2ee8SDavid du Colombier
46219b2ee8SDavid du Colombier comline: START
47219b2ee8SDavid du Colombier | MACRODEF
48219b2ee8SDavid du Colombier | START namelist deplist shellist = {
49219b2ee8SDavid du Colombier while( --nlefts >= 0)
50219b2ee8SDavid du Colombier {
51219b2ee8SDavid du Colombier wildp wp;
52219b2ee8SDavid du Colombier
53219b2ee8SDavid du Colombier leftp = lefts[nlefts];
54219b2ee8SDavid du Colombier if(wp = iswild(leftp->namep))
55219b2ee8SDavid du Colombier {
56219b2ee8SDavid du Colombier leftp->septype = SOMEDEPS;
57219b2ee8SDavid du Colombier if(lastwild)
58219b2ee8SDavid du Colombier lastwild->next = wp;
59219b2ee8SDavid du Colombier else
60219b2ee8SDavid du Colombier firstwild = wp;
61219b2ee8SDavid du Colombier lastwild = wp;
62219b2ee8SDavid du Colombier }
63219b2ee8SDavid du Colombier
64219b2ee8SDavid du Colombier if(leftp->septype == 0)
65219b2ee8SDavid du Colombier leftp->septype = sepc;
66219b2ee8SDavid du Colombier else if(leftp->septype != sepc)
67219b2ee8SDavid du Colombier {
68219b2ee8SDavid du Colombier if(! wp)
69219b2ee8SDavid du Colombier fprintf(stderr,
70219b2ee8SDavid du Colombier "Inconsistent rules lines for `%s'\n",
71219b2ee8SDavid du Colombier leftp->namep);
72219b2ee8SDavid du Colombier }
73219b2ee8SDavid du Colombier else if(sepc==ALLDEPS && leftp->namep[0]!='.' && $4!=0)
74219b2ee8SDavid du Colombier {
75219b2ee8SDavid du Colombier for(lp=leftp->linep; lp->nxtlineblock; lp=lp->nxtlineblock)
76219b2ee8SDavid du Colombier if(lp->shp)
77219b2ee8SDavid du Colombier fprintf(stderr,
78219b2ee8SDavid du Colombier "Multiple rules lines for `%s'\n",
79219b2ee8SDavid du Colombier leftp->namep);
80219b2ee8SDavid du Colombier }
81219b2ee8SDavid du Colombier
82219b2ee8SDavid du Colombier lp = ALLOC(lineblock);
83219b2ee8SDavid du Colombier lp->nxtlineblock = NULL;
84219b2ee8SDavid du Colombier lp->depp = $3;
85219b2ee8SDavid du Colombier lp->shp = $4;
86219b2ee8SDavid du Colombier if(wp)
87219b2ee8SDavid du Colombier wp->linep = lp;
88219b2ee8SDavid du Colombier
89219b2ee8SDavid du Colombier if(equal(leftp->namep, ".SUFFIXES") && $3==0)
90219b2ee8SDavid du Colombier leftp->linep = 0;
91219b2ee8SDavid du Colombier else if(leftp->linep == 0)
92219b2ee8SDavid du Colombier leftp->linep = lp;
93219b2ee8SDavid du Colombier else {
94219b2ee8SDavid du Colombier for(lpp = leftp->linep; lpp->nxtlineblock;
95219b2ee8SDavid du Colombier lpp = lpp->nxtlineblock) ;
96219b2ee8SDavid du Colombier if(sepc==ALLDEPS && leftp->namep[0]=='.')
97219b2ee8SDavid du Colombier lpp->shp = 0;
98219b2ee8SDavid du Colombier lpp->nxtlineblock = lp;
99219b2ee8SDavid du Colombier }
100219b2ee8SDavid du Colombier }
101219b2ee8SDavid du Colombier }
102219b2ee8SDavid du Colombier | error
103219b2ee8SDavid du Colombier ;
104219b2ee8SDavid du Colombier
105219b2ee8SDavid du Colombier namelist: NAME = { lefts[0] = $1; nlefts = 1; }
106219b2ee8SDavid du Colombier | namelist NAME = { lefts[nlefts++] = $2;
107219b2ee8SDavid du Colombier if(nlefts>=NLEFTS) fatal("Too many lefts"); }
108219b2ee8SDavid du Colombier ;
109219b2ee8SDavid du Colombier
110219b2ee8SDavid du Colombier deplist:
111219b2ee8SDavid du Colombier {
1127dd7cddfSDavid du Colombier char junk[100];
1137dd7cddfSDavid du Colombier sprintf(junk, "%s:%d", filestack[ninclude-1].fname, yylineno);
114219b2ee8SDavid du Colombier fatal1("Must be a separator on rules line %s", junk);
115219b2ee8SDavid du Colombier }
116219b2ee8SDavid du Colombier | dlist
117219b2ee8SDavid du Colombier ;
118219b2ee8SDavid du Colombier
119219b2ee8SDavid du Colombier dlist: sepchar = { prevdep = 0; $$ = 0; allnowait = NO; }
120219b2ee8SDavid du Colombier | sepchar AMPER = { prevdep = 0; $$ = 0; allnowait = YES; }
121219b2ee8SDavid du Colombier | dlist NAME = {
122219b2ee8SDavid du Colombier pp = ALLOC(depblock);
123219b2ee8SDavid du Colombier pp->nxtdepblock = NULL;
124219b2ee8SDavid du Colombier pp->depname = $2;
125219b2ee8SDavid du Colombier pp->nowait = allnowait;
126219b2ee8SDavid du Colombier if(prevdep == 0) $$ = pp;
127219b2ee8SDavid du Colombier else prevdep->nxtdepblock = pp;
128219b2ee8SDavid du Colombier prevdep = pp;
129219b2ee8SDavid du Colombier }
130219b2ee8SDavid du Colombier | dlist AMPER = { if(prevdep) prevdep->nowait = YES; }
131219b2ee8SDavid du Colombier | dlist AMPERAMPER
132219b2ee8SDavid du Colombier ;
133219b2ee8SDavid du Colombier
134219b2ee8SDavid du Colombier sepchar: COLON = { sepc = ALLDEPS; }
135219b2ee8SDavid du Colombier | DOUBLECOLON = { sepc = SOMEDEPS; }
136219b2ee8SDavid du Colombier ;
137219b2ee8SDavid du Colombier
138219b2ee8SDavid du Colombier shellist: = {$$ = 0; }
139219b2ee8SDavid du Colombier | shlist = { $$ = $1; }
140219b2ee8SDavid du Colombier ;
141219b2ee8SDavid du Colombier
142219b2ee8SDavid du Colombier shlist: SHELLINE = { $$ = $1; prevshp = $1; }
143219b2ee8SDavid du Colombier | shlist SHELLINE = { $$ = $1;
144219b2ee8SDavid du Colombier prevshp->nxtshblock = $2;
145219b2ee8SDavid du Colombier prevshp = $2;
146219b2ee8SDavid du Colombier }
147219b2ee8SDavid du Colombier ;
148219b2ee8SDavid du Colombier
149219b2ee8SDavid du Colombier %%
150219b2ee8SDavid du Colombier
151219b2ee8SDavid du Colombier static char *zznextc; /* null if need another line;
152219b2ee8SDavid du Colombier otherwise points to next char */
153219b2ee8SDavid du Colombier static int yylineno;
154219b2ee8SDavid du Colombier static FILE * fin;
155219b2ee8SDavid du Colombier static int retsh(char *);
156219b2ee8SDavid du Colombier static int nextlin(void);
157219b2ee8SDavid du Colombier static int isinclude(char *);
158219b2ee8SDavid du Colombier
159219b2ee8SDavid du Colombier int yyparse(void);
160219b2ee8SDavid du Colombier
161219b2ee8SDavid du Colombier int
parse(char * name)162219b2ee8SDavid du Colombier parse(char *name)
163219b2ee8SDavid du Colombier {
164219b2ee8SDavid du Colombier FILE *stream;
165219b2ee8SDavid du Colombier
166219b2ee8SDavid du Colombier if(name == CHNULL)
167219b2ee8SDavid du Colombier {
168219b2ee8SDavid du Colombier stream = NULL;
169219b2ee8SDavid du Colombier name = "(builtin-rules)";
170219b2ee8SDavid du Colombier }
171219b2ee8SDavid du Colombier else if(equal(name, "-"))
172219b2ee8SDavid du Colombier {
173219b2ee8SDavid du Colombier stream = stdin;
174219b2ee8SDavid du Colombier name = "(stdin)";
175219b2ee8SDavid du Colombier }
176219b2ee8SDavid du Colombier else if( (stream = fopen(name, "r")) == NULL)
177219b2ee8SDavid du Colombier return NO;
178219b2ee8SDavid du Colombier filestack[0].fname = copys(name);
179219b2ee8SDavid du Colombier ninclude = 1;
180219b2ee8SDavid du Colombier fin = stream;
181219b2ee8SDavid du Colombier yylineno = 0;
182219b2ee8SDavid du Colombier zznextc = 0;
183219b2ee8SDavid du Colombier
184219b2ee8SDavid du Colombier if( yyparse() )
185219b2ee8SDavid du Colombier fatal("Description file error");
186219b2ee8SDavid du Colombier
187219b2ee8SDavid du Colombier if(fin)
188219b2ee8SDavid du Colombier fclose(fin);
189219b2ee8SDavid du Colombier return YES;
190219b2ee8SDavid du Colombier }
191219b2ee8SDavid du Colombier
192219b2ee8SDavid du Colombier int
yylex(void)193219b2ee8SDavid du Colombier yylex(void)
194219b2ee8SDavid du Colombier {
195219b2ee8SDavid du Colombier char *p;
196219b2ee8SDavid du Colombier char *q;
197219b2ee8SDavid du Colombier char word[INMAX];
198219b2ee8SDavid du Colombier
199219b2ee8SDavid du Colombier if(! zznextc )
200219b2ee8SDavid du Colombier return nextlin() ;
201219b2ee8SDavid du Colombier
202219b2ee8SDavid du Colombier while( isspace(*zznextc) )
203219b2ee8SDavid du Colombier ++zznextc;
204219b2ee8SDavid du Colombier switch(*zznextc)
205219b2ee8SDavid du Colombier {
206219b2ee8SDavid du Colombier case '\0':
207219b2ee8SDavid du Colombier return nextlin() ;
208219b2ee8SDavid du Colombier
209219b2ee8SDavid du Colombier case '|':
210219b2ee8SDavid du Colombier if(zznextc[1]==':')
211219b2ee8SDavid du Colombier {
212219b2ee8SDavid du Colombier zznextc += 2;
213219b2ee8SDavid du Colombier return DOUBLECOLON;
214219b2ee8SDavid du Colombier }
215219b2ee8SDavid du Colombier break;
216219b2ee8SDavid du Colombier case ':':
217219b2ee8SDavid du Colombier if(*++zznextc == ':')
218219b2ee8SDavid du Colombier {
219219b2ee8SDavid du Colombier ++zznextc;
220219b2ee8SDavid du Colombier return DOUBLECOLON;
221219b2ee8SDavid du Colombier }
222219b2ee8SDavid du Colombier return COLON;
223219b2ee8SDavid du Colombier case '>':
224219b2ee8SDavid du Colombier ++zznextc;
225219b2ee8SDavid du Colombier return GREATER;
226219b2ee8SDavid du Colombier case '&':
227219b2ee8SDavid du Colombier if(*++zznextc == '&')
228219b2ee8SDavid du Colombier {
229219b2ee8SDavid du Colombier ++zznextc;
230219b2ee8SDavid du Colombier return AMPERAMPER;
231219b2ee8SDavid du Colombier }
232219b2ee8SDavid du Colombier return AMPER;
233219b2ee8SDavid du Colombier case ';':
234219b2ee8SDavid du Colombier return retsh(zznextc) ;
235219b2ee8SDavid du Colombier }
236219b2ee8SDavid du Colombier
237219b2ee8SDavid du Colombier p = zznextc;
238219b2ee8SDavid du Colombier q = word;
239219b2ee8SDavid du Colombier
240219b2ee8SDavid du Colombier while( ! ( funny[*p] & TERMINAL) )
241219b2ee8SDavid du Colombier *q++ = *p++;
242219b2ee8SDavid du Colombier
243219b2ee8SDavid du Colombier if(p != zznextc)
244219b2ee8SDavid du Colombier {
245219b2ee8SDavid du Colombier *q = '\0';
246219b2ee8SDavid du Colombier if((yylval.ynameblock=srchname(word))==0)
247219b2ee8SDavid du Colombier yylval.ynameblock = makename(word);
248219b2ee8SDavid du Colombier zznextc = p;
249219b2ee8SDavid du Colombier return NAME;
250219b2ee8SDavid du Colombier }
251219b2ee8SDavid du Colombier
252219b2ee8SDavid du Colombier else {
253219b2ee8SDavid du Colombier char junk[100];
254219b2ee8SDavid du Colombier sprintf(junk, "Bad character %c (octal %o), line %d of file %s",
255219b2ee8SDavid du Colombier *zznextc, *zznextc, yylineno, filestack[ninclude-1].fname);
256219b2ee8SDavid du Colombier fatal(junk);
257219b2ee8SDavid du Colombier }
258219b2ee8SDavid du Colombier return 0; /* never executed */
259219b2ee8SDavid du Colombier }
260219b2ee8SDavid du Colombier
261219b2ee8SDavid du Colombier
262219b2ee8SDavid du Colombier
263219b2ee8SDavid du Colombier
264219b2ee8SDavid du Colombier static int
retsh(char * q)265219b2ee8SDavid du Colombier retsh(char *q)
266219b2ee8SDavid du Colombier {
267219b2ee8SDavid du Colombier register char *p;
268219b2ee8SDavid du Colombier struct shblock *sp;
269219b2ee8SDavid du Colombier
270219b2ee8SDavid du Colombier for(p=q+1 ; *p==' '||*p=='\t' ; ++p) ;
271219b2ee8SDavid du Colombier
272219b2ee8SDavid du Colombier sp = ALLOC(shblock);
273219b2ee8SDavid du Colombier sp->nxtshblock = NULL;
274219b2ee8SDavid du Colombier sp->shbp = (fin ? copys(p) : p );
275219b2ee8SDavid du Colombier yylval.yshblock = sp;
276219b2ee8SDavid du Colombier zznextc = 0;
277219b2ee8SDavid du Colombier return SHELLINE;
278219b2ee8SDavid du Colombier }
279219b2ee8SDavid du Colombier
280219b2ee8SDavid du Colombier static int
nextlin(void)281219b2ee8SDavid du Colombier nextlin(void)
282219b2ee8SDavid du Colombier {
283219b2ee8SDavid du Colombier static char yytext[INMAX];
284219b2ee8SDavid du Colombier static char *yytextl = yytext+INMAX;
285219b2ee8SDavid du Colombier char *text, templin[INMAX];
286219b2ee8SDavid du Colombier char c;
287219b2ee8SDavid du Colombier char *p, *t;
288219b2ee8SDavid du Colombier char lastch, *lastchp;
289219b2ee8SDavid du Colombier extern char **linesptr;
290219b2ee8SDavid du Colombier int incom;
291219b2ee8SDavid du Colombier int kc;
292219b2ee8SDavid du Colombier
293219b2ee8SDavid du Colombier again:
294219b2ee8SDavid du Colombier
295219b2ee8SDavid du Colombier incom = NO;
296219b2ee8SDavid du Colombier zznextc = 0;
297219b2ee8SDavid du Colombier
298219b2ee8SDavid du Colombier if(fin == NULL)
299219b2ee8SDavid du Colombier {
300219b2ee8SDavid du Colombier if( (text = *linesptr++) == 0)
301219b2ee8SDavid du Colombier return 0;
302219b2ee8SDavid du Colombier ++yylineno;
303219b2ee8SDavid du Colombier }
304219b2ee8SDavid du Colombier
305219b2ee8SDavid du Colombier else {
306219b2ee8SDavid du Colombier for(p = text = yytext ; p<yytextl ; *p++ = kc)
307219b2ee8SDavid du Colombier switch(kc = getc(fin))
308219b2ee8SDavid du Colombier {
309219b2ee8SDavid du Colombier case '\t':
310219b2ee8SDavid du Colombier if(p == yytext)
311219b2ee8SDavid du Colombier incom = YES;
312219b2ee8SDavid du Colombier break;
313219b2ee8SDavid du Colombier
314219b2ee8SDavid du Colombier case ';':
315219b2ee8SDavid du Colombier incom = YES;
316219b2ee8SDavid du Colombier break;
317219b2ee8SDavid du Colombier
318219b2ee8SDavid du Colombier case '#':
319219b2ee8SDavid du Colombier if(! incom)
320219b2ee8SDavid du Colombier kc = '\0';
321219b2ee8SDavid du Colombier break;
322219b2ee8SDavid du Colombier
323219b2ee8SDavid du Colombier case '\n':
324219b2ee8SDavid du Colombier ++yylineno;
325219b2ee8SDavid du Colombier if(p==yytext || p[-1]!='\\')
326219b2ee8SDavid du Colombier {
327219b2ee8SDavid du Colombier *p = '\0';
328219b2ee8SDavid du Colombier goto endloop;
329219b2ee8SDavid du Colombier }
330219b2ee8SDavid du Colombier p[-1] = ' ';
331219b2ee8SDavid du Colombier while( (kc=getc(fin))=='\t' || kc==' ' || kc=='\n')
332219b2ee8SDavid du Colombier if(kc == '\n')
333219b2ee8SDavid du Colombier ++yylineno;
334219b2ee8SDavid du Colombier
335219b2ee8SDavid du Colombier if(kc != EOF)
336219b2ee8SDavid du Colombier break;
337219b2ee8SDavid du Colombier case EOF:
338219b2ee8SDavid du Colombier *p = '\0';
339219b2ee8SDavid du Colombier if(ninclude > 1)
340219b2ee8SDavid du Colombier {
341219b2ee8SDavid du Colombier register struct fstack *stp;
342219b2ee8SDavid du Colombier fclose(fin);
343219b2ee8SDavid du Colombier --ninclude;
344219b2ee8SDavid du Colombier stp = filestack + ninclude;
345219b2ee8SDavid du Colombier fin = stp->fin;
346219b2ee8SDavid du Colombier yylineno = stp->lineno;
347219b2ee8SDavid du Colombier free(stp->fname);
348219b2ee8SDavid du Colombier goto again;
349219b2ee8SDavid du Colombier }
350219b2ee8SDavid du Colombier return 0;
351219b2ee8SDavid du Colombier }
352219b2ee8SDavid du Colombier
353219b2ee8SDavid du Colombier fatal("line too long");
354219b2ee8SDavid du Colombier }
355219b2ee8SDavid du Colombier
356219b2ee8SDavid du Colombier endloop:
357219b2ee8SDavid du Colombier
358219b2ee8SDavid du Colombier if((c = text[0]) == '\t')
359219b2ee8SDavid du Colombier return retsh(text) ;
360219b2ee8SDavid du Colombier
3617dd7cddfSDavid du Colombier if(isalpha(c) || isdigit(c) || c==' ' || c=='.'|| c=='_')
362219b2ee8SDavid du Colombier for(p=text+1; *p!='\0'; )
363219b2ee8SDavid du Colombier if(*p == ':')
364219b2ee8SDavid du Colombier break;
365219b2ee8SDavid du Colombier else if(*p++ == '=')
366219b2ee8SDavid du Colombier {
367219b2ee8SDavid du Colombier eqsign(text);
368219b2ee8SDavid du Colombier return MACRODEF;
369219b2ee8SDavid du Colombier }
370219b2ee8SDavid du Colombier
371219b2ee8SDavid du Colombier /* substitute for macros on dependency line up to the semicolon if any */
372219b2ee8SDavid du Colombier
373219b2ee8SDavid du Colombier for(t = yytext ; *t!='\0' && *t!=';' ; ++t)
374219b2ee8SDavid du Colombier ;
375219b2ee8SDavid du Colombier
376219b2ee8SDavid du Colombier lastchp = t;
377219b2ee8SDavid du Colombier lastch = *t;
378219b2ee8SDavid du Colombier *t = '\0'; /* replace the semi with a null so subst will stop */
379219b2ee8SDavid du Colombier
380*9b7bf7dfSDavid du Colombier /* Substitute for macros on dependency lines */
381*9b7bf7dfSDavid du Colombier subst(yytext, templin, &templin[sizeof templin - 1]);
382219b2ee8SDavid du Colombier
383219b2ee8SDavid du Colombier if(lastch) /* copy the stuff after the semicolon */
384219b2ee8SDavid du Colombier {
385219b2ee8SDavid du Colombier *lastchp = lastch;
386219b2ee8SDavid du Colombier strcat(templin, lastchp);
387219b2ee8SDavid du Colombier }
388219b2ee8SDavid du Colombier
389219b2ee8SDavid du Colombier strcpy(yytext, templin);
390219b2ee8SDavid du Colombier
39180ee5cbfSDavid du Colombier /* process include files after macro substitution */
39280ee5cbfSDavid du Colombier if(strncmp(text, "include", 7) == 0) {
39380ee5cbfSDavid du Colombier if (isinclude(text+7))
39480ee5cbfSDavid du Colombier goto again;
39580ee5cbfSDavid du Colombier }
39680ee5cbfSDavid du Colombier
397219b2ee8SDavid du Colombier for(p = zznextc = text ; *p ; ++p )
398219b2ee8SDavid du Colombier if(*p!=' ' && *p!='\t')
399219b2ee8SDavid du Colombier return START;
400219b2ee8SDavid du Colombier goto again;
401219b2ee8SDavid du Colombier }
402219b2ee8SDavid du Colombier
403219b2ee8SDavid du Colombier
404219b2ee8SDavid du Colombier static int
isinclude(char * s)405219b2ee8SDavid du Colombier isinclude(char *s)
406219b2ee8SDavid du Colombier {
407219b2ee8SDavid du Colombier char *t;
408219b2ee8SDavid du Colombier struct fstack *p;
409219b2ee8SDavid du Colombier
410219b2ee8SDavid du Colombier for(t=s; *t==' ' || *t=='\t' ; ++t)
411219b2ee8SDavid du Colombier ;
412219b2ee8SDavid du Colombier if(t == s)
413219b2ee8SDavid du Colombier return NO;
414219b2ee8SDavid du Colombier
415219b2ee8SDavid du Colombier for(s = t; *s!='\n' && *s!='#' && *s!='\0' ; ++s)
416219b2ee8SDavid du Colombier if(*s == ':')
417219b2ee8SDavid du Colombier return NO;
418219b2ee8SDavid du Colombier *s = '\0';
419219b2ee8SDavid du Colombier
420219b2ee8SDavid du Colombier if(ninclude >= MAXINCLUDE)
421219b2ee8SDavid du Colombier fatal("include depth exceeded");
422219b2ee8SDavid du Colombier p = filestack + ninclude;
423219b2ee8SDavid du Colombier p->fin = fin;
424219b2ee8SDavid du Colombier p->lineno = yylineno;
425219b2ee8SDavid du Colombier p->fname = copys(t);
426219b2ee8SDavid du Colombier if( (fin = fopen(t, "r")) == NULL)
427219b2ee8SDavid du Colombier fatal1("Cannot open include file %s", t);
428219b2ee8SDavid du Colombier yylineno = 0;
429219b2ee8SDavid du Colombier ++ninclude;
430219b2ee8SDavid du Colombier return YES;
431219b2ee8SDavid du Colombier }
432219b2ee8SDavid du Colombier
433219b2ee8SDavid du Colombier
434219b2ee8SDavid du Colombier int
yyerror(char * s,...)435219b2ee8SDavid du Colombier yyerror(char *s, ...)
436219b2ee8SDavid du Colombier {
437219b2ee8SDavid du Colombier char buf[100];
438219b2ee8SDavid du Colombier
439219b2ee8SDavid du Colombier sprintf(buf, "line %d of file %s: %s",
440219b2ee8SDavid du Colombier yylineno, filestack[ninclude-1].fname, s);
441219b2ee8SDavid du Colombier fatal(buf);
442027288c8SDavid du Colombier return 0;
443219b2ee8SDavid du Colombier }
444