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);
|