mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-29 13:28:14 +00:00
- Put all lexer globals into a parse structure.
- Use UNIX I/O instead of stream I/O, and make it possible to just hang a buffer off a parse structure and parse out of the buffer with no associated file.
This commit is contained in:
parent
498d777ea3
commit
6f4b5b31e9
310
common/conflex.c
310
common/conflex.c
@ -22,88 +22,125 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: conflex.c,v 1.54 1999/09/09 23:25:27 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: conflex.c,v 1.55 1999/10/01 03:13:43 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
#include "dhctoken.h"
|
||||
#include <ctype.h>
|
||||
|
||||
int lexline;
|
||||
int lexchar;
|
||||
char *token_line;
|
||||
char *prev_line;
|
||||
char *cur_line;
|
||||
char *tlname;
|
||||
int eol_token;
|
||||
|
||||
static char line1 [81];
|
||||
static char line2 [81];
|
||||
static int lpos;
|
||||
static int line;
|
||||
static int tlpos;
|
||||
static int tline;
|
||||
static enum dhcp_token token;
|
||||
static int ugflag;
|
||||
static char *tval;
|
||||
static char tokbuf [1500];
|
||||
|
||||
#ifdef OLD_LEXER
|
||||
char comments [4096];
|
||||
int comment_index;
|
||||
#endif
|
||||
|
||||
|
||||
static int get_char PROTO ((FILE *));
|
||||
static enum dhcp_token get_token PROTO ((FILE *));
|
||||
static void skip_to_eol PROTO ((FILE *));
|
||||
static enum dhcp_token read_string PROTO ((FILE *));
|
||||
static enum dhcp_token read_number PROTO ((int, FILE *));
|
||||
static enum dhcp_token read_num_or_name PROTO ((int, FILE *));
|
||||
static int get_char PROTO ((struct parse *));
|
||||
static enum dhcp_token get_token PROTO ((struct parse *));
|
||||
static void skip_to_eol PROTO ((struct parse *));
|
||||
static enum dhcp_token read_string PROTO ((struct parse *));
|
||||
static enum dhcp_token read_number PROTO ((int, struct parse *));
|
||||
static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
|
||||
static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
|
||||
|
||||
void new_parse (name)
|
||||
isc_result_t new_parse (cfile, file, inbuf, buflen, name)
|
||||
struct parse **cfile;
|
||||
int file;
|
||||
char *inbuf;
|
||||
int buflen;
|
||||
char *name;
|
||||
{
|
||||
tlname = name;
|
||||
lpos = line = 1;
|
||||
cur_line = line1;
|
||||
prev_line = line2;
|
||||
token_line = cur_line;
|
||||
cur_line [0] = prev_line [0] = 0;
|
||||
warnings_occurred = 0;
|
||||
struct parse *tmp;
|
||||
|
||||
tmp = dmalloc (sizeof (struct parse), "new_parse");
|
||||
if (!tmp)
|
||||
return ISC_R_NOMEMORY;
|
||||
memset (tmp, 0, sizeof *tmp);
|
||||
|
||||
tmp -> tlname = name;
|
||||
tmp -> lpos = tmp -> line = 1;
|
||||
tmp -> cur_line = tmp -> line1;
|
||||
tmp -> prev_line = tmp -> line2;
|
||||
tmp -> token_line = tmp -> cur_line;
|
||||
tmp -> cur_line [0] = tmp -> prev_line [0] = 0;
|
||||
tmp -> warnings_occurred = 0;
|
||||
tmp -> file = file;
|
||||
|
||||
tmp -> bufix = 0;
|
||||
tmp -> buflen = buflen;
|
||||
if (inbuf) {
|
||||
tmp -> bufsiz = 0;
|
||||
tmp -> inbuf = inbuf;
|
||||
} else {
|
||||
tmp -> inbuf = dmalloc (8192, "new_parse");
|
||||
if (!tmp -> inbuf) {
|
||||
dfree (tmp, "new_parse");
|
||||
return ISC_R_NOMEMORY;
|
||||
}
|
||||
tmp -> bufsiz = 8192;
|
||||
}
|
||||
|
||||
*cfile = tmp;
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
isc_result_t end_parse (cfile)
|
||||
struct parse **cfile;
|
||||
{
|
||||
if ((*cfile) -> bufsiz)
|
||||
dfree ((*cfile) -> inbuf, "end_parse");
|
||||
dfree (*cfile, "end_parse");
|
||||
*cfile = (struct parse *)0;
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
static int get_char (cfile)
|
||||
FILE *cfile;
|
||||
struct parse *cfile;
|
||||
{
|
||||
int c = getc (cfile);
|
||||
if (!ugflag) {
|
||||
if (c == EOL) {
|
||||
if (cur_line == line1) {
|
||||
cur_line = line2;
|
||||
prev_line = line1;
|
||||
/* My kingdom for WITH... */
|
||||
int c;
|
||||
|
||||
if (cfile -> bufix == cfile -> buflen) {
|
||||
if (cfile -> file != -1) {
|
||||
cfile -> buflen =
|
||||
read (cfile -> file,
|
||||
cfile -> inbuf, cfile -> bufsiz);
|
||||
if (cfile -> buflen == 0) {
|
||||
c = EOF;
|
||||
cfile -> bufix = 0;
|
||||
} else if (cfile -> buflen < 0) {
|
||||
c = EOF;
|
||||
cfile -> bufix = cfile -> buflen = 0;
|
||||
} else {
|
||||
cur_line = line1;
|
||||
prev_line = line2;
|
||||
c = cfile -> inbuf [0];
|
||||
cfile -> bufix = 1;
|
||||
}
|
||||
line++;
|
||||
lpos = 1;
|
||||
cur_line [0] = 0;
|
||||
} else
|
||||
c = EOF;
|
||||
} else {
|
||||
c = cfile -> inbuf [cfile -> bufix];
|
||||
cfile -> bufix++;
|
||||
}
|
||||
|
||||
if (!cfile -> ugflag) {
|
||||
if (c == EOL) {
|
||||
if (cfile -> cur_line == cfile -> line1) {
|
||||
cfile -> cur_line = cfile -> line2;
|
||||
cfile -> prev_line = cfile -> line1;
|
||||
} else {
|
||||
cfile -> cur_line = cfile -> line1;
|
||||
cfile -> prev_line = cfile -> line2;
|
||||
}
|
||||
cfile -> line++;
|
||||
cfile -> lpos = 1;
|
||||
cfile -> cur_line [0] = 0;
|
||||
} else if (c != EOF) {
|
||||
if (lpos <= 80) {
|
||||
cur_line [lpos - 1] = c;
|
||||
cur_line [lpos] = 0;
|
||||
if (cfile -> lpos <= 80) {
|
||||
cfile -> cur_line [cfile -> lpos - 1] = c;
|
||||
cfile -> cur_line [cfile -> lpos] = 0;
|
||||
}
|
||||
lpos++;
|
||||
cfile -> lpos++;
|
||||
}
|
||||
} else
|
||||
ugflag = 0;
|
||||
cfile -> ugflag = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
static enum dhcp_token get_token (cfile)
|
||||
FILE *cfile;
|
||||
struct parse *cfile;
|
||||
{
|
||||
int c;
|
||||
enum dhcp_token ttok;
|
||||
@ -111,49 +148,50 @@ static enum dhcp_token get_token (cfile)
|
||||
int l, p, u;
|
||||
|
||||
do {
|
||||
l = line;
|
||||
p = lpos;
|
||||
u = ugflag;
|
||||
l = cfile -> line;
|
||||
p = cfile -> lpos;
|
||||
u = cfile -> ugflag;
|
||||
|
||||
c = get_char (cfile);
|
||||
#ifdef OLD_LEXER
|
||||
if (c == '\n' && p == 1 && !u
|
||||
&& comment_index < sizeof comments)
|
||||
comments [comment_index++] = '\n';
|
||||
&& cfile -> comment_index < sizeof cfile -> comments)
|
||||
cfile -> comments [cfile -> comment_index++] = '\n';
|
||||
#endif
|
||||
|
||||
if (!(c == '\n' && eol_token) && isascii (c) && isspace (c))
|
||||
if (!(c == '\n' && cfile -> eol_token)
|
||||
&& isascii (c) && isspace (c))
|
||||
continue;
|
||||
if (c == '#') {
|
||||
#ifdef OLD_LEXER
|
||||
if (comment_index < sizeof comments)
|
||||
comments [comment_index++] = '#';
|
||||
if (cfile -> comment_index < sizeof cfile -> comments)
|
||||
cfile -> comments [cfile -> comment_index++] = '#';
|
||||
#endif
|
||||
skip_to_eol (cfile);
|
||||
continue;
|
||||
}
|
||||
if (c == '"') {
|
||||
lexline = l;
|
||||
lexchar = p;
|
||||
cfile -> lexline = l;
|
||||
cfile -> lexchar = p;
|
||||
ttok = read_string (cfile);
|
||||
break;
|
||||
}
|
||||
if ((isascii (c) && isdigit (c)) || c == '-') {
|
||||
lexline = l;
|
||||
lexchar = p;
|
||||
cfile -> lexline = l;
|
||||
cfile -> lexchar = p;
|
||||
ttok = read_number (c, cfile);
|
||||
break;
|
||||
} else if (isascii (c) && isalpha (c)) {
|
||||
lexline = l;
|
||||
lexchar = p;
|
||||
cfile -> lexline = l;
|
||||
cfile -> lexchar = p;
|
||||
ttok = read_num_or_name (c, cfile);
|
||||
break;
|
||||
} else {
|
||||
lexline = l;
|
||||
lexchar = p;
|
||||
cfile -> lexline = l;
|
||||
cfile -> lexchar = p;
|
||||
tb [0] = c;
|
||||
tb [1] = 0;
|
||||
tval = tb;
|
||||
cfile -> tval = tb;
|
||||
ttok = c;
|
||||
break;
|
||||
}
|
||||
@ -163,54 +201,60 @@ static enum dhcp_token get_token (cfile)
|
||||
|
||||
enum dhcp_token next_token (rval, cfile)
|
||||
char **rval;
|
||||
FILE *cfile;
|
||||
struct parse *cfile;
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (token) {
|
||||
if (lexline != tline)
|
||||
token_line = cur_line;
|
||||
lexchar = tlpos;
|
||||
lexline = tline;
|
||||
rv = token;
|
||||
token = 0;
|
||||
if (cfile -> token) {
|
||||
if (cfile -> lexline != cfile -> tline)
|
||||
cfile -> token_line = cfile -> cur_line;
|
||||
cfile -> lexchar = cfile -> tlpos;
|
||||
cfile -> lexline = cfile -> tline;
|
||||
rv = cfile -> token;
|
||||
cfile -> token = 0;
|
||||
} else {
|
||||
rv = get_token (cfile);
|
||||
token_line = cur_line;
|
||||
cfile -> token_line = cfile -> cur_line;
|
||||
}
|
||||
if (rval)
|
||||
*rval = tval;
|
||||
*rval = cfile -> tval;
|
||||
#ifdef DEBUG_TOKENS
|
||||
fprintf (stderr, "%s:%d ", tval, rv);
|
||||
fprintf (stderr, "%s:%d ", cfile -> tval, rv);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
enum dhcp_token peek_token (rval, cfile)
|
||||
char **rval;
|
||||
FILE *cfile;
|
||||
struct parse *cfile;
|
||||
{
|
||||
int x;
|
||||
|
||||
if (!token) {
|
||||
tlpos = lexchar;
|
||||
tline = lexline;
|
||||
token = get_token (cfile);
|
||||
if (lexline != tline)
|
||||
token_line = prev_line;
|
||||
x = lexchar; lexchar = tlpos; tlpos = x;
|
||||
x = lexline; lexline = tline; tline = x;
|
||||
if (!cfile -> token) {
|
||||
cfile -> tlpos = cfile -> lexchar;
|
||||
cfile -> tline = cfile -> lexline;
|
||||
cfile -> token = get_token (cfile);
|
||||
if (cfile -> lexline != cfile -> tline)
|
||||
cfile -> token_line = cfile -> prev_line;
|
||||
|
||||
x = cfile -> lexchar;
|
||||
cfile -> lexchar = cfile -> tlpos;
|
||||
cfile -> tlpos = x;
|
||||
|
||||
x = cfile -> lexline;
|
||||
cfile -> lexline = cfile -> tline;
|
||||
cfile -> tline = x;
|
||||
}
|
||||
if (rval)
|
||||
*rval = tval;
|
||||
*rval = cfile -> tval;
|
||||
#ifdef DEBUG_TOKENS
|
||||
fprintf (stderr, "(%s:%d) ", tval, token);
|
||||
fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
|
||||
#endif
|
||||
return token;
|
||||
return cfile -> token;
|
||||
}
|
||||
|
||||
static void skip_to_eol (cfile)
|
||||
FILE *cfile;
|
||||
struct parse *cfile;
|
||||
{
|
||||
int c;
|
||||
do {
|
||||
@ -218,8 +262,8 @@ static void skip_to_eol (cfile)
|
||||
if (c == EOF)
|
||||
return;
|
||||
#ifdef OLD_LEXER
|
||||
if (comment_index < sizeof (comments))
|
||||
comments [comment_index++] = c;
|
||||
if (cfile -> comment_index < sizeof (cfile -> comments))
|
||||
comments [cfile -> comment_index++] = c;
|
||||
#endif
|
||||
if (c == EOL) {
|
||||
return;
|
||||
@ -228,49 +272,50 @@ static void skip_to_eol (cfile)
|
||||
}
|
||||
|
||||
static enum dhcp_token read_string (cfile)
|
||||
FILE *cfile;
|
||||
struct parse *cfile;
|
||||
{
|
||||
int i;
|
||||
int bs = 0;
|
||||
int c;
|
||||
|
||||
for (i = 0; i < sizeof tokbuf; i++) {
|
||||
for (i = 0; i < sizeof cfile -> tokbuf; i++) {
|
||||
c = get_char (cfile);
|
||||
if (c == EOF) {
|
||||
parse_warn ("eof in string constant");
|
||||
parse_warn (cfile, "eof in string constant");
|
||||
break;
|
||||
}
|
||||
if (bs) {
|
||||
bs = 0;
|
||||
tokbuf [i] = c;
|
||||
cfile -> tokbuf [i] = c;
|
||||
} else if (c == '\\')
|
||||
bs = 1;
|
||||
else if (c == '"')
|
||||
break;
|
||||
else
|
||||
tokbuf [i] = c;
|
||||
cfile -> tokbuf [i] = c;
|
||||
}
|
||||
/* Normally, I'd feel guilty about this, but we're talking about
|
||||
strings that'll fit in a DHCP packet here... */
|
||||
if (i == sizeof tokbuf) {
|
||||
parse_warn ("string constant larger than internal buffer");
|
||||
if (i == sizeof cfile -> tokbuf) {
|
||||
parse_warn (cfile,
|
||||
"string constant larger than internal buffer");
|
||||
--i;
|
||||
}
|
||||
tokbuf [i] = 0;
|
||||
tval = tokbuf;
|
||||
cfile -> tokbuf [i] = 0;
|
||||
cfile -> tval = cfile -> tokbuf;
|
||||
return STRING;
|
||||
}
|
||||
|
||||
static enum dhcp_token read_number (c, cfile)
|
||||
int c;
|
||||
FILE *cfile;
|
||||
struct parse *cfile;
|
||||
{
|
||||
int seenx = 0;
|
||||
int i = 0;
|
||||
int token = NUMBER;
|
||||
|
||||
tokbuf [i++] = c;
|
||||
for (; i < sizeof tokbuf; i++) {
|
||||
cfile -> tokbuf [i++] = c;
|
||||
for (; i < sizeof cfile -> tokbuf; i++) {
|
||||
c = get_char (cfile);
|
||||
if (!seenx && c == 'x') {
|
||||
seenx = 1;
|
||||
@ -282,47 +327,48 @@ static enum dhcp_token read_number (c, cfile)
|
||||
token = NUMBER_OR_NAME;
|
||||
#endif
|
||||
} else if (!isascii (c) || !isxdigit (c)) {
|
||||
ungetc (c, cfile);
|
||||
ugflag = 1;
|
||||
cfile -> bufix--;
|
||||
cfile -> ugflag = 1;
|
||||
break;
|
||||
}
|
||||
tokbuf [i] = c;
|
||||
cfile -> tokbuf [i] = c;
|
||||
}
|
||||
if (i == sizeof tokbuf) {
|
||||
parse_warn ("numeric token larger than internal buffer");
|
||||
if (i == sizeof cfile -> tokbuf) {
|
||||
parse_warn (cfile,
|
||||
"numeric token larger than internal buffer");
|
||||
--i;
|
||||
}
|
||||
tokbuf [i] = 0;
|
||||
tval = tokbuf;
|
||||
cfile -> tokbuf [i] = 0;
|
||||
cfile -> tval = cfile -> tokbuf;
|
||||
return token;
|
||||
}
|
||||
|
||||
static enum dhcp_token read_num_or_name (c, cfile)
|
||||
int c;
|
||||
FILE *cfile;
|
||||
struct parse *cfile;
|
||||
{
|
||||
int i = 0;
|
||||
enum dhcp_token rv = NUMBER_OR_NAME;
|
||||
tokbuf [i++] = c;
|
||||
for (; i < sizeof tokbuf; i++) {
|
||||
cfile -> tokbuf [i++] = c;
|
||||
for (; i < sizeof cfile -> tokbuf; i++) {
|
||||
c = get_char (cfile);
|
||||
if (!isascii (c) ||
|
||||
(c != '-' && c != '_' && !isalnum (c))) {
|
||||
ungetc (c, cfile);
|
||||
ugflag = 1;
|
||||
cfile -> bufix--;
|
||||
cfile -> ugflag = 1;
|
||||
break;
|
||||
}
|
||||
if (!isxdigit (c))
|
||||
rv = NAME;
|
||||
tokbuf [i] = c;
|
||||
cfile -> tokbuf [i] = c;
|
||||
}
|
||||
if (i == sizeof tokbuf) {
|
||||
parse_warn ("token larger than internal buffer");
|
||||
if (i == sizeof cfile -> tokbuf) {
|
||||
parse_warn (cfile, "token larger than internal buffer");
|
||||
--i;
|
||||
}
|
||||
tokbuf [i] = 0;
|
||||
tval = tokbuf;
|
||||
return intern (tval, rv);
|
||||
cfile -> tokbuf [i] = 0;
|
||||
cfile -> tval = cfile -> tokbuf;
|
||||
return intern (cfile -> tval, rv);
|
||||
}
|
||||
|
||||
static enum dhcp_token intern (atom, dfv)
|
||||
|
Loading…
x
Reference in New Issue
Block a user