aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2022-11-16 14:27:34 +0000
committerRon Yorston <rmy@pobox.com>2022-11-16 14:27:34 +0000
commit04e7f6dd0fc57ab98f39fb6fc9df610d0737ff17 (patch)
tree945247f2283a290c082b1292021e9fe87aae7d10
parentf3f72ac1d2a56b97c6e90aa359ad236f528b5294 (diff)
downloadbusybox-w32-04e7f6dd0fc57ab98f39fb6fc9df610d0737ff17.tar.gz
busybox-w32-04e7f6dd0fc57ab98f39fb6fc9df610d0737ff17.tar.bz2
busybox-w32-04e7f6dd0fc57ab98f39fb6fc9df610d0737ff17.zip
make: changes to suffix substitution in macro expansion
The POSIX standard defines suffix substitution in macro expansion as taking the form: $(string1 [: subst1 =[ subst2 ]]) Since 'subst1' isn't bracketed a value must be supplied. Enforce this in POSIX mode. As a non-POSIX extension an empty 'subst1' is permitted with 'subst2' being added to all words unconditionally. If both 'subst1' and 'subst2' are empty the words are returned unchanged.
-rw-r--r--miscutils/make.c27
-rwxr-xr-xtestsuite/make.tests11
2 files changed, 29 insertions, 9 deletions
diff --git a/miscutils/make.c b/miscutils/make.c
index 1104dfe87..941aa49e3 100644
--- a/miscutils/make.c
+++ b/miscutils/make.c
@@ -913,14 +913,14 @@ skip_macro(const char *s)
913 * Returns an allocated string or NULL if the input is unmodified. 913 * Returns an allocated string or NULL if the input is unmodified.
914 */ 914 */
915static char * 915static char *
916modify_words(const char *val, int modifier, size_t lenf, 916modify_words(const char *val, int modifier, size_t lenf, size_t lenr,
917 const char *find_pref, const char *repl_pref, 917 const char *find_pref, const char *repl_pref,
918 const char *find_suff, const char *repl_suff) 918 const char *find_suff, const char *repl_suff)
919{ 919{
920 char *s, *copy, *word, *sep, *buf = NULL; 920 char *s, *copy, *word, *sep, *buf = NULL;
921 size_t find_pref_len = 0, find_suff_len = 0; 921 size_t find_pref_len = 0, find_suff_len = 0;
922 922
923 if (!modifier && !lenf) 923 if (!modifier && lenf == 0 && lenr == 0)
924 return buf; 924 return buf;
925 925
926 if (find_pref) { 926 if (find_pref) {
@@ -948,14 +948,18 @@ modify_words(const char *val, int modifier, size_t lenf,
948 word = sep + 1; 948 word = sep + 1;
949 } 949 }
950 } 950 }
951 if (lenf) { 951 if (find_pref != NULL || lenf != 0 || lenr != 0) {
952 size_t lenw = strlen(word); 952 size_t lenw = strlen(word);
953 // This code implements pattern macro expansions: 953 // This code implements pattern macro expansions:
954 // https://austingroupbugs.net/view.php?id=519 954 // https://austingroupbugs.net/view.php?id=519
955 // 955 //
956 // find: <prefix>%<suffix> 956 // find: <prefix>%<suffix>
957 // example: src/%.c 957 // example: src/%.c
958 if (lenw >= lenf - 1 && find_pref) { 958 //
959 // For a pattern of the form:
960 // $(string1:[op]%[os]=[np][%][ns])
961 // lenf is the length of [op]%[os]. So lenf >= 1.
962 if (find_pref != NULL && lenw + 1 >= lenf) {
959 // If prefix and suffix of word match find_pref and 963 // If prefix and suffix of word match find_pref and
960 // find_suff, then do substitution. 964 // find_suff, then do substitution.
961 if (strncmp(word, find_pref, find_pref_len) == 0 && 965 if (strncmp(word, find_pref, find_pref_len) == 0 &&
@@ -1011,7 +1015,7 @@ expand_macros(const char *str, int except_dollar)
1011 char *find, *replace, *modified; 1015 char *find, *replace, *modified;
1012 char *expval, *expfind, *find_suff, *repl_suff; 1016 char *expval, *expfind, *find_suff, *repl_suff;
1013 char *find_pref = NULL, *repl_pref = NULL; 1017 char *find_pref = NULL, *repl_pref = NULL;
1014 size_t lenf; 1018 size_t lenf, lenr;
1015 char modifier; 1019 char modifier;
1016 struct macro *mp; 1020 struct macro *mp;
1017 1021
@@ -1041,11 +1045,13 @@ expand_macros(const char *str, int except_dollar)
1041 } 1045 }
1042 1046
1043 // Only do suffix replacement or pattern macro expansion 1047 // Only do suffix replacement or pattern macro expansion
1044 // if both ':' and '=' are found. This is indicated by 1048 // if both ':' and '=' are found, plus a '%' for the latter.
1045 // lenf != 0. 1049 // Suffix replacement is indicated by
1050 // find_pref == NULL && (lenf != 0 || lenr != 0);
1051 // pattern macro expansion by find_pref != NULL.
1046 expfind = NULL; 1052 expfind = NULL;
1047 find_suff = repl_suff = NULL; 1053 find_suff = repl_suff = NULL;
1048 lenf = 0; 1054 lenf = lenr = 0;
1049 if ((find = find_char(name, ':'))) { 1055 if ((find = find_char(name, ':'))) {
1050 *find++ = '\0'; 1056 *find++ = '\0';
1051 expfind = expand_macros(find, FALSE); 1057 expfind = expand_macros(find, FALSE);
@@ -1059,8 +1065,11 @@ expand_macros(const char *str, int except_dollar)
1059 if ((repl_suff = strchr(replace, '%'))) 1065 if ((repl_suff = strchr(replace, '%')))
1060 *repl_suff++ = '\0'; 1066 *repl_suff++ = '\0';
1061 } else { 1067 } else {
1068 if (posix && lenf == 0)
1069 error("empty suffix");
1062 find_suff = expfind; 1070 find_suff = expfind;
1063 repl_suff = replace; 1071 repl_suff = replace;
1072 lenr = strlen(repl_suff);
1064 } 1073 }
1065 } 1074 }
1066 } 1075 }
@@ -1105,7 +1114,7 @@ expand_macros(const char *str, int except_dollar)
1105 mp->m_flag = TRUE; 1114 mp->m_flag = TRUE;
1106 expval = expand_macros(mp->m_val, FALSE); 1115 expval = expand_macros(mp->m_val, FALSE);
1107 mp->m_flag = FALSE; 1116 mp->m_flag = FALSE;
1108 modified = modify_words(expval, modifier, lenf, 1117 modified = modify_words(expval, modifier, lenf, lenr,
1109 find_pref, repl_pref, find_suff, repl_suff); 1118 find_pref, repl_pref, find_suff, repl_suff);
1110 if (modified) 1119 if (modified)
1111 free(expval); 1120 free(expval);
diff --git a/testsuite/make.tests b/testsuite/make.tests
index 8a0f1a7d2..7749bed52 100755
--- a/testsuite/make.tests
+++ b/testsuite/make.tests
@@ -450,6 +450,17 @@ test.b:
450' 450'
451cd .. || exit 1; rm -rf make.tempdir 2>/dev/null 451cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
452 452
453# An empty original suffix indicates that every word should have
454# the new suffix added. If neither suffix is provided the words
455# remain unchanged.
456testing "make macro expansion and suffix substitution 3" \
457 "make -f -" "src1.c src2.c\nsrc1 src2\n" "" '
458SRCS = src1 src2
459target:
460 @echo $(SRCS:=.c)
461 @echo $(SRCS:=)
462'
463
453# Skip duplicate entries in $? and $^ 464# Skip duplicate entries in $? and $^
454mkdir make.tempdir && cd make.tempdir || exit 1 465mkdir make.tempdir && cd make.tempdir || exit 1
455touch -t 202206171200 file1 file3 466touch -t 202206171200 file1 file3