|
|
1.1 root 1: static char *sccsid = "@(#)main.c 8th Edition (Bell Labs) 85/10/28";
2: # include "defs"
3: /*
4: command make to update programs.
5: Flags: 'd' print out debugging comments
6: 'p' print out a version of the input graph
7: 's' silent mode--don't print out commands
8: 'f' the next argument is the name of the description file;
9: "makefile" is the default
10: 'i' ignore error codes from the shell
11: 'S' stop after any command fails (normally do parallel work)
12: 'n' don't issue, just print, commands
13: 't' touch (update time of) files but don't issue command
14: 'q' don't do anything, but check if object is up to date;
15: returns exit code 0 if up to date, -1 if not
16: 'e' use environment macros after rather than before makefiles
17: 'o' use old suffix rules instead of % patterns
18: 'Pn' set process limit to n
19: 'z' always use shell, never issue commands directly
20: */
21:
22: nameblkp mainname = NULL;
23: nameblkp firstname = NULL;
24: lineblkp sufflist = NULL;
25: struct varblock *firstvar = NULL;
26: struct pattern *firstpat = NULL;
27: struct dirhd *firstod = NULL;
28: wildp firstwild = NULL;
29: wildp lastwild = NULL;
30: nameblkp *hashtab;
31: int nhashed;
32: int hashsize;
33: int hashthresh;
34:
35: int proclimit = PROCLIMIT;
36: int nproc = 0;
37: int proclive = 0;
38: struct process procstack[MAXPROC];
39:
40: #include <signal.h>
41: int sigivalue = 0;
42: int sigqvalue = 0;
43:
44: int dbgflag = NO;
45: int prtrflag = NO;
46: int silflag = NO;
47: int noexflag = NO;
48: int keepgoing = NO;
49: int noruleflag = NO;
50: int touchflag = NO;
51: int questflag = NO;
52: int oldflag = NO;
53: int ndocoms = NO;
54: int ignerr = NO; /* default is to stop on error */
55: int forceshell = NO;
56: int okdel = YES;
57: int envlast = NO;
58: int inarglist = NO;
59: char **envpp = NULL;
60:
61: extern char *dfltmacro[];
62: extern char *dfltpat[];
63: extern char *dfltsuff[];
64: extern char **environ;
65: char **linesptr;
66:
67: #ifdef pwb
68: char *prompt = ">"; /* other systems -- pick what you want */
69: #else
70: char *prompt = ""; /* other systems -- pick what you want */
71: #endif
72: int nopdir = 0;
73: char funny[128];
74:
75: main(argc,argv,envp)
76: int argc;
77: char *argv[];
78: char *envp[];
79: {
80: register nameblkp p;
81: int i, j;
82: int descset, nfargs;
83: int nowait = NO;
84: TIMETYPE tjunk;
85: char c, *s, *mkflagp;
86: static char makeflags[30] = "-";
87: static char onechar[2] = "X";
88:
89: #ifdef unix
90: int intrupt();
91: #endif
92:
93: #ifdef METERFILE
94: meter(METERFILE);
95: #endif
96:
97: descset = 0;
98: mkflagp = makeflags+1;
99:
100: funny['\0'] = (META | TERMINAL);
101: for(s = "=|^();&<>*?[]:$`'\"\\\n" ; *s ; ++s)
102: funny[*s] |= META;
103: for(s = "\n\t :;&>|" ; *s ; ++s)
104: funny[*s] |= TERMINAL;
105:
106:
107: newhash(HASHSIZE);
108:
109: inarglist = YES;
110: for(i=1; i<argc; ++i)
111: if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i]))
112: argv[i] = 0;
113:
114: setvar("$", "$", NO);
115: inarglist = NO;
116:
117: for(i=1; i<argc; ++i)
118: if(argv[i]!=0 && argv[i][0]=='-')
119: {
120: for(j=1 ; (c=argv[i][j])!='\0' ; ++j) switch(c)
121: {
122: case 'd':
123: ++dbgflag;
124: *mkflagp++ = 'd';
125: break;
126:
127: case 'p':
128: prtrflag = YES;
129: break;
130:
131: case 's':
132: silflag = YES;
133: *mkflagp++ = 's';
134: break;
135:
136: case 'i':
137: ignerr = YES;
138: *mkflagp++ = 'i';
139: break;
140:
141: case 'S':
142: keepgoing = NO;
143: *mkflagp++ = 'S';
144: break;
145:
146: case 'k':
147: keepgoing = YES;
148: *mkflagp++ = 'k';
149: break;
150:
151: case 'n':
152: noexflag = YES;
153: *mkflagp++ = 'n';
154: break;
155:
156: case 'r':
157: noruleflag = YES;
158: break;
159:
160: case 't':
161: touchflag = YES;
162: *mkflagp++ = 't';
163: break;
164:
165: case 'q':
166: questflag = YES;
167: *mkflagp++ = 'q';
168: break;
169:
170: case 'e':
171: envlast = YES;
172: *mkflagp++ = 'e';
173: break;
174:
175: case 'o':
176: oldflag = YES;
177: *mkflagp++ = 'o';
178: break;
179:
180: case 'z':
181: forceshell = YES;
182: *mkflagp++ = 'z';
183: break;
184:
185: case 'P':
186: if(isdigit(argv[i][j+1]))
187: {
188: proclimit = argv[i][++j] - '0';
189: if(proclimit < 1)
190: proclimit = 1;
191: }
192: else
193: fatal("illegal proclimit parameter");
194: *mkflagp++ = 'P';
195: *mkflagp++ = argv[i][j];
196: break;
197:
198: case 'f':
199: if(i >= argc-1)
200: fatal("No description argument after -f flag");
201: if( ! rddescf(argv[i+1]) )
202: fatal1("Cannot open %s", argv[i+1]);
203: argv[i+1] = 0;
204: ++descset;
205: break;
206:
207: default:
208: onechar[0] = c; /* to make lint happy */
209: fatal1("Unknown flag argument %s", onechar);
210: }
211:
212: argv[i] = NULL;
213: }
214:
215: if(mkflagp > makeflags+1)
216: setvar("MAKEFLAGS", makeflags, NO);
217:
218: if( !descset )
219: if( !rddescf("makefile") &&
220: !rddescf("Makefile") &&
221: (exists(s = "s.makefile") || exists(s = "s.Makefile")) )
222: {
223: char junk[20];
224: concat("get ", s, junk);
225: (void) dosys(junk, NO, NO, junk);
226: rddescf(s+2);
227: unlink(s+2);
228: }
229:
230:
231: if(envlast)
232: loadenv();
233: if(!noruleflag && !oldflag)
234: rdarray(dfltpat);
235:
236: if(prtrflag) printdesc(NO);
237:
238: if( srchname(".IGNORE") )
239: ignerr = YES;
240: if( srchname(".SILENT") )
241: silflag = YES;
242: if( srchname(".OLDFLAG") )
243: oldflag = YES;
244: if( p=srchname(".SUFFIXES") )
245: sufflist = p->linep;
246: if( !sufflist && !firstwild)
247: fprintf(stderr,"No suffix or %% pattern list.\n");
248: /*
249: if(sufflist && !oldflag)
250: fprintf(stderr, "Suffix lists are old-fashioned. Use %% patterns\n);
251: */
252:
253: #ifdef unix
254: sigivalue = (int) signal(SIGINT, SIG_IGN) & 01;
255: sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01;
256: enbint(intrupt);
257: #endif
258:
259: nfargs = 0;
260:
261: for(i=1; i<argc; ++i)
262: if(s = argv[i])
263: {
264: if((p=srchname(s)) == NULL)
265: p = makename(s);
266: ++nfargs;
267: if(i+1<argc && equal(argv[i+1], "&") )
268: {
269: ++i;
270: nowait = YES;
271: }
272: else
273: nowait = NO;
274: doname(p, 0, &tjunk, nowait);
275: if(dbgflag) printdesc(YES);
276: }
277:
278: /*
279: If no file arguments have been encountered, make the first
280: name encountered that doesn't start with a dot
281: */
282:
283: if(nfargs == 0)
284: if(mainname == 0)
285: fatal("No arguments or description file");
286: else {
287: doname(mainname, 0, &tjunk, NO);
288: if(dbgflag) printdesc(YES);
289: }
290:
291: if(!nowait)
292: waitstack(0);
293: exit(0);
294: }
295:
296:
297:
298: #ifdef unix
299: intrupt()
300: {
301: struct varblock *varptr();
302: char *p;
303: TIMETYPE exists();
304:
305: if(okdel && !noexflag && !touchflag &&
306: (p = varptr("@")->varval) && exists(p)>0 && !isprecious(p) )
307: {
308: fprintf(stderr, "\n*** %s removed.", p);
309: unlink(p);
310: }
311:
312: fprintf(stderr, "\n");
313: exit(2);
314: }
315:
316:
317:
318:
319: isprecious(p)
320: char *p;
321: {
322: register lineblkp lp;
323: register depblkp dp;
324: register nameblkp np;
325:
326: if(np = srchname(".PRECIOUS"))
327: for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
328: for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
329: if(equal(p, dp->depname->namep))
330: return YES;
331:
332: return NO;
333: }
334:
335:
336: enbint(k)
337: int (*k)();
338: {
339: if(sigivalue == 0)
340: signal(SIGINT,k);
341: if(sigqvalue == 0)
342: signal(SIGQUIT,k);
343: }
344: #endif
345:
346: rddescf(descfile)
347: char *descfile;
348: {
349: static int firstrd = YES;
350:
351: /* read and parse description */
352:
353: if(firstrd)
354: {
355: firstrd = NO;
356: if( !noruleflag )
357: {
358: rdarray(dfltmacro);
359: if(oldflag)
360: rdarray(dfltsuff);
361: }
362: if(!envlast)
363: loadenv();
364:
365: #ifdef pwb
366: {
367: char *nlog, s[100];
368: nlog = logdir();
369: if( ! parse( concat(nlog,"/makecomm",s) ) )
370: parse( concat(nlog,"/Makecomm",s) );
371:
372: if( !parse("makecomm") )
373: parse("Makecomm");
374: }
375: #endif
376: }
377:
378: return parse(descfile);
379: }
380:
381:
382: rdarray(s)
383: char **s;
384: {
385: linesptr = s;
386: parse(CHNULL);
387: }
388:
389:
390: loadenv()
391: {
392: for(envpp = environ ; *envpp ; ++envpp)
393: eqsign(*envpp);
394: envpp = NULL;
395: }
396:
397: printdesc(prntflag)
398: int prntflag;
399: {
400: nameblkp p;
401: depblkp dp;
402: struct varblock *vp;
403: struct dirhd *od;
404: struct shblock *sp;
405: lineblkp lp;
406:
407: #ifdef unix
408: if(prntflag)
409: {
410: printf("Open directories:\n");
411: for (od = firstod; od; od = od->nxtdirhd)
412: printf("\t%s\n", od->dirn);
413: }
414: #endif
415:
416: if(firstvar != 0) printf("Macros:\n");
417: for(vp = firstvar; vp ; vp = vp->nxtvarblock)
418: printf("\t%s = %s\n" , vp->varname , vp->varval);
419:
420: for(p = firstname; p; p = p->nxtnameblock)
421: {
422: printf("\n\n%s",p->namep);
423: if(p->linep != 0) printf(":");
424: if(prntflag) printf(" done=%d",p->done);
425: if(p==mainname) printf(" (MAIN NAME)");
426: for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
427: {
428: if( dp = lp->depp )
429: {
430: printf("\n depends on:");
431: for(; dp ; dp = dp->nxtdepblock)
432: if(dp->depname != 0)
433: printf(" %s ", dp->depname->namep);
434: }
435:
436: if(sp = lp->shp)
437: {
438: printf("\n commands:\n");
439: for( ; sp ; sp = sp->nxtshblock)
440: printf("\t%s\n", sp->shbp);
441: }
442: }
443: }
444: printf("\n");
445: fflush(stdout);
446: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.