Print this page
make: remove SCCS ident stuff
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/lib/mksh/src/macro.cc
+++ new/usr/src/cmd/make/lib/mksh/src/macro.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.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 -/*
26 - * @(#)macro.cc 1.22 06/12/12
27 - */
28 25
29 -#pragma ident "@(#)macro.cc 1.22 06/12/12"
30 26
31 27 /*
32 28 * macro.cc
33 29 *
34 30 * Handle expansion of make macros
35 31 */
36 32
37 33 /*
38 34 * Included files
39 35 */
40 36 #include <mksh/dosys.h> /* sh_command2string() */
41 37 #include <mksh/i18n.h> /* get_char_semantics_value() */
42 38 #include <mksh/macro.h>
43 39 #include <mksh/misc.h> /* retmem() */
44 40 #include <mksh/read.h> /* get_next_block_fn() */
45 41 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
46 42
47 43 /*
48 44 * File table of contents
49 45 */
50 46 static void add_macro_to_global_list(Name macro_to_add);
51 47 #ifdef NSE
52 48 static void expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd);
53 49 #else
54 50 static void expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd);
55 51 #endif
56 52
57 53 static void init_arch_macros(void);
58 54 static void init_mach_macros(void);
59 55 static Boolean init_arch_done = false;
60 56 static Boolean init_mach_done = false;
61 57
62 58
63 59 long env_alloc_num = 0;
64 60 long env_alloc_bytes = 0;
65 61
66 62 /*
67 63 * getvar(name)
68 64 *
69 65 * Return expanded value of macro.
70 66 *
71 67 * Return value:
72 68 * The expanded value of the macro
73 69 *
74 70 * Parameters:
75 71 * name The name of the macro we want the value for
76 72 *
77 73 * Global variables used:
78 74 */
79 75 Name
80 76 getvar(register Name name)
81 77 {
82 78 String_rec destination;
83 79 wchar_t buffer[STRING_BUFFER_LENGTH];
84 80 register Name result;
85 81
86 82 if ((name == host_arch) || (name == target_arch)) {
87 83 if (!init_arch_done) {
88 84 init_arch_done = true;
89 85 init_arch_macros();
90 86 }
91 87 }
92 88 if ((name == host_mach) || (name == target_mach)) {
93 89 if (!init_mach_done) {
94 90 init_mach_done = true;
95 91 init_mach_macros();
96 92 }
97 93 }
98 94
99 95 INIT_STRING_FROM_STACK(destination, buffer);
100 96 expand_value(maybe_append_prop(name, macro_prop)->body.macro.value,
101 97 &destination,
102 98 false);
103 99 result = GETNAME(destination.buffer.start, FIND_LENGTH);
104 100 if (destination.free_after_use) {
105 101 retmem(destination.buffer.start);
106 102 }
107 103 return result;
108 104 }
109 105
110 106 /*
111 107 * expand_value(value, destination, cmd)
112 108 *
113 109 * Recursively expands all macros in the string value.
114 110 * destination is where the expanded value should be appended.
115 111 *
116 112 * Parameters:
117 113 * value The value we are expanding
118 114 * destination Where to deposit the expansion
119 115 * cmd If we are evaluating a command line we
120 116 * turn \ quoting off
121 117 *
122 118 * Global variables used:
123 119 */
124 120 void
125 121 expand_value(Name value, register String destination, Boolean cmd)
126 122 {
127 123 Source_rec sourceb;
128 124 register Source source = &sourceb;
129 125 register wchar_t *source_p = NULL;
130 126 register wchar_t *source_end = NULL;
131 127 wchar_t *block_start = NULL;
132 128 int quote_seen = 0;
133 129
134 130 if (value == NULL) {
135 131 /*
136 132 * Make sure to get a string allocated even if it
137 133 * will be empty.
138 134 */
139 135 MBSTOWCS(wcs_buffer, "");
140 136 append_string(wcs_buffer, destination, FIND_LENGTH);
141 137 destination->text.end = destination->text.p;
142 138 return;
143 139 }
144 140 if (!value->dollar) {
145 141 /*
146 142 * If the value we are expanding does not contain
147 143 * any $, we don't have to parse it.
148 144 */
149 145 APPEND_NAME(value,
150 146 destination,
151 147 (int) value->hash.length
152 148 );
153 149 destination->text.end = destination->text.p;
154 150 return;
155 151 }
156 152
157 153 if (value->being_expanded) {
158 154 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 113, "Loop detected when expanding macro value `%s'"),
159 155 value->string_mb);
160 156 }
161 157 value->being_expanded = true;
162 158 /* Setup the structure we read from */
163 159 Wstring vals(value);
164 160 sourceb.string.text.p = sourceb.string.buffer.start = wsdup(vals.get_string());
165 161 sourceb.string.free_after_use = true;
166 162 sourceb.string.text.end =
167 163 sourceb.string.buffer.end =
168 164 sourceb.string.text.p + value->hash.length;
169 165 sourceb.previous = NULL;
170 166 sourceb.fd = -1;
171 167 sourceb.inp_buf =
172 168 sourceb.inp_buf_ptr =
173 169 sourceb.inp_buf_end = NULL;
174 170 sourceb.error_converting = false;
175 171 /* Lift some pointers from the struct to local register variables */
176 172 CACHE_SOURCE(0);
177 173 /* We parse the string in segments */
178 174 /* We read chars until we find a $, then we append what we have read so far */
179 175 /* (since last $ processing) to the destination. When we find a $ we call */
180 176 /* expand_macro() and let it expand that particular $ reference into dest */
181 177 block_start = source_p;
182 178 quote_seen = 0;
183 179 for (; 1; source_p++) {
184 180 switch (GET_CHAR()) {
185 181 case backslash_char:
186 182 /* Quote $ in macro value */
187 183 if (!cmd) {
188 184 quote_seen = ~quote_seen;
189 185 }
190 186 continue;
191 187 case dollar_char:
192 188 /* Save the plain string we found since */
193 189 /* start of string or previous $ */
194 190 if (quote_seen) {
195 191 append_string(block_start,
196 192 destination,
197 193 source_p - block_start - 1);
198 194 block_start = source_p;
199 195 break;
200 196 }
201 197 append_string(block_start,
202 198 destination,
203 199 source_p - block_start);
204 200 source->string.text.p = ++source_p;
205 201 UNCACHE_SOURCE();
206 202 /* Go expand the macro reference */
207 203 expand_macro(source, destination, sourceb.string.buffer.start, cmd);
208 204 CACHE_SOURCE(1);
209 205 block_start = source_p + 1;
210 206 break;
211 207 case nul_char:
212 208 /* The string ran out. Get some more */
213 209 append_string(block_start,
214 210 destination,
215 211 source_p - block_start);
216 212 GET_NEXT_BLOCK_NOCHK(source);
217 213 if (source == NULL) {
218 214 destination->text.end = destination->text.p;
219 215 value->being_expanded = false;
220 216 return;
221 217 }
222 218 if (source->error_converting) {
223 219 fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_value()"));
224 220 }
225 221 block_start = source_p;
226 222 source_p--;
227 223 continue;
228 224 }
229 225 quote_seen = 0;
230 226 }
231 227 retmem(sourceb.string.buffer.start);
232 228 }
233 229
234 230 /*
235 231 * expand_macro(source, destination, current_string, cmd)
236 232 *
237 233 * Should be called with source->string.text.p pointing to
238 234 * the first char after the $ that starts a macro reference.
239 235 * source->string.text.p is returned pointing to the first char after
240 236 * the macro name.
241 237 * It will read the macro name, expanding any macros in it,
242 238 * and get the value. The value is then expanded.
243 239 * destination is a String that is filled in with the expanded macro.
244 240 * It may be passed in referencing a buffer to expand the macro into.
245 241 * Note that most expansions are done on demand, e.g. right
246 242 * before the command is executed and not while the file is
247 243 * being parsed.
248 244 *
249 245 * Parameters:
250 246 * source The source block that references the string
251 247 * to expand
252 248 * destination Where to put the result
253 249 * current_string The string we are expanding, for error msg
254 250 * cmd If we are evaluating a command line we
255 251 * turn \ quoting off
256 252 *
257 253 * Global variables used:
258 254 * funny Vector of semantic tags for characters
259 255 * is_conditional Set if a conditional macro is refd
260 256 * make_word_mentioned Set if the word "MAKE" is mentioned
261 257 * makefile_type We deliver extra msg when reading makefiles
262 258 * query The Name "?", compared against
263 259 * query_mentioned Set if the word "?" is mentioned
264 260 */
265 261 void
266 262 expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd)
267 263 {
268 264 static Name make = (Name)NULL;
269 265 static wchar_t colon_sh[4];
270 266 static wchar_t colon_shell[7];
271 267 String_rec string;
272 268 wchar_t buffer[STRING_BUFFER_LENGTH];
273 269 register wchar_t *source_p = source->string.text.p;
274 270 register wchar_t *source_end = source->string.text.end;
275 271 register int closer = 0;
276 272 wchar_t *block_start = (wchar_t *)NULL;
277 273 int quote_seen = 0;
278 274 register int closer_level = 1;
279 275 Name name = (Name)NULL;
280 276 wchar_t *colon = (wchar_t *)NULL;
281 277 wchar_t *percent = (wchar_t *)NULL;
282 278 wchar_t *eq = (wchar_t *) NULL;
283 279 Property macro = NULL;
284 280 wchar_t *p = (wchar_t*)NULL;
285 281 String_rec extracted;
286 282 wchar_t extracted_string[MAXPATHLEN];
287 283 wchar_t *left_head = NULL;
288 284 wchar_t *left_tail = NULL;
289 285 wchar_t *right_tail = NULL;
290 286 int left_head_len = 0;
291 287 int left_tail_len = 0;
292 288 int tmp_len = 0;
293 289 wchar_t *right_hand[128];
294 290 int i = 0;
295 291 enum {
296 292 no_extract,
297 293 dir_extract,
298 294 file_extract
299 295 } extraction = no_extract;
300 296 enum {
301 297 no_replace,
302 298 suffix_replace,
303 299 pattern_replace,
304 300 sh_replace
305 301 } replacement = no_replace;
306 302
307 303 if (make == NULL) {
308 304 MBSTOWCS(wcs_buffer, NOCATGETS("MAKE"));
309 305 make = GETNAME(wcs_buffer, FIND_LENGTH);
310 306
311 307 MBSTOWCS(colon_sh, NOCATGETS(":sh"));
312 308 MBSTOWCS(colon_shell, NOCATGETS(":shell"));
313 309 }
314 310
315 311 right_hand[0] = NULL;
316 312
317 313 /* First copy the (macro-expanded) macro name into string. */
318 314 INIT_STRING_FROM_STACK(string, buffer);
319 315 recheck_first_char:
320 316 /* Check the first char of the macro name to figure out what to do. */
321 317 switch (GET_CHAR()) {
322 318 case nul_char:
323 319 GET_NEXT_BLOCK_NOCHK(source);
324 320 if (source == NULL) {
325 321 WCSTOMBS(mbs_buffer, current_string);
326 322 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 114, "'$' at end of string `%s'"),
327 323 mbs_buffer);
328 324 }
329 325 if (source->error_converting) {
330 326 fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_macro()"));
331 327 }
332 328 goto recheck_first_char;
333 329 case parenleft_char:
334 330 /* Multi char name. */
335 331 closer = (int) parenright_char;
336 332 break;
337 333 case braceleft_char:
338 334 /* Multi char name. */
339 335 closer = (int) braceright_char;
340 336 break;
341 337 case newline_char:
342 338 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 115, "'$' at end of line"));
343 339 default:
344 340 /* Single char macro name. Just suck it up */
345 341 append_char(*source_p, &string);
346 342 source->string.text.p = source_p + 1;
347 343 goto get_macro_value;
348 344 }
349 345
350 346 /* Handle multi-char macro names */
351 347 block_start = ++source_p;
352 348 quote_seen = 0;
353 349 for (; 1; source_p++) {
354 350 switch (GET_CHAR()) {
355 351 case nul_char:
356 352 append_string(block_start,
357 353 &string,
358 354 source_p - block_start);
359 355 GET_NEXT_BLOCK_NOCHK(source);
360 356 if (source == NULL) {
361 357 if (current_string != NULL) {
362 358 WCSTOMBS(mbs_buffer, current_string);
363 359 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 116, "Unmatched `%c' in string `%s'"),
364 360 closer ==
365 361 (int) braceright_char ?
366 362 (int) braceleft_char :
367 363 (int) parenleft_char,
368 364 mbs_buffer);
369 365 } else {
370 366 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 117, "Premature EOF"));
371 367 }
372 368 }
373 369 if (source->error_converting) {
374 370 fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_macro()"));
375 371 }
376 372 block_start = source_p;
377 373 source_p--;
378 374 continue;
379 375 case newline_char:
380 376 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 118, "Unmatched `%c' on line"),
381 377 closer == (int) braceright_char ?
382 378 (int) braceleft_char :
383 379 (int) parenleft_char);
384 380 case backslash_char:
385 381 /* Quote dollar in macro value. */
386 382 if (!cmd) {
387 383 quote_seen = ~quote_seen;
388 384 }
389 385 continue;
390 386 case dollar_char:
391 387 /*
392 388 * Macro names may reference macros.
393 389 * This expands the value of such macros into the
394 390 * macro name string.
395 391 */
396 392 if (quote_seen) {
397 393 append_string(block_start,
398 394 &string,
399 395 source_p - block_start - 1);
400 396 block_start = source_p;
401 397 break;
402 398 }
403 399 append_string(block_start,
404 400 &string,
405 401 source_p - block_start);
406 402 source->string.text.p = ++source_p;
407 403 UNCACHE_SOURCE();
408 404 expand_macro(source, &string, current_string, cmd);
409 405 CACHE_SOURCE(0);
410 406 block_start = source_p;
411 407 source_p--;
412 408 break;
413 409 case parenleft_char:
414 410 /* Allow nested pairs of () in the macro name. */
415 411 if (closer == (int) parenright_char) {
416 412 closer_level++;
417 413 }
418 414 break;
419 415 case braceleft_char:
420 416 /* Allow nested pairs of {} in the macro name. */
421 417 if (closer == (int) braceright_char) {
422 418 closer_level++;
423 419 }
424 420 break;
425 421 case parenright_char:
426 422 case braceright_char:
427 423 /*
428 424 * End of the name. Save the string in the macro
429 425 * name string.
430 426 */
431 427 if ((*source_p == closer) && (--closer_level <= 0)) {
432 428 source->string.text.p = source_p + 1;
433 429 append_string(block_start,
434 430 &string,
435 431 source_p - block_start);
436 432 goto get_macro_value;
437 433 }
438 434 break;
439 435 }
440 436 quote_seen = 0;
441 437 }
442 438 /*
443 439 * We got the macro name. We now inspect it to see if it
444 440 * specifies any translations of the value.
445 441 */
446 442 get_macro_value:
447 443 name = NULL;
448 444 /* First check if we have a $(@D) type translation. */
449 445 if ((get_char_semantics_value(string.buffer.start[0]) &
450 446 (int) special_macro_sem) &&
451 447 (string.text.p - string.buffer.start >= 2) &&
452 448 ((string.buffer.start[1] == 'D') ||
453 449 (string.buffer.start[1] == 'F'))) {
454 450 switch (string.buffer.start[1]) {
455 451 case 'D':
456 452 extraction = dir_extract;
457 453 break;
458 454 case 'F':
459 455 extraction = file_extract;
460 456 break;
461 457 default:
462 458 WCSTOMBS(mbs_buffer, string.buffer.start);
463 459 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 119, "Illegal macro reference `%s'"),
464 460 mbs_buffer);
465 461 }
466 462 /* Internalize the macro name using the first char only. */
467 463 name = GETNAME(string.buffer.start, 1);
468 464 (void) wscpy(string.buffer.start, string.buffer.start + 2);
469 465 }
470 466 /* Check for other kinds of translations. */
471 467 if ((colon = (wchar_t *) wschr(string.buffer.start,
472 468 (int) colon_char)) != NULL) {
473 469 /*
474 470 * We have a $(FOO:.c=.o) type translation.
475 471 * Get the name of the macro proper.
476 472 */
477 473 if (name == NULL) {
478 474 name = GETNAME(string.buffer.start,
479 475 colon - string.buffer.start);
480 476 }
481 477 /* Pickup all the translations. */
482 478 if (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell)) {
483 479 replacement = sh_replace;
484 480 } else if ((svr4) ||
485 481 ((percent = (wchar_t *) wschr(colon + 1,
486 482 (int) percent_char)) == NULL)) {
487 483 while (colon != NULL) {
488 484 if ((eq = (wchar_t *) wschr(colon + 1,
489 485 (int) equal_char)) == NULL) {
490 486 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 120, "= missing from replacement macro reference"));
491 487 }
492 488 left_tail_len = eq - colon - 1;
493 489 if(left_tail) {
494 490 retmem(left_tail);
495 491 }
496 492 left_tail = ALLOC_WC(left_tail_len + 1);
497 493 (void) wsncpy(left_tail,
498 494 colon + 1,
499 495 eq - colon - 1);
500 496 left_tail[eq - colon - 1] = (int) nul_char;
501 497 replacement = suffix_replace;
502 498 if ((colon = (wchar_t *) wschr(eq + 1,
503 499 (int) colon_char)) != NULL) {
504 500 tmp_len = colon - eq;
505 501 if(right_tail) {
506 502 retmem(right_tail);
507 503 }
508 504 right_tail = ALLOC_WC(tmp_len);
509 505 (void) wsncpy(right_tail,
510 506 eq + 1,
511 507 colon - eq - 1);
512 508 right_tail[colon - eq - 1] =
513 509 (int) nul_char;
514 510 } else {
515 511 if(right_tail) {
516 512 retmem(right_tail);
517 513 }
518 514 right_tail = ALLOC_WC(wslen(eq) + 1);
519 515 (void) wscpy(right_tail, eq + 1);
520 516 }
521 517 }
522 518 } else {
523 519 if ((eq = (wchar_t *) wschr(colon + 1,
524 520 (int) equal_char)) == NULL) {
525 521 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 121, "= missing from replacement macro reference"));
526 522 }
527 523 if ((percent = (wchar_t *) wschr(colon + 1,
528 524 (int) percent_char)) == NULL) {
529 525 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 122, "%% missing from replacement macro reference"));
530 526 }
531 527 if (eq < percent) {
532 528 fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 123, "%% missing from replacement macro reference"));
533 529 }
534 530
535 531 if (percent > (colon + 1)) {
536 532 tmp_len = percent - colon;
537 533 if(left_head) {
538 534 retmem(left_head);
539 535 }
540 536 left_head = ALLOC_WC(tmp_len);
541 537 (void) wsncpy(left_head,
542 538 colon + 1,
543 539 percent - colon - 1);
544 540 left_head[percent-colon-1] = (int) nul_char;
545 541 left_head_len = percent-colon-1;
546 542 } else {
547 543 left_head = NULL;
548 544 left_head_len = 0;
549 545 }
550 546
551 547 if (eq > percent+1) {
552 548 tmp_len = eq - percent;
553 549 if(left_tail) {
554 550 retmem(left_tail);
555 551 }
556 552 left_tail = ALLOC_WC(tmp_len);
557 553 (void) wsncpy(left_tail,
558 554 percent + 1,
559 555 eq - percent - 1);
560 556 left_tail[eq-percent-1] = (int) nul_char;
561 557 left_tail_len = eq-percent-1;
562 558 } else {
563 559 left_tail = NULL;
564 560 left_tail_len = 0;
565 561 }
566 562
567 563 if ((percent = (wchar_t *) wschr(++eq,
568 564 (int) percent_char)) == NULL) {
569 565
570 566 right_hand[0] = ALLOC_WC(wslen(eq) + 1);
571 567 right_hand[1] = NULL;
572 568 (void) wscpy(right_hand[0], eq);
573 569 } else {
574 570 i = 0;
575 571 do {
576 572 right_hand[i] = ALLOC_WC(percent-eq+1);
577 573 (void) wsncpy(right_hand[i],
578 574 eq,
579 575 percent - eq);
580 576 right_hand[i][percent-eq] =
581 577 (int) nul_char;
582 578 if (i++ >= VSIZEOF(right_hand)) {
583 579 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 124, "Too many %% in pattern"));
584 580 }
585 581 eq = percent + 1;
586 582 if (eq[0] == (int) nul_char) {
587 583 MBSTOWCS(wcs_buffer, "");
588 584 right_hand[i] = (wchar_t *) wsdup(wcs_buffer);
589 585 i++;
590 586 break;
591 587 }
592 588 } while ((percent = (wchar_t *) wschr(eq, (int) percent_char)) != NULL);
593 589 if (eq[0] != (int) nul_char) {
594 590 right_hand[i] = ALLOC_WC(wslen(eq) + 1);
595 591 (void) wscpy(right_hand[i], eq);
596 592 i++;
597 593 }
598 594 right_hand[i] = NULL;
599 595 }
600 596 replacement = pattern_replace;
601 597 }
602 598 }
603 599 if (name == NULL) {
604 600 /*
605 601 * No translations found.
606 602 * Use the whole string as the macro name.
607 603 */
608 604 name = GETNAME(string.buffer.start,
609 605 string.text.p - string.buffer.start);
610 606 }
611 607 if (string.free_after_use) {
612 608 retmem(string.buffer.start);
613 609 }
614 610 if (name == make) {
615 611 make_word_mentioned = true;
616 612 }
617 613 if (name == query) {
618 614 query_mentioned = true;
619 615 }
620 616 if ((name == host_arch) || (name == target_arch)) {
621 617 if (!init_arch_done) {
622 618 init_arch_done = true;
623 619 init_arch_macros();
624 620 }
625 621 }
626 622 if ((name == host_mach) || (name == target_mach)) {
627 623 if (!init_mach_done) {
628 624 init_mach_done = true;
629 625 init_mach_macros();
630 626 }
631 627 }
632 628 /* Get the macro value. */
633 629 macro = get_prop(name->prop, macro_prop);
634 630 #ifdef NSE
635 631 if (nse_watch_vars && nse && macro != NULL) {
636 632 if (macro->body.macro.imported) {
637 633 nse_shell_var_used= name;
638 634 }
639 635 if (macro->body.macro.value != NULL){
640 636 if (nse_backquotes(macro->body.macro.value->string)) {
641 637 nse_backquote_seen= name;
642 638 }
643 639 }
644 640 }
645 641 #endif
646 642 if ((macro != NULL) && macro->body.macro.is_conditional) {
647 643 conditional_macro_used = true;
648 644 /*
649 645 * Add this conditional macro to the beginning of the
650 646 * global list.
651 647 */
652 648 add_macro_to_global_list(name);
653 649 if (makefile_type == reading_makefile) {
654 650 warning_mksh(catgets(libmksdmsi18n_catd, 1, 164, "Conditional macro `%s' referenced in file `%ws', line %d"),
655 651 name->string_mb, file_being_read, line_number);
656 652 }
657 653 }
658 654 /* Macro name read and parsed. Expand the value. */
659 655 if ((macro == NULL) || (macro->body.macro.value == NULL)) {
660 656 /* If the value is empty, we just get out of here. */
661 657 goto exit;
662 658 }
663 659 if (replacement == sh_replace) {
664 660 /* If we should do a :sh transform, we expand the command
665 661 * and process it.
666 662 */
667 663 INIT_STRING_FROM_STACK(string, buffer);
668 664 /* Expand the value into a local string buffer and run cmd. */
669 665 expand_value_with_daemon(name, macro, &string, cmd);
670 666 sh_command2string(&string, destination);
671 667 } else if ((replacement != no_replace) || (extraction != no_extract)) {
672 668 /*
673 669 * If there were any transforms specified in the macro
674 670 * name, we deal with them here.
675 671 */
676 672 INIT_STRING_FROM_STACK(string, buffer);
677 673 /* Expand the value into a local string buffer. */
678 674 expand_value_with_daemon(name, macro, &string, cmd);
679 675 /* Scan the expanded string. */
680 676 p = string.buffer.start;
681 677 while (*p != (int) nul_char) {
682 678 wchar_t chr;
683 679
684 680 /*
685 681 * First skip over any white space and append
686 682 * that to the destination string.
687 683 */
688 684 block_start = p;
689 685 while ((*p != (int) nul_char) && iswspace(*p)) {
690 686 p++;
691 687 }
692 688 append_string(block_start,
693 689 destination,
694 690 p - block_start);
695 691 /* Then find the end of the next word. */
696 692 block_start = p;
697 693 while ((*p != (int) nul_char) && !iswspace(*p)) {
698 694 p++;
699 695 }
700 696 /* If we cant find another word we are done */
701 697 if (block_start == p) {
702 698 break;
703 699 }
704 700 /* Then apply the transforms to the word */
705 701 INIT_STRING_FROM_STACK(extracted, extracted_string);
706 702 switch (extraction) {
707 703 case dir_extract:
708 704 /*
709 705 * $(@D) type transform. Extract the
710 706 * path from the word. Deliver "." if
711 707 * none is found.
712 708 */
713 709 if (p != NULL) {
714 710 chr = *p;
715 711 *p = (int) nul_char;
716 712 }
717 713 eq = (wchar_t *) wsrchr(block_start, (int) slash_char);
718 714 if (p != NULL) {
719 715 *p = chr;
720 716 }
721 717 if ((eq == NULL) || (eq > p)) {
722 718 MBSTOWCS(wcs_buffer, ".");
723 719 append_string(wcs_buffer, &extracted, 1);
724 720 } else {
725 721 append_string(block_start,
726 722 &extracted,
727 723 eq - block_start);
728 724 }
729 725 break;
730 726 case file_extract:
731 727 /*
732 728 * $(@F) type transform. Remove the path
733 729 * from the word if any.
734 730 */
735 731 if (p != NULL) {
736 732 chr = *p;
737 733 *p = (int) nul_char;
738 734 }
739 735 eq = (wchar_t *) wsrchr(block_start, (int) slash_char);
740 736 if (p != NULL) {
741 737 *p = chr;
742 738 }
743 739 if ((eq == NULL) || (eq > p)) {
744 740 append_string(block_start,
745 741 &extracted,
746 742 p - block_start);
747 743 } else {
748 744 append_string(eq + 1,
749 745 &extracted,
750 746 p - eq - 1);
751 747 }
752 748 break;
753 749 case no_extract:
754 750 append_string(block_start,
755 751 &extracted,
756 752 p - block_start);
757 753 break;
758 754 }
759 755 switch (replacement) {
760 756 case suffix_replace:
761 757 /*
762 758 * $(FOO:.o=.c) type transform.
763 759 * Maybe replace the tail of the word.
764 760 */
765 761 if (((extracted.text.p -
766 762 extracted.buffer.start) >=
767 763 left_tail_len) &&
768 764 IS_WEQUALN(extracted.text.p - left_tail_len,
769 765 left_tail,
770 766 left_tail_len)) {
771 767 append_string(extracted.buffer.start,
772 768 destination,
773 769 (extracted.text.p -
774 770 extracted.buffer.start)
775 771 - left_tail_len);
776 772 append_string(right_tail,
777 773 destination,
778 774 FIND_LENGTH);
779 775 } else {
780 776 append_string(extracted.buffer.start,
781 777 destination,
782 778 FIND_LENGTH);
783 779 }
784 780 break;
785 781 case pattern_replace:
786 782 /* $(X:a%b=c%d) type transform. */
787 783 if (((extracted.text.p -
788 784 extracted.buffer.start) >=
789 785 left_head_len+left_tail_len) &&
790 786 IS_WEQUALN(left_head,
791 787 extracted.buffer.start,
792 788 left_head_len) &&
793 789 IS_WEQUALN(left_tail,
794 790 extracted.text.p - left_tail_len,
795 791 left_tail_len)) {
796 792 i = 0;
797 793 while (right_hand[i] != NULL) {
798 794 append_string(right_hand[i],
799 795 destination,
800 796 FIND_LENGTH);
801 797 i++;
802 798 if (right_hand[i] != NULL) {
803 799 append_string(extracted.buffer.
804 800 start +
805 801 left_head_len,
806 802 destination,
807 803 (extracted.text.p - extracted.buffer.start)-left_head_len-left_tail_len);
808 804 }
809 805 }
810 806 } else {
811 807 append_string(extracted.buffer.start,
812 808 destination,
813 809 FIND_LENGTH);
814 810 }
815 811 break;
816 812 case no_replace:
817 813 append_string(extracted.buffer.start,
818 814 destination,
819 815 FIND_LENGTH);
820 816 break;
821 817 case sh_replace:
822 818 break;
823 819 }
824 820 }
825 821 if (string.free_after_use) {
826 822 retmem(string.buffer.start);
827 823 }
828 824 } else {
829 825 /*
830 826 * This is for the case when the macro name did not
831 827 * specify transforms.
832 828 */
833 829 if (!strncmp(name->string_mb, NOCATGETS("GET"), 3)) {
834 830 dollarget_seen = true;
835 831 }
836 832 dollarless_flag = false;
837 833 if (!strncmp(name->string_mb, "<", 1) &&
838 834 dollarget_seen) {
839 835 dollarless_flag = true;
840 836 dollarget_seen = false;
841 837 }
842 838 expand_value_with_daemon(name, macro, destination, cmd);
843 839 }
844 840 exit:
845 841 if(left_tail) {
846 842 retmem(left_tail);
847 843 }
848 844 if(right_tail) {
849 845 retmem(right_tail);
850 846 }
851 847 if(left_head) {
852 848 retmem(left_head);
853 849 }
854 850 i = 0;
855 851 while (right_hand[i] != NULL) {
856 852 retmem(right_hand[i]);
857 853 i++;
858 854 }
859 855 *destination->text.p = (int) nul_char;
860 856 destination->text.end = destination->text.p;
861 857 }
862 858
863 859 static void
864 860 add_macro_to_global_list(Name macro_to_add)
865 861 {
866 862 Macro_list new_macro;
867 863 Macro_list macro_on_list;
868 864 char *name_on_list = (char*)NULL;
869 865 char *name_to_add = macro_to_add->string_mb;
870 866 char *value_on_list = (char*)NULL;
871 867 char *value_to_add = (char*)NULL;
872 868
873 869 if (macro_to_add->prop->body.macro.value != NULL) {
874 870 value_to_add = macro_to_add->prop->body.macro.value->string_mb;
875 871 } else {
876 872 value_to_add = "";
877 873 }
878 874
879 875 /*
880 876 * Check if this macro is already on list, if so, do nothing
881 877 */
882 878 for (macro_on_list = cond_macro_list;
883 879 macro_on_list != NULL;
884 880 macro_on_list = macro_on_list->next) {
885 881
886 882 name_on_list = macro_on_list->macro_name;
887 883 value_on_list = macro_on_list->value;
888 884
889 885 if (IS_EQUAL(name_on_list, name_to_add)) {
890 886 if (IS_EQUAL(value_on_list, value_to_add)) {
891 887 return;
892 888 }
893 889 }
894 890 }
895 891 new_macro = (Macro_list) malloc(sizeof(Macro_list_rec));
896 892 new_macro->macro_name = strdup(name_to_add);
897 893 new_macro->value = strdup(value_to_add);
898 894 new_macro->next = cond_macro_list;
899 895 cond_macro_list = new_macro;
900 896 }
901 897
902 898 /*
903 899 * init_arch_macros(void)
904 900 *
905 901 * Set the magic macros TARGET_ARCH, HOST_ARCH,
906 902 *
907 903 * Parameters:
908 904 *
909 905 * Global variables used:
910 906 * host_arch Property for magic macro HOST_ARCH
911 907 * target_arch Property for magic macro TARGET_ARCH
912 908 *
913 909 * Return value:
914 910 * The function does not return a value, but can
915 911 * call fatal() in case of error.
916 912 */
917 913 static void
918 914 init_arch_macros(void)
919 915 {
920 916 String_rec result_string;
921 917 wchar_t wc_buf[STRING_BUFFER_LENGTH];
922 918 char mb_buf[STRING_BUFFER_LENGTH];
923 919 FILE *pipe;
924 920 Name value;
925 921 int set_host, set_target;
926 922 #ifdef NSE
927 923 Property macro;
928 924 #endif
929 925 #if defined(linux)
930 926 const char *mach_command = NOCATGETS("/bin/uname -p");
931 927 #else
932 928 const char *mach_command = NOCATGETS("/bin/mach");
933 929 #endif
934 930
935 931 set_host = (get_prop(host_arch->prop, macro_prop) == NULL);
936 932 set_target = (get_prop(target_arch->prop, macro_prop) == NULL);
937 933
938 934 if (set_host || set_target) {
939 935 INIT_STRING_FROM_STACK(result_string, wc_buf);
940 936 append_char((int) hyphen_char, &result_string);
941 937
942 938 if ((pipe = popen(mach_command, "r")) == NULL) {
943 939 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 185, "Execute of %s failed"), mach_command);
944 940 }
945 941 while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
946 942 MBSTOWCS(wcs_buffer, mb_buf);
947 943 append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
948 944 }
949 945 if (pclose(pipe) != 0) {
950 946 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 186, "Execute of %s failed"), mach_command);
951 947 }
952 948
953 949 value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
954 950
955 951 #ifdef NSE
956 952 macro = setvar_daemon(host_arch, value, false, no_daemon, true, 0);
957 953 macro->body.macro.imported= true;
958 954 macro = setvar_daemon(target_arch, value, false, no_daemon, true, 0);
959 955 macro->body.macro.imported= true;
960 956 #else
961 957 if (set_host) {
962 958 (void) setvar_daemon(host_arch, value, false, no_daemon, true, 0);
963 959 }
964 960 if (set_target) {
965 961 (void) setvar_daemon(target_arch, value, false, no_daemon, true, 0);
966 962 }
967 963 #endif
968 964 }
969 965 }
970 966
971 967 /*
972 968 * init_mach_macros(void)
973 969 *
974 970 * Set the magic macros TARGET_MACH, HOST_MACH,
975 971 *
976 972 * Parameters:
977 973 *
978 974 * Global variables used:
979 975 * host_mach Property for magic macro HOST_MACH
980 976 * target_mach Property for magic macro TARGET_MACH
981 977 *
982 978 * Return value:
983 979 * The function does not return a value, but can
984 980 * call fatal() in case of error.
985 981 */
986 982 static void
987 983 init_mach_macros(void)
988 984 {
989 985 String_rec result_string;
990 986 wchar_t wc_buf[STRING_BUFFER_LENGTH];
991 987 char mb_buf[STRING_BUFFER_LENGTH];
992 988 FILE *pipe;
993 989 Name value;
994 990 int set_host, set_target;
995 991 const char *arch_command = NOCATGETS("/bin/arch");
996 992
997 993 set_host = (get_prop(host_mach->prop, macro_prop) == NULL);
998 994 set_target = (get_prop(target_mach->prop, macro_prop) == NULL);
999 995
1000 996 if (set_host || set_target) {
1001 997 INIT_STRING_FROM_STACK(result_string, wc_buf);
1002 998 append_char((int) hyphen_char, &result_string);
1003 999
1004 1000 if ((pipe = popen(arch_command, "r")) == NULL) {
1005 1001 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 183, "Execute of %s failed"), arch_command);
1006 1002 }
1007 1003 while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
1008 1004 MBSTOWCS(wcs_buffer, mb_buf);
1009 1005 append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
1010 1006 }
1011 1007 if (pclose(pipe) != 0) {
1012 1008 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 184, "Execute of %s failed"), arch_command);
1013 1009 }
1014 1010
1015 1011 value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
1016 1012
1017 1013 if (set_host) {
1018 1014 (void) setvar_daemon(host_mach, value, false, no_daemon, true, 0);
1019 1015 }
1020 1016 if (set_target) {
1021 1017 (void) setvar_daemon(target_mach, value, false, no_daemon, true, 0);
1022 1018 }
1023 1019 }
1024 1020 }
1025 1021
1026 1022 /*
1027 1023 * expand_value_with_daemon(name, macro, destination, cmd)
1028 1024 *
1029 1025 * Checks for daemons and then maybe calls expand_value().
1030 1026 *
1031 1027 * Parameters:
1032 1028 * name Name of the macro (Added by the NSE)
1033 1029 * macro The property block with the value to expand
1034 1030 * destination Where the result should be deposited
1035 1031 * cmd If we are evaluating a command line we
1036 1032 * turn \ quoting off
1037 1033 *
1038 1034 * Global variables used:
1039 1035 */
1040 1036 static void
1041 1037 #ifdef NSE
1042 1038 expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd)
1043 1039 #else
1044 1040 expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd)
1045 1041 #endif
1046 1042 {
1047 1043 register Chain chain;
1048 1044
1049 1045 #ifdef NSE
1050 1046 if (reading_dependencies) {
1051 1047 /*
1052 1048 * Processing the dependencies themselves
1053 1049 */
1054 1050 depvar_dep_macro_used(name);
1055 1051 } else {
1056 1052 /*
1057 1053 * Processing the rules for the targets
1058 1054 * the nse_watch_vars flags chokes off most
1059 1055 * checks. it is true only when processing
1060 1056 * the output from a recursive make run
1061 1057 * which is all we are interested in here.
1062 1058 */
1063 1059 if (nse_watch_vars) {
1064 1060 depvar_rule_macro_used(name);
1065 1061 }
1066 1062 }
1067 1063 #endif
1068 1064
1069 1065 switch (macro->body.macro.daemon) {
1070 1066 case no_daemon:
1071 1067 if (!svr4 && !posix) {
1072 1068 expand_value(macro->body.macro.value, destination, cmd);
1073 1069 } else {
1074 1070 if (dollarless_flag && tilde_rule) {
1075 1071 expand_value(dollarless_value, destination, cmd);
1076 1072 dollarless_flag = false;
1077 1073 tilde_rule = false;
1078 1074 } else {
1079 1075 expand_value(macro->body.macro.value, destination, cmd);
1080 1076 }
1081 1077 }
1082 1078 return;
1083 1079 case chain_daemon:
1084 1080 /* If this is a $? value we call the daemon to translate the */
1085 1081 /* list of names to a string */
1086 1082 for (chain = (Chain) macro->body.macro.value;
1087 1083 chain != NULL;
1088 1084 chain = chain->next) {
1089 1085 APPEND_NAME(chain->name,
1090 1086 destination,
1091 1087 (int) chain->name->hash.length);
1092 1088 if (chain->next != NULL) {
1093 1089 append_char((int) space_char, destination);
1094 1090 }
1095 1091 }
1096 1092 return;
1097 1093 }
1098 1094 }
1099 1095
1100 1096 /*
1101 1097 * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
1102 1098 */
1103 1099 char *sunpro_dependencies_buf = NULL;
1104 1100 char *sunpro_dependencies_oldbuf = NULL;
1105 1101 int sunpro_dependencies_buf_size = 0;
1106 1102
1107 1103 /*
1108 1104 * setvar_daemon(name, value, append, daemon, strip_trailing_spaces)
1109 1105 *
1110 1106 * Set a macro value, possibly supplying a daemon to be used
1111 1107 * when referencing the value.
1112 1108 *
1113 1109 * Return value:
1114 1110 * The property block with the new value
1115 1111 *
1116 1112 * Parameters:
1117 1113 * name Name of the macro to set
1118 1114 * value The value to set
1119 1115 * append Should we reset or append to the current value?
1120 1116 * daemon Special treatment when reading the value
1121 1117 * strip_trailing_spaces from the end of value->string
1122 1118 * debug_level Indicates how much tracing we should do
1123 1119 *
1124 1120 * Global variables used:
1125 1121 * makefile_type Used to check if we should enforce read only
1126 1122 * path_name The Name "PATH", compared against
1127 1123 * virtual_root The Name "VIRTUAL_ROOT", compared against
1128 1124 * vpath_defined Set if the macro VPATH is set
1129 1125 * vpath_name The Name "VPATH", compared against
1130 1126 * envvar A list of environment vars with $ in value
1131 1127 */
1132 1128 Property
1133 1129 setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level)
1134 1130 {
1135 1131 register Property macro = maybe_append_prop(name, macro_prop);
1136 1132 register Property macro_apx = get_prop(name->prop, macro_append_prop);
1137 1133 int length = 0;
1138 1134 String_rec destination;
1139 1135 wchar_t buffer[STRING_BUFFER_LENGTH];
1140 1136 register Chain chain;
1141 1137 Name val;
1142 1138 wchar_t *val_string = (wchar_t*)NULL;
1143 1139 Wstring wcb;
1144 1140
1145 1141 #ifdef NSE
1146 1142 macro->body.macro.imported = false;
1147 1143 #endif
1148 1144
1149 1145 if ((makefile_type != reading_nothing) &&
1150 1146 macro->body.macro.read_only) {
1151 1147 return macro;
1152 1148 }
1153 1149 /* Strip spaces from the end of the value */
1154 1150 if (daemon == no_daemon) {
1155 1151 if(value != NULL) {
1156 1152 wcb.init(value);
1157 1153 length = wcb.length();
1158 1154 val_string = wcb.get_string();
1159 1155 }
1160 1156 if ((length > 0) && iswspace(val_string[length-1])) {
1161 1157 INIT_STRING_FROM_STACK(destination, buffer);
1162 1158 buffer[0] = 0;
1163 1159 append_string(val_string, &destination, length);
1164 1160 if (strip_trailing_spaces) {
1165 1161 while ((length > 0) &&
1166 1162 iswspace(destination.buffer.start[length-1])) {
1167 1163 destination.buffer.start[--length] = 0;
1168 1164 }
1169 1165 }
1170 1166 value = GETNAME(destination.buffer.start, FIND_LENGTH);
1171 1167 }
1172 1168 }
1173 1169
1174 1170 if(macro_apx != NULL) {
1175 1171 val = macro_apx->body.macro_appendix.value;
1176 1172 } else {
1177 1173 val = macro->body.macro.value;
1178 1174 }
1179 1175
1180 1176 if (append) {
1181 1177 /*
1182 1178 * If we are appending, we just tack the new value after
1183 1179 * the old one with a space in between.
1184 1180 */
1185 1181 INIT_STRING_FROM_STACK(destination, buffer);
1186 1182 buffer[0] = 0;
1187 1183 if ((macro != NULL) && (val != NULL)) {
1188 1184 APPEND_NAME(val,
1189 1185 &destination,
1190 1186 (int) val->hash.length);
1191 1187 if (value != NULL) {
1192 1188 wcb.init(value);
1193 1189 if(wcb.length() > 0) {
1194 1190 MBTOWC(wcs_buffer, " ");
1195 1191 append_char(wcs_buffer[0], &destination);
1196 1192 }
1197 1193 }
1198 1194 }
1199 1195 if (value != NULL) {
1200 1196 APPEND_NAME(value,
1201 1197 &destination,
1202 1198 (int) value->hash.length);
1203 1199 }
1204 1200 value = GETNAME(destination.buffer.start, FIND_LENGTH);
1205 1201 wcb.init(value);
1206 1202 if (destination.free_after_use) {
1207 1203 retmem(destination.buffer.start);
1208 1204 }
1209 1205 }
1210 1206
1211 1207 /* Debugging trace */
1212 1208 if (debug_level > 1) {
1213 1209 if (value != NULL) {
1214 1210 switch (daemon) {
1215 1211 case chain_daemon:
1216 1212 (void) printf("%s =", name->string_mb);
1217 1213 for (chain = (Chain) value;
1218 1214 chain != NULL;
1219 1215 chain = chain->next) {
1220 1216 (void) printf(" %s", chain->name->string_mb);
1221 1217 }
1222 1218 (void) printf("\n");
1223 1219 break;
1224 1220 case no_daemon:
1225 1221 (void) printf("%s= %s\n",
1226 1222 name->string_mb,
1227 1223 value->string_mb);
1228 1224 break;
1229 1225 }
1230 1226 } else {
1231 1227 (void) printf("%s =\n", name->string_mb);
1232 1228 }
1233 1229 }
1234 1230 /* Set the new values in the macro property block */
1235 1231 /**/
1236 1232 if(macro_apx != NULL) {
1237 1233 macro_apx->body.macro_appendix.value = value;
1238 1234 INIT_STRING_FROM_STACK(destination, buffer);
1239 1235 buffer[0] = 0;
1240 1236 if (value != NULL) {
1241 1237 APPEND_NAME(value,
1242 1238 &destination,
1243 1239 (int) value->hash.length);
1244 1240 if (macro_apx->body.macro_appendix.value_to_append != NULL) {
1245 1241 MBTOWC(wcs_buffer, " ");
1246 1242 append_char(wcs_buffer[0], &destination);
1247 1243 }
1248 1244 }
1249 1245 if (macro_apx->body.macro_appendix.value_to_append != NULL) {
1250 1246 APPEND_NAME(macro_apx->body.macro_appendix.value_to_append,
1251 1247 &destination,
1252 1248 (int) macro_apx->body.macro_appendix.value_to_append->hash.length);
1253 1249 }
1254 1250 value = GETNAME(destination.buffer.start, FIND_LENGTH);
1255 1251 if (destination.free_after_use) {
1256 1252 retmem(destination.buffer.start);
1257 1253 }
1258 1254 }
1259 1255 /**/
1260 1256 macro->body.macro.value = value;
1261 1257 macro->body.macro.daemon = daemon;
1262 1258 /*
1263 1259 * If the user changes the VIRTUAL_ROOT, we need to flush
1264 1260 * the vroot package cache.
1265 1261 */
1266 1262 if (name == path_name) {
1267 1263 flush_path_cache();
1268 1264 }
1269 1265 if (name == virtual_root) {
1270 1266 flush_vroot_cache();
1271 1267 }
1272 1268 /* If this sets the VPATH we remember that */
1273 1269 if ((name == vpath_name) &&
1274 1270 (value != NULL) &&
1275 1271 (value->hash.length > 0)) {
1276 1272 vpath_defined = true;
1277 1273 }
1278 1274 /*
1279 1275 * For environment variables we also set the
1280 1276 * environment value each time.
1281 1277 */
1282 1278 if (macro->body.macro.exported) {
1283 1279 static char *env;
1284 1280
1285 1281 #ifdef DISTRIBUTED
1286 1282 if (!reading_environment && (value != NULL)) {
1287 1283 #else
1288 1284 if (!reading_environment && (value != NULL) && value->dollar) {
1289 1285 #endif
1290 1286 Envvar p;
1291 1287
1292 1288 for (p = envvar; p != NULL; p = p->next) {
1293 1289 if (p->name == name) {
1294 1290 p->value = value;
1295 1291 p->already_put = false;
1296 1292 goto found_it;
1297 1293 }
1298 1294 }
1299 1295 p = ALLOC(Envvar);
1300 1296 p->name = name;
1301 1297 p->value = value;
1302 1298 p->next = envvar;
1303 1299 p->env_string = NULL;
1304 1300 p->already_put = false;
1305 1301 envvar = p;
1306 1302 found_it:;
1307 1303 #ifdef DISTRIBUTED
1308 1304 }
1309 1305 if (reading_environment || (value == NULL) || !value->dollar) {
1310 1306 #else
1311 1307 } else {
1312 1308 #endif
1313 1309 length = 2 + strlen(name->string_mb);
1314 1310 if (value != NULL) {
1315 1311 length += strlen(value->string_mb);
1316 1312 }
1317 1313 Property env_prop = maybe_append_prop(name, env_mem_prop);
1318 1314 /*
1319 1315 * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
1320 1316 */
1321 1317 if (!strncmp(name->string_mb, NOCATGETS("SUNPRO_DEPENDENCIES"), 19)) {
1322 1318 if (length >= sunpro_dependencies_buf_size) {
1323 1319 sunpro_dependencies_buf_size=length*2;
1324 1320 if (sunpro_dependencies_buf_size < 4096)
1325 1321 sunpro_dependencies_buf_size = 4096; // Default minimum size
1326 1322 if (sunpro_dependencies_buf)
1327 1323 sunpro_dependencies_oldbuf = sunpro_dependencies_buf;
1328 1324 sunpro_dependencies_buf=getmem(sunpro_dependencies_buf_size);
1329 1325 }
1330 1326 env = sunpro_dependencies_buf;
1331 1327 } else {
1332 1328 env = getmem(length);
1333 1329 }
1334 1330 env_alloc_num++;
1335 1331 env_alloc_bytes += length;
1336 1332 (void) sprintf(env,
1337 1333 "%s=%s",
1338 1334 name->string_mb,
1339 1335 value == NULL ?
1340 1336 "" : value->string_mb);
1341 1337 (void) putenv(env);
1342 1338 env_prop->body.env_mem.value = env;
1343 1339 if (sunpro_dependencies_oldbuf) {
1344 1340 /* Return old buffer */
1345 1341 retmem_mb(sunpro_dependencies_oldbuf);
1346 1342 sunpro_dependencies_oldbuf = NULL;
1347 1343 }
1348 1344 }
1349 1345 }
1350 1346 if (name == target_arch) {
1351 1347 Name ha = getvar(host_arch);
1352 1348 Name ta = getvar(target_arch);
1353 1349 Name vr = getvar(virtual_root);
1354 1350 int length;
1355 1351 wchar_t *new_value;
1356 1352 wchar_t *old_vr;
1357 1353 Boolean new_value_allocated = false;
1358 1354
1359 1355 Wstring ha_str(ha);
1360 1356 Wstring ta_str(ta);
1361 1357 Wstring vr_str(vr);
1362 1358
1363 1359 wchar_t * wcb_ha = ha_str.get_string();
1364 1360 wchar_t * wcb_ta = ta_str.get_string();
1365 1361 wchar_t * wcb_vr = vr_str.get_string();
1366 1362
1367 1363 length = 32 +
1368 1364 wslen(wcb_ha) +
1369 1365 wslen(wcb_ta) +
1370 1366 wslen(wcb_vr);
1371 1367 old_vr = wcb_vr;
1372 1368 MBSTOWCS(wcs_buffer, NOCATGETS("/usr/arch/"));
1373 1369 if (IS_WEQUALN(old_vr,
1374 1370 wcs_buffer,
1375 1371 wslen(wcs_buffer))) {
1376 1372 old_vr = (wchar_t *) wschr(old_vr, (int) colon_char) + 1;
1377 1373 }
1378 1374 if ( (ha == ta) || (wslen(wcb_ta) == 0) ) {
1379 1375 new_value = old_vr;
1380 1376 } else {
1381 1377 new_value = ALLOC_WC(length);
1382 1378 new_value_allocated = true;
1383 1379 WCSTOMBS(mbs_buffer, old_vr);
1384 1380 #if !defined(linux)
1385 1381 (void) wsprintf(new_value,
1386 1382 NOCATGETS("/usr/arch/%s/%s:%s"),
1387 1383 ha->string_mb + 1,
1388 1384 ta->string_mb + 1,
1389 1385 mbs_buffer);
1390 1386 #else
1391 1387 char * mbs_new_value = (char *)getmem(length);
1392 1388 (void) sprintf(mbs_new_value,
1393 1389 NOCATGETS("/usr/arch/%s/%s:%s"),
1394 1390 ha->string_mb + 1,
1395 1391 ta->string_mb + 1,
1396 1392 mbs_buffer);
1397 1393 MBSTOWCS(new_value, mbs_new_value);
1398 1394 retmem_mb(mbs_new_value);
1399 1395 #endif
1400 1396 }
1401 1397 if (new_value[0] != 0) {
1402 1398 (void) setvar_daemon(virtual_root,
1403 1399 GETNAME(new_value, FIND_LENGTH),
1404 1400 false,
1405 1401 no_daemon,
1406 1402 true,
1407 1403 debug_level);
1408 1404 }
1409 1405 if (new_value_allocated) {
1410 1406 retmem(new_value);
1411 1407 }
1412 1408 }
1413 1409 return macro;
1414 1410 }
↓ open down ↓ |
1375 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX