Basic test, if (no else atm), support with a single statement.
authormpi <mpi@openbsd.org>
Tue, 31 Aug 2021 12:51:24 +0000 (12:51 +0000)
committermpi <mpi@openbsd.org>
Tue, 31 Aug 2021 12:51:24 +0000 (12:51 +0000)
usr.sbin/btrace/bt_parse.y
usr.sbin/btrace/btrace.c

index 2a7ac72..9cda358 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bt_parse.y,v 1.36 2021/08/31 08:39:26 mpi Exp $       */
+/*     $OpenBSD: bt_parse.y,v 1.37 2021/08/31 12:51:24 mpi Exp $       */
 
 /*
  * Copyright (c) 2019-2021 Martin Pieuchot <mpi@openbsd.org>
@@ -115,7 +115,7 @@ static int pflag;
 %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
+%token <v.i>           BUILTIN BEGIN END HZ IF
 /* Functions and Map operators */
 %token  <v.i>          F_DELETE F_PRINT FUNC0 FUNC1 FUNCN OP1 OP4 MOP0 MOP1
 %token <v.string>      STRING CSTRING
@@ -126,7 +126,7 @@ static int pflag;
 %type  <v.i>           beginend
 %type  <v.probe>       probe pname
 %type  <v.filter>      filter
-%type  <v.stmt>        action stmt stmtlist
+%type  <v.stmt>        action stmt stmtblck stmtlist block
 %type  <v.arg>         pat vargs mentry mpat pargs
 %type  <v.arg>         expr term fterm factor
 %%
@@ -239,8 +239,17 @@ stmt       : ';' NL                        { $$ = NULL; }
        | gvar '=' OP4 '(' pat ',' vargs ')'    { $$ = bh_inc($1, $5, $7); }
        ;
 
-stmtlist: stmt
+stmtblck: IF '(' expr ')' block                        { $$ = bt_new($3, $5); }
+       ;
+
+stmtlist: stmtlist stmtblck            { $$ = bs_append($1, $2); }
        | stmtlist stmt                 { $$ = bs_append($1, $2); }
+       | stmtblck
+       | stmt
+       ;
+
+block  : '{' stmt ';' '}'                      { $$ = $2; }
+       | stmt ';'
        ;
 
 action : '{' stmtlist '}'              { $$ = $2; }
@@ -302,6 +311,17 @@ bc_new(struct bt_arg *term, enum bt_argtype op, struct bt_arg *ba)
        return bf;
 }
 
+/* Create a new if/else test */
+struct bt_stmt *
+bt_new(struct bt_arg *ba, struct bt_stmt *condbs)
+{
+       struct bt_arg *bop;
+
+       bop = ba_op(B_AT_OP_NE, NULL, ba);
+
+       return bs_new(B_AC_TEST, bop, (struct bt_var *)condbs);
+
+}
 /* Create a new probe */
 struct bt_probe *
 bp_new(const char *prov, const char *func, const char *name, int32_t rate)
@@ -638,6 +658,7 @@ lookup(char *s)
                { "exit",       FUNC0,          B_AC_EXIT },
                { "hist",       OP1,            0 },
                { "hz",         HZ,             0 },
+               { "if",         IF,             0 },
                { "kstack",     BUILTIN,        B_AT_BI_KSTACK },
                { "lhist",      OP4,            0 },
                { "max",        MOP1,           B_AT_MF_MAX },
index 44df20f..8481601 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: btrace.c,v 1.41 2021/08/31 11:30:21 mpi Exp $ */
+/*     $OpenBSD: btrace.c,v 1.42 2021/08/31 12:51:24 mpi Exp $ */
 
 /*
  * Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -81,6 +81,7 @@ void                   rule_printmaps(struct bt_rule *);
 uint64_t                builtin_nsecs(struct dt_evt *);
 const char             *builtin_kstack(struct dt_evt *);
 const char             *builtin_arg(struct dt_evt *, enum bt_argtype);
+void                    stmt_eval(struct bt_stmt *, struct dt_evt *);
 void                    stmt_bucketize(struct bt_stmt *, struct dt_evt *);
 void                    stmt_clear(struct bt_stmt *);
 void                    stmt_delete(struct bt_stmt *, struct dt_evt *);
@@ -545,40 +546,10 @@ rule_eval(struct bt_rule *r, struct dt_evt *dtev)
        }
 
        SLIST_FOREACH(bs, &r->br_action, bs_next) {
-               switch (bs->bs_act) {
-               case B_AC_BUCKETIZE:
-                       stmt_bucketize(bs, dtev);
-                       break;
-               case B_AC_CLEAR:
-                       stmt_clear(bs);
-                       break;
-               case B_AC_DELETE:
-                       stmt_delete(bs, dtev);
-                       break;
-               case B_AC_EXIT:
-                       exit(0);
-                       break;
-               case B_AC_INSERT:
-                       stmt_insert(bs, dtev);
-                       break;
-               case B_AC_PRINT:
-                       stmt_print(bs, dtev);
-                       break;
-               case B_AC_PRINTF:
-                       stmt_printf(bs, dtev);
-                       break;
-               case B_AC_STORE:
-                       stmt_store(bs, dtev);
-                       break;
-               case B_AC_TIME:
-                       stmt_time(bs, dtev);
-                       break;
-               case B_AC_ZERO:
-                       stmt_zero(bs);
-                       break;
-               default:
-                       xabort("no handler for action type %d", bs->bs_act);
-               }
+               if ((bs->bs_act == B_AC_TEST) && stmt_test(bs, dtev) == true)
+                       stmt_eval((struct bt_stmt *)bs->bs_var, dtev);
+
+               stmt_eval(bs, dtev);
        }
 }
 
@@ -689,6 +660,48 @@ builtin_arg(struct dt_evt *dtev, enum bt_argtype dat)
        return buf;
 }
 
+void
+stmt_eval(struct bt_stmt *bs, struct dt_evt *dtev)
+{
+       switch (bs->bs_act) {
+       case B_AC_BUCKETIZE:
+               stmt_bucketize(bs, dtev);
+               break;
+       case B_AC_CLEAR:
+               stmt_clear(bs);
+               break;
+       case B_AC_DELETE:
+               stmt_delete(bs, dtev);
+               break;
+       case B_AC_EXIT:
+               exit(0);
+               break;
+       case B_AC_INSERT:
+               stmt_insert(bs, dtev);
+               break;
+       case B_AC_PRINT:
+               stmt_print(bs, dtev);
+               break;
+       case B_AC_PRINTF:
+               stmt_printf(bs, dtev);
+               break;
+       case B_AC_STORE:
+               stmt_store(bs, dtev);
+               break;
+       case B_AC_TEST:
+               /* done before */
+               break;
+       case B_AC_TIME:
+               stmt_time(bs, dtev);
+               break;
+       case B_AC_ZERO:
+               stmt_zero(bs);
+               break;
+       default:
+               xabort("no handler for action type %d", bs->bs_act);
+       }
+}
+
 /*
  * Increment a bucket: { @h = hist(v); } or { @h = lhist(v, min, max, step); }
  *
@@ -885,7 +898,6 @@ stmt_test(struct bt_stmt *bs, struct dt_evt *dtev)
        if (bs == NULL)
                return true;
 
-       assert(bs->bs_var == NULL);
        ba = SLIST_FIRST(&bs->bs_args);
 
        return baexpr2long(ba, dtev) != 0;