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:
parent
d4402ecd3b
commit
e0c5dd431b
@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/libkern.h>
|
#include <sys/libkern.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
|
||||||
#include <ddb/ddb.h>
|
#include <ddb/ddb.h>
|
||||||
#include <ddb/db_lex.h>
|
#include <ddb/db_lex.h>
|
||||||
@ -45,7 +46,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
static char db_line[DB_MAXLINE];
|
static char db_line[DB_MAXLINE];
|
||||||
static char * db_lp, *db_endlp;
|
static char * db_lp, *db_endlp;
|
||||||
|
|
||||||
static int db_lex(void);
|
static int db_lex(int);
|
||||||
static void db_flush_line(void);
|
static void db_flush_line(void);
|
||||||
static int db_read_char(void);
|
static int db_read_char(void);
|
||||||
static void db_unread_char(int);
|
static void db_unread_char(int);
|
||||||
@ -124,23 +125,24 @@ db_unread_char(c)
|
|||||||
static int db_look_token = 0;
|
static int db_look_token = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
db_unread_token(t)
|
db_unread_token(int t)
|
||||||
int t;
|
|
||||||
{
|
{
|
||||||
db_look_token = t;
|
db_look_token = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
db_read_token()
|
db_read_token_flags(int flags)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
|
MPASS((flags & ~(DRT_VALID_FLAGS_MASK)) == 0);
|
||||||
|
|
||||||
if (db_look_token) {
|
if (db_look_token) {
|
||||||
t = db_look_token;
|
t = db_look_token;
|
||||||
db_look_token = 0;
|
db_look_token = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
t = db_lex();
|
t = db_lex(flags);
|
||||||
return (t);
|
return (t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,22 +160,46 @@ db_flush_lex(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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();
|
c = db_read_char();
|
||||||
while (c <= ' ' || c > '~') {
|
for (n = 0; c <= ' ' || c > '~'; n++) {
|
||||||
if (c == '\n' || c == -1)
|
if (c == '\n' || c == -1)
|
||||||
return (tEOL);
|
return (tEOL);
|
||||||
c = db_read_char();
|
c = db_read_char();
|
||||||
}
|
}
|
||||||
|
if (lex_wspace && n != 0) {
|
||||||
|
db_unread_char(c);
|
||||||
|
return (tWSPACE);
|
||||||
|
}
|
||||||
|
|
||||||
if (c >= '0' && c <= '9') {
|
if (c >= '0' && c <= '9') {
|
||||||
/* number */
|
/* number */
|
||||||
int r, digit = 0;
|
int r, digit = 0;
|
||||||
|
|
||||||
if (c > '0')
|
if (radix_mode != -1)
|
||||||
|
r = radix_mode;
|
||||||
|
else if (c > '0')
|
||||||
r = db_radix;
|
r = db_radix;
|
||||||
else {
|
else {
|
||||||
c = db_read_char();
|
c = db_read_char();
|
||||||
|
@ -38,13 +38,51 @@
|
|||||||
/*
|
/*
|
||||||
* Lexical analyzer.
|
* 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);
|
void db_flush_lex(void);
|
||||||
char *db_get_line(void);
|
char *db_get_line(void);
|
||||||
void db_inject_line(const char *command);
|
void db_inject_line(const char *command);
|
||||||
int db_read_line(void);
|
int db_read_line(void);
|
||||||
int db_read_token(void);
|
int db_read_token_flags(int);
|
||||||
void db_unread_token(int t);
|
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;
|
extern db_expr_t db_tok_number;
|
||||||
#define TOK_STRING_SIZE 120
|
#define TOK_STRING_SIZE 120
|
||||||
extern char db_tok_string[TOK_STRING_SIZE];
|
extern char db_tok_string[TOK_STRING_SIZE];
|
||||||
@ -84,5 +122,6 @@ extern char db_tok_string[TOK_STRING_SIZE];
|
|||||||
#define tSTRING 32
|
#define tSTRING 32
|
||||||
#define tQUESTION 33
|
#define tQUESTION 33
|
||||||
#define tBIT_NOT 34
|
#define tBIT_NOT 34
|
||||||
|
#define tWSPACE 35
|
||||||
|
|
||||||
#endif /* !_DDB_DB_LEX_H_ */
|
#endif /* !_DDB_DB_LEX_H_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user