summaryrefslogtreecommitdiff
path: root/variable.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2011-04-18 01:25:20 +0000
committerPaul Smith <psmith@gnu.org>2011-04-18 01:25:20 +0000
commitb34438bee83ee906a23b881f257e684a0993b9b1 (patch)
tree0e3e16d626762ad9341d6fad782a12080c795c45 /variable.c
parent1454a04f81708850353dbdc0807a099c5aaab55b (diff)
downloadgunmake-b34438bee83ee906a23b881f257e684a0993b9b1.tar.gz
Add new feature: != shell assignment for portability with BSD make.
Feature submitted by David Wheeler.
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c38
1 files changed, 37 insertions, 1 deletions
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)