[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 --- |