diff options
author | Conrad Meyer <cem@FreeBSD.org> | 2019-09-09 16:31:14 +0000 |
---|---|---|
committer | Conrad Meyer <cem@FreeBSD.org> | 2019-09-09 16:31:14 +0000 |
commit | e0c5dd431b1b117d571407fb76216acb56fe59ce (patch) | |
tree | a82ed120440a42d0bad0ff3482c6466a93d4892e /sys/ddb | |
parent | d4402ecd3bd37555be30ce2b80ef256b8e163b06 (diff) | |
download | src-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.c | 44 | ||||
-rw-r--r-- | sys/ddb/db_lex.h | 41 |
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_ */ |