From b34438bee83ee906a23b881f257e684a0993b9b1 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Mon, 18 Apr 2011 01:25:20 +0000 Subject: Add new feature: != shell assignment for portability with BSD make. Feature submitted by David Wheeler. --- variable.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'variable.c') diff --git a/variable.c b/variable.c index b699088..d0b0b0a 100644 --- a/variable.c +++ b/variable.c @@ -1111,6 +1111,29 @@ set_special_var (struct variable *var) return var; } +/* Given a string, shell-execute it and return a malloc'ed string of the + * result. This removes only ONE newline (if any) at the end, for maximum + * compatibility with the *BSD makes. If it fails, returns NULL. */ + +char * +shell_result (const char *p) +{ + char *buf; + unsigned int len; + char *args[2]; + char *result; + + install_variable_buffer (&buf, &len); + + args[0] = (char *) p; + args[1] = NULL; + variable_buffer_output (func_shell_base (variable_buffer, args, 0), "\0", 1); + result = strdup (variable_buffer); + + restore_variable_buffer (buf, len); + return result; +} + /* Given a variable, a value, and a flavor, define the variable. See the try_variable_definition() function for details on the parameters. */ @@ -1140,6 +1163,16 @@ do_variable_definition (const struct floc *flocp, const char *varname, target-specific variable. */ p = alloc_value = allocated_variable_expand (value); break; + case f_shell: + { + /* A shell definition "var != value". Expand value, pass it to + the shell, and store the result in recursively-expanded var. */ + char *q = allocated_variable_expand (value); + p = alloc_value = shell_result (q); + free (q); + flavor = f_recursive; + break; + } case f_conditional: /* A conditional variable definition "var ?= value". The value is set IFF the variable is not defined yet. */ @@ -1432,7 +1465,7 @@ parse_variable_definition (const char *p, enum variable_flavor *flavor) return (char *)p; } - /* Match assignment variants (:=, +=, ?=) */ + /* Match assignment variants (:=, +=, ?=, !=) */ if (*p == '=') { switch (c) @@ -1446,6 +1479,9 @@ parse_variable_definition (const char *p, enum variable_flavor *flavor) case '?': *flavor = f_conditional; break; + case '!': + *flavor = f_shell; + break; default: /* If we skipped whitespace, non-assignments means no var. */ if (wspace) -- cgit v1.2.3