Introduction
Introduction Statistics Contact Development Disclaimer Help
graph.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
graph.c (5833B)
---
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 dele…
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 sym->u.ptr;
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? sym->u.ptr: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-…
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), …
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-…
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) …
85 continue;
86 } else {
87 if(!match(node->name, r->target, stem, r->shellt…
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, rm…
107 else
108 subst(stem, w->s, buf);
109 a->next = newarc(applyrules(buf, cnt), r…
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 r…
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", …
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…
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…
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 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.