Module Name: src
Committed By: rillig
Date: Sat Mar 15 10:31:28 UTC 2025
Modified Files:
src/bin/expr: expr.y
src/tests/bin/expr: t_expr.sh
Log Message:
expr: don't evaluate irrelevant conditions
To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/bin/expr/expr.y
cvs rdiff -u -r1.10 -r1.11 src/tests/bin/expr/t_expr.sh
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/bin/expr/expr.y
diff -u src/bin/expr/expr.y:1.49 src/bin/expr/expr.y:1.50
--- src/bin/expr/expr.y:1.49 Sat Mar 15 10:00:56 2025
+++ src/bin/expr/expr.y Sat Mar 15 10:31:28 2025
@@ -1,4 +1,4 @@
-/* $NetBSD: expr.y,v 1.49 2025/03/15 10:00:56 rillig Exp $ */
+/* $NetBSD: expr.y,v 1.50 2025/03/15 10:31:28 rillig Exp $ */
/*-
* Copyright (c) 2000, 2025 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
%{
#include <sys/cdefs.h>
-__RCSID("$NetBSD: expr.y,v 1.49 2025/03/15 10:00:56 rillig Exp $");
+__RCSID("$NetBSD: expr.y,v 1.50 2025/03/15 10:31:28 rillig Exp $");
#include <sys/types.h>
@@ -47,6 +47,7 @@ __RCSID("$NetBSD: expr.y,v 1.49 2025/03/
#include <string.h>
static const char * const *av;
+static unsigned skip_level;
static void yyerror(const char *, ...) __dead;
static int yylex(void);
@@ -78,29 +79,41 @@ exp: expr {
;
expr: item
-| expr SPEC_OR expr {
- if (!is_empty_or_zero($1))
+| expr SPEC_OR {
+ $$ = is_empty_or_zero($1) ? NULL : "1";
+ if ($$)
+ skip_level++;
+ } expr {
+ if ($3)
$$ = $1;
else
- $$ = $3;
- }
-| expr SPEC_AND expr {
- if (!is_empty_or_zero($1) && !is_empty_or_zero($3))
+ $$ = $4;
+ if ($3)
+ skip_level--;
+ }
+| expr SPEC_AND {
+ $$ = is_empty_or_zero($1) ? NULL : "1";
+ if (!$$)
+ skip_level++;
+ } expr {
+ if ($3 && !is_empty_or_zero($4))
$$ = $1;
else
$$ = "0";
+ if (!$3)
+ skip_level--;
}
| expr SPEC_REG expr {
- $$ = eval_match($1, $3);
+ $$ = skip_level == 0 ? eval_match($1, $3) : "";
}
| expr ADD_SUB_OPERATOR expr {
- $$ = eval_arith($1, $2, $3);
+ $$ = skip_level == 0 ? eval_arith($1, $2, $3) : "";
}
| expr MUL_DIV_MOD_OPERATOR expr {
- $$ = eval_arith($1, $2, $3);
+ $$ = skip_level == 0 ? eval_arith($1, $2, $3) : "";
}
| expr COMPARE expr {
- $$ = eval_compare($1, $2, $3) ? "1" : "0";
+ $$ = skip_level == 0 && eval_compare($1, $2, $3) ? "1" : "0";
}
| LEFT_PARENT expr RIGHT_PARENT {
$$ = $2;
Index: src/tests/bin/expr/t_expr.sh
diff -u src/tests/bin/expr/t_expr.sh:1.10 src/tests/bin/expr/t_expr.sh:1.11
--- src/tests/bin/expr/t_expr.sh:1.10 Sat Mar 15 07:02:07 2025
+++ src/tests/bin/expr/t_expr.sh Sat Mar 15 10:31:28 2025
@@ -1,4 +1,4 @@
-# $NetBSD: t_expr.sh,v 1.10 2025/03/15 07:02:07 rillig Exp $
+# $NetBSD: t_expr.sh,v 1.11 2025/03/15 10:31:28 rillig Exp $
#
# Copyright (c) 2007 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -272,11 +272,11 @@ short_circuit_head() {
}
short_circuit_body() {
test_expr 0 \| 1 / 0 "expr: second argument to '/' must not be zero"
- # FIXME: The right-hand side of '|' must not be evaluated.
- test_expr 123 \| 1 / 0 "expr: second argument to '/' must not be zero"
+ test_expr 123 \| 1 / 0 '123'
+ test_expr 123 \| a : '***' '123'
- # FIXME: The right-hand side of '&' must not be evaluated.
- test_expr 0 \& 1 / 0 "expr: second argument to '/' must not be zero"
+ test_expr 0 \& 1 / 0 '0'
+ test_expr 0 \& a : '***' '0'
test_expr 123 \& 1 / 0 "expr: second argument to '/' must not be zero"
test_finish