xref: /inferno-os/utils/mk/parse.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include	"mk.h"
2*74a4d8c2SCharles.Forsyth 
3*74a4d8c2SCharles.Forsyth char *infile;
4*74a4d8c2SCharles.Forsyth int mkinline;
5*74a4d8c2SCharles.Forsyth static int rhead(char *, Word **, Word **, int *, char **);
6*74a4d8c2SCharles.Forsyth static char *rbody(Biobuf*);
7*74a4d8c2SCharles.Forsyth extern Word *target1;
8*74a4d8c2SCharles.Forsyth 
9*74a4d8c2SCharles.Forsyth void
parse(char * f,int fd,int varoverride)10*74a4d8c2SCharles.Forsyth parse(char *f, int fd, int varoverride)
11*74a4d8c2SCharles.Forsyth {
12*74a4d8c2SCharles.Forsyth 	int hline;
13*74a4d8c2SCharles.Forsyth 	char *body;
14*74a4d8c2SCharles.Forsyth 	Word *head, *tail;
15*74a4d8c2SCharles.Forsyth 	int attr, set, pid;
16*74a4d8c2SCharles.Forsyth 	char *prog, *p;
17*74a4d8c2SCharles.Forsyth 	int newfd;
18*74a4d8c2SCharles.Forsyth 	Biobuf in;
19*74a4d8c2SCharles.Forsyth 	Bufblock *buf;
20*74a4d8c2SCharles.Forsyth 
21*74a4d8c2SCharles.Forsyth 	if(fd < 0){
22*74a4d8c2SCharles.Forsyth 		perror(f);
23*74a4d8c2SCharles.Forsyth 		Exit();
24*74a4d8c2SCharles.Forsyth 	}
25*74a4d8c2SCharles.Forsyth 	ipush();
26*74a4d8c2SCharles.Forsyth 	infile = strdup(f);
27*74a4d8c2SCharles.Forsyth 	mkinline = 1;
28*74a4d8c2SCharles.Forsyth 	Binit(&in, fd, OREAD);
29*74a4d8c2SCharles.Forsyth 	buf = newbuf();
30*74a4d8c2SCharles.Forsyth 	while(assline(&in, buf)){
31*74a4d8c2SCharles.Forsyth 		hline = mkinline;
32*74a4d8c2SCharles.Forsyth 		switch(rhead(buf->start, &head, &tail, &attr, &prog))
33*74a4d8c2SCharles.Forsyth 		{
34*74a4d8c2SCharles.Forsyth 		case '<':
35*74a4d8c2SCharles.Forsyth 			p = wtos(tail, ' ');
36*74a4d8c2SCharles.Forsyth 			if(*p == 0){
37*74a4d8c2SCharles.Forsyth 				SYNERR(-1);
38*74a4d8c2SCharles.Forsyth 				fprint(2, "missing include file name\n");
39*74a4d8c2SCharles.Forsyth 				Exit();
40*74a4d8c2SCharles.Forsyth 			}
41*74a4d8c2SCharles.Forsyth 			newfd = open(p, OREAD);
42*74a4d8c2SCharles.Forsyth 			if(newfd < 0){
43*74a4d8c2SCharles.Forsyth 				fprint(2, "warning: skipping missing include file: ");
44*74a4d8c2SCharles.Forsyth 				perror(p);
45*74a4d8c2SCharles.Forsyth 			} else
46*74a4d8c2SCharles.Forsyth 				parse(p, newfd, 0);
47*74a4d8c2SCharles.Forsyth 			break;
48*74a4d8c2SCharles.Forsyth 		case '|':
49*74a4d8c2SCharles.Forsyth 			p = wtos(tail, ' ');
50*74a4d8c2SCharles.Forsyth 			if(*p == 0){
51*74a4d8c2SCharles.Forsyth 				SYNERR(-1);
52*74a4d8c2SCharles.Forsyth 				fprint(2, "missing include program name\n");
53*74a4d8c2SCharles.Forsyth 				Exit();
54*74a4d8c2SCharles.Forsyth 			}
55*74a4d8c2SCharles.Forsyth 			execinit();
56*74a4d8c2SCharles.Forsyth 			pid=pipecmd(p, envy, &newfd);
57*74a4d8c2SCharles.Forsyth 			if(newfd < 0){
58*74a4d8c2SCharles.Forsyth 				fprint(2, "warning: skipping missing program file: ");
59*74a4d8c2SCharles.Forsyth 				perror(p);
60*74a4d8c2SCharles.Forsyth 			} else
61*74a4d8c2SCharles.Forsyth 				parse(p, newfd, 0);
62*74a4d8c2SCharles.Forsyth 			while(waitup(-3, &pid) >= 0)
63*74a4d8c2SCharles.Forsyth 				;
64*74a4d8c2SCharles.Forsyth 			if(pid != 0){
65*74a4d8c2SCharles.Forsyth 				fprint(2, "bad include program status\n");
66*74a4d8c2SCharles.Forsyth 				Exit();
67*74a4d8c2SCharles.Forsyth 			}
68*74a4d8c2SCharles.Forsyth 			break;
69*74a4d8c2SCharles.Forsyth 		case ':':
70*74a4d8c2SCharles.Forsyth 			body = rbody(&in);
71*74a4d8c2SCharles.Forsyth 			addrules(head, tail, body, attr, hline, prog);
72*74a4d8c2SCharles.Forsyth 			break;
73*74a4d8c2SCharles.Forsyth 		case '=':
74*74a4d8c2SCharles.Forsyth 			if(head->next){
75*74a4d8c2SCharles.Forsyth 				SYNERR(-1);
76*74a4d8c2SCharles.Forsyth 				fprint(2, "multiple vars on left side of assignment\n");
77*74a4d8c2SCharles.Forsyth 				Exit();
78*74a4d8c2SCharles.Forsyth 			}
79*74a4d8c2SCharles.Forsyth 			if(symlook(head->s, S_OVERRIDE, 0)){
80*74a4d8c2SCharles.Forsyth 				set = varoverride;
81*74a4d8c2SCharles.Forsyth 			} else {
82*74a4d8c2SCharles.Forsyth 				set = 1;
83*74a4d8c2SCharles.Forsyth 				if(varoverride)
84*74a4d8c2SCharles.Forsyth 					symlook(head->s, S_OVERRIDE, (void *)"");
85*74a4d8c2SCharles.Forsyth 			}
86*74a4d8c2SCharles.Forsyth 			if(set){
87*74a4d8c2SCharles.Forsyth /*
88*74a4d8c2SCharles.Forsyth char *cp;
89*74a4d8c2SCharles.Forsyth dumpw("tail", tail);
90*74a4d8c2SCharles.Forsyth cp = wtos(tail, ' '); print("assign %s to %s\n", head->s, cp); free(cp);
91*74a4d8c2SCharles.Forsyth */
92*74a4d8c2SCharles.Forsyth 				setvar(head->s, (void *) tail);
93*74a4d8c2SCharles.Forsyth 				symlook(head->s, S_WESET, (void *)"");
94*74a4d8c2SCharles.Forsyth 			}
95*74a4d8c2SCharles.Forsyth 			if(attr)
96*74a4d8c2SCharles.Forsyth 				symlook(head->s, S_NOEXPORT, (void *)"");
97*74a4d8c2SCharles.Forsyth 			break;
98*74a4d8c2SCharles.Forsyth 		default:
99*74a4d8c2SCharles.Forsyth 			SYNERR(hline);
100*74a4d8c2SCharles.Forsyth 			fprint(2, "expected one of :<=\n");
101*74a4d8c2SCharles.Forsyth 			Exit();
102*74a4d8c2SCharles.Forsyth 			break;
103*74a4d8c2SCharles.Forsyth 		}
104*74a4d8c2SCharles.Forsyth 	}
105*74a4d8c2SCharles.Forsyth 	close(fd);
106*74a4d8c2SCharles.Forsyth 	freebuf(buf);
107*74a4d8c2SCharles.Forsyth 	ipop();
108*74a4d8c2SCharles.Forsyth }
109*74a4d8c2SCharles.Forsyth 
110*74a4d8c2SCharles.Forsyth void
addrules(Word * head,Word * tail,char * body,int attr,int hline,char * prog)111*74a4d8c2SCharles.Forsyth addrules(Word *head, Word *tail, char *body, int attr, int hline, char *prog)
112*74a4d8c2SCharles.Forsyth {
113*74a4d8c2SCharles.Forsyth 	Word *w;
114*74a4d8c2SCharles.Forsyth 
115*74a4d8c2SCharles.Forsyth 	assert("addrules args", head && body);
116*74a4d8c2SCharles.Forsyth 		/* tuck away first non-meta rule as default target*/
117*74a4d8c2SCharles.Forsyth 	if(target1 == 0 && !(attr&REGEXP)){
118*74a4d8c2SCharles.Forsyth 		for(w = head; w; w = w->next)
119*74a4d8c2SCharles.Forsyth 			if(charin(w->s, "%&"))
120*74a4d8c2SCharles.Forsyth 				break;
121*74a4d8c2SCharles.Forsyth 		if(w == 0)
122*74a4d8c2SCharles.Forsyth 			target1 = wdup(head);
123*74a4d8c2SCharles.Forsyth 	}
124*74a4d8c2SCharles.Forsyth 	for(w = head; w; w = w->next)
125*74a4d8c2SCharles.Forsyth 		addrule(w->s, tail, body, head, attr, hline, prog);
126*74a4d8c2SCharles.Forsyth }
127*74a4d8c2SCharles.Forsyth 
128*74a4d8c2SCharles.Forsyth static int
rhead(char * line,Word ** h,Word ** t,int * attr,char ** prog)129*74a4d8c2SCharles.Forsyth rhead(char *line, Word **h, Word **t, int *attr, char **prog)
130*74a4d8c2SCharles.Forsyth {
131*74a4d8c2SCharles.Forsyth 	char *p;
132*74a4d8c2SCharles.Forsyth 	char *pp;
133*74a4d8c2SCharles.Forsyth 	int sep;
134*74a4d8c2SCharles.Forsyth 	Rune r;
135*74a4d8c2SCharles.Forsyth 	int n;
136*74a4d8c2SCharles.Forsyth 	Word *w;
137*74a4d8c2SCharles.Forsyth 
138*74a4d8c2SCharles.Forsyth 	p = charin(line,":=<");
139*74a4d8c2SCharles.Forsyth 	if(p == 0)
140*74a4d8c2SCharles.Forsyth 		return('?');
141*74a4d8c2SCharles.Forsyth 	sep = *p;
142*74a4d8c2SCharles.Forsyth 	*p++ = 0;
143*74a4d8c2SCharles.Forsyth 	if(sep == '<' && *p == '|'){
144*74a4d8c2SCharles.Forsyth 		sep = '|';
145*74a4d8c2SCharles.Forsyth 		p++;
146*74a4d8c2SCharles.Forsyth 	}
147*74a4d8c2SCharles.Forsyth 	*attr = 0;
148*74a4d8c2SCharles.Forsyth 	*prog = 0;
149*74a4d8c2SCharles.Forsyth 	if(sep == '='){
150*74a4d8c2SCharles.Forsyth 		pp = charin(p, termchars);	/* termchars is shell-dependent */
151*74a4d8c2SCharles.Forsyth 		if (pp && *pp == '=') {
152*74a4d8c2SCharles.Forsyth 			while (p != pp) {
153*74a4d8c2SCharles.Forsyth 				n = chartorune(&r, p);
154*74a4d8c2SCharles.Forsyth 				switch(r)
155*74a4d8c2SCharles.Forsyth 				{
156*74a4d8c2SCharles.Forsyth 				default:
157*74a4d8c2SCharles.Forsyth 					SYNERR(-1);
158*74a4d8c2SCharles.Forsyth 					fprint(2, "unknown attribute '%c'\n",*p);
159*74a4d8c2SCharles.Forsyth 					Exit();
160*74a4d8c2SCharles.Forsyth 				case 'U':
161*74a4d8c2SCharles.Forsyth 					*attr = 1;
162*74a4d8c2SCharles.Forsyth 					break;
163*74a4d8c2SCharles.Forsyth 				}
164*74a4d8c2SCharles.Forsyth 				p += n;
165*74a4d8c2SCharles.Forsyth 			}
166*74a4d8c2SCharles.Forsyth 			p++;		/* skip trailing '=' */
167*74a4d8c2SCharles.Forsyth 		}
168*74a4d8c2SCharles.Forsyth 	}
169*74a4d8c2SCharles.Forsyth 	if((sep == ':') && *p && (*p != ' ') && (*p != '\t')){
170*74a4d8c2SCharles.Forsyth 		while (*p) {
171*74a4d8c2SCharles.Forsyth 			n = chartorune(&r, p);
172*74a4d8c2SCharles.Forsyth 			if (r == ':')
173*74a4d8c2SCharles.Forsyth 				break;
174*74a4d8c2SCharles.Forsyth 			p += n;
175*74a4d8c2SCharles.Forsyth 			switch(r)
176*74a4d8c2SCharles.Forsyth 			{
177*74a4d8c2SCharles.Forsyth 			default:
178*74a4d8c2SCharles.Forsyth 				SYNERR(-1);
179*74a4d8c2SCharles.Forsyth 				fprint(2, "unknown attribute '%c'\n", p[-1]);
180*74a4d8c2SCharles.Forsyth 				Exit();
181*74a4d8c2SCharles.Forsyth 			case 'D':
182*74a4d8c2SCharles.Forsyth 				*attr |= DEL;
183*74a4d8c2SCharles.Forsyth 				break;
184*74a4d8c2SCharles.Forsyth 			case 'E':
185*74a4d8c2SCharles.Forsyth 				*attr |= NOMINUSE;
186*74a4d8c2SCharles.Forsyth 				break;
187*74a4d8c2SCharles.Forsyth 			case 'n':
188*74a4d8c2SCharles.Forsyth 				*attr |= NOVIRT;
189*74a4d8c2SCharles.Forsyth 				break;
190*74a4d8c2SCharles.Forsyth 			case 'N':
191*74a4d8c2SCharles.Forsyth 				*attr |= NOREC;
192*74a4d8c2SCharles.Forsyth 				break;
193*74a4d8c2SCharles.Forsyth 			case 'P':
194*74a4d8c2SCharles.Forsyth 				pp = utfrune(p, ':');
195*74a4d8c2SCharles.Forsyth 				if (pp == 0 || *pp == 0)
196*74a4d8c2SCharles.Forsyth 					goto eos;
197*74a4d8c2SCharles.Forsyth 				*pp = 0;
198*74a4d8c2SCharles.Forsyth 				*prog = strdup(p);
199*74a4d8c2SCharles.Forsyth 				*pp = ':';
200*74a4d8c2SCharles.Forsyth 				p = pp;
201*74a4d8c2SCharles.Forsyth 				break;
202*74a4d8c2SCharles.Forsyth 			case 'Q':
203*74a4d8c2SCharles.Forsyth 				*attr |= QUIET;
204*74a4d8c2SCharles.Forsyth 				break;
205*74a4d8c2SCharles.Forsyth 			case 'R':
206*74a4d8c2SCharles.Forsyth 				*attr |= REGEXP;
207*74a4d8c2SCharles.Forsyth 				break;
208*74a4d8c2SCharles.Forsyth 			case 'U':
209*74a4d8c2SCharles.Forsyth 				*attr |= UPD;
210*74a4d8c2SCharles.Forsyth 				break;
211*74a4d8c2SCharles.Forsyth 			case 'V':
212*74a4d8c2SCharles.Forsyth 				*attr |= VIR;
213*74a4d8c2SCharles.Forsyth 				break;
214*74a4d8c2SCharles.Forsyth 			}
215*74a4d8c2SCharles.Forsyth 		}
216*74a4d8c2SCharles.Forsyth 		if (*p++ != ':') {
217*74a4d8c2SCharles.Forsyth 	eos:
218*74a4d8c2SCharles.Forsyth 			SYNERR(-1);
219*74a4d8c2SCharles.Forsyth 			fprint(2, "missing trailing :\n");
220*74a4d8c2SCharles.Forsyth 			Exit();
221*74a4d8c2SCharles.Forsyth 		}
222*74a4d8c2SCharles.Forsyth 	}
223*74a4d8c2SCharles.Forsyth 	*h = w = stow(line);
224*74a4d8c2SCharles.Forsyth 	if(*w->s == 0 && sep != '<' && sep != '|') {
225*74a4d8c2SCharles.Forsyth 		SYNERR(mkinline-1);
226*74a4d8c2SCharles.Forsyth 		fprint(2, "no var on left side of assignment/rule\n");
227*74a4d8c2SCharles.Forsyth 		Exit();
228*74a4d8c2SCharles.Forsyth 	}
229*74a4d8c2SCharles.Forsyth 	*t = stow(p);
230*74a4d8c2SCharles.Forsyth 	return(sep);
231*74a4d8c2SCharles.Forsyth }
232*74a4d8c2SCharles.Forsyth 
233*74a4d8c2SCharles.Forsyth static char *
rbody(Biobuf * in)234*74a4d8c2SCharles.Forsyth rbody(Biobuf *in)
235*74a4d8c2SCharles.Forsyth {
236*74a4d8c2SCharles.Forsyth 	Bufblock *buf;
237*74a4d8c2SCharles.Forsyth 	int r, lastr;
238*74a4d8c2SCharles.Forsyth 	char *p;
239*74a4d8c2SCharles.Forsyth 
240*74a4d8c2SCharles.Forsyth 	lastr = '\n';
241*74a4d8c2SCharles.Forsyth 	buf = newbuf();
242*74a4d8c2SCharles.Forsyth 	for(;;){
243*74a4d8c2SCharles.Forsyth 		r = Bgetrune(in);
244*74a4d8c2SCharles.Forsyth 		if (r < 0)
245*74a4d8c2SCharles.Forsyth 			break;
246*74a4d8c2SCharles.Forsyth 		if (lastr == '\n') {
247*74a4d8c2SCharles.Forsyth 			if (r == '#')
248*74a4d8c2SCharles.Forsyth 				rinsert(buf, r);
249*74a4d8c2SCharles.Forsyth 			else if (r != ' ' && r != '\t') {
250*74a4d8c2SCharles.Forsyth 				Bungetrune(in);
251*74a4d8c2SCharles.Forsyth 				break;
252*74a4d8c2SCharles.Forsyth 			}
253*74a4d8c2SCharles.Forsyth 		} else
254*74a4d8c2SCharles.Forsyth 			rinsert(buf, r);
255*74a4d8c2SCharles.Forsyth 		lastr = r;
256*74a4d8c2SCharles.Forsyth 		if (r == '\n')
257*74a4d8c2SCharles.Forsyth 			mkinline++;
258*74a4d8c2SCharles.Forsyth 	}
259*74a4d8c2SCharles.Forsyth 	insert(buf, 0);
260*74a4d8c2SCharles.Forsyth 	p = strdup(buf->start);
261*74a4d8c2SCharles.Forsyth 	freebuf(buf);
262*74a4d8c2SCharles.Forsyth 	return p;
263*74a4d8c2SCharles.Forsyth }
264*74a4d8c2SCharles.Forsyth 
265*74a4d8c2SCharles.Forsyth struct input
266*74a4d8c2SCharles.Forsyth {
267*74a4d8c2SCharles.Forsyth 	char *file;
268*74a4d8c2SCharles.Forsyth 	int line;
269*74a4d8c2SCharles.Forsyth 	struct input *next;
270*74a4d8c2SCharles.Forsyth };
271*74a4d8c2SCharles.Forsyth static struct input *inputs = 0;
272*74a4d8c2SCharles.Forsyth 
273*74a4d8c2SCharles.Forsyth void
ipush(void)274*74a4d8c2SCharles.Forsyth ipush(void)
275*74a4d8c2SCharles.Forsyth {
276*74a4d8c2SCharles.Forsyth 	struct input *in, *me;
277*74a4d8c2SCharles.Forsyth 
278*74a4d8c2SCharles.Forsyth 	me = (struct input *)Malloc(sizeof(*me));
279*74a4d8c2SCharles.Forsyth 	me->file = infile;
280*74a4d8c2SCharles.Forsyth 	me->line = mkinline;
281*74a4d8c2SCharles.Forsyth 	me->next = 0;
282*74a4d8c2SCharles.Forsyth 	if(inputs == 0)
283*74a4d8c2SCharles.Forsyth 		inputs = me;
284*74a4d8c2SCharles.Forsyth 	else {
285*74a4d8c2SCharles.Forsyth 		for(in = inputs; in->next; )
286*74a4d8c2SCharles.Forsyth 			in = in->next;
287*74a4d8c2SCharles.Forsyth 		in->next = me;
288*74a4d8c2SCharles.Forsyth 	}
289*74a4d8c2SCharles.Forsyth }
290*74a4d8c2SCharles.Forsyth 
291*74a4d8c2SCharles.Forsyth void
ipop(void)292*74a4d8c2SCharles.Forsyth ipop(void)
293*74a4d8c2SCharles.Forsyth {
294*74a4d8c2SCharles.Forsyth 	struct input *in, *me;
295*74a4d8c2SCharles.Forsyth 
296*74a4d8c2SCharles.Forsyth 	assert("pop input list", inputs != 0);
297*74a4d8c2SCharles.Forsyth 	if(inputs->next == 0){
298*74a4d8c2SCharles.Forsyth 		me = inputs;
299*74a4d8c2SCharles.Forsyth 		inputs = 0;
300*74a4d8c2SCharles.Forsyth 	} else {
301*74a4d8c2SCharles.Forsyth 		for(in = inputs; in->next->next; )
302*74a4d8c2SCharles.Forsyth 			in = in->next;
303*74a4d8c2SCharles.Forsyth 		me = in->next;
304*74a4d8c2SCharles.Forsyth 		in->next = 0;
305*74a4d8c2SCharles.Forsyth 	}
306*74a4d8c2SCharles.Forsyth 	infile = me->file;
307*74a4d8c2SCharles.Forsyth 	mkinline = me->line;
308*74a4d8c2SCharles.Forsyth 	free((char *)me);
309*74a4d8c2SCharles.Forsyth }
310