aboutsummaryrefslogtreecommitdiff
path: root/miscutils
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 /miscutils
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.
Diffstat (limited to 'miscutils')
-rw-r--r--miscutils/make.c27
1 files changed, 18 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);