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