summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2024-03-30 07:41:46 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2024-03-30 07:41:46 +0000
commitd75ffb62d682420b80696a36a3ef66b720266e66 (patch)
treea38d8c2632f7480b6bd3f1c0a4bc56d6a9ab7b4e /usr.sbin
parentcb9a1aefad92d62b67d212884b980590840cef7f (diff)
Implement else branching logic including 'else if'.
Statement lists for if & else conditions are now wrapped in a new 'struct bt_cond'. Handling B_AC_TEST statements moved to stmt_eval() to handle nested conditional statements. From Christian Ludwig christian_ludwig at genua.de
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/btrace/bt_parse.y20
-rw-r--r--usr.sbin/btrace/bt_parser.h10
-rw-r--r--usr.sbin/btrace/btrace.c34
3 files changed, 42 insertions, 22 deletions
diff --git a/usr.sbin/btrace/bt_parse.y b/usr.sbin/btrace/bt_parse.y
index 075eaa5b7f8..2497ae4eadd 100644
--- a/usr.sbin/btrace/bt_parse.y
+++ b/usr.sbin/btrace/bt_parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: bt_parse.y,v 1.59 2024/02/12 15:11:06 mpi Exp $ */
+/* $OpenBSD: bt_parse.y,v 1.60 2024/03/30 07:41:45 mpi Exp $ */
/*
* Copyright (c) 2019-2023 Martin Pieuchot <mpi@openbsd.org>
@@ -119,7 +119,7 @@ static int beflag = 0; /* BEGIN/END parsing context flag */
%token <v.i> ERROR ENDFILT
%token <v.i> OP_EQ OP_NE OP_LE OP_LT OP_GE OP_GT OP_LAND OP_LOR
/* Builtins */
-%token <v.i> BUILTIN BEGIN END HZ IF STR
+%token <v.i> BUILTIN BEGIN ELSE END HZ IF STR
/* Functions and Map operators */
%token <v.i> F_DELETE F_PRINT
%token <v.i> MFUNC FUNC0 FUNC1 FUNCN OP1 OP2 OP4 MOP0 MOP1
@@ -248,7 +248,9 @@ stmt : ';' NL { $$ = NULL; }
| GVAR '=' OP4 '(' expr ',' vargs ')' { $$ = bh_inc($1, $5, $7); }
;
-stmtblck: IF '(' expr ')' block { $$ = bt_new($3, $5); }
+stmtblck: IF '(' expr ')' block { $$ = bt_new($3, $5, NULL); }
+ | IF '(' expr ')' block ELSE block { $$ = bt_new($3, $5, $7); }
+ | IF '(' expr ')' block ELSE stmtblck { $$ = bt_new($3, $5, $7); }
;
stmtlist: stmtlist stmtblck { $$ = bs_append($1, $2); }
@@ -340,15 +342,22 @@ bc_new(struct bt_arg *term, enum bt_argtype op, struct bt_arg *ba)
/* Create a new if/else test */
struct bt_stmt *
-bt_new(struct bt_arg *ba, struct bt_stmt *condbs)
+bt_new(struct bt_arg *ba, struct bt_stmt *condbs, struct bt_stmt *elsebs)
{
struct bt_arg *bop;
+ struct bt_cond *bc;
bop = ba_op(B_AT_OP_NE, NULL, ba);
- return bs_new(B_AC_TEST, bop, (struct bt_var *)condbs);
+ bc = calloc(1, sizeof(*bc));
+ if (bc == NULL)
+ err(1, "bt_cond: calloc");
+ bc->bc_condbs = condbs;
+ bc->bc_elsebs = elsebs;
+ return bs_new(B_AC_TEST, bop, (struct bt_var *)bc);
}
+
/* Create a new probe */
struct bt_probe *
bp_new(const char *prov, const char *func, const char *name, int32_t rate)
@@ -714,6 +723,7 @@ lookup(char *s)
{ "count", MOP0, B_AT_MF_COUNT },
{ "cpu", BUILTIN, B_AT_BI_CPU },
{ "delete", F_DELETE, B_AC_DELETE },
+ { "else", ELSE, 0 },
{ "exit", FUNC0, B_AC_EXIT },
{ "hist", OP1, 0 },
{ "hz", HZ, 0 },
diff --git a/usr.sbin/btrace/bt_parser.h b/usr.sbin/btrace/bt_parser.h
index 051bd72815d..081c0045c2f 100644
--- a/usr.sbin/btrace/bt_parser.h
+++ b/usr.sbin/btrace/bt_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bt_parser.h,v 1.25 2023/10/12 15:16:44 cheloha Exp $ */
+/* $OpenBSD: bt_parser.h,v 1.26 2024/03/30 07:41:45 mpi Exp $ */
/*
* Copyright (c) 2019-2021 Martin Pieuchot <mpi@openbsd.org>
@@ -181,6 +181,14 @@ struct bt_arg {
#define BA_INITIALIZER(v, t) { { NULL }, (void *)(v), NULL, (t) }
/*
+ * Represents branches of an if-else statement.
+ */
+struct bt_cond {
+ struct bt_stmt *bc_condbs;
+ struct bt_stmt *bc_elsebs;
+};
+
+/*
* Each action associated with a given probe is made of at least one
* statement.
*
diff --git a/usr.sbin/btrace/btrace.c b/usr.sbin/btrace/btrace.c
index ce32989be91..b817d9c924b 100644
--- a/usr.sbin/btrace/btrace.c
+++ b/usr.sbin/btrace/btrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: btrace.c,v 1.89 2024/02/27 12:38:12 mpi Exp $ */
+/* $OpenBSD: btrace.c,v 1.90 2024/03/30 07:41:45 mpi Exp $ */
/*
* Copyright (c) 2019 - 2023 Martin Pieuchot <mpi@openbsd.org>
@@ -460,6 +460,7 @@ static uint64_t
rules_action_scan(struct bt_stmt *bs)
{
struct bt_arg *ba;
+ struct bt_cond *bc;
uint64_t evtflags = 0;
while (bs != NULL) {
@@ -474,8 +475,9 @@ rules_action_scan(struct bt_stmt *bs)
evtflags |= ba2dtflags(ba);
break;
case B_AC_TEST:
- evtflags |= rules_action_scan(
- (struct bt_stmt *)bs->bs_var);
+ bc = (struct bt_cond *)bs->bs_var;
+ evtflags |= rules_action_scan(bc->bc_condbs);
+ evtflags |= rules_action_scan(bc->bc_elsebs);
break;
default:
break;
@@ -669,18 +671,6 @@ rule_eval(struct bt_rule *r, struct dt_evt *dtev)
}
SLIST_FOREACH(bs, &r->br_action, bs_next) {
- if ((bs->bs_act == B_AC_TEST) && stmt_test(bs, dtev) == true) {
- struct bt_stmt *bbs = (struct bt_stmt *)bs->bs_var;
-
- while (bbs != NULL) {
- if (stmt_eval(bbs, dtev))
- return 1;
- bbs = SLIST_NEXT(bbs, bs_next);
- }
-
- continue;
- }
-
if (stmt_eval(bs, dtev))
return 1;
}
@@ -830,6 +820,8 @@ builtin_arg(struct dt_evt *dtev, enum bt_argtype dat)
int
stmt_eval(struct bt_stmt *bs, struct dt_evt *dtev)
{
+ struct bt_stmt *bbs;
+ struct bt_cond *bc;
int halt = 0;
switch (bs->bs_act) {
@@ -858,7 +850,17 @@ stmt_eval(struct bt_stmt *bs, struct dt_evt *dtev)
stmt_store(bs, dtev);
break;
case B_AC_TEST:
- /* done before */
+ bc = (struct bt_cond *)bs->bs_var;
+ if (stmt_test(bs, dtev) == true)
+ bbs = bc->bc_condbs;
+ else
+ bbs = bc->bc_elsebs;
+
+ while (bbs != NULL) {
+ if (stmt_eval(bbs, dtev))
+ return 1;
+ bbs = SLIST_NEXT(bbs, bs_next);
+ }
break;
case B_AC_TIME:
stmt_time(bs, dtev);