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
This commit is contained in:
Conrad Meyer 2019-09-09 16:31:14 +00:00
parent d4402ecd3b
commit e0c5dd431b
2 changed files with 75 additions and 10 deletions

View File

@ -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();

View File

@ -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_ */