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