[dhcp-agent-commits] dhcp-agent/src dhcp-tokenizer.c,NONE,1.1 dhcp-tokenizer.h,NONE,1.1 Makefile.am,
Status: Alpha
Brought to you by:
actmodern
Update of /cvsroot/dhcp-agent/dhcp-agent/src
In directory sc8-pr-cvs1:/tmp/cvs-serv10369
Modified Files:
Makefile.am dhcp-conf.c dhcp-libutil.h dhcp-varfile.c
Added Files:
dhcp-tokenizer.c dhcp-tokenizer.h
Removed Files:
dhcp-parser.c dhcp-parser.h
Log Message:
replaced dhcp-parser with dhcp-tokenizer -- mostly just terminology changes
--- NEW FILE: dhcp-tokenizer.c ---
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-tokenizer.c,v 1.1 2002/12/22 08:31:30 actmodern Exp $
*
* Copyright 2002 Thamer Alharbash
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. The names of the authors may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#define MODULE_NAME "dhcp-tokenizer"
#include "dhcp-local.h"
#include "dhcp-libutil.h"
#include "dhcp-tokenizer.h"
/* these characters are special. we only allow them in a quoted string. */
static char special_characters[] = ",;{}=";
/* forward declaration of tokenizers. */
static token_t tokenize_comment(tokenizer_t *tokenizer);
static token_t tokenize_gobble_line(tokenizer_t *tokenizer);
static token_t tokenize_quoted_string(tokenizer_t *tokenizer);
static token_t tokenize_string(tokenizer_t *tokenizer);
static token_t tokenize_comment(tokenizer_t *tokenizer);
static token_t tokenize_newline(tokenizer_t *tokenizer);
static token_t tokenize_assignment(tokenizer_t *tokenizer);
static token_t tokenize_block_open(tokenizer_t *tokenizer);
static token_t tokenize_block_close(tokenizer_t *tokenizer);
static token_t tokenize_comma(tokenizer_t *tokenizer);
static token_t tokenize_semicolon(tokenizer_t *tokenizer);
/* tokenizer dispatch table. */
tokenizers_t parsers[] = {
/* char val */ /* routine. */
{ ';', tokenize_semicolon },
{ '\\', tokenize_gobble_line },
{ '#' , tokenize_comment },
{ '\"', tokenize_quoted_string },
{ '\n', tokenize_newline },
{ '=', tokenize_assignment },
{ '{' , tokenize_block_open },
{ '}', tokenize_block_close },
{ ',', tokenize_comma },
};
/* * * * * * * * * * *
* utility functions *
* * * * * * * * * * */
static int is_special_char(int c)
{
int i;
for(i = 0;i < NELMS(special_characters);i++) {
if(c == special_characters[i])
return 1;
}
return 0;
}
/* is a valid string character. */
static int is_valid_string_char(int c)
{
if(c == '\\')
return 0;
if(isalnum(c) || ispunct(c))
return 1;
else
return 0;
}
/* the stream is EOF or an error occured. */
static token_t check_eof(tokenizer_t *tokenizer)
{
if(feof(tokenizer->fp))
return TOKEN_EOF;
else
return TOKEN_ERROR;
}
/* just gobble up till the end of the newline */
static token_t tokenize_gobble_line(tokenizer_t *tokenizer)
{
int c;
while(1) {
c = fgetc(tokenizer->fp);
switch (c) {
case EOF:
return check_eof(tokenizer);
case '\n':
tokenizer->line_no++;
return TOKEN_NEWLINE;
default:
break;
}
}
}
/* * * * * * * * * * * * * *
* the tokenizer routines *
* * * * * * * * * * * * * */
/* read a quoted string. */
static token_t tokenize_quoted_string(tokenizer_t *tokenizer)
{
int c, c2;
while(1) {
c = fgetc(tokenizer->fp);
switch (c) {
case EOF:
return check_eof(tokenizer);
case '\"':
return TOKEN_STRING;
case '\n':
return TOKEN_ERROR; /* error to have newline in string constant. */
case '\\':
c2 = getc(tokenizer->fp);
if(c2 != '\\') {
ungetc(c2, tokenizer->fp);
if(tokenize_gobble_line(tokenizer) != TOKEN_NEWLINE)
return TOKEN_ERROR;
else
break;
} else
ungetc(c2, tokenizer->fp);
/* otherwise put it back and fall through. */
ungetc(c, tokenizer->fp);
/* fall through */
default:
if(is_valid_string_char(c) || c == ' ' || c == '\t')
stringbuffer_append_c(tokenizer->data_buff, (char)c);
else {
ungetc(c, tokenizer->fp);
return TOKEN_ERROR;
}
}
}
}
/* read a string. */
static token_t tokenize_string(tokenizer_t *tokenizer)
{
int c, c2;
while(1) {
c = fgetc(tokenizer->fp);
switch (c) {
case EOF:
return check_eof(tokenizer);
case '\n':
ungetc(c, tokenizer->fp);
return TOKEN_STRING; /* newline terminates string. */
case '\t':
case ' ':
ungetc(c, tokenizer->fp);
return TOKEN_STRING; /* spaces or tabs terminate string */
case '\\':
c2 = getc(tokenizer->fp);
if(c2 != '\\') {
ungetc(c2, tokenizer->fp);
if(tokenize_gobble_line(tokenizer) != TOKEN_NEWLINE)
return TOKEN_ERROR;
else
break;
} else
ungetc(c2, tokenizer->fp);
/* fall through. */
default:
if(is_special_char(c)) {
ungetc(c, tokenizer->fp);
return TOKEN_STRING;
}
if(is_valid_string_char(c)) {
stringbuffer_append_c(tokenizer->data_buff, (char)c);
} else {
ungetc(c, tokenizer->fp);
return TOKEN_ERROR; /* anything else and we've been terminated. */
}
}
}
}
static token_t tokenize_comment(tokenizer_t *tokenizer)
{
return tokenize_gobble_line(tokenizer);
}
static token_t tokenize_newline(tokenizer_t *tokenizer)
{
tokenizer->line_no++;
return TOKEN_NEWLINE;
}
static token_t tokenize_assignment(tokenizer_t *tokenizer)
{
return TOKEN_ASSIGNMENT;
}
static token_t tokenize_block_open(tokenizer_t *tokenizer)
{
return TOKEN_BLOCK_OPEN;
}
static token_t tokenize_block_close(tokenizer_t *tokenizer)
{
return TOKEN_BLOCK_CLOSE;
}
static token_t tokenize_comma(tokenizer_t *tokenizer)
{
return TOKEN_COMMA;
}
static token_t tokenize_semicolon(tokenizer_t *tokenizer)
{
return TOKEN_SEMICOLON;
}
static token_t tokenizer_get_next_token_proc(tokenizer_t *tokenizer, uint8_t peeking)
{
int c, c2;
int i;
/* have we peeked previously? */
if(tokenizer->peeked) {
/* then we have enough to return with now. */
/* if we're not peeking now clear flag before return. */
if(!peeking) {
/* remove peek flag. */
tokenizer->peeked = 0;
}
/* the data is already read, go ahead and return. */
return tokenizer->peek_value;
}
/* if we're peeking then setup our flag now since we'll be returning
* a peeked value and not losing it. */
tokenizer->peeked = peeking;
/* now read as usual. */
stringbuffer_clear(tokenizer->data_buff);
while(1) {
c = fgetc(tokenizer->fp);
switch (c) {
case EOF:
tokenizer->peek_value = TOKEN_EOF;
return tokenizer->peek_value;
case ' ':
case '\t':
continue;
case '\\':
c2 = getc(tokenizer->fp);
/* any backslash whose first trailing character is a
* space-like or newline-like character means we
* gobble up, but don't report end of line instead we
* continue parsing. */
if(c2 == ' ' || c2 == '\t' || c2 == '\n' || c2 == '\r') {
ungetc(c2, tokenizer->fp);
if(tokenize_gobble_line(tokenizer) != TOKEN_NEWLINE) {
tokenizer->peek_value = TOKEN_ERROR;
return tokenizer->peek_value;
} else {
break;
}
} else {
/* the next character may not be passed through
* the special parsers. we assume it's a string
* and do our best to read it .*/
ungetc(c2, tokenizer->fp);
goto read_in_string;
}
/* fall through */
default:
for(i = 0;i < NELMS(parsers); i++) {
if(parsers[i].character == c) {
tokenizer->peek_value = parsers[i].do_parse(tokenizer);
return tokenizer->peek_value;
}
}
/* otherwise we default to trying a string. */
read_in_string:
/* if we have an alphanumeric it's a string.
* read it in. */
if(is_valid_string_char(c) || c == '\\') {
ungetc(c, tokenizer->fp);
tokenizer->peek_value = tokenize_string(tokenizer);
return tokenizer->peek_value;
}
/* anything else is an error. */
tokenizer->peek_value = TOKEN_ERROR;
return tokenizer->peek_value;
}
}
}
/* * * * * * *
* interface *
* * * * * * */
/* get the next token. */
token_t tokenizer_get_next_token(tokenizer_t *tokenizer)
{
return(tokenizer_get_next_token_proc(tokenizer, 0));
}
/* peek at the next token. */
token_t tokenizer_peek_next_token(tokenizer_t *tokenizer)
{
return(tokenizer_get_next_token_proc(tokenizer, 1));
}
/* get the next token and ignore newlines. */
token_t tokenizer_get_next_token_ignore_newlines(tokenizer_t *tokenizer)
{
token_t token;
while((token = tokenizer_get_next_token(tokenizer)) == TOKEN_NEWLINE);
return token;
}
/* peek the next token and ignore newlines. */
token_t tokenizer_peek_next_token_ignore_newlines(tokenizer_t *tokenizer)
{
token_t token;
while(1) {
token = tokenizer_peek_next_token(tokenizer);
if(token == TOKEN_NEWLINE)
tokenizer_get_next_token(tokenizer);
else
return token;
}
}
/* create a parser instance. */
tokenizer_t *tokenizer_create(const char *filename)
{
FILE *fp;
tokenizer_t *tokenizer;
fp = file_open_or_create_safe(filename, "r");
if(fp == NULL)
return NULL;
tokenizer = xmalloc(sizeof(tokenizer_t));
tokenizer->fp = fp;
tokenizer->line_no = 1;
tokenizer->data_buff = create_stringbuffer();
tokenizer->peeked = 0;
return tokenizer;
}
/* destroy a tokenizer instance. */
void tokenizer_destroy(tokenizer_t *tokenizer)
{
fclose(tokenizer->fp);
destroy_stringbuffer(tokenizer->data_buff);
xfree(tokenizer);
return;
}
/* get current line number from the tokenizer. */
int tokenizer_get_line_no(tokenizer_t *tokenizer)
{
return tokenizer->line_no;
}
/* get a data string from the tokenizer. */
const char *tokenizer_get_data(tokenizer_t *tokenizer)
{
return stringbuffer_getstring(tokenizer->data_buff);
}
--- NEW FILE: dhcp-tokenizer.h ---
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-tokenizer.h,v 1.1 2002/12/22 08:31:30 actmodern Exp $
*
* Copyright 2002 Thamer Alharbash <tm...@wh...>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. The names of the authors may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Tokenizer
*
*/
#ifndef DHCP_TOKENIZER_H
#define DHCP_TOKENIZER_H
/* types. */
/* internal tokenizer type. */
typedef token_t (*tokenizer)(tokenizer_t *tokenizer);
/* structures. */
/* tokenizer dispatch structure. */
typedef struct {
char character;
tokenizer do_parse;
} tokenizers_t;
/* prototypes. */
extern const char *tokenizer_get_data(tokenizer_t *tokenizer);
extern int tokenizer_get_line_no(tokenizer_t *tokenizer);
extern tokenizer_t *tokenizer_create(const char *filename);
extern void tokenizer_destroy(tokenizer_t *tokenizer);
extern token_t tokenizer_peek_next_token_ignore_newlines(tokenizer_t *tokenizer);
extern token_t tokenizer_peek_next_token(tokenizer_t *tokenizer);
extern token_t tokenizer_get_next_token_ignore_newlines(tokenizer_t *tokenizer);
extern token_t tokenizer_get_next_token(tokenizer_t *tokenizer);
/* tokenizer return values. */
enum parser_atom { TOKEN_ERROR = 0, TOKEN_STRING, TOKEN_ASSIGNMENT, TOKEN_NEWLINE,
TOKEN_EOF, TOKEN_BLOCK_OPEN, TOKEN_BLOCK_CLOSE, TOKEN_SEMICOLON,
TOKEN_COMMA };
#endif /* DHCP_TOKENIZER_H */
Index: Makefile.am
===================================================================
RCS file: /cvsroot/dhcp-agent/dhcp-agent/src/Makefile.am,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** Makefile.am 16 Dec 2002 07:20:41 -0000 1.11
--- Makefile.am 22 Dec 2002 08:31:29 -0000 1.12
***************
*** 16,20 ****
dhcp-libutil.h dhcp-local.h dhcp-options-strings.h dhcp-print.h dhcp-cache-entry.h \
dhcp-client-conf.h dhcp-convert.h dhcp-librawnet.h dhcp-limits.h dhcp-log.h \
! dhcp-parser.h dhcp-sysconf.h dhcp-conf.h
--- 16,20 ----
dhcp-libutil.h dhcp-local.h dhcp-options-strings.h dhcp-print.h dhcp-cache-entry.h \
dhcp-client-conf.h dhcp-convert.h dhcp-librawnet.h dhcp-limits.h dhcp-log.h \
! dhcp-tokenizer.h dhcp-sysconf.h dhcp-conf.h
***************
*** 27,31 ****
dhcp-timer.c \
dhcp-varfile.c \
! dhcp-parser.c \
dhcp-files.c \
dhcp-rawnet.c \
--- 27,31 ----
dhcp-timer.c \
dhcp-varfile.c \
! dhcp-tokenizer.c \
dhcp-files.c \
dhcp-rawnet.c \
Index: dhcp-conf.c
===================================================================
RCS file: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-conf.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** dhcp-conf.c 21 Dec 2002 18:13:10 -0000 1.7
--- dhcp-conf.c 22 Dec 2002 08:31:29 -0000 1.8
***************
*** 35,39 ****
#include "dhcp-libutil.h"
! #include "dhcp-parser.h"
#include "dhcp-conf.h"
--- 35,39 ----
#include "dhcp-libutil.h"
! #include "dhcp-tokenizer.h"
#include "dhcp-conf.h"
***************
*** 149,155 ****
conf = xmalloc(sizeof(conf_t));
! conf->parser = create_parser(filename);
! if(conf->parser == NULL) {
ERROR_MESSAGE("could not open configuration file: %s", filename);
xfree(conf);
--- 149,155 ----
conf = xmalloc(sizeof(conf_t));
! conf->tokenizer = tokenizer_create(filename);
! if(conf->tokenizer == NULL) {
ERROR_MESSAGE("could not open configuration file: %s", filename);
xfree(conf);
***************
*** 167,171 ****
{
xfree(conf->filename);
! destroy_parser(conf->parser);
purge_list(conf->directives, directive_destroy_l);
xfree(conf);
--- 167,171 ----
{
xfree(conf->filename);
! tokenizer_destroy(conf->tokenizer);
purge_list(conf->directives, directive_destroy_l);
xfree(conf);
***************
*** 182,198 ****
arg_symbol_t *identifier_symbol = NULL;
const char *string;
! atom_t atom;
const char **ptr;
int i;
! atom = get_next_atom_ignore_newlines(conf->parser);
/* identifiers are strings. so check for that type and do
* a comparison against our data. */
! if(atom != PARSER_ATOM_STRING)
return NULL;
! string = parser_get_data(conf->parser);
i = 0;
--- 182,198 ----
arg_symbol_t *identifier_symbol = NULL;
const char *string;
! token_t token;
const char **ptr;
int i;
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
/* identifiers are strings. so check for that type and do
* a comparison against our data. */
! if(token != TOKEN_STRING)
return NULL;
! string = tokenizer_get_data(conf->tokenizer);
i = 0;
***************
*** 220,231 ****
eth_addr_t *eth_addr = NULL;
const char *string;
! atom_t atom;
! atom = get_next_atom_ignore_newlines(conf->parser);
! if(atom != PARSER_ATOM_STRING)
return NULL;
! string = parser_get_data(conf->parser);
if(strchr(string, '.') != NULL) {
--- 220,231 ----
eth_addr_t *eth_addr = NULL;
const char *string;
! token_t token;
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
! if(token != TOKEN_STRING)
return NULL;
! string = tokenizer_get_data(conf->tokenizer);
if(strchr(string, '.') != NULL) {
***************
*** 252,256 ****
{
uint8_t *placeholder;
! atom_t atom;
/* this is fairly easy check if the atom is an assignment and just return an empty placeholder.
--- 252,256 ----
{
uint8_t *placeholder;
! token_t token;
/* this is fairly easy check if the atom is an assignment and just return an empty placeholder.
***************
*** 258,264 ****
* we may create more. */
! atom = get_next_atom_ignore_newlines(conf->parser);
! if(atom != PARSER_ATOM_ASSIGNMENT)
return NULL;
--- 258,264 ----
* we may create more. */
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
! if(token != TOKEN_ASSIGNMENT)
return NULL;
***************
*** 271,283 ****
{
uint8_t *bool_val;
! atom_t atom;
const char *string;
! atom = get_next_atom_ignore_newlines(conf->parser);
! if(atom != PARSER_ATOM_STRING)
return NULL;
! string = parser_get_data(conf->parser);
if(!strcmp(string, "yes")) {
--- 271,283 ----
{
uint8_t *bool_val;
! token_t token;
const char *string;
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
! if(token != TOKEN_STRING)
return NULL;
! string = tokenizer_get_data(conf->tokenizer);
if(!strcmp(string, "yes")) {
***************
*** 304,315 ****
char *string_arg;
const char *string;
! atom_t atom;
! atom = get_next_atom_ignore_newlines(conf->parser);
! if(atom != PARSER_ATOM_STRING)
return NULL;
! string = parser_get_data(conf->parser);
string_arg = xstrdup(string);
--- 304,315 ----
char *string_arg;
const char *string;
! token_t token;
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
! if(token != TOKEN_STRING)
return NULL;
! string = tokenizer_get_data(conf->tokenizer);
string_arg = xstrdup(string);
***************
*** 321,325 ****
list_t *string_list = NULL;
char *string;
! atom_t atom;
/* ask compile_arg_string_list to do the work for us.
--- 321,325 ----
list_t *string_list = NULL;
char *string;
! token_t token;
/* ask compile_arg_string_list to do the work for us.
***************
*** 342,349 ****
/* now peek for a comma, if available keep going. */
! atom = parser_peek_next_atom(conf->parser);
! if(atom == PARSER_ATOM_COMMA) {
! atom = get_next_atom_ignore_newlines(conf->parser);
} else {
--- 342,349 ----
/* now peek for a comma, if available keep going. */
! token = tokenizer_peek_next_token_ignore_newlines(conf->tokenizer);
! if(token == TOKEN_COMMA) {
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
} else {
***************
*** 361,365 ****
directive_t *directive;
void *args;
! atom_t atom;
int i;
arg_type_t *arg_type;
--- 361,365 ----
directive_t *directive;
void *args;
! token_t token;
int i;
arg_type_t *arg_type;
***************
*** 389,394 ****
/* we're done. now we need a semicolon to end this directive. */
! atom = get_next_atom_ignore_newlines(conf->parser);
! if(atom != PARSER_ATOM_SEMICOLON) {
ERROR_MESSAGE("semi colon terminator not present where expected at line: %d\n", conf_get_line_no(conf));
directive_destroy(directive);
--- 389,394 ----
/* we're done. now we need a semicolon to end this directive. */
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
! if(token != TOKEN_SEMICOLON) {
ERROR_MESSAGE("semi colon terminator not present where expected at line: %d\n", conf_get_line_no(conf));
directive_destroy(directive);
***************
*** 408,412 ****
/* we expect the string is already read from the parser
* before we're called. */
! token_string = parser_get_data(conf->parser);
/* now do a comparison and find our command_t. */
--- 408,412 ----
/* we expect the string is already read from the parser
* before we're called. */
! token_string = tokenizer_get_data(conf->tokenizer);
/* now do a comparison and find our command_t. */
***************
*** 435,439 ****
static void *compile_arg_group(conf_t *conf, const char **argument_strings, const arg_symbol_t *argument_symbols)
{
! atom_t atom;
directive_t *directive;
list_t *directive_list = NULL;
--- 435,439 ----
static void *compile_arg_group(conf_t *conf, const char **argument_strings, const arg_symbol_t *argument_symbols)
{
! token_t token;
directive_t *directive;
list_t *directive_list = NULL;
***************
*** 442,448 ****
* as per the commands allowed in the group. */
! atom = get_next_atom_ignore_newlines(conf->parser);
! if(atom != PARSER_ATOM_BLOCK_OPEN)
return NULL;
--- 442,448 ----
* as per the commands allowed in the group. */
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
! if(token != TOKEN_BLOCK_OPEN)
return NULL;
***************
*** 451,461 ****
while(1) {
! atom = get_next_atom_ignore_newlines(conf->parser);
! if(atom == PARSER_ATOM_BLOCK_CLOSE)
return directive_list;
/* we should always start with a string. */
! if(atom != PARSER_ATOM_STRING)
goto error;
--- 451,461 ----
while(1) {
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
! if(token == TOKEN_BLOCK_CLOSE)
return directive_list;
/* we should always start with a string. */
! if(token != TOKEN_STRING)
goto error;
***************
*** 501,516 ****
{
! atom_t atom;
directive_t *directive;
while(1) {
! atom = get_next_atom_ignore_newlines(conf->parser);
! if(atom == PARSER_ATOM_EOF) /* end of file */
return CONF_OK;
/* we should always start with a string. */
! if(atom != PARSER_ATOM_STRING)
return CONF_ERROR;
--- 501,516 ----
{
! token_t token;
directive_t *directive;
while(1) {
! token = tokenizer_get_next_token_ignore_newlines(conf->tokenizer);
! if(token == TOKEN_EOF) /* end of file */
return CONF_OK;
/* we should always start with a string. */
! if(token != TOKEN_STRING)
return CONF_ERROR;
***************
*** 536,539 ****
int conf_get_line_no(conf_t *conf)
{
! return parser_get_line_no(conf->parser);
}
--- 536,539 ----
int conf_get_line_no(conf_t *conf)
{
! return tokenizer_get_line_no(conf->tokenizer);
}
Index: dhcp-libutil.h
===================================================================
RCS file: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-libutil.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** dhcp-libutil.h 21 Dec 2002 16:51:53 -0000 1.15
--- dhcp-libutil.h 22 Dec 2002 08:31:30 -0000 1.16
***************
*** 31,34 ****
--- 31,35 ----
/* types. */
+ /* conf parser types. */
typedef uint32_t command_code_t;
typedef uint32_t arg_len_t;
***************
*** 36,39 ****
--- 37,43 ----
typedef uint8_t arg_symbol_t;
+ /* tokenizer types. */
+ typedef uint8_t token_t;
+
/* * * * * * * * * * *
* Data structures. *
***************
*** 41,44 ****
--- 45,49 ----
/* native data structures. */
+
/* list object. */
typedef struct list {
***************
*** 82,91 ****
int line_no;
stringbuffer *data_buff;
! } parser_t;
/* varfile object. */
typedef struct {
char *filename;
! parser_t *parser;
stringbuffer *var_name;
stringbuffer *var_val;
--- 87,98 ----
int line_no;
stringbuffer *data_buff;
! token_t peek_value;
! uint8_t peeked;
! } tokenizer_t;
/* varfile object. */
typedef struct {
char *filename;
! tokenizer_t *tokenizer;
stringbuffer *var_name;
stringbuffer *var_val;
***************
*** 116,120 ****
typedef struct {
char *filename;
! parser_t *parser;
const command_t **commands; /* list of permissible commands. */
list_t *directives;
--- 123,127 ----
typedef struct {
char *filename;
! tokenizer_t *tokenizer;
const command_t **commands; /* list of permissible commands. */
list_t *directives;
Index: dhcp-varfile.c
===================================================================
RCS file: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-varfile.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** dhcp-varfile.c 24 Nov 2002 20:54:31 -0000 1.4
--- dhcp-varfile.c 22 Dec 2002 08:31:30 -0000 1.5
***************
*** 32,36 ****
#include "dhcp-libutil.h"
! #include "dhcp-parser.h"
const char *varfile_get_name(varfile_t *varfile)
--- 32,36 ----
#include "dhcp-libutil.h"
! #include "dhcp-tokenizer.h"
const char *varfile_get_name(varfile_t *varfile)
***************
*** 46,50 ****
int varfile_get_lineno(varfile_t *varfile)
{
! return parser_get_line_no(varfile->parser);
}
--- 46,50 ----
int varfile_get_lineno(varfile_t *varfile)
{
! return tokenizer_get_line_no(varfile->tokenizer);
}
***************
*** 57,61 ****
varfile->var_name = create_stringbuffer();
varfile->var_val = create_stringbuffer();
! varfile->parser = create_parser(filename);
varfile->mode = mode;
return varfile;
--- 57,61 ----
varfile->var_name = create_stringbuffer();
varfile->var_val = create_stringbuffer();
! varfile->tokenizer = tokenizer_create(filename);
varfile->mode = mode;
return varfile;
***************
*** 64,68 ****
void destroy_varfile(varfile_t *varfile)
{
! destroy_parser(varfile->parser);
destroy_stringbuffer(varfile->var_name);
destroy_stringbuffer(varfile->var_val);
--- 64,68 ----
void destroy_varfile(varfile_t *varfile)
{
! tokenizer_destroy(varfile->tokenizer);
destroy_stringbuffer(varfile->var_name);
destroy_stringbuffer(varfile->var_val);
***************
*** 81,105 ****
int varfile_get_next_varnames(varfile_t *varfile)
{
! atom_t atom;
while(1) {
! atom = get_next_atom(varfile->parser);
! if(atom == PARSER_ATOM_NEWLINE) /* skip empty lines/comments. */
continue;
! if(atom == PARSER_ATOM_EOF)
return VARFILE_EOF;
! if(atom != PARSER_ATOM_STRING)
return VARFILE_PARSE_ERROR;
/* copy string out into varname */
! stringbuffer_set(varfile->var_name, parser_get_data(varfile->parser));
! atom = get_next_atom(varfile->parser);
/* if we don't get an end of statement or eof here it's a parse error. */
! if(atom != PARSER_ATOM_NEWLINE && atom != PARSER_ATOM_EOF)
return VARFILE_PARSE_ERROR;
--- 81,105 ----
int varfile_get_next_varnames(varfile_t *varfile)
{
! token_t token;
while(1) {
! token = tokenizer_get_next_token(varfile->tokenizer);
! if(token == TOKEN_NEWLINE) /* skip empty lines/comments. */
continue;
! if(token == TOKEN_EOF)
return VARFILE_EOF;
! if(token != TOKEN_STRING)
return VARFILE_PARSE_ERROR;
/* copy string out into varname */
! stringbuffer_set(varfile->var_name, tokenizer_get_data(varfile->tokenizer));
! token = tokenizer_get_next_token(varfile->tokenizer);
/* if we don't get an end of statement or eof here it's a parse error. */
! if(token != TOKEN_NEWLINE && token != TOKEN_EOF)
return VARFILE_PARSE_ERROR;
***************
*** 110,152 ****
int varfile_get_next_varval(varfile_t *varfile)
{
! atom_t atom;
/* get the name first. */
while(1) {
! atom = get_next_atom(varfile->parser);
! if(atom == PARSER_ATOM_NEWLINE) /* skip empty lines/comments. */
continue;
! if(atom == PARSER_ATOM_EOF)
return VARFILE_EOF;
! if(atom != PARSER_ATOM_STRING)
return VARFILE_PARSE_ERROR;
/* copy string out into varname */
! stringbuffer_set(varfile->var_name, parser_get_data(varfile->parser));
break;
}
! atom = get_next_atom(varfile->parser);
! if(atom != PARSER_ATOM_ASSIGNMENT)
return VARFILE_PARSE_ERROR;
! atom = get_next_atom(varfile->parser);
! if(atom != PARSER_ATOM_STRING)
return VARFILE_PARSE_ERROR;
/* copy string out into var val */
! stringbuffer_set(varfile->var_val, parser_get_data(varfile->parser));
/* now we need a clean end of statement. */
! atom = get_next_atom(varfile->parser);
! if(atom != PARSER_ATOM_NEWLINE && atom != PARSER_ATOM_EOF)
return VARFILE_PARSE_ERROR;
--- 110,152 ----
int varfile_get_next_varval(varfile_t *varfile)
{
! token_t token;
/* get the name first. */
while(1) {
! token = tokenizer_get_next_token(varfile->tokenizer);
! if(token == TOKEN_NEWLINE) /* skip empty lines/comments. */
continue;
! if(token == TOKEN_EOF)
return VARFILE_EOF;
! if(token != TOKEN_STRING)
return VARFILE_PARSE_ERROR;
/* copy string out into varname */
! stringbuffer_set(varfile->var_name, tokenizer_get_data(varfile->tokenizer));
break;
}
! token = tokenizer_get_next_token(varfile->tokenizer);
! if(token != TOKEN_ASSIGNMENT)
return VARFILE_PARSE_ERROR;
! token = tokenizer_get_next_token(varfile->tokenizer);
! if(token != TOKEN_STRING)
return VARFILE_PARSE_ERROR;
/* copy string out into var val */
! stringbuffer_set(varfile->var_val, tokenizer_get_data(varfile->tokenizer));
/* now we need a clean end of statement. */
! token = tokenizer_get_next_token(varfile->tokenizer);
! if(token != TOKEN_NEWLINE && token != TOKEN_EOF)
return VARFILE_PARSE_ERROR;
--- dhcp-parser.c DELETED ---
--- dhcp-parser.h DELETED ---
|