aboutsummaryrefslogtreecommitdiff
path: root/sys/ddb
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2019-09-09 16:31:14 +0000
committerConrad Meyer <cem@FreeBSD.org>2019-09-09 16:31:14 +0000
commite0c5dd431b1b117d571407fb76216acb56fe59ce (patch)
treea82ed120440a42d0bad0ff3482c6466a93d4892e /sys/ddb
parentd4402ecd3bd37555be30ce2b80ef256b8e163b06 (diff)
downloadsrc-e0c5dd431b1b117d571407fb76216acb56fe59ce.tar.gz
src-e0c5dd431b1b117d571407fb76216acb56fe59ce.zip
ddb(4): Enhance lexer functionality for specialized commands
Add a db_read_token_flags() variant of db_read_token() with configurable parameters. Allow specifying an explicit radix for tNUMBER lexing. It overrides the default inference and db_radix setting. Also provide the option of yielding any lexed whitespace (tWSPACE) (instead of ignoring it). This is useful for whitespace-sensitive CS_OWN commands. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D21459
Notes
Notes: svn path=/head/; revision=352074
Diffstat (limited to 'sys/ddb')
-rw-r--r--sys/ddb/db_lex.c44
-rw-r--r--sys/ddb/db_lex.h41
2 files changed, 75 insertions, 10 deletions
diff --git a/sys/ddb/db_lex.c b/sys/ddb/db_lex.c
index 8e25cc898fc1..5b81652bc1f1 100644
--- a/sys/ddb/db_lex.c
+++ b/sys/ddb/db_lex.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/libkern.h>
+#include <sys/lock.h>
#include <ddb/ddb.h>
#include <ddb/db_lex.h>
@@ -45,7 +46,7 @@ __FBSDID("$FreeBSD$");
static char db_line[DB_MAXLINE];
static char * db_lp, *db_endlp;
-static int db_lex(void);
+static int db_lex(int);
static void db_flush_line(void);
static int db_read_char(void);
static void db_unread_char(int);
@@ -124,23 +125,24 @@ db_unread_char(c)
static int db_look_token = 0;
void
-db_unread_token(t)
- int t;
+db_unread_token(int t)
{
db_look_token = t;
}
int
-db_read_token()
+db_read_token_flags(int flags)
{
int t;
+ MPASS((flags & ~(DRT_VALID_FLAGS_MASK)) == 0);
+
if (db_look_token) {
t = db_look_token;
db_look_token = 0;
}
else
- t = db_lex();
+ t = db_lex(flags);
return (t);
}
@@ -158,22 +160,46 @@ db_flush_lex(void)
}
static int
-db_lex(void)
+db_lex(int flags)
{
- int c;
+ int c, n, radix_mode;
+ bool lex_wspace;
+
+ switch (flags & DRT_RADIX_MASK) {
+ case DRT_DEFAULT_RADIX:
+ radix_mode = -1;
+ break;
+ case DRT_OCTAL:
+ radix_mode = 8;
+ break;
+ case DRT_DECIMAL:
+ radix_mode = 10;
+ break;
+ case DRT_HEXADECIMAL:
+ radix_mode = 16;
+ break;
+ }
+
+ lex_wspace = ((flags & DRT_WSPACE) != 0);
c = db_read_char();
- while (c <= ' ' || c > '~') {
+ for (n = 0; c <= ' ' || c > '~'; n++) {
if (c == '\n' || c == -1)
return (tEOL);
c = db_read_char();
}
+ if (lex_wspace && n != 0) {
+ db_unread_char(c);
+ return (tWSPACE);
+ }
if (c >= '0' && c <= '9') {
/* number */
int r, digit = 0;
- if (c > '0')
+ if (radix_mode != -1)
+ r = radix_mode;
+ else if (c > '0')
r = db_radix;
else {
c = db_read_char();
diff --git a/sys/ddb/db_lex.h b/sys/ddb/db_lex.h
index e9ed3a660393..3dbb42575533 100644
--- a/sys/ddb/db_lex.h
+++ b/sys/ddb/db_lex.h
@@ -38,13 +38,51 @@
/*
* Lexical analyzer.
*/
+
+/*
+ * Options and flags can configure db_read_token() => db_lex() behavior.
+ *
+ * When a radix other than DRT_DEFAULT_RADIX is used, it overrides
+ * auto-detection, as well as the user-specified db_radix, in db_lex() of
+ * 'tNUMBER' tokens.
+ */
+enum {
+ /* Infer or use db_radix using the old logic. */
+ DRT_DEFAULT_RADIX = 0,
+ /* The following set an explicit base for tNUMBER lex. */
+ DRT_OCTAL,
+ DRT_DECIMAL,
+ DRT_HEXADECIMAL,
+};
+#define DRT_RADIX_MASK 0x3
+/*
+ * Flag bit powers of two for db_read_token_flags.
+ * The low 2 bits are reserved for radix selection.
+ */
+enum {
+ _DRT_WSPACE = 2,
+};
+#ifndef BIT
+#define BIT(n) (1ull << (n))
+#endif
+enum {
+ DRT_WSPACE = BIT(_DRT_WSPACE),
+};
+#define DRT_VALID_FLAGS_MASK ((int)DRT_RADIX_MASK | DRT_WSPACE)
+
void db_flush_lex(void);
char *db_get_line(void);
void db_inject_line(const char *command);
int db_read_line(void);
-int db_read_token(void);
+int db_read_token_flags(int);
void db_unread_token(int t);
+static inline int
+db_read_token(void)
+{
+ return (db_read_token_flags(0));
+}
+
extern db_expr_t db_tok_number;
#define TOK_STRING_SIZE 120
extern char db_tok_string[TOK_STRING_SIZE];
@@ -84,5 +122,6 @@ extern char db_tok_string[TOK_STRING_SIZE];
#define tSTRING 32
#define tQUESTION 33
#define tBIT_NOT 34
+#define tWSPACE 35
#endif /* !_DDB_DB_LEX_H_ */