xref: /original-bsd/old/make/main.c (revision 92d3de31)
1 static	char *sccsid = "@(#)main.c	4.5 (Berkeley) 83/03/03";
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 struct nameblock *mainname	= NULL;
19 struct nameblock *firstname	= NULL;
20 struct lineblock *sufflist	= NULL;
21 struct varblock *firstvar	= NULL;
22 struct pattern *firstpat	= NULL;
23 struct dirhdr *firstod		= NULL;
24 
25 #include <signal.h>
26 int sigivalue	= 0;
27 int sigqvalue	= 0;
28 int waitpid	= 0;
29 
30 int dbgflag	= NO;
31 int prtrflag	= NO;
32 int silflag	= NO;
33 int noexflag	= NO;
34 int keepgoing	= NO;
35 int noruleflag	= NO;
36 int touchflag	= NO;
37 int questflag	= NO;
38 int ndocoms	= NO;
39 int ignerr	= NO;    /* default is to stop on error */
40 int okdel	= YES;
41 int inarglist;
42 #ifdef pwb
43 char *prompt	= ">";	/* other systems -- pick what you want */
44 #else
45 char *prompt	= "";	/* other systems -- pick what you want */
46 #endif
47 int nopdir	= 0;
48 char junkname[20];
49 char funny[128];
50 char	options[26 + 1] = { '-' };
51 
52 main(argc,argv)
53 int argc;
54 char *argv[];
55 {
56 register struct nameblock *p;
57 int i, j;
58 int descset, nfargs;
59 TIMETYPE tjunk;
60 char c, *s;
61 static char onechar[2] = "X";
62 #ifdef unix
63 int intrupt();
64 char *op = options + 1;
65 
66 
67 
68 #endif
69 
70 #ifdef METERFILE
71 meter(METERFILE);
72 #endif
73 
74 descset = 0;
75 
76 funny['\0'] = (META | TERMINAL);
77 for(s = "=|^();&<>*?[]:$`'\"\\\n" ; *s ; ++s)
78 	funny[*s] |= META;
79 for(s = "\n\t :;&>|" ; *s ; ++s)
80 	funny[*s] |= TERMINAL;
81 
82 
83 inarglist = 1;
84 for(i=1; i<argc; ++i)
85 	if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i]))
86 		argv[i] = 0;
87 
88 setvar("$","$");
89 inarglist = 0;
90 
91 for (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]) )
142 				fatal1("Cannot open %s", argv[i+1]);
143 				argv[i+1] = 0;
144 				++descset;
145 				break;
146 
147 			default:
148 				onechar[0] = c;	/* to make lint happy */
149 				fatal1("Unknown flag argument %s", onechar);
150 			}
151 		}
152 		argv[i] = 0;
153 	}
154 
155 *op++ = '\0';
156 if (strcmp(options, "-") == 0)
157 	*options = '\0';
158 setvar("MFLAGS", options);		/* MFLAGS=options to make */
159 
160 if( !descset )
161 #ifdef unix
162 	if( rddescf("makefile") )  rddescf("Makefile");
163 #endif
164 #ifdef gcos
165 	rddescf("makefile");
166 #endif
167 
168 if(prtrflag) printdesc(NO);
169 
170 if( srchname(".IGNORE") ) ++ignerr;
171 if( srchname(".SILENT") ) silflag = 1;
172 if(p=srchname(".SUFFIXES")) sufflist = p->linep;
173 if( !sufflist ) fprintf(stderr,"No suffix list.\n");
174 
175 #ifdef unix
176 sigivalue = (int) signal(SIGINT, SIG_IGN) & 01;
177 sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01;
178 enbint(intrupt);
179 #endif
180 
181 nfargs = 0;
182 
183 for(i=1; i<argc; ++i)
184 	if((s=argv[i]) != 0)
185 		{
186 		if((p=srchname(s)) == 0)
187 			{
188 			p = makename(s);
189 			}
190 		++nfargs;
191 		doname(p, 0, &tjunk);
192 		if(dbgflag) printdesc(YES);
193 		}
194 
195 /*
196 If no file arguments have been encountered, make the first
197 name encountered that doesn't start with a dot
198 */
199 
200 if(nfargs == 0)
201 	if(mainname == 0)
202 		fatal("No arguments or description file");
203 	else	{
204 		doname(mainname, 0, &tjunk);
205 		if(dbgflag) printdesc(YES);
206 		}
207 
208 exit(0);
209 }
210 
211 #include <sys/stat.h>
212 
213 #ifdef unix
214 intrupt()
215 {
216 struct varblock *varptr();
217 char *p;
218 TIMETYPE exists();
219 struct stat sbuf;
220 
221 if(okdel && !noexflag && !touchflag &&
222 	(p = varptr("@")->varval) &&
223 	(stat(p, &sbuf) >= 0 && (sbuf.st_mode&S_IFMT) == S_IFREG) &&
224 	!isprecious(p) )
225 		{
226 		fprintf(stderr, "\n***  %s removed.", p);
227 		unlink(p);
228 		}
229 
230 if(junkname[0])
231 	unlink(junkname);
232 fprintf(stderr, "\n");
233 exit(2);
234 }
235 
236 
237 
238 
239 isprecious(p)
240 char *p;
241 {
242 register struct lineblock *lp;
243 register struct depblock *dp;
244 register struct nameblock *np;
245 
246 if(np = srchname(".PRECIOUS"))
247 	for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
248 		for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
249 			if(! unequal(p, dp->depname->namep))
250 				return(YES);
251 
252 return(NO);
253 }
254 
255 
256 enbint(k)
257 int (*k)();
258 {
259 if(sigivalue == 0)
260 	signal(SIGINT,k);
261 if(sigqvalue == 0)
262 	signal(SIGQUIT,k);
263 }
264 #endif
265 
266 extern char *builtin[];
267 
268 char **linesptr	= builtin;
269 
270 FILE * fin;
271 int firstrd	= 0;
272 
273 
274 rddescf(descfile)
275 char *descfile;
276 {
277 FILE * k;
278 
279 /* read and parse description */
280 
281 if( !firstrd++ )
282 	{
283 	if( !noruleflag )
284 		rdd1( (FILE *) NULL);
285 
286 #ifdef pwb
287 		{
288 		char *nlog, s[100];
289 		nlog = logdir();
290 		if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
291 			rdd1(k);
292 		else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
293 			rdd1(k);
294 
295 		if ( (k=fopen("makecomm", "r")) != NULL)
296 			rdd1(k);
297 		else if ( (k=fopen("Makecomm", "r")) != NULL)
298 			rdd1(k);
299 		}
300 #endif
301 
302 	}
303 if(! unequal(descfile, "-"))
304 	return( rdd1(stdin) );
305 
306 if( (k = fopen(descfile,"r")) != NULL)
307 	return( rdd1(k) );
308 
309 return(1);
310 }
311 
312 
313 
314 
315 rdd1(k)
316 FILE * k;
317 {
318 extern int yylineno;
319 extern char *zznextc;
320 
321 fin = k;
322 yylineno = 0;
323 zznextc = 0;
324 
325 if( yyparse() )
326 	fatal("Description file error");
327 
328 if(fin != NULL)
329 	fclose(fin);
330 
331 return(0);
332 }
333 
334 printdesc(prntflag)
335 int prntflag;
336 {
337 struct nameblock *p;
338 struct depblock *dp;
339 struct varblock *vp;
340 struct dirhdr *od;
341 struct shblock *sp;
342 struct lineblock *lp;
343 
344 #ifdef unix
345 if(prntflag)
346 	{
347 	printf("Open directories:\n");
348 	for (od = firstod; od; od = od->nxtopendir)
349 		printf("\t%d: %s\n", od->dirfc->dd_fd, od->dirn);
350 	}
351 #endif
352 
353 if(firstvar != 0) printf("Macros:\n");
354 for(vp = firstvar; vp ; vp = vp->nxtvarblock)
355 	printf("\t%s = %s\n" , vp->varname , vp->varval);
356 
357 for(p = firstname; p; p = p->nxtnameblock)
358 	{
359 	printf("\n\n%s",p->namep);
360 	if(p->linep != 0) printf(":");
361 	if(prntflag) printf("  done=%d",p->done);
362 	if(p==mainname) printf("  (MAIN NAME)");
363 	for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
364 		{
365 		if( dp = lp->depp )
366 			{
367 			printf("\n depends on:");
368 			for(; dp ; dp = dp->nxtdepblock)
369 				if(dp->depname != 0)
370 					printf(" %s ", dp->depname->namep);
371 			}
372 
373 		if(sp = lp->shp)
374 			{
375 			printf("\n commands:\n");
376 			for( ; sp!=0 ; sp = sp->nxtshblock)
377 				printf("\t%s\n", sp->shbp);
378 			}
379 		}
380 	}
381 printf("\n");
382 fflush(stdout);
383 }
384