1 76193d7c 2003-09-30 devnull #include "mk.h"
3 76193d7c 2003-09-30 devnull char *infile;
4 76193d7c 2003-09-30 devnull int mkinline;
5 76193d7c 2003-09-30 devnull static int rhead(char *, Word **, Word **, int *, char **);
6 76193d7c 2003-09-30 devnull static char *rbody(Biobuf*);
7 76193d7c 2003-09-30 devnull extern Word *target1;
10 76193d7c 2003-09-30 devnull parse(char *f, int fd, int varoverride)
12 76193d7c 2003-09-30 devnull int hline;
13 76193d7c 2003-09-30 devnull char *body;
14 76193d7c 2003-09-30 devnull Word *head, *tail;
15 76193d7c 2003-09-30 devnull int attr, set, pid;
16 76193d7c 2003-09-30 devnull char *prog, *p;
17 76193d7c 2003-09-30 devnull int newfd;
18 76193d7c 2003-09-30 devnull Biobuf in;
19 76193d7c 2003-09-30 devnull Bufblock *buf;
20 9aa1c92f 2005-01-04 devnull char *err;
22 76193d7c 2003-09-30 devnull if(fd < 0){
23 76193d7c 2003-09-30 devnull fprint(2, "open %s: %r\n", f);
26 9aa1c92f 2005-01-04 devnull pushshell();
28 76193d7c 2003-09-30 devnull infile = strdup(f);
29 76193d7c 2003-09-30 devnull mkinline = 1;
30 76193d7c 2003-09-30 devnull Binit(&in, fd, OREAD);
31 76193d7c 2003-09-30 devnull buf = newbuf();
32 76193d7c 2003-09-30 devnull while(assline(&in, buf)){
33 76193d7c 2003-09-30 devnull hline = mkinline;
34 76193d7c 2003-09-30 devnull switch(rhead(buf->start, &head, &tail, &attr, &prog))
36 76193d7c 2003-09-30 devnull case '<':
37 76193d7c 2003-09-30 devnull p = wtos(tail, ' ');
38 76193d7c 2003-09-30 devnull if(*p == 0){
39 76193d7c 2003-09-30 devnull SYNERR(-1);
40 76193d7c 2003-09-30 devnull fprint(2, "missing include file name\n");
43 76193d7c 2003-09-30 devnull newfd = open(p, OREAD);
44 76193d7c 2003-09-30 devnull if(newfd < 0){
45 76193d7c 2003-09-30 devnull fprint(2, "warning: skipping missing include file %s: %r\n", p);
47 76193d7c 2003-09-30 devnull parse(p, newfd, 0);
49 76193d7c 2003-09-30 devnull case '|':
50 76193d7c 2003-09-30 devnull p = wtos(tail, ' ');
51 76193d7c 2003-09-30 devnull if(*p == 0){
52 76193d7c 2003-09-30 devnull SYNERR(-1);
53 76193d7c 2003-09-30 devnull fprint(2, "missing include program name\n");
56 76193d7c 2003-09-30 devnull execinit();
57 9aa1c92f 2005-01-04 devnull pid=pipecmd(p, envy, &newfd, shellt, shellcmd);
58 76193d7c 2003-09-30 devnull if(newfd < 0){
59 76193d7c 2003-09-30 devnull fprint(2, "warning: skipping missing program file %s: %r\n", p);
61 76193d7c 2003-09-30 devnull parse(p, newfd, 0);
62 76193d7c 2003-09-30 devnull while(waitup(-3, &pid) >= 0)
64 76193d7c 2003-09-30 devnull if(pid != 0){
65 76193d7c 2003-09-30 devnull fprint(2, "bad include program status\n");
69 76193d7c 2003-09-30 devnull case ':':
70 76193d7c 2003-09-30 devnull body = rbody(&in);
71 76193d7c 2003-09-30 devnull addrules(head, tail, body, attr, hline, prog);
73 76193d7c 2003-09-30 devnull case '=':
74 76193d7c 2003-09-30 devnull if(head->next){
75 76193d7c 2003-09-30 devnull SYNERR(-1);
76 76193d7c 2003-09-30 devnull fprint(2, "multiple vars on left side of assignment\n");
79 76193d7c 2003-09-30 devnull if(symlook(head->s, S_OVERRIDE, 0)){
80 76193d7c 2003-09-30 devnull set = varoverride;
83 76193d7c 2003-09-30 devnull if(varoverride)
84 76193d7c 2003-09-30 devnull symlook(head->s, S_OVERRIDE, (void *)"");
88 76193d7c 2003-09-30 devnull char *cp;
89 76193d7c 2003-09-30 devnull dumpw("tail", tail);
90 76193d7c 2003-09-30 devnull cp = wtos(tail, ' '); print("assign %s to %s\n", head->s, cp); free(cp);
92 76193d7c 2003-09-30 devnull setvar(head->s, (void *) tail);
93 76193d7c 2003-09-30 devnull symlook(head->s, S_WESET, (void *)"");
94 c8b6342d 2005-01-13 devnull if(strcmp(head->s, "MKSHELL") == 0){
95 c8b6342d 2005-01-13 devnull if((err = setshell(tail)) != nil){
96 c8b6342d 2005-01-13 devnull SYNERR(hline);
97 c8b6342d 2005-01-13 devnull fprint(2, "%s\n", err);
103 76193d7c 2003-09-30 devnull if(attr)
104 76193d7c 2003-09-30 devnull symlook(head->s, S_NOEXPORT, (void *)"");
106 76193d7c 2003-09-30 devnull default:
107 76193d7c 2003-09-30 devnull SYNERR(hline);
108 76193d7c 2003-09-30 devnull fprint(2, "expected one of :<=\n");
113 76193d7c 2003-09-30 devnull close(fd);
114 76193d7c 2003-09-30 devnull freebuf(buf);
116 9aa1c92f 2005-01-04 devnull popshell();
120 76193d7c 2003-09-30 devnull addrules(Word *head, Word *tail, char *body, int attr, int hline, char *prog)
122 76193d7c 2003-09-30 devnull Word *w;
124 76193d7c 2003-09-30 devnull assert("addrules args", head && body);
125 76193d7c 2003-09-30 devnull /* tuck away first non-meta rule as default target*/
126 76193d7c 2003-09-30 devnull if(target1 == 0 && !(attr®EXP)){
127 76193d7c 2003-09-30 devnull for(w = head; w; w = w->next)
128 9aa1c92f 2005-01-04 devnull if(shellt->charin(w->s, "%&"))
130 76193d7c 2003-09-30 devnull if(w == 0)
131 76193d7c 2003-09-30 devnull target1 = wdup(head);
133 76193d7c 2003-09-30 devnull for(w = head; w; w = w->next)
134 76193d7c 2003-09-30 devnull addrule(w->s, tail, body, head, attr, hline, prog);
137 76193d7c 2003-09-30 devnull static int
138 76193d7c 2003-09-30 devnull rhead(char *line, Word **h, Word **t, int *attr, char **prog)
140 76193d7c 2003-09-30 devnull char *p;
141 76193d7c 2003-09-30 devnull char *pp;
142 76193d7c 2003-09-30 devnull int sep;
145 76193d7c 2003-09-30 devnull Word *w;
147 c8b6342d 2005-01-13 devnull p = shellt->charin(line,":=<");
148 c8b6342d 2005-01-13 devnull if(p == 0)
149 c8b6342d 2005-01-13 devnull return('?');
150 c8b6342d 2005-01-13 devnull sep = *p;
151 c8b6342d 2005-01-13 devnull *p++ = 0;
152 c8b6342d 2005-01-13 devnull if(sep == '<' && *p == '|'){
153 c8b6342d 2005-01-13 devnull sep = '|';
156 76193d7c 2003-09-30 devnull *attr = 0;
157 76193d7c 2003-09-30 devnull *prog = 0;
158 76193d7c 2003-09-30 devnull if(sep == '='){
159 9aa1c92f 2005-01-04 devnull pp = shellt->charin(p, shellt->termchars); /* termchars is shell-dependent */
160 76193d7c 2003-09-30 devnull if (pp && *pp == '=') {
161 76193d7c 2003-09-30 devnull while (p != pp) {
162 76193d7c 2003-09-30 devnull n = chartorune(&r, p);
163 76193d7c 2003-09-30 devnull switch(r)
165 76193d7c 2003-09-30 devnull default:
166 76193d7c 2003-09-30 devnull SYNERR(-1);
167 76193d7c 2003-09-30 devnull fprint(2, "unknown attribute '%c'\n",*p);
169 76193d7c 2003-09-30 devnull case 'U':
170 76193d7c 2003-09-30 devnull *attr = 1;
175 76193d7c 2003-09-30 devnull p++; /* skip trailing '=' */
178 76193d7c 2003-09-30 devnull if((sep == ':') && *p && (*p != ' ') && (*p != '\t')){
179 76193d7c 2003-09-30 devnull while (*p) {
180 76193d7c 2003-09-30 devnull n = chartorune(&r, p);
181 76193d7c 2003-09-30 devnull if (r == ':')
184 76193d7c 2003-09-30 devnull switch(r)
186 76193d7c 2003-09-30 devnull default:
187 76193d7c 2003-09-30 devnull SYNERR(-1);
188 76193d7c 2003-09-30 devnull fprint(2, "unknown attribute '%c'\n", p[-1]);
190 76193d7c 2003-09-30 devnull case 'D':
191 76193d7c 2003-09-30 devnull *attr |= DEL;
193 76193d7c 2003-09-30 devnull case 'E':
194 76193d7c 2003-09-30 devnull *attr |= NOMINUSE;
196 76193d7c 2003-09-30 devnull case 'n':
197 76193d7c 2003-09-30 devnull *attr |= NOVIRT;
199 76193d7c 2003-09-30 devnull case 'N':
200 76193d7c 2003-09-30 devnull *attr |= NOREC;
202 76193d7c 2003-09-30 devnull case 'P':
203 76193d7c 2003-09-30 devnull pp = utfrune(p, ':');
204 76193d7c 2003-09-30 devnull if (pp == 0 || *pp == 0)
205 76193d7c 2003-09-30 devnull goto eos;
206 76193d7c 2003-09-30 devnull *pp = 0;
207 76193d7c 2003-09-30 devnull *prog = strdup(p);
208 76193d7c 2003-09-30 devnull *pp = ':';
211 76193d7c 2003-09-30 devnull case 'Q':
212 76193d7c 2003-09-30 devnull *attr |= QUIET;
214 76193d7c 2003-09-30 devnull case 'R':
215 76193d7c 2003-09-30 devnull *attr |= REGEXP;
217 76193d7c 2003-09-30 devnull case 'U':
218 76193d7c 2003-09-30 devnull *attr |= UPD;
220 76193d7c 2003-09-30 devnull case 'V':
221 76193d7c 2003-09-30 devnull *attr |= VIR;
225 76193d7c 2003-09-30 devnull if (*p++ != ':') {
227 76193d7c 2003-09-30 devnull SYNERR(-1);
228 76193d7c 2003-09-30 devnull fprint(2, "missing trailing :\n");
232 76193d7c 2003-09-30 devnull *h = w = stow(line);
233 9aa1c92f 2005-01-04 devnull if(*w->s == 0 && sep != '<' && sep != '|' && sep != 'S') {
234 76193d7c 2003-09-30 devnull SYNERR(mkinline-1);
235 76193d7c 2003-09-30 devnull fprint(2, "no var on left side of assignment/rule\n");
238 76193d7c 2003-09-30 devnull *t = stow(p);
239 76193d7c 2003-09-30 devnull return(sep);
242 76193d7c 2003-09-30 devnull static char *
243 76193d7c 2003-09-30 devnull rbody(Biobuf *in)
245 76193d7c 2003-09-30 devnull Bufblock *buf;
246 76193d7c 2003-09-30 devnull int r, lastr;
247 76193d7c 2003-09-30 devnull char *p;
249 76193d7c 2003-09-30 devnull lastr = '\n';
250 76193d7c 2003-09-30 devnull buf = newbuf();
251 76193d7c 2003-09-30 devnull for(;;){
252 76193d7c 2003-09-30 devnull r = Bgetrune(in);
253 76193d7c 2003-09-30 devnull if (r < 0)
255 76193d7c 2003-09-30 devnull if (lastr == '\n') {
256 76193d7c 2003-09-30 devnull if (r == '#')
257 76193d7c 2003-09-30 devnull rinsert(buf, r);
258 76193d7c 2003-09-30 devnull else if (r != ' ' && r != '\t') {
259 76193d7c 2003-09-30 devnull Bungetrune(in);
263 76193d7c 2003-09-30 devnull rinsert(buf, r);
264 76193d7c 2003-09-30 devnull lastr = r;
265 76193d7c 2003-09-30 devnull if (r == '\n')
266 76193d7c 2003-09-30 devnull mkinline++;
268 76193d7c 2003-09-30 devnull insert(buf, 0);
269 76193d7c 2003-09-30 devnull p = strdup(buf->start);
270 76193d7c 2003-09-30 devnull freebuf(buf);
271 76193d7c 2003-09-30 devnull return p;
274 76193d7c 2003-09-30 devnull struct input
276 76193d7c 2003-09-30 devnull char *file;
277 76193d7c 2003-09-30 devnull int line;
278 76193d7c 2003-09-30 devnull struct input *next;
280 76193d7c 2003-09-30 devnull static struct input *inputs = 0;
283 76193d7c 2003-09-30 devnull ipush(void)
285 76193d7c 2003-09-30 devnull struct input *in, *me;
287 76193d7c 2003-09-30 devnull me = (struct input *)Malloc(sizeof(*me));
288 76193d7c 2003-09-30 devnull me->file = infile;
289 76193d7c 2003-09-30 devnull me->line = mkinline;
290 76193d7c 2003-09-30 devnull me->next = 0;
291 76193d7c 2003-09-30 devnull if(inputs == 0)
292 76193d7c 2003-09-30 devnull inputs = me;
294 76193d7c 2003-09-30 devnull for(in = inputs; in->next; )
295 76193d7c 2003-09-30 devnull in = in->next;
296 76193d7c 2003-09-30 devnull in->next = me;
301 76193d7c 2003-09-30 devnull ipop(void)
303 76193d7c 2003-09-30 devnull struct input *in, *me;
305 76193d7c 2003-09-30 devnull assert("pop input list", inputs != 0);
306 76193d7c 2003-09-30 devnull if(inputs->next == 0){
307 76193d7c 2003-09-30 devnull me = inputs;
308 76193d7c 2003-09-30 devnull inputs = 0;
309 76193d7c 2003-09-30 devnull } else {
310 76193d7c 2003-09-30 devnull for(in = inputs; in->next->next; )
311 76193d7c 2003-09-30 devnull in = in->next;
312 76193d7c 2003-09-30 devnull me = in->next;
313 76193d7c 2003-09-30 devnull in->next = 0;
315 76193d7c 2003-09-30 devnull infile = me->file;
316 76193d7c 2003-09-30 devnull mkinline = me->line;
317 76193d7c 2003-09-30 devnull free((char *)me);