1 /* @(#)parse.c	1.129 21/08/06 Copyright 1985-2021 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)parse.c	1.129 21/08/06 Copyright 1985-2021 J. Schilling";
6 #endif
7 /*
8  *	Make program
9  *	Parsing routines
10  *
11  *	Copyright (c) 1985-2021 by J. Schilling
12  */
13 /*
14  * The contents of this file are subject to the terms of the
15  * Common Development and Distribution License, Version 1.0 only
16  * (the "License").  You may not use this file except in compliance
17  * with the License.
18  *
19  * See the file CDDL.Schily.txt in this distribution for details.
20  * A copy of the CDDL is also available via the Internet at
21  * http://www.opensource.org/licenses/cddl1.txt
22  *
23  * When distributing Covered Code, include this CDDL HEADER in each
24  * file and include the License file CDDL.Schily.txt from this distribution.
25  */
26 
27 #include <schily/stdio.h>
28 #include <schily/standard.h>
29 #include <schily/varargs.h>
30 #include <schily/stdlib.h>
31 #include <schily/unistd.h>	/* include sys/types.h for schily/schily.h */
32 #include <schily/string.h>
33 #include <schily/schily.h>
34 #include <schily/ccomdefs.h>
35 #include "make.h"
36 
37 #ifdef	pdp11
38 #define	MAXOBJS		64	/* Max # of targets in target list. */
39 #else
40 #define	MAXOBJS		512	/* Max # of targets in target list. */
41 #endif
42 
43 
44 EXPORT	void	parsefile	__PR((void));
45 LOCAL	void	define_obj	__PR((obj_t * obj, int n, int objcnt, int type, list_t * dep, cmd_t * cmd));
46 LOCAL	obj_t	*define_dcolon	__PR((obj_t *obj));
47 LOCAL	void	listappend	__PR((obj_t *obj, list_t *dep));
48 LOCAL	void	define_patrule	__PR((obj_t * obj, list_t * dep, cmd_t * cmd, int type));
49 LOCAL	void	print_patrules	__PR((FILE *f));
50 LOCAL	obj_t	*check_ssuffrule __PR((obj_t *obj, list_t *dep));
51 EXPORT	char	*get_var	__PR((char *name));
52 EXPORT	void	define_var	__PR((char *name, char *val));
53 LOCAL	int	getobjname	__PR((void));
54 LOCAL	obj_t	*getobj		__PR((void));
55 LOCAL	int	getname		__PR((int type));
56 LOCAL	obj_t	*getnam		__PR((int type));
57 LOCAL	int	getln		__PR((void));
58 LOCAL	list_t	**listcat	__PR((obj_t * obj, list_t ** tail));
59 LOCAL	list_t	**mklist	__PR((char *line, list_t ** tail, BOOL doexpand));
60 LOCAL	list_t	*cplist		__PR((list_t * l));
61 LOCAL	list_t	**exp_list	__PR((obj_t * o, list_t ** tail));
62 LOCAL	list_t	*getlist	__PR((int *typep));
63 LOCAL	BOOL	is_shvar	__PR((obj_t ** op, int *typep, list_t *** tailp));
64 LOCAL	list_t	*getshvar	__PR((int *typep));
65 LOCAL	cmd_t	*getcmd		__PR((void));
66 LOCAL	int	exp_ovec	__PR((obj_t ** ovec, int objcnt));
67 LOCAL	int	read_ovec	__PR((obj_t ** ovec, int *typep));
68 EXPORT	list_t	*cvtvpath	__PR((list_t *l));
69 EXPORT	BOOL	is_inlist	__PR((char *objname, char *name));
70 LOCAL	BOOL	obj_in_list	__PR((obj_t *obj, list_t *l));
71 EXPORT	BOOL	nowarn		__PR((char *name));
72 LOCAL	void	warn		__PR((char *, ...)) __printflike__(1, 2);
73 LOCAL	void	exerror		__PR((char *, ...)) __printflike__(1, 2);
74 LOCAL	obj_t	*_objlook	__PR((obj_t *table[], char *name, BOOL create));
75 EXPORT	obj_t	*objlook	__PR((char *name, BOOL create));
76 EXPORT	list_t	*objlist	__PR((char *name));
77 EXPORT	obj_t	*ssufflook	__PR((char *name, BOOL create));
78 EXPORT	BOOL	check_ssufftab	__PR((void));
79 LOCAL	void	clear_ssufftab	__PR((void));
80 LOCAL	BOOL	is_suffix_rule	__PR((obj_t *obj));
81 LOCAL	void	prvar		__PR((obj_t * p));
82 LOCAL	void	ptree		__PR((obj_t * p, int n));
83 EXPORT	void	printtree	__PR((void));
84 EXPORT	void	probj		__PR((FILE *f, obj_t * o, int type, int dosuff));
85 EXPORT	void	prtree		__PR((void));
86 LOCAL	char	*typestr	__PR((int type));
87 LOCAL	void	printobj	__PR((FILE *f, obj_t ** ovec, int objcnt, int type, list_t * deplist, cmd_t * cmdlist));
88 
89 /*
90  *	parse the dependency file
91  *
92  *	<obj1> {<obj2> ...} : <dependency list>
93  *	{	<cmdlist>}
94  *
95  *	<macro>= <macro value>
96  *
97  *	<macro> += <macro value>
98  *
99  *	<macro> :sh= <shell command>
100  */
101 EXPORT void
parsefile()102 parsefile()
103 {
104 	int	i, objcnt;
105 	int	type = 0;	/* init to make GCC quiet */
106 	obj_t	*ovec[MAXOBJS];
107 	list_t	*deplist;
108 	cmd_t	*cmdlist;
109 
110 	if (Do_Warn)
111 		error("Parsing file '%s'\n", mfname);
112 
113 	if (Dmake > 0)
114 		error(">>>>>>>>>>>>>>>> Reading makefile '%s'\n", mfname);
115 
116 	ovec[0] = 0;
117 	lineno = 1;
118 	col = 0;
119 	getch();
120 	while (lastc != EOF) {
121 		if (lastc == '\t') {
122 			/*
123 			 * Skip leading white space that follows a TAB.
124 			 */
125 			while (lastc != EOF && (lastc == ' ' || lastc == '\t'))
126 				getch();
127 			/*
128 			 * Abort if such a line is not empty or contains more
129 			 * than only a comment. This has the side effect that
130 			 * '^<TAB> include' will not work anymore.
131 			 */
132 			if (lastc != '\n') {
133 				exerror(
134 				"Unexpected <TAB> character followed by nonblank '%c' <%o>",
135 					lastc, lastc);
136 			}
137 			getch();	/* Eat up new line character */
138 			continue;	/* Continue with next line */
139 		}
140 		type = 0;
141 		if ((objcnt = read_ovec(ovec, &type)) == 0) {
142 			if (Do_Warn && (type & NWARN) == 0) {
143 				/*
144 				 * This is when $(EMPTY) was expanded to nothing
145 				 * in exp_ovec() inside read_ovec().
146 				 */
147 				warn("Missing object name");
148 			}
149 			type = ntype(type);
150 			if (type != COLON && type != DCOLON)
151 				continue;
152 		}
153 		type = ntype(type);
154 
155 		if (objcnt < 0) {
156 			errmsgno(EX_BAD, "Objcount: %d Objects: ", -objcnt);
157 			for (i = 0; i < -objcnt; i++)
158 				error("'%s' ", ovec[i]->o_name);
159 			error("\n");
160 			exerror("Too many target items");
161 		}
162 
163 #ifdef	XXX	/* Begin new code for include */
164 printf("objcnt: %d ovec[0]: %s lastc: '%c'\n", objcnt, ovec[0]->o_name, lastc);
165 for (i = 0; i < objcnt; i++)
166 	printf("name[%d] = %s ", i, ovec[i]->o_name);
167 printf("\n");
168 #endif
169 		if (lastc == '\n') {
170 			if (streql(ovec[0]->o_name, "include") ||
171 				streql(ovec[0]->o_name, "-include")) {
172 				for (i = 1; i < objcnt; i++) {
173 					doinclude(ovec[i]->o_name,
174 						ovec[0]->o_name[0] != '-');
175 				}
176 				/* XXX freeobj ??? */
177 				continue;
178 			}
179 			if (streql(ovec[0]->o_name, "export")) {
180 				for (i = 1; i < objcnt; i++) {
181 					doexport(ovec[i]->o_name);
182 				}
183 				/* XXX freeobj ??? */
184 				continue;
185 			}
186 			if (streql(ovec[0]->o_name, "unexport")) {
187 				for (i = 1; i < objcnt; i++) {
188 					dounexport(ovec[i]->o_name);
189 				}
190 				/* XXX freeobj ??? */
191 				continue;
192 			}
193 			if (streql(ovec[0]->o_name, "readonly")) {
194 				for (i = 1; i < objcnt; i++) {
195 					ovec[i]->o_flags |= F_READONLY;
196 				}
197 				/* XXX freeobj ??? */
198 				continue;
199 			}
200 			/*
201 			 * Any other word on the beginning of a line
202 			 * that is not followed by a ':' or a '=' is an error.
203 			 */
204 		} /* end new code for include */
205 
206 		if (lastc != ':' && lastc != '=') {
207 			errmsgno(EX_BAD, "Objcount: %d Objects: ", objcnt);
208 			for (i = 0; i < objcnt; i++)
209 				error("'%s' ", ovec[i]->o_name);
210 			error("\n");
211 			exerror("Missing : or =, got '%c' <%o>", lastc, lastc);
212 		}
213 		getch();
214 		/*
215 		 * If the macro type is ::= (GNU style assgignment),
216 		 * the + operator expands variables on the right hand side
217 		 * and we need to replace the operator + by +:= first.
218 		 * ::= followed by + results in unpredictable behavior and for
219 		 * this reason, it is recommended to have at least one
220 		 * lowercase char in ::= types macro name to tell people about
221 		 * the unusual behavior of the + operator.
222 		 */
223 		if (type == ADDMAC && ovec[0]->o_type == GNU_ASSIGN)
224 			type = ADD_VARMAC;
225 		in_parser = -1;		/* In parser but no ::= expansion */
226 		deplist = getlist(&type);
227 		in_parser = 0;
228 		if (type == SHVAR)
229 			deplist = getshvar(&type);
230 
231 		if (lastc == ';') {
232 			lastc = '\t';
233 			firstc = '\t';
234 		}
235 
236 		/*
237 		 * We should test for type == COLON only but unfortunately,
238 		 * the makefilesystem contained some simple pattern rule
239 		 * definitions that are written as: tgt_suff = list.
240 		 * We only allow what has been used in the makefilesystem.
241 		 * This changed in late 1999, we should keep support
242 		 * for it for at least 5 years.
243 		 */
244 /*		if (basetype(type) == COLON) {*/
245 		if (basetype(type) == COLON ||
246 		    (basetype(type) == EQUAL && deplist && objcnt > 0 &&
247 					ovec[0]->o_name[0] == '.')) {
248 			cmdlist = getcmd();
249 		} else {
250 			cmdlist = NULL;
251 		}
252 		while (lastc == '\n')
253 			getch();
254 		for (i = 0; i < objcnt; i++)
255 			define_obj(ovec[i], i, objcnt, type, deplist, cmdlist);
256 
257 		if (Dmake > 0)
258 			printobj(stderr, ovec, objcnt, type, deplist, cmdlist);
259 	}
260 	if (Dmake > 0)
261 		error(">>>>>>>>>>>>>>>> End of  makefile '%s'\n", mfname);
262 }
263 
264 /*
265  * Add dependency and command lists to a node in the object tree.
266  * Allow definitions to be overridden if the new definition in in
267  * a different file.
268  */
269 LOCAL void
define_obj(obj,n,objcnt,type,dep,cmd)270 define_obj(obj, n, objcnt, type, dep, cmd)
271 	register obj_t	*obj;
272 		int	n;
273 		int	objcnt;
274 		int	type;
275 	register list_t	*dep;
276 		cmd_t	*cmd;
277 {
278 	/*
279 	 * For a conditional macro assignment ?=, we do nothing if the
280 	 * object already has a value list assigned.
281 	 */
282 	if (type == CONDEQUAL && obj->o_list)
283 		return;
284 
285 	/*
286 	 * First check for possible direct recursions to avoid to blow
287 	 * up memory immediately.
288 	 */
289 	if (type != '=' && obj_in_list(obj, dep))
290 		exerror("Recursion in dependencies for '%s'", obj->o_name);
291 
292 	/*
293 	 * If we have a list of targets with the same dependency list,
294 	 * we copy the list structure to be able to separately
295 	 * append new elements to each of the targets.
296 	 */
297 	if (n > 0)
298 		dep = cplist(dep);
299 
300 	if (objcnt == 1) {
301 		if (basetype(type) == COLON &&
302 		    strchr(obj->o_name, '%') != NULL) {
303 			define_patrule(obj, dep, cmd, type);
304 			return;
305 		}
306 		/*
307 		 * We should test for type == COLON too but unfortunately,
308 		 * the makefilesystem contained some simple pattern rule
309 		 * definitions that are written as: tgt_suff = list.
310 		 * This changed in late 1999, we should keep support
311 		 * for it for at least 5 years.
312 		 */
313 /*		if (type == COLON && && dep != NULL && cmd != NULL) {*/
314 		if (dep != NULL && cmd != NULL) {
315 			obj = check_ssuffrule(obj, dep);
316 		}
317 	} else {
318 		obj->o_flags |= F_MULTITARGET;
319 	}
320 	if (obj->o_type == 0)
321 		obj->o_type = type;
322 
323 	/*
324 	 * Save first target that does not start with
325 	 * a dot in case no arguments have been supplied
326 	 * to make.
327 	 */
328 	if (n == 0 && !default_tgt && basetype(type) == COLON &&
329 	    (obj->o_name[0] != '.' || obj->o_name[1] == SLASH ||
330 	    (obj->o_name[1] == '.' && obj->o_name[2] == SLASH)))
331 		default_tgt = obj;
332 
333 	if (n == 0 && basetype(type) == COLON &&
334 	    obj->o_name[0] == '.' && streql(obj->o_name, ".POSIX"))
335 		posixmode = TRUE;
336 
337 	if (type == DCOLON)
338 		obj = define_dcolon(obj);
339 
340 	/*
341 	 * XXX Probleme gibt es mit der Gleichbehandlung von ':' und '=' typen.
342 	 * XXX So definiert 'smake' MAKE_NAME= smake und sp�ter kommt evt.
343 	 * XXX smake: $(OBJLIST)
344 	 */
345 
346 
347 	if (obj->o_flags & F_READONLY) {	/* Check for "read only" */
348 		if (!((obj->o_flags & F_IDXOVERWRT) &&
349 		    (obj->o_fileindex == Mfileindex)))
350 			return;
351 	}
352 	obj->o_flags |= Mflags;			/* Add current global flags */
353 
354 	/*
355 	 * Old:
356 	 * Definition in new Makefile overrides existing definitions
357 	 *
358 	 * New:
359 	 * Definitions in Makefiles from commandline override
360 	 * existing definitions. Further definitions in cmdline Makefiles
361 	 * append.
362 	 */
363 	if ((obj->o_fileindex < MF_IDX_MAKEFILE || basetype(obj->o_type) == EQUAL) &&
364 	    (type != ADDMAC && type != ADD_VARMAC) &&
365 	    !streql(obj->o_name, ".SUFFIXES")) {
366 
367 		/*
368 		 * We unfortunately also print this warning in case that "obj"
369 		 * just has been created by the parser.
370 		 */
371 		if (Do_Warn && (obj->o_flags & F_NEWNODE) == 0)
372 			warn("'%s' RE-defined", obj->o_name);
373 		if (obj->o_fileindex == MF_IDX_ENVIRON) {
374 			obj->o_fileindex = Mfileindex;
375 			obj->o_type = type;
376 		}
377 		obj->o_list = dep;
378 		obj->o_cmd = cmd;
379 		obj->o_flags &= ~F_NEWNODE;
380 		return;
381 	}
382 
383 	/*
384 	 * Add new definitions to list.
385 	 * Ignore definitions already in list.
386 	 */
387 	listappend(obj, dep);
388 
389 	if (obj->o_cmd != (cmd_t *) NULL) {
390 		if (cmd != (cmd_t *) NULL) {
391 			warn("Multiple commands defined for '%s'", obj->o_name);
392 			/* XXX freelist()/freecmd() ??? */
393 		}
394 	} else {
395 		obj->o_cmd = cmd;
396 	}
397 }
398 
399 /*
400  * Define an intermediate target for Double Colon :: Rules
401  *
402  * a:: b
403  *	cmd_b
404  * a:: c
405  *	cmd_c
406  *
407  * results in:
408  * 	a::	::1@a ::2@a
409  * and
410  *	::1@a: b
411  *		cmd_b
412  *	::2@a: c
413  *		cmd_c
414  */
415 LOCAL obj_t *
define_dcolon(obj)416 define_dcolon(obj)
417 	register obj_t	*obj;
418 {
419 static	int	serial = 0;
420 	obj_t	*o;
421 	list_t	*lo;
422 	char	_name[TYPICAL_NAMEMAX];
423 	char	*name = _name;
424 	size_t	namelen = sizeof (_name);
425 	char	*np = NULL;
426 
427 	if (obj->o_namelen + 16 >= namelen) {
428 		namelen = obj->o_namelen + 16;
429 		name = np = ___realloc(np, namelen, "dcolon target");
430 	}
431 	snprintf(name, namelen, "::%d@%s", ++serial, obj->o_name);
432 	o = objlook(name, TRUE);
433 	if (np)
434 		free(np);
435 	o->o_type = ':';
436 	o->o_flags |= F_DCOLON;		/* Mark as intermediate :: object */
437 	lo = (list_t *) fastalloc(sizeof (list_t));
438 	lo->l_next = NULL;
439 	lo->l_obj = o;
440 
441 	listappend(obj, lo);		/* Append this intermediate to list */
442 
443 	o->o_node = obj;		/* Make this inter. obj aux to orig */
444 	return (o);			/* Return intermediate object */
445 }
446 
447 /*
448  * Append new definitions to dependencies in o_list, but
449  * ignore them if they are already in the list.
450  */
451 LOCAL void
listappend(obj,dep)452 listappend(obj, dep)
453 	register obj_t	*obj;
454 	register list_t	*dep;
455 {
456 	if (dep == NULL && obj->o_name[0] == '.' &&
457 	    streql(obj->o_name, ".SSUFFIX_RULES"))
458 		clear_ssufftab();
459 	if (obj->o_list != (list_t *) NULL) {
460 		register list_t *l = obj->o_list;
461 
462 		if (dep == NULL && obj->o_name[0] == '.') {
463 			/*
464 			 * Allow to clear special targets.
465 			 */
466 			if (streql(obj->o_name, ".SUFFIXES") ||
467 			    streql(obj->o_name, ".SSUFFIX_RULES") ||
468 			    streql(obj->o_name, ".DEFAULT") ||
469 			    streql(obj->o_name, ".NO_WARN") ||
470 			    streql(obj->o_name, ".SCCS_GET") ||
471 			    streql(obj->o_name, ".SPACE_IN_NAMES"))
472 				obj->o_list = NULL;
473 			obj->o_flags &= ~F_NEWNODE;
474 			return;
475 		}
476 
477 		if (Do_Warn && (obj->o_flags & F_NEWNODE) == 0) {
478 			if (obj->o_type != ':' || Do_Warn > 1)
479 				warn("'%s' ADD-defined", obj->o_name);
480 		}
481 
482 		/*
483 		 * if not already head of list, try to append ...
484 		 */
485 		if (l != dep) {
486 			while (l->l_next && l->l_next != dep)
487 				l = l->l_next;
488 			if (l->l_next == (list_t *) NULL)
489 				l->l_next = dep;
490 		}
491 	} else {
492 		obj->o_list = dep;
493 	}
494 	obj->o_flags &= ~F_NEWNODE;
495 }
496 
497 patr_t	*Patrules;
498 patr_t	**pattail = &Patrules;
499 
500 /*
501  * Parse a pattern rule definition. This is a special type of implicit rules.
502  */
503 LOCAL void
define_patrule(obj,dep,cmd,type)504 define_patrule(obj, dep, cmd, type)
505 	obj_t	*obj;
506 	list_t	*dep;
507 	cmd_t	*cmd;
508 	int	type;
509 {
510 	patr_t	*p;
511 	char	*s;
512 	register list_t *l;
513 
514 	p = (patr_t *) fastalloc(sizeof (*p));	/* larger than list_t */
515 
516 	p->p_name = obj;
517 	p->p_list = dep;
518 	p->p_cmd = cmd;
519 	s = strchr(obj->o_name, '%');
520 	if (s != NULL) {
521 		*s = '\0';
522 		p->p_tgt_prefix = strsave(obj->o_name);
523 		p->p_tgt_suffix = strsave(&s[1]);
524 		*s = '%';
525 	} else {		/* This can never happen! */
526 		p->p_tgt_prefix = strsave(Nullstr);
527 		p->p_tgt_suffix = strsave(obj->o_name);
528 	}
529 	p->p_tgt_pfxlen = strlen(p->p_tgt_prefix);
530 	p->p_tgt_suflen = strlen(p->p_tgt_suffix);
531 
532 	for (l = dep; l; l = l->l_next) {
533 		if (strchr(l->l_obj->o_name, '%'))
534 			l->l_obj->o_flags |= F_PERCENT;
535 	}
536 	if (dep == NULL) {
537 		p->p_src_prefix = 0;
538 		p->p_src_suffix = 0;
539 		p->p_src_pfxlen = 0;
540 		p->p_src_suflen = 0;
541 	} else {
542 		s = strchr(dep->l_obj->o_name, '%');
543 		if (s != NULL) {
544 			*s = '\0';
545 			p->p_src_prefix = strsave(dep->l_obj->o_name);
546 			p->p_src_suffix = strsave(&s[1]);
547 			*s = '%';
548 		} else {
549 			p->p_src_prefix = strsave(Nullstr);
550 			p->p_src_suffix = strsave(dep->l_obj->o_name);
551 		}
552 		p->p_src_pfxlen = strlen(p->p_src_prefix);
553 		p->p_src_suflen = strlen(p->p_src_suffix);
554 	}
555 	p->p_flags = 0;
556 	if (type == DCOLON)
557 		p->p_flags |= PF_TERM;	/* Make it a termiator rule */
558 	*pattail = p;
559 	pattail = &p->p_next;
560 	p->p_next = 0;
561 }
562 
563 /*
564  * Print the complete list of pattern rules.
565  */
566 LOCAL void
print_patrules(f)567 print_patrules(f)
568 	FILE	*f;
569 {
570 	patr_t	*p = Patrules;
571 	cmd_t	*c;
572 
573 	while (p) {
574 		register list_t *l;
575 
576 		fprintf(f, "%s%%%s:%s",
577 		p->p_tgt_prefix, p->p_tgt_suffix,
578 		(p->p_flags & PF_TERM) ? ":":"");
579 
580 		for (l = p->p_list; l; l = l->l_next) {
581 			fprintf(f, " %s", l->l_obj->o_name);
582 		}
583 		printf("\n");
584 
585 		for (c = p->p_cmd; c; c = c->c_next)
586 			fprintf(f, "\t%s\n", c->c_line);
587 		p = p->p_next;
588 	}
589 }
590 
591 /*
592  * Check for a simple suffix rule definition.
593  * In case we found a simple suffix rule definition, return a new obj_t *.
594  */
595 LOCAL obj_t *
check_ssuffrule(obj,dep)596 check_ssuffrule(obj, dep)
597 	obj_t	*obj;
598 	list_t	*dep;
599 {
600 	register char	*name = obj->o_name;
601 	register list_t	*l;
602 	extern	 int	xssrules;
603 
604 	/*
605 	 * Check if the first character of the target is a '.' or
606 	 * if the target name equals "", but make sure this is
607 	 * not a vanilla target that just starts with "./".
608 	 */
609 	if ((name[0] == '.' && strchr(name, SLASH) == NULL) ||
610 	    (name[0] == '"' && name[1] == '"' && name[2] == '\0')) {
611 
612 		/*
613 		 * All dependency names must start with a '.'
614 		 * and may not contain a SLASH.
615 		 */
616 		for (l = dep; l; l = l->l_next) {
617 			if (l->l_obj->o_name[0] != '.')
618 				return (obj);
619 			if (strchr(l->l_obj->o_name, SLASH) != NULL)
620 				return (obj);
621 		}
622 		obj = ssufflook(obj->o_name, TRUE);
623 		xssrules++;
624 	}
625 	return (obj);
626 }
627 
628 /*
629  * Get the macro value as in the form macro=value.
630  */
631 EXPORT char *
get_var(name)632 get_var(name)
633 	char	*name;
634 {
635 	obj_t	*o = objlook(name, FALSE);
636 
637 	if (o == (obj_t *)NULL)
638 		return ((char *)NULL);
639 
640 	if (basetype(o->o_type) == EQUAL && o->o_list != NULL)
641 		return (o->o_list->l_obj->o_name);
642 	return ((char *)NULL);
643 }
644 
645 /*
646  * Define a macro as in the form macro=value.
647  * Value may only be one word.
648  */
649 EXPORT void
define_var(name,val)650 define_var(name, val)
651 	char	*name;
652 	char	*val;
653 {
654 	obj_t	*o;
655 	obj_t	*ov;
656 	list_t	*list;
657 	list_t	**tail = &list;
658 
659 	o = objlook(name, TRUE);
660 	if (o->o_flags & F_READONLY) {		/* Check for "read only" */
661 		if (!((o->o_flags & F_IDXOVERWRT) &&
662 		    (o->o_fileindex == Mfileindex)))
663 			return;
664 	}
665 	o->o_flags |= Mflags;			/* Add current global flags */
666 	if (val && *val) {			/* Only if not empty */
667 		ov = objlook(val, TRUE);
668 		tail = listcat(ov, tail);
669 	}
670 	*tail = (list_t *) NULL;
671 	o->o_list = list;
672 	o->o_type = EQUAL;
673 	o->o_flags &= ~F_NEWNODE;
674 }
675 
676 #ifdef	NEEDED
677 /*
678  * Define a macro as in the form macro=vallist.
679  * Vallist may be a list of words that is white space separated in one string.
680  */
681 EXPORT void
define_lvar(name,vallist)682 define_lvar(name, vallist)
683 	char	*name;
684 	char	*vallist;
685 {
686 	obj_t	*o;
687 	obj_t	*ov;
688 	list_t	*list;
689 	list_t	**tail = &list;
690 
691 	o = objlook(name, TRUE);
692 	if (o->o_flags & F_READONLY)		/* Check for "read only" */
693 		return;
694 	o->o_flags |= Mflags;			/* Add current global flags */
695 	tail = mklist(vallist, tail, FALSE);
696 	*tail = (list_t *) NULL;
697 	o->o_list = list;
698 	o->o_type = EQUAL;
699 	o->o_flags &= ~F_NEWNODE;
700 }
701 
702 /*
703  * Return a list_t pointer to the nth word in a macro value list.
704  */
705 list_t *
varvaln(name,n)706 varvaln(name, n)
707 	char	*name;
708 	int	n;
709 {
710 	obj_t	*o = objlook(name, FALSE);
711 
712 	if (o)
713 		return (list_nth(o->o_list, n));
714 	return ((list_t *)0);
715 }
716 #endif	/* NEEDED */
717 
718 #define	white(c)	(c == ' ' || c == '\t')
719 
720 /*
721  * Read a space separated word from current Makefile.
722  * Used for target list. Stop at space, ':' '=' and ','.
723  * Returns the length of the word.
724  */
725 LOCAL int
getobjname()726 getobjname()
727 {
728 	register char	*p = gbuf;
729 	register int	beg = 0;
730 	register int	end = 0;
731 	register int	nestlevel = 0;
732 
733 	while (white(lastc))
734 		getch();			/* Skip white space. */
735 	if (lastc == '$') {
736 		switch (beg = peekch()) {
737 
738 		case '(': end = ')'; break;
739 		case '{': end = '}'; break;
740 
741 		default:
742 			beg = end = -1;
743 		}
744 	}
745 	while (lastc != EOF && (' ' < lastc || nestlevel > 0)) {
746 		if (lastc == beg)
747 			nestlevel++;
748 		else if (lastc == end)
749 			nestlevel--;
750 		if (nestlevel <= 0) {
751 			if (lastc == ':' || lastc == '=' || lastc == ',')
752 				break;
753 		}
754 #ifdef	__CHECK_NAMEMAX_IN_GETOBJNAME__
755 		if (n >= NAMEMAX - 2)
756 			exerror("Name more than %d chars long", NAMEMAX - 2);
757 #endif	/*  __CHECK_NAMEMAX_IN_GETOBJNAME__ */
758 		if (p >= gbufend)
759 			p = growgbuf(p);
760 		*p++ = lastc;
761 		if (istext(lastc))		/* Can we avoid getch()? */
762 			p = gtext(p);		/* Get usual text faster */
763 
764 		if (nestlevel <= 0 && lastc == '\\') {
765 			if (white(peekch()) && objlist(".SPACE_IN_NAMES")) {
766 				getch();
767 				p--;
768 				*p++ = lastc;
769 			}
770 		}
771 		getch();
772 	}
773 	if (p >= gbufend)
774 		p = growgbuf(p);
775 	*p = '\0';				/* Terminate with null char */
776 	return (p - gbuf);
777 }
778 
779 /*
780  * Read a target file name.
781  */
782 LOCAL obj_t
getobj()783 *getobj()
784 {
785 	return (getobjname() ? objlook(gbuf, TRUE) : (obj_t *) NULL);
786 }
787 
788 /*
789  * Read a space separated word from current Makefile.
790  * General purpose version for dependency list.
791  * Returns the length of the word.
792  */
793 LOCAL int
getname(type)794 getname(type)
795 	int	type;
796 {
797 	register char	*p = gbuf;
798 	register int	beg = 0;
799 	register int	end = 0;
800 	register int	nestlevel = 0;
801 
802 	if (type == ':')
803 		type = ';';
804 	else
805 		type = '\0';
806 
807 	while (white(lastc))
808 		getch();			/* Skip white space. */
809 	if (lastc == '$') {
810 		switch (beg = peekch()) {
811 
812 		case '(': end = ')'; break;
813 		case '{': end = '}'; break;
814 
815 		default:
816 			beg = end = -1;
817 		}
818 	}
819 	while (lastc != EOF && (' ' < lastc || nestlevel > 0)) {
820 		if (lastc == beg)
821 			nestlevel++;
822 		else if (lastc == end)
823 			nestlevel--;
824 		if (nestlevel <= 0) {
825 			if (lastc == type)
826 				break;
827 		}
828 #ifdef	__CHECK_NAMEMAX_IN_GETNAME__
829 		if (n >= NAMEMAX - 2)
830 			exerror("Name more than %d chars long", NAMEMAX - 2);
831 #endif	/* __CHECK_NAMEMAX_IN_GETNAME__ */
832 		if (p >= gbufend)
833 			p = growgbuf(p);
834 		*p++ = lastc;
835 		if (istext(lastc))		/* Can we avoid getch()? */
836 			p = gtext(p);		/* Get usual text faster */
837 
838 		if (nestlevel <= 0 && lastc == '\\') {
839 			if (white(peekch()) && objlist(".SPACE_IN_NAMES")) {
840 				getch();
841 				p--;
842 				*p++ = lastc;
843 			}
844 		}
845 		getch();
846 	}
847 	if (p >= gbufend)
848 		p = growgbuf(p);
849 	*p = '\0';				/* Terminate with null char */
850 	return (p - gbuf);
851 }
852 
853 /*
854  * Read a dependency file name.
855  */
856 LOCAL obj_t *
getnam(type)857 getnam(type)
858 	int	type;
859 {
860 	return (getname(type) ? objlook(gbuf, TRUE) : (obj_t *) NULL);
861 }
862 
863 /*
864  * Reads a line from current Makefile.
865  * Returns the length of the string.
866  */
867 LOCAL int
getln()868 getln()
869 {
870 	register char	*p = gbuf;
871 
872 	while (white(lastc))
873 		getch();			/* Skip white space. */
874 	while (lastc != EOF && lastc != '\n') {
875 #ifdef	__CHECK_NAMEMAX_IN_GETLN__
876 		if (n >= NAMEMAX - 2) {
877 			exerror("Line more than %d chars long", NAMEMAX - 2);
878 		}
879 #endif /* __CHECK_NAMEMAX_IN_GETLN__ */
880 		if (p >= gbufend)
881 			p = growgbuf(p);
882 		*p++ = lastc;
883 		p = gtext(p);			/* Get usual text faster */
884 		getch();
885 	}
886 	if (p >= gbufend)
887 		p = growgbuf(p);
888 	*p = '\0';				/* Terminate with null char */
889 	return (p - gbuf);
890 }
891 
892 /*
893  * Add one new object to the end of a list of objects.
894  */
895 LOCAL list_t **
listcat(obj,tail)896 listcat(obj, tail)
897 	obj_t	*obj;
898 	list_t	**tail;
899 {
900 	list_t	*item;
901 
902 	*tail = item = (list_t *) fastalloc(sizeof (list_t));
903 	item->l_obj = obj;
904 	tail = &item->l_next;
905 	return (tail);
906 }
907 
908 /*
909  * Make a list of objects by parsing a line
910  * and cutting it at whitespaces.
911  */
912 LOCAL list_t **
mklist(line,tail,doexpand)913 mklist(line, tail, doexpand)
914 	register char	*line;
915 	register list_t	**tail;
916 		BOOL	doexpand;
917 {
918 	register obj_t	*o;
919 	register char	*p;
920 
921 /*printf("Line: '%s'\n", line);*/
922 
923 	for (p = line; *p; ) {
924 		while (*p && white(*p))
925 			p++;
926 		line = p;
927 		while (*p) {
928 			if (white(*p)) {
929 				*p++ = '\0';
930 				if (*line)
931 					break;
932 			}
933 			p++;
934 		}
935 /*printf("line: '%s'\n", line);*/
936 		/*
937 		 * If the list ends with white space, we will see
938 		 * an empty string at the end of the list unless
939 		 * we apply this test.
940 		 */
941 		if (*line == '\0')
942 			break;
943 		o = objlook(line, TRUE);
944 		if (doexpand)
945 			tail = exp_list(o, tail);
946 		else
947 			tail = listcat(o, tail);
948 	}
949 	return (tail);
950 }
951 
952 /*
953  * Copy a list.
954  * Generate new list pointers and re-use the old obj pointers.
955  */
956 LOCAL list_t *
cplist(l)957 cplist(l)
958 	list_t	*l;
959 {
960 		list_t	*list;
961 	register list_t	**tail = &list;
962 
963 	while (l) {
964 		tail = listcat(l->l_obj, tail);
965 		l = l->l_next;
966 	}
967 	*tail = (list_t *) NULL;
968 	return (list);
969 }
970 
971 EXPORT	BOOL	in_parser;
972 EXPORT	BOOL	in_varassign;
973 
974 /*
975  * Expand one object name using make macro definitions.
976  * Add the new objects to the end of a list of objects.
977  */
978 LOCAL list_t **
exp_list(o,tail)979 exp_list(o, tail)
980 	obj_t	*o;
981 	list_t	**tail;
982 {
983 	char	*name;
984 	char	*xname;
985 
986 	name = o->o_name;
987 	if (strchr(name, '$')) {
988 
989 		if (in_parser == FALSE)
990 			in_parser = TRUE;
991 		xname = substitute(name, NullObj, 0, 0);
992 		if (in_parser == TRUE)
993 			in_parser = FALSE;
994 		if (streql(name, xname)) {
995 			printf("eql: %s\n", name);
996 			tail = listcat(o, tail);
997 		} else {
998 /*printf("Sxname: %s <- %s\n", xname, name);*/
999 			tail = mklist(xname, tail, FALSE);
1000 		}
1001 	} else {
1002 		tail = listcat(o, tail);
1003 	}
1004 	*tail = (list_t *) NULL;
1005 	return (tail);
1006 }
1007 
1008 #ifdef	NEEDED
1009 /*
1010  * Expand a list of object names using make macro definitions.
1011  * Add the new objects to the end of a list of objects.
1012  */
1013 LOCAL list_t *
exp_olist(l)1014 exp_olist(l)
1015 	list_t	*l;
1016 {
1017 	list_t	*list;
1018 	list_t	**tail = &list;
1019 
1020 	while (l) {
1021 		tail = exp_list(l->l_obj, tail);
1022 		l = l->l_next;
1023 	}
1024 	*tail = (list_t *) NULL;
1025 	return (list);
1026 }
1027 #endif	/* NEEDED */
1028 
1029 /*
1030  * Read a list of dependency file names.
1031  */
1032 LOCAL list_t *
getlist(typep)1033 getlist(typep)
1034 	int	*typep;
1035 {
1036 	list_t	*list;
1037 	list_t	**tail = &list;
1038 	obj_t	*o;
1039 	int	type = basetype(*typep);
1040 	BOOL	first = TRUE;
1041 
1042 	if (type == '=') {
1043 		int n;
1044 #ifdef	nono
1045 		char *p;
1046 #endif
1047 
1048 		n = getln();
1049 
1050 #ifdef	nono	/* Do not kill trailing whitespace !!! */
1051 
1052 		p = &gbuf[n-1];
1053 		while (white(*p))
1054 			p--;
1055 		*++p = '\0';
1056 #endif
1057 		/*
1058 		 * Only add to list if right hand side is not completely white.
1059 		 */
1060 		if (n) {
1061 			o = objlook(gbuf, TRUE);
1062 			if (*typep == VAR_ASSIGN || *typep == GNU_ASSIGN ||
1063 			    *typep == ADD_VARMAC) {
1064 				if (*typep == VAR_ASSIGN || *typep == ADD_VARMAC)
1065 					in_varassign++;	/* Inhibit $$ expans. */
1066 				tail = exp_list(o, tail);
1067 				if (*typep == VAR_ASSIGN || *typep == ADD_VARMAC)
1068 					in_varassign--;
1069 			} else
1070 				tail = listcat(o, tail);
1071 		}
1072 	} else while ((o = getnam(type)) != (obj_t *) NULL) {
1073 		if (type == '=') {
1074 			tail = listcat(o, tail);
1075 		} else {
1076 			if (first) {
1077 				first = FALSE;
1078 				if (is_shvar(&o, typep, &tail))
1079 					break;
1080 			}
1081 			tail = exp_list(o, tail);
1082 		}
1083 	}
1084 	*tail = (list_t *) NULL;
1085 	return (list);
1086 }
1087 
1088 /*
1089  * Check if a definition for immediate shell expansion follows.
1090  */
1091 LOCAL BOOL
is_shvar(op,typep,tailp)1092 is_shvar(op, typep, tailp)
1093 	obj_t	**op;
1094 	int	*typep;
1095 	list_t	***tailp;
1096 {
1097 	obj_t	*o = *op;
1098 
1099 	if (o->o_name[0] != 's')
1100 		return (FALSE);
1101 
1102 	if (streql(o->o_name, "sh=")) {
1103 		*typep = SHVAR;
1104 		return (TRUE);
1105 	}
1106 	if (streql(o->o_name, "sh")) {
1107 		if ((o = getnam(*typep)) == (obj_t *)NULL) {
1108 			return (FALSE);
1109 		}
1110 		if (streql(o->o_name, "=")) {
1111 			*typep = SHVAR;
1112 			return (TRUE);
1113 		} else {
1114 			*tailp = exp_list(*op, *tailp);
1115 			*op = o;
1116 		}
1117 	}
1118 	return (FALSE);
1119 }
1120 
1121 /*
1122  * read a line and expand by shell
1123  */
1124 LOCAL list_t *
getshvar(typep)1125 getshvar(typep)
1126 	int	*typep;
1127 {
1128 		list_t	*list;
1129 	register list_t	**tail = &list;
1130 		char	*p;
1131 
1132 	*typep = '=';
1133 	getln();
1134 	p = shout(gbuf);
1135 
1136 	tail = mklist(p, tail, FALSE);
1137 	*tail = (list_t *) NULL;
1138 	return (list);
1139 }
1140 
1141 /*
1142  * Read a list of command lines that follow a dependency list.
1143  */
1144 LOCAL cmd_t *
getcmd()1145 getcmd()
1146 {
1147 		cmd_t	*list;
1148 	register cmd_t	*item, **tail = &list;
1149 	register char	*p;
1150 
1151 	setincmd(TRUE);			/* Switch reader to command mode */
1152 	if (lastc == '\n')		/* Not a ';' command type	 */
1153 		getch();
1154 
1155 	while (lastc != EOF && (firstc == '\t' || firstc == '#')) {
1156 		/*
1157 		 * We handle comment in command lines as in old UNIX 'make' and
1158 		 * not as required by POSIX. A command line that starts with
1159 		 * a '#' (the following code) is handled as usual.
1160 		 * A '#' inside a command line and escaped newlines are
1161 		 * forwarded to the shell. This is needed to allow something
1162 		 * like cc -# with SunPRO C.
1163 		 */
1164 		if (firstc == '#') {
1165 			skipline();	/* Skip commented out line	*/
1166 			getch();	/* Skip newline character.	*/
1167 			continue;
1168 		}
1169 		while (white(lastc))
1170 			getch();	/* Skip white space. */
1171 
1172 		for (p = gbuf; lastc != EOF; getch()) {
1173 			if (lastc == '\n' && (p == gbuf || p[-1] != '\\'))
1174 				break;
1175 			if (p >= gbufend)
1176 				p = growgbuf(p);
1177 			*p++ = lastc;
1178 		}
1179 		if (p >= gbufend)
1180 			p = growgbuf(p);
1181 		*p = '\0';
1182 		*tail = item = (cmd_t *) fastalloc(sizeof (cmd_t));
1183 		item->c_line = strsave(gbuf);
1184 		tail = &item->c_next;
1185 
1186 		if (lastc == '\n')	/* Skip newline character. */
1187 			getch();
1188 	}
1189 /*printf("getcmd: lastc: %c %CX '%.20s'\n", lastc, lastc, readbufp);*/
1190 	setincmd(FALSE);
1191 	*tail = (cmd_t *) NULL;
1192 	return (list);
1193 }
1194 
1195 /*
1196  * Expand a list of target names using make macro definitions.
1197  */
1198 LOCAL int
exp_ovec(ovec,objcnt)1199 exp_ovec(ovec, objcnt)
1200 	obj_t	*ovec[];
1201 	int	objcnt;
1202 {
1203 		list_t	*list;
1204 		list_t	*l;
1205 	register list_t	**tail = &list;
1206 	int	i;
1207 
1208 	if (objcnt == 0)
1209 		return (0);
1210 	/*
1211 	 * Catch easy case.
1212 	 */
1213 	if (objcnt == 1 && (strchr(ovec[0]->o_name, '$') == NULL))
1214 		return (objcnt);
1215 
1216 	for (i = 0; i < objcnt; i++) {
1217 		tail = exp_list(ovec[i], tail);
1218 		*tail = (list_t *) NULL;
1219 	}
1220 
1221 	for (i = 0; list; i++) {
1222 		if (i >= MAXOBJS) {
1223 			warn("Too many expanded target items");
1224 			return (-i);
1225 		}
1226 		ovec[i] = list->l_obj;
1227 		l = list;
1228 		list = list->l_next;
1229 		fastfree((char *)l, sizeof (*l));
1230 	}
1231 	return (i);
1232 }
1233 
1234 /*
1235  * Read a list of target names.
1236  * Stop if ':', '=', ',' or space is found.
1237  */
1238 LOCAL int
read_ovec(ovec,typep)1239 read_ovec(ovec, typep)
1240 	obj_t	*ovec[];
1241 	int	*typep;
1242 {
1243 	obj_t	*o;
1244 	int	objcnt;
1245 	char	*p;
1246 	int	c;
1247 	BOOL	didwarn = FALSE;
1248 
1249 /*printf("read_ovec\n");*/
1250 	for (objcnt = 0; lastc != EOF; ) {
1251 		o = getobj();
1252 		c = lastc;
1253 		while (white(lastc))
1254 			getch();
1255 /*printf("lastc: '%c'", lastc); if (o) printf(" nameL %s\n", o->o_name);*/
1256 		if (o != (obj_t *) NULL) {
1257 			p = o->o_name;
1258 			if (p[0] == '+' && p[1] == '\0') {
1259 				if (c == '=') {
1260 					*typep = ADDMAC;
1261 					break;
1262 				} else if (c == ':' && peekch() == '=') {
1263 					getch();
1264 					*typep = ADD_VARMAC;
1265 					break;
1266 				}
1267 			}
1268 			if (objcnt >= MAXOBJS) {
1269 				warn("Too many target items");
1270 				return (-objcnt);
1271 			}
1272 			ovec[objcnt++] = o;
1273 		} else {
1274 			if (lastc == '\n') {
1275 				getch();
1276 				continue;
1277 			}
1278 			if (lastc == EOF && objcnt == 0)
1279 				break;
1280 			/*
1281 			 * Empty variable name or target.
1282 			 * The POSIX standard says that this is always illegal.
1283 			 * There are makefiles that include $(EMPTY): something
1284 			 * and we like to support them, so allow empty targets
1285 			 * with ':' and '::', but abort with '=', '+=' or ':='
1286 			 *
1287 			 * We come here only with a definitely empty list. An
1288 			 * empty list still can be created later if $(EMPTY)
1289 			 * gets expanded in exp_ovec() below.
1290 			 */
1291 			if (lastc != ':' || peekch() == '=')
1292 				exerror("Missing object name");
1293 			if (!nowarn(":")) {
1294 				warn("Missing object name");
1295 				didwarn = TRUE;
1296 			}
1297 		}
1298 		/*
1299 		 * end of definition:
1300 		 * colon, equal or end of line
1301 		 */
1302 		if (lastc == '?' && peekch() == '=') {
1303 			getch();
1304 			*typep = CONDEQUAL;
1305 			break;
1306 		}
1307 		if (lastc == ':' && peekch() == ':') {
1308 			getch();
1309 			if (lastc == ':' && peekch() == ':') {
1310 				getch();
1311 				if (peekch() == '=') {		/* :::= */
1312 					getch();
1313 					*typep = VAR_ASSIGN;
1314 					break;
1315 				} else {
1316 					ungetch(':');
1317 					lastc = ':';
1318 				}
1319 			}
1320 #ifdef	GNU_ASSIGN_BY_DEFAULT
1321 			if (
1322 #else
1323 			if (posixmode &&
1324 #endif
1325 			    lastc == ':' && peekch() == '=') {
1326 				getch();
1327 				*typep = GNU_ASSIGN;
1328 				break;
1329 			}
1330 			*typep = DCOLON;
1331 			break;
1332 		}
1333 		if (lastc == ':' && peekch() == '=') {
1334 			getch();
1335 			*typep = VAR_ASSIGN;	/* Use Sun CONDMACRO later */
1336 			if (!nowarn(":=")) {
1337 				warn(
1338 				"Nonportable ':=' assignment found for macro '%s'",
1339 				o ? o->o_name : "<empty>");
1340 			}
1341 			break;
1342 		}
1343 		if (lastc == ':' || lastc == '=' || lastc == '\n') {
1344 			*typep = lastc;
1345 			break;
1346 		}
1347 		if (lastc == ',')
1348 			getch();
1349 	}
1350 	/*
1351 	 * XXX Achtung: UNIX make expandiert alles was links und rechts von ':'
1352 	 * steht, sowie Variablennamen (links von '=').
1353 	 */
1354 	in_parser = -1;			/* In parser but no ::= expansion */
1355 	objcnt = exp_ovec(ovec, objcnt);
1356 	in_parser = 0;
1357 
1358 	if (didwarn)
1359 		*typep |= NWARN;
1360 	return (objcnt);
1361 }
1362 
1363 /*
1364  *
1365  */
1366 EXPORT list_t *
cvtvpath(l)1367 cvtvpath(l)
1368 	list_t	*l;
1369 {
1370 	list_t	*lsave;
1371 	list_t	*list = (list_t *)0;
1372 	list_t	**tail = &list;
1373 	char	vpath[NAMEMAX];
1374 	char	*vpe = &vpath[NAMEMAX-1];
1375 	char	*p1, *p2;
1376 
1377 	if (l != NULL) {
1378 		for (p1 = l->l_obj->o_name, p2 = vpath; *p1; p2++) {
1379 			if (p2 >= vpe)
1380 				break;
1381 			if ((*p2 = *p1++) == ':')
1382 				*p2 = ' ';
1383 		}
1384 		*p2 = '\0';
1385 		tail = mklist(vpath, tail, TRUE);
1386 		*tail = (list_t *) NULL;
1387 		lsave = l = list;
1388 
1389 		tail = &list;
1390 
1391 		for (; l; l = l->l_next) {
1392 			tail = listcat(l->l_obj, tail);
1393 			tail = listcat(l->l_obj, tail);
1394 		}
1395 		*tail = (list_t *) NULL;
1396 		freelist(lsave);
1397 	}
1398 	if (Do_Warn)
1399 		error("VPATH but no .SEARCHLIST\n");
1400 	return (list);
1401 }
1402 
1403 
1404 EXPORT BOOL
is_inlist(objname,name)1405 is_inlist(objname, name)
1406 	char	*objname;
1407 	char	*name;
1408 {
1409 	list_t	*l;
1410 
1411 	for (l = objlist(objname); l != NULL; l = l->l_next) {
1412 		if (streql(l->l_obj->o_name, name))
1413 			return (TRUE);
1414 	}
1415 	return (FALSE);
1416 }
1417 
1418 LOCAL BOOL
obj_in_list(obj,l)1419 obj_in_list(obj, l)
1420 	register obj_t	*obj;
1421 	register list_t	*l;
1422 {
1423 	while (l) {
1424 		if (obj == l->l_obj)
1425 			return (TRUE);
1426 		l = l->l_next;
1427 	}
1428 	return (FALSE);
1429 }
1430 
1431 EXPORT BOOL
nowarn(name)1432 nowarn(name)
1433 	char	*name;
1434 {
1435 	return (is_inlist(".NO_WARN", name));
1436 }
1437 
1438 /*
1439  * NOTE: as long as warn() and exerror() use the global vars
1440  * lineno, col and Mfileindex,
1441  * we cannot use them at any other time than parse time.
1442  */
1443 
1444 /*
1445  * Print a warning with text, line number, column and filename.
1446  */
1447 
1448 /* VARARGS1 */
1449 #ifdef	PROTOTYPES
1450 LOCAL void
warn(char * msg,...)1451 warn(char *msg, ...)
1452 #else
1453 LOCAL void
1454 warn(msg, va_alist)
1455 	char	*msg;
1456 	va_dcl
1457 #endif
1458 {
1459 	va_list	args;
1460 
1461 #ifdef	PROTOTYPES
1462 	va_start(args, msg);
1463 #else
1464 	va_start(args);
1465 #endif
1466 	if (!No_Warn)
1467 		errmsgno(EX_BAD,
1468 			"WARNING: %r in line %d col %d of '%s'\n", msg, args,
1469 				lineno, col, mfname);
1470 	va_end(args);
1471 }
1472 
1473 /*
1474  * Print an error message with text, line number, column and filename, then exit.
1475  */
1476 
1477 /* VARARGS1 */
1478 #ifdef	PROTOTYPES
1479 LOCAL void
exerror(char * msg,...)1480 exerror(char *msg, ...)
1481 #else
1482 LOCAL void
1483 exerror(msg, va_alist)
1484 	char	*msg;
1485 	va_dcl
1486 #endif
1487 {
1488 	va_list	args;
1489 	int	len;
1490 
1491 #ifdef	PROTOTYPES
1492 	va_start(args, msg);
1493 #else
1494 	va_start(args);
1495 #endif
1496 	errmsgno(EX_BAD, "%r in line %d col %d of '%s'\n", msg, args,
1497 			lineno, col, mfname);
1498 	va_end(args);
1499 
1500 	len = getrdbufsize();
1501 	if (len > 80)
1502 		len = 80;
1503 	if (Debug > 0)
1504 		errmsgno(EX_BAD, "Current read buffer is: '%.*s'\n", len, getrdbuf());
1505 	comerrno(EX_BAD, "Bad syntax in '%s'.\n", mfname);
1506 }
1507 
1508 
1509 #define	MyObjTabSize	128	/* # of Hash table entries (power of two) .*/
1510 
1511 #define	ObjHash(name, h)	{				\
1512 	register unsigned char *str = (unsigned char *)(name);	\
1513 	register int	sum = 0;				\
1514 	register int	i;					\
1515 	register int	c;					\
1516 								\
1517 	for (i = 0; (c = *str++) != '\0'; i++)			\
1518 		sum ^= (c << (i&7));				\
1519 	(h) = sum & (MyObjTabSize -1);				\
1520 }
1521 
1522 LOCAL	obj_t	*ObjTab[MyObjTabSize];
1523 LOCAL	obj_t	*SuffTab[MyObjTabSize];
1524 EXPORT	obj_t	*NullObj;
1525 
1526 /*
1527  * Look up name in 'table'.
1528  * First look up in hash table then do binary search.
1529  */
1530 LOCAL obj_t *
_objlook(table,name,create)1531 _objlook(table, name, create)
1532 	obj_t	*table[];
1533 	char	*name;
1534 	BOOL	create;
1535 {
1536 	register obj_t	**pp;
1537 	register obj_t	*p;
1538 	register char	*new;
1539 	register char	*old;
1540 		int	hash;
1541 
1542 	ObjHash(name, hash);
1543 	for (pp = &table[hash]; (p = *pp) != NULL; ) {
1544 		for (new = name, old = p->o_name; *new++ == *old; ) {
1545 			if (*old++ == '\0')	/* Found 'name' */
1546 				return (p);
1547 		}
1548 		if (*--new < *old)
1549 			pp = &p->o_left;
1550 		else
1551 			pp = &p->o_right;
1552 	}
1553 	if (!create)
1554 		return ((obj_t *) NULL);
1555 
1556 	/*
1557 	 * Add new entry to ObjTab.
1558 	 */
1559 	*pp = p = (obj_t *) fastalloc(sizeof (obj_t));	/* larger than list_t */
1560 							/* insert into list */
1561 	p->o_left = p->o_right = (obj_t *) NULL;	/* old 'p' was NULL */
1562 	p->o_cmd = (cmd_t *) NULL;
1563 	p->o_list = (list_t *) NULL;
1564 	p->o_date = NOTIME;
1565 	p->o_level = MAXLEVEL;
1566 	p->o_type = 0;
1567 	p->o_flags = 0;
1568 	p->o_flags = F_NEWNODE;
1569 	p->o_fileindex = Mfileindex;
1570 	p->o_name = strsave(name);
1571 	p->o_namelen = strlen(name);
1572 	p->o_node = NULL;
1573 	return (p);
1574 }
1575 
1576 /*
1577  * Look up name in ObjTab.
1578  */
1579 EXPORT obj_t *
objlook(name,create)1580 objlook(name, create)
1581 	char	*name;
1582 	BOOL	create;
1583 {
1584 	return (_objlook(ObjTab, name, create));
1585 }
1586 
1587 EXPORT list_t *
objlist(name)1588 objlist(name)
1589 	char	*name;
1590 {
1591 	obj_t	*o;
1592 
1593 	if ((o = objlook(name, FALSE)) == NULL)
1594 		return ((list_t *)NULL);
1595 	return (o->o_list);
1596 }
1597 
1598 /*
1599  * Look up name in SuffTab.
1600  */
1601 EXPORT obj_t *
ssufflook(name,create)1602 ssufflook(name, create)
1603 	char	*name;
1604 	BOOL	create;
1605 {
1606 	return (_objlook(SuffTab, name, create));
1607 }
1608 
1609 /*
1610  * Check is SuffTab contains any entry.
1611  */
1612 EXPORT BOOL
check_ssufftab()1613 check_ssufftab()
1614 {
1615 	int	i;
1616 
1617 	for (i = 0; i < MyObjTabSize; i++)
1618 		if (SuffTab[i])
1619 			return (TRUE);
1620 	return (FALSE);
1621 }
1622 
1623 /*
1624  * Clear all entries in SuffTab.
1625  */
1626 LOCAL void
clear_ssufftab()1627 clear_ssufftab()
1628 {
1629 	int	i;
1630 
1631 	for (i = 0; i < MyObjTabSize; i++)
1632 		SuffTab[i] = NULL;
1633 	SSuffrules = FALSE;
1634 }
1635 
1636 /*
1637  * Check whether obj->o_name is a Suffix Rule.
1638  * Name must either be identical to one of the .SUFFIXES (Single Suffix Rule)
1639  * or a concatenation of two .SUFFIXES.
1640  */
1641 LOCAL BOOL
is_suffix_rule(obj)1642 is_suffix_rule(obj)
1643 	register obj_t	*obj;
1644 {
1645 	list_t	*l;
1646 	list_t	*l2;
1647 	char	*suffix;
1648 	char	*rp;
1649 	int	rlen;
1650 
1651 	if (Suffixes == NULL)
1652 		return (FALSE);
1653 
1654 	for (l = Suffixes; l; l = l->l_next) {
1655 		suffix = l->l_obj->o_name;
1656 		rlen = strlen(suffix);
1657 		if (strncmp(obj->o_name, suffix, rlen) == 0) {
1658 			rp = &obj->o_name[rlen];
1659 
1660 			if (*rp == '\0')	/* Single Suffix Rule */
1661 				return (TRUE);
1662 
1663 			for (l2 = Suffixes; l2; l2 = l2->l_next) {
1664 				if (streql(rp, l2->l_obj->o_name))
1665 					return (TRUE);
1666 			}
1667 		}
1668 	}
1669 	return (FALSE);
1670 }
1671 
1672 /*
1673  * Used by ptree() to print one single object.
1674  */
1675 LOCAL void
prvar(p)1676 prvar(p)
1677 	register obj_t	*p;
1678 {
1679 	register list_t	*q;
1680 	register cmd_t	*c;
1681 
1682 	if (!p)
1683 		return;
1684 
1685 	error("%s:", p->o_name);
1686 	for (q = p->o_list; q; q = q->l_next)
1687 		error(" %s", q->l_obj->o_name);
1688 	putc('\n', stderr);
1689 	for (c = p->o_cmd; c; c = c->c_next)
1690 		error("\t...%s\n", c->c_line);
1691 }
1692 
1693 /*
1694  * Currently only used by printtree() to implement the -probj option.
1695  */
1696 LOCAL void
ptree(p,n)1697 ptree(p, n)
1698 	register obj_t	*p;
1699 		int	n;
1700 {
1701 	register int	i;
1702 
1703 	for (; p; p = p->o_right) {
1704 		ptree(p->o_left, ++n);
1705 		for (i = 1; i < n; i++)
1706 			putc(' ', stderr);
1707 		prvar(p);
1708 	}
1709 }
1710 
1711 /*
1712  * Used by -probj Flag
1713  */
1714 EXPORT void
printtree()1715 printtree()
1716 {
1717 	int	i;
1718 
1719 	print_patrules(stderr);
1720 	for (i = 0; i < MyObjTabSize; i++)
1721 		ptree(ObjTab[i], 0);
1722 }
1723 
1724 /*
1725  * Currently only used by prtree() to implement the -p option.
1726  */
1727 #define	SUFF_ONLY	1	/* Print only Suffix Rules	*/
1728 #define	SUFF_SPECIAL	2	/* Print only special targets	*/
1729 #define	SUFF_NONE	0	/* Print only plain target rules */
1730 #define	SUFF_ANY	-1	/* Print without filtering	*/
1731 EXPORT void
probj(f,o,type,dosuff)1732 probj(f, o, type, dosuff)
1733 	FILE	*f;
1734 	obj_t	*o;
1735 	int	type;
1736 	int	dosuff;
1737 {
1738 	for (; o; o = o->o_right) {
1739 		probj(f, o->o_left, type, dosuff);
1740 		if (type >= 0 && type != o->o_type)
1741 			continue;
1742 		if (type < 0 && (o->o_type == ':' || o->o_type == '='))
1743 			continue;
1744 		if (Debug <= 0 && o->o_type == 0)
1745 			continue;	/* Ommit target only strings */
1746 
1747 		if (dosuff >= 0) {
1748 			if (dosuff == SUFF_ONLY && !is_suffix_rule(o))
1749 				continue;
1750 			else if (dosuff == SUFF_NONE && (is_suffix_rule(o) ||
1751 			    !(o->o_name[0] != '.' || o->o_name[1] == SLASH ||
1752 			    (o->o_name[1] == '.' && o->o_name[2] == SLASH))))
1753 				continue;
1754 			else if (dosuff == SUFF_SPECIAL && (is_suffix_rule(o) ||
1755 			    (o->o_name[0] != '.' || o->o_name[1] == SLASH ||
1756 			    (o->o_name[1] == '.' && o->o_name[2] == SLASH))))
1757 				continue;
1758 
1759 		}
1760 
1761 		printobj(f, &o, 1, o->o_type, o->o_list, o->o_cmd);
1762 	}
1763 }
1764 
1765 /*
1766  * Used by -p Flag, called from main().
1767  */
1768 EXPORT void
prtree()1769 prtree()
1770 {
1771 	int	i;
1772 
1773 	printf("# Implicit Pattern Rules:\n");
1774 	print_patrules(stdout);
1775 	printf("# Implicit Suffix Rules:\n");
1776 	for (i = 0; i < MyObjTabSize; i++) {
1777 		probj(stdout, ObjTab[i], ':', SUFF_ONLY);
1778 	}
1779 	printf("# Simple Suffix Rules:\n");
1780 	for (i = 0; i < MyObjTabSize; i++) {
1781 		probj(stdout, SuffTab[i], ':', SUFF_ANY);
1782 	}
1783 	printf("# Special Targets:\n");
1784 	for (i = 0; i < MyObjTabSize; i++) {
1785 		probj(stdout, ObjTab[i], ':',  SUFF_SPECIAL);
1786 	}
1787 	printf("# Target Rules:\n");
1788 	for (i = 0; i < MyObjTabSize; i++) {
1789 		probj(stdout, ObjTab[i], ':',  SUFF_NONE);
1790 	}
1791 	printf("# Macro definitions:\n");
1792 	for (i = 0; i < MyObjTabSize; i++) {
1793 		probj(stdout, ObjTab[i], '=', SUFF_ANY);
1794 	}
1795 	printf("# Various other definitions:\n");
1796 	for (i = 0; i < MyObjTabSize; i++) {
1797 		probj(stdout, ObjTab[i], -1, SUFF_ANY);
1798 	}
1799 }
1800 
1801 /*
1802  * Convert the object type into a human readable string.
1803  */
1804 LOCAL char *
typestr(type)1805 typestr(type)
1806 	int	type;
1807 {
1808 	if (type == 0)
1809 		return ("(%)");
1810 	if (type == EQUAL)
1811 		return ("=");
1812 	if (type == COLON)
1813 		return (":");
1814 	if (type == DCOLON)
1815 		return ("::");
1816 	if (type == SEMI)
1817 		return (";");
1818 	if (type == CONDEQUAL)
1819 		return ("?=");
1820 	if (type == ADDMAC)
1821 		return ("+=");
1822 	if (type == ADD_VARMAC)
1823 		return ("+:=");
1824 	if (type == GNU_ASSIGN)
1825 		return ("::=");
1826 	if (type == VAR_ASSIGN)
1827 		return (":::=");
1828 	if (type == CONDMACRO)
1829 		return (":=");
1830 	if (type == SHVAR)
1831 		return (":sh=");
1832 	return ("UNKNOWN TYPE");
1833 }
1834 
1835 /*
1836  * This is the central routine to print an object.
1837  */
1838 LOCAL void
printobj(f,ovec,objcnt,type,deplist,cmdlist)1839 printobj(f, ovec, objcnt, type, deplist, cmdlist)
1840 	FILE	*f;
1841 	obj_t	*ovec[];
1842 	int	objcnt;
1843 	int	type;
1844 	list_t	*deplist;
1845 	cmd_t	*cmdlist;
1846 {
1847 	register	list_t	*l;
1848 	register	cmd_t	*c;
1849 	register	int	i;
1850 
1851 	for (i = 0; i < objcnt; i++)
1852 		fprintf(f, "%s ", ovec[i]->o_name);
1853 	fprintf(f, "%2s\t", typestr(type));
1854 
1855 	for (l = deplist; l; l = l->l_next)
1856 		fprintf(f, "%s ", l->l_obj->o_name);
1857 	fprintf(f, "\n");
1858 
1859 	for (c = cmdlist; c; c = c->c_next)
1860 		fprintf(f, "\t%s\n", c->c_line);
1861 	fflush(f);
1862 }
1863