xref: /titanic_51/usr/src/cmd/make/bin/doname.cc (revision 10d63b7db37a83b39c7f511cf9426c9d03ea0760)
1*10d63b7dSRichard Lowe /*
2*10d63b7dSRichard Lowe  * CDDL HEADER START
3*10d63b7dSRichard Lowe  *
4*10d63b7dSRichard Lowe  * The contents of this file are subject to the terms of the
5*10d63b7dSRichard Lowe  * Common Development and Distribution License (the "License").
6*10d63b7dSRichard Lowe  * You may not use this file except in compliance with the License.
7*10d63b7dSRichard Lowe  *
8*10d63b7dSRichard Lowe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10d63b7dSRichard Lowe  * or http://www.opensolaris.org/os/licensing.
10*10d63b7dSRichard Lowe  * See the License for the specific language governing permissions
11*10d63b7dSRichard Lowe  * and limitations under the License.
12*10d63b7dSRichard Lowe  *
13*10d63b7dSRichard Lowe  * When distributing Covered Code, include this CDDL HEADER in each
14*10d63b7dSRichard Lowe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10d63b7dSRichard Lowe  * If applicable, add the following below this CDDL HEADER, with the
16*10d63b7dSRichard Lowe  * fields enclosed by brackets "[]" replaced with your own identifying
17*10d63b7dSRichard Lowe  * information: Portions Copyright [yyyy] [name of copyright owner]
18*10d63b7dSRichard Lowe  *
19*10d63b7dSRichard Lowe  * CDDL HEADER END
20*10d63b7dSRichard Lowe  */
21*10d63b7dSRichard Lowe /*
22*10d63b7dSRichard Lowe  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23*10d63b7dSRichard Lowe  * Use is subject to license terms.
24*10d63b7dSRichard Lowe  */
25*10d63b7dSRichard Lowe 
26*10d63b7dSRichard Lowe /*
27*10d63b7dSRichard Lowe  *	doname.c
28*10d63b7dSRichard Lowe  *
29*10d63b7dSRichard Lowe  *	Figure out which targets are out of date and rebuild them
30*10d63b7dSRichard Lowe  */
31*10d63b7dSRichard Lowe 
32*10d63b7dSRichard Lowe /*
33*10d63b7dSRichard Lowe  * Included files
34*10d63b7dSRichard Lowe  */
35*10d63b7dSRichard Lowe #include <alloca.h>		/* alloca() */
36*10d63b7dSRichard Lowe #include <fcntl.h>
37*10d63b7dSRichard Lowe #include <mk/defs.h>
38*10d63b7dSRichard Lowe #include <mksh/i18n.h>		/* get_char_semantics_value() */
39*10d63b7dSRichard Lowe #include <mksh/macro.h>		/* getvar(), expand_value() */
40*10d63b7dSRichard Lowe #include <mksh/misc.h>		/* getmem() */
41*10d63b7dSRichard Lowe #include <poll.h>
42*10d63b7dSRichard Lowe #include <libintl.h>
43*10d63b7dSRichard Lowe #include <signal.h>
44*10d63b7dSRichard Lowe #include <stropts.h>
45*10d63b7dSRichard Lowe #include <sys/errno.h>
46*10d63b7dSRichard Lowe #include <sys/stat.h>
47*10d63b7dSRichard Lowe #include <sys/types.h>
48*10d63b7dSRichard Lowe #include <sys/utsname.h>	/* uname() */
49*10d63b7dSRichard Lowe #include <sys/wait.h>
50*10d63b7dSRichard Lowe #include <unistd.h>		/* close() */
51*10d63b7dSRichard Lowe 
52*10d63b7dSRichard Lowe /*
53*10d63b7dSRichard Lowe  * Defined macros
54*10d63b7dSRichard Lowe  */
55*10d63b7dSRichard Lowe #	define LOCALHOST "localhost"
56*10d63b7dSRichard Lowe 
57*10d63b7dSRichard Lowe #define MAXRULES 100
58*10d63b7dSRichard Lowe 
59*10d63b7dSRichard Lowe // Sleep for .1 seconds between stat()'s
60*10d63b7dSRichard Lowe const int	STAT_RETRY_SLEEP_TIME = 100000;
61*10d63b7dSRichard Lowe 
62*10d63b7dSRichard Lowe /*
63*10d63b7dSRichard Lowe  * typedefs & structs
64*10d63b7dSRichard Lowe  */
65*10d63b7dSRichard Lowe 
66*10d63b7dSRichard Lowe /*
67*10d63b7dSRichard Lowe  * Static variables
68*10d63b7dSRichard Lowe  */
69*10d63b7dSRichard Lowe static char	hostName[MAXNAMELEN] = "";
70*10d63b7dSRichard Lowe static char	userName[MAXNAMELEN] = "";
71*10d63b7dSRichard Lowe 
72*10d63b7dSRichard Lowe 
73*10d63b7dSRichard Lowe static int	second_pass = 0;
74*10d63b7dSRichard Lowe 
75*10d63b7dSRichard Lowe /*
76*10d63b7dSRichard Lowe  * File table of contents
77*10d63b7dSRichard Lowe  */
78*10d63b7dSRichard Lowe extern	Doname		doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
79*10d63b7dSRichard Lowe extern	Doname		doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
80*10d63b7dSRichard Lowe static	Boolean		check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals);
81*10d63b7dSRichard Lowe void		dynamic_dependencies(Name target);
82*10d63b7dSRichard Lowe static	Doname		run_command(register Property line, Boolean print_machine);
83*10d63b7dSRichard Lowe extern	Doname		execute_serial(Property line);
84*10d63b7dSRichard Lowe extern	Name		vpath_translation(register Name cmd);
85*10d63b7dSRichard Lowe extern	void		check_state(Name temp_file_name);
86*10d63b7dSRichard Lowe static	void		read_dependency_file(register Name filename);
87*10d63b7dSRichard Lowe static	void		check_read_state_file(void);
88*10d63b7dSRichard Lowe static	void		do_assign(register Name line, register Name target);
89*10d63b7dSRichard Lowe static	void		build_command_strings(Name target, register Property line);
90*10d63b7dSRichard Lowe static	Doname		touch_command(register Property line, register Name target, Doname result);
91*10d63b7dSRichard Lowe extern	void		update_target(Property line, Doname result);
92*10d63b7dSRichard Lowe static	Doname		sccs_get(register Name target, register Property *command);
93*10d63b7dSRichard Lowe extern	void		read_directory_of_file(register Name file);
94*10d63b7dSRichard Lowe static	void		add_pattern_conditionals(register Name target);
95*10d63b7dSRichard Lowe extern	void		set_locals(register Name target, register Property old_locals);
96*10d63b7dSRichard Lowe extern	void		reset_locals(register Name target, register Property old_locals, register Property conditional, register int index);
97*10d63b7dSRichard Lowe extern	Boolean		check_auto_dependencies(Name target, int auto_count, Name *automatics);
98*10d63b7dSRichard Lowe static	void		delete_query_chain(Chain ch);
99*10d63b7dSRichard Lowe 
100*10d63b7dSRichard Lowe // From read2.cc
101*10d63b7dSRichard Lowe extern	Name		normalize_name(register wchar_t *name_string, register int length);
102*10d63b7dSRichard Lowe 
103*10d63b7dSRichard Lowe 
104*10d63b7dSRichard Lowe 
105*10d63b7dSRichard Lowe /*
106*10d63b7dSRichard Lowe  * DONE.
107*10d63b7dSRichard Lowe  *
108*10d63b7dSRichard Lowe  *	doname_check(target, do_get, implicit, automatic)
109*10d63b7dSRichard Lowe  *
110*10d63b7dSRichard Lowe  *	Will call doname() and then inspect the return value
111*10d63b7dSRichard Lowe  *
112*10d63b7dSRichard Lowe  *	Return value:
113*10d63b7dSRichard Lowe  *				Indication if the build failed or not
114*10d63b7dSRichard Lowe  *
115*10d63b7dSRichard Lowe  *	Parameters:
116*10d63b7dSRichard Lowe  *		target		The target to build
117*10d63b7dSRichard Lowe  *		do_get		Passed thru to doname()
118*10d63b7dSRichard Lowe  *		implicit	Passed thru to doname()
119*10d63b7dSRichard Lowe  *		automatic	Are we building a hidden dependency?
120*10d63b7dSRichard Lowe  *
121*10d63b7dSRichard Lowe  *	Global variables used:
122*10d63b7dSRichard Lowe  *		build_failed_seen	Set if -k is on and error occurs
123*10d63b7dSRichard Lowe  *		continue_after_error	Indicates that -k is on
124*10d63b7dSRichard Lowe  *		report_dependencies	No error msg if -P is on
125*10d63b7dSRichard Lowe  */
126*10d63b7dSRichard Lowe Doname
127*10d63b7dSRichard Lowe doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
128*10d63b7dSRichard Lowe {
129*10d63b7dSRichard Lowe 	int first_time = 1;
130*10d63b7dSRichard Lowe 	(void) fflush(stdout);
131*10d63b7dSRichard Lowe try_again:
132*10d63b7dSRichard Lowe 	switch (doname(target, do_get, implicit, automatic)) {
133*10d63b7dSRichard Lowe 	case build_ok:
134*10d63b7dSRichard Lowe 		second_pass = 0;
135*10d63b7dSRichard Lowe 		return build_ok;
136*10d63b7dSRichard Lowe 	case build_running:
137*10d63b7dSRichard Lowe 		second_pass = 0;
138*10d63b7dSRichard Lowe 		return build_running;
139*10d63b7dSRichard Lowe 	case build_failed:
140*10d63b7dSRichard Lowe 		if (!continue_after_error) {
141*10d63b7dSRichard Lowe 			fatal(gettext("Target `%s' not remade because of errors"),
142*10d63b7dSRichard Lowe 			      target->string_mb);
143*10d63b7dSRichard Lowe 		}
144*10d63b7dSRichard Lowe 		build_failed_seen = true;
145*10d63b7dSRichard Lowe 		second_pass = 0;
146*10d63b7dSRichard Lowe 		return build_failed;
147*10d63b7dSRichard Lowe 	case build_dont_know:
148*10d63b7dSRichard Lowe 		/*
149*10d63b7dSRichard Lowe 		 * If we can't figure out how to build an automatic
150*10d63b7dSRichard Lowe 		 * (hidden) dependency, we just ignore it.
151*10d63b7dSRichard Lowe 		 * We later declare the target to be out of date just in
152*10d63b7dSRichard Lowe 		 * case something changed.
153*10d63b7dSRichard Lowe 		 * Also, don't complain if just reporting the dependencies
154*10d63b7dSRichard Lowe 		 * and not building anything.
155*10d63b7dSRichard Lowe 		 */
156*10d63b7dSRichard Lowe 		if (automatic || (report_dependencies_level > 0)) {
157*10d63b7dSRichard Lowe 			second_pass = 0;
158*10d63b7dSRichard Lowe 			return build_dont_know;
159*10d63b7dSRichard Lowe 		}
160*10d63b7dSRichard Lowe 		if(first_time) {
161*10d63b7dSRichard Lowe 			first_time = 0;
162*10d63b7dSRichard Lowe 			second_pass = 1;
163*10d63b7dSRichard Lowe 			goto try_again;
164*10d63b7dSRichard Lowe 		}
165*10d63b7dSRichard Lowe 		second_pass = 0;
166*10d63b7dSRichard Lowe 		if (continue_after_error && !svr4) {
167*10d63b7dSRichard Lowe 			warning(gettext("Don't know how to make target `%s'"),
168*10d63b7dSRichard Lowe 				target->string_mb);
169*10d63b7dSRichard Lowe 			build_failed_seen = true;
170*10d63b7dSRichard Lowe 			return build_failed;
171*10d63b7dSRichard Lowe 		}
172*10d63b7dSRichard Lowe 		fatal(gettext("Don't know how to make target `%s'"), target->string_mb);
173*10d63b7dSRichard Lowe 		break;
174*10d63b7dSRichard Lowe 	}
175*10d63b7dSRichard Lowe #ifdef lint
176*10d63b7dSRichard Lowe 	return build_failed;
177*10d63b7dSRichard Lowe #endif
178*10d63b7dSRichard Lowe }
179*10d63b7dSRichard Lowe 
180*10d63b7dSRichard Lowe 
181*10d63b7dSRichard Lowe void
182*10d63b7dSRichard Lowe enter_explicit_rule_from_dynamic_rule(Name target, Name source)
183*10d63b7dSRichard Lowe {
184*10d63b7dSRichard Lowe 	Property line, source_line;
185*10d63b7dSRichard Lowe 	Dependency dependency;
186*10d63b7dSRichard Lowe 
187*10d63b7dSRichard Lowe 	source_line = get_prop(source->prop, line_prop);
188*10d63b7dSRichard Lowe 	line = maybe_append_prop(target, line_prop);
189*10d63b7dSRichard Lowe 	line->body.line.sccs_command = false;
190*10d63b7dSRichard Lowe 	line->body.line.target = target;
191*10d63b7dSRichard Lowe 	if (line->body.line.command_template == NULL) {
192*10d63b7dSRichard Lowe 		line->body.line.command_template = source_line->body.line.command_template;
193*10d63b7dSRichard Lowe 		for (dependency = source_line->body.line.dependencies;
194*10d63b7dSRichard Lowe 		     dependency != NULL;
195*10d63b7dSRichard Lowe 		     dependency = dependency->next) {
196*10d63b7dSRichard Lowe 			enter_dependency(line, dependency->name, false);
197*10d63b7dSRichard Lowe 		}
198*10d63b7dSRichard Lowe 		line->body.line.less = target;
199*10d63b7dSRichard Lowe 	}
200*10d63b7dSRichard Lowe 	line->body.line.percent = NULL;
201*10d63b7dSRichard Lowe }
202*10d63b7dSRichard Lowe 
203*10d63b7dSRichard Lowe 
204*10d63b7dSRichard Lowe 
205*10d63b7dSRichard Lowe Name
206*10d63b7dSRichard Lowe find_dyntarget(Name target)
207*10d63b7dSRichard Lowe {
208*10d63b7dSRichard Lowe 	Dyntarget		p;
209*10d63b7dSRichard Lowe 	int			i;
210*10d63b7dSRichard Lowe 	String_rec		string;
211*10d63b7dSRichard Lowe 	wchar_t			buffer[STRING_BUFFER_LENGTH];
212*10d63b7dSRichard Lowe 	wchar_t			*pp, * bufend;
213*10d63b7dSRichard Lowe 	wchar_t			tbuffer[MAXPATHLEN];
214*10d63b7dSRichard Lowe 	Wstring			wcb(target);
215*10d63b7dSRichard Lowe 
216*10d63b7dSRichard Lowe 	for (p = dyntarget_list; p != NULL; p = p->next) {
217*10d63b7dSRichard Lowe 		INIT_STRING_FROM_STACK(string, buffer);
218*10d63b7dSRichard Lowe 		expand_value(p->name, &string, false);
219*10d63b7dSRichard Lowe 		i = 0;
220*10d63b7dSRichard Lowe 		pp = string.buffer.start;
221*10d63b7dSRichard Lowe 		bufend = pp + STRING_BUFFER_LENGTH;
222*10d63b7dSRichard Lowe 		while((*pp != nul_char) && (pp < bufend)) {
223*10d63b7dSRichard Lowe 			if(iswspace(*pp)) {
224*10d63b7dSRichard Lowe 				tbuffer[i] = nul_char;
225*10d63b7dSRichard Lowe 				if(i > 0) {
226*10d63b7dSRichard Lowe 					if (wcb.equal(tbuffer)) {
227*10d63b7dSRichard Lowe 						enter_explicit_rule_from_dynamic_rule(target, p->name);
228*10d63b7dSRichard Lowe 						return(target);
229*10d63b7dSRichard Lowe 					}
230*10d63b7dSRichard Lowe 				}
231*10d63b7dSRichard Lowe 				pp++;
232*10d63b7dSRichard Lowe 				i = 0;
233*10d63b7dSRichard Lowe 				continue;
234*10d63b7dSRichard Lowe 			}
235*10d63b7dSRichard Lowe 			tbuffer[i] = *pp;
236*10d63b7dSRichard Lowe 			i++;
237*10d63b7dSRichard Lowe 			pp++;
238*10d63b7dSRichard Lowe 			if(*pp == nul_char) {
239*10d63b7dSRichard Lowe 				tbuffer[i] = nul_char;
240*10d63b7dSRichard Lowe 				if(i > 0) {
241*10d63b7dSRichard Lowe 					if (wcb.equal(tbuffer)) {
242*10d63b7dSRichard Lowe 						enter_explicit_rule_from_dynamic_rule(target, p->name);
243*10d63b7dSRichard Lowe 						return(target);
244*10d63b7dSRichard Lowe 					}
245*10d63b7dSRichard Lowe 				}
246*10d63b7dSRichard Lowe 				break;
247*10d63b7dSRichard Lowe 			}
248*10d63b7dSRichard Lowe 		}
249*10d63b7dSRichard Lowe 	}
250*10d63b7dSRichard Lowe 	return(NULL);
251*10d63b7dSRichard Lowe }
252*10d63b7dSRichard Lowe 
253*10d63b7dSRichard Lowe /*
254*10d63b7dSRichard Lowe  * DONE.
255*10d63b7dSRichard Lowe  *
256*10d63b7dSRichard Lowe  *	doname(target, do_get, implicit)
257*10d63b7dSRichard Lowe  *
258*10d63b7dSRichard Lowe  *	Chases all files the target depends on and builds any that
259*10d63b7dSRichard Lowe  *	are out of date. If the target is out of date it is then rebuilt.
260*10d63b7dSRichard Lowe  *
261*10d63b7dSRichard Lowe  *	Return value:
262*10d63b7dSRichard Lowe  *				Indiates if build failed or nt
263*10d63b7dSRichard Lowe  *
264*10d63b7dSRichard Lowe  *	Parameters:
265*10d63b7dSRichard Lowe  *		target		Target to build
266*10d63b7dSRichard Lowe  *		do_get		Run sccs get is nessecary
267*10d63b7dSRichard Lowe  *		implicit	doname is trying to find an implicit rule
268*10d63b7dSRichard Lowe  *
269*10d63b7dSRichard Lowe  *	Global variables used:
270*10d63b7dSRichard Lowe  *		assign_done	True if command line assgnment has happened
271*10d63b7dSRichard Lowe  *		commands_done	Preserved for the case that we need local value
272*10d63b7dSRichard Lowe  *		debug_level	Should we trace make's actions?
273*10d63b7dSRichard Lowe  *		default_rule	The rule for ".DEFAULT", used as last resort
274*10d63b7dSRichard Lowe  *		empty_name	The Name "", used when looking for single sfx
275*10d63b7dSRichard Lowe  *		keep_state	Indicates that .KEEP_STATE is on
276*10d63b7dSRichard Lowe  *		parallel	True if building in parallel
277*10d63b7dSRichard Lowe  *		recursion_level	Used for tracing
278*10d63b7dSRichard Lowe  *		report_dependencies make -P is on
279*10d63b7dSRichard Lowe  */
280*10d63b7dSRichard Lowe Doname
281*10d63b7dSRichard Lowe doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
282*10d63b7dSRichard Lowe {
283*10d63b7dSRichard Lowe 	Doname			result = build_dont_know;
284*10d63b7dSRichard Lowe 	Chain			out_of_date_list = NULL;
285*10d63b7dSRichard Lowe 	Chain			target_group;
286*10d63b7dSRichard Lowe 	Property		old_locals = NULL;
287*10d63b7dSRichard Lowe 	register Property	line;
288*10d63b7dSRichard Lowe 	Property		command = NULL;
289*10d63b7dSRichard Lowe 	register Dependency	dependency;
290*10d63b7dSRichard Lowe 	Name			less = NULL;
291*10d63b7dSRichard Lowe 	Name			true_target = target;
292*10d63b7dSRichard Lowe 	Name			*automatics = NULL;
293*10d63b7dSRichard Lowe 	register int		auto_count;
294*10d63b7dSRichard Lowe 	Boolean			rechecking_target = false;
295*10d63b7dSRichard Lowe 	Boolean			saved_commands_done;
296*10d63b7dSRichard Lowe 	Boolean			restart = false;
297*10d63b7dSRichard Lowe 	Boolean			save_parallel = parallel;
298*10d63b7dSRichard Lowe 	Boolean			doing_subtree = false;
299*10d63b7dSRichard Lowe 
300*10d63b7dSRichard Lowe 	Boolean			recheck_conditionals = false;
301*10d63b7dSRichard Lowe 
302*10d63b7dSRichard Lowe 	if (target->state == build_running) {
303*10d63b7dSRichard Lowe 		return build_running;
304*10d63b7dSRichard Lowe 	}
305*10d63b7dSRichard Lowe 	line = get_prop(target->prop, line_prop);
306*10d63b7dSRichard Lowe 	if (line != NULL) {
307*10d63b7dSRichard Lowe 		/*
308*10d63b7dSRichard Lowe 		 * If this target is a member of target group and one of the
309*10d63b7dSRichard Lowe 		 * other members of the group is running, mark this target
310*10d63b7dSRichard Lowe 		 * as running.
311*10d63b7dSRichard Lowe 		 */
312*10d63b7dSRichard Lowe 		for (target_group = line->body.line.target_group;
313*10d63b7dSRichard Lowe 		     target_group != NULL;
314*10d63b7dSRichard Lowe 		     target_group = target_group->next) {
315*10d63b7dSRichard Lowe 			if (is_running(target_group->name)) {
316*10d63b7dSRichard Lowe 				target->state = build_running;
317*10d63b7dSRichard Lowe 				add_pending(target,
318*10d63b7dSRichard Lowe 					    recursion_level,
319*10d63b7dSRichard Lowe 					    do_get,
320*10d63b7dSRichard Lowe 					    implicit,
321*10d63b7dSRichard Lowe 					    false);
322*10d63b7dSRichard Lowe 				return build_running;
323*10d63b7dSRichard Lowe 			}
324*10d63b7dSRichard Lowe 		}
325*10d63b7dSRichard Lowe 	}
326*10d63b7dSRichard Lowe 	/*
327*10d63b7dSRichard Lowe 	 * If the target is a constructed one for a "::" target,
328*10d63b7dSRichard Lowe 	 * we need to consider that.
329*10d63b7dSRichard Lowe 	 */
330*10d63b7dSRichard Lowe 	if (target->has_target_prop) {
331*10d63b7dSRichard Lowe 		true_target = get_prop(target->prop,
332*10d63b7dSRichard Lowe 				       target_prop)->body.target.target;
333*10d63b7dSRichard Lowe 		if (true_target->colon_splits > 0) {
334*10d63b7dSRichard Lowe 			/* Make sure we have a valid time for :: targets */
335*10d63b7dSRichard Lowe 			Property        time;
336*10d63b7dSRichard Lowe 
337*10d63b7dSRichard Lowe 			time = get_prop(true_target->prop, time_prop);
338*10d63b7dSRichard Lowe 			if (time != NULL) {
339*10d63b7dSRichard Lowe 				true_target->stat.time = time->body.time.time;
340*10d63b7dSRichard Lowe 			}
341*10d63b7dSRichard Lowe 		}
342*10d63b7dSRichard Lowe 	}
343*10d63b7dSRichard Lowe 	(void) exists(true_target);
344*10d63b7dSRichard Lowe 	/*
345*10d63b7dSRichard Lowe 	 * If the target has been processed, we don't need to do it again,
346*10d63b7dSRichard Lowe 	 * unless it depends on conditional macros or a delayed assignment,
347*10d63b7dSRichard Lowe 	 * or it has been done when KEEP_STATE is on.
348*10d63b7dSRichard Lowe 	 */
349*10d63b7dSRichard Lowe 	if (target->state == build_ok) {
350*10d63b7dSRichard Lowe 		if((!keep_state || (!target->depends_on_conditional && !assign_done))) {
351*10d63b7dSRichard Lowe 			return build_ok;
352*10d63b7dSRichard Lowe 		} else {
353*10d63b7dSRichard Lowe 			recheck_conditionals = true;
354*10d63b7dSRichard Lowe 		}
355*10d63b7dSRichard Lowe   	}
356*10d63b7dSRichard Lowe 	if (target->state == build_subtree) {
357*10d63b7dSRichard Lowe 		/* A dynamic macro subtree is being built */
358*10d63b7dSRichard Lowe 		target->state = build_dont_know;
359*10d63b7dSRichard Lowe 		doing_subtree = true;
360*10d63b7dSRichard Lowe 		if (!target->checking_subtree) {
361*10d63b7dSRichard Lowe 			/*
362*10d63b7dSRichard Lowe 			 * This target has been started before and therefore
363*10d63b7dSRichard Lowe 			 * not all dependencies have to be built.
364*10d63b7dSRichard Lowe 			 */
365*10d63b7dSRichard Lowe 			restart = true;
366*10d63b7dSRichard Lowe 		}
367*10d63b7dSRichard Lowe 	} else if (target->state == build_pending) {
368*10d63b7dSRichard Lowe 		target->state = build_dont_know;
369*10d63b7dSRichard Lowe 		restart = true;
370*10d63b7dSRichard Lowe /*
371*10d63b7dSRichard Lowe 	} else if (parallel &&
372*10d63b7dSRichard Lowe 		   keep_state &&
373*10d63b7dSRichard Lowe 		   (target->conditional_cnt > 0)) {
374*10d63b7dSRichard Lowe 	    if (!parallel_ok(target, false)) {
375*10d63b7dSRichard Lowe 		add_subtree(target, recursion_level, do_get, implicit);
376*10d63b7dSRichard Lowe 		target->state = build_running;
377*10d63b7dSRichard Lowe 		return build_running;
378*10d63b7dSRichard Lowe 	    }
379*10d63b7dSRichard Lowe  */
380*10d63b7dSRichard Lowe 	}
381*10d63b7dSRichard Lowe 	/*
382*10d63b7dSRichard Lowe 	 * If KEEP_STATE is on, we have to rebuild the target if the
383*10d63b7dSRichard Lowe 	 * building of it caused new automatic dependencies to be reported.
384*10d63b7dSRichard Lowe 	 * This is where we restart the build.
385*10d63b7dSRichard Lowe 	 */
386*10d63b7dSRichard Lowe 	if (line != NULL) {
387*10d63b7dSRichard Lowe 		line->body.line.percent = NULL;
388*10d63b7dSRichard Lowe 	}
389*10d63b7dSRichard Lowe recheck_target:
390*10d63b7dSRichard Lowe 	/* Init all local variables */
391*10d63b7dSRichard Lowe 	result = build_dont_know;
392*10d63b7dSRichard Lowe 	out_of_date_list = NULL;
393*10d63b7dSRichard Lowe 	command = NULL;
394*10d63b7dSRichard Lowe 	less = NULL;
395*10d63b7dSRichard Lowe 	auto_count = 0;
396*10d63b7dSRichard Lowe 	if (!restart && line != NULL) {
397*10d63b7dSRichard Lowe 		/*
398*10d63b7dSRichard Lowe 		 * If this target has never been built before, mark all
399*10d63b7dSRichard Lowe 		 * of the dependencies as never built.
400*10d63b7dSRichard Lowe 		 */
401*10d63b7dSRichard Lowe 		for (dependency = line->body.line.dependencies;
402*10d63b7dSRichard Lowe 		     dependency != NULL;
403*10d63b7dSRichard Lowe 		     dependency = dependency->next) {
404*10d63b7dSRichard Lowe 			dependency->built = false;
405*10d63b7dSRichard Lowe 		}
406*10d63b7dSRichard Lowe 	}
407*10d63b7dSRichard Lowe 	/* Save the set of automatic depes defined for this target */
408*10d63b7dSRichard Lowe 	if (keep_state &&
409*10d63b7dSRichard Lowe 	    (line != NULL) &&
410*10d63b7dSRichard Lowe 	    (line->body.line.dependencies != NULL)) {
411*10d63b7dSRichard Lowe 		Name *p;
412*10d63b7dSRichard Lowe 
413*10d63b7dSRichard Lowe 		/*
414*10d63b7dSRichard Lowe 		 * First run thru the dependency list to see how many
415*10d63b7dSRichard Lowe 		 * autos there are.
416*10d63b7dSRichard Lowe 		 */
417*10d63b7dSRichard Lowe 		for (dependency = line->body.line.dependencies;
418*10d63b7dSRichard Lowe 		     dependency != NULL;
419*10d63b7dSRichard Lowe 		     dependency = dependency->next) {
420*10d63b7dSRichard Lowe 			if (dependency->automatic && !dependency->stale) {
421*10d63b7dSRichard Lowe 				auto_count++;
422*10d63b7dSRichard Lowe 			}
423*10d63b7dSRichard Lowe 		}
424*10d63b7dSRichard Lowe 		/* Create vector to hold the current autos */
425*10d63b7dSRichard Lowe 		automatics =
426*10d63b7dSRichard Lowe 		  (Name *) alloca((int) (auto_count * sizeof (Name)));
427*10d63b7dSRichard Lowe 		/* Copy them */
428*10d63b7dSRichard Lowe 		for (p = automatics, dependency = line->body.line.dependencies;
429*10d63b7dSRichard Lowe 		     dependency != NULL;
430*10d63b7dSRichard Lowe 		     dependency = dependency->next) {
431*10d63b7dSRichard Lowe 			if (dependency->automatic && !dependency->stale) {
432*10d63b7dSRichard Lowe 				*p++ = dependency->name;
433*10d63b7dSRichard Lowe 			}
434*10d63b7dSRichard Lowe 		}
435*10d63b7dSRichard Lowe 	}
436*10d63b7dSRichard Lowe 	if (debug_level > 1) {
437*10d63b7dSRichard Lowe 		(void) printf("%*sdoname(%s)\n",
438*10d63b7dSRichard Lowe 			      recursion_level,
439*10d63b7dSRichard Lowe 			      "",
440*10d63b7dSRichard Lowe 			      target->string_mb);
441*10d63b7dSRichard Lowe 	}
442*10d63b7dSRichard Lowe 	recursion_level++;
443*10d63b7dSRichard Lowe 	/* Avoid infinite loops */
444*10d63b7dSRichard Lowe 	if (target->state == build_in_progress) {
445*10d63b7dSRichard Lowe 		warning(gettext("Infinite loop: Target `%s' depends on itself"),
446*10d63b7dSRichard Lowe 			target->string_mb);
447*10d63b7dSRichard Lowe 		return build_ok;
448*10d63b7dSRichard Lowe 	}
449*10d63b7dSRichard Lowe 	target->state = build_in_progress;
450*10d63b7dSRichard Lowe 
451*10d63b7dSRichard Lowe 	/* Activate conditional macros for the target */
452*10d63b7dSRichard Lowe 	if (!target->added_pattern_conditionals) {
453*10d63b7dSRichard Lowe 		add_pattern_conditionals(target);
454*10d63b7dSRichard Lowe 		target->added_pattern_conditionals = true;
455*10d63b7dSRichard Lowe 	}
456*10d63b7dSRichard Lowe 	if (target->conditional_cnt > 0) {
457*10d63b7dSRichard Lowe 		old_locals = (Property) alloca(target->conditional_cnt *
458*10d63b7dSRichard Lowe 					       sizeof (Property_rec));
459*10d63b7dSRichard Lowe 		set_locals(target, old_locals);
460*10d63b7dSRichard Lowe 	}
461*10d63b7dSRichard Lowe 
462*10d63b7dSRichard Lowe /*
463*10d63b7dSRichard Lowe  * after making the call to dynamic_dependecies unconditional we can handle
464*10d63b7dSRichard Lowe  * target names that are same as file name. In this case $$@ in the
465*10d63b7dSRichard Lowe  * dependencies did not mean anything. WIth this change it expands it
466*10d63b7dSRichard Lowe  * as expected.
467*10d63b7dSRichard Lowe  */
468*10d63b7dSRichard Lowe 	if (!target->has_depe_list_expanded)
469*10d63b7dSRichard Lowe 	{
470*10d63b7dSRichard Lowe 		dynamic_dependencies(target);
471*10d63b7dSRichard Lowe 	}
472*10d63b7dSRichard Lowe 
473*10d63b7dSRichard Lowe /*
474*10d63b7dSRichard Lowe  *	FIRST SECTION -- GO THROUGH DEPENDENCIES AND COLLECT EXPLICIT
475*10d63b7dSRichard Lowe  *	COMMANDS TO RUN
476*10d63b7dSRichard Lowe  */
477*10d63b7dSRichard Lowe 	if ((line = get_prop(target->prop, line_prop)) != NULL) {
478*10d63b7dSRichard Lowe 		if (check_dependencies(&result,
479*10d63b7dSRichard Lowe 				       line,
480*10d63b7dSRichard Lowe 				       do_get,
481*10d63b7dSRichard Lowe 				       target,
482*10d63b7dSRichard Lowe 				       true_target,
483*10d63b7dSRichard Lowe 				       doing_subtree,
484*10d63b7dSRichard Lowe 				       &out_of_date_list,
485*10d63b7dSRichard Lowe 				       old_locals,
486*10d63b7dSRichard Lowe 				       implicit,
487*10d63b7dSRichard Lowe 				       &command,
488*10d63b7dSRichard Lowe 				       less,
489*10d63b7dSRichard Lowe 				       rechecking_target,
490*10d63b7dSRichard Lowe 				       recheck_conditionals)) {
491*10d63b7dSRichard Lowe 			return build_running;
492*10d63b7dSRichard Lowe 		}
493*10d63b7dSRichard Lowe 		if (line->body.line.query != NULL) {
494*10d63b7dSRichard Lowe 			delete_query_chain(line->body.line.query);
495*10d63b7dSRichard Lowe 		}
496*10d63b7dSRichard Lowe 		line->body.line.query = out_of_date_list;
497*10d63b7dSRichard Lowe 	}
498*10d63b7dSRichard Lowe 
499*10d63b7dSRichard Lowe 
500*10d63b7dSRichard Lowe /*
501*10d63b7dSRichard Lowe  * If the target is a :: type, do not try to find the rule for the target,
502*10d63b7dSRichard Lowe  * all actions will be taken by separate branches.
503*10d63b7dSRichard Lowe  * Else, we try to find an implicit rule using various methods,
504*10d63b7dSRichard Lowe  * we quit as soon as one is found.
505*10d63b7dSRichard Lowe  *
506*10d63b7dSRichard Lowe  * [tolik, 12 Sep 2002] Do not try to find implicit rule for the target
507*10d63b7dSRichard Lowe  * being rechecked - the target is being rechecked means that it already
508*10d63b7dSRichard Lowe  * has explicit dependencies derived from an implicit rule found
509*10d63b7dSRichard Lowe  * in previous step.
510*10d63b7dSRichard Lowe  */
511*10d63b7dSRichard Lowe 	if (target->colon_splits == 0 && !rechecking_target) {
512*10d63b7dSRichard Lowe 		/* Look for percent matched rule */
513*10d63b7dSRichard Lowe 		if ((result == build_dont_know) &&
514*10d63b7dSRichard Lowe 		    (command == NULL)) {
515*10d63b7dSRichard Lowe 			switch (find_percent_rule(
516*10d63b7dSRichard Lowe 					target,
517*10d63b7dSRichard Lowe 					&command,
518*10d63b7dSRichard Lowe 					recheck_conditionals)) {
519*10d63b7dSRichard Lowe 			case build_failed:
520*10d63b7dSRichard Lowe 				result = build_failed;
521*10d63b7dSRichard Lowe 				break;
522*10d63b7dSRichard Lowe 			case build_running:
523*10d63b7dSRichard Lowe 				target->state = build_running;
524*10d63b7dSRichard Lowe 				add_pending(target,
525*10d63b7dSRichard Lowe 					    --recursion_level,
526*10d63b7dSRichard Lowe 					    do_get,
527*10d63b7dSRichard Lowe 					    implicit,
528*10d63b7dSRichard Lowe 					    false);
529*10d63b7dSRichard Lowe 				if (target->conditional_cnt > 0) {
530*10d63b7dSRichard Lowe 					reset_locals(target,
531*10d63b7dSRichard Lowe 						     old_locals,
532*10d63b7dSRichard Lowe 						     get_prop(target->prop,
533*10d63b7dSRichard Lowe 							     conditional_prop),
534*10d63b7dSRichard Lowe 						     0);
535*10d63b7dSRichard Lowe 				}
536*10d63b7dSRichard Lowe 				return build_running;
537*10d63b7dSRichard Lowe 			case build_ok:
538*10d63b7dSRichard Lowe 				result = build_ok;
539*10d63b7dSRichard Lowe 				break;
540*10d63b7dSRichard Lowe 			}
541*10d63b7dSRichard Lowe 		}
542*10d63b7dSRichard Lowe 		/* Look for double suffix rule */
543*10d63b7dSRichard Lowe 		if (result == build_dont_know) {
544*10d63b7dSRichard Lowe 			Property member;
545*10d63b7dSRichard Lowe 
546*10d63b7dSRichard Lowe 			if (target->is_member &&
547*10d63b7dSRichard Lowe 			    ((member = get_prop(target->prop, member_prop)) !=
548*10d63b7dSRichard Lowe 			     NULL)) {
549*10d63b7dSRichard Lowe 			        switch (find_ar_suffix_rule(target,
550*10d63b7dSRichard Lowe 						member->body.
551*10d63b7dSRichard Lowe 						member.member,
552*10d63b7dSRichard Lowe 						&command,
553*10d63b7dSRichard Lowe 						recheck_conditionals)) {
554*10d63b7dSRichard Lowe 				case build_failed:
555*10d63b7dSRichard Lowe 					result = build_failed;
556*10d63b7dSRichard Lowe 					break;
557*10d63b7dSRichard Lowe 				case build_running:
558*10d63b7dSRichard Lowe 					target->state = build_running;
559*10d63b7dSRichard Lowe 					add_pending(target,
560*10d63b7dSRichard Lowe 						    --recursion_level,
561*10d63b7dSRichard Lowe 						    do_get,
562*10d63b7dSRichard Lowe 						    implicit,
563*10d63b7dSRichard Lowe 						    false);
564*10d63b7dSRichard Lowe 				    if (target->conditional_cnt > 0) {
565*10d63b7dSRichard Lowe 					    reset_locals(target,
566*10d63b7dSRichard Lowe 							 old_locals,
567*10d63b7dSRichard Lowe 							 get_prop(target->prop,
568*10d63b7dSRichard Lowe 							     conditional_prop),
569*10d63b7dSRichard Lowe 							 0);
570*10d63b7dSRichard Lowe 				    }
571*10d63b7dSRichard Lowe 					return build_running;
572*10d63b7dSRichard Lowe 				default:
573*10d63b7dSRichard Lowe 					/* ALWAYS bind $% for old style */
574*10d63b7dSRichard Lowe 					/* ar rules */
575*10d63b7dSRichard Lowe 					if (line == NULL) {
576*10d63b7dSRichard Lowe 						line =
577*10d63b7dSRichard Lowe 						  maybe_append_prop(target,
578*10d63b7dSRichard Lowe 								    line_prop);
579*10d63b7dSRichard Lowe 					}
580*10d63b7dSRichard Lowe 					line->body.line.percent =
581*10d63b7dSRichard Lowe 					  member->body.member.member;
582*10d63b7dSRichard Lowe 					break;
583*10d63b7dSRichard Lowe 				}
584*10d63b7dSRichard Lowe 			} else {
585*10d63b7dSRichard Lowe 				switch (find_double_suffix_rule(target,
586*10d63b7dSRichard Lowe 						&command,
587*10d63b7dSRichard Lowe 						recheck_conditionals)) {
588*10d63b7dSRichard Lowe 				case build_failed:
589*10d63b7dSRichard Lowe 					result = build_failed;
590*10d63b7dSRichard Lowe 					break;
591*10d63b7dSRichard Lowe 				case build_running:
592*10d63b7dSRichard Lowe 					target->state = build_running;
593*10d63b7dSRichard Lowe 					add_pending(target,
594*10d63b7dSRichard Lowe 						    --recursion_level,
595*10d63b7dSRichard Lowe 						    do_get,
596*10d63b7dSRichard Lowe 						    implicit,
597*10d63b7dSRichard Lowe 						    false);
598*10d63b7dSRichard Lowe 					if (target->conditional_cnt > 0) {
599*10d63b7dSRichard Lowe 						reset_locals(target,
600*10d63b7dSRichard Lowe 							     old_locals,
601*10d63b7dSRichard Lowe 							     get_prop(target->
602*10d63b7dSRichard Lowe 								      prop,
603*10d63b7dSRichard Lowe 								      conditional_prop),
604*10d63b7dSRichard Lowe 							     0);
605*10d63b7dSRichard Lowe 					}
606*10d63b7dSRichard Lowe 					return build_running;
607*10d63b7dSRichard Lowe 				}
608*10d63b7dSRichard Lowe 			}
609*10d63b7dSRichard Lowe 		}
610*10d63b7dSRichard Lowe 		/* Look for single suffix rule */
611*10d63b7dSRichard Lowe 
612*10d63b7dSRichard Lowe /* /tolik/
613*10d63b7dSRichard Lowe  * I commented !implicit to fix bug 1247448: Suffix Rules failed when combine with Pattern Matching Rules.
614*10d63b7dSRichard Lowe  * This caused problem with SVR4 tilde rules (infinite recursion). So I made some changes in "implicit.cc"
615*10d63b7dSRichard Lowe  */
616*10d63b7dSRichard Lowe /* /tolik, 06.21.96/
617*10d63b7dSRichard Lowe  * Regression! See BugId 1255360
618*10d63b7dSRichard Lowe  * If more than one percent rules are defined for the same target then
619*10d63b7dSRichard Lowe  * the behaviour of 'make' with my previous fix may be different from one
620*10d63b7dSRichard Lowe  * of the 'old make'.
621*10d63b7dSRichard Lowe  * The global variable second_pass (maybe it should be an argument to doname())
622*10d63b7dSRichard Lowe  * is intended to avoid this regression. It is set in doname_check().
623*10d63b7dSRichard Lowe  * First, 'make' will work as it worked before. Only when it is
624*10d63b7dSRichard Lowe  * going to say "don't know how to make target" it sets second_pass to true and
625*10d63b7dSRichard Lowe  * run 'doname' again but now trying to use Single Suffix Rules.
626*10d63b7dSRichard Lowe  */
627*10d63b7dSRichard Lowe 		if ((result == build_dont_know) && !automatic && (!implicit || second_pass) &&
628*10d63b7dSRichard Lowe 		    ((line == NULL) ||
629*10d63b7dSRichard Lowe 		     ((line->body.line.target != NULL) &&
630*10d63b7dSRichard Lowe 		      !line->body.line.target->has_regular_dependency))) {
631*10d63b7dSRichard Lowe 			switch (find_suffix_rule(target,
632*10d63b7dSRichard Lowe 						 target,
633*10d63b7dSRichard Lowe 						 empty_name,
634*10d63b7dSRichard Lowe 						 &command,
635*10d63b7dSRichard Lowe 						 recheck_conditionals)) {
636*10d63b7dSRichard Lowe 			case build_failed:
637*10d63b7dSRichard Lowe 				result = build_failed;
638*10d63b7dSRichard Lowe 				break;
639*10d63b7dSRichard Lowe 			case build_running:
640*10d63b7dSRichard Lowe 				target->state = build_running;
641*10d63b7dSRichard Lowe 				add_pending(target,
642*10d63b7dSRichard Lowe 					    --recursion_level,
643*10d63b7dSRichard Lowe 					    do_get,
644*10d63b7dSRichard Lowe 					    implicit,
645*10d63b7dSRichard Lowe 					    false);
646*10d63b7dSRichard Lowe 				if (target->conditional_cnt > 0) {
647*10d63b7dSRichard Lowe 					reset_locals(target,
648*10d63b7dSRichard Lowe 						     old_locals,
649*10d63b7dSRichard Lowe 						     get_prop(target->prop,
650*10d63b7dSRichard Lowe 							     conditional_prop),
651*10d63b7dSRichard Lowe 						     0);
652*10d63b7dSRichard Lowe 				}
653*10d63b7dSRichard Lowe 				return build_running;
654*10d63b7dSRichard Lowe 			}
655*10d63b7dSRichard Lowe 		}
656*10d63b7dSRichard Lowe 		/* Try to sccs get */
657*10d63b7dSRichard Lowe 		if ((command == NULL) &&
658*10d63b7dSRichard Lowe 		    (result == build_dont_know) &&
659*10d63b7dSRichard Lowe 		    do_get) {
660*10d63b7dSRichard Lowe 			result = sccs_get(target, &command);
661*10d63b7dSRichard Lowe 		}
662*10d63b7dSRichard Lowe 
663*10d63b7dSRichard Lowe 		/* Use .DEFAULT rule if it is defined. */
664*10d63b7dSRichard Lowe 		if ((command == NULL) &&
665*10d63b7dSRichard Lowe 		    (result == build_dont_know) &&
666*10d63b7dSRichard Lowe 		    (true_target->colons == no_colon) &&
667*10d63b7dSRichard Lowe 		    default_rule &&
668*10d63b7dSRichard Lowe 		    !implicit) {
669*10d63b7dSRichard Lowe 			/* Make sure we have a line prop */
670*10d63b7dSRichard Lowe 			line = maybe_append_prop(target, line_prop);
671*10d63b7dSRichard Lowe 			command = line;
672*10d63b7dSRichard Lowe 			Boolean out_of_date;
673*10d63b7dSRichard Lowe 			if (true_target->is_member) {
674*10d63b7dSRichard Lowe 				out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
675*10d63b7dSRichard Lowe 									line->body.line.dependency_time);
676*10d63b7dSRichard Lowe 			} else {
677*10d63b7dSRichard Lowe 				out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
678*10d63b7dSRichard Lowe 								    line->body.line.dependency_time);
679*10d63b7dSRichard Lowe 			}
680*10d63b7dSRichard Lowe 			if (build_unconditional || out_of_date) {
681*10d63b7dSRichard Lowe 				line->body.line.is_out_of_date = true;
682*10d63b7dSRichard Lowe 				if (debug_level > 0) {
683*10d63b7dSRichard Lowe 					(void) printf(gettext("%*sBuilding %s using .DEFAULT because it is out of date\n"),
684*10d63b7dSRichard Lowe 						      recursion_level,
685*10d63b7dSRichard Lowe 						      "",
686*10d63b7dSRichard Lowe 						      true_target->string_mb);
687*10d63b7dSRichard Lowe 				}
688*10d63b7dSRichard Lowe 			}
689*10d63b7dSRichard Lowe 			line->body.line.sccs_command = false;
690*10d63b7dSRichard Lowe 			line->body.line.command_template = default_rule;
691*10d63b7dSRichard Lowe 			line->body.line.target = true_target;
692*10d63b7dSRichard Lowe 			line->body.line.star = NULL;
693*10d63b7dSRichard Lowe 			line->body.line.less = true_target;
694*10d63b7dSRichard Lowe 			line->body.line.percent = NULL;
695*10d63b7dSRichard Lowe 		}
696*10d63b7dSRichard Lowe 	}
697*10d63b7dSRichard Lowe 
698*10d63b7dSRichard Lowe 	/* We say "target up to date" if no cmd were executed for the target */
699*10d63b7dSRichard Lowe 	if (!target->is_double_colon_parent) {
700*10d63b7dSRichard Lowe 		commands_done = false;
701*10d63b7dSRichard Lowe 	}
702*10d63b7dSRichard Lowe 
703*10d63b7dSRichard Lowe 	silent = silent_all;
704*10d63b7dSRichard Lowe 	ignore_errors = ignore_errors_all;
705*10d63b7dSRichard Lowe 	if  (posix)
706*10d63b7dSRichard Lowe 	{
707*10d63b7dSRichard Lowe 	  if  (!silent)
708*10d63b7dSRichard Lowe 	  {
709*10d63b7dSRichard Lowe             silent = (Boolean) target->silent_mode;
710*10d63b7dSRichard Lowe 	  }
711*10d63b7dSRichard Lowe 	  if  (!ignore_errors)
712*10d63b7dSRichard Lowe 	  {
713*10d63b7dSRichard Lowe             ignore_errors = (Boolean) target->ignore_error_mode;
714*10d63b7dSRichard Lowe 	  }
715*10d63b7dSRichard Lowe 	}
716*10d63b7dSRichard Lowe 
717*10d63b7dSRichard Lowe 	int doname_dyntarget = 0;
718*10d63b7dSRichard Lowe r_command:
719*10d63b7dSRichard Lowe 	/* Run commands if any. */
720*10d63b7dSRichard Lowe 	if ((command != NULL) &&
721*10d63b7dSRichard Lowe 	    (command->body.line.command_template != NULL)) {
722*10d63b7dSRichard Lowe 		if (result != build_failed) {
723*10d63b7dSRichard Lowe 			result = run_command(command,
724*10d63b7dSRichard Lowe 					     (Boolean) ((parallel || save_parallel) && !silent));
725*10d63b7dSRichard Lowe 		}
726*10d63b7dSRichard Lowe 		switch (result) {
727*10d63b7dSRichard Lowe 		case build_running:
728*10d63b7dSRichard Lowe 			add_running(target,
729*10d63b7dSRichard Lowe 				    true_target,
730*10d63b7dSRichard Lowe 				    command,
731*10d63b7dSRichard Lowe 				    --recursion_level,
732*10d63b7dSRichard Lowe 				    auto_count,
733*10d63b7dSRichard Lowe 				    automatics,
734*10d63b7dSRichard Lowe 				    do_get,
735*10d63b7dSRichard Lowe 				    implicit);
736*10d63b7dSRichard Lowe 			target->state = build_running;
737*10d63b7dSRichard Lowe 			if ((line = get_prop(target->prop,
738*10d63b7dSRichard Lowe 					     line_prop)) != NULL) {
739*10d63b7dSRichard Lowe 				if (line->body.line.query != NULL) {
740*10d63b7dSRichard Lowe 					delete_query_chain(line->body.line.query);
741*10d63b7dSRichard Lowe 				}
742*10d63b7dSRichard Lowe 				line->body.line.query = NULL;
743*10d63b7dSRichard Lowe 			}
744*10d63b7dSRichard Lowe 			if (target->conditional_cnt > 0) {
745*10d63b7dSRichard Lowe 				reset_locals(target,
746*10d63b7dSRichard Lowe 					     old_locals,
747*10d63b7dSRichard Lowe 					     get_prop(target->prop,
748*10d63b7dSRichard Lowe 						     conditional_prop),
749*10d63b7dSRichard Lowe 					     0);
750*10d63b7dSRichard Lowe 			}
751*10d63b7dSRichard Lowe 			return build_running;
752*10d63b7dSRichard Lowe 		case build_serial:
753*10d63b7dSRichard Lowe 			add_serial(target,
754*10d63b7dSRichard Lowe 				   --recursion_level,
755*10d63b7dSRichard Lowe 				   do_get,
756*10d63b7dSRichard Lowe 				   implicit);
757*10d63b7dSRichard Lowe 			target->state = build_running;
758*10d63b7dSRichard Lowe 			line = get_prop(target->prop, line_prop);
759*10d63b7dSRichard Lowe 			if (line != NULL) {
760*10d63b7dSRichard Lowe 				if (line->body.line.query != NULL) {
761*10d63b7dSRichard Lowe 					delete_query_chain(line->body.line.query);
762*10d63b7dSRichard Lowe 				}
763*10d63b7dSRichard Lowe 				line->body.line.query = NULL;
764*10d63b7dSRichard Lowe 			}
765*10d63b7dSRichard Lowe 			if (target->conditional_cnt > 0) {
766*10d63b7dSRichard Lowe 				reset_locals(target,
767*10d63b7dSRichard Lowe 					     old_locals,
768*10d63b7dSRichard Lowe 					     get_prop(target->prop,
769*10d63b7dSRichard Lowe 						     conditional_prop),
770*10d63b7dSRichard Lowe 					     0);
771*10d63b7dSRichard Lowe 			}
772*10d63b7dSRichard Lowe 			return build_running;
773*10d63b7dSRichard Lowe 		case build_ok:
774*10d63b7dSRichard Lowe 			/* If all went OK set a nice timestamp */
775*10d63b7dSRichard Lowe 			if (true_target->stat.time == file_doesnt_exist) {
776*10d63b7dSRichard Lowe 				true_target->stat.time = file_max_time;
777*10d63b7dSRichard Lowe 			}
778*10d63b7dSRichard Lowe 			break;
779*10d63b7dSRichard Lowe 		}
780*10d63b7dSRichard Lowe 	} else {
781*10d63b7dSRichard Lowe 		/*
782*10d63b7dSRichard Lowe 		 * If no command was found for the target, and it doesn't
783*10d63b7dSRichard Lowe 		 * exist, and it is mentioned as a target in the makefile,
784*10d63b7dSRichard Lowe 		 * we say it is extremely new and that it is OK.
785*10d63b7dSRichard Lowe 		 */
786*10d63b7dSRichard Lowe 		if (target->colons != no_colon) {
787*10d63b7dSRichard Lowe 			if (true_target->stat.time == file_doesnt_exist){
788*10d63b7dSRichard Lowe 				true_target->stat.time = file_max_time;
789*10d63b7dSRichard Lowe 			}
790*10d63b7dSRichard Lowe 			result = build_ok;
791*10d63b7dSRichard Lowe 		}
792*10d63b7dSRichard Lowe 		/*
793*10d63b7dSRichard Lowe 		 * Trying dynamic targets.
794*10d63b7dSRichard Lowe 		 */
795*10d63b7dSRichard Lowe 		if(!doname_dyntarget) {
796*10d63b7dSRichard Lowe 			doname_dyntarget = 1;
797*10d63b7dSRichard Lowe 			Name dtarg = find_dyntarget(target);
798*10d63b7dSRichard Lowe 			if(dtarg!=NULL) {
799*10d63b7dSRichard Lowe 				if (!target->has_depe_list_expanded) {
800*10d63b7dSRichard Lowe 					dynamic_dependencies(target);
801*10d63b7dSRichard Lowe 				}
802*10d63b7dSRichard Lowe 				if ((line = get_prop(target->prop, line_prop)) != NULL) {
803*10d63b7dSRichard Lowe 					if (check_dependencies(&result,
804*10d63b7dSRichard Lowe 					                       line,
805*10d63b7dSRichard Lowe 					                       do_get,
806*10d63b7dSRichard Lowe 					                       target,
807*10d63b7dSRichard Lowe 					                       true_target,
808*10d63b7dSRichard Lowe 					                       doing_subtree,
809*10d63b7dSRichard Lowe 					                       &out_of_date_list,
810*10d63b7dSRichard Lowe 					                       old_locals,
811*10d63b7dSRichard Lowe 					                       implicit,
812*10d63b7dSRichard Lowe 					                       &command,
813*10d63b7dSRichard Lowe 					                       less,
814*10d63b7dSRichard Lowe 					                       rechecking_target,
815*10d63b7dSRichard Lowe 					                       recheck_conditionals))
816*10d63b7dSRichard Lowe 					{
817*10d63b7dSRichard Lowe 						return build_running;
818*10d63b7dSRichard Lowe 					}
819*10d63b7dSRichard Lowe 					if (line->body.line.query != NULL) {
820*10d63b7dSRichard Lowe 						delete_query_chain(line->body.line.query);
821*10d63b7dSRichard Lowe 					}
822*10d63b7dSRichard Lowe 					line->body.line.query = out_of_date_list;
823*10d63b7dSRichard Lowe 				}
824*10d63b7dSRichard Lowe 				goto r_command;
825*10d63b7dSRichard Lowe 			}
826*10d63b7dSRichard Lowe 		}
827*10d63b7dSRichard Lowe 		/*
828*10d63b7dSRichard Lowe 		 * If the file exists, it is OK that we couldnt figure
829*10d63b7dSRichard Lowe 		 * out how to build it.
830*10d63b7dSRichard Lowe 		 */
831*10d63b7dSRichard Lowe 		(void) exists(target);
832*10d63b7dSRichard Lowe 		if ((target->stat.time != file_doesnt_exist) &&
833*10d63b7dSRichard Lowe 		    (result == build_dont_know)) {
834*10d63b7dSRichard Lowe 			result = build_ok;
835*10d63b7dSRichard Lowe 		}
836*10d63b7dSRichard Lowe 	}
837*10d63b7dSRichard Lowe 
838*10d63b7dSRichard Lowe 	/*
839*10d63b7dSRichard Lowe 	 * Some of the following is duplicated in the function finish_doname.
840*10d63b7dSRichard Lowe 	 * If anything is changed here, check to see if it needs to be
841*10d63b7dSRichard Lowe 	 * changed there.
842*10d63b7dSRichard Lowe 	 */
843*10d63b7dSRichard Lowe 	if ((line = get_prop(target->prop, line_prop)) != NULL) {
844*10d63b7dSRichard Lowe 		if (line->body.line.query != NULL) {
845*10d63b7dSRichard Lowe 			delete_query_chain(line->body.line.query);
846*10d63b7dSRichard Lowe 		}
847*10d63b7dSRichard Lowe 		line->body.line.query = NULL;
848*10d63b7dSRichard Lowe 	}
849*10d63b7dSRichard Lowe 	target->state = result;
850*10d63b7dSRichard Lowe 	parallel = save_parallel;
851*10d63b7dSRichard Lowe 	if (target->conditional_cnt > 0) {
852*10d63b7dSRichard Lowe 		reset_locals(target,
853*10d63b7dSRichard Lowe 			     old_locals,
854*10d63b7dSRichard Lowe 			     get_prop(target->prop, conditional_prop),
855*10d63b7dSRichard Lowe 			     0);
856*10d63b7dSRichard Lowe 	}
857*10d63b7dSRichard Lowe 	recursion_level--;
858*10d63b7dSRichard Lowe 	if (target->is_member) {
859*10d63b7dSRichard Lowe 		Property member;
860*10d63b7dSRichard Lowe 
861*10d63b7dSRichard Lowe 		/* Propagate the timestamp from the member file to the member*/
862*10d63b7dSRichard Lowe 		if ((target->stat.time != file_max_time) &&
863*10d63b7dSRichard Lowe 		    ((member = get_prop(target->prop, member_prop)) != NULL) &&
864*10d63b7dSRichard Lowe 		    (exists(member->body.member.member) > file_doesnt_exist)) {
865*10d63b7dSRichard Lowe 			target->stat.time =
866*10d63b7dSRichard Lowe 			  member->body.member.member->stat.time;
867*10d63b7dSRichard Lowe 		}
868*10d63b7dSRichard Lowe 	}
869*10d63b7dSRichard Lowe 	/*
870*10d63b7dSRichard Lowe 	 * Check if we found any new auto dependencies when we
871*10d63b7dSRichard Lowe 	 * built the target.
872*10d63b7dSRichard Lowe 	 */
873*10d63b7dSRichard Lowe 	if ((result == build_ok) && check_auto_dependencies(target,
874*10d63b7dSRichard Lowe 							    auto_count,
875*10d63b7dSRichard Lowe 							    automatics)) {
876*10d63b7dSRichard Lowe 		if (debug_level > 0) {
877*10d63b7dSRichard Lowe 			(void) printf(gettext("%*sTarget `%s' acquired new dependencies from build, rechecking all dependencies\n"),
878*10d63b7dSRichard Lowe 				      recursion_level,
879*10d63b7dSRichard Lowe 				      "",
880*10d63b7dSRichard Lowe 				      true_target->string_mb);
881*10d63b7dSRichard Lowe 		}
882*10d63b7dSRichard Lowe 		rechecking_target = true;
883*10d63b7dSRichard Lowe 		saved_commands_done = commands_done;
884*10d63b7dSRichard Lowe 		goto recheck_target;
885*10d63b7dSRichard Lowe 	}
886*10d63b7dSRichard Lowe 
887*10d63b7dSRichard Lowe 	if (rechecking_target && !commands_done) {
888*10d63b7dSRichard Lowe 		commands_done = saved_commands_done;
889*10d63b7dSRichard Lowe 	}
890*10d63b7dSRichard Lowe 
891*10d63b7dSRichard Lowe 	return result;
892*10d63b7dSRichard Lowe }
893*10d63b7dSRichard Lowe 
894*10d63b7dSRichard Lowe /*
895*10d63b7dSRichard Lowe  * DONE.
896*10d63b7dSRichard Lowe  *
897*10d63b7dSRichard Lowe  *	check_dependencies(result, line, do_get,
898*10d63b7dSRichard Lowe  *			target, true_target, doing_subtree, out_of_date_tail,
899*10d63b7dSRichard Lowe  *			old_locals, implicit, command, less, rechecking_target)
900*10d63b7dSRichard Lowe  *
901*10d63b7dSRichard Lowe  *	Return value:
902*10d63b7dSRichard Lowe  *				True returned if some dependencies left running
903*10d63b7dSRichard Lowe  *
904*10d63b7dSRichard Lowe  *	Parameters:
905*10d63b7dSRichard Lowe  *		result		Pointer to cell we update if build failed
906*10d63b7dSRichard Lowe  *		line		We get the dependencies from here
907*10d63b7dSRichard Lowe  *		do_get		Allow use of sccs get in recursive doname()
908*10d63b7dSRichard Lowe  *		target		The target to chase dependencies for
909*10d63b7dSRichard Lowe  *		true_target	The real one for :: and lib(member)
910*10d63b7dSRichard Lowe  *		doing_subtree	True if building a conditional macro subtree
911*10d63b7dSRichard Lowe  *		out_of_date_tail Used to set the $? list
912*10d63b7dSRichard Lowe  *		old_locals	Used for resetting the local macros
913*10d63b7dSRichard Lowe  *		implicit	Called when scanning for implicit rules?
914*10d63b7dSRichard Lowe  *		command		Place to stuff command
915*10d63b7dSRichard Lowe  *		less		Set to $< value
916*10d63b7dSRichard Lowe  *
917*10d63b7dSRichard Lowe  *	Global variables used:
918*10d63b7dSRichard Lowe  *		command_changed	Set if we suspect .make.state needs rewrite
919*10d63b7dSRichard Lowe  *		debug_level	Should we trace actions?
920*10d63b7dSRichard Lowe  *		force		The Name " FORCE", compared against
921*10d63b7dSRichard Lowe  *		recursion_level	Used for tracing
922*10d63b7dSRichard Lowe  *		rewrite_statefile Set if .make.state needs rewriting
923*10d63b7dSRichard Lowe  *		wait_name	The Name ".WAIT", compared against
924*10d63b7dSRichard Lowe  */
925*10d63b7dSRichard Lowe static Boolean
926*10d63b7dSRichard Lowe check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals)
927*10d63b7dSRichard Lowe {
928*10d63b7dSRichard Lowe 	Boolean			dependencies_running;
929*10d63b7dSRichard Lowe 	register Dependency	dependency;
930*10d63b7dSRichard Lowe 	Doname			dep_result;
931*10d63b7dSRichard Lowe 	Boolean			dependency_changed = false;
932*10d63b7dSRichard Lowe 
933*10d63b7dSRichard Lowe 	line->body.line.dependency_time = file_doesnt_exist;
934*10d63b7dSRichard Lowe 	if (line->body.line.query != NULL) {
935*10d63b7dSRichard Lowe 		delete_query_chain(line->body.line.query);
936*10d63b7dSRichard Lowe 	}
937*10d63b7dSRichard Lowe 	line->body.line.query = NULL;
938*10d63b7dSRichard Lowe 	line->body.line.is_out_of_date = false;
939*10d63b7dSRichard Lowe 	dependencies_running = false;
940*10d63b7dSRichard Lowe 	/*
941*10d63b7dSRichard Lowe 	 * Run thru all the dependencies and call doname() recursively
942*10d63b7dSRichard Lowe 	 * on each of them.
943*10d63b7dSRichard Lowe 	 */
944*10d63b7dSRichard Lowe 	for (dependency = line->body.line.dependencies;
945*10d63b7dSRichard Lowe 	     dependency != NULL;
946*10d63b7dSRichard Lowe 	     dependency = dependency->next) {
947*10d63b7dSRichard Lowe 		Boolean this_dependency_changed = false;
948*10d63b7dSRichard Lowe 
949*10d63b7dSRichard Lowe 		if (!dependency->automatic &&
950*10d63b7dSRichard Lowe 		    (rechecking_target || target->rechecking_target)) {
951*10d63b7dSRichard Lowe 			/*
952*10d63b7dSRichard Lowe 			 * We only bother with the autos when rechecking
953*10d63b7dSRichard Lowe 			 */
954*10d63b7dSRichard Lowe 			continue;
955*10d63b7dSRichard Lowe 		}
956*10d63b7dSRichard Lowe 
957*10d63b7dSRichard Lowe 		if (dependency->name == wait_name) {
958*10d63b7dSRichard Lowe 			/*
959*10d63b7dSRichard Lowe 			 * The special target .WAIT means finish all of
960*10d63b7dSRichard Lowe 			 * the prior dependencies before continuing.
961*10d63b7dSRichard Lowe 			 */
962*10d63b7dSRichard Lowe 			if (dependencies_running) {
963*10d63b7dSRichard Lowe 				break;
964*10d63b7dSRichard Lowe 			}
965*10d63b7dSRichard Lowe 		} else if ((!parallel_ok(dependency->name, false)) &&
966*10d63b7dSRichard Lowe 			   (dependencies_running)) {
967*10d63b7dSRichard Lowe 			/*
968*10d63b7dSRichard Lowe 			 * If we can't execute the current dependency in
969*10d63b7dSRichard Lowe 			 * parallel, hold off the dependency processing
970*10d63b7dSRichard Lowe 			 * to preserve the order of the dependencies.
971*10d63b7dSRichard Lowe 			 */
972*10d63b7dSRichard Lowe 			break;
973*10d63b7dSRichard Lowe 		} else {
974*10d63b7dSRichard Lowe 			timestruc_t	depe_time = file_doesnt_exist;
975*10d63b7dSRichard Lowe 
976*10d63b7dSRichard Lowe 
977*10d63b7dSRichard Lowe 			if (true_target->is_member) {
978*10d63b7dSRichard Lowe 				depe_time = exists(dependency->name);
979*10d63b7dSRichard Lowe 			}
980*10d63b7dSRichard Lowe 			if (dependency->built ||
981*10d63b7dSRichard Lowe 			    (dependency->name->state == build_failed)) {
982*10d63b7dSRichard Lowe 				dep_result = (Doname) dependency->name->state;
983*10d63b7dSRichard Lowe 			} else {
984*10d63b7dSRichard Lowe 				dep_result = doname_check(dependency->name,
985*10d63b7dSRichard Lowe 							  do_get,
986*10d63b7dSRichard Lowe 							  false,
987*10d63b7dSRichard Lowe 							  (Boolean) dependency->automatic);
988*10d63b7dSRichard Lowe 			}
989*10d63b7dSRichard Lowe 			if (true_target->is_member || dependency->name->is_member) {
990*10d63b7dSRichard Lowe 				/* should compare only secs, cause lib members does not have nsec time resolution */
991*10d63b7dSRichard Lowe 				if (depe_time.tv_sec != dependency->name->stat.time.tv_sec) {
992*10d63b7dSRichard Lowe 					this_dependency_changed =
993*10d63b7dSRichard Lowe 					  dependency_changed =
994*10d63b7dSRichard Lowe 					    true;
995*10d63b7dSRichard Lowe 				}
996*10d63b7dSRichard Lowe 			} else {
997*10d63b7dSRichard Lowe 				if (depe_time != dependency->name->stat.time) {
998*10d63b7dSRichard Lowe 					this_dependency_changed =
999*10d63b7dSRichard Lowe 					  dependency_changed =
1000*10d63b7dSRichard Lowe 					    true;
1001*10d63b7dSRichard Lowe 				}
1002*10d63b7dSRichard Lowe 			}
1003*10d63b7dSRichard Lowe 			dependency->built = true;
1004*10d63b7dSRichard Lowe 			switch (dep_result) {
1005*10d63b7dSRichard Lowe 			case build_running:
1006*10d63b7dSRichard Lowe 				dependencies_running = true;
1007*10d63b7dSRichard Lowe 				continue;
1008*10d63b7dSRichard Lowe 			case build_failed:
1009*10d63b7dSRichard Lowe 				*result = build_failed;
1010*10d63b7dSRichard Lowe 				break;
1011*10d63b7dSRichard Lowe 			case build_dont_know:
1012*10d63b7dSRichard Lowe /*
1013*10d63b7dSRichard Lowe  * If make can't figure out how to make a dependency, maybe the dependency
1014*10d63b7dSRichard Lowe  * is out of date. In this case, we just declare the target out of date
1015*10d63b7dSRichard Lowe  * and go on. If we really need the dependency, the make'ing of the target
1016*10d63b7dSRichard Lowe  * will fail. This will only happen for automatic (hidden) dependencies.
1017*10d63b7dSRichard Lowe  */
1018*10d63b7dSRichard Lowe 				if(!recheck_conditionals) {
1019*10d63b7dSRichard Lowe 					line->body.line.is_out_of_date = true;
1020*10d63b7dSRichard Lowe 				}
1021*10d63b7dSRichard Lowe 				/*
1022*10d63b7dSRichard Lowe 				 * Make sure the dependency is not saved
1023*10d63b7dSRichard Lowe 				 * in the state file.
1024*10d63b7dSRichard Lowe 				 */
1025*10d63b7dSRichard Lowe 				dependency->stale = true;
1026*10d63b7dSRichard Lowe 				rewrite_statefile =
1027*10d63b7dSRichard Lowe 				  command_changed =
1028*10d63b7dSRichard Lowe 				    true;
1029*10d63b7dSRichard Lowe 				if (debug_level > 0) {
1030*10d63b7dSRichard Lowe 					(void) printf(gettext("Target %s rebuilt because dependency %s does not exist\n"),
1031*10d63b7dSRichard Lowe 						     true_target->string_mb,
1032*10d63b7dSRichard Lowe 						     dependency->name->string_mb);
1033*10d63b7dSRichard Lowe 				}
1034*10d63b7dSRichard Lowe 				break;
1035*10d63b7dSRichard Lowe 			}
1036*10d63b7dSRichard Lowe 			if (dependency->name->depends_on_conditional) {
1037*10d63b7dSRichard Lowe 				target->depends_on_conditional = true;
1038*10d63b7dSRichard Lowe 			}
1039*10d63b7dSRichard Lowe 			if (dependency->name == force) {
1040*10d63b7dSRichard Lowe 				target->stat.time =
1041*10d63b7dSRichard Lowe 				  dependency->name->stat.time;
1042*10d63b7dSRichard Lowe 			}
1043*10d63b7dSRichard Lowe 			/*
1044*10d63b7dSRichard Lowe 			 * Propagate new timestamp from "member" to
1045*10d63b7dSRichard Lowe 			 * "lib.a(member)".
1046*10d63b7dSRichard Lowe 			 */
1047*10d63b7dSRichard Lowe 			(void) exists(dependency->name);
1048*10d63b7dSRichard Lowe 
1049*10d63b7dSRichard Lowe 			/* Collect the timestamp of the youngest dependency */
1050*10d63b7dSRichard Lowe 			line->body.line.dependency_time =
1051*10d63b7dSRichard Lowe 			  MAX(dependency->name->stat.time,
1052*10d63b7dSRichard Lowe 			      line->body.line.dependency_time);
1053*10d63b7dSRichard Lowe 
1054*10d63b7dSRichard Lowe 			/* Correction: do not consider nanosecs for members */
1055*10d63b7dSRichard Lowe 			if(true_target->is_member || dependency->name->is_member) {
1056*10d63b7dSRichard Lowe 				line->body.line.dependency_time.tv_nsec = 0;
1057*10d63b7dSRichard Lowe 			}
1058*10d63b7dSRichard Lowe 
1059*10d63b7dSRichard Lowe 			if (debug_level > 1) {
1060*10d63b7dSRichard Lowe 				(void) printf(gettext("%*sDate(%s)=%s \n"),
1061*10d63b7dSRichard Lowe 					      recursion_level,
1062*10d63b7dSRichard Lowe 					      "",
1063*10d63b7dSRichard Lowe 					      dependency->name->string_mb,
1064*10d63b7dSRichard Lowe 					      time_to_string(dependency->name->
1065*10d63b7dSRichard Lowe 							     stat.time));
1066*10d63b7dSRichard Lowe 				if (dependency->name->stat.time > line->body.line.dependency_time) {
1067*10d63b7dSRichard Lowe 					(void) printf(gettext("%*sDate-dependencies(%s) set to %s\n"),
1068*10d63b7dSRichard Lowe 						      recursion_level,
1069*10d63b7dSRichard Lowe 						      "",
1070*10d63b7dSRichard Lowe 						      true_target->string_mb,
1071*10d63b7dSRichard Lowe 						      time_to_string(line->body.line.
1072*10d63b7dSRichard Lowe 								     dependency_time));
1073*10d63b7dSRichard Lowe 				}
1074*10d63b7dSRichard Lowe 			}
1075*10d63b7dSRichard Lowe 
1076*10d63b7dSRichard Lowe 			/* Build the $? list */
1077*10d63b7dSRichard Lowe 			if (true_target->is_member) {
1078*10d63b7dSRichard Lowe 				if (this_dependency_changed == true) {
1079*10d63b7dSRichard Lowe 					true_target->stat.time = dependency->name->stat.time;
1080*10d63b7dSRichard Lowe 					true_target->stat.time.tv_sec--;
1081*10d63b7dSRichard Lowe 				} else {
1082*10d63b7dSRichard Lowe 					/* Dina:
1083*10d63b7dSRichard Lowe 					 * The next statement is commented
1084*10d63b7dSRichard Lowe 					 * out as a fix for bug #1051032.
1085*10d63b7dSRichard Lowe 					 * if dependency hasn't changed
1086*10d63b7dSRichard Lowe 					 * then there's no need to invalidate
1087*10d63b7dSRichard Lowe 					 * true_target. This statemnt causes
1088*10d63b7dSRichard Lowe 					 * make to take much longer to process
1089*10d63b7dSRichard Lowe 					 * an already-built archive. Soren
1090*10d63b7dSRichard Lowe 					 * said it was a quick fix for some
1091*10d63b7dSRichard Lowe 					 * problem he doesn't remember.
1092*10d63b7dSRichard Lowe 					true_target->stat.time = file_no_time;
1093*10d63b7dSRichard Lowe 					 */
1094*10d63b7dSRichard Lowe 					(void) exists(true_target);
1095*10d63b7dSRichard Lowe 				}
1096*10d63b7dSRichard Lowe 			} else {
1097*10d63b7dSRichard Lowe 				(void) exists(true_target);
1098*10d63b7dSRichard Lowe 			}
1099*10d63b7dSRichard Lowe 			Boolean out_of_date;
1100*10d63b7dSRichard Lowe 			if (true_target->is_member || dependency->name->is_member) {
1101*10d63b7dSRichard Lowe 				out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
1102*10d63b7dSRichard Lowe 							                dependency->name->stat.time);
1103*10d63b7dSRichard Lowe 			} else {
1104*10d63b7dSRichard Lowe 				out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
1105*10d63b7dSRichard Lowe 							            dependency->name->stat.time);
1106*10d63b7dSRichard Lowe 			}
1107*10d63b7dSRichard Lowe 			if ((build_unconditional || out_of_date) &&
1108*10d63b7dSRichard Lowe 			    (dependency->name != force) &&
1109*10d63b7dSRichard Lowe 			    (dependency->stale == false)) {
1110*10d63b7dSRichard Lowe 				*out_of_date_tail = ALLOC(Chain);
1111*10d63b7dSRichard Lowe 				if (dependency->name->is_member &&
1112*10d63b7dSRichard Lowe 				    (get_prop(dependency->name->prop,
1113*10d63b7dSRichard Lowe 					      member_prop) != NULL)) {
1114*10d63b7dSRichard Lowe 					(*out_of_date_tail)->name =
1115*10d63b7dSRichard Lowe 					  get_prop(dependency->name->prop,
1116*10d63b7dSRichard Lowe 						   member_prop)->
1117*10d63b7dSRichard Lowe 						     body.member.member;
1118*10d63b7dSRichard Lowe 				} else {
1119*10d63b7dSRichard Lowe 					(*out_of_date_tail)->name =
1120*10d63b7dSRichard Lowe 					  dependency->name;
1121*10d63b7dSRichard Lowe 				}
1122*10d63b7dSRichard Lowe 				(*out_of_date_tail)->next = NULL;
1123*10d63b7dSRichard Lowe 				out_of_date_tail = &(*out_of_date_tail)->next;
1124*10d63b7dSRichard Lowe 				if (debug_level > 0) {
1125*10d63b7dSRichard Lowe 					if (dependency->name->stat.time == file_max_time) {
1126*10d63b7dSRichard Lowe 						(void) printf(gettext("%*sBuilding %s because %s does not exist\n"),
1127*10d63b7dSRichard Lowe 							      recursion_level,
1128*10d63b7dSRichard Lowe 							      "",
1129*10d63b7dSRichard Lowe 							      true_target->string_mb,
1130*10d63b7dSRichard Lowe 							      dependency->name->string_mb);
1131*10d63b7dSRichard Lowe 					} else {
1132*10d63b7dSRichard Lowe 						(void) printf(gettext("%*sBuilding %s because it is out of date relative to %s\n"),
1133*10d63b7dSRichard Lowe 							      recursion_level,
1134*10d63b7dSRichard Lowe 							      "",
1135*10d63b7dSRichard Lowe 							      true_target->string_mb,
1136*10d63b7dSRichard Lowe 							      dependency->name->string_mb);
1137*10d63b7dSRichard Lowe 					}
1138*10d63b7dSRichard Lowe 				}
1139*10d63b7dSRichard Lowe 			}
1140*10d63b7dSRichard Lowe 			if (dependency->name == force) {
1141*10d63b7dSRichard Lowe 				force->stat.time =
1142*10d63b7dSRichard Lowe 				  file_max_time;
1143*10d63b7dSRichard Lowe 				force->state = build_dont_know;
1144*10d63b7dSRichard Lowe 			}
1145*10d63b7dSRichard Lowe 		}
1146*10d63b7dSRichard Lowe 	}
1147*10d63b7dSRichard Lowe 	if (dependencies_running) {
1148*10d63b7dSRichard Lowe 		if (doing_subtree) {
1149*10d63b7dSRichard Lowe 			if (target->conditional_cnt > 0) {
1150*10d63b7dSRichard Lowe 				reset_locals(target,
1151*10d63b7dSRichard Lowe 					     old_locals,
1152*10d63b7dSRichard Lowe 					     get_prop(target->prop,
1153*10d63b7dSRichard Lowe 						      conditional_prop),
1154*10d63b7dSRichard Lowe 					     0);
1155*10d63b7dSRichard Lowe 			}
1156*10d63b7dSRichard Lowe 			return true;
1157*10d63b7dSRichard Lowe 		} else {
1158*10d63b7dSRichard Lowe 			target->state = build_running;
1159*10d63b7dSRichard Lowe 			add_pending(target,
1160*10d63b7dSRichard Lowe 				    --recursion_level,
1161*10d63b7dSRichard Lowe 				    do_get,
1162*10d63b7dSRichard Lowe 				    implicit,
1163*10d63b7dSRichard Lowe 				    false);
1164*10d63b7dSRichard Lowe 			if (target->conditional_cnt > 0) {
1165*10d63b7dSRichard Lowe 				reset_locals(target,
1166*10d63b7dSRichard Lowe 					     old_locals,
1167*10d63b7dSRichard Lowe 					     get_prop(target->prop,
1168*10d63b7dSRichard Lowe 						      conditional_prop),
1169*10d63b7dSRichard Lowe 					     0);
1170*10d63b7dSRichard Lowe 			}
1171*10d63b7dSRichard Lowe 			return true;
1172*10d63b7dSRichard Lowe 		}
1173*10d63b7dSRichard Lowe 	}
1174*10d63b7dSRichard Lowe 	/*
1175*10d63b7dSRichard Lowe 	 * Collect the timestamp of the youngest double colon target
1176*10d63b7dSRichard Lowe 	 * dependency.
1177*10d63b7dSRichard Lowe 	 */
1178*10d63b7dSRichard Lowe 	if (target->is_double_colon_parent) {
1179*10d63b7dSRichard Lowe 		for (dependency = line->body.line.dependencies;
1180*10d63b7dSRichard Lowe 		     dependency != NULL;
1181*10d63b7dSRichard Lowe 		     dependency = dependency->next) {
1182*10d63b7dSRichard Lowe 			Property        tmp_line;
1183*10d63b7dSRichard Lowe 
1184*10d63b7dSRichard Lowe 			if ((tmp_line = get_prop(dependency->name->prop, line_prop)) != NULL) {
1185*10d63b7dSRichard Lowe 				if(tmp_line->body.line.dependency_time != file_max_time) {
1186*10d63b7dSRichard Lowe 					target->stat.time =
1187*10d63b7dSRichard Lowe 					  MAX(tmp_line->body.line.dependency_time,
1188*10d63b7dSRichard Lowe 					      target->stat.time);
1189*10d63b7dSRichard Lowe 				}
1190*10d63b7dSRichard Lowe 			}
1191*10d63b7dSRichard Lowe 		}
1192*10d63b7dSRichard Lowe 	}
1193*10d63b7dSRichard Lowe 	if ((true_target->is_member) && (dependency_changed == true)) {
1194*10d63b7dSRichard Lowe 		true_target->stat.time = file_no_time;
1195*10d63b7dSRichard Lowe 	}
1196*10d63b7dSRichard Lowe 	/*
1197*10d63b7dSRichard Lowe 	 * After scanning all the dependencies, we check the rule
1198*10d63b7dSRichard Lowe 	 * if we found one.
1199*10d63b7dSRichard Lowe 	 */
1200*10d63b7dSRichard Lowe 	if (line->body.line.command_template != NULL) {
1201*10d63b7dSRichard Lowe 		if (line->body.line.command_template_redefined) {
1202*10d63b7dSRichard Lowe 			warning(gettext("Too many rules defined for target %s"),
1203*10d63b7dSRichard Lowe 				target->string_mb);
1204*10d63b7dSRichard Lowe 		}
1205*10d63b7dSRichard Lowe 		*command = line;
1206*10d63b7dSRichard Lowe 		/* Check if the target is out of date */
1207*10d63b7dSRichard Lowe 		Boolean out_of_date;
1208*10d63b7dSRichard Lowe 		if (true_target->is_member) {
1209*10d63b7dSRichard Lowe 			out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
1210*10d63b7dSRichard Lowe 				                                line->body.line.dependency_time);
1211*10d63b7dSRichard Lowe 		} else {
1212*10d63b7dSRichard Lowe 			out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
1213*10d63b7dSRichard Lowe 				                            line->body.line.dependency_time);
1214*10d63b7dSRichard Lowe 		}
1215*10d63b7dSRichard Lowe 		if (build_unconditional || out_of_date){
1216*10d63b7dSRichard Lowe 			if(!recheck_conditionals) {
1217*10d63b7dSRichard Lowe 				line->body.line.is_out_of_date = true;
1218*10d63b7dSRichard Lowe 			}
1219*10d63b7dSRichard Lowe 		}
1220*10d63b7dSRichard Lowe 		line->body.line.sccs_command = false;
1221*10d63b7dSRichard Lowe 		line->body.line.target = true_target;
1222*10d63b7dSRichard Lowe 		if(gnu_style) {
1223*10d63b7dSRichard Lowe 
1224*10d63b7dSRichard Lowe 			// set $< for explicit rule
1225*10d63b7dSRichard Lowe 			if(line->body.line.dependencies != NULL) {
1226*10d63b7dSRichard Lowe 				less = line->body.line.dependencies->name;
1227*10d63b7dSRichard Lowe 			}
1228*10d63b7dSRichard Lowe 
1229*10d63b7dSRichard Lowe 			// set $* for explicit rule
1230*10d63b7dSRichard Lowe 			Name			target_body;
1231*10d63b7dSRichard Lowe 			Name			tt = true_target;
1232*10d63b7dSRichard Lowe 			Property		member;
1233*10d63b7dSRichard Lowe 			register wchar_t	*target_end;
1234*10d63b7dSRichard Lowe 			register Dependency	suffix;
1235*10d63b7dSRichard Lowe 			register int		suffix_length;
1236*10d63b7dSRichard Lowe 			Wstring			targ_string;
1237*10d63b7dSRichard Lowe 			Wstring			suf_string;
1238*10d63b7dSRichard Lowe 
1239*10d63b7dSRichard Lowe 			if (true_target->is_member &&
1240*10d63b7dSRichard Lowe 			    ((member = get_prop(target->prop, member_prop)) !=
1241*10d63b7dSRichard Lowe 			     NULL)) {
1242*10d63b7dSRichard Lowe 				tt = member->body.member.member;
1243*10d63b7dSRichard Lowe 			}
1244*10d63b7dSRichard Lowe 			targ_string.init(tt);
1245*10d63b7dSRichard Lowe 			target_end = targ_string.get_string() + tt->hash.length;
1246*10d63b7dSRichard Lowe 			for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
1247*10d63b7dSRichard Lowe 				suffix_length = suffix->name->hash.length;
1248*10d63b7dSRichard Lowe 				suf_string.init(suffix->name);
1249*10d63b7dSRichard Lowe 				if (tt->hash.length < suffix_length) {
1250*10d63b7dSRichard Lowe 					continue;
1251*10d63b7dSRichard Lowe 				} else if (!IS_WEQUALN(suf_string.get_string(),
1252*10d63b7dSRichard Lowe 						(target_end - suffix_length),
1253*10d63b7dSRichard Lowe 						suffix_length)) {
1254*10d63b7dSRichard Lowe 					continue;
1255*10d63b7dSRichard Lowe 				}
1256*10d63b7dSRichard Lowe 				target_body = GETNAME(
1257*10d63b7dSRichard Lowe 					targ_string.get_string(),
1258*10d63b7dSRichard Lowe 					(int)(tt->hash.length - suffix_length)
1259*10d63b7dSRichard Lowe 				);
1260*10d63b7dSRichard Lowe 				line->body.line.star = target_body;
1261*10d63b7dSRichard Lowe 			}
1262*10d63b7dSRichard Lowe 
1263*10d63b7dSRichard Lowe 			// set result = build_ok so that implicit rules are not used.
1264*10d63b7dSRichard Lowe 			if(*result == build_dont_know) {
1265*10d63b7dSRichard Lowe 				*result = build_ok;
1266*10d63b7dSRichard Lowe 			}
1267*10d63b7dSRichard Lowe 		}
1268*10d63b7dSRichard Lowe 		if (less != NULL) {
1269*10d63b7dSRichard Lowe 			line->body.line.less = less;
1270*10d63b7dSRichard Lowe 		}
1271*10d63b7dSRichard Lowe 	}
1272*10d63b7dSRichard Lowe 
1273*10d63b7dSRichard Lowe 	return false;
1274*10d63b7dSRichard Lowe }
1275*10d63b7dSRichard Lowe 
1276*10d63b7dSRichard Lowe /*
1277*10d63b7dSRichard Lowe  *	dynamic_dependencies(target)
1278*10d63b7dSRichard Lowe  *
1279*10d63b7dSRichard Lowe  *	Checks if any dependency contains a macro ref
1280*10d63b7dSRichard Lowe  *	If so, it replaces the dependency with the expanded version.
1281*10d63b7dSRichard Lowe  *	Here, "$@" gets translated to target->string. That is
1282*10d63b7dSRichard Lowe  *	the current name on the left of the colon in the
1283*10d63b7dSRichard Lowe  *	makefile.  Thus,
1284*10d63b7dSRichard Lowe  *		xyz:	s.$@.c
1285*10d63b7dSRichard Lowe  *	translates into
1286*10d63b7dSRichard Lowe  *		xyz:	s.xyz.c
1287*10d63b7dSRichard Lowe  *
1288*10d63b7dSRichard Lowe  *	Also, "$(@F)" translates to the same thing without a preceeding
1289*10d63b7dSRichard Lowe  *	directory path (if one exists).
1290*10d63b7dSRichard Lowe  *	Note, to enter "$@" on a dependency line in a makefile
1291*10d63b7dSRichard Lowe  *	"$$@" must be typed. This is because make expands
1292*10d63b7dSRichard Lowe  *	macros in dependency lists upon reading them.
1293*10d63b7dSRichard Lowe  *	dynamic_dependencies() also expands file wildcards.
1294*10d63b7dSRichard Lowe  *	If there are any Shell meta characters in the name,
1295*10d63b7dSRichard Lowe  *	search the directory, and replace the dependency
1296*10d63b7dSRichard Lowe  *	with the set of files the pattern matches
1297*10d63b7dSRichard Lowe  *
1298*10d63b7dSRichard Lowe  *	Parameters:
1299*10d63b7dSRichard Lowe  *		target		Target to sanitize dependencies for
1300*10d63b7dSRichard Lowe  *
1301*10d63b7dSRichard Lowe  *	Global variables used:
1302*10d63b7dSRichard Lowe  *		c_at		The Name "@", used to set macro value
1303*10d63b7dSRichard Lowe  *		debug_level	Should we trace actions?
1304*10d63b7dSRichard Lowe  *		dot		The Name ".", used to read directory
1305*10d63b7dSRichard Lowe  *		recursion_level	Used for tracing
1306*10d63b7dSRichard Lowe  */
1307*10d63b7dSRichard Lowe void
1308*10d63b7dSRichard Lowe dynamic_dependencies(Name target)
1309*10d63b7dSRichard Lowe {
1310*10d63b7dSRichard Lowe 	wchar_t			pattern[MAXPATHLEN];
1311*10d63b7dSRichard Lowe 	register wchar_t	*p;
1312*10d63b7dSRichard Lowe 	Property		line;
1313*10d63b7dSRichard Lowe 	register Dependency	dependency;
1314*10d63b7dSRichard Lowe 	register Dependency	*remove;
1315*10d63b7dSRichard Lowe 	String_rec		string;
1316*10d63b7dSRichard Lowe 	wchar_t			buffer[MAXPATHLEN];
1317*10d63b7dSRichard Lowe 	register Boolean	set_at = false;
1318*10d63b7dSRichard Lowe 	register wchar_t	*start;
1319*10d63b7dSRichard Lowe 	Dependency		new_depe;
1320*10d63b7dSRichard Lowe 	register Boolean	reuse_cell;
1321*10d63b7dSRichard Lowe 	Dependency		first_member;
1322*10d63b7dSRichard Lowe 	Name			directory;
1323*10d63b7dSRichard Lowe 	Name			lib;
1324*10d63b7dSRichard Lowe 	Name			member;
1325*10d63b7dSRichard Lowe 	Property		prop;
1326*10d63b7dSRichard Lowe 	Name			true_target = target;
1327*10d63b7dSRichard Lowe 	wchar_t			*library;
1328*10d63b7dSRichard Lowe 
1329*10d63b7dSRichard Lowe 	if ((line = get_prop(target->prop, line_prop)) == NULL) {
1330*10d63b7dSRichard Lowe 		return;
1331*10d63b7dSRichard Lowe 	}
1332*10d63b7dSRichard Lowe 	/* If the target is constructed from a "::" target we consider that */
1333*10d63b7dSRichard Lowe 	if (target->has_target_prop) {
1334*10d63b7dSRichard Lowe 		true_target = get_prop(target->prop,
1335*10d63b7dSRichard Lowe 				       target_prop)->body.target.target;
1336*10d63b7dSRichard Lowe 	}
1337*10d63b7dSRichard Lowe 	/* Scan all dependencies and process the ones that contain "$" chars */
1338*10d63b7dSRichard Lowe 	for (dependency = line->body.line.dependencies;
1339*10d63b7dSRichard Lowe 	     dependency != NULL;
1340*10d63b7dSRichard Lowe 	     dependency = dependency->next) {
1341*10d63b7dSRichard Lowe 		if (!dependency->name->dollar) {
1342*10d63b7dSRichard Lowe 			continue;
1343*10d63b7dSRichard Lowe 		}
1344*10d63b7dSRichard Lowe 		target->has_depe_list_expanded = true;
1345*10d63b7dSRichard Lowe 
1346*10d63b7dSRichard Lowe 		/* The make macro $@ is bound to the target name once per */
1347*10d63b7dSRichard Lowe 		/* invocation of dynamic_dependencies() */
1348*10d63b7dSRichard Lowe 		if (!set_at) {
1349*10d63b7dSRichard Lowe 			(void) SETVAR(c_at, true_target, false);
1350*10d63b7dSRichard Lowe 			set_at = true;
1351*10d63b7dSRichard Lowe 		}
1352*10d63b7dSRichard Lowe 		/* Expand this dependency string */
1353*10d63b7dSRichard Lowe 		INIT_STRING_FROM_STACK(string, buffer);
1354*10d63b7dSRichard Lowe 		expand_value(dependency->name, &string, false);
1355*10d63b7dSRichard Lowe 		/* Scan the expanded string. It could contain whitespace */
1356*10d63b7dSRichard Lowe 		/* which mean it expands to several dependencies */
1357*10d63b7dSRichard Lowe 		start = string.buffer.start;
1358*10d63b7dSRichard Lowe 		while (iswspace(*start)) {
1359*10d63b7dSRichard Lowe 			start++;
1360*10d63b7dSRichard Lowe 		}
1361*10d63b7dSRichard Lowe 		/* Remove the cell (later) if the macro was empty */
1362*10d63b7dSRichard Lowe 		if (start[0] == (int) nul_char) {
1363*10d63b7dSRichard Lowe 			dependency->name = NULL;
1364*10d63b7dSRichard Lowe 		}
1365*10d63b7dSRichard Lowe 
1366*10d63b7dSRichard Lowe /* azv 10/26/95 to fix bug BID_1170218 */
1367*10d63b7dSRichard Lowe 		if ((start[0] == (int) period_char) &&
1368*10d63b7dSRichard Lowe 		    (start[1] == (int) slash_char)) {
1369*10d63b7dSRichard Lowe 			start += 2;
1370*10d63b7dSRichard Lowe 		}
1371*10d63b7dSRichard Lowe /* azv */
1372*10d63b7dSRichard Lowe 
1373*10d63b7dSRichard Lowe 		first_member = NULL;
1374*10d63b7dSRichard Lowe 		/* We use the original dependency cell for the first */
1375*10d63b7dSRichard Lowe 		/* dependency from the expansion */
1376*10d63b7dSRichard Lowe 		reuse_cell = true;
1377*10d63b7dSRichard Lowe 		/* We also have to deal with dependencies that expand to */
1378*10d63b7dSRichard Lowe 		/* lib.a(members) notation */
1379*10d63b7dSRichard Lowe 		for (p = start; *p != (int) nul_char; p++) {
1380*10d63b7dSRichard Lowe 			if ((*p == (int) parenleft_char)) {
1381*10d63b7dSRichard Lowe 				lib = GETNAME(start, p - start);
1382*10d63b7dSRichard Lowe 				lib->is_member = true;
1383*10d63b7dSRichard Lowe 				first_member = dependency;
1384*10d63b7dSRichard Lowe 				start = p + 1;
1385*10d63b7dSRichard Lowe 				while (iswspace(*start)) {
1386*10d63b7dSRichard Lowe 					start++;
1387*10d63b7dSRichard Lowe 				}
1388*10d63b7dSRichard Lowe 				break;
1389*10d63b7dSRichard Lowe 			}
1390*10d63b7dSRichard Lowe 		}
1391*10d63b7dSRichard Lowe 		do {
1392*10d63b7dSRichard Lowe 		    /* First skip whitespace */
1393*10d63b7dSRichard Lowe 			for (p = start; *p != (int) nul_char; p++) {
1394*10d63b7dSRichard Lowe 				if ((*p == (int) nul_char) ||
1395*10d63b7dSRichard Lowe 				    iswspace(*p) ||
1396*10d63b7dSRichard Lowe 				    (*p == (int) parenright_char)) {
1397*10d63b7dSRichard Lowe 					break;
1398*10d63b7dSRichard Lowe 				}
1399*10d63b7dSRichard Lowe 			}
1400*10d63b7dSRichard Lowe 			/* Enter dependency from expansion */
1401*10d63b7dSRichard Lowe 			if (p != start) {
1402*10d63b7dSRichard Lowe 				/* Create new dependency cell if */
1403*10d63b7dSRichard Lowe 				/* this is not the first dependency */
1404*10d63b7dSRichard Lowe 				/* picked from the expansion */
1405*10d63b7dSRichard Lowe 				if (!reuse_cell) {
1406*10d63b7dSRichard Lowe 					new_depe = ALLOC(Dependency);
1407*10d63b7dSRichard Lowe 					new_depe->next = dependency->next;
1408*10d63b7dSRichard Lowe 					new_depe->automatic = false;
1409*10d63b7dSRichard Lowe 					new_depe->stale = false;
1410*10d63b7dSRichard Lowe 					new_depe->built = false;
1411*10d63b7dSRichard Lowe 					dependency->next = new_depe;
1412*10d63b7dSRichard Lowe 					dependency = new_depe;
1413*10d63b7dSRichard Lowe 				}
1414*10d63b7dSRichard Lowe 				reuse_cell = false;
1415*10d63b7dSRichard Lowe 				/* Internalize the dependency name */
1416*10d63b7dSRichard Lowe 				// tolik. Fix for bug 4110429: inconsistent expansion for macros that
1417*10d63b7dSRichard Lowe 				// include "//" and "/./"
1418*10d63b7dSRichard Lowe 				//dependency->name = GETNAME(start, p - start);
1419*10d63b7dSRichard Lowe 				dependency->name = normalize_name(start, p - start);
1420*10d63b7dSRichard Lowe 				if ((debug_level > 0) &&
1421*10d63b7dSRichard Lowe 				    (first_member == NULL)) {
1422*10d63b7dSRichard Lowe 					(void) printf(gettext("%*sDynamic dependency `%s' for target `%s'\n"),
1423*10d63b7dSRichard Lowe 						      recursion_level,
1424*10d63b7dSRichard Lowe 						      "",
1425*10d63b7dSRichard Lowe 						      dependency->name->string_mb,
1426*10d63b7dSRichard Lowe 						      true_target->string_mb);
1427*10d63b7dSRichard Lowe 				}
1428*10d63b7dSRichard Lowe 				for (start = p; iswspace(*start); start++);
1429*10d63b7dSRichard Lowe 				p = start;
1430*10d63b7dSRichard Lowe 			}
1431*10d63b7dSRichard Lowe 		} while ((*p != (int) nul_char) &&
1432*10d63b7dSRichard Lowe 			 (*p != (int) parenright_char));
1433*10d63b7dSRichard Lowe 		/* If the expansion was of lib.a(members) format we now */
1434*10d63b7dSRichard Lowe 		/* enter the proper member cells */
1435*10d63b7dSRichard Lowe 		if (first_member != NULL) {
1436*10d63b7dSRichard Lowe 			/* Scan the new dependencies and transform them from */
1437*10d63b7dSRichard Lowe 			/* "foo" to "lib.a(foo)" */
1438*10d63b7dSRichard Lowe 			for (; 1; first_member = first_member->next) {
1439*10d63b7dSRichard Lowe 				/* Build "lib.a(foo)" name */
1440*10d63b7dSRichard Lowe 				INIT_STRING_FROM_STACK(string, buffer);
1441*10d63b7dSRichard Lowe 				APPEND_NAME(lib,
1442*10d63b7dSRichard Lowe 					      &string,
1443*10d63b7dSRichard Lowe 					      (int) lib->hash.length);
1444*10d63b7dSRichard Lowe 				append_char((int) parenleft_char, &string);
1445*10d63b7dSRichard Lowe 				APPEND_NAME(first_member->name,
1446*10d63b7dSRichard Lowe 					      &string,
1447*10d63b7dSRichard Lowe 					      FIND_LENGTH);
1448*10d63b7dSRichard Lowe 				append_char((int) parenright_char, &string);
1449*10d63b7dSRichard Lowe 				member = first_member->name;
1450*10d63b7dSRichard Lowe 				/* Replace "foo" with "lib.a(foo)" */
1451*10d63b7dSRichard Lowe 				first_member->name =
1452*10d63b7dSRichard Lowe 				  GETNAME(string.buffer.start, FIND_LENGTH);
1453*10d63b7dSRichard Lowe 				if (string.free_after_use) {
1454*10d63b7dSRichard Lowe 					retmem(string.buffer.start);
1455*10d63b7dSRichard Lowe 				}
1456*10d63b7dSRichard Lowe 				if (debug_level > 0) {
1457*10d63b7dSRichard Lowe 					(void) printf(gettext("%*sDynamic dependency `%s' for target `%s'\n"),
1458*10d63b7dSRichard Lowe 						      recursion_level,
1459*10d63b7dSRichard Lowe 						      "",
1460*10d63b7dSRichard Lowe 						      first_member->name->
1461*10d63b7dSRichard Lowe 						      string_mb,
1462*10d63b7dSRichard Lowe 						      true_target->string_mb);
1463*10d63b7dSRichard Lowe 				}
1464*10d63b7dSRichard Lowe 				first_member->name->is_member = lib->is_member;
1465*10d63b7dSRichard Lowe 				/* Add member property to member */
1466*10d63b7dSRichard Lowe 				prop = maybe_append_prop(first_member->name,
1467*10d63b7dSRichard Lowe 							 member_prop);
1468*10d63b7dSRichard Lowe 				prop->body.member.library = lib;
1469*10d63b7dSRichard Lowe 				prop->body.member.entry = NULL;
1470*10d63b7dSRichard Lowe 				prop->body.member.member = member;
1471*10d63b7dSRichard Lowe 				if (first_member == dependency) {
1472*10d63b7dSRichard Lowe 					break;
1473*10d63b7dSRichard Lowe 				}
1474*10d63b7dSRichard Lowe 			}
1475*10d63b7dSRichard Lowe 		}
1476*10d63b7dSRichard Lowe 	}
1477*10d63b7dSRichard Lowe 	Wstring wcb;
1478*10d63b7dSRichard Lowe 	/* Then scan all the dependencies again. This time we want to expand */
1479*10d63b7dSRichard Lowe 	/* shell file wildcards */
1480*10d63b7dSRichard Lowe 	for (remove = &line->body.line.dependencies, dependency = *remove;
1481*10d63b7dSRichard Lowe 	     dependency != NULL;
1482*10d63b7dSRichard Lowe 	     dependency = *remove) {
1483*10d63b7dSRichard Lowe 		if (dependency->name == NULL) {
1484*10d63b7dSRichard Lowe 			dependency = *remove = (*remove)->next;
1485*10d63b7dSRichard Lowe 			continue;
1486*10d63b7dSRichard Lowe 		}
1487*10d63b7dSRichard Lowe 		/* If dependency name string contains shell wildcards */
1488*10d63b7dSRichard Lowe 		/* replace the name with the expansion */
1489*10d63b7dSRichard Lowe 		if (dependency->name->wildcard) {
1490*10d63b7dSRichard Lowe 			wcb.init(dependency->name);
1491*10d63b7dSRichard Lowe 			if ((start = (wchar_t *) wcschr(wcb.get_string(),
1492*10d63b7dSRichard Lowe 					   (int) parenleft_char)) != NULL) {
1493*10d63b7dSRichard Lowe 				/* lib(*) type pattern */
1494*10d63b7dSRichard Lowe 				library = buffer;
1495*10d63b7dSRichard Lowe 				(void) wcsncpy(buffer,
1496*10d63b7dSRichard Lowe 					      wcb.get_string(),
1497*10d63b7dSRichard Lowe 					      start - wcb.get_string());
1498*10d63b7dSRichard Lowe 				buffer[start-wcb.get_string()] =
1499*10d63b7dSRichard Lowe 				  (int) nul_char;
1500*10d63b7dSRichard Lowe 				(void) wcsncpy(pattern,
1501*10d63b7dSRichard Lowe 					      start + 1,
1502*10d63b7dSRichard Lowe (int) (dependency->name->hash.length-(start-wcb.get_string())-2));
1503*10d63b7dSRichard Lowe 				pattern[dependency->name->hash.length -
1504*10d63b7dSRichard Lowe 					(start-wcb.get_string()) - 2] =
1505*10d63b7dSRichard Lowe 					  (int) nul_char;
1506*10d63b7dSRichard Lowe 			} else {
1507*10d63b7dSRichard Lowe 				library = NULL;
1508*10d63b7dSRichard Lowe 				(void) wcsncpy(pattern,
1509*10d63b7dSRichard Lowe 					      wcb.get_string(),
1510*10d63b7dSRichard Lowe 					      (int) dependency->name->hash.length);
1511*10d63b7dSRichard Lowe 				pattern[dependency->name->hash.length] =
1512*10d63b7dSRichard Lowe 				  (int) nul_char;
1513*10d63b7dSRichard Lowe 			}
1514*10d63b7dSRichard Lowe 			start = (wchar_t *) wcsrchr(pattern, (int) slash_char);
1515*10d63b7dSRichard Lowe 			if (start == NULL) {
1516*10d63b7dSRichard Lowe 				directory = dot;
1517*10d63b7dSRichard Lowe 				p = pattern;
1518*10d63b7dSRichard Lowe 			} else {
1519*10d63b7dSRichard Lowe 				directory = GETNAME(pattern, start-pattern);
1520*10d63b7dSRichard Lowe 				p = start+1;
1521*10d63b7dSRichard Lowe 			}
1522*10d63b7dSRichard Lowe 			/* The expansion is handled by the read_dir() routine*/
1523*10d63b7dSRichard Lowe 			if (read_dir(directory, p, line, library)) {
1524*10d63b7dSRichard Lowe 				*remove = (*remove)->next;
1525*10d63b7dSRichard Lowe 			} else {
1526*10d63b7dSRichard Lowe 				remove = &dependency->next;
1527*10d63b7dSRichard Lowe 			}
1528*10d63b7dSRichard Lowe 		} else {
1529*10d63b7dSRichard Lowe 			remove = &dependency->next;
1530*10d63b7dSRichard Lowe 		}
1531*10d63b7dSRichard Lowe         }
1532*10d63b7dSRichard Lowe 
1533*10d63b7dSRichard Lowe 	/* Then unbind $@ */
1534*10d63b7dSRichard Lowe 	(void) SETVAR(c_at, (Name) NULL, false);
1535*10d63b7dSRichard Lowe }
1536*10d63b7dSRichard Lowe 
1537*10d63b7dSRichard Lowe /*
1538*10d63b7dSRichard Lowe  * DONE.
1539*10d63b7dSRichard Lowe  *
1540*10d63b7dSRichard Lowe  *	run_command(line)
1541*10d63b7dSRichard Lowe  *
1542*10d63b7dSRichard Lowe  *	Takes one Cmd_line and runs the commands from it.
1543*10d63b7dSRichard Lowe  *
1544*10d63b7dSRichard Lowe  *	Return value:
1545*10d63b7dSRichard Lowe  *				Indicates if the command failed or not
1546*10d63b7dSRichard Lowe  *
1547*10d63b7dSRichard Lowe  *	Parameters:
1548*10d63b7dSRichard Lowe  *		line		The command line to run
1549*10d63b7dSRichard Lowe  *
1550*10d63b7dSRichard Lowe  *	Global variables used:
1551*10d63b7dSRichard Lowe  *		commands_done	Set if we do run command
1552*10d63b7dSRichard Lowe  *		current_line	Set to the line we run a command from
1553*10d63b7dSRichard Lowe  *		current_target	Set to the target we run a command for
1554*10d63b7dSRichard Lowe  *		file_number	Used to form temp file name
1555*10d63b7dSRichard Lowe  *		keep_state	Indicates that .KEEP_STATE is on
1556*10d63b7dSRichard Lowe  *		make_state	The Name ".make.state", used to check timestamp
1557*10d63b7dSRichard Lowe  *		parallel	True if currently building in parallel
1558*10d63b7dSRichard Lowe  *		parallel_process_cnt Count of parallel processes running
1559*10d63b7dSRichard Lowe  *		quest		Indicates that make -q is on
1560*10d63b7dSRichard Lowe  *		rewrite_statefile Set if we do run a command
1561*10d63b7dSRichard Lowe  *		sunpro_dependencies The Name "SUNPRO_DEPENDENCIES", set value
1562*10d63b7dSRichard Lowe  *		temp_file_directory Used to form temp fie name
1563*10d63b7dSRichard Lowe  *		temp_file_name	Set to the name of the temp file
1564*10d63b7dSRichard Lowe  *		touch		Indicates that make -t is on
1565*10d63b7dSRichard Lowe  */
1566*10d63b7dSRichard Lowe static Doname
1567*10d63b7dSRichard Lowe run_command(register Property line, Boolean)
1568*10d63b7dSRichard Lowe {
1569*10d63b7dSRichard Lowe 	register Doname		result = build_ok;
1570*10d63b7dSRichard Lowe 	register Boolean	remember_only = false;
1571*10d63b7dSRichard Lowe 	register Name		target = line->body.line.target;
1572*10d63b7dSRichard Lowe 	wchar_t			*string;
1573*10d63b7dSRichard Lowe 	char			tmp_file_path[MAXPATHLEN];
1574*10d63b7dSRichard Lowe 
1575*10d63b7dSRichard Lowe 	if (!line->body.line.is_out_of_date && target->rechecking_target) {
1576*10d63b7dSRichard Lowe 		target->rechecking_target = false;
1577*10d63b7dSRichard Lowe 		return build_ok;
1578*10d63b7dSRichard Lowe 	}
1579*10d63b7dSRichard Lowe 
1580*10d63b7dSRichard Lowe 	/*
1581*10d63b7dSRichard Lowe 	 * Build the command if we know the target is out of date,
1582*10d63b7dSRichard Lowe 	 * or if we want to check cmd consistency.
1583*10d63b7dSRichard Lowe 	 */
1584*10d63b7dSRichard Lowe 	if (line->body.line.is_out_of_date || keep_state) {
1585*10d63b7dSRichard Lowe 		/* Hack for handling conditional macros in DMake. */
1586*10d63b7dSRichard Lowe 		if (!line->body.line.dont_rebuild_command_used) {
1587*10d63b7dSRichard Lowe 			build_command_strings(target, line);
1588*10d63b7dSRichard Lowe 		}
1589*10d63b7dSRichard Lowe 	}
1590*10d63b7dSRichard Lowe 	/* Never mind */
1591*10d63b7dSRichard Lowe 	if (!line->body.line.is_out_of_date) {
1592*10d63b7dSRichard Lowe 		return build_ok;
1593*10d63b7dSRichard Lowe 	}
1594*10d63b7dSRichard Lowe 	/* If quest, then exit(1) because the target is out of date */
1595*10d63b7dSRichard Lowe 	if (quest) {
1596*10d63b7dSRichard Lowe 		if (posix) {
1597*10d63b7dSRichard Lowe 			result = execute_parallel(line, true);
1598*10d63b7dSRichard Lowe 		}
1599*10d63b7dSRichard Lowe 		exit_status = 1;
1600*10d63b7dSRichard Lowe 		exit(1);
1601*10d63b7dSRichard Lowe 	}
1602*10d63b7dSRichard Lowe 	/* We actually had to do something this time */
1603*10d63b7dSRichard Lowe 	rewrite_statefile = commands_done = true;
1604*10d63b7dSRichard Lowe 	/*
1605*10d63b7dSRichard Lowe 	 * If this is an sccs command, we have to do some extra checking
1606*10d63b7dSRichard Lowe 	 * and possibly complain. If the file can't be gotten because it's
1607*10d63b7dSRichard Lowe 	 * checked out, we complain and behave as if the command was
1608*10d63b7dSRichard Lowe 	 * executed eventhough we ignored the command.
1609*10d63b7dSRichard Lowe 	 */
1610*10d63b7dSRichard Lowe 	if (!touch &&
1611*10d63b7dSRichard Lowe 	    line->body.line.sccs_command &&
1612*10d63b7dSRichard Lowe 	    (target->stat.time != file_doesnt_exist) &&
1613*10d63b7dSRichard Lowe 	    ((target->stat.mode & 0222) != 0)) {
1614*10d63b7dSRichard Lowe 		fatal(gettext("%s is writable so it cannot be sccs gotten"),
1615*10d63b7dSRichard Lowe 		      target->string_mb);
1616*10d63b7dSRichard Lowe 		target->has_complained = remember_only = true;
1617*10d63b7dSRichard Lowe 	}
1618*10d63b7dSRichard Lowe 	/*
1619*10d63b7dSRichard Lowe 	 * If KEEP_STATE is on, we make sure we have the timestamp for
1620*10d63b7dSRichard Lowe 	 * .make.state. If .make.state changes during the command run,
1621*10d63b7dSRichard Lowe 	 * we reread .make.state after the command. We also setup the
1622*10d63b7dSRichard Lowe 	 * environment variable that asks utilities to report dependencies.
1623*10d63b7dSRichard Lowe 	 */
1624*10d63b7dSRichard Lowe 	if (!touch &&
1625*10d63b7dSRichard Lowe 	    keep_state &&
1626*10d63b7dSRichard Lowe 	    !remember_only) {
1627*10d63b7dSRichard Lowe 		(void) exists(make_state);
1628*10d63b7dSRichard Lowe 		if((strlen(temp_file_directory) == 1) &&
1629*10d63b7dSRichard Lowe 			(temp_file_directory[0] == '/')) {
1630*10d63b7dSRichard Lowe 		   tmp_file_path[0] = '\0';
1631*10d63b7dSRichard Lowe 		} else {
1632*10d63b7dSRichard Lowe 		   strcpy(tmp_file_path, temp_file_directory);
1633*10d63b7dSRichard Lowe 		}
1634*10d63b7dSRichard Lowe 		sprintf(mbs_buffer,
1635*10d63b7dSRichard Lowe 				"%s/.make.dependency.%08x.%d.%d",
1636*10d63b7dSRichard Lowe 			        tmp_file_path,
1637*10d63b7dSRichard Lowe 			        hostid,
1638*10d63b7dSRichard Lowe 			        getpid(),
1639*10d63b7dSRichard Lowe 			        file_number++);
1640*10d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, mbs_buffer);
1641*10d63b7dSRichard Lowe 		Boolean fnd;
1642*10d63b7dSRichard Lowe 		temp_file_name = getname_fn(wcs_buffer, FIND_LENGTH, false, &fnd);
1643*10d63b7dSRichard Lowe 		temp_file_name->stat.is_file = true;
1644*10d63b7dSRichard Lowe 		int len = 2*MAXPATHLEN + strlen(target->string_mb) + 2;
1645*10d63b7dSRichard Lowe 		wchar_t *to = string = ALLOC_WC(len);
1646*10d63b7dSRichard Lowe 		for (wchar_t *from = wcs_buffer; *from != (int) nul_char; ) {
1647*10d63b7dSRichard Lowe 			if (*from == (int) space_char) {
1648*10d63b7dSRichard Lowe 				*to++ = (int) backslash_char;
1649*10d63b7dSRichard Lowe 			}
1650*10d63b7dSRichard Lowe 			*to++ = *from++;
1651*10d63b7dSRichard Lowe 		}
1652*10d63b7dSRichard Lowe 		*to++ = (int) space_char;
1653*10d63b7dSRichard Lowe 		MBSTOWCS(to, target->string_mb);
1654*10d63b7dSRichard Lowe 		Name sprodep_name = getname_fn(string, FIND_LENGTH, false, &fnd);
1655*10d63b7dSRichard Lowe 		(void) SETVAR(sunpro_dependencies,
1656*10d63b7dSRichard Lowe 			      sprodep_name,
1657*10d63b7dSRichard Lowe 			      false);
1658*10d63b7dSRichard Lowe 		retmem(string);
1659*10d63b7dSRichard Lowe 	} else {
1660*10d63b7dSRichard Lowe 		temp_file_name = NULL;
1661*10d63b7dSRichard Lowe 	}
1662*10d63b7dSRichard Lowe 
1663*10d63b7dSRichard Lowe 	/*
1664*10d63b7dSRichard Lowe 	 * In case we are interrupted, we need to know what was going on.
1665*10d63b7dSRichard Lowe 	 */
1666*10d63b7dSRichard Lowe 	current_target = target;
1667*10d63b7dSRichard Lowe 	/*
1668*10d63b7dSRichard Lowe 	 * We also need to be able to save an empty command instead of the
1669*10d63b7dSRichard Lowe 	 * interrupted one in .make.state.
1670*10d63b7dSRichard Lowe 	 */
1671*10d63b7dSRichard Lowe 	current_line = line;
1672*10d63b7dSRichard Lowe 	if (remember_only) {
1673*10d63b7dSRichard Lowe 		/* Empty block!!! */
1674*10d63b7dSRichard Lowe 	} else if (touch) {
1675*10d63b7dSRichard Lowe 		result = touch_command(line, target, result);
1676*10d63b7dSRichard Lowe 		if (posix) {
1677*10d63b7dSRichard Lowe 			result = execute_parallel(line, true);
1678*10d63b7dSRichard Lowe 		}
1679*10d63b7dSRichard Lowe 	} else {
1680*10d63b7dSRichard Lowe 		/*
1681*10d63b7dSRichard Lowe 		 * If this is not a touch run, we need to execute the
1682*10d63b7dSRichard Lowe 		 * proper command(s) for the target.
1683*10d63b7dSRichard Lowe 		 */
1684*10d63b7dSRichard Lowe 		if (parallel) {
1685*10d63b7dSRichard Lowe 			if (!parallel_ok(target, true)) {
1686*10d63b7dSRichard Lowe 				/*
1687*10d63b7dSRichard Lowe 				 * We are building in parallel, but
1688*10d63b7dSRichard Lowe 				 * this target must be built in serial.
1689*10d63b7dSRichard Lowe 				 */
1690*10d63b7dSRichard Lowe 				/*
1691*10d63b7dSRichard Lowe 				 * If nothing else is building,
1692*10d63b7dSRichard Lowe 				 * do this one, else wait.
1693*10d63b7dSRichard Lowe 				 */
1694*10d63b7dSRichard Lowe 				if (parallel_process_cnt == 0) {
1695*10d63b7dSRichard Lowe 					result = execute_parallel(line, true, target->localhost);
1696*10d63b7dSRichard Lowe 				} else {
1697*10d63b7dSRichard Lowe 					current_target = NULL;
1698*10d63b7dSRichard Lowe 					current_line = NULL;
1699*10d63b7dSRichard Lowe /*
1700*10d63b7dSRichard Lowe 					line->body.line.command_used = NULL;
1701*10d63b7dSRichard Lowe  */
1702*10d63b7dSRichard Lowe 					line->body.line.dont_rebuild_command_used = true;
1703*10d63b7dSRichard Lowe 					return build_serial;
1704*10d63b7dSRichard Lowe 				}
1705*10d63b7dSRichard Lowe 			} else {
1706*10d63b7dSRichard Lowe 				result = execute_parallel(line, false);
1707*10d63b7dSRichard Lowe 				switch (result) {
1708*10d63b7dSRichard Lowe 				case build_running:
1709*10d63b7dSRichard Lowe 					return build_running;
1710*10d63b7dSRichard Lowe 				case build_serial:
1711*10d63b7dSRichard Lowe 					if (parallel_process_cnt == 0) {
1712*10d63b7dSRichard Lowe 						result = execute_parallel(line, true, target->localhost);
1713*10d63b7dSRichard Lowe 					} else {
1714*10d63b7dSRichard Lowe 						current_target = NULL;
1715*10d63b7dSRichard Lowe 						current_line = NULL;
1716*10d63b7dSRichard Lowe 						target->parallel = false;
1717*10d63b7dSRichard Lowe 						line->body.line.command_used =
1718*10d63b7dSRichard Lowe 						  			NULL;
1719*10d63b7dSRichard Lowe 						return build_serial;
1720*10d63b7dSRichard Lowe 					}
1721*10d63b7dSRichard Lowe 				}
1722*10d63b7dSRichard Lowe 			}
1723*10d63b7dSRichard Lowe 		} else {
1724*10d63b7dSRichard Lowe 			result = execute_parallel(line, true, target->localhost);
1725*10d63b7dSRichard Lowe 		}
1726*10d63b7dSRichard Lowe 	}
1727*10d63b7dSRichard Lowe 	temp_file_name = NULL;
1728*10d63b7dSRichard Lowe 	if (report_dependencies_level == 0){
1729*10d63b7dSRichard Lowe 		update_target(line, result);
1730*10d63b7dSRichard Lowe 	}
1731*10d63b7dSRichard Lowe 	current_target = NULL;
1732*10d63b7dSRichard Lowe 	current_line = NULL;
1733*10d63b7dSRichard Lowe 	return result;
1734*10d63b7dSRichard Lowe }
1735*10d63b7dSRichard Lowe 
1736*10d63b7dSRichard Lowe /*
1737*10d63b7dSRichard Lowe  *	execute_serial(line)
1738*10d63b7dSRichard Lowe  *
1739*10d63b7dSRichard Lowe  *	Runs thru the command line for the target and
1740*10d63b7dSRichard Lowe  *	executes the rules one by one.
1741*10d63b7dSRichard Lowe  *
1742*10d63b7dSRichard Lowe  *	Return value:
1743*10d63b7dSRichard Lowe  *				The result of the command build
1744*10d63b7dSRichard Lowe  *
1745*10d63b7dSRichard Lowe  *	Parameters:
1746*10d63b7dSRichard Lowe  *		line		The command to execute
1747*10d63b7dSRichard Lowe  *
1748*10d63b7dSRichard Lowe  *	Static variables used:
1749*10d63b7dSRichard Lowe  *
1750*10d63b7dSRichard Lowe  *	Global variables used:
1751*10d63b7dSRichard Lowe  *		continue_after_error -k flag
1752*10d63b7dSRichard Lowe  *		do_not_exec_rule -n flag
1753*10d63b7dSRichard Lowe  *		report_dependencies -P flag
1754*10d63b7dSRichard Lowe  *		silent		Don't echo commands before executing
1755*10d63b7dSRichard Lowe  *		temp_file_name	Temp file for auto dependencies
1756*10d63b7dSRichard Lowe  *		vpath_defined	If true, translate path for command
1757*10d63b7dSRichard Lowe  */
1758*10d63b7dSRichard Lowe Doname
1759*10d63b7dSRichard Lowe execute_serial(Property line)
1760*10d63b7dSRichard Lowe {
1761*10d63b7dSRichard Lowe 	int			child_pid = 0;
1762*10d63b7dSRichard Lowe 	Boolean			printed_serial;
1763*10d63b7dSRichard Lowe 	Doname			result = build_ok;
1764*10d63b7dSRichard Lowe 	Cmd_line		rule, cmd_tail, command = NULL;
1765*10d63b7dSRichard Lowe 	char			mbstring[MAXPATHLEN];
1766*10d63b7dSRichard Lowe 	int			filed;
1767*10d63b7dSRichard Lowe 	Name			target = line->body.line.target;
1768*10d63b7dSRichard Lowe 
1769*10d63b7dSRichard Lowe 	target->has_recursive_dependency = false;
1770*10d63b7dSRichard Lowe 	// We have to create a copy of the rules chain for processing because
1771*10d63b7dSRichard Lowe 	// the original one can be destroyed during .make.state file rereading.
1772*10d63b7dSRichard Lowe 	for (rule = line->body.line.command_used;
1773*10d63b7dSRichard Lowe 	     rule != NULL;
1774*10d63b7dSRichard Lowe 	     rule = rule->next) {
1775*10d63b7dSRichard Lowe 		if (command == NULL) {
1776*10d63b7dSRichard Lowe 			command = cmd_tail = ALLOC(Cmd_line);
1777*10d63b7dSRichard Lowe 		} else {
1778*10d63b7dSRichard Lowe 			cmd_tail->next = ALLOC(Cmd_line);
1779*10d63b7dSRichard Lowe 			cmd_tail = cmd_tail->next;
1780*10d63b7dSRichard Lowe 		}
1781*10d63b7dSRichard Lowe 		*cmd_tail = *rule;
1782*10d63b7dSRichard Lowe 	}
1783*10d63b7dSRichard Lowe 	if (command) {
1784*10d63b7dSRichard Lowe 		cmd_tail->next = NULL;
1785*10d63b7dSRichard Lowe 	}
1786*10d63b7dSRichard Lowe 	for (rule = command; rule != NULL; rule = rule->next) {
1787*10d63b7dSRichard Lowe 		if (posix && (touch || quest) && !rule->always_exec) {
1788*10d63b7dSRichard Lowe 			continue;
1789*10d63b7dSRichard Lowe 		}
1790*10d63b7dSRichard Lowe 		if (vpath_defined) {
1791*10d63b7dSRichard Lowe 			rule->command_line =
1792*10d63b7dSRichard Lowe 			  vpath_translation(rule->command_line);
1793*10d63b7dSRichard Lowe 		}
1794*10d63b7dSRichard Lowe 		/* Echo command line, maybe. */
1795*10d63b7dSRichard Lowe 		if ((rule->command_line->hash.length > 0) &&
1796*10d63b7dSRichard Lowe 		    !silent &&
1797*10d63b7dSRichard Lowe 		    (!rule->silent || do_not_exec_rule) &&
1798*10d63b7dSRichard Lowe 		    (report_dependencies_level == 0)) {
1799*10d63b7dSRichard Lowe 			(void) printf("%s\n", rule->command_line->string_mb);
1800*10d63b7dSRichard Lowe 		}
1801*10d63b7dSRichard Lowe 		if (rule->command_line->hash.length > 0) {
1802*10d63b7dSRichard Lowe 			/* Do assignment if command line prefixed with "=" */
1803*10d63b7dSRichard Lowe 			if (rule->assign) {
1804*10d63b7dSRichard Lowe 				result = build_ok;
1805*10d63b7dSRichard Lowe 				do_assign(rule->command_line, target);
1806*10d63b7dSRichard Lowe 			} else if (report_dependencies_level == 0) {
1807*10d63b7dSRichard Lowe 				/* Execute command line. */
1808*10d63b7dSRichard Lowe 				setvar_envvar();
1809*10d63b7dSRichard Lowe 				result = dosys(rule->command_line,
1810*10d63b7dSRichard Lowe 				               (Boolean) rule->ignore_error,
1811*10d63b7dSRichard Lowe 				               (Boolean) rule->make_refd,
1812*10d63b7dSRichard Lowe 				               /* ds 98.04.23 bug #4085164. make should always show error messages */
1813*10d63b7dSRichard Lowe 				               false,
1814*10d63b7dSRichard Lowe 				               /* BOOLEAN(rule->silent &&
1815*10d63b7dSRichard Lowe 				                       rule->ignore_error), */
1816*10d63b7dSRichard Lowe 				               (Boolean) rule->always_exec,
1817*10d63b7dSRichard Lowe 				               target);
1818*10d63b7dSRichard Lowe 				check_state(temp_file_name);
1819*10d63b7dSRichard Lowe 			}
1820*10d63b7dSRichard Lowe 		} else {
1821*10d63b7dSRichard Lowe 			result = build_ok;
1822*10d63b7dSRichard Lowe 		}
1823*10d63b7dSRichard Lowe 		if (result == build_failed) {
1824*10d63b7dSRichard Lowe 			if (silent || rule->silent) {
1825*10d63b7dSRichard Lowe 				(void) printf(gettext("The following command caused the error:\n%s\n"),
1826*10d63b7dSRichard Lowe 				              rule->command_line->string_mb);
1827*10d63b7dSRichard Lowe 			}
1828*10d63b7dSRichard Lowe 			if (!rule->ignore_error && !ignore_errors) {
1829*10d63b7dSRichard Lowe 				if (!continue_after_error) {
1830*10d63b7dSRichard Lowe 					fatal(gettext("Command failed for target `%s'"),
1831*10d63b7dSRichard Lowe 					      target->string_mb);
1832*10d63b7dSRichard Lowe 				}
1833*10d63b7dSRichard Lowe 				/*
1834*10d63b7dSRichard Lowe 				 * Make sure a failing command is not
1835*10d63b7dSRichard Lowe 				 * saved in .make.state.
1836*10d63b7dSRichard Lowe 				 */
1837*10d63b7dSRichard Lowe 				line->body.line.command_used = NULL;
1838*10d63b7dSRichard Lowe 				break;
1839*10d63b7dSRichard Lowe 			} else {
1840*10d63b7dSRichard Lowe 				result = build_ok;
1841*10d63b7dSRichard Lowe 			}
1842*10d63b7dSRichard Lowe 		}
1843*10d63b7dSRichard Lowe 	}
1844*10d63b7dSRichard Lowe 	for (rule = command; rule != NULL; rule = cmd_tail) {
1845*10d63b7dSRichard Lowe 		cmd_tail = rule->next;
1846*10d63b7dSRichard Lowe 		free(rule);
1847*10d63b7dSRichard Lowe 	}
1848*10d63b7dSRichard Lowe 	command = NULL;
1849*10d63b7dSRichard Lowe 	if (temp_file_name != NULL) {
1850*10d63b7dSRichard Lowe 		free_name(temp_file_name);
1851*10d63b7dSRichard Lowe 	}
1852*10d63b7dSRichard Lowe         temp_file_name = NULL;
1853*10d63b7dSRichard Lowe 
1854*10d63b7dSRichard Lowe 	Property spro = get_prop(sunpro_dependencies->prop, macro_prop);
1855*10d63b7dSRichard Lowe 	if(spro != NULL) {
1856*10d63b7dSRichard Lowe 		Name val = spro->body.macro.value;
1857*10d63b7dSRichard Lowe 		if(val != NULL) {
1858*10d63b7dSRichard Lowe 			free_name(val);
1859*10d63b7dSRichard Lowe 			spro->body.macro.value = NULL;
1860*10d63b7dSRichard Lowe 		}
1861*10d63b7dSRichard Lowe 	}
1862*10d63b7dSRichard Lowe 	spro = get_prop(sunpro_dependencies->prop, env_mem_prop);
1863*10d63b7dSRichard Lowe 	if(spro) {
1864*10d63b7dSRichard Lowe 		char *val = spro->body.env_mem.value;
1865*10d63b7dSRichard Lowe 		if(val != NULL) {
1866*10d63b7dSRichard Lowe 			/*
1867*10d63b7dSRichard Lowe 			 * Do not return memory allocated for SUNPRO_DEPENDENCIES
1868*10d63b7dSRichard Lowe 			 * It will be returned in setvar_daemon() in macro.cc
1869*10d63b7dSRichard Lowe 			 */
1870*10d63b7dSRichard Lowe 			//	retmem_mb(val);
1871*10d63b7dSRichard Lowe 			spro->body.env_mem.value = NULL;
1872*10d63b7dSRichard Lowe 		}
1873*10d63b7dSRichard Lowe 	}
1874*10d63b7dSRichard Lowe 
1875*10d63b7dSRichard Lowe         return result;
1876*10d63b7dSRichard Lowe }
1877*10d63b7dSRichard Lowe 
1878*10d63b7dSRichard Lowe 
1879*10d63b7dSRichard Lowe 
1880*10d63b7dSRichard Lowe /*
1881*10d63b7dSRichard Lowe  *	vpath_translation(cmd)
1882*10d63b7dSRichard Lowe  *
1883*10d63b7dSRichard Lowe  *	Translates one command line by
1884*10d63b7dSRichard Lowe  *	checking each word. If the word has an alias it is translated.
1885*10d63b7dSRichard Lowe  *
1886*10d63b7dSRichard Lowe  *	Return value:
1887*10d63b7dSRichard Lowe  *				The translated command
1888*10d63b7dSRichard Lowe  *
1889*10d63b7dSRichard Lowe  *	Parameters:
1890*10d63b7dSRichard Lowe  *		cmd		Command to translate
1891*10d63b7dSRichard Lowe  *
1892*10d63b7dSRichard Lowe  *	Global variables used:
1893*10d63b7dSRichard Lowe  */
1894*10d63b7dSRichard Lowe Name
1895*10d63b7dSRichard Lowe vpath_translation(register Name cmd)
1896*10d63b7dSRichard Lowe {
1897*10d63b7dSRichard Lowe 	wchar_t			buffer[STRING_BUFFER_LENGTH];
1898*10d63b7dSRichard Lowe 	String_rec		new_cmd;
1899*10d63b7dSRichard Lowe 	wchar_t			*p;
1900*10d63b7dSRichard Lowe 	wchar_t			*start;
1901*10d63b7dSRichard Lowe 
1902*10d63b7dSRichard Lowe 	if (!vpath_defined || (cmd == NULL) || (cmd->hash.length == 0)) {
1903*10d63b7dSRichard Lowe 		return cmd;
1904*10d63b7dSRichard Lowe 	}
1905*10d63b7dSRichard Lowe 	INIT_STRING_FROM_STACK(new_cmd, buffer);
1906*10d63b7dSRichard Lowe 
1907*10d63b7dSRichard Lowe 	Wstring wcb(cmd);
1908*10d63b7dSRichard Lowe 	p = wcb.get_string();
1909*10d63b7dSRichard Lowe 
1910*10d63b7dSRichard Lowe 	while (*p != (int) nul_char) {
1911*10d63b7dSRichard Lowe 		while (iswspace(*p) && (*p != (int) nul_char)) {
1912*10d63b7dSRichard Lowe 			append_char(*p++, &new_cmd);
1913*10d63b7dSRichard Lowe 		}
1914*10d63b7dSRichard Lowe 		start = p;
1915*10d63b7dSRichard Lowe 		while (!iswspace(*p) && (*p != (int) nul_char)) {
1916*10d63b7dSRichard Lowe 			p++;
1917*10d63b7dSRichard Lowe 		}
1918*10d63b7dSRichard Lowe 		cmd = GETNAME(start, p - start);
1919*10d63b7dSRichard Lowe 		if (cmd->has_vpath_alias_prop) {
1920*10d63b7dSRichard Lowe 			cmd = get_prop(cmd->prop, vpath_alias_prop)->
1921*10d63b7dSRichard Lowe 						body.vpath_alias.alias;
1922*10d63b7dSRichard Lowe 			APPEND_NAME(cmd,
1923*10d63b7dSRichard Lowe 				      &new_cmd,
1924*10d63b7dSRichard Lowe 				      (int) cmd->hash.length);
1925*10d63b7dSRichard Lowe 		} else {
1926*10d63b7dSRichard Lowe 			append_string(start, &new_cmd, p - start);
1927*10d63b7dSRichard Lowe 		}
1928*10d63b7dSRichard Lowe 	}
1929*10d63b7dSRichard Lowe 	cmd = GETNAME(new_cmd.buffer.start, FIND_LENGTH);
1930*10d63b7dSRichard Lowe 	if (new_cmd.free_after_use) {
1931*10d63b7dSRichard Lowe 		retmem(new_cmd.buffer.start);
1932*10d63b7dSRichard Lowe 	}
1933*10d63b7dSRichard Lowe 	return cmd;
1934*10d63b7dSRichard Lowe }
1935*10d63b7dSRichard Lowe 
1936*10d63b7dSRichard Lowe /*
1937*10d63b7dSRichard Lowe  *	check_state(temp_file_name)
1938*10d63b7dSRichard Lowe  *
1939*10d63b7dSRichard Lowe  *	Reads and checks the state changed by the previously executed command.
1940*10d63b7dSRichard Lowe  *
1941*10d63b7dSRichard Lowe  *	Parameters:
1942*10d63b7dSRichard Lowe  *		temp_file_name	The auto dependency temp file
1943*10d63b7dSRichard Lowe  *
1944*10d63b7dSRichard Lowe  *	Global variables used:
1945*10d63b7dSRichard Lowe  */
1946*10d63b7dSRichard Lowe void
1947*10d63b7dSRichard Lowe check_state(Name temp_file_name)
1948*10d63b7dSRichard Lowe {
1949*10d63b7dSRichard Lowe 	if (!keep_state) {
1950*10d63b7dSRichard Lowe 		return;
1951*10d63b7dSRichard Lowe 	}
1952*10d63b7dSRichard Lowe 
1953*10d63b7dSRichard Lowe 	/*
1954*10d63b7dSRichard Lowe 	 * Then read the temp file that now might
1955*10d63b7dSRichard Lowe 	 * contain dependency reports from utilities
1956*10d63b7dSRichard Lowe 	 */
1957*10d63b7dSRichard Lowe 	read_dependency_file(temp_file_name);
1958*10d63b7dSRichard Lowe 
1959*10d63b7dSRichard Lowe 	/*
1960*10d63b7dSRichard Lowe 	 * And reread .make.state if it
1961*10d63b7dSRichard Lowe 	 * changed (the command ran recursive makes)
1962*10d63b7dSRichard Lowe 	 */
1963*10d63b7dSRichard Lowe 	check_read_state_file();
1964*10d63b7dSRichard Lowe 	if (temp_file_name != NULL) {
1965*10d63b7dSRichard Lowe 		(void) unlink(temp_file_name->string_mb);
1966*10d63b7dSRichard Lowe 	}
1967*10d63b7dSRichard Lowe }
1968*10d63b7dSRichard Lowe 
1969*10d63b7dSRichard Lowe /*
1970*10d63b7dSRichard Lowe  *	read_dependency_file(filename)
1971*10d63b7dSRichard Lowe  *
1972*10d63b7dSRichard Lowe  *	Read the temp file used for reporting dependencies to make
1973*10d63b7dSRichard Lowe  *
1974*10d63b7dSRichard Lowe  *	Parameters:
1975*10d63b7dSRichard Lowe  *		filename	The name of the file with the state info
1976*10d63b7dSRichard Lowe  *
1977*10d63b7dSRichard Lowe  *	Global variables used:
1978*10d63b7dSRichard Lowe  *		makefile_type	The type of makefile being read
1979*10d63b7dSRichard Lowe  *		read_trace_level Debug flag
1980*10d63b7dSRichard Lowe  *		temp_file_number The always increasing number for unique files
1981*10d63b7dSRichard Lowe  *		trace_reader	Debug flag
1982*10d63b7dSRichard Lowe  */
1983*10d63b7dSRichard Lowe static void
1984*10d63b7dSRichard Lowe read_dependency_file(register Name filename)
1985*10d63b7dSRichard Lowe {
1986*10d63b7dSRichard Lowe 	register Makefile_type	save_makefile_type;
1987*10d63b7dSRichard Lowe 
1988*10d63b7dSRichard Lowe 	if (filename == NULL) {
1989*10d63b7dSRichard Lowe 		return;
1990*10d63b7dSRichard Lowe 	}
1991*10d63b7dSRichard Lowe 	filename->stat.time = file_no_time;
1992*10d63b7dSRichard Lowe 	if (exists(filename) > file_doesnt_exist) {
1993*10d63b7dSRichard Lowe 		save_makefile_type = makefile_type;
1994*10d63b7dSRichard Lowe 		makefile_type = reading_cpp_file;
1995*10d63b7dSRichard Lowe 		if (read_trace_level > 1) {
1996*10d63b7dSRichard Lowe 			trace_reader = true;
1997*10d63b7dSRichard Lowe 		}
1998*10d63b7dSRichard Lowe 		temp_file_number++;
1999*10d63b7dSRichard Lowe 		(void) read_simple_file(filename,
2000*10d63b7dSRichard Lowe 					false,
2001*10d63b7dSRichard Lowe 					false,
2002*10d63b7dSRichard Lowe 					false,
2003*10d63b7dSRichard Lowe 					false,
2004*10d63b7dSRichard Lowe 					false,
2005*10d63b7dSRichard Lowe 					false);
2006*10d63b7dSRichard Lowe 		trace_reader = false;
2007*10d63b7dSRichard Lowe 		makefile_type = save_makefile_type;
2008*10d63b7dSRichard Lowe 	}
2009*10d63b7dSRichard Lowe }
2010*10d63b7dSRichard Lowe 
2011*10d63b7dSRichard Lowe /*
2012*10d63b7dSRichard Lowe  *	check_read_state_file()
2013*10d63b7dSRichard Lowe  *
2014*10d63b7dSRichard Lowe  *	Check if .make.state has changed
2015*10d63b7dSRichard Lowe  *	If it has we reread it
2016*10d63b7dSRichard Lowe  *
2017*10d63b7dSRichard Lowe  *	Parameters:
2018*10d63b7dSRichard Lowe  *
2019*10d63b7dSRichard Lowe  *	Global variables used:
2020*10d63b7dSRichard Lowe  *		make_state	Make state file name
2021*10d63b7dSRichard Lowe  *		makefile_type	Type of makefile being read
2022*10d63b7dSRichard Lowe  *		read_trace_level Debug flag
2023*10d63b7dSRichard Lowe  *		trace_reader	Debug flag
2024*10d63b7dSRichard Lowe  */
2025*10d63b7dSRichard Lowe static void
2026*10d63b7dSRichard Lowe check_read_state_file(void)
2027*10d63b7dSRichard Lowe {
2028*10d63b7dSRichard Lowe 	timestruc_t		previous = make_state->stat.time;
2029*10d63b7dSRichard Lowe 	register Makefile_type	save_makefile_type;
2030*10d63b7dSRichard Lowe 	register Property	makefile;
2031*10d63b7dSRichard Lowe 
2032*10d63b7dSRichard Lowe 	make_state->stat.time = file_no_time;
2033*10d63b7dSRichard Lowe 	if ((exists(make_state) == file_doesnt_exist) ||
2034*10d63b7dSRichard Lowe 	    (make_state->stat.time == previous)) {
2035*10d63b7dSRichard Lowe 		return;
2036*10d63b7dSRichard Lowe 	}
2037*10d63b7dSRichard Lowe 	save_makefile_type = makefile_type;
2038*10d63b7dSRichard Lowe 	makefile_type = rereading_statefile;
2039*10d63b7dSRichard Lowe 	/* Make sure we clear the old cached contents of .make.state */
2040*10d63b7dSRichard Lowe 	makefile = maybe_append_prop(make_state, makefile_prop);
2041*10d63b7dSRichard Lowe 	if (makefile->body.makefile.contents != NULL) {
2042*10d63b7dSRichard Lowe 		retmem(makefile->body.makefile.contents);
2043*10d63b7dSRichard Lowe 		makefile->body.makefile.contents = NULL;
2044*10d63b7dSRichard Lowe 	}
2045*10d63b7dSRichard Lowe 	if (read_trace_level > 1) {
2046*10d63b7dSRichard Lowe 		trace_reader = true;
2047*10d63b7dSRichard Lowe 	}
2048*10d63b7dSRichard Lowe 	temp_file_number++;
2049*10d63b7dSRichard Lowe 	(void) read_simple_file(make_state,
2050*10d63b7dSRichard Lowe 				false,
2051*10d63b7dSRichard Lowe 				false,
2052*10d63b7dSRichard Lowe 				false,
2053*10d63b7dSRichard Lowe 				false,
2054*10d63b7dSRichard Lowe 				false,
2055*10d63b7dSRichard Lowe 				true);
2056*10d63b7dSRichard Lowe 	trace_reader = false;
2057*10d63b7dSRichard Lowe 	makefile_type = save_makefile_type;
2058*10d63b7dSRichard Lowe }
2059*10d63b7dSRichard Lowe 
2060*10d63b7dSRichard Lowe /*
2061*10d63b7dSRichard Lowe  *	do_assign(line, target)
2062*10d63b7dSRichard Lowe  *
2063*10d63b7dSRichard Lowe  *	Handles runtime assignments for command lines prefixed with "=".
2064*10d63b7dSRichard Lowe  *
2065*10d63b7dSRichard Lowe  *	Parameters:
2066*10d63b7dSRichard Lowe  *		line		The command that contains an assignment
2067*10d63b7dSRichard Lowe  *		target		The Name of the target, used for error reports
2068*10d63b7dSRichard Lowe  *
2069*10d63b7dSRichard Lowe  *	Global variables used:
2070*10d63b7dSRichard Lowe  *		assign_done	Set to indicate doname needs to reprocess
2071*10d63b7dSRichard Lowe  */
2072*10d63b7dSRichard Lowe static void
2073*10d63b7dSRichard Lowe do_assign(register Name line, register Name target)
2074*10d63b7dSRichard Lowe {
2075*10d63b7dSRichard Lowe 	Wstring wcb(line);
2076*10d63b7dSRichard Lowe 	register wchar_t	*string = wcb.get_string();
2077*10d63b7dSRichard Lowe 	register wchar_t	*equal;
2078*10d63b7dSRichard Lowe 	register Name		name;
2079*10d63b7dSRichard Lowe 	register Boolean	append = false;
2080*10d63b7dSRichard Lowe 
2081*10d63b7dSRichard Lowe 	/*
2082*10d63b7dSRichard Lowe 	 * If any runtime assignments are done, doname() must reprocess all
2083*10d63b7dSRichard Lowe 	 * targets in the future since the macro values used to build the
2084*10d63b7dSRichard Lowe 	 * command lines for the targets might have changed.
2085*10d63b7dSRichard Lowe 	 */
2086*10d63b7dSRichard Lowe 	assign_done = true;
2087*10d63b7dSRichard Lowe 	/* Skip white space. */
2088*10d63b7dSRichard Lowe 	while (iswspace(*string)) {
2089*10d63b7dSRichard Lowe 		string++;
2090*10d63b7dSRichard Lowe 	}
2091*10d63b7dSRichard Lowe 	equal = string;
2092*10d63b7dSRichard Lowe 	/* Find "+=" or "=". */
2093*10d63b7dSRichard Lowe 	while (!iswspace(*equal) &&
2094*10d63b7dSRichard Lowe 	       (*equal != (int) plus_char) &&
2095*10d63b7dSRichard Lowe 	       (*equal != (int) equal_char)) {
2096*10d63b7dSRichard Lowe 		equal++;
2097*10d63b7dSRichard Lowe 	}
2098*10d63b7dSRichard Lowe 	/* Internalize macro name. */
2099*10d63b7dSRichard Lowe 	name = GETNAME(string, equal - string);
2100*10d63b7dSRichard Lowe 	/* Skip over "+=" "=". */
2101*10d63b7dSRichard Lowe 	while (!((*equal == (int) nul_char) ||
2102*10d63b7dSRichard Lowe 		 (*equal == (int) equal_char) ||
2103*10d63b7dSRichard Lowe 		 (*equal == (int) plus_char))) {
2104*10d63b7dSRichard Lowe 		equal++;
2105*10d63b7dSRichard Lowe 	}
2106*10d63b7dSRichard Lowe 	switch (*equal) {
2107*10d63b7dSRichard Lowe 	case nul_char:
2108*10d63b7dSRichard Lowe 		fatal(gettext("= expected in rule `%s' for target `%s'"),
2109*10d63b7dSRichard Lowe 		      line->string_mb,
2110*10d63b7dSRichard Lowe 		      target->string_mb);
2111*10d63b7dSRichard Lowe 	case plus_char:
2112*10d63b7dSRichard Lowe 		append = true;
2113*10d63b7dSRichard Lowe 		equal++;
2114*10d63b7dSRichard Lowe 		break;
2115*10d63b7dSRichard Lowe 	}
2116*10d63b7dSRichard Lowe 	equal++;
2117*10d63b7dSRichard Lowe 	/* Skip over whitespace in front of value. */
2118*10d63b7dSRichard Lowe 	while (iswspace(*equal)) {
2119*10d63b7dSRichard Lowe 		equal++;
2120*10d63b7dSRichard Lowe 	}
2121*10d63b7dSRichard Lowe 	/* Enter new macro value. */
2122*10d63b7dSRichard Lowe 	enter_equal(name,
2123*10d63b7dSRichard Lowe 		    GETNAME(equal, wcb.get_string() + line->hash.length - equal),
2124*10d63b7dSRichard Lowe 		    append);
2125*10d63b7dSRichard Lowe }
2126*10d63b7dSRichard Lowe 
2127*10d63b7dSRichard Lowe /*
2128*10d63b7dSRichard Lowe  *	build_command_strings(target, line)
2129*10d63b7dSRichard Lowe  *
2130*10d63b7dSRichard Lowe  *	Builds the command string to used when
2131*10d63b7dSRichard Lowe  *	building a target. If the string is different from the previous one
2132*10d63b7dSRichard Lowe  *	is_out_of_date is set.
2133*10d63b7dSRichard Lowe  *
2134*10d63b7dSRichard Lowe  *	Parameters:
2135*10d63b7dSRichard Lowe  *		target		Target to build commands for
2136*10d63b7dSRichard Lowe  *		line		Where to stuff result
2137*10d63b7dSRichard Lowe  *
2138*10d63b7dSRichard Lowe  *	Global variables used:
2139*10d63b7dSRichard Lowe  *		c_at		The Name "@", used to set macro value
2140*10d63b7dSRichard Lowe  *		command_changed	Set if command is different from old
2141*10d63b7dSRichard Lowe  *		debug_level	Should we trace activities?
2142*10d63b7dSRichard Lowe  *		do_not_exec_rule Always echo when running -n
2143*10d63b7dSRichard Lowe  *		empty_name	The Name "", used for empty rule
2144*10d63b7dSRichard Lowe  *		funny		Semantics of characters
2145*10d63b7dSRichard Lowe  *		ignore_errors	Used to init field for line
2146*10d63b7dSRichard Lowe  *		is_conditional	Set to false befor evaling macro, checked
2147*10d63b7dSRichard Lowe  *				after expanding macros
2148*10d63b7dSRichard Lowe  *		keep_state	Indicates that .KEEP_STATE is on
2149*10d63b7dSRichard Lowe  *		make_word_mentioned Set by macro eval, inits field for cmd
2150*10d63b7dSRichard Lowe  *		query		The Name "?", used to set macro value
2151*10d63b7dSRichard Lowe  *		query_mentioned	Set by macro eval, inits field for cmd
2152*10d63b7dSRichard Lowe  *		recursion_level	Used for tracing
2153*10d63b7dSRichard Lowe  *		silent		Used to init field for line
2154*10d63b7dSRichard Lowe  */
2155*10d63b7dSRichard Lowe static void
2156*10d63b7dSRichard Lowe build_command_strings(Name target, register Property line)
2157*10d63b7dSRichard Lowe {
2158*10d63b7dSRichard Lowe 	String_rec		command_line;
2159*10d63b7dSRichard Lowe 	register Cmd_line	command_template = line->body.line.command_template;
2160*10d63b7dSRichard Lowe 	register Cmd_line	*insert = &line->body.line.command_used;
2161*10d63b7dSRichard Lowe 	register Cmd_line	used = *insert;
2162*10d63b7dSRichard Lowe 	wchar_t			buffer[STRING_BUFFER_LENGTH];
2163*10d63b7dSRichard Lowe 	wchar_t			*start;
2164*10d63b7dSRichard Lowe 	Name			new_command_line;
2165*10d63b7dSRichard Lowe 	register Boolean	new_command_longer = false;
2166*10d63b7dSRichard Lowe 	register Boolean	ignore_all_command_dependency = true;
2167*10d63b7dSRichard Lowe 	Property		member;
2168*10d63b7dSRichard Lowe 	static Name		less_name;
2169*10d63b7dSRichard Lowe 	static Name		percent_name;
2170*10d63b7dSRichard Lowe 	static Name		star;
2171*10d63b7dSRichard Lowe 	Name			tmp_name;
2172*10d63b7dSRichard Lowe 
2173*10d63b7dSRichard Lowe 	if (less_name == NULL) {
2174*10d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "<");
2175*10d63b7dSRichard Lowe 		less_name = GETNAME(wcs_buffer, FIND_LENGTH);
2176*10d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "%");
2177*10d63b7dSRichard Lowe 		percent_name = GETNAME(wcs_buffer, FIND_LENGTH);
2178*10d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "*");
2179*10d63b7dSRichard Lowe 		star = GETNAME(wcs_buffer, FIND_LENGTH);
2180*10d63b7dSRichard Lowe 	}
2181*10d63b7dSRichard Lowe 
2182*10d63b7dSRichard Lowe 	/* We have to check if a target depends on conditional macros */
2183*10d63b7dSRichard Lowe 	/* Targets that do must be reprocessed by doname() each time around */
2184*10d63b7dSRichard Lowe 	/* since the macro values used when building the target might have */
2185*10d63b7dSRichard Lowe 	/* changed */
2186*10d63b7dSRichard Lowe 	conditional_macro_used = false;
2187*10d63b7dSRichard Lowe 	/* If we are building a lib.a(member) target $@ should be bound */
2188*10d63b7dSRichard Lowe 	/* to lib.a */
2189*10d63b7dSRichard Lowe 	if (target->is_member &&
2190*10d63b7dSRichard Lowe 	    ((member = get_prop(target->prop, member_prop)) != NULL)) {
2191*10d63b7dSRichard Lowe 		target = member->body.member.library;
2192*10d63b7dSRichard Lowe 	}
2193*10d63b7dSRichard Lowe 	/* If we are building a "::" help target $@ should be bound to */
2194*10d63b7dSRichard Lowe 	/* the real target name */
2195*10d63b7dSRichard Lowe 	/* A lib.a(member) target is never :: */
2196*10d63b7dSRichard Lowe 	if (target->has_target_prop) {
2197*10d63b7dSRichard Lowe 		target = get_prop(target->prop, target_prop)->
2198*10d63b7dSRichard Lowe 		  body.target.target;
2199*10d63b7dSRichard Lowe 	}
2200*10d63b7dSRichard Lowe 	/* Bind the magic macros that make supplies */
2201*10d63b7dSRichard Lowe 	tmp_name = target;
2202*10d63b7dSRichard Lowe 	if(tmp_name != NULL) {
2203*10d63b7dSRichard Lowe 		if (tmp_name->has_vpath_alias_prop) {
2204*10d63b7dSRichard Lowe 			tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
2205*10d63b7dSRichard Lowe 					body.vpath_alias.alias;
2206*10d63b7dSRichard Lowe 		}
2207*10d63b7dSRichard Lowe 	}
2208*10d63b7dSRichard Lowe 	(void) SETVAR(c_at, tmp_name, false);
2209*10d63b7dSRichard Lowe 
2210*10d63b7dSRichard Lowe 	tmp_name = line->body.line.star;
2211*10d63b7dSRichard Lowe 	if(tmp_name != NULL) {
2212*10d63b7dSRichard Lowe 		if (tmp_name->has_vpath_alias_prop) {
2213*10d63b7dSRichard Lowe 			tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
2214*10d63b7dSRichard Lowe 					body.vpath_alias.alias;
2215*10d63b7dSRichard Lowe 		}
2216*10d63b7dSRichard Lowe 	}
2217*10d63b7dSRichard Lowe 	(void) SETVAR(star, tmp_name, false);
2218*10d63b7dSRichard Lowe 
2219*10d63b7dSRichard Lowe 	tmp_name = line->body.line.less;
2220*10d63b7dSRichard Lowe 	if(tmp_name != NULL) {
2221*10d63b7dSRichard Lowe 		if (tmp_name->has_vpath_alias_prop) {
2222*10d63b7dSRichard Lowe 			tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
2223*10d63b7dSRichard Lowe 					body.vpath_alias.alias;
2224*10d63b7dSRichard Lowe 		}
2225*10d63b7dSRichard Lowe 	}
2226*10d63b7dSRichard Lowe 	(void) SETVAR(less_name, tmp_name, false);
2227*10d63b7dSRichard Lowe 
2228*10d63b7dSRichard Lowe 	tmp_name = line->body.line.percent;
2229*10d63b7dSRichard Lowe 	if(tmp_name != NULL) {
2230*10d63b7dSRichard Lowe 		if (tmp_name->has_vpath_alias_prop) {
2231*10d63b7dSRichard Lowe 			tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
2232*10d63b7dSRichard Lowe 					body.vpath_alias.alias;
2233*10d63b7dSRichard Lowe 		}
2234*10d63b7dSRichard Lowe 	}
2235*10d63b7dSRichard Lowe 	(void) SETVAR(percent_name, tmp_name, false);
2236*10d63b7dSRichard Lowe 
2237*10d63b7dSRichard Lowe 	/* $? is seldom used and it is expensive to build */
2238*10d63b7dSRichard Lowe 	/* so we store the list form and build the string on demand */
2239*10d63b7dSRichard Lowe 	Chain query_list = NULL;
2240*10d63b7dSRichard Lowe 	Chain *query_list_tail = &query_list;
2241*10d63b7dSRichard Lowe 
2242*10d63b7dSRichard Lowe 	for (Chain ch = line->body.line.query; ch != NULL; ch = ch->next) {
2243*10d63b7dSRichard Lowe 		*query_list_tail = ALLOC(Chain);
2244*10d63b7dSRichard Lowe 		(*query_list_tail)->name = ch->name;
2245*10d63b7dSRichard Lowe 		if ((*query_list_tail)->name->has_vpath_alias_prop) {
2246*10d63b7dSRichard Lowe 			(*query_list_tail)->name =
2247*10d63b7dSRichard Lowe 				get_prop((*query_list_tail)->name->prop,
2248*10d63b7dSRichard Lowe 					vpath_alias_prop)->body.vpath_alias.alias;
2249*10d63b7dSRichard Lowe 		}
2250*10d63b7dSRichard Lowe 		(*query_list_tail)->next = NULL;
2251*10d63b7dSRichard Lowe 		query_list_tail = &(*query_list_tail)->next;
2252*10d63b7dSRichard Lowe 	}
2253*10d63b7dSRichard Lowe 	(void) setvar_daemon(query,
2254*10d63b7dSRichard Lowe 			     (Name) query_list,
2255*10d63b7dSRichard Lowe 			     false,
2256*10d63b7dSRichard Lowe 			     chain_daemon,
2257*10d63b7dSRichard Lowe                              false,
2258*10d63b7dSRichard Lowe                              debug_level);
2259*10d63b7dSRichard Lowe 
2260*10d63b7dSRichard Lowe 	/* build $^ */
2261*10d63b7dSRichard Lowe 	Chain hat_list = NULL;
2262*10d63b7dSRichard Lowe 	Chain *hat_list_tail = &hat_list;
2263*10d63b7dSRichard Lowe 
2264*10d63b7dSRichard Lowe 	for (Dependency dependency = line->body.line.dependencies;
2265*10d63b7dSRichard Lowe 		dependency != NULL;
2266*10d63b7dSRichard Lowe 		dependency = dependency->next) {
2267*10d63b7dSRichard Lowe 		/* skip automatic dependencies */
2268*10d63b7dSRichard Lowe 		if (!dependency->automatic) {
2269*10d63b7dSRichard Lowe 			if ((dependency->name != force) &&
2270*10d63b7dSRichard Lowe 				(dependency->stale == false)) {
2271*10d63b7dSRichard Lowe 				*hat_list_tail = ALLOC(Chain);
2272*10d63b7dSRichard Lowe 
2273*10d63b7dSRichard Lowe 				if (dependency->name->is_member &&
2274*10d63b7dSRichard Lowe 					(get_prop(dependency->name->prop, member_prop) != NULL)) {
2275*10d63b7dSRichard Lowe 					(*hat_list_tail)->name =
2276*10d63b7dSRichard Lowe 							get_prop(dependency->name->prop,
2277*10d63b7dSRichard Lowe 								member_prop)->body.member.member;
2278*10d63b7dSRichard Lowe 				} else {
2279*10d63b7dSRichard Lowe 					(*hat_list_tail)->name = dependency->name;
2280*10d63b7dSRichard Lowe 				}
2281*10d63b7dSRichard Lowe 
2282*10d63b7dSRichard Lowe 				if((*hat_list_tail)->name != NULL) {
2283*10d63b7dSRichard Lowe 					if ((*hat_list_tail)->name->has_vpath_alias_prop) {
2284*10d63b7dSRichard Lowe 						(*hat_list_tail)->name =
2285*10d63b7dSRichard Lowe 							get_prop((*hat_list_tail)->name->prop,
2286*10d63b7dSRichard Lowe 								vpath_alias_prop)->body.vpath_alias.alias;
2287*10d63b7dSRichard Lowe 					}
2288*10d63b7dSRichard Lowe 				}
2289*10d63b7dSRichard Lowe 
2290*10d63b7dSRichard Lowe 				(*hat_list_tail)->next = NULL;
2291*10d63b7dSRichard Lowe 				hat_list_tail = &(*hat_list_tail)->next;
2292*10d63b7dSRichard Lowe 			}
2293*10d63b7dSRichard Lowe 		}
2294*10d63b7dSRichard Lowe 	}
2295*10d63b7dSRichard Lowe 	(void) setvar_daemon(hat,
2296*10d63b7dSRichard Lowe 			     (Name) hat_list,
2297*10d63b7dSRichard Lowe 			     false,
2298*10d63b7dSRichard Lowe 			     chain_daemon,
2299*10d63b7dSRichard Lowe                              false,
2300*10d63b7dSRichard Lowe                              debug_level);
2301*10d63b7dSRichard Lowe 
2302*10d63b7dSRichard Lowe /* We have two command sequences we need to handle */
2303*10d63b7dSRichard Lowe /* The old one that we probably read from .make.state */
2304*10d63b7dSRichard Lowe /* and the new one we are building that will replace the old one */
2305*10d63b7dSRichard Lowe /* Even when KEEP_STATE is not on we build a new command sequence and store */
2306*10d63b7dSRichard Lowe /* it in the line prop. This command sequence is then executed by */
2307*10d63b7dSRichard Lowe /* run_command(). If KEEP_STATE is on it is also later written to */
2308*10d63b7dSRichard Lowe /* .make.state. The routine replaces the old command line by line with the */
2309*10d63b7dSRichard Lowe /* new one trying to reuse Cmd_lines */
2310*10d63b7dSRichard Lowe 
2311*10d63b7dSRichard Lowe 	/* If there is no old command_used we have to start creating */
2312*10d63b7dSRichard Lowe 	/* Cmd_lines to keep the new cmd in */
2313*10d63b7dSRichard Lowe 	if (used == NULL) {
2314*10d63b7dSRichard Lowe 		new_command_longer = true;
2315*10d63b7dSRichard Lowe 		*insert = used = ALLOC(Cmd_line);
2316*10d63b7dSRichard Lowe 		used->next = NULL;
2317*10d63b7dSRichard Lowe 		used->command_line = NULL;
2318*10d63b7dSRichard Lowe 		insert = &used->next;
2319*10d63b7dSRichard Lowe 	}
2320*10d63b7dSRichard Lowe 	/* Run thru the template for the new command and build the expanded */
2321*10d63b7dSRichard Lowe 	/* new command lines */
2322*10d63b7dSRichard Lowe 	for (;
2323*10d63b7dSRichard Lowe 	     command_template != NULL;
2324*10d63b7dSRichard Lowe 	     command_template = command_template->next, insert = &used->next, used = *insert) {
2325*10d63b7dSRichard Lowe 		/* If there is no old command_used Cmd_line we need to */
2326*10d63b7dSRichard Lowe 		/* create one and say that cmd consistency failed */
2327*10d63b7dSRichard Lowe 		if (used == NULL) {
2328*10d63b7dSRichard Lowe 			new_command_longer = true;
2329*10d63b7dSRichard Lowe 			*insert = used = ALLOC(Cmd_line);
2330*10d63b7dSRichard Lowe 			used->next = NULL;
2331*10d63b7dSRichard Lowe 			used->command_line = empty_name;
2332*10d63b7dSRichard Lowe 		}
2333*10d63b7dSRichard Lowe 		/* Prepare the Cmd_line for the processing */
2334*10d63b7dSRichard Lowe 		/* The command line prefixes "@-=?" are stripped and that */
2335*10d63b7dSRichard Lowe 		/* information is saved in the Cmd_line */
2336*10d63b7dSRichard Lowe 		used->assign = false;
2337*10d63b7dSRichard Lowe 		used->ignore_error = ignore_errors;
2338*10d63b7dSRichard Lowe 		used->silent = silent;
2339*10d63b7dSRichard Lowe 		used->always_exec = false;
2340*10d63b7dSRichard Lowe 		/* Expand the macros in the command line */
2341*10d63b7dSRichard Lowe 		INIT_STRING_FROM_STACK(command_line, buffer);
2342*10d63b7dSRichard Lowe 		make_word_mentioned =
2343*10d63b7dSRichard Lowe 		  query_mentioned =
2344*10d63b7dSRichard Lowe 		    false;
2345*10d63b7dSRichard Lowe 		expand_value(command_template->command_line, &command_line, true);
2346*10d63b7dSRichard Lowe 		/* If the macro $(MAKE) is mentioned in the command */
2347*10d63b7dSRichard Lowe 		/* "make -n" runs actually execute the command */
2348*10d63b7dSRichard Lowe 		used->make_refd = make_word_mentioned;
2349*10d63b7dSRichard Lowe 		used->ignore_command_dependency = query_mentioned;
2350*10d63b7dSRichard Lowe 		/* Strip the prefixes */
2351*10d63b7dSRichard Lowe 		start = command_line.buffer.start;
2352*10d63b7dSRichard Lowe 		for (;
2353*10d63b7dSRichard Lowe 		     iswspace(*start) ||
2354*10d63b7dSRichard Lowe 		     (get_char_semantics_value(*start) & (int) command_prefix_sem);
2355*10d63b7dSRichard Lowe 		     start++) {
2356*10d63b7dSRichard Lowe 			switch (*start) {
2357*10d63b7dSRichard Lowe 			case question_char:
2358*10d63b7dSRichard Lowe 				used->ignore_command_dependency = true;
2359*10d63b7dSRichard Lowe 				break;
2360*10d63b7dSRichard Lowe 			case exclam_char:
2361*10d63b7dSRichard Lowe 				used->ignore_command_dependency = false;
2362*10d63b7dSRichard Lowe 				break;
2363*10d63b7dSRichard Lowe 			case equal_char:
2364*10d63b7dSRichard Lowe 				used->assign = true;
2365*10d63b7dSRichard Lowe 				break;
2366*10d63b7dSRichard Lowe 			case hyphen_char:
2367*10d63b7dSRichard Lowe 				used->ignore_error = true;
2368*10d63b7dSRichard Lowe 				break;
2369*10d63b7dSRichard Lowe 			case at_char:
2370*10d63b7dSRichard Lowe 				if (!do_not_exec_rule) {
2371*10d63b7dSRichard Lowe 					used->silent = true;
2372*10d63b7dSRichard Lowe 				}
2373*10d63b7dSRichard Lowe 				break;
2374*10d63b7dSRichard Lowe 			case plus_char:
2375*10d63b7dSRichard Lowe 				if(posix) {
2376*10d63b7dSRichard Lowe 				  used->always_exec  = true;
2377*10d63b7dSRichard Lowe 				}
2378*10d63b7dSRichard Lowe 				break;
2379*10d63b7dSRichard Lowe 			}
2380*10d63b7dSRichard Lowe 		}
2381*10d63b7dSRichard Lowe 		/* If all command lines of the template are prefixed with "?"*/
2382*10d63b7dSRichard Lowe 		/* the VIRTUAL_ROOT is not used for cmd consistency checks */
2383*10d63b7dSRichard Lowe 		if (!used->ignore_command_dependency) {
2384*10d63b7dSRichard Lowe 			ignore_all_command_dependency = false;
2385*10d63b7dSRichard Lowe 		}
2386*10d63b7dSRichard Lowe 		/* Internalize the expanded and stripped command line */
2387*10d63b7dSRichard Lowe 		new_command_line = GETNAME(start, FIND_LENGTH);
2388*10d63b7dSRichard Lowe 		if ((used->command_line == NULL) &&
2389*10d63b7dSRichard Lowe 		    (line->body.line.sccs_command)) {
2390*10d63b7dSRichard Lowe 			used->command_line = new_command_line;
2391*10d63b7dSRichard Lowe 			new_command_longer = false;
2392*10d63b7dSRichard Lowe 		}
2393*10d63b7dSRichard Lowe 		/* Compare it with the old one for command consistency */
2394*10d63b7dSRichard Lowe 		if (used->command_line != new_command_line) {
2395*10d63b7dSRichard Lowe 			Name vpath_translated = vpath_translation(new_command_line);
2396*10d63b7dSRichard Lowe 			if (keep_state &&
2397*10d63b7dSRichard Lowe 			    !used->ignore_command_dependency && (vpath_translated != used->command_line)) {
2398*10d63b7dSRichard Lowe 				if (debug_level > 0) {
2399*10d63b7dSRichard Lowe 					if (used->command_line != NULL
2400*10d63b7dSRichard Lowe 					    && *used->command_line->string_mb !=
2401*10d63b7dSRichard Lowe 					    '\0') {
2402*10d63b7dSRichard Lowe 						(void) printf(gettext("%*sBuilding %s because new command \n\t%s\n%*sdifferent from old\n\t%s\n"),
2403*10d63b7dSRichard Lowe 							      recursion_level,
2404*10d63b7dSRichard Lowe 							      "",
2405*10d63b7dSRichard Lowe 							      target->string_mb,
2406*10d63b7dSRichard Lowe 							      vpath_translated->string_mb,
2407*10d63b7dSRichard Lowe 							      recursion_level,
2408*10d63b7dSRichard Lowe 							      "",
2409*10d63b7dSRichard Lowe 							      used->
2410*10d63b7dSRichard Lowe 							      command_line->
2411*10d63b7dSRichard Lowe 							      string_mb);
2412*10d63b7dSRichard Lowe 					} else {
2413*10d63b7dSRichard Lowe 						(void) printf(gettext("%*sBuilding %s because new command \n\t%s\n%*sdifferent from empty old command\n"),
2414*10d63b7dSRichard Lowe 							      recursion_level,
2415*10d63b7dSRichard Lowe 							      "",
2416*10d63b7dSRichard Lowe 							      target->string_mb,
2417*10d63b7dSRichard Lowe 							      vpath_translated->string_mb,
2418*10d63b7dSRichard Lowe 							      recursion_level,
2419*10d63b7dSRichard Lowe 							      "");
2420*10d63b7dSRichard Lowe 					}
2421*10d63b7dSRichard Lowe 				}
2422*10d63b7dSRichard Lowe 				command_changed = true;
2423*10d63b7dSRichard Lowe                                 line->body.line.is_out_of_date = true;
2424*10d63b7dSRichard Lowe 			}
2425*10d63b7dSRichard Lowe 			used->command_line = new_command_line;
2426*10d63b7dSRichard Lowe 		}
2427*10d63b7dSRichard Lowe 		if (command_line.free_after_use) {
2428*10d63b7dSRichard Lowe 			retmem(command_line.buffer.start);
2429*10d63b7dSRichard Lowe 		}
2430*10d63b7dSRichard Lowe 	}
2431*10d63b7dSRichard Lowe 	/* Check if the old command is longer than the new for */
2432*10d63b7dSRichard Lowe 	/* command consistency */
2433*10d63b7dSRichard Lowe 	if (used != NULL) {
2434*10d63b7dSRichard Lowe 		*insert = NULL;
2435*10d63b7dSRichard Lowe 		if (keep_state &&
2436*10d63b7dSRichard Lowe 		    !ignore_all_command_dependency) {
2437*10d63b7dSRichard Lowe 			if (debug_level > 0) {
2438*10d63b7dSRichard Lowe 				(void) printf(gettext("%*sBuilding %s because new command shorter than old\n"),
2439*10d63b7dSRichard Lowe 					      recursion_level,
2440*10d63b7dSRichard Lowe 					      "",
2441*10d63b7dSRichard Lowe 					      target->string_mb);
2442*10d63b7dSRichard Lowe 			}
2443*10d63b7dSRichard Lowe 			command_changed = true;
2444*10d63b7dSRichard Lowe                         line->body.line.is_out_of_date = true;
2445*10d63b7dSRichard Lowe 		}
2446*10d63b7dSRichard Lowe 	}
2447*10d63b7dSRichard Lowe 	/* Check if the new command is longer than the old command for */
2448*10d63b7dSRichard Lowe 	/* command consistency */
2449*10d63b7dSRichard Lowe 	if (new_command_longer &&
2450*10d63b7dSRichard Lowe 	    !ignore_all_command_dependency &&
2451*10d63b7dSRichard Lowe 	    keep_state) {
2452*10d63b7dSRichard Lowe 		if (debug_level > 0) {
2453*10d63b7dSRichard Lowe 			(void) printf(gettext("%*sBuilding %s because new command longer than old\n"),
2454*10d63b7dSRichard Lowe 				      recursion_level,
2455*10d63b7dSRichard Lowe 				      "",
2456*10d63b7dSRichard Lowe 				      target->string_mb);
2457*10d63b7dSRichard Lowe 		}
2458*10d63b7dSRichard Lowe 		command_changed = true;
2459*10d63b7dSRichard Lowe                 line->body.line.is_out_of_date = true;
2460*10d63b7dSRichard Lowe 	}
2461*10d63b7dSRichard Lowe 	/* Unbind the magic macros */
2462*10d63b7dSRichard Lowe 	(void) SETVAR(c_at, (Name) NULL, false);
2463*10d63b7dSRichard Lowe 	(void) SETVAR(star, (Name) NULL, false);
2464*10d63b7dSRichard Lowe 	(void) SETVAR(less_name, (Name) NULL, false);
2465*10d63b7dSRichard Lowe 	(void) SETVAR(percent_name, (Name) NULL, false);
2466*10d63b7dSRichard Lowe 	(void) SETVAR(query, (Name) NULL, false);
2467*10d63b7dSRichard Lowe         if (query_list != NULL) {
2468*10d63b7dSRichard Lowe         	delete_query_chain(query_list);
2469*10d63b7dSRichard Lowe         }
2470*10d63b7dSRichard Lowe 	(void) SETVAR(hat, (Name) NULL, false);
2471*10d63b7dSRichard Lowe         if (hat_list != NULL) {
2472*10d63b7dSRichard Lowe         	delete_query_chain(hat_list);
2473*10d63b7dSRichard Lowe         }
2474*10d63b7dSRichard Lowe 
2475*10d63b7dSRichard Lowe 	if (conditional_macro_used) {
2476*10d63b7dSRichard Lowe 		target->conditional_macro_list = cond_macro_list;
2477*10d63b7dSRichard Lowe 		cond_macro_list = NULL;
2478*10d63b7dSRichard Lowe 		target->depends_on_conditional = true;
2479*10d63b7dSRichard Lowe 	}
2480*10d63b7dSRichard Lowe }
2481*10d63b7dSRichard Lowe 
2482*10d63b7dSRichard Lowe /*
2483*10d63b7dSRichard Lowe  *	touch_command(line, target, result)
2484*10d63b7dSRichard Lowe  *
2485*10d63b7dSRichard Lowe  *	If this is an "make -t" run we do this.
2486*10d63b7dSRichard Lowe  *	We touch all targets in the target group ("foo + fie:") if any.
2487*10d63b7dSRichard Lowe  *
2488*10d63b7dSRichard Lowe  *	Return value:
2489*10d63b7dSRichard Lowe  *				Indicates if the command failed or not
2490*10d63b7dSRichard Lowe  *
2491*10d63b7dSRichard Lowe  *	Parameters:
2492*10d63b7dSRichard Lowe  *		line		The command line to update
2493*10d63b7dSRichard Lowe  *		target		The target we are touching
2494*10d63b7dSRichard Lowe  *		result		Initial value for the result we return
2495*10d63b7dSRichard Lowe  *
2496*10d63b7dSRichard Lowe  *	Global variables used:
2497*10d63b7dSRichard Lowe  *		do_not_exec_rule Indicates that -n is on
2498*10d63b7dSRichard Lowe  *		silent		Do not echo commands
2499*10d63b7dSRichard Lowe  */
2500*10d63b7dSRichard Lowe static Doname
2501*10d63b7dSRichard Lowe touch_command(register Property line, register Name target, Doname result)
2502*10d63b7dSRichard Lowe {
2503*10d63b7dSRichard Lowe 	Name			name;
2504*10d63b7dSRichard Lowe 	register Chain		target_group;
2505*10d63b7dSRichard Lowe 	String_rec		touch_string;
2506*10d63b7dSRichard Lowe 	wchar_t			buffer[MAXPATHLEN];
2507*10d63b7dSRichard Lowe 	Name			touch_cmd;
2508*10d63b7dSRichard Lowe 	Cmd_line		rule;
2509*10d63b7dSRichard Lowe 
2510*10d63b7dSRichard Lowe 	for (name = target, target_group = NULL; name != NULL;) {
2511*10d63b7dSRichard Lowe 		if (!name->is_member) {
2512*10d63b7dSRichard Lowe 			/*
2513*10d63b7dSRichard Lowe 			 * Build a touch command that can be passed
2514*10d63b7dSRichard Lowe 			 * to dosys(). If KEEP_STATE is on, "make -t"
2515*10d63b7dSRichard Lowe 			 * will save the proper command, not the
2516*10d63b7dSRichard Lowe 			 * "touch" in .make.state.
2517*10d63b7dSRichard Lowe 			 */
2518*10d63b7dSRichard Lowe 			INIT_STRING_FROM_STACK(touch_string, buffer);
2519*10d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, "touch ");
2520*10d63b7dSRichard Lowe 			append_string(wcs_buffer, &touch_string, FIND_LENGTH);
2521*10d63b7dSRichard Lowe 			touch_cmd = name;
2522*10d63b7dSRichard Lowe 			if (name->has_vpath_alias_prop) {
2523*10d63b7dSRichard Lowe 				touch_cmd = get_prop(name->prop,
2524*10d63b7dSRichard Lowe 						 vpath_alias_prop)->
2525*10d63b7dSRichard Lowe 						   body.vpath_alias.alias;
2526*10d63b7dSRichard Lowe 			}
2527*10d63b7dSRichard Lowe 			APPEND_NAME(touch_cmd,
2528*10d63b7dSRichard Lowe 				      &touch_string,
2529*10d63b7dSRichard Lowe 				      FIND_LENGTH);
2530*10d63b7dSRichard Lowe 			touch_cmd = GETNAME(touch_string.buffer.start,
2531*10d63b7dSRichard Lowe 					    FIND_LENGTH);
2532*10d63b7dSRichard Lowe 			if (touch_string.free_after_use) {
2533*10d63b7dSRichard Lowe 				retmem(touch_string.buffer.start);
2534*10d63b7dSRichard Lowe 			}
2535*10d63b7dSRichard Lowe 			if (!silent ||
2536*10d63b7dSRichard Lowe 			    do_not_exec_rule &&
2537*10d63b7dSRichard Lowe 			    (target_group == NULL)) {
2538*10d63b7dSRichard Lowe 				(void) printf("%s\n", touch_cmd->string_mb);
2539*10d63b7dSRichard Lowe 			}
2540*10d63b7dSRichard Lowe 			/* Run the touch command, or simulate it */
2541*10d63b7dSRichard Lowe 			if (!do_not_exec_rule) {
2542*10d63b7dSRichard Lowe 				result = dosys(touch_cmd,
2543*10d63b7dSRichard Lowe 					       false,
2544*10d63b7dSRichard Lowe 					       false,
2545*10d63b7dSRichard Lowe 					       false,
2546*10d63b7dSRichard Lowe 					       false,
2547*10d63b7dSRichard Lowe 					       name);
2548*10d63b7dSRichard Lowe 			} else {
2549*10d63b7dSRichard Lowe 				result = build_ok;
2550*10d63b7dSRichard Lowe 			}
2551*10d63b7dSRichard Lowe 		} else {
2552*10d63b7dSRichard Lowe 			result = build_ok;
2553*10d63b7dSRichard Lowe 		}
2554*10d63b7dSRichard Lowe 		if (target_group == NULL) {
2555*10d63b7dSRichard Lowe 			target_group = line->body.line.target_group;
2556*10d63b7dSRichard Lowe 		} else {
2557*10d63b7dSRichard Lowe 			target_group = target_group->next;
2558*10d63b7dSRichard Lowe 		}
2559*10d63b7dSRichard Lowe 		if (target_group != NULL) {
2560*10d63b7dSRichard Lowe 			name = target_group->name;
2561*10d63b7dSRichard Lowe 		} else {
2562*10d63b7dSRichard Lowe 			name = NULL;
2563*10d63b7dSRichard Lowe 		}
2564*10d63b7dSRichard Lowe 	}
2565*10d63b7dSRichard Lowe 	return result;
2566*10d63b7dSRichard Lowe }
2567*10d63b7dSRichard Lowe 
2568*10d63b7dSRichard Lowe /*
2569*10d63b7dSRichard Lowe  *	update_target(line, result)
2570*10d63b7dSRichard Lowe  *
2571*10d63b7dSRichard Lowe  *	updates the status of a target after executing its commands.
2572*10d63b7dSRichard Lowe  *
2573*10d63b7dSRichard Lowe  *	Parameters:
2574*10d63b7dSRichard Lowe  *		line		The command line block to update
2575*10d63b7dSRichard Lowe  *		result		Indicates that build is OK so can update
2576*10d63b7dSRichard Lowe  *
2577*10d63b7dSRichard Lowe  *	Global variables used:
2578*10d63b7dSRichard Lowe  *		do_not_exec_rule Indicates that -n is on
2579*10d63b7dSRichard Lowe  *		touch		Fake the new timestamp if we are just touching
2580*10d63b7dSRichard Lowe  */
2581*10d63b7dSRichard Lowe void
2582*10d63b7dSRichard Lowe update_target(Property line, Doname result)
2583*10d63b7dSRichard Lowe {
2584*10d63b7dSRichard Lowe 	Name			target;
2585*10d63b7dSRichard Lowe 	Chain			target_group;
2586*10d63b7dSRichard Lowe 	Property		line2;
2587*10d63b7dSRichard Lowe 	timestruc_t		old_stat_time;
2588*10d63b7dSRichard Lowe 	Property		member;
2589*10d63b7dSRichard Lowe 
2590*10d63b7dSRichard Lowe 	/*
2591*10d63b7dSRichard Lowe 	 * [tolik] Additional fix for bug 1063790. It was fixed
2592*10d63b7dSRichard Lowe 	 * for serial make long ago, but DMake dumps core when
2593*10d63b7dSRichard Lowe 	 * target is a symlink and sccs file is newer then target.
2594*10d63b7dSRichard Lowe 	 * In this case, finish_children() calls update_target()
2595*10d63b7dSRichard Lowe 	 * with line==NULL.
2596*10d63b7dSRichard Lowe 	 */
2597*10d63b7dSRichard Lowe 	if(line == NULL) {
2598*10d63b7dSRichard Lowe 		/* XXX. Should we do anything here? */
2599*10d63b7dSRichard Lowe 		return;
2600*10d63b7dSRichard Lowe 	}
2601*10d63b7dSRichard Lowe 
2602*10d63b7dSRichard Lowe 	target = line->body.line.target;
2603*10d63b7dSRichard Lowe 
2604*10d63b7dSRichard Lowe 	if ((result == build_ok) && (line->body.line.command_used != NULL)) {
2605*10d63b7dSRichard Lowe 		if (do_not_exec_rule ||
2606*10d63b7dSRichard Lowe 		    touch ||
2607*10d63b7dSRichard Lowe 		    (target->is_member &&
2608*10d63b7dSRichard Lowe 		     (line->body.line.command_template != NULL) &&
2609*10d63b7dSRichard Lowe 		     (line->body.line.command_template->command_line->string_mb[0] == 0) &&
2610*10d63b7dSRichard Lowe 		     (line->body.line.command_template->next == NULL))) {
2611*10d63b7dSRichard Lowe 			/* If we are simulating execution we need to fake a */
2612*10d63b7dSRichard Lowe 			/* new timestamp for the target we didnt build */
2613*10d63b7dSRichard Lowe 			target->stat.time = file_max_time;
2614*10d63b7dSRichard Lowe 		} else {
2615*10d63b7dSRichard Lowe 			/*
2616*10d63b7dSRichard Lowe 			 * If we really built the target we read the new
2617*10d63b7dSRichard Lowe 			 * timestamp.
2618*10d63b7dSRichard Lowe 			 * Fix for bug #1110906: if .c file is newer than
2619*10d63b7dSRichard Lowe 			 * the corresponding .o file which is in an archive
2620*10d63b7dSRichard Lowe 			 * file, make will compile the .c file but it won't
2621*10d63b7dSRichard Lowe 			 * update the object in the .a file.
2622*10d63b7dSRichard Lowe 			 */
2623*10d63b7dSRichard Lowe 			old_stat_time = target->stat.time;
2624*10d63b7dSRichard Lowe 			target->stat.time = file_no_time;
2625*10d63b7dSRichard Lowe 			(void) exists(target);
2626*10d63b7dSRichard Lowe 			if ((target->is_member) &&
2627*10d63b7dSRichard Lowe 			    (target->stat.time == old_stat_time)) {
2628*10d63b7dSRichard Lowe 				member = get_prop(target->prop, member_prop);
2629*10d63b7dSRichard Lowe 				if (member != NULL) {
2630*10d63b7dSRichard Lowe 					target->stat.time = member->body.member.library->stat.time;
2631*10d63b7dSRichard Lowe 					target->stat.time.tv_sec++;
2632*10d63b7dSRichard Lowe 				}
2633*10d63b7dSRichard Lowe 			}
2634*10d63b7dSRichard Lowe 		}
2635*10d63b7dSRichard Lowe 		/* If the target is part of a group we need to propagate the */
2636*10d63b7dSRichard Lowe 		/* result of the run to all members */
2637*10d63b7dSRichard Lowe 		for (target_group = line->body.line.target_group;
2638*10d63b7dSRichard Lowe 		     target_group != NULL;
2639*10d63b7dSRichard Lowe 		     target_group = target_group->next) {
2640*10d63b7dSRichard Lowe 			target_group->name->stat.time = target->stat.time;
2641*10d63b7dSRichard Lowe 			line2 = maybe_append_prop(target_group->name,
2642*10d63b7dSRichard Lowe 						  line_prop);
2643*10d63b7dSRichard Lowe 			line2->body.line.command_used =
2644*10d63b7dSRichard Lowe 			  line->body.line.command_used;
2645*10d63b7dSRichard Lowe 			line2->body.line.target = target_group->name;
2646*10d63b7dSRichard Lowe 		}
2647*10d63b7dSRichard Lowe 	}
2648*10d63b7dSRichard Lowe 	target->has_built = true;
2649*10d63b7dSRichard Lowe }
2650*10d63b7dSRichard Lowe 
2651*10d63b7dSRichard Lowe /*
2652*10d63b7dSRichard Lowe  *	sccs_get(target, command)
2653*10d63b7dSRichard Lowe  *
2654*10d63b7dSRichard Lowe  *	Figures out if it possible to sccs get a file
2655*10d63b7dSRichard Lowe  *	and builds the command to do it if it is.
2656*10d63b7dSRichard Lowe  *
2657*10d63b7dSRichard Lowe  *	Return value:
2658*10d63b7dSRichard Lowe  *				Indicates if sccs get failed or not
2659*10d63b7dSRichard Lowe  *
2660*10d63b7dSRichard Lowe  *	Parameters:
2661*10d63b7dSRichard Lowe  *		target		Target to get
2662*10d63b7dSRichard Lowe  *		command		Where to deposit command to use
2663*10d63b7dSRichard Lowe  *
2664*10d63b7dSRichard Lowe  *	Global variables used:
2665*10d63b7dSRichard Lowe  *		debug_level	Should we trace activities?
2666*10d63b7dSRichard Lowe  *		recursion_level	Used for tracing
2667*10d63b7dSRichard Lowe  *		sccs_get_rule	The rule to used for sccs getting
2668*10d63b7dSRichard Lowe  */
2669*10d63b7dSRichard Lowe static Doname
2670*10d63b7dSRichard Lowe sccs_get(register Name target, register Property *command)
2671*10d63b7dSRichard Lowe {
2672*10d63b7dSRichard Lowe 	register int		result;
2673*10d63b7dSRichard Lowe 	char			link[MAXPATHLEN];
2674*10d63b7dSRichard Lowe 	String_rec		string;
2675*10d63b7dSRichard Lowe 	wchar_t			name[MAXPATHLEN];
2676*10d63b7dSRichard Lowe 	register wchar_t	*p;
2677*10d63b7dSRichard Lowe 	timestruc_t		sccs_time;
2678*10d63b7dSRichard Lowe 	register Property	line;
2679*10d63b7dSRichard Lowe 	int			sym_link_depth = 0;
2680*10d63b7dSRichard Lowe 
2681*10d63b7dSRichard Lowe 	/* For sccs, we need to chase symlinks. */
2682*10d63b7dSRichard Lowe         while (target->stat.is_sym_link) {
2683*10d63b7dSRichard Lowe 		if (sym_link_depth++ > 90) {
2684*10d63b7dSRichard Lowe 			fatal(gettext("Can't read symbolic link `%s': Number of symbolic links encountered during path name traversal exceeds 90."),
2685*10d63b7dSRichard Lowe 			      target->string_mb);
2686*10d63b7dSRichard Lowe 		}
2687*10d63b7dSRichard Lowe                 /* Read the value of the link. */
2688*10d63b7dSRichard Lowe                 result = readlink_vroot(target->string_mb,
2689*10d63b7dSRichard Lowe 					link,
2690*10d63b7dSRichard Lowe 					sizeof(link),
2691*10d63b7dSRichard Lowe 					NULL,
2692*10d63b7dSRichard Lowe 					VROOT_DEFAULT);
2693*10d63b7dSRichard Lowe                 if (result == -1) {
2694*10d63b7dSRichard Lowe                         fatal(gettext("Can't read symbolic link `%s': %s"),
2695*10d63b7dSRichard Lowe                               target->string_mb, errmsg(errno));
2696*10d63b7dSRichard Lowe 		}
2697*10d63b7dSRichard Lowe 		link[result] = 0;
2698*10d63b7dSRichard Lowe                 /* Use the value to build the proper filename. */
2699*10d63b7dSRichard Lowe                 INIT_STRING_FROM_STACK(string, name);
2700*10d63b7dSRichard Lowe 
2701*10d63b7dSRichard Lowe 		Wstring wcb(target);
2702*10d63b7dSRichard Lowe                 if ((link[0] != slash_char) &&
2703*10d63b7dSRichard Lowe                     ((p = (wchar_t *) wcsrchr(wcb.get_string(), slash_char)) != NULL)) {
2704*10d63b7dSRichard Lowe                         append_string(wcb.get_string(), &string, p - wcb.get_string() + 1);
2705*10d63b7dSRichard Lowe 		}
2706*10d63b7dSRichard Lowe                 append_string(link, &string, result);
2707*10d63b7dSRichard Lowe                 /* Replace the old name with the translated name. */
2708*10d63b7dSRichard Lowe 		target = normalize_name(string.buffer.start, string.text.p - string.buffer.start);
2709*10d63b7dSRichard Lowe                 (void) exists(target);
2710*10d63b7dSRichard Lowe                 if (string.free_after_use) {
2711*10d63b7dSRichard Lowe                         retmem(string.buffer.start);
2712*10d63b7dSRichard Lowe 		}
2713*10d63b7dSRichard Lowe         }
2714*10d63b7dSRichard Lowe 
2715*10d63b7dSRichard Lowe 	/*
2716*10d63b7dSRichard Lowe 	 * read_dir() also reads the ?/SCCS dir and saves information
2717*10d63b7dSRichard Lowe 	 * about which files have SCSC/s. files.
2718*10d63b7dSRichard Lowe 	 */
2719*10d63b7dSRichard Lowe 	if (target->stat.has_sccs == DONT_KNOW_SCCS) {
2720*10d63b7dSRichard Lowe 		read_directory_of_file(target);
2721*10d63b7dSRichard Lowe 	}
2722*10d63b7dSRichard Lowe 	switch (target->stat.has_sccs) {
2723*10d63b7dSRichard Lowe 	case DONT_KNOW_SCCS:
2724*10d63b7dSRichard Lowe 		/* We dont know by now there is no SCCS/s.* */
2725*10d63b7dSRichard Lowe 		target->stat.has_sccs = NO_SCCS;
2726*10d63b7dSRichard Lowe 	case NO_SCCS:
2727*10d63b7dSRichard Lowe 		/*
2728*10d63b7dSRichard Lowe 		 * If there is no SCCS/s.* but the plain file exists,
2729*10d63b7dSRichard Lowe 		 * we say things are OK.
2730*10d63b7dSRichard Lowe 		 */
2731*10d63b7dSRichard Lowe 		if (target->stat.time > file_doesnt_exist) {
2732*10d63b7dSRichard Lowe 			return build_ok;
2733*10d63b7dSRichard Lowe 		}
2734*10d63b7dSRichard Lowe 		/* If we cant find the plain file, we give up. */
2735*10d63b7dSRichard Lowe 		return build_dont_know;
2736*10d63b7dSRichard Lowe 	case HAS_SCCS:
2737*10d63b7dSRichard Lowe 		/*
2738*10d63b7dSRichard Lowe 		 * Pay dirt. We now need to figure out if the plain file
2739*10d63b7dSRichard Lowe 		 * is out of date relative to the SCCS/s.* file.
2740*10d63b7dSRichard Lowe 		 */
2741*10d63b7dSRichard Lowe 		sccs_time = exists(get_prop(target->prop,
2742*10d63b7dSRichard Lowe 					    sccs_prop)->body.sccs.file);
2743*10d63b7dSRichard Lowe 		break;
2744*10d63b7dSRichard Lowe 	}
2745*10d63b7dSRichard Lowe 
2746*10d63b7dSRichard Lowe 	if ((!target->has_complained &&
2747*10d63b7dSRichard Lowe 	    (sccs_time != file_doesnt_exist) &&
2748*10d63b7dSRichard Lowe 	    (sccs_get_rule != NULL))) {
2749*10d63b7dSRichard Lowe 		/* only checking */
2750*10d63b7dSRichard Lowe 		if (command == NULL) {
2751*10d63b7dSRichard Lowe 			return build_ok;
2752*10d63b7dSRichard Lowe 		}
2753*10d63b7dSRichard Lowe 		/*
2754*10d63b7dSRichard Lowe 		 * We provide a command line for the target. The line is a
2755*10d63b7dSRichard Lowe 		 * "sccs get" command from default.mk.
2756*10d63b7dSRichard Lowe 		 */
2757*10d63b7dSRichard Lowe 		line = maybe_append_prop(target, line_prop);
2758*10d63b7dSRichard Lowe 		*command = line;
2759*10d63b7dSRichard Lowe 		if (sccs_time > target->stat.time) {
2760*10d63b7dSRichard Lowe 			/*
2761*10d63b7dSRichard Lowe 			 * And only if the plain file is out of date do we
2762*10d63b7dSRichard Lowe 			 * request execution of the command.
2763*10d63b7dSRichard Lowe 			 */
2764*10d63b7dSRichard Lowe 			line->body.line.is_out_of_date = true;
2765*10d63b7dSRichard Lowe 			if (debug_level > 0) {
2766*10d63b7dSRichard Lowe 				(void) printf(gettext("%*sSccs getting %s because s. file is younger than source file\n"),
2767*10d63b7dSRichard Lowe 					      recursion_level,
2768*10d63b7dSRichard Lowe 					      "",
2769*10d63b7dSRichard Lowe 					      target->string_mb);
2770*10d63b7dSRichard Lowe 			}
2771*10d63b7dSRichard Lowe 		}
2772*10d63b7dSRichard Lowe 		line->body.line.sccs_command = true;
2773*10d63b7dSRichard Lowe 		line->body.line.command_template = sccs_get_rule;
2774*10d63b7dSRichard Lowe 		if(!svr4 && (!allrules_read || posix)) {
2775*10d63b7dSRichard Lowe 		   if((target->prop) &&
2776*10d63b7dSRichard Lowe 		      (target->prop->body.sccs.file) &&
2777*10d63b7dSRichard Lowe 		      (target->prop->body.sccs.file->string_mb)) {
2778*10d63b7dSRichard Lowe 		      if((strlen(target->prop->body.sccs.file->string_mb) ==
2779*10d63b7dSRichard Lowe 			strlen(target->string_mb) + 2) &&
2780*10d63b7dSRichard Lowe 		        (target->prop->body.sccs.file->string_mb[0] == 's') &&
2781*10d63b7dSRichard Lowe 		        (target->prop->body.sccs.file->string_mb[1] == '.')) {
2782*10d63b7dSRichard Lowe 
2783*10d63b7dSRichard Lowe 		         line->body.line.command_template = get_posix_rule;
2784*10d63b7dSRichard Lowe 		      }
2785*10d63b7dSRichard Lowe 		   }
2786*10d63b7dSRichard Lowe 		}
2787*10d63b7dSRichard Lowe 		line->body.line.target = target;
2788*10d63b7dSRichard Lowe 		/*
2789*10d63b7dSRichard Lowe 		 * Also make sure the rule is build with $* and $<
2790*10d63b7dSRichard Lowe 		 * bound properly.
2791*10d63b7dSRichard Lowe 		 */
2792*10d63b7dSRichard Lowe 		line->body.line.star = NULL;
2793*10d63b7dSRichard Lowe 		line->body.line.less = NULL;
2794*10d63b7dSRichard Lowe 		line->body.line.percent = NULL;
2795*10d63b7dSRichard Lowe 		return build_ok;
2796*10d63b7dSRichard Lowe 	}
2797*10d63b7dSRichard Lowe 	return build_dont_know;
2798*10d63b7dSRichard Lowe }
2799*10d63b7dSRichard Lowe 
2800*10d63b7dSRichard Lowe /*
2801*10d63b7dSRichard Lowe  *	read_directory_of_file(file)
2802*10d63b7dSRichard Lowe  *
2803*10d63b7dSRichard Lowe  *	Reads the directory the specified file lives in.
2804*10d63b7dSRichard Lowe  *
2805*10d63b7dSRichard Lowe  *	Parameters:
2806*10d63b7dSRichard Lowe  *		file		The file we need to read dir for
2807*10d63b7dSRichard Lowe  *
2808*10d63b7dSRichard Lowe  *	Global variables used:
2809*10d63b7dSRichard Lowe  *		dot		The Name ".", used as the default dir
2810*10d63b7dSRichard Lowe  */
2811*10d63b7dSRichard Lowe void
2812*10d63b7dSRichard Lowe read_directory_of_file(register Name file)
2813*10d63b7dSRichard Lowe {
2814*10d63b7dSRichard Lowe 
2815*10d63b7dSRichard Lowe 	Wstring file_string(file);
2816*10d63b7dSRichard Lowe 	wchar_t * wcb = file_string.get_string();
2817*10d63b7dSRichard Lowe 	wchar_t usr_include_buf[MAXPATHLEN];
2818*10d63b7dSRichard Lowe 	wchar_t usr_include_sys_buf[MAXPATHLEN];
2819*10d63b7dSRichard Lowe 
2820*10d63b7dSRichard Lowe 	register Name		directory = dot;
2821*10d63b7dSRichard Lowe 	register wchar_t	*p = (wchar_t *) wcsrchr(wcb,
2822*10d63b7dSRichard Lowe 							(int) slash_char);
2823*10d63b7dSRichard Lowe 	register int		length = p - wcb;
2824*10d63b7dSRichard Lowe 	static Name		usr_include;
2825*10d63b7dSRichard Lowe 	static Name		usr_include_sys;
2826*10d63b7dSRichard Lowe 
2827*10d63b7dSRichard Lowe 	if (usr_include == NULL) {
2828*10d63b7dSRichard Lowe 		MBSTOWCS(usr_include_buf, "/usr/include");
2829*10d63b7dSRichard Lowe 		usr_include = GETNAME(usr_include_buf, FIND_LENGTH);
2830*10d63b7dSRichard Lowe 		MBSTOWCS(usr_include_sys_buf, "/usr/include/sys");
2831*10d63b7dSRichard Lowe 		usr_include_sys = GETNAME(usr_include_sys_buf, FIND_LENGTH);
2832*10d63b7dSRichard Lowe 	}
2833*10d63b7dSRichard Lowe 
2834*10d63b7dSRichard Lowe 	/*
2835*10d63b7dSRichard Lowe 	 * If the filename contains a "/" we have to extract the path
2836*10d63b7dSRichard Lowe 	 * Else the path defaults to ".".
2837*10d63b7dSRichard Lowe 	 */
2838*10d63b7dSRichard Lowe 	if (p != NULL) {
2839*10d63b7dSRichard Lowe 		/*
2840*10d63b7dSRichard Lowe 		 * Check some popular directories first to possibly
2841*10d63b7dSRichard Lowe 		 * save time. Compare string length first to gain speed.
2842*10d63b7dSRichard Lowe 		 */
2843*10d63b7dSRichard Lowe 		if ((usr_include->hash.length == length) &&
2844*10d63b7dSRichard Lowe 		    IS_WEQUALN(usr_include_buf,
2845*10d63b7dSRichard Lowe 			       wcb,
2846*10d63b7dSRichard Lowe 			       length)) {
2847*10d63b7dSRichard Lowe 			directory = usr_include;
2848*10d63b7dSRichard Lowe 		} else if ((usr_include_sys->hash.length == length) &&
2849*10d63b7dSRichard Lowe 		           IS_WEQUALN(usr_include_sys_buf,
2850*10d63b7dSRichard Lowe 		                      wcb,
2851*10d63b7dSRichard Lowe 		                      length)) {
2852*10d63b7dSRichard Lowe 			directory = usr_include_sys;
2853*10d63b7dSRichard Lowe 		} else {
2854*10d63b7dSRichard Lowe 			directory = GETNAME(wcb, length);
2855*10d63b7dSRichard Lowe 		}
2856*10d63b7dSRichard Lowe 	}
2857*10d63b7dSRichard Lowe 	(void) read_dir(directory,
2858*10d63b7dSRichard Lowe 			(wchar_t *) NULL,
2859*10d63b7dSRichard Lowe 			(Property) NULL,
2860*10d63b7dSRichard Lowe 			(wchar_t *) NULL);
2861*10d63b7dSRichard Lowe }
2862*10d63b7dSRichard Lowe 
2863*10d63b7dSRichard Lowe /*
2864*10d63b7dSRichard Lowe  *	add_pattern_conditionals(target)
2865*10d63b7dSRichard Lowe  *
2866*10d63b7dSRichard Lowe  *	Scan the list of conditionals defined for pattern targets and add any
2867*10d63b7dSRichard Lowe  *	that match this target to its list of conditionals.
2868*10d63b7dSRichard Lowe  *
2869*10d63b7dSRichard Lowe  *	Parameters:
2870*10d63b7dSRichard Lowe  *		target		The target we should add conditionals for
2871*10d63b7dSRichard Lowe  *
2872*10d63b7dSRichard Lowe  *	Global variables used:
2873*10d63b7dSRichard Lowe  *		conditionals	The list of pattern conditionals
2874*10d63b7dSRichard Lowe  */
2875*10d63b7dSRichard Lowe static void
2876*10d63b7dSRichard Lowe add_pattern_conditionals(register Name target)
2877*10d63b7dSRichard Lowe {
2878*10d63b7dSRichard Lowe 	register Property	conditional;
2879*10d63b7dSRichard Lowe 	Property		new_prop;
2880*10d63b7dSRichard Lowe 	Property		*previous;
2881*10d63b7dSRichard Lowe 	Name_rec		dummy;
2882*10d63b7dSRichard Lowe 	wchar_t			*pattern;
2883*10d63b7dSRichard Lowe 	wchar_t			*percent;
2884*10d63b7dSRichard Lowe 	int			length;
2885*10d63b7dSRichard Lowe 
2886*10d63b7dSRichard Lowe 	Wstring wcb(target);
2887*10d63b7dSRichard Lowe 	Wstring wcb1;
2888*10d63b7dSRichard Lowe 
2889*10d63b7dSRichard Lowe 	for (conditional = get_prop(conditionals->prop, conditional_prop);
2890*10d63b7dSRichard Lowe 	     conditional != NULL;
2891*10d63b7dSRichard Lowe 	     conditional = get_prop(conditional->next, conditional_prop)) {
2892*10d63b7dSRichard Lowe 		wcb1.init(conditional->body.conditional.target);
2893*10d63b7dSRichard Lowe 		pattern = wcb1.get_string();
2894*10d63b7dSRichard Lowe 		if (pattern[1] != 0) {
2895*10d63b7dSRichard Lowe 			percent = (wchar_t *) wcschr(pattern, (int) percent_char);
2896*10d63b7dSRichard Lowe 			if (!wcb.equaln(pattern, percent-pattern) ||
2897*10d63b7dSRichard Lowe 			    !IS_WEQUAL(wcb.get_string(wcb.length()-wcslen(percent+1)), percent+1)) {
2898*10d63b7dSRichard Lowe 				continue;
2899*10d63b7dSRichard Lowe 			}
2900*10d63b7dSRichard Lowe 		}
2901*10d63b7dSRichard Lowe 		for (previous = &target->prop;
2902*10d63b7dSRichard Lowe 		     *previous != NULL;
2903*10d63b7dSRichard Lowe 		     previous = &(*previous)->next) {
2904*10d63b7dSRichard Lowe 			if (((*previous)->type == conditional_prop) &&
2905*10d63b7dSRichard Lowe 			    ((*previous)->body.conditional.sequence >
2906*10d63b7dSRichard Lowe 			     conditional->body.conditional.sequence)) {
2907*10d63b7dSRichard Lowe 				break;
2908*10d63b7dSRichard Lowe 			}
2909*10d63b7dSRichard Lowe 		}
2910*10d63b7dSRichard Lowe 		if (*previous == NULL) {
2911*10d63b7dSRichard Lowe 			new_prop = append_prop(target, conditional_prop);
2912*10d63b7dSRichard Lowe 		} else {
2913*10d63b7dSRichard Lowe 			dummy.prop = NULL;
2914*10d63b7dSRichard Lowe 			new_prop = append_prop(&dummy, conditional_prop);
2915*10d63b7dSRichard Lowe 			new_prop->next = *previous;
2916*10d63b7dSRichard Lowe 			*previous = new_prop;
2917*10d63b7dSRichard Lowe 		}
2918*10d63b7dSRichard Lowe 		target->conditional_cnt++;
2919*10d63b7dSRichard Lowe 		new_prop->body.conditional = conditional->body.conditional;
2920*10d63b7dSRichard Lowe 	}
2921*10d63b7dSRichard Lowe }
2922*10d63b7dSRichard Lowe 
2923*10d63b7dSRichard Lowe /*
2924*10d63b7dSRichard Lowe  *	set_locals(target, old_locals)
2925*10d63b7dSRichard Lowe  *
2926*10d63b7dSRichard Lowe  *	Sets any conditional macros for the target.
2927*10d63b7dSRichard Lowe  *	Each target carries a possibly empty set of conditional properties.
2928*10d63b7dSRichard Lowe  *
2929*10d63b7dSRichard Lowe  *	Parameters:
2930*10d63b7dSRichard Lowe  *		target		The target to set conditional macros for
2931*10d63b7dSRichard Lowe  *		old_locals	Space to store old values in
2932*10d63b7dSRichard Lowe  *
2933*10d63b7dSRichard Lowe  *	Global variables used:
2934*10d63b7dSRichard Lowe  *		debug_level	Should we trace activity?
2935*10d63b7dSRichard Lowe  *		is_conditional	We need to preserve this value
2936*10d63b7dSRichard Lowe  *		recursion_level	Used for tracing
2937*10d63b7dSRichard Lowe  */
2938*10d63b7dSRichard Lowe void
2939*10d63b7dSRichard Lowe set_locals(register Name target, register Property old_locals)
2940*10d63b7dSRichard Lowe {
2941*10d63b7dSRichard Lowe 	register Property	conditional;
2942*10d63b7dSRichard Lowe 	register int		i;
2943*10d63b7dSRichard Lowe 	register Boolean	saved_conditional_macro_used;
2944*10d63b7dSRichard Lowe 	Chain			cond_name;
2945*10d63b7dSRichard Lowe 	Chain			cond_chain;
2946*10d63b7dSRichard Lowe 
2947*10d63b7dSRichard Lowe 	if (target->dont_activate_cond_values) {
2948*10d63b7dSRichard Lowe 		return;
2949*10d63b7dSRichard Lowe 	}
2950*10d63b7dSRichard Lowe 
2951*10d63b7dSRichard Lowe 	saved_conditional_macro_used = conditional_macro_used;
2952*10d63b7dSRichard Lowe 
2953*10d63b7dSRichard Lowe 	/* Scan the list of conditional properties and apply each one */
2954*10d63b7dSRichard Lowe 	for (conditional = get_prop(target->prop, conditional_prop), i = 0;
2955*10d63b7dSRichard Lowe 	     conditional != NULL;
2956*10d63b7dSRichard Lowe 	     conditional = get_prop(conditional->next, conditional_prop),
2957*10d63b7dSRichard Lowe 	     i++) {
2958*10d63b7dSRichard Lowe 		/* Save the old value */
2959*10d63b7dSRichard Lowe 		old_locals[i].body.macro =
2960*10d63b7dSRichard Lowe 		  maybe_append_prop(conditional->body.conditional.name,
2961*10d63b7dSRichard Lowe 				    macro_prop)->body.macro;
2962*10d63b7dSRichard Lowe 		if (debug_level > 1) {
2963*10d63b7dSRichard Lowe 			(void) printf(gettext("%*sActivating conditional value: "),
2964*10d63b7dSRichard Lowe 				      recursion_level,
2965*10d63b7dSRichard Lowe 				      "");
2966*10d63b7dSRichard Lowe 		}
2967*10d63b7dSRichard Lowe 		/* Set the conditional value. Macros are expanded when the */
2968*10d63b7dSRichard Lowe 		/* macro is refd as usual */
2969*10d63b7dSRichard Lowe 		if ((conditional->body.conditional.name != virtual_root) ||
2970*10d63b7dSRichard Lowe 		    (conditional->body.conditional.value != virtual_root)) {
2971*10d63b7dSRichard Lowe 			(void) SETVAR(conditional->body.conditional.name,
2972*10d63b7dSRichard Lowe 				      conditional->body.conditional.value,
2973*10d63b7dSRichard Lowe 				      (Boolean) conditional->body.conditional.append);
2974*10d63b7dSRichard Lowe 		}
2975*10d63b7dSRichard Lowe 		cond_name = ALLOC(Chain);
2976*10d63b7dSRichard Lowe 		cond_name->name = conditional->body.conditional.name;
2977*10d63b7dSRichard Lowe 	}
2978*10d63b7dSRichard Lowe 	/* Put this target on the front of the chain of conditional targets */
2979*10d63b7dSRichard Lowe 	cond_chain = ALLOC(Chain);
2980*10d63b7dSRichard Lowe 	cond_chain->name = target;
2981*10d63b7dSRichard Lowe 	cond_chain->next = conditional_targets;
2982*10d63b7dSRichard Lowe 	conditional_targets = cond_chain;
2983*10d63b7dSRichard Lowe 	conditional_macro_used = saved_conditional_macro_used;
2984*10d63b7dSRichard Lowe }
2985*10d63b7dSRichard Lowe 
2986*10d63b7dSRichard Lowe /*
2987*10d63b7dSRichard Lowe  *	reset_locals(target, old_locals, conditional, index)
2988*10d63b7dSRichard Lowe  *
2989*10d63b7dSRichard Lowe  *	Removes any conditional macros for the target.
2990*10d63b7dSRichard Lowe  *
2991*10d63b7dSRichard Lowe  *	Parameters:
2992*10d63b7dSRichard Lowe  *		target		The target we are retoring values for
2993*10d63b7dSRichard Lowe  *		old_locals	The values to restore
2994*10d63b7dSRichard Lowe  *		conditional	The first conditional block for the target
2995*10d63b7dSRichard Lowe  *		index		into the old_locals vector
2996*10d63b7dSRichard Lowe  *	Global variables used:
2997*10d63b7dSRichard Lowe  *		debug_level	Should we trace activities?
2998*10d63b7dSRichard Lowe  *		recursion_level	Used for tracing
2999*10d63b7dSRichard Lowe  */
3000*10d63b7dSRichard Lowe void
3001*10d63b7dSRichard Lowe reset_locals(register Name target, register Property old_locals, register Property conditional, register int index)
3002*10d63b7dSRichard Lowe {
3003*10d63b7dSRichard Lowe 	register Property	this_conditional;
3004*10d63b7dSRichard Lowe 	Chain			cond_chain;
3005*10d63b7dSRichard Lowe 
3006*10d63b7dSRichard Lowe 	if (target->dont_activate_cond_values) {
3007*10d63b7dSRichard Lowe 		return;
3008*10d63b7dSRichard Lowe 	}
3009*10d63b7dSRichard Lowe 
3010*10d63b7dSRichard Lowe 	/* Scan the list of conditional properties and restore the old value */
3011*10d63b7dSRichard Lowe 	/* to each one Reverse the order relative to when we assigned macros */
3012*10d63b7dSRichard Lowe 	this_conditional = get_prop(conditional->next, conditional_prop);
3013*10d63b7dSRichard Lowe 	if (this_conditional != NULL) {
3014*10d63b7dSRichard Lowe 		reset_locals(target, old_locals, this_conditional, index+1);
3015*10d63b7dSRichard Lowe 	} else {
3016*10d63b7dSRichard Lowe 		/* Remove conditional target from chain */
3017*10d63b7dSRichard Lowe 		if (conditional_targets == NULL ||
3018*10d63b7dSRichard Lowe 		    conditional_targets->name != target) {
3019*10d63b7dSRichard Lowe 			warning(gettext("Internal error: reset target not at head of condtional_targets chain"));
3020*10d63b7dSRichard Lowe 		} else {
3021*10d63b7dSRichard Lowe 			cond_chain = conditional_targets->next;
3022*10d63b7dSRichard Lowe 			retmem_mb((caddr_t) conditional_targets);
3023*10d63b7dSRichard Lowe 			conditional_targets = cond_chain;
3024*10d63b7dSRichard Lowe 		}
3025*10d63b7dSRichard Lowe 	}
3026*10d63b7dSRichard Lowe 	get_prop(conditional->body.conditional.name->prop,
3027*10d63b7dSRichard Lowe 		 macro_prop)->body.macro = old_locals[index].body.macro;
3028*10d63b7dSRichard Lowe 	if (conditional->body.conditional.name == virtual_root) {
3029*10d63b7dSRichard Lowe 		(void) SETVAR(virtual_root, getvar(virtual_root), false);
3030*10d63b7dSRichard Lowe 	}
3031*10d63b7dSRichard Lowe 	if (debug_level > 1) {
3032*10d63b7dSRichard Lowe 		if (old_locals[index].body.macro.value != NULL) {
3033*10d63b7dSRichard Lowe 			(void) printf(gettext("%*sdeactivating conditional value: %s= %s\n"),
3034*10d63b7dSRichard Lowe 				      recursion_level,
3035*10d63b7dSRichard Lowe 				      "",
3036*10d63b7dSRichard Lowe 				      conditional->body.conditional.name->
3037*10d63b7dSRichard Lowe 				      string_mb,
3038*10d63b7dSRichard Lowe 				      old_locals[index].body.macro.value->
3039*10d63b7dSRichard Lowe 				      string_mb);
3040*10d63b7dSRichard Lowe 		} else {
3041*10d63b7dSRichard Lowe 			(void) printf(gettext("%*sdeactivating conditional value: %s =\n"),
3042*10d63b7dSRichard Lowe 				      recursion_level,
3043*10d63b7dSRichard Lowe 				      "",
3044*10d63b7dSRichard Lowe 				      conditional->body.conditional.name->
3045*10d63b7dSRichard Lowe 				      string_mb);
3046*10d63b7dSRichard Lowe 		}
3047*10d63b7dSRichard Lowe 	}
3048*10d63b7dSRichard Lowe }
3049*10d63b7dSRichard Lowe 
3050*10d63b7dSRichard Lowe /*
3051*10d63b7dSRichard Lowe  *	check_auto_dependencies(target, auto_count, automatics)
3052*10d63b7dSRichard Lowe  *
3053*10d63b7dSRichard Lowe  *	Returns true if the target now has a dependency
3054*10d63b7dSRichard Lowe  *	it didn't previously have (saved on automatics).
3055*10d63b7dSRichard Lowe  *
3056*10d63b7dSRichard Lowe  *	Return value:
3057*10d63b7dSRichard Lowe  *				true if new dependency found
3058*10d63b7dSRichard Lowe  *
3059*10d63b7dSRichard Lowe  *	Parameters:
3060*10d63b7dSRichard Lowe  *		target		Target we check
3061*10d63b7dSRichard Lowe  *		auto_count	Number of old automatic vars
3062*10d63b7dSRichard Lowe  *		automatics	Saved old automatics
3063*10d63b7dSRichard Lowe  *
3064*10d63b7dSRichard Lowe  *	Global variables used:
3065*10d63b7dSRichard Lowe  *		keep_state	Indicates that .KEEP_STATE is on
3066*10d63b7dSRichard Lowe  */
3067*10d63b7dSRichard Lowe Boolean
3068*10d63b7dSRichard Lowe check_auto_dependencies(Name target, int auto_count, Name *automatics)
3069*10d63b7dSRichard Lowe {
3070*10d63b7dSRichard Lowe 	Name		*p;
3071*10d63b7dSRichard Lowe 	int		n;
3072*10d63b7dSRichard Lowe 	Property	line;
3073*10d63b7dSRichard Lowe 	Dependency	dependency;
3074*10d63b7dSRichard Lowe 
3075*10d63b7dSRichard Lowe 	if (keep_state) {
3076*10d63b7dSRichard Lowe 		if ((line = get_prop(target->prop, line_prop)) == NULL) {
3077*10d63b7dSRichard Lowe 			return false;
3078*10d63b7dSRichard Lowe 		}
3079*10d63b7dSRichard Lowe 		/* Go thru new list of automatic depes */
3080*10d63b7dSRichard Lowe 		for (dependency = line->body.line.dependencies;
3081*10d63b7dSRichard Lowe 		     dependency != NULL;
3082*10d63b7dSRichard Lowe 		     dependency = dependency->next) {
3083*10d63b7dSRichard Lowe 			/* And make sure that each one existed before we */
3084*10d63b7dSRichard Lowe 			/* built the target */
3085*10d63b7dSRichard Lowe 			if (dependency->automatic && !dependency->stale) {
3086*10d63b7dSRichard Lowe 				for (n = auto_count, p = automatics;
3087*10d63b7dSRichard Lowe 				     n > 0;
3088*10d63b7dSRichard Lowe 				     n--) {
3089*10d63b7dSRichard Lowe 					if (*p++ == dependency->name) {
3090*10d63b7dSRichard Lowe 						/* If we can find it on the */
3091*10d63b7dSRichard Lowe 						/* saved list of autos we */
3092*10d63b7dSRichard Lowe 						/* are OK  */
3093*10d63b7dSRichard Lowe 						goto not_new;
3094*10d63b7dSRichard Lowe 					}
3095*10d63b7dSRichard Lowe 				}
3096*10d63b7dSRichard Lowe 				/* But if we scan over the old list */
3097*10d63b7dSRichard Lowe 				/* of auto. without finding it it is */
3098*10d63b7dSRichard Lowe 				/* new and we must check it */
3099*10d63b7dSRichard Lowe 				return true;
3100*10d63b7dSRichard Lowe 			}
3101*10d63b7dSRichard Lowe 		not_new:;
3102*10d63b7dSRichard Lowe 		}
3103*10d63b7dSRichard Lowe 		return false;
3104*10d63b7dSRichard Lowe 	} else {
3105*10d63b7dSRichard Lowe 		return false;
3106*10d63b7dSRichard Lowe 	}
3107*10d63b7dSRichard Lowe }
3108*10d63b7dSRichard Lowe 
3109*10d63b7dSRichard Lowe 
3110*10d63b7dSRichard Lowe // Recursively delete each of the Chain struct on the chain.
3111*10d63b7dSRichard Lowe 
3112*10d63b7dSRichard Lowe static void
3113*10d63b7dSRichard Lowe delete_query_chain(Chain ch)
3114*10d63b7dSRichard Lowe {
3115*10d63b7dSRichard Lowe 	if (ch == NULL) {
3116*10d63b7dSRichard Lowe 		return;
3117*10d63b7dSRichard Lowe 	} else {
3118*10d63b7dSRichard Lowe 		delete_query_chain(ch->next);
3119*10d63b7dSRichard Lowe 		retmem_mb((char *) ch);
3120*10d63b7dSRichard Lowe 	}
3121*10d63b7dSRichard Lowe }
3122*10d63b7dSRichard Lowe 
3123*10d63b7dSRichard Lowe Doname
3124*10d63b7dSRichard Lowe target_can_be_built(register Name target) {
3125*10d63b7dSRichard Lowe 	Doname		result = build_dont_know;
3126*10d63b7dSRichard Lowe 	Name		true_target = target;
3127*10d63b7dSRichard Lowe 	Property	line;
3128*10d63b7dSRichard Lowe 
3129*10d63b7dSRichard Lowe 	if (target == wait_name) {
3130*10d63b7dSRichard Lowe 		return(build_ok);
3131*10d63b7dSRichard Lowe 	}
3132*10d63b7dSRichard Lowe 	/*
3133*10d63b7dSRichard Lowe 	 * If the target is a constructed one for a "::" target,
3134*10d63b7dSRichard Lowe 	 * we need to consider that.
3135*10d63b7dSRichard Lowe 	 */
3136*10d63b7dSRichard Lowe 	if (target->has_target_prop) {
3137*10d63b7dSRichard Lowe 		true_target = get_prop(target->prop,
3138*10d63b7dSRichard Lowe 				       target_prop)->body.target.target;
3139*10d63b7dSRichard Lowe 	}
3140*10d63b7dSRichard Lowe 
3141*10d63b7dSRichard Lowe 	(void) exists(true_target);
3142*10d63b7dSRichard Lowe 
3143*10d63b7dSRichard Lowe 	if (true_target->state == build_running) {
3144*10d63b7dSRichard Lowe 		return(build_running);
3145*10d63b7dSRichard Lowe 	}
3146*10d63b7dSRichard Lowe 	if (true_target->stat.time != file_doesnt_exist) {
3147*10d63b7dSRichard Lowe 		result = build_ok;
3148*10d63b7dSRichard Lowe 	}
3149*10d63b7dSRichard Lowe 
3150*10d63b7dSRichard Lowe 	/* get line property for the target */
3151*10d63b7dSRichard Lowe 	line = get_prop(true_target->prop, line_prop);
3152*10d63b7dSRichard Lowe 
3153*10d63b7dSRichard Lowe 	/* first check for explicit rule */
3154*10d63b7dSRichard Lowe 	if (line != NULL && line->body.line.command_template != NULL) {
3155*10d63b7dSRichard Lowe 		result = build_ok;
3156*10d63b7dSRichard Lowe 	}
3157*10d63b7dSRichard Lowe 	/* try to find pattern rule */
3158*10d63b7dSRichard Lowe 	if (result == build_dont_know) {
3159*10d63b7dSRichard Lowe 		result = find_percent_rule(target, NULL, false);
3160*10d63b7dSRichard Lowe 	}
3161*10d63b7dSRichard Lowe 
3162*10d63b7dSRichard Lowe 	/* try to find double suffix rule */
3163*10d63b7dSRichard Lowe 	if (result == build_dont_know) {
3164*10d63b7dSRichard Lowe 		if (target->is_member) {
3165*10d63b7dSRichard Lowe 			Property member = get_prop(target->prop, member_prop);
3166*10d63b7dSRichard Lowe 			if (member != NULL && member->body.member.member != NULL) {
3167*10d63b7dSRichard Lowe 				result = find_ar_suffix_rule(target, member->body.member.member, NULL, false);
3168*10d63b7dSRichard Lowe 			} else {
3169*10d63b7dSRichard Lowe 				result = find_double_suffix_rule(target, NULL, false);
3170*10d63b7dSRichard Lowe 			}
3171*10d63b7dSRichard Lowe 		} else {
3172*10d63b7dSRichard Lowe 			result = find_double_suffix_rule(target, NULL, false);
3173*10d63b7dSRichard Lowe 		}
3174*10d63b7dSRichard Lowe 	}
3175*10d63b7dSRichard Lowe 
3176*10d63b7dSRichard Lowe 	/* try to find suffix rule */
3177*10d63b7dSRichard Lowe 	if ((result == build_dont_know) && second_pass) {
3178*10d63b7dSRichard Lowe 		result = find_suffix_rule(target, target, empty_name, NULL, false);
3179*10d63b7dSRichard Lowe 	}
3180*10d63b7dSRichard Lowe 
3181*10d63b7dSRichard Lowe 	/* check for sccs */
3182*10d63b7dSRichard Lowe 	if (result == build_dont_know) {
3183*10d63b7dSRichard Lowe 		result = sccs_get(target, NULL);
3184*10d63b7dSRichard Lowe 	}
3185*10d63b7dSRichard Lowe 
3186*10d63b7dSRichard Lowe 	/* try to find dyn target */
3187*10d63b7dSRichard Lowe 	if (result == build_dont_know) {
3188*10d63b7dSRichard Lowe 		Name dtarg = find_dyntarget(target);
3189*10d63b7dSRichard Lowe 		if (dtarg != NULL) {
3190*10d63b7dSRichard Lowe 			result = target_can_be_built(dtarg);
3191*10d63b7dSRichard Lowe 		}
3192*10d63b7dSRichard Lowe 	}
3193*10d63b7dSRichard Lowe 
3194*10d63b7dSRichard Lowe 	/* check whether target was mentioned in makefile */
3195*10d63b7dSRichard Lowe 	if (result == build_dont_know) {
3196*10d63b7dSRichard Lowe 		if (target->colons != no_colon) {
3197*10d63b7dSRichard Lowe 			result = build_ok;
3198*10d63b7dSRichard Lowe 		}
3199*10d63b7dSRichard Lowe 	}
3200*10d63b7dSRichard Lowe 
3201*10d63b7dSRichard Lowe 	/* result */
3202*10d63b7dSRichard Lowe 	return result;
3203*10d63b7dSRichard Lowe }
3204