Research V7 development
[unix-history] / usr / src / cmd / make / main.c
CommitLineData
47f9f6cd
F
1# include "defs"
2/*
3command make to update programs.
4Flags: 'd' print out debugging comments
5 'p' print out a version of the input graph
6 's' silent mode--don't print out commands
7 'f' the next argument is the name of the description file;
8 "makefile" is the default
9 'i' ignore error codes from the shell
10 'S' stop after any command fails (normally do parallel work)
11 'n' don't issue, just print, commands
12 't' touch (update time of) files but don't issue command
13 'q' don't do anything, but check if object is up to date;
14 returns exit code 0 if up to date, -1 if not
15*/
16
17struct nameblock *mainname ;
18struct nameblock *firstname;
19struct lineblock *sufflist;
20struct varblock *firstvar;
21struct pattern *firstpat ;
22struct opendir *firstod;
23
24#include <signal.h>
25int sigivalue = 0;
26int sigqvalue = 0;
27int waitpid = 0;
28
29int dbgflag = NO;
30int prtrflag = NO;
31int silflag = NO;
32int noexflag = NO;
33int keepgoing = NO;
34int noruleflag = NO;
35int touchflag = NO;
36int questflag = NO;
37int ndocoms = NO;
38int ignerr = NO; /* default is to stop on error */
39int okdel = YES;
40int inarglist;
41char *prompt = ""; /* other systems -- pick what you want */
42char junkname[20];
43char funny[128];
44
45main(argc,argv)
46int argc;
47char *argv[];
48{
49register struct nameblock *p;
50int i, j;
51int descset, nfargs;
52TIMETYPE tjunk;
53char c, *s;
54static char onechar[2] = "X";
55#ifdef unix
56int intrupt();
57
58
59
60#endif
61
62#ifdef METERFILE
63meter(METERFILE);
64#endif
65
66descset = 0;
67
68funny['\0'] = (META | TERMINAL);
69for(s = "=|^();&<>*?[]:$`'\"\\\n" ; *s ; ++s)
70 funny[*s] |= META;
71for(s = "\n\t :;&>|" ; *s ; ++s)
72 funny[*s] |= TERMINAL;
73
74
75inarglist = 1;
76for(i=1; i<argc; ++i)
77 if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i]))
78 argv[i] = 0;
79
80setvar("$","$");
81inarglist = 0;
82
83for(i=1; i<argc; ++i)
84 if(argv[i]!=0 && argv[i][0]=='-')
85 {
86 for(j=1 ; (c=argv[i][j])!='\0' ; ++j) switch(c)
87 {
88 case 'd':
89 dbgflag = YES;
90 break;
91
92 case 'p':
93 prtrflag = YES;
94 break;
95
96 case 's':
97 silflag = YES;
98 break;
99
100 case 'i':
101 ignerr = YES;
102 break;
103
104 case 'S':
105 keepgoing = NO;
106 break;
107
108 case 'k':
109 keepgoing = YES;
110 break;
111
112 case 'n':
113 noexflag = YES;
114 break;
115
116 case 'r':
117 noruleflag = YES;
118 break;
119
120 case 't':
121 touchflag = YES;
122 break;
123
124 case 'q':
125 questflag = YES;
126 break;
127
128 case 'f':
129 if(i >= argc-1)
130 fatal("No description argument after -f flag");
131 if( rddescf(argv[i+1]) )
132 fatal1("Cannot open %s", argv[i+1]);
133 argv[i+1] = 0;
134 ++descset;
135 break;
136
137 default:
138 onechar[0] = c; /* to make lint happy */
139 fatal1("Unknown flag argument %s", onechar);
140 }
141
142 argv[i] = 0;
143 }
144
145if( !descset )
146#ifdef unix
147 if( rddescf("makefile") ) rddescf("Makefile");
148#endif
149#ifdef gcos
150 rddescf("makefile");
151#endif
152
153if(prtrflag) printdesc(NO);
154
155if( srchname(".IGNORE") ) ++ignerr;
156if( srchname(".SILENT") ) silflag = 1;
157if(p=srchname(".SUFFIXES")) sufflist = p->linep;
158if( !sufflist ) fprintf(stderr,"No suffix list.\n");
159
160#ifdef unix
161sigivalue = (int) signal(SIGINT, SIG_IGN) & 01;
162sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01;
163enbint(intrupt);
164#endif
165
166nfargs = 0;
167
168for(i=1; i<argc; ++i)
169 if((s=argv[i]) != 0)
170 {
171 if((p=srchname(s)) == 0)
172 {
173 p = makename(s);
174 }
175 ++nfargs;
176 doname(p, 0, &tjunk);
177 if(dbgflag) printdesc(YES);
178 }
179
180/*
181If no file arguments have been encountered, make the first
182name encountered that doesn't start with a dot
183*/
184
185if(nfargs == 0)
186 if(mainname == 0)
187 fatal("No arguments or description file");
188 else {
189 doname(mainname, 0, &tjunk);
190 if(dbgflag) printdesc(YES);
191 }
192
193exit(0);
194}
195
196
197
198#ifdef unix
199intrupt()
200{
201struct varblock *varptr();
202char *p;
203TIMETYPE exists();
204
205if(okdel && !noexflag && !touchflag &&
206 (p = varptr("@")->varval) && exists(p)>0 && !isprecious(p) )
207 {
208 fprintf(stderr, "\n*** %s removed.", p);
209 unlink(p);
210 }
211
212if(junkname[0])
213 unlink(junkname);
214fprintf(stderr, "\n");
215exit(2);
216}
217
218
219
220
221isprecious(p)
222char *p;
223{
224register struct lineblock *lp;
225register struct depblock *dp;
226register struct nameblock *np;
227
228if(np = srchname(".PRECIOUS"))
229 for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
230 for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
231 if(! unequal(p, dp->depname->namep))
232 return(YES);
233
234return(NO);
235}
236
237
238enbint(k)
239int (*k)();
240{
241if(sigivalue == 0)
242 signal(SIGINT,k);
243if(sigqvalue == 0)
244 signal(SIGQUIT,k);
245}
246#endif
247\f
248extern char *builtin[];
249
250char **linesptr = builtin;
251
252FILE * fin;
253int firstrd = 0;
254
255
256rddescf(descfile)
257char *descfile;
258{
259extern int yylineno;
260extern char *zznextc;
261FILE * k;
262
263/* read and parse description */
264
265if( !firstrd++ )
266 {
267 if( !noruleflag )
268 rdd1( (FILE *) NULL);
269
270#ifdef pwb
271 {
272 char *nlog, s[100];
273 nlog = logdir();
274 if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
275 rdd1(k);
276 else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
277 rdd1(k);
278
279 if ( (k=fopen("makecomm", "r")) != NULL)
280 rdd1(k);
281 else if ( (k=fopen("Makecomm", "r")) != NULL)
282 rdd1(k);
283 }
284#endif
285
286 }
287if(! unequal(descfile, "-"))
288 return( rdd1(stdin) );
289
290if( (k = fopen(descfile,"r")) != NULL)
291 return( rdd1(k) );
292
293return(1);
294}
295
296
297
298
299rdd1(k)
300FILE * k;
301{
302fin = k;
303yylineno = 0;
304zznextc = 0;
305
306if( yyparse() )
307 fatal("Description file error");
308
309if(fin != NULL)
310 fclose(fin);
311
312return(0);
313}
314\f
315printdesc(prntflag)
316int prntflag;
317{
318struct nameblock *p;
319struct depblock *dp;
320struct varblock *vp;
321struct opendir *od;
322struct shblock *sp;
323struct lineblock *lp;
324
325#ifdef unix
326if(prntflag)
327 {
328 printf("Open directories:\n");
329 for(od = firstod ; od ; od = od->nxtopendir)
330 printf("\t%d: %s\n", fileno(od->dirfc), od->dirn);
331 }
332#endif
333
334if(firstvar != 0) printf("Macros:\n");
335for(vp = firstvar; vp ; vp = vp->nxtvarblock)
336 printf("\t%s = %s\n" , vp->varname , vp->varval);
337
338for(p = firstname; p; p = p->nxtnameblock)
339 {
340 printf("\n\n%s",p->namep);
341 if(p->linep != 0) printf(":");
342 if(prntflag) printf(" done=%d",p->done);
343 if(p==mainname) printf(" (MAIN NAME)");
344 for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
345 {
346 if( dp = lp->depp )
347 {
348 printf("\n depends on:");
349 for(; dp ; dp = dp->nxtdepblock)
350 if(dp->depname != 0)
351 printf(" %s ", dp->depname->namep);
352 }
353
354 if(sp = lp->shp)
355 {
356 printf("\n commands:\n");
357 for( ; sp!=0 ; sp = sp->nxtshblock)
358 printf("\t%s\n", sp->shbp);
359 }
360 }
361 }
362printf("\n");
363fflush(stdout);
364}