xref: /plan9/sys/src/ape/cmd/make/main.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1*219b2ee8SDavid du Colombier # include "defs.h"
2*219b2ee8SDavid du Colombier /*
3*219b2ee8SDavid du Colombier command make to update programs.
4*219b2ee8SDavid du Colombier Posix Flags:
5*219b2ee8SDavid du Colombier 	'e'  use environment macros after rather than before makefiles
6*219b2ee8SDavid du Colombier 	'f'  the next argument is the name of the description file;
7*219b2ee8SDavid du Colombier 	     "makefile" is the default
8*219b2ee8SDavid du Colombier 	'i'  ignore error codes from the shell
9*219b2ee8SDavid du Colombier 	'k'  continue to update other targets that don't depend
10*219b2ee8SDavid du Colombier 	     on target if error occurs making a target
11*219b2ee8SDavid du Colombier 	'n'  don't issue, just print, commands
12*219b2ee8SDavid du Colombier 	'p'  print out a version of the input graph
13*219b2ee8SDavid du Colombier 	'q'  don't do anything, but check if object is up to date;
14*219b2ee8SDavid du Colombier 	     returns exit code 0 if up to date, 1 if not
15*219b2ee8SDavid du Colombier 	'r'  clear the builtin suffix list and don't use built-in rules
16*219b2ee8SDavid du Colombier 	's'  silent mode--don't print out commands
17*219b2ee8SDavid du Colombier 	'S'  stop after any command fails (default; opposite of -k)
18*219b2ee8SDavid du Colombier 	't'  touch (update time of) files but don't issue command
19*219b2ee8SDavid du Colombier 
20*219b2ee8SDavid du Colombier Nonposix Flags:
21*219b2ee8SDavid du Colombier 	'd'  print out debugging comments
22*219b2ee8SDavid du Colombier 	'N'  use % patterns instead of old suffix rules
23*219b2ee8SDavid du Colombier 	'Pn' set process limit to n
24*219b2ee8SDavid du Colombier 	'z'  always use shell, never issue commands directly
25*219b2ee8SDavid du Colombier 
26*219b2ee8SDavid du Colombier */
27*219b2ee8SDavid du Colombier 
28*219b2ee8SDavid du Colombier nameblkp mainname	= NULL;
29*219b2ee8SDavid du Colombier nameblkp firstname	= NULL;
30*219b2ee8SDavid du Colombier lineblkp sufflist	= NULL;
31*219b2ee8SDavid du Colombier struct varblock *firstvar	= NULL;
32*219b2ee8SDavid du Colombier struct pattern *firstpat	= NULL;
33*219b2ee8SDavid du Colombier struct dirhd *firstod		= NULL;
34*219b2ee8SDavid du Colombier wildp firstwild			= NULL;
35*219b2ee8SDavid du Colombier wildp lastwild			= NULL;
36*219b2ee8SDavid du Colombier nameblkp *hashtab;
37*219b2ee8SDavid du Colombier int nhashed;
38*219b2ee8SDavid du Colombier int hashsize;
39*219b2ee8SDavid du Colombier int hashthresh;
40*219b2ee8SDavid du Colombier 
41*219b2ee8SDavid du Colombier int proclimit	= PROCLIMIT;
42*219b2ee8SDavid du Colombier int nproc	= 0;
43*219b2ee8SDavid du Colombier int proclive	= 0;
44*219b2ee8SDavid du Colombier struct process procstack[MAXPROC];
45*219b2ee8SDavid du Colombier 
46*219b2ee8SDavid du Colombier int sigivalue	= 0;
47*219b2ee8SDavid du Colombier int sigqvalue	= 0;
48*219b2ee8SDavid du Colombier 
49*219b2ee8SDavid du Colombier int dbgflag	= NO;
50*219b2ee8SDavid du Colombier int prtrflag	= NO;
51*219b2ee8SDavid du Colombier int silflag	= NO;
52*219b2ee8SDavid du Colombier int noexflag	= NO;
53*219b2ee8SDavid du Colombier int keepgoing	= NO;
54*219b2ee8SDavid du Colombier int noruleflag	= NO;
55*219b2ee8SDavid du Colombier int touchflag	= NO;
56*219b2ee8SDavid du Colombier int questflag	= NO;
57*219b2ee8SDavid du Colombier int oldflag	= YES;
58*219b2ee8SDavid du Colombier int ndocoms	= NO;
59*219b2ee8SDavid du Colombier int ignerr	= NO;    /* default is to stop on error */
60*219b2ee8SDavid du Colombier int forceshell	= NO;
61*219b2ee8SDavid du Colombier int okdel	= YES;
62*219b2ee8SDavid du Colombier int envlast	= NO;
63*219b2ee8SDavid du Colombier int inarglist	= NO;
64*219b2ee8SDavid du Colombier char **envpp	= NULL;
65*219b2ee8SDavid du Colombier 
66*219b2ee8SDavid du Colombier extern char *dfltmacro[];
67*219b2ee8SDavid du Colombier extern char *dfltpat[];
68*219b2ee8SDavid du Colombier extern char *dfltsuff[];
69*219b2ee8SDavid du Colombier extern char **environ;
70*219b2ee8SDavid du Colombier char **linesptr;
71*219b2ee8SDavid du Colombier 
72*219b2ee8SDavid du Colombier char *prompt	= "";
73*219b2ee8SDavid du Colombier int nopdir	= 0;
74*219b2ee8SDavid du Colombier char funny[128];
75*219b2ee8SDavid du Colombier 
76*219b2ee8SDavid du Colombier static void	loadenv(void);
77*219b2ee8SDavid du Colombier static int	isprecious(char *);
78*219b2ee8SDavid du Colombier static int	rddescf(char *);
79*219b2ee8SDavid du Colombier static void	rdarray(char **);
80*219b2ee8SDavid du Colombier static void	printdesc(int);
81*219b2ee8SDavid du Colombier 
82*219b2ee8SDavid du Colombier void
main(int argc,char ** argv)83*219b2ee8SDavid du Colombier main(int argc, char **argv)
84*219b2ee8SDavid du Colombier {
85*219b2ee8SDavid du Colombier nameblkp p;
86*219b2ee8SDavid du Colombier int i, j;
87*219b2ee8SDavid du Colombier int descset, nfargs;
88*219b2ee8SDavid du Colombier int nowait = NO;
89*219b2ee8SDavid du Colombier time_t tjunk;
90*219b2ee8SDavid du Colombier char c, *s, *mkflagp;
91*219b2ee8SDavid du Colombier static char makeflags[30] = "-";
92*219b2ee8SDavid du Colombier static char onechar[2] = "X";
93*219b2ee8SDavid du Colombier 
94*219b2ee8SDavid du Colombier descset = 0;
95*219b2ee8SDavid du Colombier mkflagp = makeflags+1;
96*219b2ee8SDavid du Colombier 
97*219b2ee8SDavid du Colombier funny['\0'] = (META | TERMINAL);
98*219b2ee8SDavid du Colombier for(s = "=|^();&<>*?[]:$`'\"\\\n" ; *s ; ++s)
99*219b2ee8SDavid du Colombier 	funny[*s] |= META;
100*219b2ee8SDavid du Colombier for(s = "\n\t :;&>|" ; *s ; ++s)
101*219b2ee8SDavid du Colombier 	funny[*s] |= TERMINAL;
102*219b2ee8SDavid du Colombier 
103*219b2ee8SDavid du Colombier 
104*219b2ee8SDavid du Colombier newhash(HASHSIZE);
105*219b2ee8SDavid du Colombier 
106*219b2ee8SDavid du Colombier inarglist = YES;
107*219b2ee8SDavid du Colombier for(i=1; i<argc; ++i)
108*219b2ee8SDavid du Colombier 	if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i]))
109*219b2ee8SDavid du Colombier 		argv[i] = 0;
110*219b2ee8SDavid du Colombier 
111*219b2ee8SDavid du Colombier setvar("$", "$", NO);
112*219b2ee8SDavid du Colombier inarglist = NO;
113*219b2ee8SDavid du Colombier 
114*219b2ee8SDavid du Colombier for(i=1; i<argc; ++i)
115*219b2ee8SDavid du Colombier     if(argv[i]!=0 && argv[i][0]=='-')
116*219b2ee8SDavid du Colombier 	{
117*219b2ee8SDavid du Colombier 	for(j=1 ; (c=argv[i][j])!='\0' ; ++j)  switch(c)
118*219b2ee8SDavid du Colombier 		{
119*219b2ee8SDavid du Colombier 		case 'd':
120*219b2ee8SDavid du Colombier 			++dbgflag;
121*219b2ee8SDavid du Colombier 			*mkflagp++ = 'd';
122*219b2ee8SDavid du Colombier 			break;
123*219b2ee8SDavid du Colombier 
124*219b2ee8SDavid du Colombier 		case 'e':
125*219b2ee8SDavid du Colombier 			envlast = YES;
126*219b2ee8SDavid du Colombier 			*mkflagp++ = 'e';
127*219b2ee8SDavid du Colombier 			break;
128*219b2ee8SDavid du Colombier 
129*219b2ee8SDavid du Colombier 		case 'f':
130*219b2ee8SDavid du Colombier 			if(i >= argc-1)
131*219b2ee8SDavid du Colombier 			  fatal("No description argument after -f flag");
132*219b2ee8SDavid du Colombier 			if( ! rddescf(argv[i+1]) )
133*219b2ee8SDavid du Colombier 				fatal1("Cannot open %s", argv[i+1]);
134*219b2ee8SDavid du Colombier 			argv[i+1] = 0;
135*219b2ee8SDavid du Colombier 			++descset;
136*219b2ee8SDavid du Colombier 			break;
137*219b2ee8SDavid du Colombier 
138*219b2ee8SDavid du Colombier 		case 'i':
139*219b2ee8SDavid du Colombier 			ignerr = YES;
140*219b2ee8SDavid du Colombier 			*mkflagp++ = 'i';
141*219b2ee8SDavid du Colombier 			break;
142*219b2ee8SDavid du Colombier 
143*219b2ee8SDavid du Colombier 		case 'k':
144*219b2ee8SDavid du Colombier 			keepgoing = YES;
145*219b2ee8SDavid du Colombier 			*mkflagp++ = 'k';
146*219b2ee8SDavid du Colombier 			break;
147*219b2ee8SDavid du Colombier 
148*219b2ee8SDavid du Colombier 		case 'n':
149*219b2ee8SDavid du Colombier 			noexflag = YES;
150*219b2ee8SDavid du Colombier 			*mkflagp++ = 'n';
151*219b2ee8SDavid du Colombier 			break;
152*219b2ee8SDavid du Colombier 
153*219b2ee8SDavid du Colombier 		case 'N':
154*219b2ee8SDavid du Colombier 			oldflag = NO;
155*219b2ee8SDavid du Colombier 			*mkflagp++ = 'N';
156*219b2ee8SDavid du Colombier 			break;
157*219b2ee8SDavid du Colombier 
158*219b2ee8SDavid du Colombier 		case 'p':
159*219b2ee8SDavid du Colombier 			prtrflag = YES;
160*219b2ee8SDavid du Colombier 			break;
161*219b2ee8SDavid du Colombier 
162*219b2ee8SDavid du Colombier 		case 'P':
163*219b2ee8SDavid du Colombier 			if(isdigit(argv[i][j+1]))
164*219b2ee8SDavid du Colombier 				{
165*219b2ee8SDavid du Colombier 				proclimit = argv[i][++j] - '0';
166*219b2ee8SDavid du Colombier 				if(proclimit < 1)
167*219b2ee8SDavid du Colombier 					proclimit = 1;
168*219b2ee8SDavid du Colombier 				}
169*219b2ee8SDavid du Colombier 			else
170*219b2ee8SDavid du Colombier 				fatal("illegal proclimit parameter");
171*219b2ee8SDavid du Colombier 			*mkflagp++ = 'P';
172*219b2ee8SDavid du Colombier 			*mkflagp++ = argv[i][j];
173*219b2ee8SDavid du Colombier 			break;
174*219b2ee8SDavid du Colombier 
175*219b2ee8SDavid du Colombier 		case 'q':
176*219b2ee8SDavid du Colombier 			questflag = YES;
177*219b2ee8SDavid du Colombier 			*mkflagp++ = 'q';
178*219b2ee8SDavid du Colombier 			break;
179*219b2ee8SDavid du Colombier 
180*219b2ee8SDavid du Colombier 		case 'r':
181*219b2ee8SDavid du Colombier 			noruleflag = YES;
182*219b2ee8SDavid du Colombier 			*mkflagp++ = 'r';
183*219b2ee8SDavid du Colombier 			break;
184*219b2ee8SDavid du Colombier 
185*219b2ee8SDavid du Colombier 		case 's':
186*219b2ee8SDavid du Colombier 			silflag = YES;
187*219b2ee8SDavid du Colombier 			*mkflagp++ = 's';
188*219b2ee8SDavid du Colombier 			break;
189*219b2ee8SDavid du Colombier 
190*219b2ee8SDavid du Colombier 		case 'S':
191*219b2ee8SDavid du Colombier 			keepgoing = NO;
192*219b2ee8SDavid du Colombier 			*mkflagp++ = 'S';
193*219b2ee8SDavid du Colombier 			break;
194*219b2ee8SDavid du Colombier 
195*219b2ee8SDavid du Colombier 		case 't':
196*219b2ee8SDavid du Colombier 			touchflag = YES;
197*219b2ee8SDavid du Colombier 			*mkflagp++ = 't';
198*219b2ee8SDavid du Colombier 			break;
199*219b2ee8SDavid du Colombier 
200*219b2ee8SDavid du Colombier 		case 'z':
201*219b2ee8SDavid du Colombier 			forceshell = YES;
202*219b2ee8SDavid du Colombier 			*mkflagp++ = 'z';
203*219b2ee8SDavid du Colombier 			break;
204*219b2ee8SDavid du Colombier 
205*219b2ee8SDavid du Colombier 		default:
206*219b2ee8SDavid du Colombier 			onechar[0] = c;	/* to make lint happy */
207*219b2ee8SDavid du Colombier 			fatal1("Unknown flag argument %s", onechar);
208*219b2ee8SDavid du Colombier 		}
209*219b2ee8SDavid du Colombier 
210*219b2ee8SDavid du Colombier 	argv[i] = NULL;
211*219b2ee8SDavid du Colombier 	}
212*219b2ee8SDavid du Colombier 
213*219b2ee8SDavid du Colombier if(mkflagp > makeflags+1)
214*219b2ee8SDavid du Colombier 	setvar("MAKEFLAGS", makeflags, NO);
215*219b2ee8SDavid du Colombier 
216*219b2ee8SDavid du Colombier if( !descset )
217*219b2ee8SDavid du Colombier if(	!rddescf("makefile") &&
218*219b2ee8SDavid du Colombier 	!rddescf("Makefile") &&
219*219b2ee8SDavid du Colombier 	(exists(s = "s.makefile") || exists(s = "s.Makefile")) )
220*219b2ee8SDavid du Colombier 		{
221*219b2ee8SDavid du Colombier 		char junk[20];
222*219b2ee8SDavid du Colombier 		concat("get ", s, junk);
223*219b2ee8SDavid du Colombier 		(void) dosys(junk, NO, NO, junk);
224*219b2ee8SDavid du Colombier 		rddescf(s+2);
225*219b2ee8SDavid du Colombier 		unlink(s+2);
226*219b2ee8SDavid du Colombier 		}
227*219b2ee8SDavid du Colombier 
228*219b2ee8SDavid du Colombier 
229*219b2ee8SDavid du Colombier if(envlast)
230*219b2ee8SDavid du Colombier 	loadenv();
231*219b2ee8SDavid du Colombier if(!noruleflag && !oldflag)
232*219b2ee8SDavid du Colombier 	rdarray(dfltpat);
233*219b2ee8SDavid du Colombier 
234*219b2ee8SDavid du Colombier if(prtrflag) printdesc(NO);
235*219b2ee8SDavid du Colombier 
236*219b2ee8SDavid du Colombier if( srchname(".IGNORE") )
237*219b2ee8SDavid du Colombier 	ignerr = YES;
238*219b2ee8SDavid du Colombier if( srchname(".SILENT") )
239*219b2ee8SDavid du Colombier 	silflag = YES;
240*219b2ee8SDavid du Colombier if( srchname(".OLDFLAG") )
241*219b2ee8SDavid du Colombier 	oldflag = YES;
242*219b2ee8SDavid du Colombier if( p=srchname(".SUFFIXES") )
243*219b2ee8SDavid du Colombier 	sufflist = p->linep;
244*219b2ee8SDavid du Colombier if( !sufflist && !firstwild)
245*219b2ee8SDavid du Colombier 	fprintf(stderr,"No suffix or %% pattern list.\n");
246*219b2ee8SDavid du Colombier /*
247*219b2ee8SDavid du Colombier if(sufflist && !oldflag)
248*219b2ee8SDavid du Colombier 	fprintf(stderr, "Suffix lists are old-fashioned. Use %% patterns\n);
249*219b2ee8SDavid du Colombier */
250*219b2ee8SDavid du Colombier 
251*219b2ee8SDavid du Colombier 	sigivalue = (int) signal(SIGINT, SIG_IGN);
252*219b2ee8SDavid du Colombier 	sigqvalue = (int) signal(SIGQUIT, SIG_IGN);
253*219b2ee8SDavid du Colombier 	enbint(intrupt);
254*219b2ee8SDavid du Colombier 
255*219b2ee8SDavid du Colombier nfargs = 0;
256*219b2ee8SDavid du Colombier 
257*219b2ee8SDavid du Colombier for(i=1; i<argc; ++i)
258*219b2ee8SDavid du Colombier 	if(s = argv[i])
259*219b2ee8SDavid du Colombier 		{
260*219b2ee8SDavid du Colombier 		if((p=srchname(s)) == NULL)
261*219b2ee8SDavid du Colombier 			p = makename(s);
262*219b2ee8SDavid du Colombier 		++nfargs;
263*219b2ee8SDavid du Colombier 		if(i+1<argc && argv[i+1] != 0 && equal(argv[i+1], "&") )
264*219b2ee8SDavid du Colombier 			{
265*219b2ee8SDavid du Colombier 			++i;
266*219b2ee8SDavid du Colombier 			nowait = YES;
267*219b2ee8SDavid du Colombier 			}
268*219b2ee8SDavid du Colombier 		else
269*219b2ee8SDavid du Colombier 			nowait = NO;
270*219b2ee8SDavid du Colombier 		doname(p, 0, &tjunk, nowait);
271*219b2ee8SDavid du Colombier 		if(dbgflag) printdesc(YES);
272*219b2ee8SDavid du Colombier 		}
273*219b2ee8SDavid du Colombier 
274*219b2ee8SDavid du Colombier /*
275*219b2ee8SDavid du Colombier If no file arguments have been encountered, make the first
276*219b2ee8SDavid du Colombier name encountered that doesn't start with a dot
277*219b2ee8SDavid du Colombier */
278*219b2ee8SDavid du Colombier 
279*219b2ee8SDavid du Colombier if(nfargs == 0)
280*219b2ee8SDavid du Colombier 	if(mainname == 0)
281*219b2ee8SDavid du Colombier 		fatal("No arguments or description file");
282*219b2ee8SDavid du Colombier 	else	{
283*219b2ee8SDavid du Colombier 		doname(mainname, 0, &tjunk, NO);
284*219b2ee8SDavid du Colombier 		if(dbgflag) printdesc(YES);
285*219b2ee8SDavid du Colombier 		}
286*219b2ee8SDavid du Colombier 
287*219b2ee8SDavid du Colombier if(!nowait)
288*219b2ee8SDavid du Colombier 	waitstack(0);
289*219b2ee8SDavid du Colombier exit(0);
290*219b2ee8SDavid du Colombier }
291*219b2ee8SDavid du Colombier 
292*219b2ee8SDavid du Colombier 
293*219b2ee8SDavid du Colombier void
intrupt(int sig)294*219b2ee8SDavid du Colombier intrupt(int sig)
295*219b2ee8SDavid du Colombier {
296*219b2ee8SDavid du Colombier char *p;
297*219b2ee8SDavid du Colombier 
298*219b2ee8SDavid du Colombier if(okdel && !noexflag && !touchflag &&
299*219b2ee8SDavid du Colombier 	(p = varptr("@")->varval) && exists(p)>0 && !isprecious(p) )
300*219b2ee8SDavid du Colombier 		{
301*219b2ee8SDavid du Colombier 		fprintf(stderr, "\n***  %s removed.", p);
302*219b2ee8SDavid du Colombier 		remove(p);
303*219b2ee8SDavid du Colombier 		}
304*219b2ee8SDavid du Colombier 
305*219b2ee8SDavid du Colombier fprintf(stderr, "\n");
306*219b2ee8SDavid du Colombier exit(2);
307*219b2ee8SDavid du Colombier }
308*219b2ee8SDavid du Colombier 
309*219b2ee8SDavid du Colombier 
310*219b2ee8SDavid du Colombier 
311*219b2ee8SDavid du Colombier static int
isprecious(char * p)312*219b2ee8SDavid du Colombier isprecious(char *p)
313*219b2ee8SDavid du Colombier {
314*219b2ee8SDavid du Colombier lineblkp lp;
315*219b2ee8SDavid du Colombier depblkp dp;
316*219b2ee8SDavid du Colombier nameblkp np;
317*219b2ee8SDavid du Colombier 
318*219b2ee8SDavid du Colombier if(np = srchname(".PRECIOUS"))
319*219b2ee8SDavid du Colombier 	for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
320*219b2ee8SDavid du Colombier 		for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
321*219b2ee8SDavid du Colombier 			if(equal(p, dp->depname->namep))
322*219b2ee8SDavid du Colombier 				return YES;
323*219b2ee8SDavid du Colombier 
324*219b2ee8SDavid du Colombier return NO;
325*219b2ee8SDavid du Colombier }
326*219b2ee8SDavid du Colombier 
327*219b2ee8SDavid du Colombier 
328*219b2ee8SDavid du Colombier void
enbint(void (* k)(int))329*219b2ee8SDavid du Colombier enbint(void (*k)(int))
330*219b2ee8SDavid du Colombier {
331*219b2ee8SDavid du Colombier if(sigivalue == 0)
332*219b2ee8SDavid du Colombier 	signal(SIGINT,k);
333*219b2ee8SDavid du Colombier if(sigqvalue == 0)
334*219b2ee8SDavid du Colombier 	signal(SIGQUIT,k);
335*219b2ee8SDavid du Colombier }
336*219b2ee8SDavid du Colombier 
337*219b2ee8SDavid du Colombier static int
rddescf(char * descfile)338*219b2ee8SDavid du Colombier rddescf(char *descfile)
339*219b2ee8SDavid du Colombier {
340*219b2ee8SDavid du Colombier static int firstrd = YES;
341*219b2ee8SDavid du Colombier 
342*219b2ee8SDavid du Colombier /* read and parse description */
343*219b2ee8SDavid du Colombier 
344*219b2ee8SDavid du Colombier if(firstrd)
345*219b2ee8SDavid du Colombier 	{
346*219b2ee8SDavid du Colombier 	firstrd = NO;
347*219b2ee8SDavid du Colombier 	if( !noruleflag )
348*219b2ee8SDavid du Colombier 		{
349*219b2ee8SDavid du Colombier 		rdarray(dfltmacro);
350*219b2ee8SDavid du Colombier 		if(oldflag)
351*219b2ee8SDavid du Colombier 			rdarray(dfltsuff);
352*219b2ee8SDavid du Colombier 		}
353*219b2ee8SDavid du Colombier 	if(!envlast)
354*219b2ee8SDavid du Colombier 		loadenv();
355*219b2ee8SDavid du Colombier 
356*219b2ee8SDavid du Colombier 	}
357*219b2ee8SDavid du Colombier 
358*219b2ee8SDavid du Colombier return  parse(descfile);
359*219b2ee8SDavid du Colombier }
360*219b2ee8SDavid du Colombier 
361*219b2ee8SDavid du Colombier static void
rdarray(char ** s)362*219b2ee8SDavid du Colombier rdarray(char **s)
363*219b2ee8SDavid du Colombier {
364*219b2ee8SDavid du Colombier linesptr = s;
365*219b2ee8SDavid du Colombier parse(CHNULL);
366*219b2ee8SDavid du Colombier }
367*219b2ee8SDavid du Colombier 
368*219b2ee8SDavid du Colombier static void
loadenv(void)369*219b2ee8SDavid du Colombier loadenv(void)
370*219b2ee8SDavid du Colombier {
371*219b2ee8SDavid du Colombier for(envpp = environ ; *envpp ; ++envpp)
372*219b2ee8SDavid du Colombier 	eqsign(*envpp);
373*219b2ee8SDavid du Colombier envpp = NULL;
374*219b2ee8SDavid du Colombier }
375*219b2ee8SDavid du Colombier 
376*219b2ee8SDavid du Colombier static void
printdesc(int prntflag)377*219b2ee8SDavid du Colombier printdesc(int prntflag)
378*219b2ee8SDavid du Colombier {
379*219b2ee8SDavid du Colombier nameblkp p;
380*219b2ee8SDavid du Colombier depblkp dp;
381*219b2ee8SDavid du Colombier struct varblock *vp;
382*219b2ee8SDavid du Colombier struct dirhd *od;
383*219b2ee8SDavid du Colombier struct shblock *sp;
384*219b2ee8SDavid du Colombier lineblkp lp;
385*219b2ee8SDavid du Colombier 
386*219b2ee8SDavid du Colombier if(prntflag)
387*219b2ee8SDavid du Colombier 	{
388*219b2ee8SDavid du Colombier 	printf("Open directories:\n");
389*219b2ee8SDavid du Colombier 	for (od = firstod; od; od = od->nxtdirhd)
390*219b2ee8SDavid du Colombier 		printf("\t%s\n", od->dirn);
391*219b2ee8SDavid du Colombier 	}
392*219b2ee8SDavid du Colombier 
393*219b2ee8SDavid du Colombier if(firstvar != 0) printf("Macros:\n");
394*219b2ee8SDavid du Colombier for(vp = firstvar; vp ; vp = vp->nxtvarblock)
395*219b2ee8SDavid du Colombier 	printf("\t%s = %s\n" , vp->varname , vp->varval ? vp->varval : "(null)");
396*219b2ee8SDavid du Colombier 
397*219b2ee8SDavid du Colombier for(p = firstname; p; p = p->nxtnameblock)
398*219b2ee8SDavid du Colombier 	{
399*219b2ee8SDavid du Colombier 	printf("\n\n%s",p->namep);
400*219b2ee8SDavid du Colombier 	if(p->linep != 0) printf(":");
401*219b2ee8SDavid du Colombier 	if(prntflag) printf("  done=%d",p->done);
402*219b2ee8SDavid du Colombier 	if(p==mainname) printf("  (MAIN NAME)");
403*219b2ee8SDavid du Colombier 	for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
404*219b2ee8SDavid du Colombier 		{
405*219b2ee8SDavid du Colombier 		if( dp = lp->depp )
406*219b2ee8SDavid du Colombier 			{
407*219b2ee8SDavid du Colombier 			printf("\n depends on:");
408*219b2ee8SDavid du Colombier 			for(; dp ; dp = dp->nxtdepblock)
409*219b2ee8SDavid du Colombier 				if(dp->depname != 0)
410*219b2ee8SDavid du Colombier 					printf(" %s ", dp->depname->namep);
411*219b2ee8SDavid du Colombier 			}
412*219b2ee8SDavid du Colombier 
413*219b2ee8SDavid du Colombier 		if(sp = lp->shp)
414*219b2ee8SDavid du Colombier 			{
415*219b2ee8SDavid du Colombier 			printf("\n commands:\n");
416*219b2ee8SDavid du Colombier 			for( ; sp ; sp = sp->nxtshblock)
417*219b2ee8SDavid du Colombier 				printf("\t%s\n", sp->shbp);
418*219b2ee8SDavid du Colombier 			}
419*219b2ee8SDavid du Colombier 		}
420*219b2ee8SDavid du Colombier 	}
421*219b2ee8SDavid du Colombier printf("\n");
422*219b2ee8SDavid du Colombier fflush(stdout);
423*219b2ee8SDavid du Colombier }
424