13e12c5d1SDavid du Colombier #include "mk.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier char *infile;
4*7dd7cddfSDavid du Colombier int mkinline;
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
parse(char * f,int fd,int varoverride)10*7dd7cddfSDavid du Colombier parse(char *f, int fd, int varoverride)
113e12c5d1SDavid du Colombier {
123e12c5d1SDavid du Colombier int hline;
133e12c5d1SDavid du Colombier char *body;
143e12c5d1SDavid du Colombier Word *head, *tail;
15*7dd7cddfSDavid du Colombier int attr, set, pid;
16*7dd7cddfSDavid du Colombier char *prog, *p;
17219b2ee8SDavid 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);
27*7dd7cddfSDavid du Colombier mkinline = 1;
283e12c5d1SDavid du Colombier Binit(&in, fd, OREAD);
293e12c5d1SDavid du Colombier buf = newbuf();
303e12c5d1SDavid du Colombier while(assline(&in, buf)){
31*7dd7cddfSDavid du Colombier hline = mkinline;
323e12c5d1SDavid du Colombier switch(rhead(buf->start, &head, &tail, &attr, &prog))
333e12c5d1SDavid du Colombier {
343e12c5d1SDavid du Colombier case '<':
35*7dd7cddfSDavid du Colombier p = wtos(tail, ' ');
36*7dd7cddfSDavid du Colombier if(*p == 0){
373e12c5d1SDavid du Colombier SYNERR(-1);
383e12c5d1SDavid du Colombier fprint(2, "missing include file name\n");
393e12c5d1SDavid du Colombier Exit();
403e12c5d1SDavid du Colombier }
41*7dd7cddfSDavid du Colombier newfd = open(p, OREAD);
42*7dd7cddfSDavid du Colombier if(newfd < 0){
43219b2ee8SDavid du Colombier fprint(2, "warning: skipping missing include file: ");
44*7dd7cddfSDavid du Colombier perror(p);
45219b2ee8SDavid du Colombier } else
46*7dd7cddfSDavid du Colombier parse(p, newfd, 0);
47*7dd7cddfSDavid du Colombier break;
48*7dd7cddfSDavid du Colombier case '|':
49*7dd7cddfSDavid du Colombier p = wtos(tail, ' ');
50*7dd7cddfSDavid du Colombier if(*p == 0){
51*7dd7cddfSDavid du Colombier SYNERR(-1);
52*7dd7cddfSDavid du Colombier fprint(2, "missing include program name\n");
53*7dd7cddfSDavid du Colombier Exit();
54*7dd7cddfSDavid du Colombier }
55*7dd7cddfSDavid du Colombier execinit();
56*7dd7cddfSDavid du Colombier pid=pipecmd(p, envy, &newfd);
57*7dd7cddfSDavid du Colombier if(newfd < 0){
58*7dd7cddfSDavid du Colombier fprint(2, "warning: skipping missing program file: ");
59*7dd7cddfSDavid du Colombier perror(p);
60*7dd7cddfSDavid du Colombier } else
61*7dd7cddfSDavid du Colombier parse(p, newfd, 0);
62*7dd7cddfSDavid du Colombier while(waitup(-3, &pid) >= 0)
63*7dd7cddfSDavid du Colombier ;
64*7dd7cddfSDavid du Colombier if(pid != 0){
65*7dd7cddfSDavid du Colombier fprint(2, "bad include program status\n");
66*7dd7cddfSDavid du Colombier Exit();
67*7dd7cddfSDavid du Colombier }
683e12c5d1SDavid du Colombier break;
693e12c5d1SDavid du Colombier case ':':
703e12c5d1SDavid du Colombier body = rbody(&in);
71*7dd7cddfSDavid du Colombier addrules(head, tail, body, attr, hline, prog);
723e12c5d1SDavid du Colombier break;
733e12c5d1SDavid du Colombier case '=':
743e12c5d1SDavid du Colombier if(head->next){
753e12c5d1SDavid du Colombier SYNERR(-1);
763e12c5d1SDavid du Colombier fprint(2, "multiple vars on left side of assignment\n");
773e12c5d1SDavid du Colombier Exit();
783e12c5d1SDavid du Colombier }
79*7dd7cddfSDavid du Colombier if(symlook(head->s, S_OVERRIDE, 0)){
803e12c5d1SDavid du Colombier set = varoverride;
813e12c5d1SDavid du Colombier } else {
823e12c5d1SDavid du Colombier set = 1;
833e12c5d1SDavid du Colombier if(varoverride)
84*7dd7cddfSDavid du Colombier symlook(head->s, S_OVERRIDE, (void *)"");
853e12c5d1SDavid du Colombier }
863e12c5d1SDavid du Colombier if(set){
873e12c5d1SDavid du Colombier /*
883e12c5d1SDavid du Colombier char *cp;
893e12c5d1SDavid du Colombier dumpw("tail", tail);
90*7dd7cddfSDavid du Colombier cp = wtos(tail, ' '); print("assign %s to %s\n", head->s, cp); free(cp);
913e12c5d1SDavid du Colombier */
92*7dd7cddfSDavid du Colombier setvar(head->s, (void *) tail);
93*7dd7cddfSDavid du Colombier symlook(head->s, S_WESET, (void *)"");
943e12c5d1SDavid du Colombier }
953e12c5d1SDavid du Colombier if(attr)
96*7dd7cddfSDavid du Colombier symlook(head->s, S_NOEXPORT, (void *)"");
973e12c5d1SDavid du Colombier break;
983e12c5d1SDavid du Colombier default:
993e12c5d1SDavid du Colombier SYNERR(hline);
1003e12c5d1SDavid du Colombier fprint(2, "expected one of :<=\n");
1013e12c5d1SDavid du Colombier Exit();
1023e12c5d1SDavid du Colombier break;
1033e12c5d1SDavid du Colombier }
1043e12c5d1SDavid du Colombier }
1053e12c5d1SDavid du Colombier close(fd);
1063e12c5d1SDavid du Colombier freebuf(buf);
1073e12c5d1SDavid du Colombier ipop();
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier
1103e12c5d1SDavid du Colombier void
addrules(Word * head,Word * tail,char * body,int attr,int hline,char * prog)111*7dd7cddfSDavid du Colombier addrules(Word *head, Word *tail, char *body, int attr, int hline, char *prog)
1123e12c5d1SDavid du Colombier {
1133e12c5d1SDavid du Colombier Word *w;
1143e12c5d1SDavid du Colombier
115*7dd7cddfSDavid du Colombier assert(/*addrules args*/ head && body);
116*7dd7cddfSDavid du Colombier /* tuck away first non-meta rule as default target*/
117*7dd7cddfSDavid du Colombier if(target1 == 0 && !(attr®EXP)){
1183e12c5d1SDavid du Colombier for(w = head; w; w = w->next)
119*7dd7cddfSDavid du Colombier if(charin(w->s, "%&"))
120*7dd7cddfSDavid du Colombier break;
121*7dd7cddfSDavid du Colombier if(w == 0)
122*7dd7cddfSDavid du Colombier target1 = wdup(head);
123*7dd7cddfSDavid du Colombier }
124*7dd7cddfSDavid du Colombier for(w = head; w; w = w->next)
125*7dd7cddfSDavid du Colombier addrule(w->s, tail, body, head, attr, hline, prog);
1263e12c5d1SDavid du Colombier }
1273e12c5d1SDavid du Colombier
1283e12c5d1SDavid du Colombier static int
rhead(char * line,Word ** h,Word ** t,int * attr,char ** prog)1293e12c5d1SDavid du Colombier rhead(char *line, Word **h, Word **t, int *attr, char **prog)
1303e12c5d1SDavid du Colombier {
1313e12c5d1SDavid du Colombier char *p;
1323e12c5d1SDavid du Colombier char *pp;
1333e12c5d1SDavid du Colombier int sep;
1343e12c5d1SDavid du Colombier Rune r;
1353e12c5d1SDavid du Colombier int n;
1363e12c5d1SDavid du Colombier Word *w;
1373e12c5d1SDavid du Colombier
1383e12c5d1SDavid du Colombier p = charin(line,":=<");
1393e12c5d1SDavid du Colombier if(p == 0)
1403e12c5d1SDavid du Colombier return('?');
1413e12c5d1SDavid du Colombier sep = *p;
1423e12c5d1SDavid du Colombier *p++ = 0;
143*7dd7cddfSDavid du Colombier if(sep == '<' && *p == '|'){
144*7dd7cddfSDavid du Colombier sep = '|';
145*7dd7cddfSDavid du Colombier p++;
146*7dd7cddfSDavid du Colombier }
1473e12c5d1SDavid du Colombier *attr = 0;
1483e12c5d1SDavid du Colombier *prog = 0;
1493e12c5d1SDavid du Colombier if(sep == '='){
150*7dd7cddfSDavid du Colombier pp = charin(p, termchars); /* termchars is shell-dependent */
151219b2ee8SDavid du Colombier if (pp && *pp == '=') {
1523e12c5d1SDavid du Colombier while (p != pp) {
1533e12c5d1SDavid du Colombier n = chartorune(&r, p);
1543e12c5d1SDavid du Colombier switch(r)
1553e12c5d1SDavid du Colombier {
1563e12c5d1SDavid du Colombier default:
1573e12c5d1SDavid du Colombier SYNERR(-1);
1583e12c5d1SDavid du Colombier fprint(2, "unknown attribute '%c'\n",*p);
1593e12c5d1SDavid du Colombier Exit();
1603e12c5d1SDavid du Colombier case 'U':
1613e12c5d1SDavid du Colombier *attr = 1;
1623e12c5d1SDavid du Colombier break;
1633e12c5d1SDavid du Colombier }
1643e12c5d1SDavid du Colombier p += n;
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier p++; /* skip trailing '=' */
1673e12c5d1SDavid du Colombier }
1683e12c5d1SDavid du Colombier }
1693e12c5d1SDavid du Colombier if((sep == ':') && *p && (*p != ' ') && (*p != '\t')){
1703e12c5d1SDavid du Colombier while (*p) {
1713e12c5d1SDavid du Colombier n = chartorune(&r, p);
1723e12c5d1SDavid du Colombier if (r == ':')
1733e12c5d1SDavid du Colombier break;
1743e12c5d1SDavid du Colombier p += n;
1753e12c5d1SDavid du Colombier switch(r)
1763e12c5d1SDavid du Colombier {
1773e12c5d1SDavid du Colombier default:
1783e12c5d1SDavid du Colombier SYNERR(-1);
1793e12c5d1SDavid du Colombier fprint(2, "unknown attribute '%c'\n", p[-1]);
1803e12c5d1SDavid du Colombier Exit();
1813e12c5d1SDavid du Colombier case 'D':
1823e12c5d1SDavid du Colombier *attr |= DEL;
1833e12c5d1SDavid du Colombier break;
1843e12c5d1SDavid du Colombier case 'E':
1853e12c5d1SDavid du Colombier *attr |= NOMINUSE;
1863e12c5d1SDavid du Colombier break;
1873e12c5d1SDavid du Colombier case 'n':
1883e12c5d1SDavid du Colombier *attr |= NOVIRT;
1893e12c5d1SDavid du Colombier break;
1903e12c5d1SDavid du Colombier case 'N':
1913e12c5d1SDavid du Colombier *attr |= NOREC;
1923e12c5d1SDavid du Colombier break;
1933e12c5d1SDavid du Colombier case 'P':
194*7dd7cddfSDavid du Colombier pp = utfrune(p, ':');
1953e12c5d1SDavid du Colombier if (pp == 0 || *pp == 0)
1963e12c5d1SDavid du Colombier goto eos;
1973e12c5d1SDavid du Colombier *pp = 0;
1983e12c5d1SDavid du Colombier *prog = strdup(p);
1993e12c5d1SDavid du Colombier *pp = ':';
2003e12c5d1SDavid du Colombier p = pp;
2013e12c5d1SDavid du Colombier break;
2023e12c5d1SDavid du Colombier case 'Q':
2033e12c5d1SDavid du Colombier *attr |= QUIET;
2043e12c5d1SDavid du Colombier break;
2053e12c5d1SDavid du Colombier case 'R':
2063e12c5d1SDavid du Colombier *attr |= REGEXP;
2073e12c5d1SDavid du Colombier break;
2083e12c5d1SDavid du Colombier case 'U':
2093e12c5d1SDavid du Colombier *attr |= UPD;
2103e12c5d1SDavid du Colombier break;
2113e12c5d1SDavid du Colombier case 'V':
2123e12c5d1SDavid du Colombier *attr |= VIR;
2133e12c5d1SDavid du Colombier break;
2143e12c5d1SDavid du Colombier }
2153e12c5d1SDavid du Colombier }
2163e12c5d1SDavid du Colombier if (*p++ != ':') {
2173e12c5d1SDavid du Colombier eos:
2183e12c5d1SDavid du Colombier SYNERR(-1);
2193e12c5d1SDavid du Colombier fprint(2, "missing trailing :\n");
2203e12c5d1SDavid du Colombier Exit();
2213e12c5d1SDavid du Colombier }
2223e12c5d1SDavid du Colombier }
2233e12c5d1SDavid du Colombier *h = w = stow(line);
224*7dd7cddfSDavid du Colombier if(*w->s == 0 && sep != '<' && sep != '|') {
225*7dd7cddfSDavid du Colombier SYNERR(mkinline-1);
2263e12c5d1SDavid du Colombier fprint(2, "no var on left side of assignment/rule\n");
2273e12c5d1SDavid du Colombier Exit();
2283e12c5d1SDavid du Colombier }
2293e12c5d1SDavid du Colombier *t = stow(p);
2303e12c5d1SDavid du Colombier return(sep);
2313e12c5d1SDavid du Colombier }
2323e12c5d1SDavid du Colombier
2333e12c5d1SDavid du Colombier static char *
rbody(Biobuf * in)2343e12c5d1SDavid du Colombier rbody(Biobuf *in)
2353e12c5d1SDavid du Colombier {
2363e12c5d1SDavid du Colombier Bufblock *buf;
2373e12c5d1SDavid du Colombier int r, lastr;
2383e12c5d1SDavid du Colombier char *p;
2393e12c5d1SDavid du Colombier
2403e12c5d1SDavid du Colombier lastr = '\n';
2413e12c5d1SDavid du Colombier buf = newbuf();
2423e12c5d1SDavid du Colombier for(;;){
2433e12c5d1SDavid du Colombier r = Bgetrune(in);
2443e12c5d1SDavid du Colombier if (r < 0)
2453e12c5d1SDavid du Colombier break;
2463e12c5d1SDavid du Colombier if (lastr == '\n') {
2473e12c5d1SDavid du Colombier if (r == '#')
2483e12c5d1SDavid du Colombier rinsert(buf, r);
2493e12c5d1SDavid du Colombier else if (r != ' ' && r != '\t') {
2503e12c5d1SDavid du Colombier Bungetrune(in);
2513e12c5d1SDavid du Colombier break;
2523e12c5d1SDavid du Colombier }
2533e12c5d1SDavid du Colombier } else
2543e12c5d1SDavid du Colombier rinsert(buf, r);
2553e12c5d1SDavid du Colombier lastr = r;
2563e12c5d1SDavid du Colombier if (r == '\n')
257*7dd7cddfSDavid du Colombier mkinline++;
2583e12c5d1SDavid du Colombier }
2593e12c5d1SDavid du Colombier insert(buf, 0);
2603e12c5d1SDavid du Colombier p = strdup(buf->start);
2613e12c5d1SDavid du Colombier freebuf(buf);
2623e12c5d1SDavid du Colombier return p;
2633e12c5d1SDavid du Colombier }
2643e12c5d1SDavid du Colombier
2653e12c5d1SDavid du Colombier struct input
2663e12c5d1SDavid du Colombier {
2673e12c5d1SDavid du Colombier char *file;
2683e12c5d1SDavid du Colombier int line;
2693e12c5d1SDavid du Colombier struct input *next;
2703e12c5d1SDavid du Colombier };
2713e12c5d1SDavid du Colombier static struct input *inputs = 0;
2723e12c5d1SDavid du Colombier
2733e12c5d1SDavid du Colombier void
ipush(void)2743e12c5d1SDavid du Colombier ipush(void)
2753e12c5d1SDavid du Colombier {
2763e12c5d1SDavid du Colombier struct input *in, *me;
2773e12c5d1SDavid du Colombier
2783e12c5d1SDavid du Colombier me = (struct input *)Malloc(sizeof(*me));
2793e12c5d1SDavid du Colombier me->file = infile;
280*7dd7cddfSDavid du Colombier me->line = mkinline;
2813e12c5d1SDavid du Colombier me->next = 0;
2823e12c5d1SDavid du Colombier if(inputs == 0)
2833e12c5d1SDavid du Colombier inputs = me;
2843e12c5d1SDavid du Colombier else {
2853e12c5d1SDavid du Colombier for(in = inputs; in->next; )
2863e12c5d1SDavid du Colombier in = in->next;
2873e12c5d1SDavid du Colombier in->next = me;
2883e12c5d1SDavid du Colombier }
2893e12c5d1SDavid du Colombier }
2903e12c5d1SDavid du Colombier
2913e12c5d1SDavid du Colombier void
ipop(void)2923e12c5d1SDavid du Colombier ipop(void)
2933e12c5d1SDavid du Colombier {
2943e12c5d1SDavid du Colombier struct input *in, *me;
2953e12c5d1SDavid du Colombier
296*7dd7cddfSDavid du Colombier assert(/*pop input list*/ inputs != 0);
2973e12c5d1SDavid du Colombier if(inputs->next == 0){
2983e12c5d1SDavid du Colombier me = inputs;
2993e12c5d1SDavid du Colombier inputs = 0;
3003e12c5d1SDavid du Colombier } else {
3013e12c5d1SDavid du Colombier for(in = inputs; in->next->next; )
3023e12c5d1SDavid du Colombier in = in->next;
3033e12c5d1SDavid du Colombier me = in->next;
3043e12c5d1SDavid du Colombier in->next = 0;
3053e12c5d1SDavid du Colombier }
3063e12c5d1SDavid du Colombier infile = me->file;
307*7dd7cddfSDavid du Colombier mkinline = me->line;
3083e12c5d1SDavid du Colombier free((char *)me);
3093e12c5d1SDavid du Colombier }
310