- New code capability: a read-only string cache. Start of solution for

Savannah bug #15182, but not much uses it yet.  Coming shortly.
- Added short-circuiting $(and ..) and $(or ...) functions.
This commit is contained in:
Paul Smith
2006-02-10 05:29:00 +00:00
parent d0c4e92f11
commit 5a7a42cfce
15 changed files with 530 additions and 67 deletions

View File

@@ -1230,6 +1230,110 @@ func_if (char *o, char **argv, const char *funcname UNUSED)
return o;
}
/*
$(or condition1[,condition2[,condition3[...]]])
A CONDITION is false iff it evaluates to an empty string. White
space before and after CONDITION are stripped before evaluation.
CONDITION1 is evaluated. If it's true, then this is the result of
expansion. If it's false, CONDITION2 is evaluated, and so on. If none of
the conditions are true, the expansion is the empty string.
Once a CONDITION is true no further conditions are evaluated
(short-circuiting).
*/
static char *
func_or (char *o, char **argv, const char *funcname UNUSED)
{
for ( ; *argv ; ++argv)
{
const char *begp = *argv;
const char *endp = begp + strlen (*argv) - 1;
char *expansion;
int result = 0;
/* Find the result of the condition: if it's false keep going. */
strip_whitespace (&begp, &endp);
if (begp > endp)
continue;
expansion = expand_argument (begp, endp+1);
result = strlen (expansion);
/* If the result is false keep going. */
if (!result)
{
free (expansion);
continue;
}
/* It's true! Keep this result and return. */
o = variable_buffer_output (o, expansion, result);
free (expansion);
break;
}
return o;
}
/*
$(and condition1[,condition2[,condition3[...]]])
A CONDITION is false iff it evaluates to an empty string. White
space before and after CONDITION are stripped before evaluation.
CONDITION1 is evaluated. If it's false, then this is the result of
expansion. If it's true, CONDITION2 is evaluated, and so on. If all of
the conditions are true, the expansion is the result of the last condition.
Once a CONDITION is false no further conditions are evaluated
(short-circuiting).
*/
static char *
func_and (char *o, char **argv, const char *funcname UNUSED)
{
char *expansion;
int result;
while (1)
{
const char *begp = *argv;
const char *endp = begp + strlen (*argv) - 1;
/* An empty condition is always false. */
strip_whitespace (&begp, &endp);
if (begp > endp)
return o;
expansion = expand_argument (begp, endp+1);
result = strlen (expansion);
/* If the result is false, stop here: we're done. */
if (!result)
break;
/* Otherwise the result is true. If this is the last one, keep this
result and quit. Otherwise go on to the next one! */
if (*(++argv))
free (expansion);
else
{
o = variable_buffer_output (o, expansion, result);
break;
}
}
free (expansion);
return o;
}
static char *
func_wildcard (char *o, char **argv, const char *funcname UNUSED)
{
@@ -1977,6 +2081,8 @@ static struct function_table_entry function_table_init[] =
{ STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error},
{ STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error},
{ STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if},
{ STRING_SIZE_TUPLE("or"), 1, 0, 0, func_or},
{ STRING_SIZE_TUPLE("and"), 1, 0, 0, func_and},
{ STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value},
{ STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval},
#ifdef EXPERIMENTAL