btrace: add support for hex and octal values.
authordv <dv@openbsd.org>
Wed, 20 Dec 2023 14:00:17 +0000 (14:00 +0000)
committerdv <dv@openbsd.org>
Wed, 20 Dec 2023 14:00:17 +0000 (14:00 +0000)
Changes number tokenizing and parsing to support hex & octal values.
Does not address other lexer issues (e.g. $0x1) to close gaps with
bpftrace.

OK claudio@

regress/usr.sbin/btrace/arithm.bt
regress/usr.sbin/btrace/arithm.ok
usr.sbin/btrace/bt_parse.y

index e2d35a8..58638e7 100644 (file)
@@ -3,7 +3,7 @@ BEGIN
        @a = 10;
        @b = 5;
 
-       printf("a + b = %d\n", @a + @b);
+       printf("a + b + 0xf = %d\n", @a + @b + 0xf);
 }
 
 END
@@ -11,5 +11,6 @@ END
        printf("a - b = %d\n", @a - @b);
 
        $c = @a + 2 * @b;
-       printf("c = %d, total = %d\n", $c, ($c - @b) / 5);
+        $d = @a + 0xf5;
+       printf("c = %d, d = 0x%x, total = %d\n", $c, $d, ($c - @b) / 5);
 }
index 9575561..0c05e39 100644 (file)
@@ -1,3 +1,3 @@
-a + b = 15
+a + b + 0xf = 30
 a - b = 5
-c = 20, total = 3
+c = 20, d = 0xff, total = 3
index 0207fe9..1eb5280 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bt_parse.y,v 1.55 2023/12/20 01:38:46 dv Exp $        */
+/*     $OpenBSD: bt_parse.y,v 1.56 2023/12/20 14:00:17 dv Exp $        */
 
 /*
  * Copyright (c) 2019-2023 Martin Pieuchot <mpi@openbsd.org>
@@ -34,6 +34,7 @@
 #include <assert.h>
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
 #include <limits.h>
 #include <stdarg.h>
 #include <stdint.h>
@@ -925,17 +926,20 @@ again:
                                yyerror("line too long");
                                return ERROR;
                        }
-               } while ((c = lgetc()) != EOF && isdigit(c));
+               } while ((c = lgetc()) != EOF &&
+                   (isxdigit(c) || c == 'x' || c == 'X'));
                lungetc();
                if (c == EOF || allowed_to_end_number(c)) {
-                       const char *errstr = NULL;
-
                        *p = '\0';
-                       yylval.v.number = strtonum(buf, LONG_MIN, LONG_MAX,
-                           &errstr);
-                       if (errstr) {
-                               yyerror("invalid number '%s' (%s)", buf,
-                                   errstr);
+                       errno = 0;
+                       yylval.v.number = strtol(buf, NULL, 0);
+                       if (errno == ERANGE) {
+                               /*
+                                * Characters are already validated, so only
+                                * check ERANGE.
+                                */
+                               yyerror("%sflow", (yylval.v.number == LONG_MIN)
+                                   ? "under" : "over");
                                return ERROR;
                        }
                        return NUMBER;