Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/ape/cmd/make/gram.y – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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