xref: /original-bsd/old/make/gram.y (revision dccf34f1)
105438568Swnj %{#include "defs"
2*dccf34f1Sbostic static	char *sccsid = "@(#)gram.y	4.2 (Berkeley) 87/10/22";
305438568Swnj %}
405438568Swnj 
505438568Swnj %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER
605438568Swnj %union
705438568Swnj 	{
805438568Swnj 	struct shblock *yshblock;
905438568Swnj 	struct depblock *ydepblock;
1005438568Swnj 	struct nameblock *ynameblock;
1105438568Swnj 	}
1205438568Swnj 
1305438568Swnj %type <yshblock> SHELLINE, shlist, shellist
1405438568Swnj %type <ynameblock> NAME, namelist
1505438568Swnj %type <ydepblock> deplist, dlist
1605438568Swnj 
1705438568Swnj 
1805438568Swnj %%
1905438568Swnj 
2005438568Swnj %{
2105438568Swnj struct depblock *pp;
2205438568Swnj FSTATIC struct shblock *prevshp;
2305438568Swnj 
2405438568Swnj FSTATIC struct nameblock *lefts[NLEFTS];
2505438568Swnj struct nameblock *leftp;
2605438568Swnj FSTATIC int nlefts;
2705438568Swnj 
2805438568Swnj struct lineblock *lp, *lpp;
2905438568Swnj FSTATIC struct depblock *prevdep;
3005438568Swnj FSTATIC int sepc;
3105438568Swnj %}
3205438568Swnj 
3305438568Swnj 
3405438568Swnj file:
3505438568Swnj 	| file comline
3605438568Swnj 	;
3705438568Swnj 
3805438568Swnj comline:  START
3905438568Swnj 	| MACRODEF
4005438568Swnj 	| START namelist deplist shellist = {
4105438568Swnj 	    while( --nlefts >= 0)
4205438568Swnj 		{
4305438568Swnj 		leftp = lefts[nlefts];
4405438568Swnj 		if(leftp->septype == 0)
4505438568Swnj 			leftp->septype = sepc;
4605438568Swnj 		else if(leftp->septype != sepc)
4705438568Swnj 			fprintf(stderr, "Inconsistent rules lines for `%s'\n",
4805438568Swnj 				leftp->namep);
4905438568Swnj 		else if(sepc==ALLDEPS && *(leftp->namep)!='.' && $4!=0)
5005438568Swnj 			{
5105438568Swnj 			for(lp=leftp->linep; lp->nxtlineblock!=0; lp=lp->nxtlineblock)
5205438568Swnj 			    if(lp->shp)
5305438568Swnj 				fprintf(stderr, "Multiple rules lines for `%s'\n",
5405438568Swnj 				    leftp->namep);
5505438568Swnj 			}
5605438568Swnj 
5705438568Swnj 		lp = ALLOC(lineblock);
5805438568Swnj 		lp->nxtlineblock = NULL;
5905438568Swnj 		lp->depp = $3;
6005438568Swnj 		lp->shp = $4;
6105438568Swnj 
6205438568Swnj 		if(! unequal(leftp->namep, ".SUFFIXES") && $3==0)
6305438568Swnj 			leftp->linep = 0;
6405438568Swnj 		else if(leftp->linep == 0)
6505438568Swnj 			leftp->linep = lp;
6605438568Swnj 		else	{
6705438568Swnj 			for(lpp = leftp->linep; lpp->nxtlineblock;
6805438568Swnj 				lpp = lpp->nxtlineblock) ;
6905438568Swnj 				if(sepc==ALLDEPS && leftp->namep[0]=='.')
7005438568Swnj 					lpp->shp = 0;
7105438568Swnj 			lpp->nxtlineblock = lp;
7205438568Swnj 			}
7305438568Swnj 		}
7405438568Swnj 	}
7505438568Swnj 	| error
7605438568Swnj 	;
7705438568Swnj 
7805438568Swnj namelist: NAME	= { lefts[0] = $1; nlefts = 1; }
7905438568Swnj 	| namelist NAME	= { lefts[nlefts++] = $2;
8005438568Swnj 	    	if(nlefts>=NLEFTS) fatal("Too many lefts"); }
8105438568Swnj 	;
8205438568Swnj 
8305438568Swnj deplist:
8405438568Swnj 		{
8505438568Swnj 		char junk[10];
86*dccf34f1Sbostic 		(void)sprintf(junk, "%d", yylineno);
8705438568Swnj 		fatal1("Must be a separator on rules line %s", junk);
8805438568Swnj 		}
8905438568Swnj 	| dlist
9005438568Swnj 	;
9105438568Swnj 
9205438568Swnj dlist:  sepchar	= { prevdep = 0;  $$ = 0; }
9305438568Swnj 	| dlist NAME	= {
9405438568Swnj 			  pp = ALLOC(depblock);
9505438568Swnj 			  pp->nxtdepblock = NULL;
9605438568Swnj 			  pp->depname = $2;
9705438568Swnj 			  if(prevdep == 0) $$ = pp;
9805438568Swnj 			  else  prevdep->nxtdepblock = pp;
9905438568Swnj 			  prevdep = pp;
10005438568Swnj 			  }
10105438568Swnj 	;
10205438568Swnj 
10305438568Swnj sepchar:  COLON 	= { sepc = ALLDEPS; }
10405438568Swnj 	| DOUBLECOLON	= { sepc = SOMEDEPS; }
10505438568Swnj 	;
10605438568Swnj 
10705438568Swnj shellist:	= {$$ = 0; }
10805438568Swnj 	| shlist = { $$ = $1; }
10905438568Swnj 	;
11005438568Swnj 
11105438568Swnj shlist:	SHELLINE   = { $$ = $1;  prevshp = $1; }
11205438568Swnj 	| shlist SHELLINE = { $$ = $1;
11305438568Swnj 			prevshp->nxtshblock = $2;
11405438568Swnj 			prevshp = $2;
11505438568Swnj 			}
11605438568Swnj 	;
11705438568Swnj 
11805438568Swnj %%
11905438568Swnj 
12005438568Swnj char *zznextc;	/* zero if need another line; otherwise points to next char */
12105438568Swnj int yylineno;
12205438568Swnj extern FILE * fin;
12305438568Swnj 
yylex()12405438568Swnj yylex()
12505438568Swnj {
12605438568Swnj register char *p;
12705438568Swnj register char *q;
12805438568Swnj char word[INMAX];
12905438568Swnj 
13005438568Swnj if(zznextc == 0)
13105438568Swnj 	return( nextlin() );
13205438568Swnj 
13305438568Swnj while( isspace(*zznextc) )
13405438568Swnj 	++zznextc;
13505438568Swnj 
13605438568Swnj if(*zznextc == '\0')
13705438568Swnj 	return( nextlin() );
13805438568Swnj 
13905438568Swnj if(*zznextc == ':')
14005438568Swnj 	{
14105438568Swnj 	if(*++zznextc == ':')
14205438568Swnj 		{
14305438568Swnj 		++zznextc;
14405438568Swnj 		return(DOUBLECOLON);
14505438568Swnj 		}
14605438568Swnj 	else	return(COLON);
14705438568Swnj 	}
14805438568Swnj 
14905438568Swnj if(*zznextc == '>')
15005438568Swnj 	{
15105438568Swnj 	++zznextc;
15205438568Swnj 	return(GREATER);
15305438568Swnj 	}
15405438568Swnj 
15505438568Swnj if(*zznextc == ';')
15605438568Swnj 	return( retsh(zznextc) );
15705438568Swnj 
15805438568Swnj p = zznextc;
15905438568Swnj q = word;
16005438568Swnj 
16105438568Swnj while( ! ( funny[*p] & TERMINAL) )
16205438568Swnj 	*q++ = *p++;
16305438568Swnj 
16405438568Swnj if(p != zznextc)
16505438568Swnj 	{
16605438568Swnj 	*q = '\0';
16705438568Swnj 	if((yylval.ynameblock=srchname(word))==0)
16805438568Swnj 		yylval.ynameblock = makename(word);
16905438568Swnj 	zznextc = p;
17005438568Swnj 	return(NAME);
17105438568Swnj 	}
17205438568Swnj 
17305438568Swnj else	{
17405438568Swnj 	fprintf(stderr,"Bad character %c (octal %o), line %d",
17505438568Swnj 		*zznextc,*zznextc,yylineno);
17605438568Swnj 	fatal( (char *) NULL );
17705438568Swnj 	}
17805438568Swnj return(0);	/* never executed */
17905438568Swnj }
18005438568Swnj 
18105438568Swnj 
18205438568Swnj 
18305438568Swnj 
18405438568Swnj 
retsh(q)18505438568Swnj retsh(q)
18605438568Swnj char *q;
18705438568Swnj {
18805438568Swnj register char *p;
18905438568Swnj struct shblock *sp;
19005438568Swnj char *copys();
19105438568Swnj 
19205438568Swnj for(p=q+1 ; *p==' '||*p=='\t' ; ++p)  ;
19305438568Swnj 
19405438568Swnj sp = ALLOC(shblock);
19505438568Swnj sp->nxtshblock = NULL;
19605438568Swnj sp->shbp = (fin == NULL ? p : copys(p) );
19705438568Swnj yylval.yshblock = sp;
19805438568Swnj zznextc = 0;
19905438568Swnj return(SHELLINE);
20005438568Swnj }
20105438568Swnj 
nextlin()20205438568Swnj nextlin()
20305438568Swnj {
20405438568Swnj static char yytext[INMAX];
20505438568Swnj static char *yytextl	= yytext+INMAX;
20605438568Swnj char *text, templin[INMAX];
20705438568Swnj register char c;
20805438568Swnj register char *p, *t;
20905438568Swnj char lastch, *lastchp;
21005438568Swnj extern char **linesptr;
21105438568Swnj int incom;
21205438568Swnj int kc;
21305438568Swnj 
21405438568Swnj again:
21505438568Swnj 
21605438568Swnj 	incom = NO;
21705438568Swnj 	zznextc = 0;
21805438568Swnj 
21905438568Swnj if(fin == NULL)
22005438568Swnj 	{
22105438568Swnj 	if( (text = *linesptr++) == 0)
22205438568Swnj 		return(0);
22305438568Swnj 	++yylineno;
22405438568Swnj 	}
22505438568Swnj 
22605438568Swnj else	{
22705438568Swnj 	for(p = text = yytext ; p<yytextl ; *p++ = kc)
22805438568Swnj 		switch(kc = getc(fin))
22905438568Swnj 			{
23005438568Swnj 			case '\t':
23105438568Swnj 				if(p != yytext)
23205438568Swnj 					break;
23305438568Swnj 			case ';':
23405438568Swnj 				incom = YES;
23505438568Swnj 				break;
23605438568Swnj 
23705438568Swnj 			case '#':
23805438568Swnj 				if(! incom)
23905438568Swnj 					kc = '\0';
24005438568Swnj 				break;
24105438568Swnj 
24205438568Swnj 			case '\n':
24305438568Swnj 				++yylineno;
24405438568Swnj 				if(p==yytext || p[-1]!='\\')
24505438568Swnj 					{
24605438568Swnj 					*p = '\0';
24705438568Swnj 					goto endloop;
24805438568Swnj 					}
24905438568Swnj 				p[-1] = ' ';
25005438568Swnj 				while( (kc=getc(fin))=='\t' || kc==' ' || kc=='\n')
25105438568Swnj 					if(kc == '\n')
25205438568Swnj 						++yylineno;
25305438568Swnj 
25405438568Swnj 				if(kc != EOF)
25505438568Swnj 					break;
25605438568Swnj 			case EOF:
25705438568Swnj 				*p = '\0';
25805438568Swnj 				return(0);
25905438568Swnj 			}
26005438568Swnj 
26105438568Swnj 	fatal("line too long");
26205438568Swnj 	}
26305438568Swnj 
26405438568Swnj endloop:
26505438568Swnj 
26605438568Swnj 	if((c = text[0]) == '\t')
26705438568Swnj 		return( retsh(text) );
26805438568Swnj 
26905438568Swnj 	if(isalpha(c) || isdigit(c) || c==' ' || c=='.')
27005438568Swnj 		for(p=text+1; *p!='\0'; )
27105438568Swnj 			if(*p == ':')
27205438568Swnj 				break;
27305438568Swnj 			else if(*p++ == '=')
27405438568Swnj 				{
27505438568Swnj 				eqsign(text);
27605438568Swnj 				return(MACRODEF);
27705438568Swnj 				}
27805438568Swnj 
27905438568Swnj /* substitute for macros on dependency line up to the semicolon if any */
28005438568Swnj 
28105438568Swnj for(t = yytext ; *t!='\0' && *t!=';' ; ++t)
28205438568Swnj 	;
28305438568Swnj 
28405438568Swnj lastchp = t;
28505438568Swnj lastch = *t;
28605438568Swnj *t = '\0';
28705438568Swnj 
28805438568Swnj subst(yytext, templin);		/* Substitute for macros on dependency lines */
28905438568Swnj 
29005438568Swnj if(lastch)
29105438568Swnj 	{
29205438568Swnj 	for(t = templin ; *t ; ++t)
29305438568Swnj 		;
29405438568Swnj 	*t = lastch;
29505438568Swnj 	while( *++t = *++lastchp ) ;
29605438568Swnj 	}
29705438568Swnj 
29805438568Swnj p = templin;
29905438568Swnj t = yytext;
30005438568Swnj while( *t++ = *p++ )
30105438568Swnj 	;
30205438568Swnj 
30305438568Swnj for(p = zznextc = text ; *p ; ++p )
30405438568Swnj 	if(*p!=' ' && *p!='\t')
30505438568Swnj 		return(START);
30605438568Swnj goto again;
30705438568Swnj }
308