22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 /*
28 * macro.cc
29 *
30 * Handle expansion of make macros
31 */
32
33 /*
34 * Included files
35 */
36 #include <mksh/dosys.h> /* sh_command2string() */
37 #include <mksh/i18n.h> /* get_char_semantics_value() */
38 #include <mksh/macro.h>
39 #include <mksh/misc.h> /* retmem() */
40 #include <mksh/read.h> /* get_next_block_fn() */
41
42 #include <widec.h>
43 #include <libintl.h>
44
45 /*
46 * File table of contents
47 */
48 static void add_macro_to_global_list(Name macro_to_add);
49 static void expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd);
50
51 static void init_arch_macros(void);
52 static void init_mach_macros(void);
53 static Boolean init_arch_done = false;
54 static Boolean init_mach_done = false;
55
56
57 long env_alloc_num = 0;
58 long env_alloc_bytes = 0;
59
60 /*
61 * getvar(name)
62 *
138 if (!value->dollar) {
139 /*
140 * If the value we are expanding does not contain
141 * any $, we don't have to parse it.
142 */
143 APPEND_NAME(value,
144 destination,
145 (int) value->hash.length
146 );
147 destination->text.end = destination->text.p;
148 return;
149 }
150
151 if (value->being_expanded) {
152 fatal_reader_mksh(gettext("Loop detected when expanding macro value `%s'"),
153 value->string_mb);
154 }
155 value->being_expanded = true;
156 /* Setup the structure we read from */
157 Wstring vals(value);
158 sourceb.string.text.p = sourceb.string.buffer.start = wsdup(vals.get_string());
159 sourceb.string.free_after_use = true;
160 sourceb.string.text.end =
161 sourceb.string.buffer.end =
162 sourceb.string.text.p + value->hash.length;
163 sourceb.previous = NULL;
164 sourceb.fd = -1;
165 sourceb.inp_buf =
166 sourceb.inp_buf_ptr =
167 sourceb.inp_buf_end = NULL;
168 sourceb.error_converting = false;
169 /* Lift some pointers from the struct to local register variables */
170 CACHE_SOURCE(0);
171 /* We parse the string in segments */
172 /* We read chars until we find a $, then we append what we have read so far */
173 /* (since last $ processing) to the destination. When we find a $ we call */
174 /* expand_macro() and let it expand that particular $ reference into dest */
175 block_start = source_p;
176 quote_seen = 0;
177 for (; 1; source_p++) {
178 switch (GET_CHAR()) {
442 /* First check if we have a $(@D) type translation. */
443 if ((get_char_semantics_value(string.buffer.start[0]) &
444 (int) special_macro_sem) &&
445 (string.text.p - string.buffer.start >= 2) &&
446 ((string.buffer.start[1] == 'D') ||
447 (string.buffer.start[1] == 'F'))) {
448 switch (string.buffer.start[1]) {
449 case 'D':
450 extraction = dir_extract;
451 break;
452 case 'F':
453 extraction = file_extract;
454 break;
455 default:
456 WCSTOMBS(mbs_buffer, string.buffer.start);
457 fatal_reader_mksh(gettext("Illegal macro reference `%s'"),
458 mbs_buffer);
459 }
460 /* Internalize the macro name using the first char only. */
461 name = GETNAME(string.buffer.start, 1);
462 (void) wscpy(string.buffer.start, string.buffer.start + 2);
463 }
464 /* Check for other kinds of translations. */
465 if ((colon = (wchar_t *) wschr(string.buffer.start,
466 (int) colon_char)) != NULL) {
467 /*
468 * We have a $(FOO:.c=.o) type translation.
469 * Get the name of the macro proper.
470 */
471 if (name == NULL) {
472 name = GETNAME(string.buffer.start,
473 colon - string.buffer.start);
474 }
475 /* Pickup all the translations. */
476 if (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell)) {
477 replacement = sh_replace;
478 } else if ((svr4) ||
479 ((percent = (wchar_t *) wschr(colon + 1,
480 (int) percent_char)) == NULL)) {
481 while (colon != NULL) {
482 if ((eq = (wchar_t *) wschr(colon + 1,
483 (int) equal_char)) == NULL) {
484 fatal_reader_mksh(gettext("= missing from replacement macro reference"));
485 }
486 left_tail_len = eq - colon - 1;
487 if(left_tail) {
488 retmem(left_tail);
489 }
490 left_tail = ALLOC_WC(left_tail_len + 1);
491 (void) wsncpy(left_tail,
492 colon + 1,
493 eq - colon - 1);
494 left_tail[eq - colon - 1] = (int) nul_char;
495 replacement = suffix_replace;
496 if ((colon = (wchar_t *) wschr(eq + 1,
497 (int) colon_char)) != NULL) {
498 tmp_len = colon - eq;
499 if(right_tail) {
500 retmem(right_tail);
501 }
502 right_tail = ALLOC_WC(tmp_len);
503 (void) wsncpy(right_tail,
504 eq + 1,
505 colon - eq - 1);
506 right_tail[colon - eq - 1] =
507 (int) nul_char;
508 } else {
509 if(right_tail) {
510 retmem(right_tail);
511 }
512 right_tail = ALLOC_WC(wslen(eq) + 1);
513 (void) wscpy(right_tail, eq + 1);
514 }
515 }
516 } else {
517 if ((eq = (wchar_t *) wschr(colon + 1,
518 (int) equal_char)) == NULL) {
519 fatal_reader_mksh(gettext("= missing from replacement macro reference"));
520 }
521 if ((percent = (wchar_t *) wschr(colon + 1,
522 (int) percent_char)) == NULL) {
523 fatal_reader_mksh(gettext("%% missing from replacement macro reference"));
524 }
525 if (eq < percent) {
526 fatal_reader_mksh(gettext("%% missing from replacement macro reference"));
527 }
528
529 if (percent > (colon + 1)) {
530 tmp_len = percent - colon;
531 if(left_head) {
532 retmem(left_head);
533 }
534 left_head = ALLOC_WC(tmp_len);
535 (void) wsncpy(left_head,
536 colon + 1,
537 percent - colon - 1);
538 left_head[percent-colon-1] = (int) nul_char;
539 left_head_len = percent-colon-1;
540 } else {
541 left_head = NULL;
542 left_head_len = 0;
543 }
544
545 if (eq > percent+1) {
546 tmp_len = eq - percent;
547 if(left_tail) {
548 retmem(left_tail);
549 }
550 left_tail = ALLOC_WC(tmp_len);
551 (void) wsncpy(left_tail,
552 percent + 1,
553 eq - percent - 1);
554 left_tail[eq-percent-1] = (int) nul_char;
555 left_tail_len = eq-percent-1;
556 } else {
557 left_tail = NULL;
558 left_tail_len = 0;
559 }
560
561 if ((percent = (wchar_t *) wschr(++eq,
562 (int) percent_char)) == NULL) {
563
564 right_hand[0] = ALLOC_WC(wslen(eq) + 1);
565 right_hand[1] = NULL;
566 (void) wscpy(right_hand[0], eq);
567 } else {
568 i = 0;
569 do {
570 right_hand[i] = ALLOC_WC(percent-eq+1);
571 (void) wsncpy(right_hand[i],
572 eq,
573 percent - eq);
574 right_hand[i][percent-eq] =
575 (int) nul_char;
576 if (i++ >= VSIZEOF(right_hand)) {
577 fatal_mksh(gettext("Too many %% in pattern"));
578 }
579 eq = percent + 1;
580 if (eq[0] == (int) nul_char) {
581 MBSTOWCS(wcs_buffer, "");
582 right_hand[i] = (wchar_t *) wsdup(wcs_buffer);
583 i++;
584 break;
585 }
586 } while ((percent = (wchar_t *) wschr(eq, (int) percent_char)) != NULL);
587 if (eq[0] != (int) nul_char) {
588 right_hand[i] = ALLOC_WC(wslen(eq) + 1);
589 (void) wscpy(right_hand[i], eq);
590 i++;
591 }
592 right_hand[i] = NULL;
593 }
594 replacement = pattern_replace;
595 }
596 }
597 if (name == NULL) {
598 /*
599 * No translations found.
600 * Use the whole string as the macro name.
601 */
602 name = GETNAME(string.buffer.start,
603 string.text.p - string.buffer.start);
604 }
605 if (string.free_after_use) {
606 retmem(string.buffer.start);
607 }
608 if (name == make) {
609 make_word_mentioned = true;
679 while ((*p != (int) nul_char) && !iswspace(*p)) {
680 p++;
681 }
682 /* If we cant find another word we are done */
683 if (block_start == p) {
684 break;
685 }
686 /* Then apply the transforms to the word */
687 INIT_STRING_FROM_STACK(extracted, extracted_string);
688 switch (extraction) {
689 case dir_extract:
690 /*
691 * $(@D) type transform. Extract the
692 * path from the word. Deliver "." if
693 * none is found.
694 */
695 if (p != NULL) {
696 chr = *p;
697 *p = (int) nul_char;
698 }
699 eq = (wchar_t *) wsrchr(block_start, (int) slash_char);
700 if (p != NULL) {
701 *p = chr;
702 }
703 if ((eq == NULL) || (eq > p)) {
704 MBSTOWCS(wcs_buffer, ".");
705 append_string(wcs_buffer, &extracted, 1);
706 } else {
707 append_string(block_start,
708 &extracted,
709 eq - block_start);
710 }
711 break;
712 case file_extract:
713 /*
714 * $(@F) type transform. Remove the path
715 * from the word if any.
716 */
717 if (p != NULL) {
718 chr = *p;
719 *p = (int) nul_char;
720 }
721 eq = (wchar_t *) wsrchr(block_start, (int) slash_char);
722 if (p != NULL) {
723 *p = chr;
724 }
725 if ((eq == NULL) || (eq > p)) {
726 append_string(block_start,
727 &extracted,
728 p - block_start);
729 } else {
730 append_string(eq + 1,
731 &extracted,
732 p - eq - 1);
733 }
734 break;
735 case no_extract:
736 append_string(block_start,
737 &extracted,
738 p - block_start);
739 break;
740 }
741 switch (replacement) {
902 String_rec result_string;
903 wchar_t wc_buf[STRING_BUFFER_LENGTH];
904 char mb_buf[STRING_BUFFER_LENGTH];
905 FILE *pipe;
906 Name value;
907 int set_host, set_target;
908 const char *mach_command = "/bin/mach";
909
910 set_host = (get_prop(host_arch->prop, macro_prop) == NULL);
911 set_target = (get_prop(target_arch->prop, macro_prop) == NULL);
912
913 if (set_host || set_target) {
914 INIT_STRING_FROM_STACK(result_string, wc_buf);
915 append_char((int) hyphen_char, &result_string);
916
917 if ((pipe = popen(mach_command, "r")) == NULL) {
918 fatal_mksh(gettext("Execute of %s failed"), mach_command);
919 }
920 while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
921 MBSTOWCS(wcs_buffer, mb_buf);
922 append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
923 }
924 if (pclose(pipe) != 0) {
925 fatal_mksh(gettext("Execute of %s failed"), mach_command);
926 }
927
928 value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
929
930 if (set_host) {
931 (void) setvar_daemon(host_arch, value, false, no_daemon, true, 0);
932 }
933 if (set_target) {
934 (void) setvar_daemon(target_arch, value, false, no_daemon, true, 0);
935 }
936 }
937 }
938
939 /*
940 * init_mach_macros(void)
941 *
942 * Set the magic macros TARGET_MACH, HOST_MACH,
943 *
944 * Parameters:
945 *
946 * Global variables used:
947 * host_mach Property for magic macro HOST_MACH
948 * target_mach Property for magic macro TARGET_MACH
957 String_rec result_string;
958 wchar_t wc_buf[STRING_BUFFER_LENGTH];
959 char mb_buf[STRING_BUFFER_LENGTH];
960 FILE *pipe;
961 Name value;
962 int set_host, set_target;
963 const char *arch_command = "/bin/arch";
964
965 set_host = (get_prop(host_mach->prop, macro_prop) == NULL);
966 set_target = (get_prop(target_mach->prop, macro_prop) == NULL);
967
968 if (set_host || set_target) {
969 INIT_STRING_FROM_STACK(result_string, wc_buf);
970 append_char((int) hyphen_char, &result_string);
971
972 if ((pipe = popen(arch_command, "r")) == NULL) {
973 fatal_mksh(gettext("Execute of %s failed"), arch_command);
974 }
975 while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
976 MBSTOWCS(wcs_buffer, mb_buf);
977 append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
978 }
979 if (pclose(pipe) != 0) {
980 fatal_mksh(gettext("Execute of %s failed"), arch_command);
981 }
982
983 value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
984
985 if (set_host) {
986 (void) setvar_daemon(host_mach, value, false, no_daemon, true, 0);
987 }
988 if (set_target) {
989 (void) setvar_daemon(target_mach, value, false, no_daemon, true, 0);
990 }
991 }
992 }
993
994 /*
995 * expand_value_with_daemon(name, macro, destination, cmd)
996 *
997 * Checks for daemons and then maybe calls expand_value().
998 *
999 * Parameters:
1000 * name Name of the macro (Added by the NSE)
1001 * macro The property block with the value to expand
1002 * destination Where the result should be deposited
1003 * cmd If we are evaluating a command line we
1281 }
1282 }
1283 if (name == target_arch) {
1284 Name ha = getvar(host_arch);
1285 Name ta = getvar(target_arch);
1286 Name vr = getvar(virtual_root);
1287 int length;
1288 wchar_t *new_value;
1289 wchar_t *old_vr;
1290 Boolean new_value_allocated = false;
1291
1292 Wstring ha_str(ha);
1293 Wstring ta_str(ta);
1294 Wstring vr_str(vr);
1295
1296 wchar_t * wcb_ha = ha_str.get_string();
1297 wchar_t * wcb_ta = ta_str.get_string();
1298 wchar_t * wcb_vr = vr_str.get_string();
1299
1300 length = 32 +
1301 wslen(wcb_ha) +
1302 wslen(wcb_ta) +
1303 wslen(wcb_vr);
1304 old_vr = wcb_vr;
1305 MBSTOWCS(wcs_buffer, "/usr/arch/");
1306 if (IS_WEQUALN(old_vr,
1307 wcs_buffer,
1308 wslen(wcs_buffer))) {
1309 old_vr = (wchar_t *) wschr(old_vr, (int) colon_char) + 1;
1310 }
1311 if ( (ha == ta) || (wslen(wcb_ta) == 0) ) {
1312 new_value = old_vr;
1313 } else {
1314 new_value = ALLOC_WC(length);
1315 new_value_allocated = true;
1316 WCSTOMBS(mbs_buffer, old_vr);
1317 (void) wsprintf(new_value,
1318 "/usr/arch/%s/%s:%s",
1319 ha->string_mb + 1,
1320 ta->string_mb + 1,
1321 mbs_buffer);
1322 }
1323 if (new_value[0] != 0) {
1324 (void) setvar_daemon(virtual_root,
1325 GETNAME(new_value, FIND_LENGTH),
1326 false,
1327 no_daemon,
1328 true,
1329 debug_level);
1330 }
1331 if (new_value_allocated) {
1332 retmem(new_value);
1333 }
1334 }
1335 return macro;
1336 }
|
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 /*
28 * macro.cc
29 *
30 * Handle expansion of make macros
31 */
32
33 /*
34 * Included files
35 */
36 #include <mksh/dosys.h> /* sh_command2string() */
37 #include <mksh/i18n.h> /* get_char_semantics_value() */
38 #include <mksh/macro.h>
39 #include <mksh/misc.h> /* retmem() */
40 #include <mksh/read.h> /* get_next_block_fn() */
41
42 #include <libintl.h>
43
44 /*
45 * File table of contents
46 */
47 static void add_macro_to_global_list(Name macro_to_add);
48 static void expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd);
49
50 static void init_arch_macros(void);
51 static void init_mach_macros(void);
52 static Boolean init_arch_done = false;
53 static Boolean init_mach_done = false;
54
55
56 long env_alloc_num = 0;
57 long env_alloc_bytes = 0;
58
59 /*
60 * getvar(name)
61 *
137 if (!value->dollar) {
138 /*
139 * If the value we are expanding does not contain
140 * any $, we don't have to parse it.
141 */
142 APPEND_NAME(value,
143 destination,
144 (int) value->hash.length
145 );
146 destination->text.end = destination->text.p;
147 return;
148 }
149
150 if (value->being_expanded) {
151 fatal_reader_mksh(gettext("Loop detected when expanding macro value `%s'"),
152 value->string_mb);
153 }
154 value->being_expanded = true;
155 /* Setup the structure we read from */
156 Wstring vals(value);
157 sourceb.string.text.p = sourceb.string.buffer.start = wcsdup(vals.get_string());
158 sourceb.string.free_after_use = true;
159 sourceb.string.text.end =
160 sourceb.string.buffer.end =
161 sourceb.string.text.p + value->hash.length;
162 sourceb.previous = NULL;
163 sourceb.fd = -1;
164 sourceb.inp_buf =
165 sourceb.inp_buf_ptr =
166 sourceb.inp_buf_end = NULL;
167 sourceb.error_converting = false;
168 /* Lift some pointers from the struct to local register variables */
169 CACHE_SOURCE(0);
170 /* We parse the string in segments */
171 /* We read chars until we find a $, then we append what we have read so far */
172 /* (since last $ processing) to the destination. When we find a $ we call */
173 /* expand_macro() and let it expand that particular $ reference into dest */
174 block_start = source_p;
175 quote_seen = 0;
176 for (; 1; source_p++) {
177 switch (GET_CHAR()) {
441 /* First check if we have a $(@D) type translation. */
442 if ((get_char_semantics_value(string.buffer.start[0]) &
443 (int) special_macro_sem) &&
444 (string.text.p - string.buffer.start >= 2) &&
445 ((string.buffer.start[1] == 'D') ||
446 (string.buffer.start[1] == 'F'))) {
447 switch (string.buffer.start[1]) {
448 case 'D':
449 extraction = dir_extract;
450 break;
451 case 'F':
452 extraction = file_extract;
453 break;
454 default:
455 WCSTOMBS(mbs_buffer, string.buffer.start);
456 fatal_reader_mksh(gettext("Illegal macro reference `%s'"),
457 mbs_buffer);
458 }
459 /* Internalize the macro name using the first char only. */
460 name = GETNAME(string.buffer.start, 1);
461 (void) wcscpy(string.buffer.start, string.buffer.start + 2);
462 }
463 /* Check for other kinds of translations. */
464 if ((colon = (wchar_t *) wcschr(string.buffer.start,
465 (int) colon_char)) != NULL) {
466 /*
467 * We have a $(FOO:.c=.o) type translation.
468 * Get the name of the macro proper.
469 */
470 if (name == NULL) {
471 name = GETNAME(string.buffer.start,
472 colon - string.buffer.start);
473 }
474 /* Pickup all the translations. */
475 if (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell)) {
476 replacement = sh_replace;
477 } else if ((svr4) ||
478 ((percent = (wchar_t *) wcschr(colon + 1,
479 (int) percent_char)) == NULL)) {
480 while (colon != NULL) {
481 if ((eq = (wchar_t *) wcschr(colon + 1,
482 (int) equal_char)) == NULL) {
483 fatal_reader_mksh(gettext("= missing from replacement macro reference"));
484 }
485 left_tail_len = eq - colon - 1;
486 if(left_tail) {
487 retmem(left_tail);
488 }
489 left_tail = ALLOC_WC(left_tail_len + 1);
490 (void) wcsncpy(left_tail,
491 colon + 1,
492 eq - colon - 1);
493 left_tail[eq - colon - 1] = (int) nul_char;
494 replacement = suffix_replace;
495 if ((colon = (wchar_t *) wcschr(eq + 1,
496 (int) colon_char)) != NULL) {
497 tmp_len = colon - eq;
498 if(right_tail) {
499 retmem(right_tail);
500 }
501 right_tail = ALLOC_WC(tmp_len);
502 (void) wcsncpy(right_tail,
503 eq + 1,
504 colon - eq - 1);
505 right_tail[colon - eq - 1] =
506 (int) nul_char;
507 } else {
508 if(right_tail) {
509 retmem(right_tail);
510 }
511 right_tail = ALLOC_WC(wcslen(eq) + 1);
512 (void) wcscpy(right_tail, eq + 1);
513 }
514 }
515 } else {
516 if ((eq = (wchar_t *) wcschr(colon + 1,
517 (int) equal_char)) == NULL) {
518 fatal_reader_mksh(gettext("= missing from replacement macro reference"));
519 }
520 if ((percent = (wchar_t *) wcschr(colon + 1,
521 (int) percent_char)) == NULL) {
522 fatal_reader_mksh(gettext("%% missing from replacement macro reference"));
523 }
524 if (eq < percent) {
525 fatal_reader_mksh(gettext("%% missing from replacement macro reference"));
526 }
527
528 if (percent > (colon + 1)) {
529 tmp_len = percent - colon;
530 if(left_head) {
531 retmem(left_head);
532 }
533 left_head = ALLOC_WC(tmp_len);
534 (void) wcsncpy(left_head,
535 colon + 1,
536 percent - colon - 1);
537 left_head[percent-colon-1] = (int) nul_char;
538 left_head_len = percent-colon-1;
539 } else {
540 left_head = NULL;
541 left_head_len = 0;
542 }
543
544 if (eq > percent+1) {
545 tmp_len = eq - percent;
546 if(left_tail) {
547 retmem(left_tail);
548 }
549 left_tail = ALLOC_WC(tmp_len);
550 (void) wcsncpy(left_tail,
551 percent + 1,
552 eq - percent - 1);
553 left_tail[eq-percent-1] = (int) nul_char;
554 left_tail_len = eq-percent-1;
555 } else {
556 left_tail = NULL;
557 left_tail_len = 0;
558 }
559
560 if ((percent = (wchar_t *) wcschr(++eq,
561 (int) percent_char)) == NULL) {
562
563 right_hand[0] = ALLOC_WC(wcslen(eq) + 1);
564 right_hand[1] = NULL;
565 (void) wcscpy(right_hand[0], eq);
566 } else {
567 i = 0;
568 do {
569 right_hand[i] = ALLOC_WC(percent-eq+1);
570 (void) wcsncpy(right_hand[i],
571 eq,
572 percent - eq);
573 right_hand[i][percent-eq] =
574 (int) nul_char;
575 if (i++ >= VSIZEOF(right_hand)) {
576 fatal_mksh(gettext("Too many %% in pattern"));
577 }
578 eq = percent + 1;
579 if (eq[0] == (int) nul_char) {
580 MBSTOWCS(wcs_buffer, "");
581 right_hand[i] = (wchar_t *) wcsdup(wcs_buffer);
582 i++;
583 break;
584 }
585 } while ((percent = (wchar_t *) wcschr(eq, (int) percent_char)) != NULL);
586 if (eq[0] != (int) nul_char) {
587 right_hand[i] = ALLOC_WC(wcslen(eq) + 1);
588 (void) wcscpy(right_hand[i], eq);
589 i++;
590 }
591 right_hand[i] = NULL;
592 }
593 replacement = pattern_replace;
594 }
595 }
596 if (name == NULL) {
597 /*
598 * No translations found.
599 * Use the whole string as the macro name.
600 */
601 name = GETNAME(string.buffer.start,
602 string.text.p - string.buffer.start);
603 }
604 if (string.free_after_use) {
605 retmem(string.buffer.start);
606 }
607 if (name == make) {
608 make_word_mentioned = true;
678 while ((*p != (int) nul_char) && !iswspace(*p)) {
679 p++;
680 }
681 /* If we cant find another word we are done */
682 if (block_start == p) {
683 break;
684 }
685 /* Then apply the transforms to the word */
686 INIT_STRING_FROM_STACK(extracted, extracted_string);
687 switch (extraction) {
688 case dir_extract:
689 /*
690 * $(@D) type transform. Extract the
691 * path from the word. Deliver "." if
692 * none is found.
693 */
694 if (p != NULL) {
695 chr = *p;
696 *p = (int) nul_char;
697 }
698 eq = (wchar_t *) wcsrchr(block_start, (int) slash_char);
699 if (p != NULL) {
700 *p = chr;
701 }
702 if ((eq == NULL) || (eq > p)) {
703 MBSTOWCS(wcs_buffer, ".");
704 append_string(wcs_buffer, &extracted, 1);
705 } else {
706 append_string(block_start,
707 &extracted,
708 eq - block_start);
709 }
710 break;
711 case file_extract:
712 /*
713 * $(@F) type transform. Remove the path
714 * from the word if any.
715 */
716 if (p != NULL) {
717 chr = *p;
718 *p = (int) nul_char;
719 }
720 eq = (wchar_t *) wcsrchr(block_start, (int) slash_char);
721 if (p != NULL) {
722 *p = chr;
723 }
724 if ((eq == NULL) || (eq > p)) {
725 append_string(block_start,
726 &extracted,
727 p - block_start);
728 } else {
729 append_string(eq + 1,
730 &extracted,
731 p - eq - 1);
732 }
733 break;
734 case no_extract:
735 append_string(block_start,
736 &extracted,
737 p - block_start);
738 break;
739 }
740 switch (replacement) {
901 String_rec result_string;
902 wchar_t wc_buf[STRING_BUFFER_LENGTH];
903 char mb_buf[STRING_BUFFER_LENGTH];
904 FILE *pipe;
905 Name value;
906 int set_host, set_target;
907 const char *mach_command = "/bin/mach";
908
909 set_host = (get_prop(host_arch->prop, macro_prop) == NULL);
910 set_target = (get_prop(target_arch->prop, macro_prop) == NULL);
911
912 if (set_host || set_target) {
913 INIT_STRING_FROM_STACK(result_string, wc_buf);
914 append_char((int) hyphen_char, &result_string);
915
916 if ((pipe = popen(mach_command, "r")) == NULL) {
917 fatal_mksh(gettext("Execute of %s failed"), mach_command);
918 }
919 while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
920 MBSTOWCS(wcs_buffer, mb_buf);
921 append_string(wcs_buffer, &result_string, wcslen(wcs_buffer));
922 }
923 if (pclose(pipe) != 0) {
924 fatal_mksh(gettext("Execute of %s failed"), mach_command);
925 }
926
927 value = GETNAME(result_string.buffer.start, wcslen(result_string.buffer.start));
928
929 if (set_host) {
930 (void) setvar_daemon(host_arch, value, false, no_daemon, true, 0);
931 }
932 if (set_target) {
933 (void) setvar_daemon(target_arch, value, false, no_daemon, true, 0);
934 }
935 }
936 }
937
938 /*
939 * init_mach_macros(void)
940 *
941 * Set the magic macros TARGET_MACH, HOST_MACH,
942 *
943 * Parameters:
944 *
945 * Global variables used:
946 * host_mach Property for magic macro HOST_MACH
947 * target_mach Property for magic macro TARGET_MACH
956 String_rec result_string;
957 wchar_t wc_buf[STRING_BUFFER_LENGTH];
958 char mb_buf[STRING_BUFFER_LENGTH];
959 FILE *pipe;
960 Name value;
961 int set_host, set_target;
962 const char *arch_command = "/bin/arch";
963
964 set_host = (get_prop(host_mach->prop, macro_prop) == NULL);
965 set_target = (get_prop(target_mach->prop, macro_prop) == NULL);
966
967 if (set_host || set_target) {
968 INIT_STRING_FROM_STACK(result_string, wc_buf);
969 append_char((int) hyphen_char, &result_string);
970
971 if ((pipe = popen(arch_command, "r")) == NULL) {
972 fatal_mksh(gettext("Execute of %s failed"), arch_command);
973 }
974 while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
975 MBSTOWCS(wcs_buffer, mb_buf);
976 append_string(wcs_buffer, &result_string, wcslen(wcs_buffer));
977 }
978 if (pclose(pipe) != 0) {
979 fatal_mksh(gettext("Execute of %s failed"), arch_command);
980 }
981
982 value = GETNAME(result_string.buffer.start, wcslen(result_string.buffer.start));
983
984 if (set_host) {
985 (void) setvar_daemon(host_mach, value, false, no_daemon, true, 0);
986 }
987 if (set_target) {
988 (void) setvar_daemon(target_mach, value, false, no_daemon, true, 0);
989 }
990 }
991 }
992
993 /*
994 * expand_value_with_daemon(name, macro, destination, cmd)
995 *
996 * Checks for daemons and then maybe calls expand_value().
997 *
998 * Parameters:
999 * name Name of the macro (Added by the NSE)
1000 * macro The property block with the value to expand
1001 * destination Where the result should be deposited
1002 * cmd If we are evaluating a command line we
1280 }
1281 }
1282 if (name == target_arch) {
1283 Name ha = getvar(host_arch);
1284 Name ta = getvar(target_arch);
1285 Name vr = getvar(virtual_root);
1286 int length;
1287 wchar_t *new_value;
1288 wchar_t *old_vr;
1289 Boolean new_value_allocated = false;
1290
1291 Wstring ha_str(ha);
1292 Wstring ta_str(ta);
1293 Wstring vr_str(vr);
1294
1295 wchar_t * wcb_ha = ha_str.get_string();
1296 wchar_t * wcb_ta = ta_str.get_string();
1297 wchar_t * wcb_vr = vr_str.get_string();
1298
1299 length = 32 +
1300 wcslen(wcb_ha) +
1301 wcslen(wcb_ta) +
1302 wcslen(wcb_vr);
1303 old_vr = wcb_vr;
1304 MBSTOWCS(wcs_buffer, "/usr/arch/");
1305 if (IS_WEQUALN(old_vr,
1306 wcs_buffer,
1307 wcslen(wcs_buffer))) {
1308 old_vr = (wchar_t *) wcschr(old_vr, (int) colon_char) + 1;
1309 }
1310 if ( (ha == ta) || (wcslen(wcb_ta) == 0) ) {
1311 new_value = old_vr;
1312 } else {
1313 new_value = ALLOC_WC(length);
1314 new_value_allocated = true;
1315 WCSTOMBS(mbs_buffer, old_vr);
1316 (void) swprintf(new_value, length * SIZEOFWCHAR_T,
1317 L"/usr/arch/%s/%s:%s",
1318 ha->string_mb + 1,
1319 ta->string_mb + 1,
1320 mbs_buffer);
1321 }
1322 if (new_value[0] != 0) {
1323 (void) setvar_daemon(virtual_root,
1324 GETNAME(new_value, FIND_LENGTH),
1325 false,
1326 no_daemon,
1327 true,
1328 debug_level);
1329 }
1330 if (new_value_allocated) {
1331 retmem(new_value);
1332 }
1333 }
1334 return macro;
1335 }
|