From eaa8695b76849d8156826a8919a591555c81a3dd Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Wed, 22 May 2024 08:58:13 +0100 Subject: make: add support for CURDIR macro Austin Group defect report 1626 introduced support for the CURDIR macro: https://www.austingroupbugs.net/view.php?id=1626 Implement this as a POSIX 202X feature. Adds 160-176 bytes. --- miscutils/make.c | 33 ++++++++++++++++++++++++++++----- testsuite/make.tests | 25 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/miscutils/make.c b/miscutils/make.c index fca00d8e3..f594e196b 100644 --- a/miscutils/make.c +++ b/miscutils/make.c @@ -2681,9 +2681,10 @@ expand_makeflags(void) } // These macros require special treatment -#define MAKEFLAGS_SHELL "MAKEFLAGS\0SHELL\0" +#define SPECIAL_MACROS "MAKEFLAGS\0SHELL\0CURDIR\0" #define MAKEFLAGS 0 #define SHELL 1 +#define CURDIR 2 /* * Instantiate all macros in an argv-style array of pointers. Stop @@ -2697,7 +2698,7 @@ process_macros(char **argv, int level) char *p; for (; *argv; argv++) { - int immediate = 0; + int idx, immediate = 0; if (!(p = strchr(*argv, '='))) { // Skip targets on the command line @@ -2714,8 +2715,15 @@ process_macros(char **argv, int level) immediate = M_IMMEDIATE; p[-2] = '\0'; } else - *p = '\0'; - if (level != 3 || index_in_strings(MAKEFLAGS_SHELL, *argv) < 0) { + *p = '\0'; + + /* We want to process _most_ macro assignments. + * There are exceptions for particular values from the + * environment (level 3). */ + idx = index_in_strings(SPECIAL_MACROS, *argv); + if (!(level == 3 && + (idx == MAKEFLAGS || idx == SHELL || + (idx == CURDIR && !useenv && !POSIX_2017)))) { if (immediate) { char *exp = expand_macros(p + 1, FALSE); setmacro(*argv, exp, level | immediate); @@ -2724,6 +2732,7 @@ process_macros(char **argv, int level) setmacro(*argv, p + 1, level); } } + *p = '='; if (immediate) p[-2] = ':'; @@ -2766,7 +2775,7 @@ update_makeflags(void) for (i = 0; i < HTABSIZE; ++i) { for (mp = macrohead[i]; mp; mp = mp->m_next) { if (mp->m_level == 1 || mp->m_level == 2) { - int idx = index_in_strings(MAKEFLAGS_SHELL, mp->m_name); + int idx = index_in_strings(SPECIAL_MACROS, mp->m_name); if (idx == MAKEFLAGS) continue; macro = xzalloc(strlen(mp->m_name) + 2 * strlen(mp->m_val) + 1); @@ -2960,6 +2969,20 @@ int make_main(int argc UNUSED_PARAM, char **argv) setmacro("SHELL", DEFAULT_SHELL, 4); setmacro("MAKE", path, 4); + if (!POSIX_2017) { + char *cwd = xrealloc_getcwd_or_warn(NULL); + + if (cwd) { + if (!useenv) { + // Export cwd to environment, if necessary + char *envcwd = getenv("CURDIR"); + if (envcwd && strcmp(cwd, envcwd) != 0) + setenv("CURDIR", cwd, 1); + } + setmacro("CURDIR", cwd, 4); + } + free(cwd); + } free((void *)newpath); if (!makefiles) { // Look for a default Makefile diff --git a/testsuite/make.tests b/testsuite/make.tests index 546dca7d5..fdbb4ccfc 100755 --- a/testsuite/make.tests +++ b/testsuite/make.tests @@ -377,6 +377,31 @@ target: b} ' +# The CURDIR macro is supported in POSIX 202X. +testing "make CURDIR macro" \ + "make -f -" \ + "OK\n" "" ' +target: + @test "$(CURDIR)" = "$$(pwd)" && echo OK +' +# The CURDIR environment variable doesn't affect the macro +export CURDIR=/you/are/here +testing "make CURDIR macro not affected by environment" \ + "make -f -" \ + "OK\n" "" ' +target: + @test "$(CURDIR)" != "/you/are/here" && echo OK +' + +# The -e option makes the CURDIR macro match the environment +testing "make with -e CURDIR macro is affected by the environment" \ + "make -e -f -" \ + "/you/are/here\n" "" ' +target: + @echo $(CURDIR) +' +unset CURDIR + # POSIX 202X permits additional characters in macro and target names testing "make allow - and / in target names, - in macro names" \ "make -f -" \ -- cgit v1.2.3-55-g6feb