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