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