implement $unsafecall (4.3BSD-reno/pgrm/3)
[unix-history] / usr / src / old / make / main.c
CommitLineData
31e81748 1static char *sccsid = "@(#)main.c 4.12 (Berkeley) 91/02/28";
8f5e70e1
BJ
2# include "defs"
3/*
4command make to update programs.
5Flags: '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
2b29f189 16 'e' environment variables have precedence over makefiles
8f5e70e1
BJ
17*/
18
19struct nameblock *mainname = NULL;
20struct nameblock *firstname = NULL;
21struct lineblock *sufflist = NULL;
22struct varblock *firstvar = NULL;
23struct pattern *firstpat = NULL;
b342e078 24struct dirhdr *firstod = NULL;
8f5e70e1
BJ
25
26#include <signal.h>
27int sigivalue = 0;
28int sigqvalue = 0;
29int waitpid = 0;
30
31int dbgflag = NO;
32int prtrflag = NO;
33int silflag = NO;
34int noexflag = NO;
35int keepgoing = NO;
36int noruleflag = NO;
37int touchflag = NO;
38int questflag = NO;
39int ndocoms = NO;
40int ignerr = NO; /* default is to stop on error */
41int okdel = YES;
2b29f189 42int doenvlast = NO;
8f5e70e1
BJ
43int inarglist;
44#ifdef pwb
45char *prompt = ">"; /* other systems -- pick what you want */
46#else
47char *prompt = ""; /* other systems -- pick what you want */
48#endif
49int nopdir = 0;
50char junkname[20];
51char funny[128];
6738d7a9 52char options[26 + 1] = { '-' };
8f5e70e1
BJ
53
54main(argc,argv)
55int argc;
56char *argv[];
57{
58register struct nameblock *p;
59int i, j;
60int descset, nfargs;
61TIMETYPE tjunk;
62char c, *s;
63static char onechar[2] = "X";
64#ifdef unix
31e81748 65void intrupt();
c93a5b01 66#endif
6738d7a9 67char *op = options + 1;
8f5e70e1
BJ
68
69
8f5e70e1
BJ
70#ifdef METERFILE
71meter(METERFILE);
72#endif
73
74descset = 0;
75
76funny['\0'] = (META | TERMINAL);
77for(s = "=|^();&<>*?[]:$`'\"\\\n" ; *s ; ++s)
78 funny[*s] |= META;
79for(s = "\n\t :;&>|" ; *s ; ++s)
80 funny[*s] |= TERMINAL;
81
82
83inarglist = 1;
84for(i=1; i<argc; ++i)
85 if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i]))
86 argv[i] = 0;
87
88setvar("$","$");
89inarglist = 0;
90
6738d7a9
SL
91for (i=1; i<argc; ++i)
92 if (argv[i]!=0 && argv[i][0]=='-') {
93 for (j=1 ; (c=argv[i][j])!='\0' ; ++j) {
94 *op++ = c;
95 switch (c) {
96
97 case 'd':
98 dbgflag = YES;
99 break;
100
101 case 'p':
102 prtrflag = YES;
103 break;
104
105 case 's':
106 silflag = YES;
107 break;
108
109 case 'i':
110 ignerr = YES;
111 break;
112
113 case 'S':
114 keepgoing = NO;
115 break;
116
117 case 'k':
118 keepgoing = YES;
119 break;
120
121 case 'n':
122 noexflag = YES;
123 break;
124
125 case 'r':
126 noruleflag = YES;
127 break;
128
129 case 't':
130 touchflag = YES;
131 break;
132
133 case 'q':
134 questflag = YES;
135 break;
136
137 case 'f':
138 op--; /* don't pass this one */
139 if(i >= argc-1)
140 fatal("No description argument after -f flag");
141 if( rddescf(argv[i+1]) )
8f5e70e1 142 fatal1("Cannot open %s", argv[i+1]);
6738d7a9
SL
143 argv[i+1] = 0;
144 ++descset;
145 break;
146
2b29f189
KB
147 case 'e':
148 doenvlast = YES;
149 break;
150
6738d7a9
SL
151 default:
152 onechar[0] = c; /* to make lint happy */
153 fatal1("Unknown flag argument %s", onechar);
154 }
8f5e70e1 155 }
6738d7a9 156 argv[i] = 0;
8f5e70e1
BJ
157 }
158
6738d7a9 159*op++ = '\0';
83d9028e
SL
160if (strcmp(options, "-") == 0)
161 *options = '\0';
6738d7a9
SL
162setvar("MFLAGS", options); /* MFLAGS=options to make */
163
2b29f189
KB
164setvar("MACHINE", MACHINE);
165
9b9fbe7e
KB
166if (!descset) {
167 if (rddescf("makefile"))
168 rddescf("Makefile");
169 rddescf(".depend");
170}
8f5e70e1 171
2b29f189
KB
172if (doenvlast == YES)
173 readenv();
174
8f5e70e1
BJ
175if(prtrflag) printdesc(NO);
176
177if( srchname(".IGNORE") ) ++ignerr;
178if( srchname(".SILENT") ) silflag = 1;
179if(p=srchname(".SUFFIXES")) sufflist = p->linep;
180if( !sufflist ) fprintf(stderr,"No suffix list.\n");
181
182#ifdef unix
183sigivalue = (int) signal(SIGINT, SIG_IGN) & 01;
184sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01;
185enbint(intrupt);
186#endif
187
188nfargs = 0;
189
190for(i=1; i<argc; ++i)
191 if((s=argv[i]) != 0)
192 {
193 if((p=srchname(s)) == 0)
194 {
195 p = makename(s);
196 }
197 ++nfargs;
198 doname(p, 0, &tjunk);
199 if(dbgflag) printdesc(YES);
200 }
201
202/*
203If no file arguments have been encountered, make the first
204name encountered that doesn't start with a dot
205*/
206
207if(nfargs == 0)
208 if(mainname == 0)
209 fatal("No arguments or description file");
210 else {
211 doname(mainname, 0, &tjunk);
212 if(dbgflag) printdesc(YES);
213 }
214
215exit(0);
216}
217
a781a4b6 218#include <sys/stat.h>
8f5e70e1
BJ
219
220#ifdef unix
31e81748 221void
8f5e70e1
BJ
222intrupt()
223{
224struct varblock *varptr();
225char *p;
226TIMETYPE exists();
a781a4b6 227struct stat sbuf;
8f5e70e1
BJ
228
229if(okdel && !noexflag && !touchflag &&
a781a4b6
SL
230 (p = varptr("@")->varval) &&
231 (stat(p, &sbuf) >= 0 && (sbuf.st_mode&S_IFMT) == S_IFREG) &&
232 !isprecious(p) )
8f5e70e1
BJ
233 {
234 fprintf(stderr, "\n*** %s removed.", p);
235 unlink(p);
236 }
237
238if(junkname[0])
239 unlink(junkname);
240fprintf(stderr, "\n");
241exit(2);
242}
243
244
245
246
247isprecious(p)
248char *p;
249{
250register struct lineblock *lp;
251register struct depblock *dp;
252register struct nameblock *np;
253
254if(np = srchname(".PRECIOUS"))
255 for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
256 for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
257 if(! unequal(p, dp->depname->namep))
258 return(YES);
259
260return(NO);
261}
262
263
264enbint(k)
31e81748 265void (*k)();
8f5e70e1
BJ
266{
267if(sigivalue == 0)
268 signal(SIGINT,k);
269if(sigqvalue == 0)
270 signal(SIGQUIT,k);
271}
272#endif
273\f
274extern char *builtin[];
275
276char **linesptr = builtin;
277
278FILE * fin;
279int firstrd = 0;
280
281
282rddescf(descfile)
283char *descfile;
284{
285FILE * k;
286
287/* read and parse description */
288
289if( !firstrd++ )
290 {
291 if( !noruleflag )
292 rdd1( (FILE *) NULL);
293
2b29f189
KB
294 if (doenvlast == NO)
295 readenv();
296
8f5e70e1
BJ
297#ifdef pwb
298 {
dbf5cc74 299 char *nlog, s[BUFSIZ];
8f5e70e1
BJ
300 nlog = logdir();
301 if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
302 rdd1(k);
303 else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
304 rdd1(k);
305
306 if ( (k=fopen("makecomm", "r")) != NULL)
307 rdd1(k);
308 else if ( (k=fopen("Makecomm", "r")) != NULL)
309 rdd1(k);
310 }
311#endif
312
313 }
314if(! unequal(descfile, "-"))
315 return( rdd1(stdin) );
316
317if( (k = fopen(descfile,"r")) != NULL)
318 return( rdd1(k) );
319
320return(1);
321}
322
323
324
325
326rdd1(k)
327FILE * k;
328{
329extern int yylineno;
330extern char *zznextc;
331
332fin = k;
333yylineno = 0;
334zznextc = 0;
335
336if( yyparse() )
337 fatal("Description file error");
338
96cf4ac6 339if(fin != NULL && fin != stdin)
8f5e70e1
BJ
340 fclose(fin);
341
342return(0);
343}
344\f
345printdesc(prntflag)
346int prntflag;
347{
348struct nameblock *p;
349struct depblock *dp;
350struct varblock *vp;
b342e078 351struct dirhdr *od;
8f5e70e1
BJ
352struct shblock *sp;
353struct lineblock *lp;
354
355#ifdef unix
356if(prntflag)
357 {
358 printf("Open directories:\n");
359 for (od = firstod; od; od = od->nxtopendir)
c01bbea7 360 printf("\t%d: %s\n", dirfd(od->dirfc), od->dirn);
8f5e70e1
BJ
361 }
362#endif
363
364if(firstvar != 0) printf("Macros:\n");
365for(vp = firstvar; vp ; vp = vp->nxtvarblock)
366 printf("\t%s = %s\n" , vp->varname , vp->varval);
367
368for(p = firstname; p; p = p->nxtnameblock)
369 {
370 printf("\n\n%s",p->namep);
371 if(p->linep != 0) printf(":");
372 if(prntflag) printf(" done=%d",p->done);
373 if(p==mainname) printf(" (MAIN NAME)");
374 for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
375 {
376 if( dp = lp->depp )
377 {
378 printf("\n depends on:");
379 for(; dp ; dp = dp->nxtdepblock)
380 if(dp->depname != 0)
381 printf(" %s ", dp->depname->namep);
382 }
383
384 if(sp = lp->shp)
385 {
386 printf("\n commands:\n");
387 for( ; sp!=0 ; sp = sp->nxtshblock)
388 printf("\t%s\n", sp->shbp);
389 }
390 }
391 }
392printf("\n");
393fflush(stdout);
394}
2b29f189
KB
395
396readenv()
397{
398 register char **ep, *p;
399 extern char **environ;
400
401 for(ep = environ ; *ep ; ++ep) {
402 for (p = *ep; *p; p++) {
403 if (isalnum(*p))
404 continue;
405 if (*p == '=') {
406 eqsign(*ep);
407 }
408 break;
409 }
410 }
411}