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