13e12c5d1SDavid du Colombier #include "mk.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier char *infile; 43e12c5d1SDavid du Colombier int inline; 53e12c5d1SDavid du Colombier static int rhead(char *, Word **, Word **, int *, char **); 63e12c5d1SDavid du Colombier static char *rbody(Biobuf*); 73e12c5d1SDavid du Colombier extern Word *target1; 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier void 103e12c5d1SDavid du Colombier parse(char *f, int fd, int varoverride, int ruleoverride) 113e12c5d1SDavid du Colombier { 123e12c5d1SDavid du Colombier int hline; 133e12c5d1SDavid du Colombier char *body; 143e12c5d1SDavid du Colombier Word *head, *tail; 153e12c5d1SDavid du Colombier int attr, set; 163e12c5d1SDavid du Colombier char *prog, *inc; 17*219b2ee8SDavid du Colombier int newfd; 183e12c5d1SDavid du Colombier Biobuf in; 193e12c5d1SDavid du Colombier Bufblock *buf; 203e12c5d1SDavid du Colombier 213e12c5d1SDavid du Colombier if(fd < 0){ 223e12c5d1SDavid du Colombier perror(f); 233e12c5d1SDavid du Colombier Exit(); 243e12c5d1SDavid du Colombier } 253e12c5d1SDavid du Colombier ipush(); 263e12c5d1SDavid du Colombier infile = strdup(f); 273e12c5d1SDavid du Colombier inline = 1; 283e12c5d1SDavid du Colombier Binit(&in, fd, OREAD); 293e12c5d1SDavid du Colombier buf = newbuf(); 303e12c5d1SDavid du Colombier inc = 0; 313e12c5d1SDavid du Colombier while(assline(&in, buf)){ 323e12c5d1SDavid du Colombier hline = inline; 333e12c5d1SDavid du Colombier switch(rhead(buf->start, &head, &tail, &attr, &prog)) 343e12c5d1SDavid du Colombier { 353e12c5d1SDavid du Colombier case '<': 363e12c5d1SDavid du Colombier if((tail == 0) || ((inc = wtos(tail)) == 0)){ 373e12c5d1SDavid du Colombier SYNERR(-1); 383e12c5d1SDavid du Colombier fprint(2, "missing include file name\n"); 393e12c5d1SDavid du Colombier Exit(); 403e12c5d1SDavid du Colombier } 41*219b2ee8SDavid du Colombier if((newfd = open(inc, 0)) < 0){ 42*219b2ee8SDavid du Colombier fprint(2, "warning: skipping missing include file: "); 43*219b2ee8SDavid du Colombier perror(inc); 44*219b2ee8SDavid du Colombier } else 45*219b2ee8SDavid du Colombier parse(inc, newfd, 0, 1); 463e12c5d1SDavid du Colombier break; 473e12c5d1SDavid du Colombier case ':': 483e12c5d1SDavid du Colombier body = rbody(&in); 493e12c5d1SDavid du Colombier addrules(head, tail, body, attr, hline, ruleoverride, prog); 503e12c5d1SDavid du Colombier break; 513e12c5d1SDavid du Colombier case '=': 523e12c5d1SDavid du Colombier if(head->next){ 533e12c5d1SDavid du Colombier SYNERR(-1); 543e12c5d1SDavid du Colombier fprint(2, "multiple vars on left side of assignment\n"); 553e12c5d1SDavid du Colombier Exit(); 563e12c5d1SDavid du Colombier } 573e12c5d1SDavid du Colombier if(symlook(head->s, S_OVERRIDE, (char *)0)){ 583e12c5d1SDavid du Colombier set = varoverride; 593e12c5d1SDavid du Colombier symdel(head->s, S_OVERRIDE); 603e12c5d1SDavid du Colombier } else { 613e12c5d1SDavid du Colombier set = 1; 623e12c5d1SDavid du Colombier if(varoverride) 633e12c5d1SDavid du Colombier symlook(head->s, S_OVERRIDE, ""); 643e12c5d1SDavid du Colombier } 653e12c5d1SDavid du Colombier if(set){ 663e12c5d1SDavid du Colombier /* 673e12c5d1SDavid du Colombier char *cp; 683e12c5d1SDavid du Colombier dumpw("tail", tail); 693e12c5d1SDavid du Colombier cp = wtos(tail); print("assign %s to %s\n", head->s, cp); free(cp); 703e12c5d1SDavid du Colombier */ 713e12c5d1SDavid du Colombier setvar(head->s, (char *) tail); 723e12c5d1SDavid du Colombier symlook(head->s, S_WESET, ""); 733e12c5d1SDavid du Colombier } 743e12c5d1SDavid du Colombier if(attr) 753e12c5d1SDavid du Colombier symlook(head->s, S_NOEXPORT, ""); 763e12c5d1SDavid du Colombier break; 773e12c5d1SDavid du Colombier default: 783e12c5d1SDavid du Colombier SYNERR(hline); 793e12c5d1SDavid du Colombier fprint(2, "expected one of :<=\n"); 803e12c5d1SDavid du Colombier Exit(); 813e12c5d1SDavid du Colombier break; 823e12c5d1SDavid du Colombier } 833e12c5d1SDavid du Colombier } 843e12c5d1SDavid du Colombier close(fd); 853e12c5d1SDavid du Colombier freebuf(buf); 863e12c5d1SDavid du Colombier ipop(); 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier 893e12c5d1SDavid du Colombier void 903e12c5d1SDavid du Colombier addrules(Word *head, Word *tail, char *body, int attr, int hline, int override, char *prog) 913e12c5d1SDavid du Colombier { 923e12c5d1SDavid du Colombier Word *w; 933e12c5d1SDavid du Colombier 943e12c5d1SDavid du Colombier assert("addrules args", head && body); 953e12c5d1SDavid du Colombier if((target1 == 0) && !(attr®EXP)) 963e12c5d1SDavid du Colombier frule(head); 973e12c5d1SDavid du Colombier for(w = head; w; w = w->next) 983e12c5d1SDavid du Colombier addrule(w->s, tail, body, head, attr, hline, override, prog); 993e12c5d1SDavid du Colombier } 1003e12c5d1SDavid du Colombier 1013e12c5d1SDavid du Colombier static int 1023e12c5d1SDavid du Colombier rhead(char *line, Word **h, Word **t, int *attr, char **prog) 1033e12c5d1SDavid du Colombier { 1043e12c5d1SDavid du Colombier char *p; 1053e12c5d1SDavid du Colombier char *pp; 1063e12c5d1SDavid du Colombier int sep; 1073e12c5d1SDavid du Colombier Rune r; 1083e12c5d1SDavid du Colombier int n; 1093e12c5d1SDavid du Colombier Word *w; 1103e12c5d1SDavid du Colombier 1113e12c5d1SDavid du Colombier p = charin(line,":=<"); 1123e12c5d1SDavid du Colombier if(p == 0) 1133e12c5d1SDavid du Colombier return('?'); 1143e12c5d1SDavid du Colombier sep = *p; 1153e12c5d1SDavid du Colombier *p++ = 0; 1163e12c5d1SDavid du Colombier *attr = 0; 1173e12c5d1SDavid du Colombier *prog = 0; 1183e12c5d1SDavid du Colombier /*print("SEP: %c\n", sep);*/ 1193e12c5d1SDavid du Colombier if(sep == '='){ 120*219b2ee8SDavid du Colombier pp = charin(p, "'= \t"); 121*219b2ee8SDavid du Colombier if (pp && *pp == '=') { 1223e12c5d1SDavid du Colombier while (p != pp) { 1233e12c5d1SDavid du Colombier n = chartorune(&r, p); 1243e12c5d1SDavid du Colombier switch(r) 1253e12c5d1SDavid du Colombier { 1263e12c5d1SDavid du Colombier default: 1273e12c5d1SDavid du Colombier SYNERR(-1); 1283e12c5d1SDavid du Colombier fprint(2, "unknown attribute '%c'\n",*p); 1293e12c5d1SDavid du Colombier Exit(); 1303e12c5d1SDavid du Colombier case 'U': 1313e12c5d1SDavid du Colombier *attr = 1; 1323e12c5d1SDavid du Colombier break; 1333e12c5d1SDavid du Colombier } 1343e12c5d1SDavid du Colombier p += n; 1353e12c5d1SDavid du Colombier } 1363e12c5d1SDavid du Colombier p++; /* skip trailing '=' */ 1373e12c5d1SDavid du Colombier } 1383e12c5d1SDavid du Colombier } 1393e12c5d1SDavid du Colombier if((sep == ':') && *p && (*p != ' ') && (*p != '\t')){ 1403e12c5d1SDavid du Colombier while (*p) { 1413e12c5d1SDavid du Colombier n = chartorune(&r, p); 1423e12c5d1SDavid du Colombier if (r == ':') 1433e12c5d1SDavid du Colombier break; 1443e12c5d1SDavid du Colombier p += n; 1453e12c5d1SDavid du Colombier switch(r) 1463e12c5d1SDavid du Colombier { 1473e12c5d1SDavid du Colombier default: 1483e12c5d1SDavid du Colombier SYNERR(-1); 1493e12c5d1SDavid du Colombier fprint(2, "unknown attribute '%c'\n", p[-1]); 1503e12c5d1SDavid du Colombier Exit(); 1513e12c5d1SDavid du Colombier case '<': 1523e12c5d1SDavid du Colombier *attr |= RED; 1533e12c5d1SDavid du Colombier break; 1543e12c5d1SDavid du Colombier case 'D': 1553e12c5d1SDavid du Colombier *attr |= DEL; 1563e12c5d1SDavid du Colombier break; 1573e12c5d1SDavid du Colombier case 'E': 1583e12c5d1SDavid du Colombier *attr |= NOMINUSE; 1593e12c5d1SDavid du Colombier break; 1603e12c5d1SDavid du Colombier case 'n': 1613e12c5d1SDavid du Colombier *attr |= NOVIRT; 1623e12c5d1SDavid du Colombier break; 1633e12c5d1SDavid du Colombier case 'N': 1643e12c5d1SDavid du Colombier *attr |= NOREC; 1653e12c5d1SDavid du Colombier break; 1663e12c5d1SDavid du Colombier case 'P': 1673e12c5d1SDavid du Colombier pp = charin(p, ":"); 1683e12c5d1SDavid du Colombier if (pp == 0 || *pp == 0) 1693e12c5d1SDavid du Colombier goto eos; 1703e12c5d1SDavid du Colombier *pp = 0; 1713e12c5d1SDavid du Colombier *prog = strdup(p); 1723e12c5d1SDavid du Colombier *pp = ':'; 1733e12c5d1SDavid du Colombier p = pp; 1743e12c5d1SDavid du Colombier break; 1753e12c5d1SDavid du Colombier case 'Q': 1763e12c5d1SDavid du Colombier *attr |= QUIET; 1773e12c5d1SDavid du Colombier break; 1783e12c5d1SDavid du Colombier case 'R': 1793e12c5d1SDavid du Colombier *attr |= REGEXP; 1803e12c5d1SDavid du Colombier break; 1813e12c5d1SDavid du Colombier case 'U': 1823e12c5d1SDavid du Colombier *attr |= UPD; 1833e12c5d1SDavid du Colombier break; 1843e12c5d1SDavid du Colombier case 'V': 1853e12c5d1SDavid du Colombier *attr |= VIR; 1863e12c5d1SDavid du Colombier break; 1873e12c5d1SDavid du Colombier } 1883e12c5d1SDavid du Colombier } 1893e12c5d1SDavid du Colombier if (*p++ != ':') { 1903e12c5d1SDavid du Colombier eos: 1913e12c5d1SDavid du Colombier SYNERR(-1); 1923e12c5d1SDavid du Colombier fprint(2, "missing trailing :\n"); 1933e12c5d1SDavid du Colombier Exit(); 1943e12c5d1SDavid du Colombier } 1953e12c5d1SDavid du Colombier } 1963e12c5d1SDavid du Colombier *h = w = stow(line); 1973e12c5d1SDavid du Colombier if(!*w->s) { 1983e12c5d1SDavid du Colombier if (sep != '<') { 1993e12c5d1SDavid du Colombier SYNERR(inline-1); 2003e12c5d1SDavid du Colombier fprint(2, "no var on left side of assignment/rule\n"); 2013e12c5d1SDavid du Colombier Exit(); 2023e12c5d1SDavid du Colombier } 2033e12c5d1SDavid du Colombier } 2043e12c5d1SDavid du Colombier *t = stow(p); 2053e12c5d1SDavid du Colombier return(sep); 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier 2083e12c5d1SDavid du Colombier static char * 2093e12c5d1SDavid du Colombier rbody(Biobuf *in) 2103e12c5d1SDavid du Colombier { 2113e12c5d1SDavid du Colombier Bufblock *buf; 2123e12c5d1SDavid du Colombier int r, lastr; 2133e12c5d1SDavid du Colombier char *p; 2143e12c5d1SDavid du Colombier 2153e12c5d1SDavid du Colombier lastr = '\n'; 2163e12c5d1SDavid du Colombier buf = newbuf(); 2173e12c5d1SDavid du Colombier for(;;){ 2183e12c5d1SDavid du Colombier r = Bgetrune(in); 2193e12c5d1SDavid du Colombier if (r < 0) 2203e12c5d1SDavid du Colombier break; 2213e12c5d1SDavid du Colombier if (lastr == '\n') { 2223e12c5d1SDavid du Colombier if (r == '#') 2233e12c5d1SDavid du Colombier rinsert(buf, r); 2243e12c5d1SDavid du Colombier else if (r != ' ' && r != '\t') { 2253e12c5d1SDavid du Colombier Bungetrune(in); 2263e12c5d1SDavid du Colombier break; 2273e12c5d1SDavid du Colombier } 2283e12c5d1SDavid du Colombier } else 2293e12c5d1SDavid du Colombier rinsert(buf, r); 2303e12c5d1SDavid du Colombier lastr = r; 2313e12c5d1SDavid du Colombier if (r == '\n') 2323e12c5d1SDavid du Colombier inline++; 2333e12c5d1SDavid du Colombier } 2343e12c5d1SDavid du Colombier insert(buf, 0); 2353e12c5d1SDavid du Colombier p = strdup(buf->start); 2363e12c5d1SDavid du Colombier freebuf(buf); 2373e12c5d1SDavid du Colombier return p; 2383e12c5d1SDavid du Colombier } 2393e12c5d1SDavid du Colombier 2403e12c5d1SDavid du Colombier struct input 2413e12c5d1SDavid du Colombier { 2423e12c5d1SDavid du Colombier char *file; 2433e12c5d1SDavid du Colombier int line; 2443e12c5d1SDavid du Colombier struct input *next; 2453e12c5d1SDavid du Colombier }; 2463e12c5d1SDavid du Colombier static struct input *inputs = 0; 2473e12c5d1SDavid du Colombier 2483e12c5d1SDavid du Colombier void 2493e12c5d1SDavid du Colombier ipush(void) 2503e12c5d1SDavid du Colombier { 2513e12c5d1SDavid du Colombier struct input *in, *me; 2523e12c5d1SDavid du Colombier 2533e12c5d1SDavid du Colombier me = (struct input *)Malloc(sizeof(*me)); 2543e12c5d1SDavid du Colombier me->file = infile; 2553e12c5d1SDavid du Colombier me->line = inline; 2563e12c5d1SDavid du Colombier me->next = 0; 2573e12c5d1SDavid du Colombier if(inputs == 0) 2583e12c5d1SDavid du Colombier inputs = me; 2593e12c5d1SDavid du Colombier else { 2603e12c5d1SDavid du Colombier for(in = inputs; in->next; ) 2613e12c5d1SDavid du Colombier in = in->next; 2623e12c5d1SDavid du Colombier in->next = me; 2633e12c5d1SDavid du Colombier } 2643e12c5d1SDavid du Colombier } 2653e12c5d1SDavid du Colombier 2663e12c5d1SDavid du Colombier void 2673e12c5d1SDavid du Colombier ipop(void) 2683e12c5d1SDavid du Colombier { 2693e12c5d1SDavid du Colombier struct input *in, *me; 2703e12c5d1SDavid du Colombier 2713e12c5d1SDavid du Colombier assert("pop input list", inputs != 0); 2723e12c5d1SDavid du Colombier if(inputs->next == 0){ 2733e12c5d1SDavid du Colombier me = inputs; 2743e12c5d1SDavid du Colombier inputs = 0; 2753e12c5d1SDavid du Colombier } else { 2763e12c5d1SDavid du Colombier for(in = inputs; in->next->next; ) 2773e12c5d1SDavid du Colombier in = in->next; 2783e12c5d1SDavid du Colombier me = in->next; 2793e12c5d1SDavid du Colombier in->next = 0; 2803e12c5d1SDavid du Colombier } 2813e12c5d1SDavid du Colombier infile = me->file; 2823e12c5d1SDavid du Colombier inline = me->line; 2833e12c5d1SDavid du Colombier free((char *)me); 2843e12c5d1SDavid du Colombier } 285