#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];
+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));
-#ifdef OLD_LEXER
-char comments [4096];
-int comment_index;
-#endif
+isc_result_t new_parse (cfile, file, inbuf, buflen, name)
+ struct parse **cfile;
+ int file;
+ char *inbuf;
+ int buflen;
+ char *name;
+{
+ struct parse *tmp;
+ tmp = dmalloc (sizeof (struct parse), "new_parse");
+ if (!tmp)
+ return ISC_R_NOMEMORY;
+ memset (tmp, 0, sizeof *tmp);
-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));
+ 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;
-void new_parse (name)
- char *name;
+ 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;
{
- 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;
+ 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) {
+ /* 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 {
+ c = cfile -> inbuf [0];
+ cfile -> bufix = 1;
+ }
+ } else
+ c = EOF;
+ } else {
+ c = cfile -> inbuf [cfile -> bufix];
+ cfile -> bufix++;
+ }
+
+ if (!cfile -> ugflag) {
if (c == EOL) {
- if (cur_line == line1) {
- cur_line = line2;
- prev_line = line1;
+ if (cfile -> cur_line == cfile -> line1) {
+ cfile -> cur_line = cfile -> line2;
+ cfile -> prev_line = cfile -> line1;
} else {
- cur_line = line1;
- prev_line = line2;
+ cfile -> cur_line = cfile -> line1;
+ cfile -> prev_line = cfile -> line2;
}
- line++;
- lpos = 1;
- cur_line [0] = 0;
+ 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;
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;
}
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 {
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;
}
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;
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)