Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/make make(1): add tests for really strange edge case...
details: https://anonhg.NetBSD.org/src/rev/51330cb606d5
branches: trunk
changeset: 954800:51330cb606d5
user: rillig <rillig%NetBSD.org@localhost>
date: Fri Sep 11 06:47:42 2020 +0000
description:
make(1): add tests for really strange edge cases in conditions
diffstat:
usr.bin/make/cond.c | 29 +++++++-----
usr.bin/make/unit-tests/cond-token-plain.exp | 17 +++++++
usr.bin/make/unit-tests/cond-token-plain.mk | 62 +++++++++++++++++++++++++++-
3 files changed, 94 insertions(+), 14 deletions(-)
diffs (184 lines):
diff -r 669c3eec1425 -r 51330cb606d5 usr.bin/make/cond.c
--- a/usr.bin/make/cond.c Fri Sep 11 06:40:25 2020 +0000
+++ b/usr.bin/make/cond.c Fri Sep 11 06:47:42 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cond.c,v 1.127 2020/09/11 06:08:10 rillig Exp $ */
+/* $NetBSD: cond.c,v 1.128 2020/09/11 06:47:42 rillig 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.127 2020/09/11 06:08:10 rillig Exp $";
+static char rcsid[] = "$NetBSD: cond.c,v 1.128 2020/09/11 06:47:42 rillig 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.127 2020/09/11 06:08:10 rillig Exp $");
+__RCSID("$NetBSD: cond.c,v 1.128 2020/09/11 06:47:42 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -985,7 +985,12 @@
static CondEvalResult
CondParser_Eval(CondParser *par, Boolean *value)
{
- Token res = CondParser_Expr(par, TRUE);
+ Token res;
+
+ if (DEBUG(COND))
+ fprintf(debug_file, "CondParser_Eval: %s\n", par->p);
+
+ res = CondParser_Expr(par, TRUE);
if (res != TOK_FALSE && res != TOK_TRUE)
return COND_INVALID;
@@ -996,9 +1001,9 @@
return COND_PARSE;
}
-/* Evaluate the condition in the passed line, including any side effects from
- * the variable expressions in the condition. The condition consists of &&,
- * ||, !, function(arg), comparisons and parenthetical groupings thereof.
+/* Evaluate the condition, including any side effects from the variable
+ * expressions in the condition. The condition consists of &&, ||, !,
+ * function(arg), comparisons and parenthetical groupings thereof.
*
* Results:
* COND_PARSE if the condition was valid grammatically
@@ -1007,7 +1012,7 @@
* (*value) is set to the boolean value of the condition
*/
CondEvalResult
-Cond_EvalExpression(const struct If *info, const char *line, Boolean *value,
+Cond_EvalExpression(const struct If *info, const char *cond, Boolean *value,
int eprint, Boolean strictLHS)
{
static const struct If *dflt_info;
@@ -1016,8 +1021,8 @@
lhsStrict = strictLHS;
- while (*line == ' ' || *line == '\t')
- line++;
+ while (*cond == ' ' || *cond == '\t')
+ cond++;
if (info == NULL && (info = dflt_info) == NULL) {
/* Scan for the entry for .if - it can't be first */
@@ -1029,13 +1034,13 @@
assert(info != NULL);
par.if_info = info;
- par.p = line;
+ par.p = cond;
par.curr = TOK_NONE;
rval = CondParser_Eval(&par, value);
if (rval == COND_INVALID && eprint)
- Parse_Error(PARSE_FATAL, "Malformed conditional (%s)", line);
+ Parse_Error(PARSE_FATAL, "Malformed conditional (%s)", cond);
return rval;
}
diff -r 669c3eec1425 -r 51330cb606d5 usr.bin/make/unit-tests/cond-token-plain.exp
--- a/usr.bin/make/unit-tests/cond-token-plain.exp Fri Sep 11 06:40:25 2020 +0000
+++ b/usr.bin/make/unit-tests/cond-token-plain.exp Fri Sep 11 06:47:42 2020 +0000
@@ -1,1 +1,18 @@
+CondParser_Eval: ${:Uvalue} != value
+lhs = "value", rhs = "value", op = !=
+CondParser_Eval: ${:U} != "
+lhs = "", rhs = "", op = !=
+CondParser_Eval: ${:U#hash} != "#hash"
+lhs = "#hash", rhs = "#hash", op = !=
+CondParser_Eval: ${:U\\} != "\\
+lhs = "\", rhs = "\", op = !=
+CondParser_Eval: ${:U#hash} != #hash
+lhs = "#hash", rhs = "#hash", op = !=
+CondParser_Eval: 0 # This is treated as a comment, but why?
+CondParser_Eval: ${0 # comment :?yes:no} != no
+CondParser_Eval: 0 # comment
+lhs = "no", rhs = "no", op = !=
+CondParser_Eval: ${1 # comment :?yes:no} != yes
+CondParser_Eval: 1 # comment
+lhs = "yes", rhs = "yes", op = !=
exit status 0
diff -r 669c3eec1425 -r 51330cb606d5 usr.bin/make/unit-tests/cond-token-plain.mk
--- a/usr.bin/make/unit-tests/cond-token-plain.mk Fri Sep 11 06:40:25 2020 +0000
+++ b/usr.bin/make/unit-tests/cond-token-plain.mk Fri Sep 11 06:47:42 2020 +0000
@@ -1,9 +1,67 @@
-# $NetBSD: cond-token-plain.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
+# $NetBSD: cond-token-plain.mk,v 1.3 2020/09/11 06:47:42 rillig Exp $
#
# Tests for plain tokens (that is, string literals without quotes)
# in .if conditions.
-# TODO: Implementation
+.MAKEFLAGS: -dc
+
+.if ${:Uvalue} != value
+. error
+.endif
+
+# Malformed condition since comment parsing is done in an early phase
+# and removes the '#' and everything behind it long before the condition
+# parser gets to see it.
+#
+# XXX: The error message is missing for this malformed condition.
+# The right-hand side of the comparison is just a '"'.
+.if ${:U} != "#hash"
+. error
+.endif
+
+# To get a '#' into a condition, it has to be escaped using a backslash.
+# This prevents the comment parser from removing it, and in turn, it becomes
+# visible to CondParser_String.
+.if ${:U\#hash} != "\#hash"
+. error
+.endif
+
+# Since 2002-12-30, and still as of 2020-09-11, CondParser_Token handles
+# the '#' specially, even though at this point, there should be no need for
+# comment handling anymore. The comments are supposed to be stripped off
+# in a very early parsing phase.
+#
+# XXX: Missing error message for the malformed condition. The right-hand
+# side is double-quotes, backslash, backslash.
+# XXX: It is unexpected that the right-hand side evaluates to a single
+# backslash.
+.if ${:U\\} != "\\#hash"
+. error
+.endif
+
+# The right-hand side of a comparison is not parsed as a token, therefore
+# the code from CondParser_Token does not apply to it.
+.if ${:U\#hash} != \#hash
+. error
+.endif
+
+# XXX: What is the purpose of treating an escaped '#' in the following
+# condition as a comment? And why only at the beginning of a token,
+# just as in the shell?
+.if 0 \# This is treated as a comment, but why?
+. error
+.endif
+
+# Ah, ok, this can be used to add an end-of-condition comment. But does
+# anybody really use this? This is neither documented nor obvious since
+# the '#' is escaped. It's much clearer to write a comment in the line
+# above the condition.
+.if ${0 \# comment :?yes:no} != no
+. error
+.endif
+.if ${1 \# comment :?yes:no} != yes
+. error
+.endif
all:
@:;
Home |
Main Index |
Thread Index |
Old Index