~ubuntu-branches/ubuntu/natty/9base/natty

« back to all changes in this revision

Viewing changes to mk/parse.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-08-20 17:34:06 UTC
  • mfrom: (6.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090820173406-xpwqa9ruyevvc0ut
Tags: 1:3-3
* Updating maintainer field.
* Updating vcs fields.
* Updating package to standards version 3.8.3.
* Updatin variables writing in rules to consistent style.

Show diffs side-by-side

added added

removed removed

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