2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-30 05:47:45 +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:
Ted Lemon 1999-10-01 03:13:43 +00:00
parent 498d777ea3
commit 6f4b5b31e9

View File

@ -22,88 +22,125 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
#include "dhctoken.h"
#include <ctype.h> #include <ctype.h>
int lexline; static int get_char PROTO ((struct parse *));
int lexchar; static enum dhcp_token get_token PROTO ((struct parse *));
char *token_line; static void skip_to_eol PROTO ((struct parse *));
char *prev_line; static enum dhcp_token read_string PROTO ((struct parse *));
char *cur_line; static enum dhcp_token read_number PROTO ((int, struct parse *));
char *tlname; static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
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 enum dhcp_token intern PROTO ((char *, enum dhcp_token)); 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; char *name;
{ {
tlname = name; struct parse *tmp;
lpos = line = 1;
cur_line = line1; tmp = dmalloc (sizeof (struct parse), "new_parse");
prev_line = line2; if (!tmp)
token_line = cur_line; return ISC_R_NOMEMORY;
cur_line [0] = prev_line [0] = 0; memset (tmp, 0, sizeof *tmp);
warnings_occurred = 0;
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) static int get_char (cfile)
FILE *cfile; struct parse *cfile;
{ {
int c = getc (cfile); /* My kingdom for WITH... */
if (!ugflag) { int c;
if (c == EOL) {
if (cur_line == line1) { if (cfile -> bufix == cfile -> buflen) {
cur_line = line2; if (cfile -> file != -1) {
prev_line = line1; 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 { } else {
cur_line = line1; c = cfile -> inbuf [0];
prev_line = line2; cfile -> bufix = 1;
} }
line++; } else
lpos = 1; c = EOF;
cur_line [0] = 0; } 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) { } else if (c != EOF) {
if (lpos <= 80) { if (cfile -> lpos <= 80) {
cur_line [lpos - 1] = c; cfile -> cur_line [cfile -> lpos - 1] = c;
cur_line [lpos] = 0; cfile -> cur_line [cfile -> lpos] = 0;
} }
lpos++; cfile -> lpos++;
} }
} else } else
ugflag = 0; cfile -> ugflag = 0;
return c; return c;
} }
static enum dhcp_token get_token (cfile) static enum dhcp_token get_token (cfile)
FILE *cfile; struct parse *cfile;
{ {
int c; int c;
enum dhcp_token ttok; enum dhcp_token ttok;
@ -111,49 +148,50 @@ static enum dhcp_token get_token (cfile)
int l, p, u; int l, p, u;
do { do {
l = line; l = cfile -> line;
p = lpos; p = cfile -> lpos;
u = ugflag; u = cfile -> ugflag;
c = get_char (cfile); c = get_char (cfile);
#ifdef OLD_LEXER #ifdef OLD_LEXER
if (c == '\n' && p == 1 && !u if (c == '\n' && p == 1 && !u
&& comment_index < sizeof comments) && cfile -> comment_index < sizeof cfile -> comments)
comments [comment_index++] = '\n'; cfile -> comments [cfile -> comment_index++] = '\n';
#endif #endif
if (!(c == '\n' && eol_token) && isascii (c) && isspace (c)) if (!(c == '\n' && cfile -> eol_token)
&& isascii (c) && isspace (c))
continue; continue;
if (c == '#') { if (c == '#') {
#ifdef OLD_LEXER #ifdef OLD_LEXER
if (comment_index < sizeof comments) if (cfile -> comment_index < sizeof cfile -> comments)
comments [comment_index++] = '#'; cfile -> comments [cfile -> comment_index++] = '#';
#endif #endif
skip_to_eol (cfile); skip_to_eol (cfile);
continue; continue;
} }
if (c == '"') { if (c == '"') {
lexline = l; cfile -> lexline = l;
lexchar = p; cfile -> lexchar = p;
ttok = read_string (cfile); ttok = read_string (cfile);
break; break;
} }
if ((isascii (c) && isdigit (c)) || c == '-') { if ((isascii (c) && isdigit (c)) || c == '-') {
lexline = l; cfile -> lexline = l;
lexchar = p; cfile -> lexchar = p;
ttok = read_number (c, cfile); ttok = read_number (c, cfile);
break; break;
} else if (isascii (c) && isalpha (c)) { } else if (isascii (c) && isalpha (c)) {
lexline = l; cfile -> lexline = l;
lexchar = p; cfile -> lexchar = p;
ttok = read_num_or_name (c, cfile); ttok = read_num_or_name (c, cfile);
break; break;
} else { } else {
lexline = l; cfile -> lexline = l;
lexchar = p; cfile -> lexchar = p;
tb [0] = c; tb [0] = c;
tb [1] = 0; tb [1] = 0;
tval = tb; cfile -> tval = tb;
ttok = c; ttok = c;
break; break;
} }
@ -163,54 +201,60 @@ static enum dhcp_token get_token (cfile)
enum dhcp_token next_token (rval, cfile) enum dhcp_token next_token (rval, cfile)
char **rval; char **rval;
FILE *cfile; struct parse *cfile;
{ {
int rv; int rv;
if (token) { if (cfile -> token) {
if (lexline != tline) if (cfile -> lexline != cfile -> tline)
token_line = cur_line; cfile -> token_line = cfile -> cur_line;
lexchar = tlpos; cfile -> lexchar = cfile -> tlpos;
lexline = tline; cfile -> lexline = cfile -> tline;
rv = token; rv = cfile -> token;
token = 0; cfile -> token = 0;
} else { } else {
rv = get_token (cfile); rv = get_token (cfile);
token_line = cur_line; cfile -> token_line = cfile -> cur_line;
} }
if (rval) if (rval)
*rval = tval; *rval = cfile -> tval;
#ifdef DEBUG_TOKENS #ifdef DEBUG_TOKENS
fprintf (stderr, "%s:%d ", tval, rv); fprintf (stderr, "%s:%d ", cfile -> tval, rv);
#endif #endif
return rv; return rv;
} }
enum dhcp_token peek_token (rval, cfile) enum dhcp_token peek_token (rval, cfile)
char **rval; char **rval;
FILE *cfile; struct parse *cfile;
{ {
int x; int x;
if (!token) { if (!cfile -> token) {
tlpos = lexchar; cfile -> tlpos = cfile -> lexchar;
tline = lexline; cfile -> tline = cfile -> lexline;
token = get_token (cfile); cfile -> token = get_token (cfile);
if (lexline != tline) if (cfile -> lexline != cfile -> tline)
token_line = prev_line; cfile -> token_line = cfile -> prev_line;
x = lexchar; lexchar = tlpos; tlpos = x;
x = lexline; lexline = tline; tline = x; x = cfile -> lexchar;
cfile -> lexchar = cfile -> tlpos;
cfile -> tlpos = x;
x = cfile -> lexline;
cfile -> lexline = cfile -> tline;
cfile -> tline = x;
} }
if (rval) if (rval)
*rval = tval; *rval = cfile -> tval;
#ifdef DEBUG_TOKENS #ifdef DEBUG_TOKENS
fprintf (stderr, "(%s:%d) ", tval, token); fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
#endif #endif
return token; return cfile -> token;
} }
static void skip_to_eol (cfile) static void skip_to_eol (cfile)
FILE *cfile; struct parse *cfile;
{ {
int c; int c;
do { do {
@ -218,8 +262,8 @@ static void skip_to_eol (cfile)
if (c == EOF) if (c == EOF)
return; return;
#ifdef OLD_LEXER #ifdef OLD_LEXER
if (comment_index < sizeof (comments)) if (cfile -> comment_index < sizeof (cfile -> comments))
comments [comment_index++] = c; comments [cfile -> comment_index++] = c;
#endif #endif
if (c == EOL) { if (c == EOL) {
return; return;
@ -228,49 +272,50 @@ static void skip_to_eol (cfile)
} }
static enum dhcp_token read_string (cfile) static enum dhcp_token read_string (cfile)
FILE *cfile; struct parse *cfile;
{ {
int i; int i;
int bs = 0; int bs = 0;
int c; int c;
for (i = 0; i < sizeof tokbuf; i++) { for (i = 0; i < sizeof cfile -> tokbuf; i++) {
c = get_char (cfile); c = get_char (cfile);
if (c == EOF) { if (c == EOF) {
parse_warn ("eof in string constant"); parse_warn (cfile, "eof in string constant");
break; break;
} }
if (bs) { if (bs) {
bs = 0; bs = 0;
tokbuf [i] = c; cfile -> tokbuf [i] = c;
} else if (c == '\\') } else if (c == '\\')
bs = 1; bs = 1;
else if (c == '"') else if (c == '"')
break; break;
else else
tokbuf [i] = c; cfile -> tokbuf [i] = c;
} }
/* Normally, I'd feel guilty about this, but we're talking about /* Normally, I'd feel guilty about this, but we're talking about
strings that'll fit in a DHCP packet here... */ strings that'll fit in a DHCP packet here... */
if (i == sizeof tokbuf) { if (i == sizeof cfile -> tokbuf) {
parse_warn ("string constant larger than internal buffer"); parse_warn (cfile,
"string constant larger than internal buffer");
--i; --i;
} }
tokbuf [i] = 0; cfile -> tokbuf [i] = 0;
tval = tokbuf; cfile -> tval = cfile -> tokbuf;
return STRING; return STRING;
} }
static enum dhcp_token read_number (c, cfile) static enum dhcp_token read_number (c, cfile)
int c; int c;
FILE *cfile; struct parse *cfile;
{ {
int seenx = 0; int seenx = 0;
int i = 0; int i = 0;
int token = NUMBER; int token = NUMBER;
tokbuf [i++] = c; cfile -> tokbuf [i++] = c;
for (; i < sizeof tokbuf; i++) { for (; i < sizeof cfile -> tokbuf; i++) {
c = get_char (cfile); c = get_char (cfile);
if (!seenx && c == 'x') { if (!seenx && c == 'x') {
seenx = 1; seenx = 1;
@ -282,47 +327,48 @@ static enum dhcp_token read_number (c, cfile)
token = NUMBER_OR_NAME; token = NUMBER_OR_NAME;
#endif #endif
} else if (!isascii (c) || !isxdigit (c)) { } else if (!isascii (c) || !isxdigit (c)) {
ungetc (c, cfile); cfile -> bufix--;
ugflag = 1; cfile -> ugflag = 1;
break; break;
} }
tokbuf [i] = c; cfile -> tokbuf [i] = c;
} }
if (i == sizeof tokbuf) { if (i == sizeof cfile -> tokbuf) {
parse_warn ("numeric token larger than internal buffer"); parse_warn (cfile,
"numeric token larger than internal buffer");
--i; --i;
} }
tokbuf [i] = 0; cfile -> tokbuf [i] = 0;
tval = tokbuf; cfile -> tval = cfile -> tokbuf;
return token; return token;
} }
static enum dhcp_token read_num_or_name (c, cfile) static enum dhcp_token read_num_or_name (c, cfile)
int c; int c;
FILE *cfile; struct parse *cfile;
{ {
int i = 0; int i = 0;
enum dhcp_token rv = NUMBER_OR_NAME; enum dhcp_token rv = NUMBER_OR_NAME;
tokbuf [i++] = c; cfile -> tokbuf [i++] = c;
for (; i < sizeof tokbuf; i++) { for (; i < sizeof cfile -> tokbuf; i++) {
c = get_char (cfile); c = get_char (cfile);
if (!isascii (c) || if (!isascii (c) ||
(c != '-' && c != '_' && !isalnum (c))) { (c != '-' && c != '_' && !isalnum (c))) {
ungetc (c, cfile); cfile -> bufix--;
ugflag = 1; cfile -> ugflag = 1;
break; break;
} }
if (!isxdigit (c)) if (!isxdigit (c))
rv = NAME; rv = NAME;
tokbuf [i] = c; cfile -> tokbuf [i] = c;
} }
if (i == sizeof tokbuf) { if (i == sizeof cfile -> tokbuf) {
parse_warn ("token larger than internal buffer"); parse_warn (cfile, "token larger than internal buffer");
--i; --i;
} }
tokbuf [i] = 0; cfile -> tokbuf [i] = 0;
tval = tokbuf; cfile -> tval = cfile -> tokbuf;
return intern (tval, rv); return intern (cfile -> tval, rv);
} }
static enum dhcp_token intern (atom, dfv) static enum dhcp_token intern (atom, dfv)