|
|
1.1 root 1: #include "mk.h"
2:
3: char *infile;
4: int inline;
5: static longline();
6: extern Word *target1;
7:
8: parse(f, fd, varoverride, ruleoverride)
9: char *f;
10: {
11: int hline;
12: char *s, *body;
13: Word *head, *tail;
14: int attr, set;
15: char *prog, *inc;
16:
17: if(fd < 0){
18: perror(f);
19: Exit();
20: }
21: ipush();
22: infile = strdup(f);
23: inline = 1;
24: Finit(fd, (char *)0);
25: while(s = Frdline(fd)){
26: if((*s == '#') || (*s == 0)){
27: inline++;
28: continue;
29: }
30: hline = inline;
31: switch(rhead(s, fd, &head, &tail, &attr, &prog))
32: {
33: case '<':
34: if((tail == 0) || ((inc = wtos(tail)) == 0)){
35: SYNERR(-1);
36: Fprint(2, "missing include file name\n");
37: Exit();
38: }
39: parse(inc, open(inc, 0), 0, 1);
40: break;
41: case ':':
42: rbody(fd, &body);
43: addrules(head, tail, body, attr, hline, ruleoverride, prog);
44: break;
45: case '=':
46: if(head->next){
47: SYNERR(-1);
48: Fprint(2, "multiple vars on left side of assignment\n");
49: Exit();
50: }
51: if(symlook(head->s, S_OVERRIDE, (char *)0)){
52: set = varoverride;
53: symdel(head->s, S_OVERRIDE);
54: } else {
55: set = 1;
56: if(varoverride)
57: symlook(head->s, S_OVERRIDE, "");
58: }
59: if(set)
60: setvar(head->s, wtos(tail));
61: if(attr)
62: (void)symlook(head->s, S_NOEXPORT, "");
63: break;
64: default:
65: SYNERR(hline);
66: Fprint(2, "expected : or =\n");
67: Exit();
68: break;
69: }
70: }
71: close(fd);
72: ipop();
73: }
74:
75: addrules(head, tail, body, attr, hline, override, prog)
76: Word *head, *tail;
77: char *body, *prog;
78: {
79: register Word *w;
80:
81: assert("addrules args", head && body);
82: if((target1 == 0) && !(attr®EXP))
83: frule(head);
84: for(w = head; w; w = w->next)
85: addrule(w->s, tail, body, head, attr, hline, override, prog);
86: }
87:
88: rhead(s, fd, h, t, attr, prog)
89: char *s;
90: Word **h, **t;
91: int *attr;
92: char **prog;
93: {
94: char buf[BIGBLOCK];
95: register char *p;
96: char *pp;
97: int sep;
98:
99: longline(fd, s, buf); /* cover \\n guys */
100: lex(fd, buf);
101: if(p = strchr(buf, '#')) /* comment ? */
102: *p = 0;
103: for(p = buf; *p; p++)
104: if((*p == ':') || (*p == '=') || (*p == '<')) break;
105: if(*p == 0){
106: return('?');
107: }
108: sep = *p;
109: *p++ = 0;
110: *attr = 0;
111: *prog = 0;
112: if(sep == '='){
113: char *le, *e;
114:
115: le = strchr(p, ' ');
116: if(e = strchr(p, '\t'))
117: if((le == 0) || (e < le))
118: le = e;
119: if((e = strchr(p, '=')) && ((le == 0) || (e < le))){
120: while(*p != '='){
121: switch(*p++)
122: {
123: case 0:
124: SYNERR(-1);
125: Fprint(2, "missing trailing =\n");
126: Exit();
127: default:
128: SYNERR(-1);
129: Fprint(2, "unknown attribute '%c'\n", p[-1]);
130: Exit();
131: case 'U':
132: *attr = 1;
133: break;
134: }
135: }
136: p++;
137: }
138: }
139: if((sep == ':') && *p && (*p != ' ') && (*p != '\t')){
140: while(*p != ':')
141: switch(*p++)
142: {
143: case 0:
144: eos:
145: SYNERR(-1);
146: Fprint(2, "missing trailing :\n");
147: Exit();
148: default:
149: SYNERR(-1);
150: Fprint(2, "unknown attribute '%c'\n", p[-1]);
151: Exit();
152: case '<':
153: *attr |= RED;
154: break;
155: case 'D':
156: *attr |= DEL;
157: break;
158: case 'N':
159: *attr |= NOREC;
160: break;
161: case 'P':
162: pp = p;
163: while(*p && (*p != ':'))
164: p++;
165: if(*p == 0)
166: goto eos;
167: *p = 0;
168: *prog = strdup(pp);
169: *p = ':';
170: break;
171: case 'Q':
172: *attr |= QUIET;
173: break;
174: case 'R':
175: *attr |= REGEXP;
176: break;
177: case 'U':
178: *attr |= UPD;
179: break;
180: case 'V':
181: *attr |= VIR;
182: break;
183: }
184: p++;
185: }
186: *h = expand(buf);
187: if((*h == 0) && (sep != '<')){
188: SYNERR(inline-1);
189: Fprint(2, "no var on left side of assignment/rule\n");
190: Exit();
191: }
192: while((*p == ' ') || (*p == '\t'))
193: p++;
194: *t = expand(p);
195: return(sep);
196: }
197:
198: rbody(fd, b)
199: char **b;
200: {
201: char buf[BIGBLOCK];
202: char *cp, *s;
203: register n;
204:
205: cp = buf;
206: while(s = Frdline(fd)){
207: inline++;
208: if((*s != '\t') && (*s != ' ')){
209: inline--;
210: Fundo(fd);
211: break;
212: }
213: memcpy(cp, s+1, n = FIOLINELEN(fd)-1);
214: cp += n;
215: *cp++ = '\n';
216: }
217: *cp++ = 0;
218: assert("rbody overflow", cp <= &buf[BIGBLOCK]);
219: *b = (buf[0])? strndup(buf, (int)(cp-buf)) : strdup("");
220: }
221:
222: static
223: longline(fd, line, dest)
224: register char *line, *dest;
225: {
226: for(;;){
227: inline++;
228: while(*dest++ = *line++);
229: dest -= 2;
230: if(*dest == '\\'){
231: *dest = 0;
232: if((line = Frdline(fd)) == 0){
233: Fundo(fd);
234: break;
235: }
236: } else
237: break;
238: }
239: }
240:
241: struct input
242: {
243: char *file;
244: int line;
245: struct input *next;
246: };
247: static struct input *inputs = 0;
248:
249: ipush()
250: {
251: register struct input *in, *me;
252:
253: me = (struct input *)Malloc(sizeof(*me));
254: me->file = infile;
255: me->line = inline;
256: me->next = 0;
257: if(inputs == 0)
258: inputs = me;
259: else {
260: for(in = inputs; in->next; )
261: in = in->next;
262: in->next = me;
263: }
264: }
265:
266: ipop()
267: {
268: register struct input *in, *me;
269:
270: assert("pop input list", inputs != 0);
271: if(inputs->next == 0){
272: me = inputs;
273: inputs = 0;
274: } else {
275: for(in = inputs; in->next->next; )
276: in = in->next;
277: me = in->next;
278: in->next = 0;
279: }
280: infile = me->file;
281: inline = me->line;
282: free((char *)me);
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.