diff options
author | Ron Yorston <rmy@pobox.com> | 2024-05-29 17:07:19 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2024-05-29 17:07:19 +0100 |
commit | 2a0923c400fe5df140e1c5aad8dc59f4733e8598 (patch) | |
tree | bea94ec747825a054a5f9d080bf241c1cbec62a1 | |
parent | e46cb57b07b4b2c54e8219a5035ee4dff8a20a4c (diff) | |
download | busybox-w32-2a0923c400fe5df140e1c5aad8dc59f4733e8598.tar.gz busybox-w32-2a0923c400fe5df140e1c5aad8dc59f4733e8598.tar.bz2 busybox-w32-2a0923c400fe5df140e1c5aad8dc59f4733e8598.zip |
make: allow :::= macro assignment on command line
GNU make and bmake have different implementations for := macro
assignment. In POSIX 202X these are supported by the forms ::=
and :::= respectively. Only the former was supported on the
pdpmake command line.
Add the required support in process_macros() and update the usage
message.
Adds 48-64 bytes.
-rw-r--r-- | miscutils/make.c | 44 | ||||
-rwxr-xr-x | testsuite/make.tests | 24 |
2 files changed, 52 insertions, 16 deletions
diff --git a/miscutils/make.c b/miscutils/make.c index a4fecd640..8d5664500 100644 --- a/miscutils/make.c +++ b/miscutils/make.c | |||
@@ -51,10 +51,10 @@ | |||
51 | 51 | ||
52 | //usage:#define make_trivial_usage | 52 | //usage:#define make_trivial_usage |
53 | //usage: IF_FEATURE_MAKE_POSIX( | 53 | //usage: IF_FEATURE_MAKE_POSIX( |
54 | //usage: "[--posix] [-C DIR] [-f FILE] [-j NUM] [-x PRAG] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..." | 54 | //usage: "[--posix] [-C DIR] [-f FILE] [-j NUM] [-x PRAG] [-eiknpqrsSt] [MACRO[::[:]]=VAL]... [TARGET]..." |
55 | //usage: ) | 55 | //usage: ) |
56 | //usage: IF_NOT_FEATURE_MAKE_POSIX( | 56 | //usage: IF_NOT_FEATURE_MAKE_POSIX( |
57 | //usage: "[-C DIR] [-f FILE] [-j NUM] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..." | 57 | //usage: "[-C DIR] [-f FILE] [-j NUM] [-eiknpqrsSt] [MACRO[::[:]]=VAL]... [TARGET]..." |
58 | //usage: ) | 58 | //usage: ) |
59 | //usage:#define make_full_usage "\n\n" | 59 | //usage:#define make_full_usage "\n\n" |
60 | //usage: "Maintain files based on their dependencies\n" | 60 | //usage: "Maintain files based on their dependencies\n" |
@@ -2837,12 +2837,14 @@ expand_makeflags(void) | |||
2837 | static char ** | 2837 | static char ** |
2838 | process_macros(char **argv, int level) | 2838 | process_macros(char **argv, int level) |
2839 | { | 2839 | { |
2840 | char *p; | 2840 | char *equal; |
2841 | 2841 | ||
2842 | for (; *argv; argv++) { | 2842 | for (; *argv; argv++) { |
2843 | char *colon = NULL; | ||
2843 | int idx, immediate = 0; | 2844 | int idx, immediate = 0; |
2845 | int except_dollar = FALSE; | ||
2844 | 2846 | ||
2845 | if (!(p = strchr(*argv, '='))) { | 2847 | if (!(equal = strchr(*argv, '='))) { |
2846 | // Skip targets on the command line | 2848 | // Skip targets on the command line |
2847 | if (!posix && level == 1) | 2849 | if (!posix && level == 1) |
2848 | continue; | 2850 | continue; |
@@ -2851,13 +2853,23 @@ process_macros(char **argv, int level) | |||
2851 | break; | 2853 | break; |
2852 | } | 2854 | } |
2853 | 2855 | ||
2854 | if (p - 2 > *argv && p[-1] == ':' && p[-2] == ':') { | 2856 | if (equal - 2 > *argv && equal[-1] == ':' && equal[-2] == ':') { |
2855 | if (POSIX_2017) | 2857 | if (POSIX_2017) |
2856 | error("invalid macro assignment"); | 2858 | error("invalid macro assignment"); |
2857 | immediate = M_IMMEDIATE; | 2859 | if (equal - 3 > *argv && equal[-3] == ':') { |
2858 | p[-2] = '\0'; | 2860 | // BSD-style ':='. Expand RHS, but not '$$', |
2861 | // resulting macro is delayed expansion. | ||
2862 | colon = equal - 3; | ||
2863 | except_dollar = TRUE; | ||
2864 | } else { | ||
2865 | // GNU-style ':='. Expand RHS, including '$$', | ||
2866 | // resulting macro is immediate expansion. | ||
2867 | colon = equal - 2; | ||
2868 | immediate = M_IMMEDIATE; | ||
2869 | } | ||
2870 | *colon = '\0'; | ||
2859 | } else | 2871 | } else |
2860 | *p = '\0'; | 2872 | *equal = '\0'; |
2861 | 2873 | ||
2862 | /* We want to process _most_ macro assignments. | 2874 | /* We want to process _most_ macro assignments. |
2863 | * There are exceptions for particular values from the | 2875 | * There are exceptions for particular values from the |
@@ -2866,18 +2878,18 @@ process_macros(char **argv, int level) | |||
2866 | if (!(level == 3 && | 2878 | if (!(level == 3 && |
2867 | (idx == MAKEFLAGS || idx == SHELL || | 2879 | (idx == MAKEFLAGS || idx == SHELL || |
2868 | (idx == CURDIR && !useenv && !POSIX_2017)))) { | 2880 | (idx == CURDIR && !useenv && !POSIX_2017)))) { |
2869 | if (immediate) { | 2881 | if (colon) { |
2870 | char *exp = expand_macros(p + 1, FALSE); | 2882 | char *exp = expand_macros(equal + 1, except_dollar); |
2871 | setmacro(*argv, exp, level | immediate); | 2883 | setmacro(*argv, exp, level | immediate); |
2872 | free(exp); | 2884 | free(exp); |
2873 | } else { | 2885 | } else |
2874 | setmacro(*argv, p + 1, level); | 2886 | setmacro(*argv, equal + 1, level); |
2875 | } | ||
2876 | } | 2887 | } |
2877 | 2888 | ||
2878 | *p = '='; | 2889 | if (colon) |
2879 | if (immediate) | 2890 | *colon = ':'; |
2880 | p[-2] = ':'; | 2891 | else |
2892 | *equal = '='; | ||
2881 | } | 2893 | } |
2882 | return argv; | 2894 | return argv; |
2883 | } | 2895 | } |
diff --git a/testsuite/make.tests b/testsuite/make.tests index bac673178..0397ab4de 100755 --- a/testsuite/make.tests +++ b/testsuite/make.tests | |||
@@ -176,6 +176,30 @@ target: | |||
176 | @echo $(reset) | 176 | @echo $(reset) |
177 | ' | 177 | ' |
178 | 178 | ||
179 | # Since GNU make and bmake interpret := macro assignments differently, | ||
180 | # POSIX has ::= for the GNU variant and :::= for BSD. | ||
181 | testing "make different styles of := macro assignment" \ | ||
182 | "make -f -" \ | ||
183 | '65 a a $A\n' "" ' | ||
184 | A = a | ||
185 | GNU ::= $A | ||
186 | BSD1 :::= $A | ||
187 | BSD2 :::= $$A | ||
188 | A = 65 | ||
189 | |||
190 | target: | ||
191 | @echo '\''$(A) $(GNU) $(BSD1) $(BSD2)'\'' | ||
192 | ' | ||
193 | |||
194 | # Similar to the above but for macro assignments on the command line. | ||
195 | # POSIX has ::= for the GNU variant and :::= for BSD. | ||
196 | testing "make := macro assignment on command line" \ | ||
197 | "make -f - A=a 'GNU::=\$A' 'BSD1:::=\$A' 'BSD2:::=\$\$A' A=65" \ | ||
198 | '65 a a $A\n' "" ' | ||
199 | target: | ||
200 | @echo '\''$(A) $(GNU) $(BSD1) $(BSD2)'\'' | ||
201 | ' | ||
202 | |||
179 | # basic pattern macro expansion | 203 | # basic pattern macro expansion |
180 | testing "make basic pattern macro expansion" \ | 204 | testing "make basic pattern macro expansion" \ |
181 | "make -f -" \ | 205 | "make -f -" \ |