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


  94 Name_vector
  95 enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen)
  96 {
  97         Name                    name;
  98         register wchar_t        *cp;
  99         wchar_t                 ch;
 100 
 101         /* If we were passed a separate tail of the name we append it to the */
 102         /* make string with the rest of it */
 103         if (tail_present) {
 104                 append_string(string_start, string, string_end - string_start);
 105                 string_start = string->buffer.start;
 106                 string_end = string->text.p;
 107         }
 108         ch = *string_end;
 109         *string_end = (int) nul_char;
 110         /*
 111          * Check if there are any ( or [ that are not prefixed with $.
 112          * If there are, we have to deal with the lib.a(members) format.
 113          */
 114         for (cp = (wchar_t *) wschr(string_start, (int) parenleft_char);
 115              cp != NULL;
 116              cp = (wchar_t *) wschr(cp + 1, (int) parenleft_char)) {
 117                 if (*(cp - 1) != (int) dollar_char) {
 118                         *string_end = ch;
 119                         return enter_member_name(string_start,
 120                                                  cp,
 121                                                  string_end,
 122                                                  current_names,
 123                                                  extra_names);
 124                 }
 125         }
 126         *string_end = ch;
 127 
 128         if (makefile_type == reading_cpp_file) {
 129                 /* Remove extra ../ constructs if we are reading from a report file */
 130                 name = normalize_name(string_start, string_end - string_start);
 131         } else {
 132                 /*
 133                  * /tolik, fix bug 1197477/
 134                  * Normalize every target name before entering.
 135                  * ..//obj/a.o and ../obj//a.o are not two different targets.
 136                  * There is only one target ../obj/a.o


 199         Name                    name;
 200         Property                prop;
 201         wchar_t                 *memberp;
 202         wchar_t                 *q;
 203         register int            paren_count;
 204         register Boolean        has_dollar;
 205         register wchar_t        *cq;
 206         Name                    long_member_name = NULL;
 207 
 208         /* Internalize the name of the library */
 209         lib = GETNAME(lib_start, member_start - lib_start);
 210         lib->is_member = true;
 211         member_start++;
 212         if (*member_start == (int) parenleft_char) {
 213                 /* This is really the "lib.a((entries))" format */
 214                 entry = true;
 215                 member_start++;
 216         }
 217         /* Move the library name to the buffer where we intend to build the */
 218         /* "lib.a(member)" for each member */
 219         (void) wsncpy(buffer, lib_start, member_start - lib_start);
 220         memberp = buffer + (member_start-lib_start);
 221         while (1) {
 222                 long_member_name = NULL;
 223                 /* Skip leading spaces */
 224                 for (;
 225                      (member_start < string_end) && iswspace(*member_start);
 226                      member_start++);
 227                 /* Find the end of the member name. Allow nested (). Detect $*/
 228                 for (cq = memberp, has_dollar = false, paren_count = 0;
 229                      (member_start < string_end) &&
 230                      ((*member_start != (int) parenright_char) ||
 231                       (paren_count > 0)) &&
 232                      !iswspace(*member_start);
 233                      *cq++ = *member_start++) {
 234                         switch (*member_start) {
 235                         case parenleft_char:
 236                                 paren_count++;
 237                                 break;
 238                         case parenright_char:
 239                                 paren_count--;
 240                                 break;
 241                         case dollar_char:
 242                                 has_dollar = true;
 243                         }
 244                 }
 245                 /* Internalize the member name */
 246                 member = GETNAME(memberp, cq - memberp);
 247                 *cq = 0;
 248                 if ((q = (wchar_t *) wsrchr(memberp, (int) slash_char)) == NULL) {
 249                         q = memberp;
 250                 }
 251                 if ((cq - q > (int) ar_member_name_len) &&
 252                     !has_dollar) {
 253                         *cq++ = (int) parenright_char;
 254                         if (entry) {
 255                                 *cq++ = (int) parenright_char;
 256                         }
 257                         long_member_name = GETNAME(buffer, cq - buffer);
 258                         cq = q + (int) ar_member_name_len;
 259                 }
 260                 *cq++ = (int) parenright_char;
 261                 if (entry) {
 262                         *cq++ = (int) parenright_char;
 263                 }
 264                 /* Internalize the "lib.a(member)" notation for this member */
 265                 name = GETNAME(buffer, cq - buffer);
 266                 name->is_member = lib->is_member;
 267                 if (long_member_name != NULL) {
 268                         prop = append_prop(name, long_member_name_prop);


 380                     (name_string[1] == (int) slash_char)) {
 381                         name_string++;
 382                         length--;
 383                         continue;
 384                 }
 385                 *cdp++ = *name_string++;
 386                 length--;
 387         }
 388         *cdp = (int) nul_char;
 389         /*
 390          * Now scan for <name>/../ and remove such combinations iff <name>
 391          * is not another ..
 392          * Each time something is removed, the whole process is restarted.
 393          */
 394 removed_one:
 395         name_string = string;
 396         string2 = name_string;          /*save for free*/
 397         current_component =
 398           cdp =
 399             string =
 400               ALLOC_WC((length = wslen(name_string)) + 1);
 401         while (length > 0) {
 402                 if (((length > 3) &&
 403                      (name_string[0] == (int) slash_char) &&
 404                      (name_string[1] == (int) period_char) &&
 405                      (name_string[2] == (int) period_char) &&
 406                      (name_string[3] == (int) slash_char)) ||
 407                     ((length == 3) &&
 408                      (name_string[0] == (int) slash_char) &&
 409                      (name_string[1] == (int) period_char) &&
 410                      (name_string[2] == (int) period_char))) {
 411                         /* Positioned on the / that starts a /.. sequence */
 412                         if (((count = cdp - current_component) != 0) &&
 413                             (exists(name = GETNAME(string, cdp - string)) > file_doesnt_exist) &&
 414                             (!name->stat.is_sym_link)) {
 415                                 name = GETNAME(current_component, count);
 416                                 if(name != dotdot) {
 417                                         cdp = current_component;
 418                                         name_string += 3;
 419                                         length -= 3;
 420                                         if (length > 0) {


 641                                     (makefile_type == reading_cpp_file);
 642                                 return;
 643                         }
 644                 }
 645                 line2 = append_prop(target, recursive_prop);
 646                 line2->body.recursive.directory = directory;
 647                 line2->body.recursive.target = name;
 648                 line2->body.recursive.makefiles = dp;
 649                 line2->body.recursive.has_built = 
 650                     (Boolean) (makefile_type == reading_cpp_file);
 651                 line2->body.recursive.in_depinfo = false;
 652                 return;
 653         }
 654         /* If this is the first target that doesnt start with a "." in the */
 655         /* makefile we remember that */
 656         Wstring tstr(target);
 657         wchar_t * wcb = tstr.get_string();
 658         if ((makefile_type == reading_makefile) &&
 659             (default_target_to_build == NULL) &&
 660             ((wcb[0] != (int) period_char) ||
 661              wschr(wcb, (int) slash_char))) {
 662 
 663 /* BID 1181577: $(EMPTY_MACRO) + $(EMPTY_MACRO):
 664 ** The target with empty name cannot be default_target_to_build
 665 */
 666                 if (target->hash.length != 0)
 667                         default_target_to_build = target;
 668         }
 669         /* Check if the line is ":" or "::" */
 670         if (makefile_type == reading_makefile) {
 671                 if (target->colons == no_colon) {
 672                         target->colons = separator;
 673                 } else {
 674                         if (target->colons != separator) {
 675                                 fatal_reader(gettext(":/:: conflict for target `%s'"),
 676                                              target->string_mb);
 677                         }
 678                 }
 679                 if (target->colons == two_colon) {
 680                         if (depes->used == 0) {
 681                                 /* If this is a "::" type line with no */


 730                         if (trace_reader) {
 731                                 (void) printf("\n");
 732                         }
 733                         (target = name)->stat.is_file = true;
 734                 }
 735         }
 736         /* This really is a regular dependency line. Just enter it */
 737         line = maybe_append_prop(target, line_prop);
 738         line->body.line.target = target;
 739         /* Depending on what kind of makefile we are reading we have to */
 740         /* treat things differently */
 741         switch (makefile_type) {
 742         case reading_makefile:
 743                 /* Reading regular makefile. Just notice whether this */
 744                 /* redefines the rule for the  target */
 745                 if (command != NULL) {
 746                         if (line->body.line.command_template != NULL) {
 747                                 line->body.line.command_template_redefined =
 748                                   true;
 749                                 if ((wcb[0] == (int) period_char) &&
 750                                     !wschr(wcb, (int) slash_char)) {
 751                                         line->body.line.command_template =
 752                                           command;
 753                                 }
 754                         } else {
 755                                 line->body.line.command_template = command;
 756                         }
 757                 } else {
 758                         if ((wcb[0] == (int) period_char) &&
 759                             !wschr(wcb, (int) slash_char)) {
 760                                 line->body.line.command_template = command;
 761                         }
 762                 }
 763                 break;
 764         case rereading_statefile:
 765                 /* Rereading the statefile. We only enter thing that changed */
 766                 /* since the previous time we read it */
 767                 if (!built_last_make_run_seen) {
 768                         for (Cmd_line next, cmd = command; cmd != NULL; cmd = next) {
 769                                 next = cmd->next;
 770                                 free(cmd);
 771                         }
 772                         return;
 773                 }
 774                 built_last_make_run_seen = false;
 775                 command_changed = true;
 776                 target->ran_command = true;
 777         case reading_statefile:
 778                 /* Reading the statefile for the first time. Enter the rules */
 779                 /* as "Commands used" not "templates to use" */


 930         register Percent        *depe_tail = &result->dependencies;
 931         register Percent        *insert;
 932         register wchar_t        *cp, *cp1;
 933         Name_vector             nvp;
 934         int                     i;
 935         int                     pattern;
 936 
 937         result->next = NULL;
 938         result->patterns = NULL;
 939         result->patterns_total = 0;
 940         result->command_template = command;
 941         result->being_expanded = false;
 942         result->name = target;
 943         result->dependencies = NULL;
 944         result->target_group = target_group;
 945 
 946         /* get patterns count */
 947         Wstring wcb(target);
 948         cp = wcb.get_string();
 949         while (true) {
 950                 cp = (wchar_t *) wschr(cp, (int) percent_char);
 951                 if (cp != NULL) {
 952                         result->patterns_total++;
 953                         cp++;
 954                 } else {
 955                         break;
 956                 }
 957         }
 958         result->patterns_total++;
 959 
 960         /* allocate storage for patterns */
 961         result->patterns = (Name *) getmem(sizeof(Name) * result->patterns_total);
 962 
 963         /* then create patterns */
 964         cp = wcb.get_string();
 965         pattern = 0;
 966         while (true) {
 967                 cp1 = (wchar_t *) wschr(cp, (int) percent_char);
 968                 if (cp1 != NULL) {
 969                         result->patterns[pattern] = GETNAME(cp, cp1 - cp);
 970                         cp = cp1 + 1;
 971                         pattern++;
 972                 } else {
 973                         result->patterns[pattern] = GETNAME(cp, (int) target->hash.length - (cp - wcb.get_string()));
 974                         break;
 975                 }
 976         }
 977 
 978         Wstring wcb1;
 979 
 980         /* build dependencies list */
 981         for (nvp = depes; nvp != NULL; nvp = nvp->next) {
 982                 for (i = 0; i < nvp->used; i++) {
 983                         depe = ALLOC(Percent);
 984                         depe->next = NULL;
 985                         depe->patterns = NULL;
 986                         depe->patterns_total = 0;
 987                         depe->name = nvp->names[i];
 988                         depe->dependencies = NULL;
 989                         depe->command_template = NULL;
 990                         depe->being_expanded = false;
 991                         depe->target_group = NULL;
 992 
 993                         *depe_tail = depe;
 994                         depe_tail = &depe->next;
 995 
 996                         if (depe->name->percent) {
 997                                 /* get patterns count */
 998                                 wcb1.init(depe->name);
 999                                 cp = wcb1.get_string();
1000                                 while (true) {
1001                                         cp = (wchar_t *) wschr(cp, (int) percent_char);
1002                                         if (cp != NULL) {
1003                                                 depe->patterns_total++;
1004                                                 cp++;
1005                                         } else {
1006                                                 break;
1007                                         }
1008                                 }
1009                                 depe->patterns_total++;
1010 
1011                                 /* allocate storage for patterns */
1012                                 depe->patterns = (Name *) getmem(sizeof(Name) * depe->patterns_total);
1013 
1014                                 /* then create patterns */
1015                                 cp = wcb1.get_string();
1016                                 pattern = 0;
1017                                 while (true) {
1018                                         cp1 = (wchar_t *) wschr(cp, (int) percent_char);
1019                                         if (cp1 != NULL) {
1020                                                 depe->patterns[pattern] = GETNAME(cp, cp1 - cp);
1021                                                 cp = cp1 + 1;
1022                                                 pattern++;
1023                                         } else {
1024                                                 depe->patterns[pattern] = GETNAME(cp, (int) depe->name->hash.length - (cp - wcb1.get_string()));
1025                                                 break;
1026                                         }
1027                                 }
1028                         }
1029                 }
1030         }
1031 
1032         /* Find the end of the percent list and append the new pattern */
1033         for (insert = &percent_list; (*insert) != NULL; insert = &(*insert)->next);
1034         *insert = result;
1035 
1036         if (trace_reader) {
1037                 (void) printf("%s:", result->name->string_mb);
1038 


1551  *
1552  *      Parameters:
1553  *              to              The path we want to make relative
1554  *              result          Where to put the resulting relative path
1555  *
1556  *      Global variables used:
1557  */
1558 static void
1559 make_relative(wchar_t *to, wchar_t *result)
1560 {
1561         wchar_t                 *from;
1562         wchar_t                 *allocated;
1563         wchar_t                 *cp;
1564         wchar_t                 *tocomp;
1565         int                     ncomps;
1566         int                     i;
1567         int                     len;
1568 
1569         /* Check if the path is already relative. */
1570         if (to[0] != (int) slash_char) {
1571                 (void) wscpy(result, to);
1572                 return;
1573         }
1574 
1575         MBSTOWCS(wcs_buffer, get_current_path());
1576         from = allocated = (wchar_t *) wsdup(wcs_buffer);
1577 
1578         /*
1579          * Find the number of components in the from name.
1580          * ncomp = number of slashes + 1.
1581          */
1582         ncomps = 1;
1583         for (cp = from; *cp != (int) nul_char; cp++) {
1584                 if (*cp == (int) slash_char) {
1585                         ncomps++;
1586                 }
1587         }
1588 
1589         /*
1590          * See how many components match to determine how many "..",
1591          * if any, will be needed.
1592          */
1593         result[0] = (int) nul_char;
1594         tocomp = to;
1595         while ((*from != (int) nul_char) && (*from == *to)) {
1596                 if (*from == (int) slash_char) {
1597                         ncomps--;
1598                         tocomp = &to[1];
1599                 }
1600                 from++;
1601                 to++;
1602         }
1603 
1604         /*
1605          * Now for some special cases. Check for exact matches and
1606          * for either name terminating exactly.
1607          */
1608         if (*from == (int) nul_char) {
1609                 if (*to == (int) nul_char) {
1610                         MBSTOWCS(wcs_buffer, ".");
1611                         (void) wscpy(result, wcs_buffer);
1612                         retmem(allocated);
1613                         return;
1614                 }
1615                 if (*to == (int) slash_char) {
1616                         ncomps--;
1617                         tocomp = &to[1];
1618                 }
1619         } else if ((*from == (int) slash_char) && (*to == (int) nul_char)) {
1620                 ncomps--;
1621                 tocomp = to;
1622         }
1623         /* Add on the ".."s. */
1624         for (i = 0; i < ncomps; i++) {
1625                 MBSTOWCS(wcs_buffer, "../");
1626                 (void) wscat(result, wcs_buffer);
1627         }
1628 
1629         /* Add on the remainder of the to name, if any. */
1630         if (*tocomp == (int) nul_char) {
1631                 len = wslen(result);
1632                 result[len - 1] = (int) nul_char;
1633         } else {
1634                 (void) wscat(result, tocomp);
1635         }
1636         retmem(allocated);
1637         return;
1638 }
1639 
1640 /*
1641  *      print_rule(command)
1642  *
1643  *      Used when tracing the reading of rules
1644  *
1645  *      Parameters:
1646  *              command         Command to print
1647  *
1648  *      Global variables used:
1649  */
1650 static void
1651 print_rule(register Cmd_line command)
1652 {
1653         for (; command != NULL; command = command->next) {
1654                 (void) printf("\t%s\n", command->command_line->string_mb);


1789 static void
1790 sh_transform(Name *name, Name *value)
1791 {
1792         /* Check if we need :sh transform */
1793         wchar_t         *colon;
1794         String_rec      command;
1795         String_rec      destination;
1796         wchar_t         buffer[1000];
1797         wchar_t         buffer1[1000];
1798 
1799         static wchar_t  colon_sh[4];
1800         static wchar_t  colon_shell[7];
1801 
1802         if (colon_sh[0] == (int) nul_char) {
1803                 MBSTOWCS(colon_sh, ":sh");
1804                 MBSTOWCS(colon_shell, ":shell");
1805         }
1806         Wstring nms((*name));
1807         wchar_t * wcb = nms.get_string();
1808 
1809         colon = (wchar_t *) wsrchr(wcb, (int) colon_char);
1810         if ((colon != NULL) && (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell))) {
1811                 INIT_STRING_FROM_STACK(destination, buffer);
1812 
1813                 if(*value == NULL) {
1814                         buffer[0] = 0;
1815                 } else {
1816                         Wstring wcb1((*value));
1817                         if (IS_WEQUAL(colon, colon_shell)) {
1818                                 INIT_STRING_FROM_STACK(command, buffer1);
1819                                 expand_value(*value, &command, false);
1820                         } else {
1821                                 command.text.p = wcb1.get_string() + (*value)->hash.length;
1822                                 command.text.end = command.text.p;
1823                                 command.buffer.start = wcb1.get_string();
1824                                 command.buffer.end = command.text.p;
1825                         }
1826                         sh_command2string(&command, &destination);
1827                 }
1828 
1829                 (*value) = GETNAME(destination.buffer.start, FIND_LENGTH);




  94 Name_vector
  95 enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen)
  96 {
  97         Name                    name;
  98         register wchar_t        *cp;
  99         wchar_t                 ch;
 100 
 101         /* If we were passed a separate tail of the name we append it to the */
 102         /* make string with the rest of it */
 103         if (tail_present) {
 104                 append_string(string_start, string, string_end - string_start);
 105                 string_start = string->buffer.start;
 106                 string_end = string->text.p;
 107         }
 108         ch = *string_end;
 109         *string_end = (int) nul_char;
 110         /*
 111          * Check if there are any ( or [ that are not prefixed with $.
 112          * If there are, we have to deal with the lib.a(members) format.
 113          */
 114         for (cp = (wchar_t *) wcschr(string_start, (int) parenleft_char);
 115              cp != NULL;
 116              cp = (wchar_t *) wcschr(cp + 1, (int) parenleft_char)) {
 117                 if (*(cp - 1) != (int) dollar_char) {
 118                         *string_end = ch;
 119                         return enter_member_name(string_start,
 120                                                  cp,
 121                                                  string_end,
 122                                                  current_names,
 123                                                  extra_names);
 124                 }
 125         }
 126         *string_end = ch;
 127 
 128         if (makefile_type == reading_cpp_file) {
 129                 /* Remove extra ../ constructs if we are reading from a report file */
 130                 name = normalize_name(string_start, string_end - string_start);
 131         } else {
 132                 /*
 133                  * /tolik, fix bug 1197477/
 134                  * Normalize every target name before entering.
 135                  * ..//obj/a.o and ../obj//a.o are not two different targets.
 136                  * There is only one target ../obj/a.o


 199         Name                    name;
 200         Property                prop;
 201         wchar_t                 *memberp;
 202         wchar_t                 *q;
 203         register int            paren_count;
 204         register Boolean        has_dollar;
 205         register wchar_t        *cq;
 206         Name                    long_member_name = NULL;
 207 
 208         /* Internalize the name of the library */
 209         lib = GETNAME(lib_start, member_start - lib_start);
 210         lib->is_member = true;
 211         member_start++;
 212         if (*member_start == (int) parenleft_char) {
 213                 /* This is really the "lib.a((entries))" format */
 214                 entry = true;
 215                 member_start++;
 216         }
 217         /* Move the library name to the buffer where we intend to build the */
 218         /* "lib.a(member)" for each member */
 219         (void) wcsncpy(buffer, lib_start, member_start - lib_start);
 220         memberp = buffer + (member_start-lib_start);
 221         while (1) {
 222                 long_member_name = NULL;
 223                 /* Skip leading spaces */
 224                 for (;
 225                      (member_start < string_end) && iswspace(*member_start);
 226                      member_start++);
 227                 /* Find the end of the member name. Allow nested (). Detect $*/
 228                 for (cq = memberp, has_dollar = false, paren_count = 0;
 229                      (member_start < string_end) &&
 230                      ((*member_start != (int) parenright_char) ||
 231                       (paren_count > 0)) &&
 232                      !iswspace(*member_start);
 233                      *cq++ = *member_start++) {
 234                         switch (*member_start) {
 235                         case parenleft_char:
 236                                 paren_count++;
 237                                 break;
 238                         case parenright_char:
 239                                 paren_count--;
 240                                 break;
 241                         case dollar_char:
 242                                 has_dollar = true;
 243                         }
 244                 }
 245                 /* Internalize the member name */
 246                 member = GETNAME(memberp, cq - memberp);
 247                 *cq = 0;
 248                 if ((q = (wchar_t *) wcsrchr(memberp, (int) slash_char)) == NULL) {
 249                         q = memberp;
 250                 }
 251                 if ((cq - q > (int) ar_member_name_len) &&
 252                     !has_dollar) {
 253                         *cq++ = (int) parenright_char;
 254                         if (entry) {
 255                                 *cq++ = (int) parenright_char;
 256                         }
 257                         long_member_name = GETNAME(buffer, cq - buffer);
 258                         cq = q + (int) ar_member_name_len;
 259                 }
 260                 *cq++ = (int) parenright_char;
 261                 if (entry) {
 262                         *cq++ = (int) parenright_char;
 263                 }
 264                 /* Internalize the "lib.a(member)" notation for this member */
 265                 name = GETNAME(buffer, cq - buffer);
 266                 name->is_member = lib->is_member;
 267                 if (long_member_name != NULL) {
 268                         prop = append_prop(name, long_member_name_prop);


 380                     (name_string[1] == (int) slash_char)) {
 381                         name_string++;
 382                         length--;
 383                         continue;
 384                 }
 385                 *cdp++ = *name_string++;
 386                 length--;
 387         }
 388         *cdp = (int) nul_char;
 389         /*
 390          * Now scan for <name>/../ and remove such combinations iff <name>
 391          * is not another ..
 392          * Each time something is removed, the whole process is restarted.
 393          */
 394 removed_one:
 395         name_string = string;
 396         string2 = name_string;          /*save for free*/
 397         current_component =
 398           cdp =
 399             string =
 400               ALLOC_WC((length = wcslen(name_string)) + 1);
 401         while (length > 0) {
 402                 if (((length > 3) &&
 403                      (name_string[0] == (int) slash_char) &&
 404                      (name_string[1] == (int) period_char) &&
 405                      (name_string[2] == (int) period_char) &&
 406                      (name_string[3] == (int) slash_char)) ||
 407                     ((length == 3) &&
 408                      (name_string[0] == (int) slash_char) &&
 409                      (name_string[1] == (int) period_char) &&
 410                      (name_string[2] == (int) period_char))) {
 411                         /* Positioned on the / that starts a /.. sequence */
 412                         if (((count = cdp - current_component) != 0) &&
 413                             (exists(name = GETNAME(string, cdp - string)) > file_doesnt_exist) &&
 414                             (!name->stat.is_sym_link)) {
 415                                 name = GETNAME(current_component, count);
 416                                 if(name != dotdot) {
 417                                         cdp = current_component;
 418                                         name_string += 3;
 419                                         length -= 3;
 420                                         if (length > 0) {


 641                                     (makefile_type == reading_cpp_file);
 642                                 return;
 643                         }
 644                 }
 645                 line2 = append_prop(target, recursive_prop);
 646                 line2->body.recursive.directory = directory;
 647                 line2->body.recursive.target = name;
 648                 line2->body.recursive.makefiles = dp;
 649                 line2->body.recursive.has_built = 
 650                     (Boolean) (makefile_type == reading_cpp_file);
 651                 line2->body.recursive.in_depinfo = false;
 652                 return;
 653         }
 654         /* If this is the first target that doesnt start with a "." in the */
 655         /* makefile we remember that */
 656         Wstring tstr(target);
 657         wchar_t * wcb = tstr.get_string();
 658         if ((makefile_type == reading_makefile) &&
 659             (default_target_to_build == NULL) &&
 660             ((wcb[0] != (int) period_char) ||
 661              wcschr(wcb, (int) slash_char))) {
 662 
 663 /* BID 1181577: $(EMPTY_MACRO) + $(EMPTY_MACRO):
 664 ** The target with empty name cannot be default_target_to_build
 665 */
 666                 if (target->hash.length != 0)
 667                         default_target_to_build = target;
 668         }
 669         /* Check if the line is ":" or "::" */
 670         if (makefile_type == reading_makefile) {
 671                 if (target->colons == no_colon) {
 672                         target->colons = separator;
 673                 } else {
 674                         if (target->colons != separator) {
 675                                 fatal_reader(gettext(":/:: conflict for target `%s'"),
 676                                              target->string_mb);
 677                         }
 678                 }
 679                 if (target->colons == two_colon) {
 680                         if (depes->used == 0) {
 681                                 /* If this is a "::" type line with no */


 730                         if (trace_reader) {
 731                                 (void) printf("\n");
 732                         }
 733                         (target = name)->stat.is_file = true;
 734                 }
 735         }
 736         /* This really is a regular dependency line. Just enter it */
 737         line = maybe_append_prop(target, line_prop);
 738         line->body.line.target = target;
 739         /* Depending on what kind of makefile we are reading we have to */
 740         /* treat things differently */
 741         switch (makefile_type) {
 742         case reading_makefile:
 743                 /* Reading regular makefile. Just notice whether this */
 744                 /* redefines the rule for the  target */
 745                 if (command != NULL) {
 746                         if (line->body.line.command_template != NULL) {
 747                                 line->body.line.command_template_redefined =
 748                                   true;
 749                                 if ((wcb[0] == (int) period_char) &&
 750                                     !wcschr(wcb, (int) slash_char)) {
 751                                         line->body.line.command_template =
 752                                           command;
 753                                 }
 754                         } else {
 755                                 line->body.line.command_template = command;
 756                         }
 757                 } else {
 758                         if ((wcb[0] == (int) period_char) &&
 759                             !wcschr(wcb, (int) slash_char)) {
 760                                 line->body.line.command_template = command;
 761                         }
 762                 }
 763                 break;
 764         case rereading_statefile:
 765                 /* Rereading the statefile. We only enter thing that changed */
 766                 /* since the previous time we read it */
 767                 if (!built_last_make_run_seen) {
 768                         for (Cmd_line next, cmd = command; cmd != NULL; cmd = next) {
 769                                 next = cmd->next;
 770                                 free(cmd);
 771                         }
 772                         return;
 773                 }
 774                 built_last_make_run_seen = false;
 775                 command_changed = true;
 776                 target->ran_command = true;
 777         case reading_statefile:
 778                 /* Reading the statefile for the first time. Enter the rules */
 779                 /* as "Commands used" not "templates to use" */


 930         register Percent        *depe_tail = &result->dependencies;
 931         register Percent        *insert;
 932         register wchar_t        *cp, *cp1;
 933         Name_vector             nvp;
 934         int                     i;
 935         int                     pattern;
 936 
 937         result->next = NULL;
 938         result->patterns = NULL;
 939         result->patterns_total = 0;
 940         result->command_template = command;
 941         result->being_expanded = false;
 942         result->name = target;
 943         result->dependencies = NULL;
 944         result->target_group = target_group;
 945 
 946         /* get patterns count */
 947         Wstring wcb(target);
 948         cp = wcb.get_string();
 949         while (true) {
 950                 cp = (wchar_t *) wcschr(cp, (int) percent_char);
 951                 if (cp != NULL) {
 952                         result->patterns_total++;
 953                         cp++;
 954                 } else {
 955                         break;
 956                 }
 957         }
 958         result->patterns_total++;
 959 
 960         /* allocate storage for patterns */
 961         result->patterns = (Name *) getmem(sizeof(Name) * result->patterns_total);
 962 
 963         /* then create patterns */
 964         cp = wcb.get_string();
 965         pattern = 0;
 966         while (true) {
 967                 cp1 = (wchar_t *) wcschr(cp, (int) percent_char);
 968                 if (cp1 != NULL) {
 969                         result->patterns[pattern] = GETNAME(cp, cp1 - cp);
 970                         cp = cp1 + 1;
 971                         pattern++;
 972                 } else {
 973                         result->patterns[pattern] = GETNAME(cp, (int) target->hash.length - (cp - wcb.get_string()));
 974                         break;
 975                 }
 976         }
 977 
 978         Wstring wcb1;
 979 
 980         /* build dependencies list */
 981         for (nvp = depes; nvp != NULL; nvp = nvp->next) {
 982                 for (i = 0; i < nvp->used; i++) {
 983                         depe = ALLOC(Percent);
 984                         depe->next = NULL;
 985                         depe->patterns = NULL;
 986                         depe->patterns_total = 0;
 987                         depe->name = nvp->names[i];
 988                         depe->dependencies = NULL;
 989                         depe->command_template = NULL;
 990                         depe->being_expanded = false;
 991                         depe->target_group = NULL;
 992 
 993                         *depe_tail = depe;
 994                         depe_tail = &depe->next;
 995 
 996                         if (depe->name->percent) {
 997                                 /* get patterns count */
 998                                 wcb1.init(depe->name);
 999                                 cp = wcb1.get_string();
1000                                 while (true) {
1001                                         cp = (wchar_t *) wcschr(cp, (int) percent_char);
1002                                         if (cp != NULL) {
1003                                                 depe->patterns_total++;
1004                                                 cp++;
1005                                         } else {
1006                                                 break;
1007                                         }
1008                                 }
1009                                 depe->patterns_total++;
1010 
1011                                 /* allocate storage for patterns */
1012                                 depe->patterns = (Name *) getmem(sizeof(Name) * depe->patterns_total);
1013 
1014                                 /* then create patterns */
1015                                 cp = wcb1.get_string();
1016                                 pattern = 0;
1017                                 while (true) {
1018                                         cp1 = (wchar_t *) wcschr(cp, (int) percent_char);
1019                                         if (cp1 != NULL) {
1020                                                 depe->patterns[pattern] = GETNAME(cp, cp1 - cp);
1021                                                 cp = cp1 + 1;
1022                                                 pattern++;
1023                                         } else {
1024                                                 depe->patterns[pattern] = GETNAME(cp, (int) depe->name->hash.length - (cp - wcb1.get_string()));
1025                                                 break;
1026                                         }
1027                                 }
1028                         }
1029                 }
1030         }
1031 
1032         /* Find the end of the percent list and append the new pattern */
1033         for (insert = &percent_list; (*insert) != NULL; insert = &(*insert)->next);
1034         *insert = result;
1035 
1036         if (trace_reader) {
1037                 (void) printf("%s:", result->name->string_mb);
1038 


1551  *
1552  *      Parameters:
1553  *              to              The path we want to make relative
1554  *              result          Where to put the resulting relative path
1555  *
1556  *      Global variables used:
1557  */
1558 static void
1559 make_relative(wchar_t *to, wchar_t *result)
1560 {
1561         wchar_t                 *from;
1562         wchar_t                 *allocated;
1563         wchar_t                 *cp;
1564         wchar_t                 *tocomp;
1565         int                     ncomps;
1566         int                     i;
1567         int                     len;
1568 
1569         /* Check if the path is already relative. */
1570         if (to[0] != (int) slash_char) {
1571                 (void) wcscpy(result, to);
1572                 return;
1573         }
1574 
1575         MBSTOWCS(wcs_buffer, get_current_path());
1576         from = allocated = (wchar_t *) wcsdup(wcs_buffer);
1577 
1578         /*
1579          * Find the number of components in the from name.
1580          * ncomp = number of slashes + 1.
1581          */
1582         ncomps = 1;
1583         for (cp = from; *cp != (int) nul_char; cp++) {
1584                 if (*cp == (int) slash_char) {
1585                         ncomps++;
1586                 }
1587         }
1588 
1589         /*
1590          * See how many components match to determine how many "..",
1591          * if any, will be needed.
1592          */
1593         result[0] = (int) nul_char;
1594         tocomp = to;
1595         while ((*from != (int) nul_char) && (*from == *to)) {
1596                 if (*from == (int) slash_char) {
1597                         ncomps--;
1598                         tocomp = &to[1];
1599                 }
1600                 from++;
1601                 to++;
1602         }
1603 
1604         /*
1605          * Now for some special cases. Check for exact matches and
1606          * for either name terminating exactly.
1607          */
1608         if (*from == (int) nul_char) {
1609                 if (*to == (int) nul_char) {
1610                         MBSTOWCS(wcs_buffer, ".");
1611                         (void) wcscpy(result, wcs_buffer);
1612                         retmem(allocated);
1613                         return;
1614                 }
1615                 if (*to == (int) slash_char) {
1616                         ncomps--;
1617                         tocomp = &to[1];
1618                 }
1619         } else if ((*from == (int) slash_char) && (*to == (int) nul_char)) {
1620                 ncomps--;
1621                 tocomp = to;
1622         }
1623         /* Add on the ".."s. */
1624         for (i = 0; i < ncomps; i++) {
1625                 MBSTOWCS(wcs_buffer, "../");
1626                 (void) wcscat(result, wcs_buffer);
1627         }
1628 
1629         /* Add on the remainder of the to name, if any. */
1630         if (*tocomp == (int) nul_char) {
1631                 len = wcslen(result);
1632                 result[len - 1] = (int) nul_char;
1633         } else {
1634                 (void) wcscat(result, tocomp);
1635         }
1636         retmem(allocated);
1637         return;
1638 }
1639 
1640 /*
1641  *      print_rule(command)
1642  *
1643  *      Used when tracing the reading of rules
1644  *
1645  *      Parameters:
1646  *              command         Command to print
1647  *
1648  *      Global variables used:
1649  */
1650 static void
1651 print_rule(register Cmd_line command)
1652 {
1653         for (; command != NULL; command = command->next) {
1654                 (void) printf("\t%s\n", command->command_line->string_mb);


1789 static void
1790 sh_transform(Name *name, Name *value)
1791 {
1792         /* Check if we need :sh transform */
1793         wchar_t         *colon;
1794         String_rec      command;
1795         String_rec      destination;
1796         wchar_t         buffer[1000];
1797         wchar_t         buffer1[1000];
1798 
1799         static wchar_t  colon_sh[4];
1800         static wchar_t  colon_shell[7];
1801 
1802         if (colon_sh[0] == (int) nul_char) {
1803                 MBSTOWCS(colon_sh, ":sh");
1804                 MBSTOWCS(colon_shell, ":shell");
1805         }
1806         Wstring nms((*name));
1807         wchar_t * wcb = nms.get_string();
1808 
1809         colon = (wchar_t *) wcsrchr(wcb, (int) colon_char);
1810         if ((colon != NULL) && (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell))) {
1811                 INIT_STRING_FROM_STACK(destination, buffer);
1812 
1813                 if(*value == NULL) {
1814                         buffer[0] = 0;
1815                 } else {
1816                         Wstring wcb1((*value));
1817                         if (IS_WEQUAL(colon, colon_shell)) {
1818                                 INIT_STRING_FROM_STACK(command, buffer1);
1819                                 expand_value(*value, &command, false);
1820                         } else {
1821                                 command.text.p = wcb1.get_string() + (*value)->hash.length;
1822                                 command.text.end = command.text.p;
1823                                 command.buffer.start = wcb1.get_string();
1824                                 command.buffer.end = command.text.p;
1825                         }
1826                         sh_command2string(&command, &destination);
1827                 }
1828 
1829                 (*value) = GETNAME(destination.buffer.start, FIND_LENGTH);