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