summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-09-11 22:16:16 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-09-11 22:16:16 +0000
commit0de9a172671305cf5ab28653ded3dc58a1b00f0a (patch)
treec331f494b8afe9474fb622657c9be6b105bcbde3
parent396f8321b4570b9d64236f1aeb314864e3ba9d22 (diff)
extend lex to spot numbers in the stream, without impacting the parsing
of ip addresses and such. this change is being pushed into all the pfctl derived parsers, starting with the easy ones. chio does not yet use the NUMBER token, but may one day. ok krw
-rw-r--r--bin/chio/parse.y41
1 files changed, 39 insertions, 2 deletions
diff --git a/bin/chio/parse.y b/bin/chio/parse.y
index 552ebdee668..a3af5f7c9ca 100644
--- a/bin/chio/parse.y
+++ b/bin/chio/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.4 2007/06/01 06:48:34 cnst Exp $ */
+/* $OpenBSD: parse.y,v 1.5 2007/09/11 22:16:15 deraadt Exp $ */
/*
* Copyright (c) 2006 Bob Beck <beck@openbsd.org>
@@ -58,7 +58,7 @@ int yylex(void);
typedef struct {
union {
- u_int32_t number;
+ int64_t number;
char *string;
} v;
int lineno;
@@ -70,6 +70,7 @@ typedef struct {
%token DRIVE
%token ERROR
%token <v.string> STRING
+%token <v.number> NUMBER
%%
grammar : /* empty */
@@ -294,6 +295,42 @@ yylex(void)
return (STRING);
}
+#define allowed_to_end_number(x) \
+ (isspace(x) || c == ')' || c ==',' || c == '/' || c == '}')
+
+ if (c == '-' || isdigit(c)) {
+ do {
+ *p++ = c;
+ if ((unsigned)(p-buf) >= sizeof(buf)) {
+ yyerror("string too long");
+ return (findeol());
+ }
+ } while ((c = lgetc(fin)) != EOF && isdigit(c));
+ lungetc(c);
+ if (p == buf + 1 && buf[0] == '-')
+ goto nodigits;
+ if (c == EOF || allowed_to_end_number(c)) {
+ const char *errstr = NULL;
+
+ *p = '\0';
+ yylval.v.number = strtonum(buf, LLONG_MIN,
+ LLONG_MAX, &errstr);
+ if (errstr) {
+ yyerror("\"%s\" invalid number: %s",
+ buf, errstr);
+ return (findeol());
+ }
+ return (NUMBER);
+ } else {
+nodigits:
+ while (p > buf + 1)
+ lungetc(*--p);
+ c = *--p;
+ if (c == '-')
+ return (c);
+ }
+ }
+
#define allowed_in_string(x) \
(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
x != '{' && x != '}' && x != '<' && x != '>' && \