~ubuntu-branches/ubuntu/precise/9base/precise

« back to all changes in this revision

Viewing changes to mk/graph.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
 
static Node *applyrules(char *, char *);
4
 
static void togo(Node *);
5
 
static int vacuous(Node *);
6
 
static Node *newnode(char *);
7
 
static void trace(char *, Arc *);
8
 
static void cyclechk(Node *);
9
 
static void ambiguous(Node *);
10
 
static void attribute(Node *);
11
 
 
12
 
Node *
13
 
graph(char *target)
14
 
{
15
 
        Node *node;
16
 
        char *cnt;
17
 
 
18
 
        cnt = rulecnt();
19
 
        node = applyrules(target, cnt);
20
 
        free(cnt);
21
 
        cyclechk(node);
22
 
        node->flags |= PROBABLE;        /* make sure it doesn't get deleted */
23
 
        vacuous(node);
24
 
        ambiguous(node);
25
 
        attribute(node);
26
 
        return(node);
27
 
}
28
 
 
29
 
static Node *
30
 
applyrules(char *target, char *cnt)
31
 
{
32
 
        Symtab *sym;
33
 
        Node *node;
34
 
        Rule *r;
35
 
        Arc head, *a = &head;
36
 
        Word *w;
37
 
        char stem[NAMEBLOCK], buf[NAMEBLOCK];
38
 
        Resub rmatch[NREGEXP];
39
 
 
40
 
/*      print("applyrules(%lux='%s')\n", target, target);*//**/
41
 
        sym = symlook(target, S_NODE, 0);
42
 
        if(sym)
43
 
                return (Node *)(sym->value);
44
 
        target = strdup(target);
45
 
        node = newnode(target);
46
 
        head.n = 0;
47
 
        head.next = 0;
48
 
        sym = symlook(target, S_TARGET, 0);
49
 
        memset((char*)rmatch, 0, sizeof(rmatch));
50
 
        for(r = sym? (Rule *)(sym->value):0; r; r = r->chain){
51
 
                if(r->attr&META) continue;
52
 
                if(strcmp(target, r->target)) continue;
53
 
                if((!r->recipe || !*r->recipe) && (!r->tail || !r->tail->s || !*r->tail->s)) continue;  /* no effect; ignore */
54
 
                if(cnt[r->rule] >= nreps) continue;
55
 
                cnt[r->rule]++;
56
 
                node->flags |= PROBABLE;
57
 
 
58
 
/*              if(r->attr&VIR)
59
 
 *                      node->flags |= VIRTUAL;
60
 
 *              if(r->attr&NOREC)
61
 
 *                      node->flags |= NORECIPE;
62
 
 *              if(r->attr&DEL)
63
 
 *                      node->flags |= DELETE;
64
 
 */
65
 
                if(!r->tail || !r->tail->s || !*r->tail->s) {
66
 
                        a->next = newarc((Node *)0, r, "", rmatch);
67
 
                        a = a->next;
68
 
                } else
69
 
                        for(w = r->tail; w; w = w->next){
70
 
                                a->next = newarc(applyrules(w->s, cnt), r, "", rmatch);
71
 
                                a = a->next;
72
 
                }
73
 
                cnt[r->rule]--;
74
 
                head.n = node;
75
 
        }
76
 
        for(r = metarules; r; r = r->next){
77
 
                if((!r->recipe || !*r->recipe) && (!r->tail || !r->tail->s || !*r->tail->s)) continue;  /* no effect; ignore */
78
 
                if ((r->attr&NOVIRT) && a != &head && (a->r->attr&VIR))
79
 
                        continue;
80
 
                if(r->attr&REGEXP){
81
 
                        stem[0] = 0;
82
 
                        patrule = r;
83
 
                        memset((char*)rmatch, 0, sizeof(rmatch));
84
 
                        if(regexec(r->pat, node->name, rmatch, NREGEXP) == 0)
85
 
                                continue;
86
 
                } else {
87
 
                        if(!match(node->name, r->target, stem, r->shellt)) continue;
88
 
                }
89
 
                if(cnt[r->rule] >= nreps) continue;
90
 
                cnt[r->rule]++;
91
 
 
92
 
/*              if(r->attr&VIR)
93
 
 *                      node->flags |= VIRTUAL;
94
 
 *              if(r->attr&NOREC)
95
 
 *                      node->flags |= NORECIPE;
96
 
 *              if(r->attr&DEL)
97
 
 *                      node->flags |= DELETE;
98
 
 */
99
 
 
100
 
                if(!r->tail || !r->tail->s || !*r->tail->s) {
101
 
                        a->next = newarc((Node *)0, r, stem, rmatch);
102
 
                        a = a->next;
103
 
                } else
104
 
                        for(w = r->tail; w; w = w->next){
105
 
                                if(r->attr&REGEXP)
106
 
                                        regsub(w->s, buf, sizeof buf, rmatch, NREGEXP);
107
 
                                else
108
 
                                        subst(stem, w->s, buf);
109
 
                                a->next = newarc(applyrules(buf, cnt), r, stem, rmatch);
110
 
                                a = a->next;
111
 
                        }
112
 
                cnt[r->rule]--;
113
 
        }
114
 
        a->next = node->prereqs;
115
 
        node->prereqs = head.next;
116
 
        return(node);
117
 
}
118
 
 
119
 
static void
120
 
togo(Node *node)
121
 
{
122
 
        Arc *la, *a;
123
 
 
124
 
        /* delete them now */
125
 
        la = 0;
126
 
        for(a = node->prereqs; a; la = a, a = a->next)
127
 
                if(a->flag&TOGO){
128
 
                        if(a == node->prereqs)
129
 
                                node->prereqs = a->next;
130
 
                        else
131
 
                                la->next = a->next, a = la;
132
 
                }
133
 
}
134
 
 
135
 
static int
136
 
vacuous(Node *node)
137
 
{
138
 
        Arc *la, *a;
139
 
        int vac = !(node->flags&PROBABLE);
140
 
 
141
 
        if(node->flags&READY)
142
 
                return(node->flags&VACUOUS);
143
 
        node->flags |= READY;
144
 
        for(a = node->prereqs; a; a = a->next)
145
 
                if(a->n && vacuous(a->n) && (a->r->attr&META))
146
 
                        a->flag |= TOGO;
147
 
                else
148
 
                        vac = 0;
149
 
        /* if a rule generated arcs that DON'T go; no others from that rule go */
150
 
        for(a = node->prereqs; a; a = a->next)
151
 
                if((a->flag&TOGO) == 0)
152
 
                        for(la = node->prereqs; la; la = la->next)
153
 
                                if((la->flag&TOGO) && (la->r == a->r)){
154
 
                                        la->flag &= ~TOGO;
155
 
                                }
156
 
        togo(node);
157
 
        if(vac)
158
 
                node->flags |= VACUOUS;
159
 
        return(vac);
160
 
}
161
 
 
162
 
static Node *
163
 
newnode(char *name)
164
 
{
165
 
        register Node *node;
166
 
 
167
 
        node = (Node *)Malloc(sizeof(Node));
168
 
        symlook(name, S_NODE, (void *)node);
169
 
        node->name = name;
170
 
        node->time = timeof(name, 0);
171
 
        node->prereqs = 0;
172
 
        node->flags = node->time? PROBABLE : 0;
173
 
        node->next = 0;
174
 
        return(node);
175
 
}
176
 
 
177
 
void
178
 
dumpn(char *s, Node *n)
179
 
{
180
 
        char buf[1024];
181
 
        Arc *a;
182
 
 
183
 
        snprint(buf, sizeof buf, "%s   ", (*s == ' ')? s:"");
184
 
        Bprint(&bout, "%s%s@%ld: time=%ld flags=0x%x next=%ld\n",
185
 
                s, n->name, n, n->time, n->flags, n->next);
186
 
        for(a = n->prereqs; a; a = a->next)
187
 
                dumpa(buf, a);
188
 
}
189
 
 
190
 
static void
191
 
trace(char *s, Arc *a)
192
 
{
193
 
        fprint(2, "\t%s", s);
194
 
        while(a){
195
 
                fprint(2, " <-(%s:%d)- %s", a->r->file, a->r->line,
196
 
                        a->n? a->n->name:"");
197
 
                if(a->n){
198
 
                        for(a = a->n->prereqs; a; a = a->next)
199
 
                                if(*a->r->recipe) break;
200
 
                } else
201
 
                        a = 0;
202
 
        }
203
 
        fprint(2, "\n");
204
 
}
205
 
 
206
 
static void
207
 
cyclechk(Node *n)
208
 
{
209
 
        Arc *a;
210
 
 
211
 
        if((n->flags&CYCLE) && n->prereqs){
212
 
                fprint(2, "mk: cycle in graph detected at target %s\n", n->name);
213
 
                Exit();
214
 
        }
215
 
        n->flags |= CYCLE;
216
 
        for(a = n->prereqs; a; a = a->next)
217
 
                if(a->n)
218
 
                        cyclechk(a->n);
219
 
        n->flags &= ~CYCLE;
220
 
}
221
 
 
222
 
static void
223
 
ambiguous(Node *n)
224
 
{
225
 
        Arc *a;
226
 
        Rule *r = 0;
227
 
        Arc *la;
228
 
        int bad = 0;
229
 
 
230
 
        la = 0;
231
 
        for(a = n->prereqs; a; a = a->next){
232
 
                if(a->n)
233
 
                        ambiguous(a->n);
234
 
                if(*a->r->recipe == 0) continue;
235
 
                if(r == 0)
236
 
                        r = a->r, la = a;
237
 
                else{
238
 
                        if(r->recipe != a->r->recipe){
239
 
                                if((r->attr&META) && !(a->r->attr&META)){
240
 
                                        la->flag |= TOGO;
241
 
                                        r = a->r, la = a;
242
 
                                } else if(!(r->attr&META) && (a->r->attr&META)){
243
 
                                        a->flag |= TOGO;
244
 
                                        continue;
245
 
                                }
246
 
                        }
247
 
                        if(r->recipe != a->r->recipe){
248
 
                                if(bad == 0){
249
 
                                        fprint(2, "mk: ambiguous recipes for %s:\n", n->name);
250
 
                                        bad = 1;
251
 
                                        trace(n->name, la);
252
 
                                }
253
 
                                trace(n->name, a);
254
 
                        }
255
 
                }
256
 
        }
257
 
        if(bad)
258
 
                Exit();
259
 
        togo(n);
260
 
}
261
 
 
262
 
static void
263
 
attribute(Node *n)
264
 
{
265
 
        register Arc *a;
266
 
 
267
 
        for(a = n->prereqs; a; a = a->next){
268
 
                if(a->r->attr&VIR)
269
 
                        n->flags |= VIRTUAL;
270
 
                if(a->r->attr&NOREC)
271
 
                        n->flags |= NORECIPE;
272
 
                if(a->r->attr&DEL)
273
 
                        n->flags |= DELETE;
274
 
                if(a->n)
275
 
                        attribute(a->n);
276
 
        }
277
 
        if(n->flags&VIRTUAL)
278
 
                n->time = 0;
279
 
}