Add new feature: != shell assignment for portability with BSD make.

Feature submitted by David Wheeler.
This commit is contained in:
Paul Smith
2011-04-18 01:25:20 +00:00
parent 1454a04f81
commit b34438bee8
10 changed files with 213 additions and 17 deletions

View File

@@ -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)