|
|
1.1 root 1: #include "mk.h"
2:
3: int runerrs;
4:
5: mk(target)
6: 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: if(mflag)
15: maketarget(target);
16: node = graph(target);
17: if(DEBUG(D_GRAPH)){
18: dumpn("new target\n", node);
19: Fflush(1);
20: }
21: clrmade(node);
22: while(node->flags&NOTMADE){
23: if(work(node, (Node *)0, (Arc *)0))
24: did = 1; /* found something to do */
25: else {
26: if(waitup(1, (int *)0) > 0){
27: if(node->flags&(NOTMADE|BEINGMADE)){
28: assert("must be run errors", runerrs);
29: break; /* nothing more waiting */
30: }
31: }
32: }
33: }
34: if(node->flags&BEINGMADE)
35: waitup(-1, (int *)0);
36: while(jobs)
37: waitup(-2, (int *)0);
38: assert("target didn't get done", runerrs || (node->flags&MADE));
39: if(did == 0)
40: Fprint(1, "mk: '%s' is up to date\n", node->name);
41: }
42:
43: clrmade(n)
44: register Node *n;
45: {
46: register Arc *a;
47:
48: n->flags &= ~(CANPRETEND|PRETENDING);
49: n->flags |= CANPRETEND;
50: MADESET(n, NOTMADE);
51: for(a = n->prereqs; a; a = a->next)
52: if(a->n)
53: clrmade(a->n);
54: }
55:
56: static void
57: unpretend(n)
58: register Node *n;
59: {
60: MADESET(n, NOTMADE);
61: n->flags &= ~(CANPRETEND|PRETENDING);
62: n->time = 0;
63: }
64:
65: work(node, p, parc)
66: Node *node, *p;
67: Arc *parc;
68: {
69: register Arc *a, *ra;
70: int weoutofdate;
71: int ready;
72: int did = 0;
73:
74: /* print("work(%s) flags=0x%x time=%ld\n", node->name, node->flags, node->time);/**/
75: if(node->flags&BEINGMADE)
76: return(did);
77: if((node->flags&MADE) && (node->flags&PRETENDING) && p && outofdate(p, parc, 0)){
78: if(explain)
79: fprint(1, "unpretending %s(%ld) because %s is out of date(%ld)\n",
80: node->name, node->time, p->name, p->time);
81: unpretend(node);
82: }
83: /*
84: have a look if we are pretending in case
85: someone has been unpretended out from underneath us
86: */
87: if(node->flags&MADE){
88: if(node->flags&PRETENDING){
89: node->time = 0;
90: }else
91: return(did);
92: }
93: /* consider no prerequsite case */
94: if(node->prereqs == 0){
95: if(node->time == 0){
96: Fprint(2, "mk: don't know how to make '%s'\n", node->name);
97: if(kflag){
98: node->flags |= BEINGMADE;
99: runerrs++;
100: } else
101: Exit();
102: } else
103: MADESET(node, MADE);
104: return(did);
105: }
106: /*
107: now see if we are out of date or what
108: */
109: ready = 1;
110: weoutofdate = aflag;
111: ra = 0;
112: for(a = node->prereqs; a; a = a->next)
113: if(a->n){
114: did = work(a->n, node, a) || did;
115: if(a->n->flags&(NOTMADE|BEINGMADE))
116: ready = 0;
117: if(outofdate(node, a, 0)){
118: weoutofdate = 1;
119: if((ra == 0) || (ra->n == 0)
120: || (ra->n->time < a->n->time))
121: ra = a;
122: }
123: } else {
124: if(node->time == 0){
125: if(ra == 0)
126: ra = a;
127: weoutofdate = 1;
128: }
129: }
130: if(ready == 0) /* can't do anything now */
131: return(did);
132: if(weoutofdate == 0){
133: MADESET(node, MADE);
134: return(did);
135: }
136: /*
137: can we pretend to be made?
138: */
139: if((iflag == 0) && (node->time == 0) && (node->flags&(PRETENDING|CANPRETEND)) && p && ra->n && !outofdate(p, ra, 0)){
140: node->flags &= ~CANPRETEND;
141: MADESET(node, MADE);
142: node->time = ra->n->time;
143: if(explain && ((node->flags&PRETENDING) == 0))
144: fprint(1, "pretending %s has time %ld\n", node->name, node->time);
145: node->flags |= PRETENDING;
146: return(did);
147: }
148: /*
149: node is out of date and we REALLY do have to do something.
150: quickly rescan for pretenders
151: */
152: for(a = node->prereqs; a; a = a->next)
153: if(a->n && (a->n->flags&PRETENDING)){
154: if(explain)
155: Fprint(1, "unpretending %s because of %s because of %s\n",
156: a->n->name, node->name, ra->n? ra->n->name : "rule with no prerequisites");
157:
158: unpretend(a->n);
159: did = work(a->n, node, a) || did;
160: ready = 0;
161: }
162: if(ready == 0) /* try later unless nothing has happened for -k's sake */
163: return(did || work(node, p, parc));
164: did = dorecipe(node) || did;
165: return(did);
166: }
167:
168: update(fake, node)
169: register Node *node;
170: {
171: register Arc *a;
172:
173: MADESET(node, fake? BEINGMADE : MADE);
174: if(((node->flags&VIRTUAL) == 0) && (access(node->name, 0) == 0)){
175: node->time = timeof(node->name, 1);
176: node->flags &= ~(CANPRETEND|PRETENDING);
177: for(a = node->prereqs; a; a = a->next)
178: if(a->prog)
179: (void)outofdate(node, a, 1);
180: } else {
181: node->time = 1;
182: for(a = node->prereqs; a; a = a->next)
183: if(a->n && outofdate(node, a, 1))
184: node->time = a->n->time;
185: }
186: /* print("----node %s time=%ld flags=0x%x\n", node->name, node->time, node->flags);/**/
187: }
188:
189: static
190: pcmp(prog, n1, n2)
191: char *prog, *n1, *n2;
192: {
193: char buf[3*NAMEBLOCK];
194: int ret, pid;
195:
196: pid = fork();
197: if(pid < 0){
198: fprint(2, "mk: ");
199: perror("pcmp fork");
200: Exit();
201: }
202: Fexit(0);
203: if(pid == 0){
204: sprint(buf, "%s '%s' '%s'", prog, n1, n2);
205: execl(SHELL, "sh", "-c", buf, (char *)0);
206: sprint(buf, "exec %s", SHELL);
207: perror(buf);
208: _exit(1);
209: } else {
210: while(waitup(-3, &pid) >= 0)
211: ;
212: return(pid? 2:1);
213: }
214: }
215:
216:
217: outofdate(node, arc, eval)
218: register Node *node;
219: register Arc *arc;
220: {
221: char buf[3*NAMEBLOCK], *str;
222: Symtab *sym;
223: int ret;
224:
225: if(arc->prog){
226: sprint(buf, "%s%c%s", node->name, 0377, arc->n->name);
227: if(!(sym = symlook(buf, S_OUTOFDATE, (char *)0)) || eval){
228: if(!sym)
229: str = strdup(buf);
230: ret = pcmp(arc->prog, node->name, arc->n->name);
231: if(sym)
232: sym->value = (char *)ret;
233: else
234: symlook(str, S_OUTOFDATE, (char *)ret);
235: } else
236: ret = (int)sym->value;
237: return(ret-1);
238: } else
239: return(node->time < arc->n->time);
240: }
241:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.