|
|
1.1 root 1: /* @(#)/usr/src/cmd/make/main.c 3.4 */
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: */
17:
18: char makefile[] = "makefile";
19: char Nullstr[] = "";
20: char Makefile[] = "Makefile";
21: char RELEASE[] = "RELEASE";
22: CHARSTAR badptr = (CHARSTAR)-1;
23:
24: NAMEBLOCK mainname ;
25: NAMEBLOCK firstname;
26: LINEBLOCK sufflist;
27: VARBLOCK firstvar;
28: PATTERN firstpat ;
29: OPENDIR firstod;
30:
31:
32: #include <signal.h>
33: int sigivalue=0;
34: int sigqvalue=0;
35: int waitpid=0;
36:
37: int Mflags=MH_DEP;
38: int ndocoms=0;
39: int okdel=YES;
40:
41: CHARSTAR prompt="\t"; /* other systems -- pick what you want */
42: char junkname[20];
43: char funny[128];
44:
45:
46:
47:
48: char Makeflags[]="MAKEFLAGS";
49:
50: main(argc,argv)
51: int argc;
52: CHARSTAR argv[];
53: {
54: register NAMEBLOCK p;
55: int i, j;
56: int descset, nfargs;
57: TIMETYPE tjunk;
58: char c;
59: CHARSTAR s, *e;
60: #ifdef unix
61: int intrupt();
62:
63:
64:
65: #endif
66:
67: #ifdef METERFILE
68: meter(METERFILE);
69: #endif
70:
71: descset = 0;
72:
73: for(s = "#|=^();&<>*?[]:$`'\"\\\n" ; *s ; ++s)
74: funny[*s] |= META;
75: for(s = "\n\t :=;{}&>|" ; *s ; ++s)
76: funny[*s] |= TERMINAL;
77: funny['\0'] |= TERMINAL;
78:
79: TURNON(INTRULE); /* Default internal rules, turned on */
80:
81: /*
82: * Set command line flags
83: */
84:
85: getmflgs(); /* Init $(MAKEFLAGS) variable */
86: setflags(argc, argv);
87:
88: setvar("$","$");
89:
90:
91: /*
92: * Read command line "=" type args and make them readonly.
93: */
94: TURNON(INARGS|EXPORT);
95: if(IS_ON(DBUG))printf("Reading \"=\" type args on command line.\n");
96: for(i=1; i<argc; ++i)
97: if(argv[i]!=0 && argv[i][0]!=MINUS && (eqsign(argv[i]) == YES) )
98: argv[i] = 0;
99: TURNOFF(INARGS|EXPORT);
100:
101: /*
102: * Read internal definitions and rules.
103: */
104:
105: if( IS_ON(INTRULE) )
106: {
107: if(IS_ON(DBUG))printf("Reading internal rules.\n");
108: rdd1(NULL);
109: }
110:
111: /*
112: * Done with internal rules, now.
113: */
114: TURNOFF(INTRULE);
115:
116: /*
117: * Read environment args. Let file args which follow override.
118: * unless 'e' in MAKEFLAGS variable is set.
119: */
120: if( any( (varptr(Makeflags))->varval, 'e') )
121: TURNON(ENVOVER);
122: if(IS_ON(DBUG))printf("Reading environment.\n");
123: TURNON(EXPORT);
124: readenv();
125: TURNOFF(EXPORT|ENVOVER);
126:
127: /*
128: * Read command line "-f" arguments.
129: */
130:
131: rdmakecomm();
132:
133: for(i = 1; i < argc; i++)
134: if( argv[i] && argv[i][0] == MINUS && argv[i][1] == 'f' && argv[i][2] == CNULL)
135: {
136: argv[i] = 0;
137: if(i >= argc-1)
138: fatal("No description argument after -f flag");
139: if( rddescf(argv[++i], YES) )
140: fatal1("Cannot open %s", argv[i]);
141: argv[i] = 0;
142: ++descset;
143: }
144:
145:
146: /*
147: * If no command line "-f" args then look for some form of "makefile"
148: */
149: if( !descset )
150: #ifdef unix
151: if( rddescf(makefile, NO))
152: if( rddescf(Makefile, NO))
153: if( rddescf(makefile, YES))
154: rddescf(Makefile, YES);
155:
156: #endif
157: #ifdef gcos
158: rddescf(makefile, NO);
159: #endif
160:
161:
162: if(IS_ON(PRTR)) printdesc(NO);
163:
164: if( srchname(".IGNORE") ) TURNON(IGNERR);
165: if( srchname(".SILENT") ) TURNON(SIL);
166: if(p=srchname(".SUFFIXES")) sufflist = p->linep;
167: if( !sufflist ) fprintf(stderr,"No suffix list.\n");
168:
169: #ifdef unix
170: sigivalue = (int)signal(SIGINT,1) & 01;
171: sigqvalue = (int)signal(SIGQUIT,1) & 01;
172: enbint(intrupt);
173: #endif
174:
175: nfargs = 0;
176:
177: for(i=1; i<argc; ++i)
178: if((s=argv[i]) != 0)
179: {
180: if((p=srchname(s)) == 0)
181: {
182: p = makename(s);
183: }
184: ++nfargs;
185: doname(p, 0, &tjunk);
186: if(IS_ON(DBUG)) printdesc(YES);
187: }
188:
189: /*
190: If no file arguments have been encountered, make the first
191: name encountered that doesn't start with a dot
192: */
193:
194: if(nfargs == 0)
195: if(mainname == 0)
196: fatal("No arguments or description file");
197: else
198: {
199: doname(mainname, 0, &tjunk);
200: if(IS_ON(DBUG)) printdesc(YES);
201: }
202:
203: exit(0);
204: }
205:
206:
207:
208: #ifdef unix
209: intrupt()
210: {
211: CHARSTAR p;
212:
213: if(okdel && IS_OFF(NOEX) && IS_OFF(TOUCH) &&
214: (p = varptr("@")->varval) && exists(srchname(p))>0 &&
215: !isprecious(p) )
216: {
217: if(isdir(p))
218: fprintf(stderr, "\n*** %s NOT REMOVED.",p);
219: else if(unlink(p) == 0)
220: fprintf(stderr, "\n*** %s removed.", p);
221: }
222:
223: if(junkname[0])
224: unlink(junkname);
225: fprintf(stderr, "\n");
226: exit(2);
227: }
228:
229:
230:
231:
232: isprecious(p)
233: CHARSTAR p;
234: {
235: register NAMEBLOCK np;
236: register LINEBLOCK lp;
237: register DEPBLOCK dp;
238:
239: if(np = srchname(".PRECIOUS"))
240: for(lp = np->linep ; lp ; lp = lp->nextline)
241: for(dp = lp->depp ; dp; dp = dp->nextdep)
242: if(equal(p, dp->depname->namep))
243: return(YES);
244:
245: return(NO);
246: }
247:
248:
249: enbint(k)
250: int (*k)();
251: {
252: if(sigivalue == 0)
253: signal(SIGINT,k);
254: if(sigqvalue == 0)
255: signal(SIGQUIT,k);
256: }
257: #endif
258:
259: extern CHARSTAR builtin[];
260:
261: CHARSTAR *linesptr=builtin;
262:
263: FILE * fin;
264: int firstrd=0;
265:
266: rdmakecomm()
267: {
268: /******GONE FOR EVER
269: #ifdef PWB
270: register char *nlog;
271: char s[128];
272: CHARSTAR concat(), getenv();
273:
274: if(rddescf( concat((nlog=getenv("HOME")),"/makecomm",s), NO))
275: rddescf( concat(nlog,"/Makecomm",s), NO);
276:
277: if(rddescf("makecomm", NO))
278: rddescf("Makecomm", NO);
279: #endif
280: ************/
281: }
282:
283: extern int yylineno;
284: extern CHARSTAR zznextc;
285: rddescf(descfile, flg)
286: CHARSTAR descfile;
287: int flg; /* if YES try s.descfile */
288: {
289: FILE * k;
290:
291: /* read and parse description */
292:
293: if(equal(descfile, "-"))
294: return( rdd1(stdin) );
295:
296: retry:
297: if( (k = fopen(descfile,"r")) != NULL)
298: {
299: if(IS_ON(DBUG))printf("Reading %s\n", descfile);
300: return( rdd1(k) );
301: }
302:
303: if(flg == NO)
304: return(1);
305: if(get(descfile, CD, varptr(RELEASE)->varval) == NO)
306: return(1);
307: flg = NO;
308: goto retry;
309:
310: }
311:
312:
313:
314:
315: rdd1(k)
316: FILE * k;
317: {
318: fin = k;
319: yylineno = 0;
320: zznextc = 0;
321:
322: if( yyparse() )
323: fatal("Description file error");
324:
325: if(fin != NULL)
326: fclose(fin);
327:
328: return(0);
329: }
330:
331: printdesc(prntflag)
332: int prntflag;
333: {
334: NAMEBLOCK p;
335: DEPBLOCK dp;
336: VARBLOCK vp;
337: OPENDIR od;
338: SHBLOCK sp;
339: LINEBLOCK lp;
340:
341: #ifdef unix
342: if(prntflag)
343: {
344: fprintf(stderr,"Open directories:\n");
345: for(od=firstod; od!=0; od = od->nextopendir)
346: fprintf(stderr,"\t%d: %s\n", fileno(od->dirfc), od->dirn);
347: }
348: #endif
349:
350: if(firstvar != 0) fprintf(stderr,"Macros:\n");
351: for(vp=firstvar; vp!=0; vp=vp->nextvar)
352: if(vp->v_aflg == NO)
353: printf("\t%s = %s\n" , vp->varname , vp->varval);
354: else
355: {
356: CHAIN pch;
357:
358: fprintf(stderr,"Lookup chain: %s\n\t", vp->varname);
359: for(pch = (CHAIN)vp->varval; pch; pch = pch->nextchain)
360: fprintf(stderr," %s",
361: ((NAMEBLOCK)pch->datap)->namep);
362: fprintf(stderr,"\n");
363: }
364:
365: for(p=firstname; p!=0; p = p->nextname)
366: prname(p, prntflag);
367: printf("\n");
368: fflush(stdout);
369: }
370:
371: prname(p, prntflag)
372: register NAMEBLOCK p;
373: {
374: register LINEBLOCK lp;
375: register DEPBLOCK dp;
376: register SHBLOCK sp;
377:
378: if(p->linep != 0)
379: printf("\n\n%s:",p->namep);
380: else
381: fprintf(stderr, "\n\n%s", p->namep);
382: if(prntflag)
383: {
384: fprintf(stderr," done=%d",p->done);
385: }
386: if(p==mainname) fprintf(stderr," (MAIN NAME)");
387: for(lp = p->linep ; lp!=0 ; lp = lp->nextline)
388: {
389: if( dp = lp->depp )
390: {
391: fprintf(stderr,"\n depends on:");
392: for(; dp!=0 ; dp = dp->nextdep)
393: if(dp->depname != 0)
394: {
395: printf(" %s", dp->depname->namep);
396: printf(" ");
397: }
398: }
399: if(sp = lp->shp)
400: {
401: printf("\n");
402: fprintf(stderr," commands:\n");
403: for( ; sp!=0 ; sp = sp->nextsh)
404: printf("\t%s\n", sp->shbp);
405: }
406: }
407: }
408:
409:
410: setflags(ac, av)
411: int ac;
412: CHARSTAR *av;
413: {
414: register int i, j;
415: register char c;
416: int flflg=0; /* flag to note `-f' option. */
417:
418: for(i=1; i<ac; ++i)
419: {
420: if(flflg)
421: {
422: flflg = 0;
423: continue;
424: }
425: if(av[i]!=0 && av[i][0]==MINUS)
426: {
427: if(any(av[i], 'f'))
428: flflg++;
429: for(j=1 ; (c=av[i][j])!=CNULL ; ++j)
430: optswitch(c);
431: if(flflg)
432: av[i] = "-f";
433: else
434: av[i] = 0;
435: }
436: }
437: }
438:
439:
440: /*
441: * Handle a single char option.
442: */
443: optswitch(c)
444: register char c;
445: {
446:
447: switch(c)
448: {
449:
450: case 'e': /* environment override flag */
451: setmflgs(c);
452: break;
453:
454: case 'd': /* debug flag */
455: TURNON(DBUG);
456: setmflgs(c);
457: break;
458:
459: case 'p': /* print description */
460: TURNON(PRTR);
461: break;
462:
463: case 's': /* silent flag */
464: TURNON(SIL);
465: setmflgs(c);
466: break;
467:
468: case 'i': /* ignore errors */
469: TURNON(IGNERR);
470: setmflgs(c);
471: break;
472:
473: case 'S':
474: TURNOFF(KEEPGO);
475: setmflgs(c);
476: break;
477:
478: case 'k':
479: TURNON(KEEPGO);
480: setmflgs(c);
481: break;
482:
483: case 'n': /* do not exec any commands, just print */
484: TURNON(NOEX);
485: setmflgs(c);
486: break;
487:
488: case 'r': /* turn off internal rules */
489: TURNOFF(INTRULE);
490: break;
491:
492: case 't': /* touch flag */
493: TURNON(TOUCH);
494: setmflgs(c);
495: break;
496:
497: case 'q': /* question flag */
498: TURNON(QUEST);
499: setmflgs(c);
500: break;
501:
502: case 'g': /* turn default $(GET) of files not found */
503: TURNON(GET);
504: setmflgs(c);
505: break;
506:
507: case 'm': /* print memory map */
508: TURNON(MEMMAP);
509: setmflgs(c);
510: break;
511:
512: case 'b': /* use MH version of test for whether a cmd exists */
513: TURNON(MH_DEP);
514: setmflgs(c);
515: break;
516: case 'B': /* turn off -b flag */
517: TURNOFF(MH_DEP);
518: setmflgs(c);
519: break;
520:
521: case 'f': /* Named makefile; already handled by setflags(). */
522: break;
523:
524: default:
525: fatal1("Unknown flag argument %c", c);
526: }
527: }
528:
529: /*
530: * getmflgs() set the cmd line flags into an EXPORTED variable
531: * for future invocations of make to read.
532: */
533:
534:
535: getmflgs()
536: {
537: register VARBLOCK vpr;
538: register CHARSTAR *pe;
539: register CHARSTAR p;
540:
541: vpr = varptr(Makeflags);
542: setvar(Makeflags, "ZZZZZZZZZZZZZZZZ");
543: vpr->varval[0] = CNULL;
544: vpr->envflg = YES;
545: vpr->noreset = YES;
546: optswitch('b');
547: for(pe = environ; *pe; pe++)
548: {
549: if(sindex(*pe, "MAKEFLAGS=") == 0)
550: {
551: for(p = (*pe)+sizeof Makeflags; *p; p++)
552: optswitch(*p);
553: return;
554: }
555: }
556: }
557:
558: /*
559: * setmflgs(c) sets up the cmd line input flags for EXPORT.
560: */
561:
562: setmflgs(c)
563: register char c;
564: {
565: register VARBLOCK vpr;
566: register CHARSTAR p;
567:
568: vpr = varptr(Makeflags);
569: for(p = vpr->varval; *p; p++)
570: {
571: if(*p == c)
572: return;
573: }
574: *p++ = c;
575: *p = CNULL;
576: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.