diff options
author | Ron Yorston <rmy@pobox.com> | 2022-11-16 14:27:34 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2022-11-16 14:27:34 +0000 |
commit | 04e7f6dd0fc57ab98f39fb6fc9df610d0737ff17 (patch) | |
tree | 945247f2283a290c082b1292021e9fe87aae7d10 /miscutils | |
parent | f3f72ac1d2a56b97c6e90aa359ad236f528b5294 (diff) | |
download | busybox-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.c | 27 |
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 | */ |
915 | static char * | 915 | static char * |
916 | modify_words(const char *val, int modifier, size_t lenf, | 916 | modify_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); |