Print this page
make: use the more modern wchar routines, not widec.h


  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 }