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