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