1*10d63b7dSRichard Lowe /*
2*10d63b7dSRichard Lowe * CDDL HEADER START
3*10d63b7dSRichard Lowe *
4*10d63b7dSRichard Lowe * The contents of this file are subject to the terms of the
5*10d63b7dSRichard Lowe * Common Development and Distribution License (the "License").
6*10d63b7dSRichard Lowe * You may not use this file except in compliance with the License.
7*10d63b7dSRichard Lowe *
8*10d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*10d63b7dSRichard Lowe * See the License for the specific language governing permissions
11*10d63b7dSRichard Lowe * and limitations under the License.
12*10d63b7dSRichard Lowe *
13*10d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*10d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*10d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*10d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*10d63b7dSRichard Lowe *
19*10d63b7dSRichard Lowe * CDDL HEADER END
20*10d63b7dSRichard Lowe */
21*10d63b7dSRichard Lowe /*
22*10d63b7dSRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23*10d63b7dSRichard Lowe * Use is subject to license terms.
24*10d63b7dSRichard Lowe */
25*10d63b7dSRichard Lowe
26*10d63b7dSRichard Lowe /*
27*10d63b7dSRichard Lowe * implicit.c
28*10d63b7dSRichard Lowe *
29*10d63b7dSRichard Lowe * Handle suffix and percent rules
30*10d63b7dSRichard Lowe */
31*10d63b7dSRichard Lowe
32*10d63b7dSRichard Lowe /*
33*10d63b7dSRichard Lowe * Included files
34*10d63b7dSRichard Lowe */
35*10d63b7dSRichard Lowe #include <mk/defs.h>
36*10d63b7dSRichard Lowe #include <mksh/macro.h> /* expand_value() */
37*10d63b7dSRichard Lowe #include <mksh/misc.h> /* retmem() */
38*10d63b7dSRichard Lowe #include <libintl.h>
39*10d63b7dSRichard Lowe
40*10d63b7dSRichard Lowe /*
41*10d63b7dSRichard Lowe * Defined macros
42*10d63b7dSRichard Lowe */
43*10d63b7dSRichard Lowe
44*10d63b7dSRichard Lowe /*
45*10d63b7dSRichard Lowe * typedefs & structs
46*10d63b7dSRichard Lowe */
47*10d63b7dSRichard Lowe
48*10d63b7dSRichard Lowe /*
49*10d63b7dSRichard Lowe * Static variables
50*10d63b7dSRichard Lowe */
51*10d63b7dSRichard Lowe static wchar_t WIDE_NULL[1] = {(wchar_t) nul_char};
52*10d63b7dSRichard Lowe
53*10d63b7dSRichard Lowe /*
54*10d63b7dSRichard Lowe * File table of contents
55*10d63b7dSRichard Lowe */
56*10d63b7dSRichard Lowe extern Doname find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking);
57*10d63b7dSRichard Lowe extern Doname find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking);
58*10d63b7dSRichard Lowe extern Doname find_double_suffix_rule(register Name target, Property *command, Boolean rechecking);
59*10d63b7dSRichard Lowe extern void build_suffix_list(register Name target_suffix);
60*10d63b7dSRichard Lowe extern Doname find_percent_rule(register Name target, Property *command, Boolean rechecking);
61*10d63b7dSRichard Lowe static void create_target_group_and_dependencies_list(Name target, Percent pat_rule, String percent);
62*10d63b7dSRichard Lowe static Boolean match_found_with_pattern(Name target, Percent pat_rule, String percent, wchar_t *percent_buf);
63*10d63b7dSRichard Lowe static void construct_string_from_pattern(Percent pat_rule, String percent, String result);
64*10d63b7dSRichard Lowe static Boolean dependency_exists(Name target, Property line);
65*10d63b7dSRichard Lowe extern Property maybe_append_prop(Name, Property_id);
66*10d63b7dSRichard Lowe extern void add_target_to_chain(Name target, Chain * query);
67*10d63b7dSRichard Lowe
68*10d63b7dSRichard Lowe /*
69*10d63b7dSRichard Lowe * find_suffix_rule(target, target_body, target_suffix, command, rechecking)
70*10d63b7dSRichard Lowe *
71*10d63b7dSRichard Lowe * Does the lookup for single and double suffix rules.
72*10d63b7dSRichard Lowe * It calls build_suffix_list() to build the list of possible suffixes
73*10d63b7dSRichard Lowe * for the given target.
74*10d63b7dSRichard Lowe * It then scans the list to find the first possible source file that
75*10d63b7dSRichard Lowe * exists. This is done by concatenating the body of the target name
76*10d63b7dSRichard Lowe * (target name less target suffix) and the source suffix and checking
77*10d63b7dSRichard Lowe * if the resulting file exists.
78*10d63b7dSRichard Lowe *
79*10d63b7dSRichard Lowe * Return value:
80*10d63b7dSRichard Lowe * Indicates if search failed or not
81*10d63b7dSRichard Lowe *
82*10d63b7dSRichard Lowe * Parameters:
83*10d63b7dSRichard Lowe * target The target we need a rule for
84*10d63b7dSRichard Lowe * target_body The target name without the suffix
85*10d63b7dSRichard Lowe * target_suffix The suffix of the target
86*10d63b7dSRichard Lowe * command Pointer to slot to deposit cmd in if found
87*10d63b7dSRichard Lowe * rechecking true if we are rechecking target which depends
88*10d63b7dSRichard Lowe * on conditional macro and keep_state is set
89*10d63b7dSRichard Lowe *
90*10d63b7dSRichard Lowe * Global variables used:
91*10d63b7dSRichard Lowe * debug_level Indicates how much tracing to do
92*10d63b7dSRichard Lowe * recursion_level Used for tracing
93*10d63b7dSRichard Lowe */
94*10d63b7dSRichard Lowe
95*10d63b7dSRichard Lowe static Boolean actual_doname = false;
96*10d63b7dSRichard Lowe
97*10d63b7dSRichard Lowe /* /tolik/
98*10d63b7dSRichard Lowe * fix bug 1247448: Suffix Rules failed when combine with Pattern Matching Rules.
99*10d63b7dSRichard Lowe * When make attemps to apply % rule it didn't look for a single suffix rule because
100*10d63b7dSRichard Lowe * if "doname" is called from "find_percent_rule" argument "implicit" is set to true
101*10d63b7dSRichard Lowe * and find_suffix_rule was not called. I've commented the checking of "implicit"
102*10d63b7dSRichard Lowe * in "doname" and make got infinite recursion for SVR4 tilde rules.
103*10d63b7dSRichard Lowe * Usage of "we_are_in_tilde" is intended to avoid this recursion.
104*10d63b7dSRichard Lowe */
105*10d63b7dSRichard Lowe
106*10d63b7dSRichard Lowe static Boolean we_are_in_tilde = false;
107*10d63b7dSRichard Lowe
108*10d63b7dSRichard Lowe Doname
find_suffix_rule(Name target,Name target_body,Name target_suffix,Property * command,Boolean rechecking)109*10d63b7dSRichard Lowe find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking)
110*10d63b7dSRichard Lowe {
111*10d63b7dSRichard Lowe static wchar_t static_string_buf_3M [ 3 * MAXPATHLEN ];
112*10d63b7dSRichard Lowe Name true_target = target;
113*10d63b7dSRichard Lowe wchar_t *sourcename = (wchar_t*)static_string_buf_3M;
114*10d63b7dSRichard Lowe register wchar_t *put_suffix;
115*10d63b7dSRichard Lowe register Property source_suffix;
116*10d63b7dSRichard Lowe register Name source;
117*10d63b7dSRichard Lowe Doname result;
118*10d63b7dSRichard Lowe register Property line;
119*10d63b7dSRichard Lowe extern Boolean tilde_rule;
120*10d63b7dSRichard Lowe Boolean name_found = true;
121*10d63b7dSRichard Lowe Boolean posix_tilde_attempt = true;
122*10d63b7dSRichard Lowe int src_len = MAXPATHLEN + strlen(target_body->string_mb);
123*10d63b7dSRichard Lowe
124*10d63b7dSRichard Lowe /*
125*10d63b7dSRichard Lowe * To avoid infinite recursion
126*10d63b7dSRichard Lowe */
127*10d63b7dSRichard Lowe if(we_are_in_tilde) {
128*10d63b7dSRichard Lowe we_are_in_tilde = false;
129*10d63b7dSRichard Lowe return(build_dont_know);
130*10d63b7dSRichard Lowe }
131*10d63b7dSRichard Lowe
132*10d63b7dSRichard Lowe /*
133*10d63b7dSRichard Lowe * If the target is a constructed one for a "::" target,
134*10d63b7dSRichard Lowe * we need to consider that.
135*10d63b7dSRichard Lowe */
136*10d63b7dSRichard Lowe if (target->has_target_prop) {
137*10d63b7dSRichard Lowe true_target = get_prop(target->prop,
138*10d63b7dSRichard Lowe target_prop)->body.target.target;
139*10d63b7dSRichard Lowe }
140*10d63b7dSRichard Lowe if (debug_level > 1) {
141*10d63b7dSRichard Lowe (void) printf("%*sfind_suffix_rule(%s,%s,%s)\n",
142*10d63b7dSRichard Lowe recursion_level,
143*10d63b7dSRichard Lowe "",
144*10d63b7dSRichard Lowe true_target->string_mb,
145*10d63b7dSRichard Lowe target_body->string_mb,
146*10d63b7dSRichard Lowe target_suffix->string_mb);
147*10d63b7dSRichard Lowe }
148*10d63b7dSRichard Lowe if (command != NULL) {
149*10d63b7dSRichard Lowe if ((true_target->suffix_scan_done == true) && (*command == NULL)) {
150*10d63b7dSRichard Lowe return build_ok;
151*10d63b7dSRichard Lowe }
152*10d63b7dSRichard Lowe }
153*10d63b7dSRichard Lowe true_target->suffix_scan_done = true;
154*10d63b7dSRichard Lowe /*
155*10d63b7dSRichard Lowe * Enter all names from the directory where the target lives as
156*10d63b7dSRichard Lowe * files that makes sense.
157*10d63b7dSRichard Lowe * This will make finding the synthesized source possible.
158*10d63b7dSRichard Lowe */
159*10d63b7dSRichard Lowe read_directory_of_file(target_body);
160*10d63b7dSRichard Lowe /* Cache the suffixes for this target suffix if not done. */
161*10d63b7dSRichard Lowe if (!target_suffix->has_read_suffixes) {
162*10d63b7dSRichard Lowe build_suffix_list(target_suffix);
163*10d63b7dSRichard Lowe }
164*10d63b7dSRichard Lowe /* Preload the sourcename vector with the head of the target name. */
165*10d63b7dSRichard Lowe if (src_len >= sizeof(static_string_buf_3M)) {
166*10d63b7dSRichard Lowe sourcename = ALLOC_WC(src_len);
167*10d63b7dSRichard Lowe }
168*10d63b7dSRichard Lowe (void) mbstowcs(sourcename,
169*10d63b7dSRichard Lowe target_body->string_mb,
170*10d63b7dSRichard Lowe (int) target_body->hash.length);
171*10d63b7dSRichard Lowe put_suffix = sourcename + target_body->hash.length;
172*10d63b7dSRichard Lowe /* Scan the suffix list for the target if one exists. */
173*10d63b7dSRichard Lowe if (target_suffix->has_suffixes) {
174*10d63b7dSRichard Lowe posix_attempts:
175*10d63b7dSRichard Lowe for (source_suffix = get_prop(target_suffix->prop,
176*10d63b7dSRichard Lowe suffix_prop);
177*10d63b7dSRichard Lowe source_suffix != NULL;
178*10d63b7dSRichard Lowe source_suffix = get_prop(source_suffix->next,
179*10d63b7dSRichard Lowe suffix_prop)) {
180*10d63b7dSRichard Lowe /* Build the synthesized source name. */
181*10d63b7dSRichard Lowe (void) mbstowcs(put_suffix,
182*10d63b7dSRichard Lowe source_suffix->body.
183*10d63b7dSRichard Lowe suffix.suffix->string_mb,
184*10d63b7dSRichard Lowe (int) source_suffix->body.
185*10d63b7dSRichard Lowe suffix.suffix->hash.length);
186*10d63b7dSRichard Lowe put_suffix[source_suffix->body.
187*10d63b7dSRichard Lowe suffix.suffix->hash.length] =
188*10d63b7dSRichard Lowe (int) nul_char;
189*10d63b7dSRichard Lowe if (debug_level > 1) {
190*10d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, sourcename);
191*10d63b7dSRichard Lowe (void) printf(gettext("%*sTrying %s\n"),
192*10d63b7dSRichard Lowe recursion_level,
193*10d63b7dSRichard Lowe "",
194*10d63b7dSRichard Lowe mbs_buffer);
195*10d63b7dSRichard Lowe }
196*10d63b7dSRichard Lowe source = getname_fn(sourcename, FIND_LENGTH, false, &name_found);
197*10d63b7dSRichard Lowe /*
198*10d63b7dSRichard Lowe * If the source file is not registered as
199*10d63b7dSRichard Lowe * a file, this source suffix did not match.
200*10d63b7dSRichard Lowe */
201*10d63b7dSRichard Lowe if(vpath_defined && !posix && !svr4) {
202*10d63b7dSRichard Lowe (void) exists(source);
203*10d63b7dSRichard Lowe }
204*10d63b7dSRichard Lowe if (!source->stat.is_file) {
205*10d63b7dSRichard Lowe if(!(posix|svr4))
206*10d63b7dSRichard Lowe {
207*10d63b7dSRichard Lowe if(!name_found) {
208*10d63b7dSRichard Lowe free_name(source);
209*10d63b7dSRichard Lowe }
210*10d63b7dSRichard Lowe continue;
211*10d63b7dSRichard Lowe }
212*10d63b7dSRichard Lowe
213*10d63b7dSRichard Lowe /* following code will ensure that the corresponding
214*10d63b7dSRichard Lowe ** tilde rules are executed when corresponding s. file
215*10d63b7dSRichard Lowe ** exists in the current directory. Though the current
216*10d63b7dSRichard Lowe ** target ends with a ~ character, there wont be any
217*10d63b7dSRichard Lowe ** any file in the current directory with that suffix
218*10d63b7dSRichard Lowe ** as it's fictitious. Even if it exists, it'll
219*10d63b7dSRichard Lowe ** execute all the rules for the ~ target.
220*10d63b7dSRichard Lowe */
221*10d63b7dSRichard Lowe
222*10d63b7dSRichard Lowe if(source->string_mb[source->hash.length - 1] == '~' &&
223*10d63b7dSRichard Lowe ( svr4 || posix_tilde_attempt ) )
224*10d63b7dSRichard Lowe {
225*10d63b7dSRichard Lowe char *p, *np;
226*10d63b7dSRichard Lowe char *tmpbuf;
227*10d63b7dSRichard Lowe
228*10d63b7dSRichard Lowe tmpbuf = getmem(source->hash.length + 8);
229*10d63b7dSRichard Lowe /* + 8 to add "s." or "SCCS/s." */
230*10d63b7dSRichard Lowe memset(tmpbuf,0,source->hash.length + 8);
231*10d63b7dSRichard Lowe source->string_mb[source->hash.length - 1] = '\0';
232*10d63b7dSRichard Lowe if(p = (char *) memchr((char *)source->string_mb,'/',source->hash.length))
233*10d63b7dSRichard Lowe {
234*10d63b7dSRichard Lowe while(1) {
235*10d63b7dSRichard Lowe if(np = (char *) memchr((char *)p+1,'/',source->hash.length - (p - source->string_mb))) {
236*10d63b7dSRichard Lowe p = np;
237*10d63b7dSRichard Lowe } else {break;}
238*10d63b7dSRichard Lowe }
239*10d63b7dSRichard Lowe /* copy everything including '/' */
240*10d63b7dSRichard Lowe strncpy(tmpbuf, source->string_mb, p - source->string_mb + 1);
241*10d63b7dSRichard Lowe strcat(tmpbuf, "s.");
242*10d63b7dSRichard Lowe strcat(tmpbuf, p+1);
243*10d63b7dSRichard Lowe retmem((wchar_t *) source->string_mb);
244*10d63b7dSRichard Lowe source->string_mb = tmpbuf;
245*10d63b7dSRichard Lowe
246*10d63b7dSRichard Lowe } else {
247*10d63b7dSRichard Lowe strcpy(tmpbuf, "s.");
248*10d63b7dSRichard Lowe strcat(tmpbuf, source->string_mb);
249*10d63b7dSRichard Lowe retmem((wchar_t *) source->string_mb);
250*10d63b7dSRichard Lowe source->string_mb = tmpbuf;
251*10d63b7dSRichard Lowe
252*10d63b7dSRichard Lowe }
253*10d63b7dSRichard Lowe source->hash.length = strlen(source->string_mb);
254*10d63b7dSRichard Lowe if(exists(source) == file_doesnt_exist)
255*10d63b7dSRichard Lowe continue;
256*10d63b7dSRichard Lowe tilde_rule = true;
257*10d63b7dSRichard Lowe we_are_in_tilde = true;
258*10d63b7dSRichard Lowe } else {
259*10d63b7dSRichard Lowe if(!name_found) {
260*10d63b7dSRichard Lowe free_name(source);
261*10d63b7dSRichard Lowe }
262*10d63b7dSRichard Lowe continue;
263*10d63b7dSRichard Lowe }
264*10d63b7dSRichard Lowe } else {
265*10d63b7dSRichard Lowe if(posix && posix_tilde_attempt) {
266*10d63b7dSRichard Lowe if(exists(source) == file_doesnt_exist) {
267*10d63b7dSRichard Lowe if(!name_found) {
268*10d63b7dSRichard Lowe free_name(source);
269*10d63b7dSRichard Lowe }
270*10d63b7dSRichard Lowe continue;
271*10d63b7dSRichard Lowe }
272*10d63b7dSRichard Lowe }
273*10d63b7dSRichard Lowe }
274*10d63b7dSRichard Lowe
275*10d63b7dSRichard Lowe if (command != NULL) {
276*10d63b7dSRichard Lowe if(!name_found) {
277*10d63b7dSRichard Lowe store_name(source);
278*10d63b7dSRichard Lowe }
279*10d63b7dSRichard Lowe /*
280*10d63b7dSRichard Lowe * The source file is a file.
281*10d63b7dSRichard Lowe * Make sure it is up to date.
282*10d63b7dSRichard Lowe */
283*10d63b7dSRichard Lowe if (dependency_exists(source,
284*10d63b7dSRichard Lowe get_prop(target->prop,
285*10d63b7dSRichard Lowe line_prop))) {
286*10d63b7dSRichard Lowe result = (Doname) source->state;
287*10d63b7dSRichard Lowe } else {
288*10d63b7dSRichard Lowe #if 0 /* with_squiggle sends false, which is buggy. : djay */
289*10d63b7dSRichard Lowe result = doname(source,
290*10d63b7dSRichard Lowe (Boolean) source_suffix->body.
291*10d63b7dSRichard Lowe suffix.suffix->with_squiggle,
292*10d63b7dSRichard Lowe true);
293*10d63b7dSRichard Lowe #else
294*10d63b7dSRichard Lowe result = doname(source,
295*10d63b7dSRichard Lowe true,
296*10d63b7dSRichard Lowe true);
297*10d63b7dSRichard Lowe #endif
298*10d63b7dSRichard Lowe }
299*10d63b7dSRichard Lowe } else {
300*10d63b7dSRichard Lowe result = target_can_be_built(source);
301*10d63b7dSRichard Lowe
302*10d63b7dSRichard Lowe if (result == build_ok) {
303*10d63b7dSRichard Lowe return result;
304*10d63b7dSRichard Lowe } else {
305*10d63b7dSRichard Lowe if(!name_found) {
306*10d63b7dSRichard Lowe free_name(source);
307*10d63b7dSRichard Lowe }
308*10d63b7dSRichard Lowe continue;
309*10d63b7dSRichard Lowe }
310*10d63b7dSRichard Lowe }
311*10d63b7dSRichard Lowe
312*10d63b7dSRichard Lowe switch (result) {
313*10d63b7dSRichard Lowe case build_dont_know:
314*10d63b7dSRichard Lowe /*
315*10d63b7dSRichard Lowe * If we still can't build the source,
316*10d63b7dSRichard Lowe * this rule is not a match,
317*10d63b7dSRichard Lowe * try the next one.
318*10d63b7dSRichard Lowe */
319*10d63b7dSRichard Lowe if (source->stat.time == file_doesnt_exist) {
320*10d63b7dSRichard Lowe if(!name_found) {
321*10d63b7dSRichard Lowe free_name(source);
322*10d63b7dSRichard Lowe }
323*10d63b7dSRichard Lowe continue;
324*10d63b7dSRichard Lowe }
325*10d63b7dSRichard Lowe case build_running:
326*10d63b7dSRichard Lowe if(!name_found) {
327*10d63b7dSRichard Lowe store_name(source);
328*10d63b7dSRichard Lowe }
329*10d63b7dSRichard Lowe true_target->suffix_scan_done = false;
330*10d63b7dSRichard Lowe line = maybe_append_prop(target, line_prop);
331*10d63b7dSRichard Lowe enter_dependency(line, source, false);
332*10d63b7dSRichard Lowe line->body.line.target = true_target;
333*10d63b7dSRichard Lowe return build_running;
334*10d63b7dSRichard Lowe case build_ok:
335*10d63b7dSRichard Lowe if(!name_found) {
336*10d63b7dSRichard Lowe store_name(source);
337*10d63b7dSRichard Lowe }
338*10d63b7dSRichard Lowe break;
339*10d63b7dSRichard Lowe case build_failed:
340*10d63b7dSRichard Lowe if(!name_found) {
341*10d63b7dSRichard Lowe store_name(source);
342*10d63b7dSRichard Lowe }
343*10d63b7dSRichard Lowe if (sourcename != static_string_buf_3M) {
344*10d63b7dSRichard Lowe retmem(sourcename);
345*10d63b7dSRichard Lowe }
346*10d63b7dSRichard Lowe return build_failed;
347*10d63b7dSRichard Lowe }
348*10d63b7dSRichard Lowe
349*10d63b7dSRichard Lowe if (debug_level > 1) {
350*10d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, sourcename);
351*10d63b7dSRichard Lowe (void) printf(gettext("%*sFound %s\n"),
352*10d63b7dSRichard Lowe recursion_level,
353*10d63b7dSRichard Lowe "",
354*10d63b7dSRichard Lowe mbs_buffer);
355*10d63b7dSRichard Lowe }
356*10d63b7dSRichard Lowe
357*10d63b7dSRichard Lowe if (source->depends_on_conditional) {
358*10d63b7dSRichard Lowe target->depends_on_conditional = true;
359*10d63b7dSRichard Lowe }
360*10d63b7dSRichard Lowe /*
361*10d63b7dSRichard Lowe * Since it is possible that the same target is built several times during
362*10d63b7dSRichard Lowe * the make run, we have to patch the target with all information we found
363*10d63b7dSRichard Lowe * here. Thus, the target will have an explicit rule the next time around.
364*10d63b7dSRichard Lowe */
365*10d63b7dSRichard Lowe line = maybe_append_prop(target, line_prop);
366*10d63b7dSRichard Lowe if (*command == NULL) {
367*10d63b7dSRichard Lowe *command = line;
368*10d63b7dSRichard Lowe }
369*10d63b7dSRichard Lowe if ((source->stat.time > (*command)->body.line.dependency_time) &&
370*10d63b7dSRichard Lowe (debug_level > 1)) {
371*10d63b7dSRichard Lowe (void) printf(gettext("%*sDate(%s)=%s Date-dependencies(%s)=%s\n"),
372*10d63b7dSRichard Lowe recursion_level,
373*10d63b7dSRichard Lowe "",
374*10d63b7dSRichard Lowe source->string_mb,
375*10d63b7dSRichard Lowe time_to_string(source->
376*10d63b7dSRichard Lowe stat.time),
377*10d63b7dSRichard Lowe true_target->string_mb,
378*10d63b7dSRichard Lowe time_to_string((*command)->
379*10d63b7dSRichard Lowe body.line.
380*10d63b7dSRichard Lowe dependency_time));
381*10d63b7dSRichard Lowe }
382*10d63b7dSRichard Lowe /*
383*10d63b7dSRichard Lowe * Determine if this new dependency made the
384*10d63b7dSRichard Lowe * target out of date.
385*10d63b7dSRichard Lowe */
386*10d63b7dSRichard Lowe (*command)->body.line.dependency_time =
387*10d63b7dSRichard Lowe MAX((*command)->body.line.dependency_time,
388*10d63b7dSRichard Lowe source->stat.time);
389*10d63b7dSRichard Lowe Boolean out_of_date;
390*10d63b7dSRichard Lowe if (target->is_member) {
391*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE_SEC(target->stat.time,
392*10d63b7dSRichard Lowe (*command)->body.line.dependency_time);
393*10d63b7dSRichard Lowe } else {
394*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE(target->stat.time,
395*10d63b7dSRichard Lowe (*command)->body.line.dependency_time);
396*10d63b7dSRichard Lowe }
397*10d63b7dSRichard Lowe if (build_unconditional || out_of_date) {
398*10d63b7dSRichard Lowe if(!rechecking) {
399*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
400*10d63b7dSRichard Lowe }
401*10d63b7dSRichard Lowe if (debug_level > 0) {
402*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s using suffix rule for %s%s because it is out of date relative to %s\n"),
403*10d63b7dSRichard Lowe recursion_level,
404*10d63b7dSRichard Lowe "",
405*10d63b7dSRichard Lowe true_target->string_mb,
406*10d63b7dSRichard Lowe source_suffix->body.suffix.suffix->string_mb,
407*10d63b7dSRichard Lowe target_suffix->string_mb,
408*10d63b7dSRichard Lowe source->string_mb);
409*10d63b7dSRichard Lowe }
410*10d63b7dSRichard Lowe }
411*10d63b7dSRichard Lowe /*
412*10d63b7dSRichard Lowe * Add the implicit rule as the target's explicit
413*10d63b7dSRichard Lowe * rule if none actually given, and register
414*10d63b7dSRichard Lowe * dependency.
415*10d63b7dSRichard Lowe * The time checking above really should be
416*10d63b7dSRichard Lowe * conditional on actual use of implicit rule
417*10d63b7dSRichard Lowe * as well.
418*10d63b7dSRichard Lowe */
419*10d63b7dSRichard Lowe line->body.line.sccs_command = false;
420*10d63b7dSRichard Lowe if (line->body.line.command_template == NULL) {
421*10d63b7dSRichard Lowe line->body.line.command_template =
422*10d63b7dSRichard Lowe source_suffix->body.suffix.command_template;
423*10d63b7dSRichard Lowe }
424*10d63b7dSRichard Lowe enter_dependency(line, source, false);
425*10d63b7dSRichard Lowe line->body.line.target = true_target;
426*10d63b7dSRichard Lowe /*
427*10d63b7dSRichard Lowe * Also make sure the rule is built with
428*10d63b7dSRichard Lowe * $* and $< bound properly.
429*10d63b7dSRichard Lowe */
430*10d63b7dSRichard Lowe line->body.line.star = target_body;
431*10d63b7dSRichard Lowe if(svr4|posix) {
432*10d63b7dSRichard Lowe char * p;
433*10d63b7dSRichard Lowe char tstr[256];
434*10d63b7dSRichard Lowe extern Boolean dollarless_flag;
435*10d63b7dSRichard Lowe extern Name dollarless_value;
436*10d63b7dSRichard Lowe
437*10d63b7dSRichard Lowe if(tilde_rule) {
438*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, source->string_mb);
439*10d63b7dSRichard Lowe dollarless_value = GETNAME(wcs_buffer,FIND_LENGTH);
440*10d63b7dSRichard Lowe }
441*10d63b7dSRichard Lowe else {
442*10d63b7dSRichard Lowe dollarless_flag = false;
443*10d63b7dSRichard Lowe }
444*10d63b7dSRichard Lowe }
445*10d63b7dSRichard Lowe line->body.line.less = source;
446*10d63b7dSRichard Lowe line->body.line.percent = NULL;
447*10d63b7dSRichard Lowe add_target_to_chain(source, &(line->body.line.query));
448*10d63b7dSRichard Lowe if (sourcename != static_string_buf_3M) {
449*10d63b7dSRichard Lowe retmem(sourcename);
450*10d63b7dSRichard Lowe }
451*10d63b7dSRichard Lowe return build_ok;
452*10d63b7dSRichard Lowe }
453*10d63b7dSRichard Lowe if(posix && posix_tilde_attempt) {
454*10d63b7dSRichard Lowe posix_tilde_attempt = false;
455*10d63b7dSRichard Lowe goto posix_attempts;
456*10d63b7dSRichard Lowe }
457*10d63b7dSRichard Lowe if ((command != NULL) &&
458*10d63b7dSRichard Lowe ((*command) != NULL) &&
459*10d63b7dSRichard Lowe ((*command)->body.line.star == NULL)) {
460*10d63b7dSRichard Lowe (*command)->body.line.star = target_body;
461*10d63b7dSRichard Lowe }
462*10d63b7dSRichard Lowe }
463*10d63b7dSRichard Lowe if (sourcename != static_string_buf_3M) {
464*10d63b7dSRichard Lowe retmem(sourcename);
465*10d63b7dSRichard Lowe }
466*10d63b7dSRichard Lowe /* Return here in case no rule matched the target */
467*10d63b7dSRichard Lowe return build_dont_know;
468*10d63b7dSRichard Lowe }
469*10d63b7dSRichard Lowe
470*10d63b7dSRichard Lowe /*
471*10d63b7dSRichard Lowe * find_ar_suffix_rule(target, true_target, command, rechecking)
472*10d63b7dSRichard Lowe *
473*10d63b7dSRichard Lowe * Scans the .SUFFIXES list and tries
474*10d63b7dSRichard Lowe * to find a suffix on it that matches the tail of the target member name.
475*10d63b7dSRichard Lowe * If it finds a matching suffix it calls find_suffix_rule() to find
476*10d63b7dSRichard Lowe * a rule for the target using the suffix ".a".
477*10d63b7dSRichard Lowe *
478*10d63b7dSRichard Lowe * Return value:
479*10d63b7dSRichard Lowe * Indicates if search failed or not
480*10d63b7dSRichard Lowe *
481*10d63b7dSRichard Lowe * Parameters:
482*10d63b7dSRichard Lowe * target The target we need a rule for
483*10d63b7dSRichard Lowe * true_target The proper name
484*10d63b7dSRichard Lowe * command Pointer to slot where we stuff cmd, if found
485*10d63b7dSRichard Lowe * rechecking true if we are rechecking target which depends
486*10d63b7dSRichard Lowe * on conditional macro and keep_state is set
487*10d63b7dSRichard Lowe *
488*10d63b7dSRichard Lowe * Global variables used:
489*10d63b7dSRichard Lowe * debug_level Indicates how much tracing to do
490*10d63b7dSRichard Lowe * dot_a The Name ".a", compared against
491*10d63b7dSRichard Lowe * recursion_level Used for tracing
492*10d63b7dSRichard Lowe * suffixes List of suffixes used for scan (from .SUFFIXES)
493*10d63b7dSRichard Lowe */
494*10d63b7dSRichard Lowe Doname
find_ar_suffix_rule(register Name target,Name true_target,Property * command,Boolean rechecking)495*10d63b7dSRichard Lowe find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking)
496*10d63b7dSRichard Lowe {
497*10d63b7dSRichard Lowe wchar_t *target_end;
498*10d63b7dSRichard Lowe register Dependency suffix;
499*10d63b7dSRichard Lowe register int suffix_length;
500*10d63b7dSRichard Lowe Property line;
501*10d63b7dSRichard Lowe Name body;
502*10d63b7dSRichard Lowe static Name dot_a;
503*10d63b7dSRichard Lowe
504*10d63b7dSRichard Lowe Wstring targ_string(true_target);
505*10d63b7dSRichard Lowe Wstring suf_string;
506*10d63b7dSRichard Lowe
507*10d63b7dSRichard Lowe if (dot_a == NULL) {
508*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, ".a");
509*10d63b7dSRichard Lowe dot_a = GETNAME(wcs_buffer, FIND_LENGTH);
510*10d63b7dSRichard Lowe }
511*10d63b7dSRichard Lowe target_end = targ_string.get_string() + true_target->hash.length;
512*10d63b7dSRichard Lowe
513*10d63b7dSRichard Lowe /*
514*10d63b7dSRichard Lowe * We compare the tail of the target name with the suffixes
515*10d63b7dSRichard Lowe * from .SUFFIXES.
516*10d63b7dSRichard Lowe */
517*10d63b7dSRichard Lowe if (debug_level > 1) {
518*10d63b7dSRichard Lowe (void) printf("%*sfind_ar_suffix_rule(%s)\n",
519*10d63b7dSRichard Lowe recursion_level,
520*10d63b7dSRichard Lowe "",
521*10d63b7dSRichard Lowe true_target->string_mb);
522*10d63b7dSRichard Lowe }
523*10d63b7dSRichard Lowe /*
524*10d63b7dSRichard Lowe * Scan the .SUFFIXES list to see if the target matches any of
525*10d63b7dSRichard Lowe * those suffixes.
526*10d63b7dSRichard Lowe */
527*10d63b7dSRichard Lowe for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
528*10d63b7dSRichard Lowe /* Compare one suffix. */
529*10d63b7dSRichard Lowe suffix_length = suffix->name->hash.length;
530*10d63b7dSRichard Lowe suf_string.init(suffix->name);
531*10d63b7dSRichard Lowe if (!IS_WEQUALN(suf_string.get_string(),
532*10d63b7dSRichard Lowe target_end - suffix_length,
533*10d63b7dSRichard Lowe suffix_length)) {
534*10d63b7dSRichard Lowe goto not_this_one;
535*10d63b7dSRichard Lowe }
536*10d63b7dSRichard Lowe /*
537*10d63b7dSRichard Lowe * The target tail matched a suffix from the .SUFFIXES list.
538*10d63b7dSRichard Lowe * Now check for a rule to match.
539*10d63b7dSRichard Lowe */
540*10d63b7dSRichard Lowe target->suffix_scan_done = false;
541*10d63b7dSRichard Lowe body = GETNAME(targ_string.get_string(),
542*10d63b7dSRichard Lowe (int)(true_target->hash.length -
543*10d63b7dSRichard Lowe suffix_length));
544*10d63b7dSRichard Lowe we_are_in_tilde = false;
545*10d63b7dSRichard Lowe switch (find_suffix_rule(target,
546*10d63b7dSRichard Lowe body,
547*10d63b7dSRichard Lowe dot_a,
548*10d63b7dSRichard Lowe command,
549*10d63b7dSRichard Lowe rechecking)) {
550*10d63b7dSRichard Lowe case build_ok:
551*10d63b7dSRichard Lowe line = get_prop(target->prop, line_prop);
552*10d63b7dSRichard Lowe line->body.line.star = body;
553*10d63b7dSRichard Lowe return build_ok;
554*10d63b7dSRichard Lowe case build_running:
555*10d63b7dSRichard Lowe return build_running;
556*10d63b7dSRichard Lowe }
557*10d63b7dSRichard Lowe /*
558*10d63b7dSRichard Lowe * If no rule was found, we try the next suffix to see
559*10d63b7dSRichard Lowe * if it matches the target tail, and so on.
560*10d63b7dSRichard Lowe * Go here if the suffix did not match the target tail.
561*10d63b7dSRichard Lowe */
562*10d63b7dSRichard Lowe not_this_one:;
563*10d63b7dSRichard Lowe }
564*10d63b7dSRichard Lowe return build_dont_know;
565*10d63b7dSRichard Lowe }
566*10d63b7dSRichard Lowe
567*10d63b7dSRichard Lowe /*
568*10d63b7dSRichard Lowe * find_double_suffix_rule(target, command, rechecking)
569*10d63b7dSRichard Lowe *
570*10d63b7dSRichard Lowe * Scans the .SUFFIXES list and tries
571*10d63b7dSRichard Lowe * to find a suffix on it that matches the tail of the target name.
572*10d63b7dSRichard Lowe * If it finds a matching suffix it calls find_suffix_rule() to find
573*10d63b7dSRichard Lowe * a rule for the target.
574*10d63b7dSRichard Lowe *
575*10d63b7dSRichard Lowe * Return value:
576*10d63b7dSRichard Lowe * Indicates if scan failed or not
577*10d63b7dSRichard Lowe *
578*10d63b7dSRichard Lowe * Parameters:
579*10d63b7dSRichard Lowe * target Target we need a rule for
580*10d63b7dSRichard Lowe * command Pointer to slot where we stuff cmd, if found
581*10d63b7dSRichard Lowe * rechecking true if we are rechecking target which depends
582*10d63b7dSRichard Lowe * on conditional macro and keep_state is set
583*10d63b7dSRichard Lowe *
584*10d63b7dSRichard Lowe * Global variables used:
585*10d63b7dSRichard Lowe * debug_level Indicates how much tracing to do
586*10d63b7dSRichard Lowe * recursion_level Used for tracing
587*10d63b7dSRichard Lowe * suffixes List of suffixes used for scan (from .SUFFIXES)
588*10d63b7dSRichard Lowe */
589*10d63b7dSRichard Lowe Doname
find_double_suffix_rule(register Name target,Property * command,Boolean rechecking)590*10d63b7dSRichard Lowe find_double_suffix_rule(register Name target, Property *command, Boolean rechecking)
591*10d63b7dSRichard Lowe {
592*10d63b7dSRichard Lowe Name true_target = target;
593*10d63b7dSRichard Lowe Name target_body;
594*10d63b7dSRichard Lowe register wchar_t *target_end;
595*10d63b7dSRichard Lowe register Dependency suffix;
596*10d63b7dSRichard Lowe register int suffix_length;
597*10d63b7dSRichard Lowe Boolean scanned_once = false;
598*10d63b7dSRichard Lowe Boolean name_found = true;
599*10d63b7dSRichard Lowe
600*10d63b7dSRichard Lowe Wstring targ_string;
601*10d63b7dSRichard Lowe Wstring suf_string;
602*10d63b7dSRichard Lowe
603*10d63b7dSRichard Lowe /*
604*10d63b7dSRichard Lowe * If the target is a constructed one for a "::" target,
605*10d63b7dSRichard Lowe * we need to consider that.
606*10d63b7dSRichard Lowe */
607*10d63b7dSRichard Lowe if (target->has_target_prop) {
608*10d63b7dSRichard Lowe true_target = get_prop(target->prop,
609*10d63b7dSRichard Lowe target_prop)->body.target.target;
610*10d63b7dSRichard Lowe }
611*10d63b7dSRichard Lowe targ_string.init(true_target);
612*10d63b7dSRichard Lowe
613*10d63b7dSRichard Lowe /*
614*10d63b7dSRichard Lowe * We compare the tail of the target name with the
615*10d63b7dSRichard Lowe * suffixes from .SUFFIXES.
616*10d63b7dSRichard Lowe */
617*10d63b7dSRichard Lowe target_end = targ_string.get_string() + true_target->hash.length;
618*10d63b7dSRichard Lowe if (debug_level > 1) {
619*10d63b7dSRichard Lowe (void) printf("%*sfind_double_suffix_rule(%s)\n",
620*10d63b7dSRichard Lowe recursion_level,
621*10d63b7dSRichard Lowe "",
622*10d63b7dSRichard Lowe true_target->string_mb);
623*10d63b7dSRichard Lowe }
624*10d63b7dSRichard Lowe /*
625*10d63b7dSRichard Lowe * Scan the .SUFFIXES list to see if the target matches
626*10d63b7dSRichard Lowe * any of those suffixes.
627*10d63b7dSRichard Lowe */
628*10d63b7dSRichard Lowe for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
629*10d63b7dSRichard Lowe target->suffix_scan_done = false;
630*10d63b7dSRichard Lowe true_target->suffix_scan_done = false;
631*10d63b7dSRichard Lowe /* Compare one suffix. */
632*10d63b7dSRichard Lowe suffix_length = suffix->name->hash.length;
633*10d63b7dSRichard Lowe suf_string.init(suffix->name);
634*10d63b7dSRichard Lowe /* Check the lengths, or else RTC will report rua. */
635*10d63b7dSRichard Lowe if (true_target->hash.length < suffix_length) {
636*10d63b7dSRichard Lowe goto not_this_one;
637*10d63b7dSRichard Lowe } else if (!IS_WEQUALN(suf_string.get_string(),
638*10d63b7dSRichard Lowe (target_end - suffix_length),
639*10d63b7dSRichard Lowe suffix_length)) {
640*10d63b7dSRichard Lowe goto not_this_one;
641*10d63b7dSRichard Lowe }
642*10d63b7dSRichard Lowe /*
643*10d63b7dSRichard Lowe * The target tail matched a suffix from the .SUFFIXES list.
644*10d63b7dSRichard Lowe * Now check for a rule to match.
645*10d63b7dSRichard Lowe */
646*10d63b7dSRichard Lowe we_are_in_tilde = false;
647*10d63b7dSRichard Lowe target_body = GETNAME(
648*10d63b7dSRichard Lowe targ_string.get_string(),
649*10d63b7dSRichard Lowe (int)(true_target->hash.length - suffix_length)
650*10d63b7dSRichard Lowe );
651*10d63b7dSRichard Lowe switch (find_suffix_rule(target,
652*10d63b7dSRichard Lowe target_body,
653*10d63b7dSRichard Lowe suffix->name,
654*10d63b7dSRichard Lowe command,
655*10d63b7dSRichard Lowe rechecking)) {
656*10d63b7dSRichard Lowe case build_ok:
657*10d63b7dSRichard Lowe return build_ok;
658*10d63b7dSRichard Lowe case build_running:
659*10d63b7dSRichard Lowe return build_running;
660*10d63b7dSRichard Lowe }
661*10d63b7dSRichard Lowe if (true_target->suffix_scan_done == true) {
662*10d63b7dSRichard Lowe scanned_once = true;
663*10d63b7dSRichard Lowe }
664*10d63b7dSRichard Lowe /*
665*10d63b7dSRichard Lowe * If no rule was found, we try the next suffix to see
666*10d63b7dSRichard Lowe * if it matches the target tail. And so on.
667*10d63b7dSRichard Lowe * Go here if the suffix did not match the target tail.
668*10d63b7dSRichard Lowe */
669*10d63b7dSRichard Lowe not_this_one:;
670*10d63b7dSRichard Lowe }
671*10d63b7dSRichard Lowe if (scanned_once)
672*10d63b7dSRichard Lowe true_target->suffix_scan_done = true;
673*10d63b7dSRichard Lowe return build_dont_know;
674*10d63b7dSRichard Lowe }
675*10d63b7dSRichard Lowe
676*10d63b7dSRichard Lowe /*
677*10d63b7dSRichard Lowe * build_suffix_list(target_suffix)
678*10d63b7dSRichard Lowe *
679*10d63b7dSRichard Lowe * Scans the .SUFFIXES list and figures out
680*10d63b7dSRichard Lowe * which suffixes this target can be derived from.
681*10d63b7dSRichard Lowe * The target itself is not know here, we just know the suffix of the
682*10d63b7dSRichard Lowe * target. For each suffix on the list the target can be derived iff
683*10d63b7dSRichard Lowe * a rule exists for the name "<suffix-on-list><target-suffix>".
684*10d63b7dSRichard Lowe * A list of all possible building suffixes is built, with the rule for
685*10d63b7dSRichard Lowe * each, and tacked to the target suffix nameblock.
686*10d63b7dSRichard Lowe *
687*10d63b7dSRichard Lowe * Parameters:
688*10d63b7dSRichard Lowe * target_suffix The suffix we build a match list for
689*10d63b7dSRichard Lowe *
690*10d63b7dSRichard Lowe * Global variables used:
691*10d63b7dSRichard Lowe * debug_level Indicates how much tracing to do
692*10d63b7dSRichard Lowe * recursion_level Used for tracing
693*10d63b7dSRichard Lowe * suffixes List of suffixes used for scan (from .SUFFIXES)
694*10d63b7dSRichard Lowe * working_on_targets Indicates that this is a real target
695*10d63b7dSRichard Lowe */
696*10d63b7dSRichard Lowe void
build_suffix_list(register Name target_suffix)697*10d63b7dSRichard Lowe build_suffix_list(register Name target_suffix)
698*10d63b7dSRichard Lowe {
699*10d63b7dSRichard Lowe register Dependency source_suffix;
700*10d63b7dSRichard Lowe wchar_t rule_name[MAXPATHLEN];
701*10d63b7dSRichard Lowe register Property line;
702*10d63b7dSRichard Lowe register Property suffix;
703*10d63b7dSRichard Lowe Name rule;
704*10d63b7dSRichard Lowe
705*10d63b7dSRichard Lowe /* If this is before default.mk has been read we just return to try */
706*10d63b7dSRichard Lowe /* again later */
707*10d63b7dSRichard Lowe if ((suffixes == NULL) || !working_on_targets) {
708*10d63b7dSRichard Lowe return;
709*10d63b7dSRichard Lowe }
710*10d63b7dSRichard Lowe if (debug_level > 1) {
711*10d63b7dSRichard Lowe (void) printf("%*sbuild_suffix_list(%s) ",
712*10d63b7dSRichard Lowe recursion_level,
713*10d63b7dSRichard Lowe "",
714*10d63b7dSRichard Lowe target_suffix->string_mb);
715*10d63b7dSRichard Lowe }
716*10d63b7dSRichard Lowe /* Mark the target suffix saying we cashed its list */
717*10d63b7dSRichard Lowe target_suffix->has_read_suffixes = true;
718*10d63b7dSRichard Lowe /* Scan the .SUFFIXES list */
719*10d63b7dSRichard Lowe for (source_suffix = suffixes;
720*10d63b7dSRichard Lowe source_suffix != NULL;
721*10d63b7dSRichard Lowe source_suffix = source_suffix->next) {
722*10d63b7dSRichard Lowe /*
723*10d63b7dSRichard Lowe * Build the name "<suffix-on-list><target-suffix>".
724*10d63b7dSRichard Lowe * (a popular one would be ".c.o").
725*10d63b7dSRichard Lowe */
726*10d63b7dSRichard Lowe (void) mbstowcs(rule_name,
727*10d63b7dSRichard Lowe source_suffix->name->string_mb,
728*10d63b7dSRichard Lowe (int) source_suffix->name->hash.length);
729*10d63b7dSRichard Lowe (void) mbstowcs(rule_name + source_suffix->name->hash.length,
730*10d63b7dSRichard Lowe target_suffix->string_mb,
731*10d63b7dSRichard Lowe (int) target_suffix->hash.length);
732*10d63b7dSRichard Lowe /*
733*10d63b7dSRichard Lowe * Check if that name has a rule. If not, it cannot match
734*10d63b7dSRichard Lowe * any implicit rule scan and is ignored.
735*10d63b7dSRichard Lowe * The GETNAME() call only checks for presence, it will not
736*10d63b7dSRichard Lowe * enter the name if it is not defined.
737*10d63b7dSRichard Lowe */
738*10d63b7dSRichard Lowe if (((rule = getname_fn(rule_name,
739*10d63b7dSRichard Lowe (int) (source_suffix->name->
740*10d63b7dSRichard Lowe hash.length +
741*10d63b7dSRichard Lowe target_suffix->hash.length),
742*10d63b7dSRichard Lowe true)) != NULL) &&
743*10d63b7dSRichard Lowe ((line = get_prop(rule->prop, line_prop)) != NULL)) {
744*10d63b7dSRichard Lowe if (debug_level > 1) {
745*10d63b7dSRichard Lowe (void) printf("%s ", rule->string_mb);
746*10d63b7dSRichard Lowe }
747*10d63b7dSRichard Lowe /*
748*10d63b7dSRichard Lowe * This makes it possible to quickly determine if
749*10d63b7dSRichard Lowe * it will pay to look for a suffix property.
750*10d63b7dSRichard Lowe */
751*10d63b7dSRichard Lowe target_suffix->has_suffixes = true;
752*10d63b7dSRichard Lowe /*
753*10d63b7dSRichard Lowe * Add the suffix property to the target suffix
754*10d63b7dSRichard Lowe * and save the rule with it.
755*10d63b7dSRichard Lowe * All information the implicit rule scanner need
756*10d63b7dSRichard Lowe * is saved in the suffix property.
757*10d63b7dSRichard Lowe */
758*10d63b7dSRichard Lowe suffix = append_prop(target_suffix, suffix_prop);
759*10d63b7dSRichard Lowe suffix->body.suffix.suffix = source_suffix->name;
760*10d63b7dSRichard Lowe suffix->body.suffix.command_template =
761*10d63b7dSRichard Lowe line->body.line.command_template;
762*10d63b7dSRichard Lowe }
763*10d63b7dSRichard Lowe }
764*10d63b7dSRichard Lowe if (debug_level > 1) {
765*10d63b7dSRichard Lowe (void) printf("\n");
766*10d63b7dSRichard Lowe }
767*10d63b7dSRichard Lowe }
768*10d63b7dSRichard Lowe
769*10d63b7dSRichard Lowe /*
770*10d63b7dSRichard Lowe * find_percent_rule(target, command, rechecking)
771*10d63b7dSRichard Lowe *
772*10d63b7dSRichard Lowe * Tries to find a rule from the list of wildcard matched rules.
773*10d63b7dSRichard Lowe * It scans the list attempting to match the target.
774*10d63b7dSRichard Lowe * For each target match it checks if the corresponding source exists.
775*10d63b7dSRichard Lowe * If it does the match is returned.
776*10d63b7dSRichard Lowe * The percent_list is built at makefile read time.
777*10d63b7dSRichard Lowe * Each percent rule get one entry on the list.
778*10d63b7dSRichard Lowe *
779*10d63b7dSRichard Lowe * Return value:
780*10d63b7dSRichard Lowe * Indicates if the scan failed or not
781*10d63b7dSRichard Lowe *
782*10d63b7dSRichard Lowe * Parameters:
783*10d63b7dSRichard Lowe * target The target we need a rule for
784*10d63b7dSRichard Lowe * command Pointer to slot where we stuff cmd, if found
785*10d63b7dSRichard Lowe * rechecking true if we are rechecking target which depends
786*10d63b7dSRichard Lowe * on conditional macro and keep_state is set
787*10d63b7dSRichard Lowe *
788*10d63b7dSRichard Lowe * Global variables used:
789*10d63b7dSRichard Lowe * debug_level Indicates how much tracing to do
790*10d63b7dSRichard Lowe * percent_list List of all percent rules
791*10d63b7dSRichard Lowe * recursion_level Used for tracing
792*10d63b7dSRichard Lowe * empty_name
793*10d63b7dSRichard Lowe */
794*10d63b7dSRichard Lowe Doname
find_percent_rule(register Name target,Property * command,Boolean rechecking)795*10d63b7dSRichard Lowe find_percent_rule(register Name target, Property *command, Boolean rechecking)
796*10d63b7dSRichard Lowe {
797*10d63b7dSRichard Lowe register Percent pat_rule, pat_depe;
798*10d63b7dSRichard Lowe register Name depe_to_check;
799*10d63b7dSRichard Lowe register Dependency depe;
800*10d63b7dSRichard Lowe register Property line;
801*10d63b7dSRichard Lowe String_rec string;
802*10d63b7dSRichard Lowe wchar_t string_buf[STRING_BUFFER_LENGTH];
803*10d63b7dSRichard Lowe String_rec percent;
804*10d63b7dSRichard Lowe wchar_t percent_buf[STRING_BUFFER_LENGTH];
805*10d63b7dSRichard Lowe Name true_target = target;
806*10d63b7dSRichard Lowe Name less;
807*10d63b7dSRichard Lowe Boolean nonpattern_less;
808*10d63b7dSRichard Lowe Boolean dep_name_found = false;
809*10d63b7dSRichard Lowe Doname result = build_dont_know;
810*10d63b7dSRichard Lowe Percent rule_candidate = NULL;
811*10d63b7dSRichard Lowe Boolean rule_maybe_ok;
812*10d63b7dSRichard Lowe Boolean is_pattern;
813*10d63b7dSRichard Lowe
814*10d63b7dSRichard Lowe /* If the target is constructed for a "::" target we consider that */
815*10d63b7dSRichard Lowe if (target->has_target_prop) {
816*10d63b7dSRichard Lowe true_target = get_prop(target->prop,
817*10d63b7dSRichard Lowe target_prop)->body.target.target;
818*10d63b7dSRichard Lowe }
819*10d63b7dSRichard Lowe if (target->has_long_member_name) {
820*10d63b7dSRichard Lowe true_target = get_prop(target->prop,
821*10d63b7dSRichard Lowe long_member_name_prop)->body.long_member_name.member_name;
822*10d63b7dSRichard Lowe }
823*10d63b7dSRichard Lowe if (debug_level > 1) {
824*10d63b7dSRichard Lowe (void) printf(gettext("%*sLooking for %% rule for %s\n"),
825*10d63b7dSRichard Lowe recursion_level,
826*10d63b7dSRichard Lowe "",
827*10d63b7dSRichard Lowe true_target->string_mb);
828*10d63b7dSRichard Lowe }
829*10d63b7dSRichard Lowe for (pat_rule = percent_list;
830*10d63b7dSRichard Lowe pat_rule != NULL;
831*10d63b7dSRichard Lowe pat_rule = pat_rule->next) {
832*10d63b7dSRichard Lowe /* Avoid infinite recursion when expanding patterns */
833*10d63b7dSRichard Lowe if (pat_rule->being_expanded == true) {
834*10d63b7dSRichard Lowe continue;
835*10d63b7dSRichard Lowe }
836*10d63b7dSRichard Lowe
837*10d63b7dSRichard Lowe /* Mark this pat_rule as "maybe ok". If no % rule is found
838*10d63b7dSRichard Lowe make will use this rule. The following algorithm is used:
839*10d63b7dSRichard Lowe 1) make scans all pattern rules in order to find the rule
840*10d63b7dSRichard Lowe where ALL dependencies, including nonpattern ones, exist or
841*10d63b7dSRichard Lowe can be built (GNU behaviour). If such rule is found make
842*10d63b7dSRichard Lowe will apply it.
843*10d63b7dSRichard Lowe 2) During this check make also remembers the first pattern rule
844*10d63b7dSRichard Lowe where all PATTERN dependencies can be build (no matter what
845*10d63b7dSRichard Lowe happens with nonpattern dependencies).
846*10d63b7dSRichard Lowe 3) If no rule satisfying 1) is found, make will apply the rule
847*10d63b7dSRichard Lowe remembered in 2) if there is one.
848*10d63b7dSRichard Lowe */
849*10d63b7dSRichard Lowe rule_maybe_ok = true;
850*10d63b7dSRichard Lowe
851*10d63b7dSRichard Lowe /* used to track first percent dependency */
852*10d63b7dSRichard Lowe less = NULL;
853*10d63b7dSRichard Lowe nonpattern_less = true;
854*10d63b7dSRichard Lowe
855*10d63b7dSRichard Lowe /* check whether pattern matches.
856*10d63b7dSRichard Lowe if it matches, percent string will contain matched percent part of pattern */
857*10d63b7dSRichard Lowe if (!match_found_with_pattern(true_target, pat_rule, &percent, percent_buf)) {
858*10d63b7dSRichard Lowe continue;
859*10d63b7dSRichard Lowe }
860*10d63b7dSRichard Lowe if (pat_rule->dependencies != NULL) {
861*10d63b7dSRichard Lowe for (pat_depe = pat_rule->dependencies;
862*10d63b7dSRichard Lowe pat_depe != NULL;
863*10d63b7dSRichard Lowe pat_depe = pat_depe->next) {
864*10d63b7dSRichard Lowe /* checking result for dependency */
865*10d63b7dSRichard Lowe result = build_dont_know;
866*10d63b7dSRichard Lowe
867*10d63b7dSRichard Lowe dep_name_found = true;
868*10d63b7dSRichard Lowe if (pat_depe->name->percent) {
869*10d63b7dSRichard Lowe is_pattern = true;
870*10d63b7dSRichard Lowe /* build dependency name */
871*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
872*10d63b7dSRichard Lowe construct_string_from_pattern(pat_depe, &percent, &string);
873*10d63b7dSRichard Lowe depe_to_check = getname_fn(string.buffer.start,
874*10d63b7dSRichard Lowe FIND_LENGTH,
875*10d63b7dSRichard Lowe false,
876*10d63b7dSRichard Lowe &dep_name_found
877*10d63b7dSRichard Lowe );
878*10d63b7dSRichard Lowe
879*10d63b7dSRichard Lowe if ((less == NULL) || nonpattern_less) {
880*10d63b7dSRichard Lowe less = depe_to_check;
881*10d63b7dSRichard Lowe nonpattern_less = false;
882*10d63b7dSRichard Lowe }
883*10d63b7dSRichard Lowe } else {
884*10d63b7dSRichard Lowe /* nonpattern dependency */
885*10d63b7dSRichard Lowe is_pattern = false;
886*10d63b7dSRichard Lowe depe_to_check = pat_depe->name;
887*10d63b7dSRichard Lowe if(depe_to_check->dollar) {
888*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
889*10d63b7dSRichard Lowe expand_value(depe_to_check, &string, false);
890*10d63b7dSRichard Lowe depe_to_check = getname_fn(string.buffer.start,
891*10d63b7dSRichard Lowe FIND_LENGTH,
892*10d63b7dSRichard Lowe false,
893*10d63b7dSRichard Lowe &dep_name_found
894*10d63b7dSRichard Lowe );
895*10d63b7dSRichard Lowe }
896*10d63b7dSRichard Lowe if (less == NULL) {
897*10d63b7dSRichard Lowe less = depe_to_check;
898*10d63b7dSRichard Lowe }
899*10d63b7dSRichard Lowe }
900*10d63b7dSRichard Lowe
901*10d63b7dSRichard Lowe if (depe_to_check == empty_name) {
902*10d63b7dSRichard Lowe result = build_ok;
903*10d63b7dSRichard Lowe } else {
904*10d63b7dSRichard Lowe if (debug_level > 1) {
905*10d63b7dSRichard Lowe (void) printf(gettext("%*sTrying %s\n"),
906*10d63b7dSRichard Lowe recursion_level,
907*10d63b7dSRichard Lowe "",
908*10d63b7dSRichard Lowe depe_to_check->string_mb);
909*10d63b7dSRichard Lowe }
910*10d63b7dSRichard Lowe
911*10d63b7dSRichard Lowe pat_rule->being_expanded = true;
912*10d63b7dSRichard Lowe
913*10d63b7dSRichard Lowe /* suppress message output */
914*10d63b7dSRichard Lowe int save_debug_level = debug_level;
915*10d63b7dSRichard Lowe debug_level = 0;
916*10d63b7dSRichard Lowe
917*10d63b7dSRichard Lowe /* check whether dependency can be built */
918*10d63b7dSRichard Lowe if (dependency_exists(depe_to_check,
919*10d63b7dSRichard Lowe get_prop(target->prop,
920*10d63b7dSRichard Lowe line_prop)))
921*10d63b7dSRichard Lowe {
922*10d63b7dSRichard Lowe result = (Doname) depe_to_check->state;
923*10d63b7dSRichard Lowe } else {
924*10d63b7dSRichard Lowe if(actual_doname) {
925*10d63b7dSRichard Lowe result = doname(depe_to_check, true, true);
926*10d63b7dSRichard Lowe } else {
927*10d63b7dSRichard Lowe result = target_can_be_built(depe_to_check);
928*10d63b7dSRichard Lowe }
929*10d63b7dSRichard Lowe if(!dep_name_found) {
930*10d63b7dSRichard Lowe if(result != build_ok && result != build_running) {
931*10d63b7dSRichard Lowe free_name(depe_to_check);
932*10d63b7dSRichard Lowe } else {
933*10d63b7dSRichard Lowe store_name(depe_to_check);
934*10d63b7dSRichard Lowe }
935*10d63b7dSRichard Lowe }
936*10d63b7dSRichard Lowe }
937*10d63b7dSRichard Lowe if(result != build_ok && is_pattern) {
938*10d63b7dSRichard Lowe rule_maybe_ok = false;
939*10d63b7dSRichard Lowe }
940*10d63b7dSRichard Lowe
941*10d63b7dSRichard Lowe /* restore debug_level */
942*10d63b7dSRichard Lowe debug_level = save_debug_level;
943*10d63b7dSRichard Lowe }
944*10d63b7dSRichard Lowe
945*10d63b7dSRichard Lowe if (pat_depe->name->percent) {
946*10d63b7dSRichard Lowe if (string.free_after_use) {
947*10d63b7dSRichard Lowe retmem(string.buffer.start);
948*10d63b7dSRichard Lowe }
949*10d63b7dSRichard Lowe }
950*10d63b7dSRichard Lowe /* make can't figure out how to make this dependency */
951*10d63b7dSRichard Lowe if (result != build_ok && result != build_running) {
952*10d63b7dSRichard Lowe pat_rule->being_expanded = false;
953*10d63b7dSRichard Lowe break;
954*10d63b7dSRichard Lowe }
955*10d63b7dSRichard Lowe }
956*10d63b7dSRichard Lowe } else {
957*10d63b7dSRichard Lowe result = build_ok;
958*10d63b7dSRichard Lowe }
959*10d63b7dSRichard Lowe
960*10d63b7dSRichard Lowe /* this pattern rule is the needed one since all dependencies could be built */
961*10d63b7dSRichard Lowe if (result == build_ok || result == build_running) {
962*10d63b7dSRichard Lowe break;
963*10d63b7dSRichard Lowe }
964*10d63b7dSRichard Lowe
965*10d63b7dSRichard Lowe /* Make does not know how to build some of dependencies from this rule.
966*10d63b7dSRichard Lowe But if all "pattern" dependencies can be built, we remember this rule
967*10d63b7dSRichard Lowe as a candidate for the case if no other pattern rule found.
968*10d63b7dSRichard Lowe */
969*10d63b7dSRichard Lowe if(rule_maybe_ok && rule_candidate == NULL) {
970*10d63b7dSRichard Lowe rule_candidate = pat_rule;
971*10d63b7dSRichard Lowe }
972*10d63b7dSRichard Lowe }
973*10d63b7dSRichard Lowe
974*10d63b7dSRichard Lowe /* if no pattern matching rule was found, use the remembered candidate
975*10d63b7dSRichard Lowe or return build_dont_know if there is no candidate.
976*10d63b7dSRichard Lowe */
977*10d63b7dSRichard Lowe if (result != build_ok && result != build_running) {
978*10d63b7dSRichard Lowe if(rule_candidate) {
979*10d63b7dSRichard Lowe pat_rule = rule_candidate;
980*10d63b7dSRichard Lowe } else {
981*10d63b7dSRichard Lowe return build_dont_know;
982*10d63b7dSRichard Lowe }
983*10d63b7dSRichard Lowe }
984*10d63b7dSRichard Lowe
985*10d63b7dSRichard Lowe /* if we are performing only check whether dependency could be built with existing rules,
986*10d63b7dSRichard Lowe return success */
987*10d63b7dSRichard Lowe if (command == NULL) {
988*10d63b7dSRichard Lowe if(pat_rule != NULL) {
989*10d63b7dSRichard Lowe pat_rule->being_expanded = false;
990*10d63b7dSRichard Lowe }
991*10d63b7dSRichard Lowe return result;
992*10d63b7dSRichard Lowe }
993*10d63b7dSRichard Lowe
994*10d63b7dSRichard Lowe if (debug_level > 1) {
995*10d63b7dSRichard Lowe (void) printf(gettext("%*sMatched %s:"),
996*10d63b7dSRichard Lowe recursion_level,
997*10d63b7dSRichard Lowe "",
998*10d63b7dSRichard Lowe target->string_mb);
999*10d63b7dSRichard Lowe
1000*10d63b7dSRichard Lowe for (pat_depe = pat_rule->dependencies;
1001*10d63b7dSRichard Lowe pat_depe != NULL;
1002*10d63b7dSRichard Lowe pat_depe = pat_depe->next) {
1003*10d63b7dSRichard Lowe if (pat_depe->name->percent) {
1004*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
1005*10d63b7dSRichard Lowe construct_string_from_pattern(pat_depe, &percent, &string);
1006*10d63b7dSRichard Lowe depe_to_check = GETNAME(string.buffer.start, FIND_LENGTH);
1007*10d63b7dSRichard Lowe } else {
1008*10d63b7dSRichard Lowe depe_to_check = pat_depe->name;
1009*10d63b7dSRichard Lowe if(depe_to_check->dollar) {
1010*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
1011*10d63b7dSRichard Lowe expand_value(depe_to_check, &string, false);
1012*10d63b7dSRichard Lowe depe_to_check = GETNAME(string.buffer.start, FIND_LENGTH);
1013*10d63b7dSRichard Lowe }
1014*10d63b7dSRichard Lowe }
1015*10d63b7dSRichard Lowe
1016*10d63b7dSRichard Lowe if (depe_to_check != empty_name) {
1017*10d63b7dSRichard Lowe (void) printf(" %s", depe_to_check->string_mb);
1018*10d63b7dSRichard Lowe }
1019*10d63b7dSRichard Lowe }
1020*10d63b7dSRichard Lowe
1021*10d63b7dSRichard Lowe (void) printf(gettext(" from: %s:"),
1022*10d63b7dSRichard Lowe pat_rule->name->string_mb);
1023*10d63b7dSRichard Lowe
1024*10d63b7dSRichard Lowe for (pat_depe = pat_rule->dependencies;
1025*10d63b7dSRichard Lowe pat_depe != NULL;
1026*10d63b7dSRichard Lowe pat_depe = pat_depe->next) {
1027*10d63b7dSRichard Lowe (void) printf(" %s", pat_depe->name->string_mb);
1028*10d63b7dSRichard Lowe }
1029*10d63b7dSRichard Lowe
1030*10d63b7dSRichard Lowe (void) printf("\n");
1031*10d63b7dSRichard Lowe }
1032*10d63b7dSRichard Lowe
1033*10d63b7dSRichard Lowe if (true_target->colons == no_colon) {
1034*10d63b7dSRichard Lowe true_target->colons = one_colon;
1035*10d63b7dSRichard Lowe }
1036*10d63b7dSRichard Lowe
1037*10d63b7dSRichard Lowe /* create deppendency list and target group from matched pattern rule */
1038*10d63b7dSRichard Lowe create_target_group_and_dependencies_list(target, pat_rule, &percent);
1039*10d63b7dSRichard Lowe
1040*10d63b7dSRichard Lowe /* save command */
1041*10d63b7dSRichard Lowe line = get_prop(target->prop, line_prop);
1042*10d63b7dSRichard Lowe *command = line;
1043*10d63b7dSRichard Lowe
1044*10d63b7dSRichard Lowe /* free query chain if one exist */
1045*10d63b7dSRichard Lowe while(line->body.line.query != NULL) {
1046*10d63b7dSRichard Lowe Chain to_free = line->body.line.query;
1047*10d63b7dSRichard Lowe line->body.line.query = line->body.line.query->next;
1048*10d63b7dSRichard Lowe retmem_mb((char *) to_free);
1049*10d63b7dSRichard Lowe }
1050*10d63b7dSRichard Lowe
1051*10d63b7dSRichard Lowe if (line->body.line.dependencies != NULL) {
1052*10d63b7dSRichard Lowe /* build all collected dependencies */
1053*10d63b7dSRichard Lowe for (depe = line->body.line.dependencies;
1054*10d63b7dSRichard Lowe depe != NULL;
1055*10d63b7dSRichard Lowe depe = depe->next) {
1056*10d63b7dSRichard Lowe actual_doname = true;
1057*10d63b7dSRichard Lowe result = doname_check(depe->name, true, true, depe->automatic);
1058*10d63b7dSRichard Lowe
1059*10d63b7dSRichard Lowe actual_doname = false;
1060*10d63b7dSRichard Lowe if (result == build_failed) {
1061*10d63b7dSRichard Lowe pat_rule->being_expanded = false;
1062*10d63b7dSRichard Lowe return build_failed;
1063*10d63b7dSRichard Lowe }
1064*10d63b7dSRichard Lowe if (result == build_running) {
1065*10d63b7dSRichard Lowe pat_rule->being_expanded = false;
1066*10d63b7dSRichard Lowe return build_running;
1067*10d63b7dSRichard Lowe }
1068*10d63b7dSRichard Lowe
1069*10d63b7dSRichard Lowe if ((depe->name->stat.time > line->body.line.dependency_time) &&
1070*10d63b7dSRichard Lowe (debug_level > 1)) {
1071*10d63b7dSRichard Lowe (void) printf(gettext("%*sDate(%s)=%s Date-dependencies(%s)=%s\n"),
1072*10d63b7dSRichard Lowe recursion_level,
1073*10d63b7dSRichard Lowe "",
1074*10d63b7dSRichard Lowe depe->name->string_mb,
1075*10d63b7dSRichard Lowe time_to_string(depe->name->stat.time),
1076*10d63b7dSRichard Lowe true_target->string_mb,
1077*10d63b7dSRichard Lowe time_to_string(line->body.line.dependency_time));
1078*10d63b7dSRichard Lowe }
1079*10d63b7dSRichard Lowe
1080*10d63b7dSRichard Lowe line->body.line.dependency_time =
1081*10d63b7dSRichard Lowe MAX(line->body.line.dependency_time, depe->name->stat.time);
1082*10d63b7dSRichard Lowe
1083*10d63b7dSRichard Lowe /* determine whether this dependency made target out of date */
1084*10d63b7dSRichard Lowe Boolean out_of_date;
1085*10d63b7dSRichard Lowe if (target->is_member || depe->name->is_member) {
1086*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE_SEC(target->stat.time, depe->name->stat.time);
1087*10d63b7dSRichard Lowe } else {
1088*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE(target->stat.time, depe->name->stat.time);
1089*10d63b7dSRichard Lowe }
1090*10d63b7dSRichard Lowe if (build_unconditional || out_of_date) {
1091*10d63b7dSRichard Lowe if(!rechecking) {
1092*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
1093*10d63b7dSRichard Lowe }
1094*10d63b7dSRichard Lowe add_target_to_chain(depe->name, &(line->body.line.query));
1095*10d63b7dSRichard Lowe
1096*10d63b7dSRichard Lowe if (debug_level > 0) {
1097*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s using pattern rule %s:"),
1098*10d63b7dSRichard Lowe recursion_level,
1099*10d63b7dSRichard Lowe "",
1100*10d63b7dSRichard Lowe true_target->string_mb,
1101*10d63b7dSRichard Lowe pat_rule->name->string_mb);
1102*10d63b7dSRichard Lowe
1103*10d63b7dSRichard Lowe for (pat_depe = pat_rule->dependencies;
1104*10d63b7dSRichard Lowe pat_depe != NULL;
1105*10d63b7dSRichard Lowe pat_depe = pat_depe->next) {
1106*10d63b7dSRichard Lowe (void) printf(" %s", pat_depe->name->string_mb);
1107*10d63b7dSRichard Lowe }
1108*10d63b7dSRichard Lowe
1109*10d63b7dSRichard Lowe (void) printf(gettext(" because it is out of date relative to %s\n"),
1110*10d63b7dSRichard Lowe depe->name->string_mb);
1111*10d63b7dSRichard Lowe }
1112*10d63b7dSRichard Lowe }
1113*10d63b7dSRichard Lowe }
1114*10d63b7dSRichard Lowe } else {
1115*10d63b7dSRichard Lowe if ((true_target->stat.time <= file_doesnt_exist) ||
1116*10d63b7dSRichard Lowe (true_target->stat.time < line->body.line.dependency_time)) {
1117*10d63b7dSRichard Lowe if(!rechecking) {
1118*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
1119*10d63b7dSRichard Lowe }
1120*10d63b7dSRichard Lowe if (debug_level > 0) {
1121*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s using pattern rule %s: "),
1122*10d63b7dSRichard Lowe recursion_level,
1123*10d63b7dSRichard Lowe "",
1124*10d63b7dSRichard Lowe true_target->string_mb,
1125*10d63b7dSRichard Lowe pat_rule->name->string_mb,
1126*10d63b7dSRichard Lowe (target->stat.time > file_doesnt_exist) ?
1127*10d63b7dSRichard Lowe gettext("because it is out of date") :
1128*10d63b7dSRichard Lowe gettext("because it does not exist"));
1129*10d63b7dSRichard Lowe }
1130*10d63b7dSRichard Lowe }
1131*10d63b7dSRichard Lowe }
1132*10d63b7dSRichard Lowe
1133*10d63b7dSRichard Lowe /* enter explicit rule from percent rule */
1134*10d63b7dSRichard Lowe Name lmn_target = true_target;
1135*10d63b7dSRichard Lowe if (true_target->has_long_member_name) {
1136*10d63b7dSRichard Lowe lmn_target = get_prop(true_target->prop, long_member_name_prop)->body.long_member_name.member_name;
1137*10d63b7dSRichard Lowe }
1138*10d63b7dSRichard Lowe line->body.line.sccs_command = false;
1139*10d63b7dSRichard Lowe line->body.line.target = true_target;
1140*10d63b7dSRichard Lowe line->body.line.command_template = pat_rule->command_template;
1141*10d63b7dSRichard Lowe line->body.line.star = GETNAME(percent.buffer.start, FIND_LENGTH);
1142*10d63b7dSRichard Lowe line->body.line.less = less;
1143*10d63b7dSRichard Lowe
1144*10d63b7dSRichard Lowe if (lmn_target->parenleft) {
1145*10d63b7dSRichard Lowe Wstring lmn_string(lmn_target);
1146*10d63b7dSRichard Lowe
1147*10d63b7dSRichard Lowe wchar_t *left = (wchar_t *) wcschr(lmn_string.get_string(), (int) parenleft_char);
1148*10d63b7dSRichard Lowe wchar_t *right = (wchar_t *) wcschr(lmn_string.get_string(), (int) parenright_char);
1149*10d63b7dSRichard Lowe
1150*10d63b7dSRichard Lowe if ((left == NULL) || (right == NULL)) {
1151*10d63b7dSRichard Lowe line->body.line.percent = NULL;
1152*10d63b7dSRichard Lowe } else {
1153*10d63b7dSRichard Lowe line->body.line.percent = GETNAME(left + 1, right - left - 1);
1154*10d63b7dSRichard Lowe }
1155*10d63b7dSRichard Lowe } else {
1156*10d63b7dSRichard Lowe line->body.line.percent = NULL;
1157*10d63b7dSRichard Lowe }
1158*10d63b7dSRichard Lowe pat_rule->being_expanded = false;
1159*10d63b7dSRichard Lowe
1160*10d63b7dSRichard Lowe return result;
1161*10d63b7dSRichard Lowe }
1162*10d63b7dSRichard Lowe
1163*10d63b7dSRichard Lowe /*
1164*10d63b7dSRichard Lowe * match_found_with_pattern
1165*10d63b7dSRichard Lowe * ( target, pat_rule, percent, percent_buf)
1166*10d63b7dSRichard Lowe *
1167*10d63b7dSRichard Lowe * matches "target->string" with a % pattern.
1168*10d63b7dSRichard Lowe * If pattern contains a MACRO definition, it's expanded first.
1169*10d63b7dSRichard Lowe *
1170*10d63b7dSRichard Lowe * Return value:
1171*10d63b7dSRichard Lowe * true if a match was found
1172*10d63b7dSRichard Lowe *
1173*10d63b7dSRichard Lowe * Parameters:
1174*10d63b7dSRichard Lowe * target The target we're trying to match
1175*10d63b7dSRichard Lowe * pattern
1176*10d63b7dSRichard Lowe * percent record that contains "percent_buf" below
1177*10d63b7dSRichard Lowe * percent_buf This is where the patched % part of pattern is stored
1178*10d63b7dSRichard Lowe *
1179*10d63b7dSRichard Lowe */
1180*10d63b7dSRichard Lowe
1181*10d63b7dSRichard Lowe static Boolean
match_found_with_pattern(Name target,Percent pat_rule,String percent,wchar_t * percent_buf)1182*10d63b7dSRichard Lowe match_found_with_pattern(Name target, Percent pat_rule, String percent, wchar_t *percent_buf) {
1183*10d63b7dSRichard Lowe String_rec string;
1184*10d63b7dSRichard Lowe wchar_t string_buf[STRING_BUFFER_LENGTH];
1185*10d63b7dSRichard Lowe
1186*10d63b7dSRichard Lowe /* construct prefix string and check whether prefix matches */
1187*10d63b7dSRichard Lowe Name prefix = pat_rule->patterns[0];
1188*10d63b7dSRichard Lowe int prefix_length;
1189*10d63b7dSRichard Lowe
1190*10d63b7dSRichard Lowe Wstring targ_string(target);
1191*10d63b7dSRichard Lowe Wstring pref_string(prefix);
1192*10d63b7dSRichard Lowe Wstring suf_string;
1193*10d63b7dSRichard Lowe
1194*10d63b7dSRichard Lowe if (prefix->dollar) {
1195*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
1196*10d63b7dSRichard Lowe expand_value(prefix, &string, false);
1197*10d63b7dSRichard Lowe prefix_length = string.text.p - string.buffer.start;
1198*10d63b7dSRichard Lowe if ((string.buffer.start[0] == (int) period_char) &&
1199*10d63b7dSRichard Lowe (string.buffer.start[1] == (int) slash_char)) {
1200*10d63b7dSRichard Lowe string.buffer.start += 2;
1201*10d63b7dSRichard Lowe prefix_length -= 2;
1202*10d63b7dSRichard Lowe }
1203*10d63b7dSRichard Lowe if (!targ_string.equaln(string.buffer.start, prefix_length)) {
1204*10d63b7dSRichard Lowe return false;
1205*10d63b7dSRichard Lowe }
1206*10d63b7dSRichard Lowe } else {
1207*10d63b7dSRichard Lowe prefix_length = prefix->hash.length;
1208*10d63b7dSRichard Lowe if (!targ_string.equaln(&pref_string, prefix_length)) {
1209*10d63b7dSRichard Lowe return false;
1210*10d63b7dSRichard Lowe }
1211*10d63b7dSRichard Lowe }
1212*10d63b7dSRichard Lowe
1213*10d63b7dSRichard Lowe /* do the same with pattern suffix */
1214*10d63b7dSRichard Lowe Name suffix = pat_rule->patterns[pat_rule->patterns_total - 1];
1215*10d63b7dSRichard Lowe suf_string.init(suffix);
1216*10d63b7dSRichard Lowe
1217*10d63b7dSRichard Lowe int suffix_length;
1218*10d63b7dSRichard Lowe if (suffix->dollar) {
1219*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
1220*10d63b7dSRichard Lowe expand_value(suffix, &string, false);
1221*10d63b7dSRichard Lowe suffix_length = string.text.p - string.buffer.start;
1222*10d63b7dSRichard Lowe if(suffix_length > target->hash.length) {
1223*10d63b7dSRichard Lowe return false;
1224*10d63b7dSRichard Lowe }
1225*10d63b7dSRichard Lowe if (!targ_string.equal(string.buffer.start, target->hash.length - suffix_length)) {
1226*10d63b7dSRichard Lowe return false;
1227*10d63b7dSRichard Lowe }
1228*10d63b7dSRichard Lowe } else {
1229*10d63b7dSRichard Lowe suffix_length = (int) suffix->hash.length;
1230*10d63b7dSRichard Lowe if(suffix_length > target->hash.length) {
1231*10d63b7dSRichard Lowe return false;
1232*10d63b7dSRichard Lowe }
1233*10d63b7dSRichard Lowe if (!targ_string.equal(&suf_string, target->hash.length - suffix_length)) {
1234*10d63b7dSRichard Lowe return false;
1235*10d63b7dSRichard Lowe }
1236*10d63b7dSRichard Lowe }
1237*10d63b7dSRichard Lowe
1238*10d63b7dSRichard Lowe Boolean match_found = false;
1239*10d63b7dSRichard Lowe int percent_length = target->hash.length - prefix_length - suffix_length;
1240*10d63b7dSRichard Lowe
1241*10d63b7dSRichard Lowe while (!match_found && (percent_length >= 0)) {
1242*10d63b7dSRichard Lowe /* init result string */
1243*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
1244*10d63b7dSRichard Lowe
1245*10d63b7dSRichard Lowe /* init percent string */
1246*10d63b7dSRichard Lowe percent->buffer.start = percent_buf;
1247*10d63b7dSRichard Lowe percent->text.p = percent_buf;
1248*10d63b7dSRichard Lowe percent->text.end = NULL;
1249*10d63b7dSRichard Lowe percent->free_after_use = false;
1250*10d63b7dSRichard Lowe percent->buffer.end = percent_buf + STRING_BUFFER_LENGTH;
1251*10d63b7dSRichard Lowe
1252*10d63b7dSRichard Lowe /* construct percent and result strings */
1253*10d63b7dSRichard Lowe targ_string.append_to_str(percent, prefix_length, percent_length);
1254*10d63b7dSRichard Lowe construct_string_from_pattern(pat_rule, percent, &string);
1255*10d63b7dSRichard Lowe
1256*10d63b7dSRichard Lowe /* check for match */
1257*10d63b7dSRichard Lowe if (targ_string.equal(string.buffer.start, 0)) {
1258*10d63b7dSRichard Lowe match_found = true;
1259*10d63b7dSRichard Lowe } else {
1260*10d63b7dSRichard Lowe percent_length--;
1261*10d63b7dSRichard Lowe }
1262*10d63b7dSRichard Lowe }
1263*10d63b7dSRichard Lowe
1264*10d63b7dSRichard Lowe /* result */
1265*10d63b7dSRichard Lowe return match_found;
1266*10d63b7dSRichard Lowe }
1267*10d63b7dSRichard Lowe
1268*10d63b7dSRichard Lowe
1269*10d63b7dSRichard Lowe /*
1270*10d63b7dSRichard Lowe * create_target_group_and_dependencies_list
1271*10d63b7dSRichard Lowe * (target, pat_rule, percent)
1272*10d63b7dSRichard Lowe *
1273*10d63b7dSRichard Lowe * constructs dependency list and a target group from pattern.
1274*10d63b7dSRichard Lowe *
1275*10d63b7dSRichard Lowe * If we have the lines
1276*10d63b7dSRichard Lowe * %/%.a + %/%.b + C%/CC%.c: yyy %.d bb%/BB%.e
1277*10d63b7dSRichard Lowe * commands
1278*10d63b7dSRichard Lowe *
1279*10d63b7dSRichard Lowe * and we have matched the pattern xx/xx.a with %/%.a, then we
1280*10d63b7dSRichard Lowe * construct a target group that looks like this:
1281*10d63b7dSRichard Lowe * xx/xx.a + xx/xx.b + Cxx/CCxx.c: dependencies
1282*10d63b7dSRichard Lowe *
1283*10d63b7dSRichard Lowe * and construct dependency list that looks like this:
1284*10d63b7dSRichard Lowe * yyy xx.d bbxx/BBxx.e + already existed dependencies
1285*10d63b7dSRichard Lowe *
1286*10d63b7dSRichard Lowe * Return value:
1287*10d63b7dSRichard Lowe * none
1288*10d63b7dSRichard Lowe *
1289*10d63b7dSRichard Lowe * Parameters:
1290*10d63b7dSRichard Lowe * target The target we are building, in the previous
1291*10d63b7dSRichard Lowe * example, this is xx/xx.a
1292*10d63b7dSRichard Lowe * pat_rule the % pattern that matched "target", here %/%.a
1293*10d63b7dSRichard Lowe * percent string containing matched % part. In the example=xx.
1294*10d63b7dSRichard Lowe *
1295*10d63b7dSRichard Lowe * Global variables used:
1296*10d63b7dSRichard Lowe * empty_name
1297*10d63b7dSRichard Lowe */
1298*10d63b7dSRichard Lowe
1299*10d63b7dSRichard Lowe static void
create_target_group_and_dependencies_list(Name target,Percent pat_rule,String percent)1300*10d63b7dSRichard Lowe create_target_group_and_dependencies_list(Name target, Percent pat_rule, String percent) {
1301*10d63b7dSRichard Lowe String_rec string;
1302*10d63b7dSRichard Lowe wchar_t string_buf[STRING_BUFFER_LENGTH];
1303*10d63b7dSRichard Lowe Percent pat_depe;
1304*10d63b7dSRichard Lowe Name depe;
1305*10d63b7dSRichard Lowe Property line = maybe_append_prop(target, line_prop);
1306*10d63b7dSRichard Lowe Chain new_target_group = NULL;
1307*10d63b7dSRichard Lowe Chain *new_target_group_tail = &new_target_group;
1308*10d63b7dSRichard Lowe Chain group_member;
1309*10d63b7dSRichard Lowe
1310*10d63b7dSRichard Lowe /* create and append dependencies from rule */
1311*10d63b7dSRichard Lowe for (pat_depe = pat_rule->dependencies; pat_depe != NULL; pat_depe = pat_depe->next) {
1312*10d63b7dSRichard Lowe if (pat_depe->name->percent) {
1313*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
1314*10d63b7dSRichard Lowe construct_string_from_pattern(pat_depe, percent, &string);
1315*10d63b7dSRichard Lowe depe = GETNAME(string.buffer.start, FIND_LENGTH);
1316*10d63b7dSRichard Lowe if (depe != empty_name) {
1317*10d63b7dSRichard Lowe enter_dependency(line, depe, false);
1318*10d63b7dSRichard Lowe }
1319*10d63b7dSRichard Lowe } else {
1320*10d63b7dSRichard Lowe depe = pat_depe->name;
1321*10d63b7dSRichard Lowe if(depe->dollar) {
1322*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
1323*10d63b7dSRichard Lowe expand_value(depe, &string, false);
1324*10d63b7dSRichard Lowe depe = GETNAME(string.buffer.start, FIND_LENGTH);
1325*10d63b7dSRichard Lowe }
1326*10d63b7dSRichard Lowe enter_dependency(line, depe, false);
1327*10d63b7dSRichard Lowe }
1328*10d63b7dSRichard Lowe }
1329*10d63b7dSRichard Lowe
1330*10d63b7dSRichard Lowe /* if matched pattern is a group member, create new target group */
1331*10d63b7dSRichard Lowe for (group_member = pat_rule->target_group; group_member != NULL; group_member = group_member->next) {
1332*10d63b7dSRichard Lowe Name new_target = group_member->name;
1333*10d63b7dSRichard Lowe if (group_member->name->percent) {
1334*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf);
1335*10d63b7dSRichard Lowe construct_string_from_pattern(group_member->percent_member, percent, &string);
1336*10d63b7dSRichard Lowe new_target = GETNAME(string.buffer.start, FIND_LENGTH);
1337*10d63b7dSRichard Lowe if (new_target == empty_name) {
1338*10d63b7dSRichard Lowe continue;
1339*10d63b7dSRichard Lowe }
1340*10d63b7dSRichard Lowe }
1341*10d63b7dSRichard Lowe
1342*10d63b7dSRichard Lowe /* check for duplicates */
1343*10d63b7dSRichard Lowe Chain tgm;
1344*10d63b7dSRichard Lowe for (tgm = new_target_group; tgm != NULL; tgm = tgm->next) {
1345*10d63b7dSRichard Lowe if (new_target == tgm->name) {
1346*10d63b7dSRichard Lowe break;
1347*10d63b7dSRichard Lowe }
1348*10d63b7dSRichard Lowe }
1349*10d63b7dSRichard Lowe if (tgm != NULL) {
1350*10d63b7dSRichard Lowe continue;
1351*10d63b7dSRichard Lowe }
1352*10d63b7dSRichard Lowe
1353*10d63b7dSRichard Lowe /* insert it into the targets list */
1354*10d63b7dSRichard Lowe (*new_target_group_tail) = ALLOC(Chain);
1355*10d63b7dSRichard Lowe (*new_target_group_tail)->name = new_target;
1356*10d63b7dSRichard Lowe (*new_target_group_tail)->next = NULL;
1357*10d63b7dSRichard Lowe new_target_group_tail = &(*new_target_group_tail)->next;
1358*10d63b7dSRichard Lowe }
1359*10d63b7dSRichard Lowe
1360*10d63b7dSRichard Lowe /* now we gathered all dependencies and created target group */
1361*10d63b7dSRichard Lowe line->body.line.target_group = new_target_group;
1362*10d63b7dSRichard Lowe
1363*10d63b7dSRichard Lowe /* update properties for group members */
1364*10d63b7dSRichard Lowe for (group_member = new_target_group; group_member != NULL; group_member = group_member->next) {
1365*10d63b7dSRichard Lowe if (group_member->name != target) {
1366*10d63b7dSRichard Lowe group_member->name->prop = target->prop;
1367*10d63b7dSRichard Lowe group_member->name->conditional_cnt = target->conditional_cnt;
1368*10d63b7dSRichard Lowe }
1369*10d63b7dSRichard Lowe }
1370*10d63b7dSRichard Lowe }
1371*10d63b7dSRichard Lowe
1372*10d63b7dSRichard Lowe /*
1373*10d63b7dSRichard Lowe * construct_string_from_pattern
1374*10d63b7dSRichard Lowe * (pat_rule, percent, result)
1375*10d63b7dSRichard Lowe *
1376*10d63b7dSRichard Lowe * after pattern matched a target this routine is called to construct targets and dependencies
1377*10d63b7dSRichard Lowe * strings from this matched pattern rule and a string (percent) with substitutes % sign in pattern.
1378*10d63b7dSRichard Lowe *
1379*10d63b7dSRichard Lowe * Return value:
1380*10d63b7dSRichard Lowe * none
1381*10d63b7dSRichard Lowe *
1382*10d63b7dSRichard Lowe * Parameters:
1383*10d63b7dSRichard Lowe * pat_rule matched pattern rule
1384*10d63b7dSRichard Lowe * percent string containing matched % sign part.
1385*10d63b7dSRichard Lowe * result holds the result of string construction.
1386*10d63b7dSRichard Lowe *
1387*10d63b7dSRichard Lowe */
1388*10d63b7dSRichard Lowe static void
construct_string_from_pattern(Percent pat_rule,String percent,String result)1389*10d63b7dSRichard Lowe construct_string_from_pattern(Percent pat_rule, String percent, String result) {
1390*10d63b7dSRichard Lowe for (int i = 0; i < pat_rule->patterns_total; i++) {
1391*10d63b7dSRichard Lowe if (pat_rule->patterns[i]->dollar) {
1392*10d63b7dSRichard Lowe expand_value(pat_rule->patterns[i],
1393*10d63b7dSRichard Lowe result,
1394*10d63b7dSRichard Lowe false);
1395*10d63b7dSRichard Lowe
1396*10d63b7dSRichard Lowe } else {
1397*10d63b7dSRichard Lowe append_string(pat_rule->patterns[i]->string_mb,
1398*10d63b7dSRichard Lowe result,
1399*10d63b7dSRichard Lowe pat_rule->patterns[i]->hash.length);
1400*10d63b7dSRichard Lowe }
1401*10d63b7dSRichard Lowe
1402*10d63b7dSRichard Lowe if (i < pat_rule->patterns_total - 1) {
1403*10d63b7dSRichard Lowe append_string(percent->buffer.start,
1404*10d63b7dSRichard Lowe result,
1405*10d63b7dSRichard Lowe percent->text.p - percent->buffer.start);
1406*10d63b7dSRichard Lowe }
1407*10d63b7dSRichard Lowe }
1408*10d63b7dSRichard Lowe
1409*10d63b7dSRichard Lowe if ((result->buffer.start[0] == (int) period_char) &&
1410*10d63b7dSRichard Lowe (result->buffer.start[1] == (int) slash_char)) {
1411*10d63b7dSRichard Lowe result->buffer.start += 2;
1412*10d63b7dSRichard Lowe }
1413*10d63b7dSRichard Lowe }
1414*10d63b7dSRichard Lowe
1415*10d63b7dSRichard Lowe /*
1416*10d63b7dSRichard Lowe * dependency_exists(target, line)
1417*10d63b7dSRichard Lowe *
1418*10d63b7dSRichard Lowe * Returns true if the target exists in the
1419*10d63b7dSRichard Lowe * dependency list of the line.
1420*10d63b7dSRichard Lowe *
1421*10d63b7dSRichard Lowe * Return value:
1422*10d63b7dSRichard Lowe * True if target is on dependency list
1423*10d63b7dSRichard Lowe *
1424*10d63b7dSRichard Lowe * Parameters:
1425*10d63b7dSRichard Lowe * target Target we scan for
1426*10d63b7dSRichard Lowe * line We get the dependency list from here
1427*10d63b7dSRichard Lowe *
1428*10d63b7dSRichard Lowe * Global variables used:
1429*10d63b7dSRichard Lowe */
1430*10d63b7dSRichard Lowe static Boolean
dependency_exists(Name target,Property line)1431*10d63b7dSRichard Lowe dependency_exists(Name target, Property line)
1432*10d63b7dSRichard Lowe {
1433*10d63b7dSRichard Lowe Dependency dp;
1434*10d63b7dSRichard Lowe
1435*10d63b7dSRichard Lowe if (line == NULL) {
1436*10d63b7dSRichard Lowe return false;
1437*10d63b7dSRichard Lowe }
1438*10d63b7dSRichard Lowe for (dp = line->body.line.dependencies; dp != NULL; dp = dp->next) {
1439*10d63b7dSRichard Lowe if (dp->name == target) {
1440*10d63b7dSRichard Lowe return true;
1441*10d63b7dSRichard Lowe }
1442*10d63b7dSRichard Lowe }
1443*10d63b7dSRichard Lowe return false;
1444*10d63b7dSRichard Lowe }
1445*10d63b7dSRichard Lowe
1446*10d63b7dSRichard Lowe void
add_target_to_chain(Name target,Chain * query)1447*10d63b7dSRichard Lowe add_target_to_chain(Name target, Chain * query)
1448*10d63b7dSRichard Lowe {
1449*10d63b7dSRichard Lowe if (target->is_member && (get_prop(target->prop, member_prop) != NULL)) {
1450*10d63b7dSRichard Lowe target = get_prop(target->prop, member_prop)->body.member.member;
1451*10d63b7dSRichard Lowe }
1452*10d63b7dSRichard Lowe Chain *query_tail;
1453*10d63b7dSRichard Lowe for (query_tail = query; *query_tail != NULL; query_tail = &(*query_tail)->next) {
1454*10d63b7dSRichard Lowe if ((*query_tail)->name == target) {
1455*10d63b7dSRichard Lowe return;
1456*10d63b7dSRichard Lowe }
1457*10d63b7dSRichard Lowe }
1458*10d63b7dSRichard Lowe *query_tail = ALLOC(Chain);
1459*10d63b7dSRichard Lowe (*query_tail)->name = target;
1460*10d63b7dSRichard Lowe (*query_tail)->next = NULL;
1461*10d63b7dSRichard Lowe }
1462*10d63b7dSRichard Lowe
1463