ddb(4): Add some support for lexing IPv6 addresses

Allow commands to specify that (hex) numbers may start with A-F, by adding
the DRT_HEX flag for db_read_token_flags().  As before, numbers containing
invalid digits for the current radix are rejected.

Also, lex ':' and '::' tokens as tCOLON and tCOLONCOLON respectively.

There is a mild conflict here with lexed "identifiers" (tIDENT): ddb
identifiers may contain arbitrary colons, and the ddb lexer is greedy.  So
the identifier lex will swallow any colons it finds inside identifiers, and
consumers are still unable to expect the token sequence 'tIDENT tCOLON'.
That limitation does not matter for IPv6 addresses, because the lexer always
attempts to lex numbers before identifiers.

Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D21509
This commit is contained in:
Conrad Meyer 2019-09-09 16:32:23 +00:00
parent e0c5dd431b
commit 25b3370cfd
2 changed files with 25 additions and 4 deletions

View File

@ -163,7 +163,7 @@ static int
db_lex(int flags)
{
int c, n, radix_mode;
bool lex_wspace;
bool lex_wspace, lex_hex_numbers;
switch (flags & DRT_RADIX_MASK) {
case DRT_DEFAULT_RADIX:
@ -181,6 +181,7 @@ db_lex(int flags)
}
lex_wspace = ((flags & DRT_WSPACE) != 0);
lex_hex_numbers = ((flags & DRT_HEX) != 0);
c = db_read_char();
for (n = 0; c <= ' ' || c > '~'; n++) {
@ -193,13 +194,16 @@ db_lex(int flags)
return (tWSPACE);
}
if (c >= '0' && c <= '9') {
if ((c >= '0' && c <= '9') ||
(lex_hex_numbers &&
((c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F')))) {
/* number */
int r, digit = 0;
if (radix_mode != -1)
r = radix_mode;
else if (c > '0')
else if (c != '0')
r = db_radix;
else {
c = db_read_char();
@ -328,6 +332,12 @@ db_lex(int flags)
}
db_unread_char(c);
return (tEXCL);
case ':':
c = db_read_char();
if (c == ':')
return (tCOLONCOLON);
db_unread_char(c);
return (tCOLON);
case ';':
return (tSEMI);
case '&':

View File

@ -58,17 +58,26 @@ enum {
/*
* Flag bit powers of two for db_read_token_flags.
* The low 2 bits are reserved for radix selection.
*
* WSPACE: Yield explicit tWSPACE tokens when one or more whitespace characters
* is consumed.
* HEX: Allow tNUMBER tokens to start with 'A'-'F' without explicit "0x"
* prefix.
*/
enum {
_DRT_WSPACE = 2,
_DRT_HEX,
};
#ifndef BIT
#define BIT(n) (1ull << (n))
#endif
enum {
DRT_WSPACE = BIT(_DRT_WSPACE),
DRT_HEX = BIT(_DRT_HEX),
};
#define DRT_VALID_FLAGS_MASK ((int)DRT_RADIX_MASK | DRT_WSPACE)
#define DRT_VALID_FLAGS_MASK ((int)DRT_RADIX_MASK | \
DRT_WSPACE | \
DRT_HEX)
void db_flush_lex(void);
char *db_get_line(void);
@ -123,5 +132,7 @@ extern char db_tok_string[TOK_STRING_SIZE];
#define tQUESTION 33
#define tBIT_NOT 34
#define tWSPACE 35
#define tCOLON 36
#define tCOLONCOLON 37
#endif /* !_DDB_DB_LEX_H_ */