tmk.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tmk.c (5252B) | |
--- | |
1 #include "mk.h" | |
2 | |
3 int runerrs; | |
4 | |
5 void | |
6 mk(char *target) | |
7 { | |
8 Node *node; | |
9 int did = 0; | |
10 | |
11 nproc(); /* it can be updated dynamically */ | |
12 nrep(); /* it can be updated dynamically … | |
13 runerrs = 0; | |
14 node = graph(target); | |
15 if(DEBUG(D_GRAPH)){ | |
16 dumpn("new target\n", node); | |
17 Bflush(&bout); | |
18 } | |
19 clrmade(node); | |
20 while(node->flags&NOTMADE){ | |
21 if(work(node, (Node *)0, (Arc *)0)) | |
22 did = 1; /* found something to do */ | |
23 else { | |
24 if(waitup(1, (int *)0) > 0){ | |
25 if(node->flags&(NOTMADE|BEINGMADE)){ | |
26 assert("must be run errors", run… | |
27 break; /* nothing more wa… | |
28 } | |
29 } | |
30 } | |
31 } | |
32 if(node->flags&BEINGMADE) | |
33 waitup(-1, (int *)0); | |
34 while(jobs) | |
35 waitup(-2, (int *)0); | |
36 assert("target didn't get done", runerrs || (node->flags&MADE)); | |
37 if(did == 0) | |
38 Bprint(&bout, "mk: '%s' is up to date\n", node->name); | |
39 } | |
40 | |
41 void | |
42 clrmade(Node *n) | |
43 { | |
44 Arc *a; | |
45 | |
46 n->flags &= ~(CANPRETEND|PRETENDING); | |
47 if(strchr(n->name, '(') ==0 || n->time) | |
48 n->flags |= CANPRETEND; | |
49 MADESET(n, NOTMADE); | |
50 for(a = n->prereqs; a; a = a->next) | |
51 if(a->n) | |
52 clrmade(a->n); | |
53 } | |
54 | |
55 static void | |
56 unpretend(Node *n) | |
57 { | |
58 MADESET(n, NOTMADE); | |
59 n->flags &= ~(CANPRETEND|PRETENDING); | |
60 n->time = 0; | |
61 } | |
62 | |
63 static char* | |
64 dir(void) | |
65 { | |
66 static char buf[1024]; | |
67 | |
68 return getcwd(buf, sizeof buf); | |
69 } | |
70 | |
71 int | |
72 work(Node *node, Node *p, Arc *parc) | |
73 { | |
74 Arc *a, *ra; | |
75 int weoutofdate; | |
76 int ready; | |
77 int did = 0; | |
78 | |
79 /*print("work(%s) flags=0x%x time=%ld\n", node->name, node->flag… | |
80 if(node->flags&BEINGMADE) | |
81 return(did); | |
82 if((node->flags&MADE) && (node->flags&PRETENDING) && p && outofd… | |
83 if(explain) | |
84 fprint(1, "unpretending %s(%ld) because %s is ou… | |
85 node->name, node->time, p->name, p->time… | |
86 unpretend(node); | |
87 } | |
88 /* | |
89 have a look if we are pretending in case | |
90 someone has been unpretended out from underneath us | |
91 */ | |
92 if(node->flags&MADE){ | |
93 if(node->flags&PRETENDING){ | |
94 node->time = 0; | |
95 }else | |
96 return(did); | |
97 } | |
98 /* consider no prerequsite case */ | |
99 if(node->prereqs == 0){ | |
100 if(node->time == 0){ | |
101 fprint(2, "mk: don't know how to make '%s' in %s… | |
102 if(kflag){ | |
103 node->flags |= BEINGMADE; | |
104 runerrs++; | |
105 } else | |
106 Exit(); | |
107 } else | |
108 MADESET(node, MADE); | |
109 return(did); | |
110 } | |
111 /* | |
112 now see if we are out of date or what | |
113 */ | |
114 ready = 1; | |
115 weoutofdate = aflag; | |
116 ra = 0; | |
117 for(a = node->prereqs; a; a = a->next) | |
118 if(a->n){ | |
119 did = work(a->n, node, a) || did; | |
120 if(a->n->flags&(NOTMADE|BEINGMADE)) | |
121 ready = 0; | |
122 if(outofdate(node, a, 0)){ | |
123 weoutofdate = 1; | |
124 if((ra == 0) || (ra->n == 0) | |
125 || (ra->n->time < a->n->… | |
126 ra = a; | |
127 } | |
128 } else { | |
129 if(node->time == 0){ | |
130 if(ra == 0) | |
131 ra = a; | |
132 weoutofdate = 1; | |
133 } | |
134 } | |
135 if(ready == 0) /* can't do anything now */ | |
136 return(did); | |
137 if(weoutofdate == 0){ | |
138 MADESET(node, MADE); | |
139 return(did); | |
140 } | |
141 /* | |
142 can we pretend to be made? | |
143 */ | |
144 if((iflag == 0) && (node->time == 0) && (node->flags&(PRETENDING… | |
145 && p && ra->n && !outofdate(p, ra, 0)){ | |
146 node->flags &= ~CANPRETEND; | |
147 MADESET(node, MADE); | |
148 if(explain && ((node->flags&PRETENDING) == 0)) | |
149 fprint(1, "pretending %s has time %ld\n", node->… | |
150 node->flags |= PRETENDING; | |
151 return(did); | |
152 } | |
153 /* | |
154 node is out of date and we REALLY do have to do somethin… | |
155 quickly rescan for pretenders | |
156 */ | |
157 for(a = node->prereqs; a; a = a->next) | |
158 if(a->n && (a->n->flags&PRETENDING)){ | |
159 if(explain) | |
160 Bprint(&bout, "unpretending %s because o… | |
161 a->n->name, node->name, ra->n? ra->n->na… | |
162 | |
163 unpretend(a->n); | |
164 did = work(a->n, node, a) || did; | |
165 ready = 0; | |
166 } | |
167 if(ready == 0) /* try later unless nothing has happened f… | |
168 return(did || work(node, p, parc)); | |
169 did = dorecipe(node) || did; | |
170 return(did); | |
171 } | |
172 | |
173 void | |
174 update(int fake, Node *node) | |
175 { | |
176 Arc *a; | |
177 | |
178 MADESET(node, fake? BEINGMADE : MADE); | |
179 if(((node->flags&VIRTUAL) == 0) && (access(node->name, 0) == 0)){ | |
180 node->time = timeof(node->name, 1); | |
181 node->flags &= ~(CANPRETEND|PRETENDING); | |
182 for(a = node->prereqs; a; a = a->next) | |
183 if(a->prog) | |
184 outofdate(node, a, 1); | |
185 } else { | |
186 node->time = 1; | |
187 for(a = node->prereqs; a; a = a->next) | |
188 if(a->n && outofdate(node, a, 1)) | |
189 node->time = a->n->time; | |
190 } | |
191 /* print("----node %s time=%ld flags=0x%x\n", node->name, node->t… | |
192 } | |
193 | |
194 static int | |
195 pcmp(char *prog, char *p, char *q, Shell *sh, Word *shcmd) | |
196 { | |
197 char buf[3*NAMEBLOCK]; | |
198 int pid; | |
199 | |
200 Bflush(&bout); | |
201 snprint(buf, sizeof buf, "%s '%s' '%s'\n", prog, p, q); | |
202 pid = pipecmd(buf, envy, 0, sh, shcmd); | |
203 while(waitup(-3, &pid) >= 0) | |
204 ; | |
205 return(pid? 2:1); | |
206 } | |
207 | |
208 int | |
209 outofdate(Node *node, Arc *arc, int eval) | |
210 { | |
211 char buf[3*NAMEBLOCK], *str; | |
212 Symtab *sym; | |
213 int ret; | |
214 | |
215 str = 0; | |
216 if(arc->prog){ | |
217 snprint(buf, sizeof buf, "%s%c%s", node->name, 0377, arc… | |
218 sym = symlook(buf, S_OUTOFDATE, 0); | |
219 if(sym == 0 || eval){ | |
220 if(sym == 0) | |
221 str = strdup(buf); | |
222 ret = pcmp(arc->prog, node->name, arc->n->name, … | |
223 if(sym) | |
224 sym->u.value = ret; | |
225 else | |
226 symlook(str, S_OUTOFDATE, (void *)(uintp… | |
227 } else | |
228 ret = sym->u.value; | |
229 return(ret-1); | |
230 } else if(strchr(arc->n->name, '(') && arc->n->time == 0) /* mi… | |
231 return 1; | |
232 else | |
233 return node->time <= arc->n->time; | |
234 } |