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