From 2a0923c400fe5df140e1c5aad8dc59f4733e8598 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Wed, 29 May 2024 17:07:19 +0100 Subject: 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. --- miscutils/make.c | 44 ++++++++++++++++++++++++++++---------------- 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 @@ //usage:#define make_trivial_usage //usage: IF_FEATURE_MAKE_POSIX( -//usage: "[--posix] [-C DIR] [-f FILE] [-j NUM] [-x PRAG] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..." +//usage: "[--posix] [-C DIR] [-f FILE] [-j NUM] [-x PRAG] [-eiknpqrsSt] [MACRO[::[:]]=VAL]... [TARGET]..." //usage: ) //usage: IF_NOT_FEATURE_MAKE_POSIX( -//usage: "[-C DIR] [-f FILE] [-j NUM] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..." +//usage: "[-C DIR] [-f FILE] [-j NUM] [-eiknpqrsSt] [MACRO[::[:]]=VAL]... [TARGET]..." //usage: ) //usage:#define make_full_usage "\n\n" //usage: "Maintain files based on their dependencies\n" @@ -2837,12 +2837,14 @@ expand_makeflags(void) static char ** process_macros(char **argv, int level) { - char *p; + char *equal; for (; *argv; argv++) { + char *colon = NULL; int idx, immediate = 0; + int except_dollar = FALSE; - if (!(p = strchr(*argv, '='))) { + if (!(equal = strchr(*argv, '='))) { // Skip targets on the command line if (!posix && level == 1) continue; @@ -2851,13 +2853,23 @@ process_macros(char **argv, int level) break; } - if (p - 2 > *argv && p[-1] == ':' && p[-2] == ':') { + if (equal - 2 > *argv && equal[-1] == ':' && equal[-2] == ':') { if (POSIX_2017) error("invalid macro assignment"); - immediate = M_IMMEDIATE; - p[-2] = '\0'; + if (equal - 3 > *argv && equal[-3] == ':') { + // BSD-style ':='. Expand RHS, but not '$$', + // resulting macro is delayed expansion. + colon = equal - 3; + except_dollar = TRUE; + } else { + // GNU-style ':='. Expand RHS, including '$$', + // resulting macro is immediate expansion. + colon = equal - 2; + immediate = M_IMMEDIATE; + } + *colon = '\0'; } else - *p = '\0'; + *equal = '\0'; /* We want to process _most_ macro assignments. * There are exceptions for particular values from the @@ -2866,18 +2878,18 @@ process_macros(char **argv, int level) if (!(level == 3 && (idx == MAKEFLAGS || idx == SHELL || (idx == CURDIR && !useenv && !POSIX_2017)))) { - if (immediate) { - char *exp = expand_macros(p + 1, FALSE); + if (colon) { + char *exp = expand_macros(equal + 1, except_dollar); setmacro(*argv, exp, level | immediate); free(exp); - } else { - setmacro(*argv, p + 1, level); - } + } else + setmacro(*argv, equal + 1, level); } - *p = '='; - if (immediate) - p[-2] = ':'; + if (colon) + *colon = ':'; + else + *equal = '='; } return argv; } 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: @echo $(reset) ' +# Since GNU make and bmake interpret := macro assignments differently, +# POSIX has ::= for the GNU variant and :::= for BSD. +testing "make different styles of := macro assignment" \ + "make -f -" \ + '65 a a $A\n' "" ' +A = a +GNU ::= $A +BSD1 :::= $A +BSD2 :::= $$A +A = 65 + +target: + @echo '\''$(A) $(GNU) $(BSD1) $(BSD2)'\'' +' + +# Similar to the above but for macro assignments on the command line. +# POSIX has ::= for the GNU variant and :::= for BSD. +testing "make := macro assignment on command line" \ + "make -f - A=a 'GNU::=\$A' 'BSD1:::=\$A' 'BSD2:::=\$\$A' A=65" \ + '65 a a $A\n' "" ' +target: + @echo '\''$(A) $(GNU) $(BSD1) $(BSD2)'\'' +' + # basic pattern macro expansion testing "make basic pattern macro expansion" \ "make -f -" \ -- cgit v1.2.3-55-g6feb