xref: /original-bsd/old/make/main.c (revision 62734ea8)
1 static	char *sccsid = "@(#)main.c	4.4 (Berkeley) 82/10/11";
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 
212 
213 #ifdef unix
214 intrupt()
215 {
216 struct varblock *varptr();
217 char *p;
218 TIMETYPE exists();
219 
220 if(okdel && !noexflag && !touchflag &&
221 	(p = varptr("@")->varval) && exists(p)>0 && !isprecious(p) )
222 		{
223 		fprintf(stderr, "\n***  %s removed.", p);
224 		unlink(p);
225 		}
226 
227 if(junkname[0])
228 	unlink(junkname);
229 fprintf(stderr, "\n");
230 exit(2);
231 }
232 
233 
234 
235 
236 isprecious(p)
237 char *p;
238 {
239 register struct lineblock *lp;
240 register struct depblock *dp;
241 register struct nameblock *np;
242 
243 if(np = srchname(".PRECIOUS"))
244 	for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
245 		for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
246 			if(! unequal(p, dp->depname->namep))
247 				return(YES);
248 
249 return(NO);
250 }
251 
252 
253 enbint(k)
254 int (*k)();
255 {
256 if(sigivalue == 0)
257 	signal(SIGINT,k);
258 if(sigqvalue == 0)
259 	signal(SIGQUIT,k);
260 }
261 #endif
262 
263 extern char *builtin[];
264 
265 char **linesptr	= builtin;
266 
267 FILE * fin;
268 int firstrd	= 0;
269 
270 
271 rddescf(descfile)
272 char *descfile;
273 {
274 FILE * k;
275 
276 /* read and parse description */
277 
278 if( !firstrd++ )
279 	{
280 	if( !noruleflag )
281 		rdd1( (FILE *) NULL);
282 
283 #ifdef pwb
284 		{
285 		char *nlog, s[100];
286 		nlog = logdir();
287 		if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
288 			rdd1(k);
289 		else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
290 			rdd1(k);
291 
292 		if ( (k=fopen("makecomm", "r")) != NULL)
293 			rdd1(k);
294 		else if ( (k=fopen("Makecomm", "r")) != NULL)
295 			rdd1(k);
296 		}
297 #endif
298 
299 	}
300 if(! unequal(descfile, "-"))
301 	return( rdd1(stdin) );
302 
303 if( (k = fopen(descfile,"r")) != NULL)
304 	return( rdd1(k) );
305 
306 return(1);
307 }
308 
309 
310 
311 
312 rdd1(k)
313 FILE * k;
314 {
315 extern int yylineno;
316 extern char *zznextc;
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 struct nameblock *p;
335 struct depblock *dp;
336 struct varblock *vp;
337 struct dirhdr *od;
338 struct shblock *sp;
339 struct lineblock *lp;
340 
341 #ifdef unix
342 if(prntflag)
343 	{
344 	printf("Open directories:\n");
345 	for (od = firstod; od; od = od->nxtopendir)
346 		printf("\t%d: %s\n", od->dirfc->dd_fd, od->dirn);
347 	}
348 #endif
349 
350 if(firstvar != 0) printf("Macros:\n");
351 for(vp = firstvar; vp ; vp = vp->nxtvarblock)
352 	printf("\t%s = %s\n" , vp->varname , vp->varval);
353 
354 for(p = firstname; p; p = p->nxtnameblock)
355 	{
356 	printf("\n\n%s",p->namep);
357 	if(p->linep != 0) printf(":");
358 	if(prntflag) printf("  done=%d",p->done);
359 	if(p==mainname) printf("  (MAIN NAME)");
360 	for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
361 		{
362 		if( dp = lp->depp )
363 			{
364 			printf("\n depends on:");
365 			for(; dp ; dp = dp->nxtdepblock)
366 				if(dp->depname != 0)
367 					printf(" %s ", dp->depname->namep);
368 			}
369 
370 		if(sp = lp->shp)
371 			{
372 			printf("\n commands:\n");
373 			for( ; sp!=0 ; sp = sp->nxtshblock)
374 				printf("\t%s\n", sp->shbp);
375 			}
376 		}
377 	}
378 printf("\n");
379 fflush(stdout);
380 }
381