diff options
| author | dsl <dsl@NetBSD.org> | 2008-11-29 14:42:21 +0000 |
|---|---|---|
| committer | dsl <dsl@NetBSD.org> | 2008-11-29 14:42:21 +0000 |
| commit | 34a8d95d663e40fe4dfd46c2c1d36508af660b1c (patch) | |
| tree | 30ff80366c69f2308aea2a605171e2e12d8176eb /usr.bin | |
| parent | b8ee15c2f2cc3b416a8ec07b4e31a7f4150501ad (diff) | |
Before deciding to use the default function in a .if, check whether the
token that follows the argument might be '==' or '!='.
If so then treat as a string comparison instead.
Fixes bin/15233 and bin/30967 provided some whitespace is present.
".if A==A" remains a check for defined(A==A) since make places no
restrictions on the names of variables!
Diffstat (limited to 'usr.bin')
| -rw-r--r-- | usr.bin/make/cond.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/usr.bin/make/cond.c b/usr.bin/make/cond.c index 6a177f2165b..d0ad4c8bc7e 100644 --- a/usr.bin/make/cond.c +++ b/usr.bin/make/cond.c @@ -1,4 +1,4 @@ -/* $NetBSD: cond.c,v 1.47 2008/11/29 14:12:48 dsl Exp $ */ +/* $NetBSD: cond.c,v 1.48 2008/11/29 14:42:21 dsl Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: cond.c,v 1.47 2008/11/29 14:12:48 dsl Exp $"; +static char rcsid[] = "$NetBSD: cond.c,v 1.48 2008/11/29 14:42:21 dsl Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94"; #else -__RCSID("$NetBSD: cond.c,v 1.47 2008/11/29 14:12:48 dsl Exp $"); +__RCSID("$NetBSD: cond.c,v 1.48 2008/11/29 14:42:21 dsl Exp $"); #endif #endif /* not lint */ #endif @@ -874,6 +874,7 @@ compare_function(Boolean doEval) char *arg = NULL; int arglen; char *cp = condExpr; + char *cp1; for (fn_def = fn_defs; fn_def->fn_name != NULL; fn_def++) { if (!istoken(cp, fn_def->fn_name, fn_def->fn_name_len)) @@ -902,14 +903,30 @@ compare_function(Boolean doEval) } /* Push anything numeric through the compare expression */ - if (isdigit((unsigned char)condExpr[0]) || strchr("+-", condExpr[0])) + cp = condExpr; + if (isdigit((unsigned char)cp[0]) || strchr("+-", cp[0])) return compare_expression(doEval); /* + * Most likely we have a naked token to apply the default function to. + * However ".if a == b" gets here when the "a" is unquoted and doesn't + * start with a '$'. This surprises people - especially given the way + * that for loops get expanded. + * If what follows the function argument is a '=' or '!' then the syntax + * would be invalid if we did "defined(a)" - so instead treat as an + * expression. + */ + arglen = CondGetArg(&cp, &arg, "", FALSE); + for (cp1 = cp; isspace(*(unsigned char *)cp1); cp1++) + continue; + if (*cp1 == '=' || *cp1 == '!') + return compare_expression(doEval); + condExpr = cp; + + /* * Evaluate the argument using the default function. If invert * is TRUE, we invert the sense of the result. */ - arglen = CondGetArg(&condExpr, &arg, "", FALSE); t = !doEval || (* condDefProc)(arglen, arg) != condInvert ? True : False; if (arg) free(arg); |
