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