Print this page
make: unifdef for NSE (undefined)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/bin/read2.cc
+++ new/usr/src/cmd/make/bin/read2.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 2005 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * read.c
28 28 *
29 29 * This file contains the makefile reader.
30 30 */
31 31
32 32 /*
33 33 * Included files
34 34 */
35 35 #include <mk/defs.h>
36 36 #include <mksh/dosys.h> /* sh_command2string() */
37 37 #include <mksh/macro.h> /* expand_value() */
38 38 #include <mksh/misc.h> /* retmem() */
39 39 #include <stdarg.h> /* va_list, va_start(), va_end() */
40 40
41 41 /*
42 42 * Defined macros
43 43 */
44 44
45 45 /*
46 46 * typedefs & structs
47 47 */
48 48
49 49 /*
50 50 * Static variables
51 51 */
52 52 static Boolean built_last_make_run_seen;
53 53
54 54 /*
55 55 * File table of contents
56 56 */
57 57 static Name_vector enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names);
58 58 extern Name normalize_name(register wchar_t *name_string, register int length);
59 59 static void read_suffixes_list(register Name_vector depes);
60 60 static void make_relative(wchar_t *to, wchar_t *result);
61 61 static void print_rule(register Cmd_line command);
62 62 static void sh_transform(Name *name, Name *value);
63 63
64 64
65 65 /*
66 66 * enter_name(string, tail_present, string_start, string_end,
67 67 * current_names, extra_names, target_group_seen)
68 68 *
69 69 * Take one string and enter it as a name. The string is passed in
70 70 * two parts. A make string and possibly a C string to append to it.
71 71 * The result is stuffed in the vector current_names.
72 72 * extra_names points to a vector that is used if current_names overflows.
73 73 * This is allocad in the calling routine.
74 74 * Here we handle the "lib.a[members]" notation.
75 75 *
76 76 * Return value:
77 77 * The name vector that was used
78 78 *
79 79 * Parameters:
80 80 * tail_present Indicates if both C and make string was passed
81 81 * string_start C string
82 82 * string_end Pointer to char after last in C string
83 83 * string make style string with head of name
84 84 * current_names Vector to deposit the name in
85 85 * extra_names Where to get next name vector if we run out
86 86 * target_group_seen Pointer to boolean that is set if "+" is seen
87 87 *
88 88 * Global variables used:
89 89 * makefile_type When we read a report file we normalize paths
90 90 * plus Points to the Name "+"
91 91 */
92 92
93 93 Name_vector
94 94 enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen)
95 95 {
96 96 Name name;
97 97 register wchar_t *cp;
98 98 wchar_t ch;
99 99
100 100 /* If we were passed a separate tail of the name we append it to the */
101 101 /* make string with the rest of it */
102 102 if (tail_present) {
103 103 append_string(string_start, string, string_end - string_start);
104 104 string_start = string->buffer.start;
105 105 string_end = string->text.p;
106 106 }
107 107 ch = *string_end;
108 108 *string_end = (int) nul_char;
109 109 /*
110 110 * Check if there are any ( or [ that are not prefixed with $.
111 111 * If there are, we have to deal with the lib.a(members) format.
112 112 */
113 113 for (cp = (wchar_t *) wschr(string_start, (int) parenleft_char);
114 114 cp != NULL;
115 115 cp = (wchar_t *) wschr(cp + 1, (int) parenleft_char)) {
116 116 if (*(cp - 1) != (int) dollar_char) {
117 117 *string_end = ch;
118 118 return enter_member_name(string_start,
119 119 cp,
120 120 string_end,
121 121 current_names,
122 122 extra_names);
123 123 }
124 124 }
125 125 *string_end = ch;
126 126
127 127 if (makefile_type == reading_cpp_file) {
128 128 /* Remove extra ../ constructs if we are reading from a report file */
129 129 name = normalize_name(string_start, string_end - string_start);
130 130 } else {
131 131 /*
132 132 * /tolik, fix bug 1197477/
133 133 * Normalize every target name before entering.
134 134 * ..//obj/a.o and ../obj//a.o are not two different targets.
135 135 * There is only one target ../obj/a.o
136 136 */
137 137 /*name = GETNAME(string_start, string_end - string_start);*/
138 138 name = normalize_name(string_start, string_end - string_start);
139 139 }
140 140
141 141 /* Internalize the name. Detect the name "+" (target group here) */
142 142 if(current_names->used != 0 && current_names->names[current_names->used-1] == plus) {
143 143 if(name == plus) {
144 144 return current_names;
145 145 }
146 146 }
147 147 /* If the current_names vector is full we patch in the one from */
148 148 /* extra_names */
149 149 if (current_names->used == VSIZEOF(current_names->names)) {
150 150 if (current_names->next != NULL) {
151 151 current_names = current_names->next;
152 152 } else {
153 153 current_names->next = *extra_names;
154 154 *extra_names = NULL;
155 155 current_names = current_names->next;
156 156 current_names->used = 0;
157 157 current_names->next = NULL;
158 158 }
159 159 }
160 160 current_names->target_group[current_names->used] = NULL;
161 161 current_names->names[current_names->used++] = name;
162 162 if (name == plus) {
163 163 *target_group_seen = true;
164 164 }
165 165 if (tail_present && string->free_after_use) {
166 166 retmem(string->buffer.start);
167 167 }
168 168 return current_names;
169 169 }
170 170
171 171 /*
172 172 * enter_member_name(lib_start, member_start, string_end,
173 173 * current_names, extra_names)
174 174 *
175 175 * A string has been found to contain member names.
176 176 * (The "lib.a[members]" and "lib.a(members)" notation)
177 177 * Handle it pretty much as enter_name() does for simple names.
178 178 *
179 179 * Return value:
180 180 * The name vector that was used
181 181 *
182 182 * Parameters:
183 183 * lib_start Points to the of start of "lib.a(member.o)"
184 184 * member_start Points to "member.o" from above string.
185 185 * string_end Points to char after last of above string.
186 186 * current_names Vector to deposit the name in
187 187 * extra_names Where to get next name vector if we run out
188 188 *
189 189 * Global variables used:
190 190 */
191 191 static Name_vector
192 192 enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names)
193 193 {
194 194 register Boolean entry = false;
195 195 wchar_t buffer[STRING_BUFFER_LENGTH];
196 196 Name lib;
197 197 Name member;
198 198 Name name;
199 199 Property prop;
200 200 wchar_t *memberp;
201 201 wchar_t *q;
202 202 register int paren_count;
203 203 register Boolean has_dollar;
204 204 register wchar_t *cq;
205 205 Name long_member_name = NULL;
206 206
207 207 /* Internalize the name of the library */
208 208 lib = GETNAME(lib_start, member_start - lib_start);
209 209 lib->is_member = true;
210 210 member_start++;
211 211 if (*member_start == (int) parenleft_char) {
212 212 /* This is really the "lib.a((entries))" format */
213 213 entry = true;
214 214 member_start++;
215 215 }
216 216 /* Move the library name to the buffer where we intend to build the */
217 217 /* "lib.a(member)" for each member */
218 218 (void) wsncpy(buffer, lib_start, member_start - lib_start);
219 219 memberp = buffer + (member_start-lib_start);
220 220 while (1) {
221 221 long_member_name = NULL;
222 222 /* Skip leading spaces */
223 223 for (;
224 224 (member_start < string_end) && iswspace(*member_start);
225 225 member_start++);
226 226 /* Find the end of the member name. Allow nested (). Detect $*/
227 227 for (cq = memberp, has_dollar = false, paren_count = 0;
228 228 (member_start < string_end) &&
229 229 ((*member_start != (int) parenright_char) ||
230 230 (paren_count > 0)) &&
231 231 !iswspace(*member_start);
232 232 *cq++ = *member_start++) {
233 233 switch (*member_start) {
234 234 case parenleft_char:
235 235 paren_count++;
236 236 break;
237 237 case parenright_char:
238 238 paren_count--;
239 239 break;
240 240 case dollar_char:
241 241 has_dollar = true;
242 242 }
243 243 }
244 244 /* Internalize the member name */
245 245 member = GETNAME(memberp, cq - memberp);
246 246 *cq = 0;
247 247 if ((q = (wchar_t *) wsrchr(memberp, (int) slash_char)) == NULL) {
248 248 q = memberp;
249 249 }
250 250 if ((cq - q > (int) ar_member_name_len) &&
251 251 !has_dollar) {
252 252 *cq++ = (int) parenright_char;
253 253 if (entry) {
254 254 *cq++ = (int) parenright_char;
255 255 }
256 256 long_member_name = GETNAME(buffer, cq - buffer);
257 257 cq = q + (int) ar_member_name_len;
258 258 }
259 259 *cq++ = (int) parenright_char;
260 260 if (entry) {
261 261 *cq++ = (int) parenright_char;
262 262 }
263 263 /* Internalize the "lib.a(member)" notation for this member */
264 264 name = GETNAME(buffer, cq - buffer);
265 265 name->is_member = lib->is_member;
266 266 if (long_member_name != NULL) {
267 267 prop = append_prop(name, long_member_name_prop);
268 268 name->has_long_member_name = true;
269 269 prop->body.long_member_name.member_name =
270 270 long_member_name;
271 271 }
272 272 /* And add the member prop */
273 273 prop = append_prop(name, member_prop);
274 274 prop->body.member.library = lib;
275 275 if (entry) {
276 276 /* "lib.a((entry))" notation */
277 277 prop->body.member.entry = member;
278 278 prop->body.member.member = NULL;
279 279 } else {
280 280 /* "lib.a(member)" Notation */
281 281 prop->body.member.entry = NULL;
282 282 prop->body.member.member = member;
283 283 }
284 284 /* Handle overflow of current_names */
285 285 if (current_names->used == VSIZEOF(current_names->names)) {
286 286 if (current_names->next != NULL) {
287 287 current_names = current_names->next;
288 288 } else {
289 289 if (*extra_names == NULL) {
290 290 current_names =
291 291 current_names->next =
292 292 ALLOC(Name_vector);
293 293 } else {
294 294 current_names =
295 295 current_names->next =
296 296 *extra_names;
297 297 *extra_names = NULL;
298 298 }
299 299 current_names->used = 0;
300 300 current_names->next = NULL;
301 301 }
302 302 }
303 303 current_names->target_group[current_names->used] = NULL;
304 304 current_names->names[current_names->used++] = name;
305 305 while (iswspace(*member_start)) {
306 306 member_start++;
307 307 }
308 308 /* Check if there are more members */
309 309 if ((*member_start == (int) parenright_char) ||
310 310 (member_start >= string_end)) {
311 311 return current_names;
312 312 }
313 313 }
314 314 /* NOTREACHED */
315 315 }
316 316
317 317 /*
318 318 * normalize_name(name_string, length)
319 319 *
320 320 * Take a namestring and remove redundant ../, // and ./ constructs
321 321 *
322 322 * Return value:
323 323 * The normalized name
324 324 *
325 325 * Parameters:
326 326 * name_string Path string to normalize
327 327 * length Length of that string
328 328 *
329 329 * Global variables used:
330 330 * dot The Name ".", compared against
331 331 * dotdot The Name "..", compared against
332 332 */
333 333 Name
334 334 normalize_name(register wchar_t *name_string, register int length)
335 335 {
336 336 static Name dotdot;
337 337 register wchar_t *string = ALLOC_WC(length + 1);
338 338 register wchar_t *string2;
339 339 register wchar_t *cdp;
340 340 wchar_t *current_component;
341 341 Name name;
342 342 register int count;
343 343
344 344 if (dotdot == NULL) {
345 345 MBSTOWCS(wcs_buffer, "..");
346 346 dotdot = GETNAME(wcs_buffer, FIND_LENGTH);
347 347 }
348 348
349 349 /*
350 350 * Copy string removing ./ and //.
351 351 * First strip leading ./
352 352 */
353 353 while ((length > 1) &&
354 354 (name_string[0] == (int) period_char) &&
355 355 (name_string[1] == (int) slash_char)) {
356 356 name_string += 2;
357 357 length -= 2;
358 358 while ((length > 0) && (name_string[0] == (int) slash_char)) {
359 359 name_string++;
360 360 length--;
361 361 }
362 362 }
363 363 /* Then copy the rest of the string removing /./ & // */
364 364 cdp = string;
365 365 while (length > 0) {
366 366 if (((length > 2) &&
367 367 (name_string[0] == (int) slash_char) &&
368 368 (name_string[1] == (int) period_char) &&
369 369 (name_string[2] == (int) slash_char)) ||
370 370 ((length == 2) &&
371 371 (name_string[0] == (int) slash_char) &&
372 372 (name_string[1] == (int) period_char))) {
373 373 name_string += 2;
374 374 length -= 2;
375 375 continue;
376 376 }
377 377 if ((length > 1) &&
378 378 (name_string[0] == (int) slash_char) &&
379 379 (name_string[1] == (int) slash_char)) {
380 380 name_string++;
381 381 length--;
382 382 continue;
383 383 }
384 384 *cdp++ = *name_string++;
385 385 length--;
386 386 }
387 387 *cdp = (int) nul_char;
388 388 /*
389 389 * Now scan for <name>/../ and remove such combinations iff <name>
390 390 * is not another ..
391 391 * Each time something is removed, the whole process is restarted.
392 392 */
393 393 removed_one:
394 394 name_string = string;
395 395 string2 = name_string; /*save for free*/
396 396 current_component =
397 397 cdp =
398 398 string =
399 399 ALLOC_WC((length = wslen(name_string)) + 1);
400 400 while (length > 0) {
401 401 if (((length > 3) &&
402 402 (name_string[0] == (int) slash_char) &&
403 403 (name_string[1] == (int) period_char) &&
404 404 (name_string[2] == (int) period_char) &&
405 405 (name_string[3] == (int) slash_char)) ||
406 406 ((length == 3) &&
407 407 (name_string[0] == (int) slash_char) &&
408 408 (name_string[1] == (int) period_char) &&
409 409 (name_string[2] == (int) period_char))) {
410 410 /* Positioned on the / that starts a /.. sequence */
411 411 if (((count = cdp - current_component) != 0) &&
412 412 (exists(name = GETNAME(string, cdp - string)) > file_doesnt_exist) &&
413 413 (!name->stat.is_sym_link)) {
414 414 name = GETNAME(current_component, count);
415 415 if(name != dotdot) {
416 416 cdp = current_component;
417 417 name_string += 3;
418 418 length -= 3;
419 419 if (length > 0) {
420 420 name_string++; /* skip slash */
421 421 length--;
422 422 while (length > 0) {
423 423 *cdp++ = *name_string++;
424 424 length--;
425 425 }
426 426 }
427 427 *cdp = (int) nul_char;
428 428 retmem(string2);
429 429 goto removed_one;
430 430 }
431 431 }
432 432 }
433 433 if ((*cdp++ = *name_string++) == (int) slash_char) {
434 434 current_component = cdp;
435 435 }
436 436 length--;
437 437 }
438 438 *cdp = (int) nul_char;
439 439 if (string[0] == (int) nul_char) {
440 440 name = dot;
441 441 } else {
442 442 name = GETNAME(string, FIND_LENGTH);
443 443 }
444 444 retmem(string);
445 445 retmem(string2);
446 446 return name;
447 447 }
448 448
449 449 /*
450 450 * find_target_groups(target_list)
451 451 *
452 452 * If a "+" was seen when the target list was scanned we need to extract
453 453 * the groups. Each target in the name vector that is a member of a
454 454 * group gets a pointer to a chain of all the members stuffed in its
455 455 * target_group vector slot
456 456 *
457 457 * Parameters:
458 458 * target_list The list of targets that contains "+"
459 459 *
460 460 * Global variables used:
461 461 * plus The Name "+", compared against
462 462 */
463 463 Chain
464 464 find_target_groups(register Name_vector target_list, register int i, Boolean reset)
465 465 {
466 466 static Chain target_group = NULL;
467 467 static Chain tail_target_group = NULL;
468 468 static Name *next;
469 469 static Boolean clear_target_group = false;
470 470
471 471 if (reset) {
472 472 target_group = NULL;
473 473 tail_target_group = NULL;
474 474 clear_target_group = false;
475 475 }
476 476
477 477 /* Scan the list of targets */
478 478 /* If the previous target terminated a group */
479 479 /* we flush the pointer to that member chain */
480 480 if (clear_target_group) {
481 481 clear_target_group = false;
482 482 target_group = NULL;
483 483 }
484 484 /* Pick up a pointer to the cell with */
485 485 /* the next target */
486 486 if (i + 1 != target_list->used) {
487 487 next = &target_list->names[i + 1];
488 488 } else {
489 489 next = (target_list->next != NULL) ?
490 490 &target_list->next->names[0] : NULL;
491 491 }
492 492 /* We have four states here :
493 493 * 0: No target group started and next element is not "+"
494 494 * This is not interesting.
495 495 * 1: A target group is being built and the next element
496 496 * is not "+". This terminates the group.
497 497 * 2: No target group started and the next member is "+"
498 498 * This is the first target in a group.
499 499 * 3: A target group started and the next member is a "+"
500 500 * The group continues.
501 501 */
502 502 switch ((target_group ? 1 : 0) +
503 503 (next && (*next == plus) ?
504 504 2 : 0)) {
505 505 case 0: /* Not target_group */
506 506 break;
507 507 case 1: /* Last group member */
508 508 /* We need to keep this pointer so */
509 509 /* we can stuff it for last member */
510 510 clear_target_group = true;
511 511 /* fall into */
512 512 case 3: /* Middle group member */
513 513 /* Add this target to the */
514 514 /* current chain */
515 515 tail_target_group->next = ALLOC(Chain);
516 516 tail_target_group = tail_target_group->next;
517 517 tail_target_group->next = NULL;
518 518 tail_target_group->name = target_list->names[i];
519 519 break;
520 520 case 2: /* First group member */
521 521 /* Start a new chain */
522 522 target_group = tail_target_group = ALLOC(Chain);
523 523 target_group->next = NULL;
524 524 target_group->name = target_list->names[i];
525 525 break;
526 526 }
527 527 /* Stuff the current chain, if any, in the */
528 528 /* targets group slot */
529 529 target_list->target_group[i] = target_group;
530 530 if ((next != NULL) &&
531 531 (*next == plus)) {
532 532 *next = NULL;
533 533 }
534 534 return (tail_target_group);
535 535 }
536 536
537 537 /*
538 538 * enter_dependencies(target, target_group, depes, command, separator)
539 539 *
540 540 * Take one target and a list of dependencies and process the whole thing.
541 541 * The target might be special in some sense in which case that is handled
542 542 *
543 543 * Parameters:
544 544 * target The target we want to enter
545 545 * target_group Non-NULL if target is part of a group this time
546 546 * depes A list of dependencies for the target
547 547 * command The command the target should be entered with
548 548 * separator Indicates if this is a ":" or a "::" rule
549 549 *
550 550 * Static variables used:
551 551 * built_last_make_run_seen If the previous target was
552 552 * .BUILT_LAST_MAKE_RUN we say to rewrite
553 553 * the state file later on
554 554 *
555 555 * Global variables used:
556 556 * command_changed Set to indicate if .make.state needs rewriting
557 557 * default_target_to_build Set to the target if reading makefile
558 558 * and this is the first regular target
559 559 * force The Name " FORCE", used with "::" targets
560 560 * makefile_type We do different things for makefile vs. report
561 561 * not_auto The Name ".NOT_AUTO", compared against
562 562 * recursive_name The Name ".RECURSIVE", compared against
563 563 * temp_file_number Used to figure out when to clear stale
564 564 * automatic dependencies
565 565 * trace_reader Indicates that we should echo stuff we read
566 566 */
567 567 void
568 568 enter_dependencies(register Name target, Chain target_group, register Name_vector depes, register Cmd_line command, register Separator separator)
569 569 {
570 570 register int i;
571 571 register Property line;
572 572 Name name;
573 573 Name directory;
574 574 wchar_t *namep;
575 575 char *mb_namep;
576 576 Dependency dp;
577 577 Dependency *dpp;
578 578 Property line2;
↓ open down ↓ |
578 lines elided |
↑ open up ↑ |
579 579 wchar_t relative[MAXPATHLEN];
580 580 register int recursive_state;
581 581 Boolean register_as_auto;
582 582 Boolean not_auto_found;
583 583 char *slash;
584 584 Wstring depstr;
585 585
586 586 /* Check if this is a .RECURSIVE line */
587 587 if ((depes->used >= 3) &&
588 588 (depes->names[0] == recursive_name)) {
589 -#ifdef NSE
590 - nse_did_recursion= true;
591 -#endif
592 589 target->has_recursive_dependency = true;
593 590 depes->names[0] = NULL;
594 591 recursive_state = 0;
595 592 dp = NULL;
596 593 dpp = &dp;
597 594 /* Read the dependencies. They are "<directory> <target-made>*/
598 595 /* <makefile>*" */
599 596 for (; depes != NULL; depes = depes->next) {
600 597 for (i = 0; i < depes->used; i++) {
601 598 if (depes->names[i] != NULL) {
602 599 switch (recursive_state++) {
603 600 case 0: /* Directory */
604 601 {
605 602 depstr.init(depes->names[i]);
606 603 make_relative(depstr.get_string(),
607 604 relative);
608 605 directory =
609 606 GETNAME(relative,
610 607 FIND_LENGTH);
611 608 }
612 609 break;
613 610 case 1: /* Target */
614 611 name = depes->names[i];
615 612 break;
616 613 default: /* Makefiles */
617 614 *dpp = ALLOC(Dependency);
618 615 (*dpp)->next = NULL;
619 616 (*dpp)->name = depes->names[i];
620 617 (*dpp)->automatic = false;
621 618 (*dpp)->stale = false;
622 619 (*dpp)->built = false;
623 620 dpp = &((*dpp)->next);
624 621 break;
625 622 }
626 623 }
627 624 }
628 625 }
629 626 /* Check if this recursion already has been reported else */
630 627 /* enter the recursive prop for the target */
631 628 /* The has_built flag is used to tell if this .RECURSIVE */
632 629 /* was discovered from this run (read from a tmp file) */
633 630 /* or was from discovered from the original .make.state */
634 631 /* file */
635 632 for (line = get_prop(target->prop, recursive_prop);
636 633 line != NULL;
637 634 line = get_prop(line->next, recursive_prop)) {
638 635 if ((line->body.recursive.directory == directory) &&
639 636 (line->body.recursive.target == name)) {
640 637 line->body.recursive.makefiles = dp;
641 638 line->body.recursive.has_built =
642 639 (Boolean)
643 640 (makefile_type == reading_cpp_file);
644 641 return;
645 642 }
646 643 }
647 644 line2 = append_prop(target, recursive_prop);
648 645 line2->body.recursive.directory = directory;
649 646 line2->body.recursive.target = name;
650 647 line2->body.recursive.makefiles = dp;
651 648 line2->body.recursive.has_built =
652 649 (Boolean) (makefile_type == reading_cpp_file);
653 650 line2->body.recursive.in_depinfo = false;
654 651 return;
655 652 }
656 653 /* If this is the first target that doesnt start with a "." in the */
657 654 /* makefile we remember that */
658 655 Wstring tstr(target);
659 656 wchar_t * wcb = tstr.get_string();
660 657 if ((makefile_type == reading_makefile) &&
661 658 (default_target_to_build == NULL) &&
662 659 ((wcb[0] != (int) period_char) ||
663 660 wschr(wcb, (int) slash_char))) {
664 661
665 662 /* BID 1181577: $(EMPTY_MACRO) + $(EMPTY_MACRO):
666 663 ** The target with empty name cannot be default_target_to_build
667 664 */
668 665 if (target->hash.length != 0)
669 666 default_target_to_build = target;
670 667 }
671 668 /* Check if the line is ":" or "::" */
672 669 if (makefile_type == reading_makefile) {
673 670 if (target->colons == no_colon) {
674 671 target->colons = separator;
675 672 } else {
676 673 if (target->colons != separator) {
677 674 fatal_reader(catgets(catd, 1, 92, ":/:: conflict for target `%s'"),
678 675 target->string_mb);
679 676 }
680 677 }
681 678 if (target->colons == two_colon) {
682 679 if (depes->used == 0) {
683 680 /* If this is a "::" type line with no */
684 681 /* dependencies we add one "FRC" type */
685 682 /* dependency for free */
686 683 depes->used = 1; /* Force :: targets with no
687 684 * depes to always run */
688 685 depes->names[0] = force;
689 686 }
690 687 /* Do not delete "::" type targets when interrupted */
691 688 target->stat.is_precious = true;
692 689 /*
693 690 * Build a synthetic target "<number>%target"
694 691 * for "target".
695 692 */
696 693 mb_namep = getmem((int) (strlen(target->string_mb) + 10));
697 694 namep = ALLOC_WC((int) (target->hash.length + 10));
698 695 slash = strrchr(target->string_mb, (int) slash_char);
699 696 if (slash == NULL) {
700 697 (void) sprintf(mb_namep,
701 698 "%d@%s",
702 699 target->colon_splits++,
703 700 target->string_mb);
704 701 } else {
705 702 *slash = 0;
706 703 (void) sprintf(mb_namep,
707 704 "%s/%d@%s",
708 705 target->string_mb,
709 706 target->colon_splits++,
710 707 slash + 1);
711 708 *slash = (int) slash_char;
712 709 }
713 710 MBSTOWCS(namep, mb_namep);
714 711 retmem_mb(mb_namep);
715 712 name = GETNAME(namep, FIND_LENGTH);
716 713 retmem(namep);
717 714 if (trace_reader) {
718 715 (void) printf("%s:\t", target->string_mb);
719 716 }
720 717 /* Make "target" depend on "<number>%target */
721 718 line2 = maybe_append_prop(target, line_prop);
722 719 enter_dependency(line2, name, true);
723 720 line2->body.line.target = target;
724 721 /* Put a prop on "<number>%target that makes */
725 722 /* appear as "target" */
726 723 /* when it is processed */
727 724 maybe_append_prop(name, target_prop)->
728 725 body.target.target = target;
729 726 target->is_double_colon_parent = true;
730 727 name->is_double_colon = true;
731 728 name->has_target_prop = true;
732 729 if (trace_reader) {
733 730 (void) printf("\n");
734 731 }
735 732 (target = name)->stat.is_file = true;
736 733 }
737 734 }
738 735 /* This really is a regular dependency line. Just enter it */
739 736 line = maybe_append_prop(target, line_prop);
740 737 line->body.line.target = target;
741 738 /* Depending on what kind of makefile we are reading we have to */
742 739 /* treat things differently */
743 740 switch (makefile_type) {
744 741 case reading_makefile:
745 742 /* Reading regular makefile. Just notice whether this */
746 743 /* redefines the rule for the target */
747 744 if (command != NULL) {
748 745 if (line->body.line.command_template != NULL) {
749 746 line->body.line.command_template_redefined =
750 747 true;
751 748 if ((wcb[0] == (int) period_char) &&
752 749 !wschr(wcb, (int) slash_char)) {
753 750 line->body.line.command_template =
754 751 command;
755 752 }
756 753 } else {
757 754 line->body.line.command_template = command;
758 755 }
759 756 } else {
760 757 if ((wcb[0] == (int) period_char) &&
761 758 !wschr(wcb, (int) slash_char)) {
762 759 line->body.line.command_template = command;
763 760 }
764 761 }
765 762 break;
766 763 case rereading_statefile:
767 764 /* Rereading the statefile. We only enter thing that changed */
768 765 /* since the previous time we read it */
769 766 if (!built_last_make_run_seen) {
770 767 for (Cmd_line next, cmd = command; cmd != NULL; cmd = next) {
771 768 next = cmd->next;
772 769 free(cmd);
773 770 }
774 771 return;
775 772 }
776 773 built_last_make_run_seen = false;
777 774 command_changed = true;
778 775 target->ran_command = true;
779 776 case reading_statefile:
780 777 /* Reading the statefile for the first time. Enter the rules */
781 778 /* as "Commands used" not "templates to use" */
782 779 if (command != NULL) {
783 780 for (Cmd_line next, cmd = line->body.line.command_used;
784 781 cmd != NULL; cmd = next) {
785 782 next = cmd->next;
786 783 free(cmd);
787 784 }
788 785 line->body.line.command_used = command;
789 786 }
790 787 case reading_cpp_file:
791 788 /* Reading report file from programs that reports */
792 789 /* dependencies. If this is the first time the target is */
793 790 /* read from this reportfile we clear all old */
794 791 /* automatic depes */
795 792 if (target->temp_file_number == temp_file_number) {
796 793 break;
797 794 }
798 795 target->temp_file_number = temp_file_number;
799 796 command_changed = true;
800 797 if (line != NULL) {
801 798 for (dp = line->body.line.dependencies;
802 799 dp != NULL;
803 800 dp = dp->next) {
804 801 if (dp->automatic) {
805 802 dp->stale = true;
806 803 }
807 804 }
808 805 }
809 806 break;
810 807 default:
811 808 fatal_reader(catgets(catd, 1, 93, "Internal error. Unknown makefile type %d"),
812 809 makefile_type);
813 810 }
814 811 /* A target may only be involved in one target group */
815 812 if (line->body.line.target_group != NULL) {
816 813 if (target_group != NULL) {
817 814 fatal_reader(catgets(catd, 1, 94, "Too many target groups for target `%s'"),
818 815 target->string_mb);
819 816 }
820 817 } else {
821 818 line->body.line.target_group = target_group;
822 819 }
823 820
824 821 if (trace_reader) {
825 822 (void) printf("%s:\t", target->string_mb);
826 823 }
827 824 /* Enter the dependencies */
828 825 register_as_auto = BOOLEAN(makefile_type != reading_makefile);
829 826 not_auto_found = false;
830 827 for (;
831 828 (depes != NULL) && !not_auto_found;
832 829 depes = depes->next) {
833 830 for (i = 0; i < depes->used; i++) {
834 831 /* the dependency .NOT_AUTO signals beginning of
835 832 * explicit dependancies which were put at end of
836 833 * list in .make.state file - we stop entering
837 834 * dependencies at this point
838 835 */
839 836 if (depes->names[i] == not_auto) {
840 837 not_auto_found = true;
841 838 break;
842 839 }
843 840 enter_dependency(line,
844 841 depes->names[i],
845 842 register_as_auto);
846 843 }
847 844 }
848 845 if (trace_reader) {
849 846 (void) printf("\n");
850 847 print_rule(command);
851 848 }
852 849 }
853 850
854 851 /*
855 852 * enter_dependency(line, depe, automatic)
856 853 *
857 854 * Enter one dependency. Do not enter duplicates.
858 855 *
859 856 * Parameters:
860 857 * line The line block that the dependeny is
861 858 * entered for
862 859 * depe The dependency to enter
863 860 * automatic Used to set the field "automatic"
864 861 *
865 862 * Global variables used:
866 863 * makefile_type We do different things for makefile vs. report
867 864 * trace_reader Indicates that we should echo stuff we read
868 865 * wait_name The Name ".WAIT", compared against
869 866 */
870 867 void
871 868 enter_dependency(Property line, register Name depe, Boolean automatic)
872 869 {
873 870 register Dependency dp;
874 871 register Dependency *insert;
875 872
876 873 if (trace_reader) {
877 874 (void) printf("%s ", depe->string_mb);
878 875 }
↓ open down ↓ |
277 lines elided |
↑ open up ↑ |
879 876 /* Find the end of the list and check for duplicates */
880 877 for (insert = &line->body.line.dependencies, dp = *insert;
881 878 dp != NULL;
882 879 insert = &dp->next, dp = *insert) {
883 880 if ((dp->name == depe) && (depe != wait_name)) {
884 881 if (dp->automatic) {
885 882 dp->automatic = automatic;
886 883 if (automatic) {
887 884 dp->built = false;
888 885 depe->stat.is_file = true;
889 -#ifdef NSE
890 - depe->has_parent= true;
891 - depe->is_target= true;
892 -#endif
893 886 }
894 887 }
895 888 dp->stale = false;
896 889 return;
897 890 }
898 891 }
899 892 /* Insert the new dependency since we couldnt find it */
900 893 dp = *insert = ALLOC(Dependency);
901 894 dp->name = depe;
902 895 dp->next = NULL;
903 896 dp->automatic = automatic;
904 897 dp->stale = false;
905 898 dp->built = false;
906 899 depe->stat.is_file = true;
907 -#ifdef NSE
908 - depe->has_parent= true;
909 - depe->is_target= true;
910 -#endif
911 900
912 901 if ((makefile_type == reading_makefile) &&
913 902 (line != NULL) &&
914 903 (line->body.line.target != NULL)) {
915 904 line->body.line.target->has_regular_dependency = true;
916 -#ifdef NSE
917 - line->body.line.target->is_target= true;
918 -#endif
919 905 }
920 906 }
921 907
922 908 /*
923 909 * enter_percent(target, depes, command)
924 910 *
925 911 * Enter "x%y : a%b" type lines
926 912 * % patterns are stored in four parts head and tail for target and source
927 913 *
928 914 * Parameters:
929 915 * target Left hand side of pattern
930 916 * depes The dependency list with the rh pattern
931 917 * command The command for the pattern
932 918 *
933 919 * Global variables used:
934 920 * empty_name The Name "", compared against
935 921 * percent_list The list of all percent rules, added to
936 922 * trace_reader Indicates that we should echo stuff we read
937 923 */
938 924 Percent
939 925 enter_percent(register Name target, Chain target_group, register Name_vector depes, Cmd_line command)
940 926 {
941 927 register Percent result = ALLOC(Percent);
942 928 register Percent depe;
943 929 register Percent *depe_tail = &result->dependencies;
944 930 register Percent *insert;
945 931 register wchar_t *cp, *cp1;
946 932 Name_vector nvp;
947 933 int i;
948 934 int pattern;
949 935
950 936 result->next = NULL;
951 937 result->patterns = NULL;
952 938 result->patterns_total = 0;
953 939 result->command_template = command;
954 940 result->being_expanded = false;
955 941 result->name = target;
956 942 result->dependencies = NULL;
957 943 result->target_group = target_group;
958 944
959 945 /* get patterns count */
960 946 Wstring wcb(target);
961 947 cp = wcb.get_string();
962 948 while (true) {
963 949 cp = (wchar_t *) wschr(cp, (int) percent_char);
964 950 if (cp != NULL) {
965 951 result->patterns_total++;
966 952 cp++;
967 953 } else {
968 954 break;
969 955 }
970 956 }
971 957 result->patterns_total++;
972 958
973 959 /* allocate storage for patterns */
974 960 result->patterns = (Name *) getmem(sizeof(Name) * result->patterns_total);
975 961
976 962 /* then create patterns */
977 963 cp = wcb.get_string();
978 964 pattern = 0;
979 965 while (true) {
980 966 cp1 = (wchar_t *) wschr(cp, (int) percent_char);
981 967 if (cp1 != NULL) {
982 968 result->patterns[pattern] = GETNAME(cp, cp1 - cp);
983 969 cp = cp1 + 1;
984 970 pattern++;
985 971 } else {
986 972 result->patterns[pattern] = GETNAME(cp, (int) target->hash.length - (cp - wcb.get_string()));
987 973 break;
988 974 }
989 975 }
990 976
991 977 Wstring wcb1;
992 978
993 979 /* build dependencies list */
994 980 for (nvp = depes; nvp != NULL; nvp = nvp->next) {
995 981 for (i = 0; i < nvp->used; i++) {
996 982 depe = ALLOC(Percent);
997 983 depe->next = NULL;
998 984 depe->patterns = NULL;
999 985 depe->patterns_total = 0;
1000 986 depe->name = nvp->names[i];
1001 987 depe->dependencies = NULL;
1002 988 depe->command_template = NULL;
1003 989 depe->being_expanded = false;
1004 990 depe->target_group = NULL;
1005 991
1006 992 *depe_tail = depe;
1007 993 depe_tail = &depe->next;
1008 994
1009 995 if (depe->name->percent) {
1010 996 /* get patterns count */
1011 997 wcb1.init(depe->name);
1012 998 cp = wcb1.get_string();
1013 999 while (true) {
1014 1000 cp = (wchar_t *) wschr(cp, (int) percent_char);
1015 1001 if (cp != NULL) {
1016 1002 depe->patterns_total++;
1017 1003 cp++;
1018 1004 } else {
1019 1005 break;
1020 1006 }
1021 1007 }
1022 1008 depe->patterns_total++;
1023 1009
1024 1010 /* allocate storage for patterns */
1025 1011 depe->patterns = (Name *) getmem(sizeof(Name) * depe->patterns_total);
1026 1012
1027 1013 /* then create patterns */
1028 1014 cp = wcb1.get_string();
1029 1015 pattern = 0;
1030 1016 while (true) {
1031 1017 cp1 = (wchar_t *) wschr(cp, (int) percent_char);
1032 1018 if (cp1 != NULL) {
1033 1019 depe->patterns[pattern] = GETNAME(cp, cp1 - cp);
1034 1020 cp = cp1 + 1;
1035 1021 pattern++;
1036 1022 } else {
1037 1023 depe->patterns[pattern] = GETNAME(cp, (int) depe->name->hash.length - (cp - wcb1.get_string()));
1038 1024 break;
1039 1025 }
1040 1026 }
1041 1027 }
1042 1028 }
1043 1029 }
1044 1030
1045 1031 /* Find the end of the percent list and append the new pattern */
1046 1032 for (insert = &percent_list; (*insert) != NULL; insert = &(*insert)->next);
1047 1033 *insert = result;
1048 1034
1049 1035 if (trace_reader) {
1050 1036 (void) printf("%s:", result->name->string_mb);
1051 1037
1052 1038 for (depe = result->dependencies; depe != NULL; depe = depe->next) {
1053 1039 (void) printf(" %s", depe->name->string_mb);
1054 1040 }
1055 1041
1056 1042 (void) printf("\n");
1057 1043
1058 1044 print_rule(command);
1059 1045 }
1060 1046
1061 1047 return result;
1062 1048 }
1063 1049
1064 1050 /*
1065 1051 * enter_dyntarget(target)
1066 1052 *
1067 1053 * Enter "$$(MACRO) : b" type lines
1068 1054 *
1069 1055 * Parameters:
1070 1056 * target Left hand side of pattern
1071 1057 *
1072 1058 * Global variables used:
1073 1059 * dyntarget_list The list of all percent rules, added to
1074 1060 * trace_reader Indicates that we should echo stuff we read
1075 1061 */
1076 1062 Dyntarget
1077 1063 enter_dyntarget(register Name target)
1078 1064 {
1079 1065 register Dyntarget result = ALLOC(Dyntarget);
1080 1066 Dyntarget p;
1081 1067 Dyntarget *insert;
1082 1068 int i;
1083 1069
1084 1070 result->next = NULL;
1085 1071 result->name = target;
1086 1072
1087 1073
1088 1074 /* Find the end of the dyntarget list and append the new pattern */
1089 1075 for (insert = &dyntarget_list, p = *insert;
1090 1076 p != NULL;
1091 1077 insert = &p->next, p = *insert);
1092 1078 *insert = result;
1093 1079
1094 1080 if (trace_reader) {
1095 1081 (void) printf(NOCATGETS("Dynamic target %s:\n"), result->name->string_mb);
1096 1082 }
1097 1083 return( result);
1098 1084 }
1099 1085
1100 1086
1101 1087 /*
1102 1088 * special_reader(target, depes, command)
1103 1089 *
1104 1090 * Read the pseudo targets make knows about
1105 1091 * This handles the special targets that should not be entered as regular
1106 1092 * target/dependency sets.
1107 1093 *
1108 1094 * Parameters:
1109 1095 * target The special target
1110 1096 * depes The list of dependencies it was entered with
1111 1097 * command The command it was entered with
1112 1098 *
1113 1099 * Static variables used:
1114 1100 * built_last_make_run_seen Set to indicate .BUILT_LAST... seen
1115 1101 *
1116 1102 * Global variables used:
1117 1103 * all_parallel Set to indicate that everything runs parallel
1118 1104 * svr4 Set when ".SVR4" target is read
1119 1105 * svr4_name The Name ".SVR4"
1120 1106 * posix Set when ".POSIX" target is read
1121 1107 * posix_name The Name ".POSIX"
1122 1108 * current_make_version The Name "<current version number>"
1123 1109 * default_rule Set when ".DEFAULT" target is read
1124 1110 * default_rule_name The Name ".DEFAULT", used for tracing
1125 1111 * dot_keep_state The Name ".KEEP_STATE", used for tracing
1126 1112 * ignore_errors Set if ".IGNORE" target is read
1127 1113 * ignore_name The Name ".IGNORE", used for tracing
1128 1114 * keep_state Set if ".KEEP_STATE" target is read
1129 1115 * no_parallel_name The Name ".NO_PARALLEL", used for tracing
1130 1116 * only_parallel Set to indicate only some targets runs parallel
1131 1117 * parallel_name The Name ".PARALLEL", used for tracing
1132 1118 * precious The Name ".PRECIOUS", used for tracing
1133 1119 * sccs_get_name The Name ".SCCS_GET", used for tracing
1134 1120 * sccs_get_posix_name The Name ".SCCS_GET_POSIX", used for tracing
1135 1121 * get_name The Name ".GET", used for tracing
1136 1122 * sccs_get_rule Set when ".SCCS_GET" target is read
1137 1123 * silent Set when ".SILENT" target is read
1138 1124 * silent_name The Name ".SILENT", used for tracing
1139 1125 * trace_reader Indicates that we should echo stuff we read
1140 1126 */
1141 1127 void
1142 1128 special_reader(Name target, register Name_vector depes, Cmd_line command)
1143 1129 {
1144 1130 register int n;
1145 1131
1146 1132 switch (target->special_reader) {
1147 1133
1148 1134 case svr4_special:
1149 1135 if (depes->used != 0) {
1150 1136 fatal_reader(catgets(catd, 1, 98, "Illegal dependencies for target `%s'"),
1151 1137 target->string_mb);
1152 1138 }
1153 1139 svr4 = true;
1154 1140 posix = false;
1155 1141 keep_state = false;
1156 1142 all_parallel = false;
1157 1143 only_parallel = false;
1158 1144 if (trace_reader) {
1159 1145 (void) printf("%s:\n", svr4_name->string_mb);
1160 1146 }
1161 1147 break;
1162 1148
1163 1149 case posix_special:
1164 1150 if(svr4)
1165 1151 break;
1166 1152 if (depes->used != 0) {
1167 1153 fatal_reader(catgets(catd, 1, 99, "Illegal dependencies for target `%s'"),
1168 1154 target->string_mb);
1169 1155 }
1170 1156 posix = true;
1171 1157 /* with posix on, use the posix get rule */
1172 1158 sccs_get_rule = sccs_get_posix_rule;
1173 1159 /* turn keep state off being SunPro make specific */
1174 1160 keep_state = false;
1175 1161 /* Use /usr/xpg4/bin/sh on Solaris */
1176 1162 MBSTOWCS(wcs_buffer, NOCATGETS("/usr/xpg4/bin/sh"));
1177 1163 (void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
1178 1164 if (trace_reader) {
1179 1165 (void) printf("%s:\n", posix_name->string_mb);
1180 1166 }
1181 1167 break;
1182 1168
1183 1169 case built_last_make_run_special:
1184 1170 built_last_make_run_seen = true;
1185 1171 break;
1186 1172
1187 1173 case default_special:
1188 1174 if (depes->used != 0) {
1189 1175 warning(catgets(catd, 1, 100, "Illegal dependency list for target `%s'"),
↓ open down ↓ |
261 lines elided |
↑ open up ↑ |
1190 1176 target->string_mb);
1191 1177 }
1192 1178 default_rule = command;
1193 1179 if (trace_reader) {
1194 1180 (void) printf("%s:\n",
1195 1181 default_rule_name->string_mb);
1196 1182 print_rule(command);
1197 1183 }
1198 1184 break;
1199 1185
1200 -#ifdef NSE
1201 - case derived_src_special:
1202 - for (; depes != NULL; depes= depes->next)
1203 - for (n= 0; n < depes->used; n++) {
1204 - if (trace_reader)
1205 - (void)printf("%s:\t%s\n",
1206 - precious->string_mb,
1207 - depes->names[n]->string_mb);
1208 - depes->names[n]->stat.is_derived_src= true;
1209 - };
1210 - break;
1211 -#endif
1212 1186
1213 1187 case ignore_special:
1214 1188 if ((depes->used != 0) &&(!posix)){
1215 1189 fatal_reader(catgets(catd, 1, 101, "Illegal dependencies for target `%s'"),
1216 1190 target->string_mb);
1217 1191 }
1218 1192 if (depes->used == 0)
1219 1193 {
1220 1194 ignore_errors_all = true;
1221 1195 }
1222 1196 if(svr4) {
1223 1197 ignore_errors_all = true;
1224 1198 break;
1225 1199 }
1226 1200 for (; depes != NULL; depes = depes->next) {
1227 1201 for (n = 0; n < depes->used; n++) {
1228 1202 depes->names[n]->ignore_error_mode = true;
1229 1203 }
1230 1204 }
1231 1205 if (trace_reader) {
1232 1206 (void) printf("%s:\n", ignore_name->string_mb);
1233 1207 }
1234 1208 break;
1235 1209
1236 1210 case keep_state_special:
1237 1211 if(svr4)
1238 1212 break;
1239 1213 /* ignore keep state, being SunPro make specific */
1240 1214 if(posix)
1241 1215 break;
1242 1216 if (depes->used != 0) {
1243 1217 fatal_reader(catgets(catd, 1, 102, "Illegal dependencies for target `%s'"),
1244 1218 target->string_mb);
1245 1219 }
1246 1220 keep_state = true;
1247 1221 if (trace_reader) {
1248 1222 (void) printf("%s:\n",
1249 1223 dot_keep_state->string_mb);
1250 1224 }
1251 1225 break;
1252 1226
1253 1227 case keep_state_file_special:
1254 1228 if(svr4)
1255 1229 break;
1256 1230 if(posix)
1257 1231 break;
1258 1232 /* it's not necessary to specify KEEP_STATE, if this
1259 1233 ** is given, so set the keep_state.
1260 1234 */
1261 1235 keep_state = true;
1262 1236 if (depes->used != 0) {
1263 1237 if((!make_state) ||(!strcmp(make_state->string_mb,NOCATGETS(".make.state")))) {
1264 1238 make_state = depes->names[0];
1265 1239 }
1266 1240 }
1267 1241 break;
1268 1242 case make_version_special:
1269 1243 if(svr4)
1270 1244 break;
1271 1245 if (depes->used != 1) {
1272 1246 fatal_reader(catgets(catd, 1, 103, "Illegal dependency list for target `%s'"),
1273 1247 target->string_mb);
1274 1248 }
1275 1249 if (depes->names[0] != current_make_version) {
1276 1250 /*
1277 1251 * Special case the fact that version 1.0 and 1.1
1278 1252 * are identical.
1279 1253 */
1280 1254 if (!IS_EQUAL(depes->names[0]->string_mb,
1281 1255 NOCATGETS("VERSION-1.1")) ||
1282 1256 !IS_EQUAL(current_make_version->string_mb,
1283 1257 NOCATGETS("VERSION-1.0"))) {
1284 1258 /*
1285 1259 * Version mismatches should cause the
1286 1260 * .make.state file to be skipped.
1287 1261 * This is currently not true - it is read
1288 1262 * anyway.
1289 1263 */
1290 1264 warning(catgets(catd, 1, 104, "Version mismatch between current version `%s' and `%s'"),
1291 1265 current_make_version->string_mb,
1292 1266 depes->names[0]->string_mb);
1293 1267 }
1294 1268 }
1295 1269 break;
1296 1270
1297 1271 case no_parallel_special:
1298 1272 if(svr4)
1299 1273 break;
1300 1274 /* Set the no_parallel bit for all the targets on */
1301 1275 /* the dependency list */
1302 1276 if (depes->used == 0) {
1303 1277 /* only those explicitly made parallel */
1304 1278 only_parallel = true;
1305 1279 all_parallel = false;
1306 1280 }
1307 1281 for (; depes != NULL; depes = depes->next) {
1308 1282 for (n = 0; n < depes->used; n++) {
1309 1283 if (trace_reader) {
1310 1284 (void) printf("%s:\t%s\n",
1311 1285 no_parallel_name->string_mb,
1312 1286 depes->names[n]->string_mb);
1313 1287 }
1314 1288 depes->names[n]->no_parallel = true;
1315 1289 depes->names[n]->parallel = false;
1316 1290 }
1317 1291 }
1318 1292 break;
1319 1293
1320 1294 case parallel_special:
1321 1295 if(svr4)
1322 1296 break;
1323 1297 if (depes->used == 0) {
1324 1298 /* everything runs in parallel */
1325 1299 all_parallel = true;
1326 1300 only_parallel = false;
1327 1301 }
1328 1302 /* Set the parallel bit for all the targets on */
1329 1303 /* the dependency list */
1330 1304 for (; depes != NULL; depes = depes->next) {
1331 1305 for (n = 0; n < depes->used; n++) {
1332 1306 if (trace_reader) {
1333 1307 (void) printf("%s:\t%s\n",
1334 1308 parallel_name->string_mb,
1335 1309 depes->names[n]->string_mb);
1336 1310 }
1337 1311 depes->names[n]->parallel = true;
1338 1312 depes->names[n]->no_parallel = false;
1339 1313 }
1340 1314 }
1341 1315 break;
1342 1316
1343 1317 case localhost_special:
1344 1318 if(svr4)
1345 1319 break;
1346 1320 /* Set the no_parallel bit for all the targets on */
1347 1321 /* the dependency list */
1348 1322 if (depes->used == 0) {
1349 1323 /* only those explicitly made parallel */
1350 1324 only_parallel = true;
1351 1325 all_parallel = false;
1352 1326 }
1353 1327 for (; depes != NULL; depes = depes->next) {
1354 1328 for (n = 0; n < depes->used; n++) {
1355 1329 if (trace_reader) {
1356 1330 (void) printf("%s:\t%s\n",
1357 1331 localhost_name->string_mb,
1358 1332 depes->names[n]->string_mb);
1359 1333 }
1360 1334 depes->names[n]->no_parallel = true;
1361 1335 depes->names[n]->parallel = false;
1362 1336 depes->names[n]->localhost = true;
1363 1337 }
1364 1338 }
1365 1339 break;
1366 1340
1367 1341 case precious_special:
1368 1342 if (depes->used == 0) {
1369 1343 /* everything is precious */
1370 1344 all_precious = true;
1371 1345 } else {
1372 1346 all_precious = false;
1373 1347 }
1374 1348 if(svr4) {
1375 1349 all_precious = true;
1376 1350 break;
1377 1351 }
1378 1352 /* Set the precious bit for all the targets on */
1379 1353 /* the dependency list */
1380 1354 for (; depes != NULL; depes = depes->next) {
1381 1355 for (n = 0; n < depes->used; n++) {
1382 1356 if (trace_reader) {
1383 1357 (void) printf("%s:\t%s\n",
1384 1358 precious->string_mb,
1385 1359 depes->names[n]->string_mb);
1386 1360 }
1387 1361 depes->names[n]->stat.is_precious = true;
1388 1362 }
1389 1363 }
1390 1364 break;
1391 1365
1392 1366 case sccs_get_special:
1393 1367 if (depes->used != 0) {
1394 1368 fatal_reader(catgets(catd, 1, 105, "Illegal dependencies for target `%s'"),
1395 1369 target->string_mb);
1396 1370 }
1397 1371 sccs_get_rule = command;
1398 1372 sccs_get_org_rule = command;
1399 1373 if (trace_reader) {
1400 1374 (void) printf("%s:\n", sccs_get_name->string_mb);
1401 1375 print_rule(command);
1402 1376 }
1403 1377 break;
1404 1378
1405 1379 case sccs_get_posix_special:
1406 1380 if (depes->used != 0) {
1407 1381 fatal_reader(catgets(catd, 1, 106, "Illegal dependencies for target `%s'"),
1408 1382 target->string_mb);
1409 1383 }
1410 1384 sccs_get_posix_rule = command;
1411 1385 if (trace_reader) {
1412 1386 (void) printf("%s:\n", sccs_get_posix_name->string_mb);
1413 1387 print_rule(command);
1414 1388 }
1415 1389 break;
1416 1390
1417 1391 case get_posix_special:
1418 1392 if (depes->used != 0) {
1419 1393 fatal_reader(catgets(catd, 1, 107, "Illegal dependencies for target `%s'"),
1420 1394 target->string_mb);
1421 1395 }
1422 1396 get_posix_rule = command;
1423 1397 if (trace_reader) {
1424 1398 (void) printf("%s:\n", get_posix_name->string_mb);
1425 1399 print_rule(command);
1426 1400 }
1427 1401 break;
1428 1402
1429 1403 case get_special:
1430 1404 if(!svr4) {
1431 1405 break;
1432 1406 }
1433 1407 if (depes->used != 0) {
1434 1408 fatal_reader(catgets(catd, 1, 108, "Illegal dependencies for target `%s'"),
1435 1409 target->string_mb);
1436 1410 }
1437 1411 get_rule = command;
1438 1412 sccs_get_rule = command;
1439 1413 if (trace_reader) {
1440 1414 (void) printf("%s:\n", get_name->string_mb);
1441 1415 print_rule(command);
1442 1416 }
1443 1417 break;
1444 1418
1445 1419 case silent_special:
1446 1420 if ((depes->used != 0) && (!posix)){
1447 1421 fatal_reader(catgets(catd, 1, 109, "Illegal dependencies for target `%s'"),
1448 1422 target->string_mb);
1449 1423 }
1450 1424 if (depes->used == 0)
1451 1425 {
1452 1426 silent_all = true;
1453 1427 }
1454 1428 if(svr4) {
1455 1429 silent_all = true;
1456 1430 break;
1457 1431 }
1458 1432 for (; depes != NULL; depes = depes->next) {
1459 1433 for (n = 0; n < depes->used; n++) {
1460 1434 depes->names[n]->silent_mode = true;
1461 1435 }
1462 1436 }
1463 1437 if (trace_reader) {
1464 1438 (void) printf("%s:\n", silent_name->string_mb);
1465 1439 }
1466 1440 break;
1467 1441
1468 1442 case suffixes_special:
1469 1443 read_suffixes_list(depes);
1470 1444 break;
1471 1445
1472 1446 default:
1473 1447
1474 1448 fatal_reader(catgets(catd, 1, 110, "Internal error: Unknown special reader"));
1475 1449 }
1476 1450 }
1477 1451
1478 1452 /*
1479 1453 * read_suffixes_list(depes)
1480 1454 *
1481 1455 * Read the special list .SUFFIXES. If it is empty the old list is
1482 1456 * cleared. Else the new one is appended. Suffixes with ~ are extracted
1483 1457 * and marked.
1484 1458 *
1485 1459 * Parameters:
1486 1460 * depes The list of suffixes
1487 1461 *
1488 1462 * Global variables used:
1489 1463 * hashtab The central hashtable for Names.
1490 1464 * suffixes The list of suffixes, set or appended to
1491 1465 * suffixes_name The Name ".SUFFIXES", used for tracing
1492 1466 * trace_reader Indicates that we should echo stuff we read
1493 1467 */
1494 1468 static void
1495 1469 read_suffixes_list(register Name_vector depes)
1496 1470 {
1497 1471 register int n;
1498 1472 register Dependency dp;
1499 1473 register Dependency *insert_dep;
1500 1474 register Name np;
1501 1475 Name np2;
1502 1476 register Boolean first = true;
1503 1477
1504 1478 if (depes->used == 0) {
1505 1479 /* .SUFFIXES with no dependency list clears the */
1506 1480 /* suffixes list */
1507 1481 for (Name_set::iterator np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
1508 1482 np->with_squiggle =
1509 1483 np->without_squiggle =
1510 1484 false;
1511 1485 }
1512 1486 suffixes = NULL;
1513 1487 if (trace_reader) {
1514 1488 (void) printf("%s:\n", suffixes_name->string_mb);
1515 1489 }
1516 1490 return;
1517 1491 }
1518 1492 Wstring str;
1519 1493 /* Otherwise we append to the list */
1520 1494 for (; depes != NULL; depes = depes->next) {
1521 1495 for (n = 0; n < depes->used; n++) {
1522 1496 np = depes->names[n];
1523 1497 /* Find the end of the list and check if the */
1524 1498 /* suffix already has been entered */
1525 1499 for (insert_dep = &suffixes, dp = *insert_dep;
1526 1500 dp != NULL;
1527 1501 insert_dep = &dp->next, dp = *insert_dep) {
1528 1502 if (dp->name == np) {
1529 1503 goto duplicate_suffix;
1530 1504 }
1531 1505 }
1532 1506 if (trace_reader) {
1533 1507 if (first) {
1534 1508 (void) printf("%s:\t",
1535 1509 suffixes_name->string_mb);
1536 1510 first = false;
1537 1511 }
1538 1512 (void) printf("%s ", depes->names[n]->string_mb);
1539 1513 }
1540 1514 if(!(posix|svr4)) {
1541 1515 /* If the suffix is suffixed with "~" we */
1542 1516 /* strip that and mark the suffix nameblock */
1543 1517 str.init(np);
1544 1518 wchar_t * wcb = str.get_string();
1545 1519 if (wcb[np->hash.length - 1] ==
1546 1520 (int) tilde_char) {
1547 1521 np2 = GETNAME(wcb,
1548 1522 (int)(np->hash.length - 1));
1549 1523 np2->with_squiggle = true;
1550 1524 if (np2->without_squiggle) {
1551 1525 continue;
1552 1526 }
1553 1527 np = np2;
1554 1528 }
1555 1529 }
1556 1530 np->without_squiggle = true;
1557 1531 /* Add the suffix to the list */
1558 1532 dp = *insert_dep = ALLOC(Dependency);
1559 1533 insert_dep = &dp->next;
1560 1534 dp->next = NULL;
1561 1535 dp->name = np;
1562 1536 dp->built = false;
1563 1537 duplicate_suffix:;
1564 1538 }
1565 1539 }
1566 1540 if (trace_reader) {
1567 1541 (void) printf("\n");
1568 1542 }
1569 1543 }
1570 1544
1571 1545 /*
1572 1546 * make_relative(to, result)
1573 1547 *
1574 1548 * Given a file name compose a relative path name from it to the
1575 1549 * current directory.
1576 1550 *
1577 1551 * Parameters:
1578 1552 * to The path we want to make relative
1579 1553 * result Where to put the resulting relative path
1580 1554 *
1581 1555 * Global variables used:
1582 1556 */
1583 1557 static void
1584 1558 make_relative(wchar_t *to, wchar_t *result)
1585 1559 {
1586 1560 wchar_t *from;
1587 1561 wchar_t *allocated;
1588 1562 wchar_t *cp;
1589 1563 wchar_t *tocomp;
1590 1564 int ncomps;
1591 1565 int i;
1592 1566 int len;
1593 1567
1594 1568 /* Check if the path is already relative. */
1595 1569 if (to[0] != (int) slash_char) {
1596 1570 (void) wscpy(result, to);
1597 1571 return;
1598 1572 }
1599 1573
1600 1574 MBSTOWCS(wcs_buffer, get_current_path());
1601 1575 from = allocated = (wchar_t *) wsdup(wcs_buffer);
1602 1576
1603 1577 /*
1604 1578 * Find the number of components in the from name.
1605 1579 * ncomp = number of slashes + 1.
1606 1580 */
1607 1581 ncomps = 1;
1608 1582 for (cp = from; *cp != (int) nul_char; cp++) {
1609 1583 if (*cp == (int) slash_char) {
1610 1584 ncomps++;
1611 1585 }
1612 1586 }
1613 1587
1614 1588 /*
1615 1589 * See how many components match to determine how many "..",
1616 1590 * if any, will be needed.
1617 1591 */
1618 1592 result[0] = (int) nul_char;
1619 1593 tocomp = to;
1620 1594 while ((*from != (int) nul_char) && (*from == *to)) {
1621 1595 if (*from == (int) slash_char) {
1622 1596 ncomps--;
1623 1597 tocomp = &to[1];
1624 1598 }
1625 1599 from++;
1626 1600 to++;
1627 1601 }
1628 1602
1629 1603 /*
1630 1604 * Now for some special cases. Check for exact matches and
1631 1605 * for either name terminating exactly.
1632 1606 */
1633 1607 if (*from == (int) nul_char) {
1634 1608 if (*to == (int) nul_char) {
1635 1609 MBSTOWCS(wcs_buffer, ".");
1636 1610 (void) wscpy(result, wcs_buffer);
1637 1611 retmem(allocated);
1638 1612 return;
1639 1613 }
1640 1614 if (*to == (int) slash_char) {
1641 1615 ncomps--;
1642 1616 tocomp = &to[1];
1643 1617 }
1644 1618 } else if ((*from == (int) slash_char) && (*to == (int) nul_char)) {
1645 1619 ncomps--;
1646 1620 tocomp = to;
1647 1621 }
1648 1622 /* Add on the ".."s. */
1649 1623 for (i = 0; i < ncomps; i++) {
1650 1624 MBSTOWCS(wcs_buffer, "../");
1651 1625 (void) wscat(result, wcs_buffer);
1652 1626 }
1653 1627
1654 1628 /* Add on the remainder of the to name, if any. */
1655 1629 if (*tocomp == (int) nul_char) {
1656 1630 len = wslen(result);
1657 1631 result[len - 1] = (int) nul_char;
1658 1632 } else {
1659 1633 (void) wscat(result, tocomp);
1660 1634 }
1661 1635 retmem(allocated);
1662 1636 return;
1663 1637 }
1664 1638
1665 1639 /*
1666 1640 * print_rule(command)
1667 1641 *
1668 1642 * Used when tracing the reading of rules
1669 1643 *
1670 1644 * Parameters:
1671 1645 * command Command to print
1672 1646 *
1673 1647 * Global variables used:
1674 1648 */
1675 1649 static void
1676 1650 print_rule(register Cmd_line command)
1677 1651 {
1678 1652 for (; command != NULL; command = command->next) {
1679 1653 (void) printf("\t%s\n", command->command_line->string_mb);
1680 1654 }
1681 1655 }
1682 1656
1683 1657 /*
1684 1658 * enter_conditional(target, name, value, append)
1685 1659 *
1686 1660 * Enter "target := MACRO= value" constructs
1687 1661 *
1688 1662 * Parameters:
1689 1663 * target The target the macro is for
1690 1664 * name The name of the macro
1691 1665 * value The value for the macro
1692 1666 * append Indicates if the assignment is appending or not
1693 1667 *
1694 1668 * Global variables used:
1695 1669 * conditionals A special Name that stores all conditionals
1696 1670 * where the target is a % pattern
1697 1671 * trace_reader Indicates that we should echo stuff we read
1698 1672 */
1699 1673 void
1700 1674 enter_conditional(register Name target, Name name, Name value, register Boolean append)
1701 1675 {
1702 1676 register Property conditional;
1703 1677 static int sequence;
1704 1678 Name orig_target = target;
1705 1679
1706 1680 if (name == target_arch) {
1707 1681 enter_conditional(target, virtual_root, virtual_root, false);
1708 1682 }
1709 1683
1710 1684 if (target->percent) {
1711 1685 target = conditionals;
1712 1686 }
1713 1687
1714 1688 if (name->colon) {
1715 1689 sh_transform(&name, &value);
1716 1690 }
1717 1691
1718 1692 /* Count how many conditionals we must activate before building the */
1719 1693 /* target */
1720 1694 if (target->percent) {
1721 1695 target = conditionals;
1722 1696 }
1723 1697
1724 1698 target->conditional_cnt++;
1725 1699 maybe_append_prop(name, macro_prop)->body.macro.is_conditional = true;
1726 1700 /* Add the property for the target */
1727 1701 conditional = append_prop(target, conditional_prop);
1728 1702 conditional->body.conditional.target = orig_target;
1729 1703 conditional->body.conditional.name = name;
1730 1704 conditional->body.conditional.value = value;
1731 1705 conditional->body.conditional.sequence = sequence++;
1732 1706 conditional->body.conditional.append = append;
1733 1707 if (trace_reader) {
1734 1708 if (value == NULL) {
1735 1709 (void) printf("%s := %s %c=\n",
1736 1710 target->string_mb,
1737 1711 name->string_mb,
1738 1712 append ?
1739 1713 (int) plus_char : (int) space_char);
1740 1714 } else {
1741 1715 (void) printf("%s := %s %c= %s\n",
1742 1716 target->string_mb,
1743 1717 name->string_mb,
1744 1718 append ?
1745 1719 (int) plus_char : (int) space_char,
1746 1720 value->string_mb);
1747 1721 }
1748 1722 }
1749 1723 }
1750 1724
1751 1725 /*
1752 1726 * enter_equal(name, value, append)
1753 1727 *
1754 1728 * Enter "MACRO= value" constructs
1755 1729 *
1756 1730 * Parameters:
1757 1731 * name The name of the macro
1758 1732 * value The value for the macro
1759 1733 * append Indicates if the assignment is appending or not
1760 1734 *
1761 1735 * Global variables used:
1762 1736 * trace_reader Indicates that we should echo stuff we read
1763 1737 */
1764 1738 void
1765 1739 enter_equal(Name name, Name value, register Boolean append)
1766 1740 {
1767 1741 wchar_t *string;
1768 1742 Name temp;
1769 1743
1770 1744 if (name->colon) {
1771 1745 sh_transform(&name, &value);
1772 1746 }
1773 1747 (void) SETVAR(name, value, append);
1774 1748
1775 1749 /* if we're setting FC, we want to set F77 to the same value. */
1776 1750 Wstring nms(name);
1777 1751 wchar_t * wcb = nms.get_string();
1778 1752 string = wcb;
1779 1753 if (string[0]=='F' &&
1780 1754 string[1]=='C' &&
1781 1755 string[2]=='\0') {
1782 1756 MBSTOWCS(wcs_buffer, NOCATGETS("F77"));
1783 1757 temp = GETNAME(wcs_buffer, FIND_LENGTH);
1784 1758 (void) SETVAR(temp, value, append);
1785 1759 /*
1786 1760 fprintf(stderr, catgets(catd, 1, 111, "warning: FC is obsolete, use F77 instead\n"));
1787 1761 */
1788 1762 }
1789 1763
1790 1764 if (trace_reader) {
1791 1765 if (value == NULL) {
1792 1766 (void) printf("%s %c=\n",
1793 1767 name->string_mb,
1794 1768 append ?
1795 1769 (int) plus_char : (int) space_char);
1796 1770 } else {
1797 1771 (void) printf("%s %c= %s\n",
1798 1772 name->string_mb,
1799 1773 append ?
1800 1774 (int) plus_char : (int) space_char,
1801 1775 value->string_mb);
1802 1776 }
1803 1777 }
1804 1778 }
1805 1779
1806 1780 /*
1807 1781 * sh_transform(name, value)
1808 1782 *
1809 1783 * Parameters:
1810 1784 * name The name of the macro we might transform
1811 1785 * value The value to transform
1812 1786 *
1813 1787 */
1814 1788 static void
1815 1789 sh_transform(Name *name, Name *value)
1816 1790 {
1817 1791 /* Check if we need :sh transform */
1818 1792 wchar_t *colon;
1819 1793 String_rec command;
1820 1794 String_rec destination;
1821 1795 wchar_t buffer[1000];
1822 1796 wchar_t buffer1[1000];
1823 1797
1824 1798 static wchar_t colon_sh[4];
1825 1799 static wchar_t colon_shell[7];
1826 1800
1827 1801 if (colon_sh[0] == (int) nul_char) {
1828 1802 MBSTOWCS(colon_sh, NOCATGETS(":sh"));
1829 1803 MBSTOWCS(colon_shell, NOCATGETS(":shell"));
1830 1804 }
1831 1805 Wstring nms((*name));
1832 1806 wchar_t * wcb = nms.get_string();
1833 1807
1834 1808 colon = (wchar_t *) wsrchr(wcb, (int) colon_char);
1835 1809 if ((colon != NULL) && (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell))) {
1836 1810 INIT_STRING_FROM_STACK(destination, buffer);
1837 1811
1838 1812 if(*value == NULL) {
1839 1813 buffer[0] = 0;
1840 1814 } else {
1841 1815 Wstring wcb1((*value));
1842 1816 if (IS_WEQUAL(colon, colon_shell)) {
1843 1817 INIT_STRING_FROM_STACK(command, buffer1);
1844 1818 expand_value(*value, &command, false);
1845 1819 } else {
1846 1820 command.text.p = wcb1.get_string() + (*value)->hash.length;
1847 1821 command.text.end = command.text.p;
1848 1822 command.buffer.start = wcb1.get_string();
1849 1823 command.buffer.end = command.text.p;
1850 1824 }
1851 1825 sh_command2string(&command, &destination);
1852 1826 }
1853 1827
1854 1828 (*value) = GETNAME(destination.buffer.start, FIND_LENGTH);
1855 1829 *colon = (int) nul_char;
1856 1830 (*name) = GETNAME(wcb, FIND_LENGTH);
1857 1831 *colon = (int) colon_char;
1858 1832 }
1859 1833 }
1860 1834
1861 1835 /*
1862 1836 * fatal_reader(format, args...)
1863 1837 *
1864 1838 * Parameters:
1865 1839 * format printf style format string
1866 1840 * args arguments to match the format
1867 1841 *
1868 1842 * Global variables used:
1869 1843 * file_being_read Name of the makefile being read
1870 1844 * line_number Line that is being read
1871 1845 * report_pwd Indicates whether current path should be shown
1872 1846 * temp_file_name When reading tempfile we report that name
1873 1847 */
1874 1848 /*VARARGS*/
1875 1849 void
1876 1850 fatal_reader(char * pattern, ...)
1877 1851 {
1878 1852 va_list args;
1879 1853 char message[1000];
1880 1854
1881 1855 va_start(args, pattern);
1882 1856 if (file_being_read != NULL) {
1883 1857 WCSTOMBS(mbs_buffer, file_being_read);
1884 1858 if (line_number != 0) {
1885 1859 (void) sprintf(message,
1886 1860 catgets(catd, 1, 112, "%s, line %d: %s"),
1887 1861 mbs_buffer,
1888 1862 line_number,
1889 1863 pattern);
1890 1864 } else {
1891 1865 (void) sprintf(message,
1892 1866 "%s: %s",
1893 1867 mbs_buffer,
1894 1868 pattern);
1895 1869 }
1896 1870 pattern = message;
1897 1871 }
1898 1872
1899 1873 (void) fflush(stdout);
1900 1874 #ifdef DISTRIBUTED
1901 1875 (void) fprintf(stderr, catgets(catd, 1, 113, "dmake: Fatal error in reader: "));
1902 1876 #else
1903 1877 (void) fprintf(stderr, catgets(catd, 1, 238, "make: Fatal error in reader: "));
1904 1878 #endif
1905 1879 (void) vfprintf(stderr, pattern, args);
1906 1880 (void) fprintf(stderr, "\n");
1907 1881 va_end(args);
1908 1882
1909 1883 if (temp_file_name != NULL) {
1910 1884 (void) fprintf(stderr,
1911 1885 #ifdef DISTRIBUTED
1912 1886 catgets(catd, 1, 114, "dmake: Temp-file %s not removed\n"),
1913 1887 #else
1914 1888 catgets(catd, 1, 239, "make: Temp-file %s not removed\n"),
1915 1889 #endif
1916 1890 temp_file_name->string_mb);
1917 1891 temp_file_name = NULL;
1918 1892 }
1919 1893
1920 1894 if (report_pwd) {
1921 1895 (void) fprintf(stderr,
1922 1896 catgets(catd, 1, 115, "Current working directory %s\n"),
1923 1897 get_current_path());
1924 1898 }
1925 1899 (void) fflush(stderr);
1926 1900 exit_status = 1;
1927 1901 exit(1);
1928 1902 }
1929 1903
↓ open down ↓ |
708 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX