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