[dhcp-agent-commits] dhcp-agent/src dhcp-parser.c,1.3,1.4 dhcp-parser.h,1.3,1.4 dhcp-varfile.c,1.3,1
Status: Alpha
Brought to you by:
actmodern
From: <act...@us...> - 2002-11-24 20:54:37
|
Update of /cvsroot/dhcp-agent/dhcp-agent/src In directory sc8-pr-cvs1:/tmp/cvs-serv23533 Modified Files: dhcp-parser.c dhcp-parser.h dhcp-varfile.c Log Message: revamp to parser Index: dhcp-parser.c =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-parser.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dhcp-parser.c 16 Nov 2002 00:23:43 -0000 1.3 --- dhcp-parser.c 24 Nov 2002 20:54:31 -0000 1.4 *************** *** 30,33 **** --- 30,76 ---- #include "dhcp-parser.h" + /* these characters are special. we only allow them in a quoted string. */ + static char special_characters[] = ";{}="; + + /* forward declaration of parsers. */ + static token_t parse_comment(parser_t *input); + static token_t parse_gobble_line(parser_t *input); + static token_t parse_quoted_string(parser_t *input); + static token_t parse_string(parser_t *input); + static token_t parse_comment(parser_t *input); + static token_t parse_newline(parser_t *input); + static token_t parse_assignment(parser_t *input); + static token_t parse_block_open(parser_t *input); + static token_t parse_block_close(parser_t *input); + static token_t parse_comma(parser_t *input); + static token_t parse_semicolon(parser_t *input); + + /* parser dispatch table. */ + parser_input_t parsers[] = { + + { ';', parse_semicolon, }, + { '\\', parse_gobble_line }, + { '#' , parse_comment }, + { '\"', parse_quoted_string }, + { '\n', parse_newline }, + { '=', parse_assignment }, + { '{' , parse_block_open }, + { '}', parse_block_close }, + { ',', parse_comma }, + + }; + + 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) *************** *** 36,40 **** return 0; ! if(ispunct(c) || isalnum(c)) return 1; else --- 79,83 ---- return 0; ! if(isalnum(c) || ispunct(c)) return 1; else *************** *** 46,52 **** { if(feof(input->fp)) ! return PARSER_TOKEN_EOF; else ! return PARSER_TOKEN_ERROR; } --- 89,95 ---- { if(feof(input->fp)) ! return PARSER_ATOM_EOF; else ! return PARSER_ATOM_ERROR; } *************** *** 66,70 **** case '\n': input->line_no++; ! return PARSER_TOKEN_NEWLINE; default: --- 109,113 ---- case '\n': input->line_no++; ! return PARSER_ATOM_NEWLINE; default: *************** *** 75,79 **** /* read a quoted string. */ ! static token_t parse_get_quoted_string(parser_t *input) { int c, c2; --- 118,122 ---- /* read a quoted string. */ ! static token_t parse_quoted_string(parser_t *input) { int c, c2; *************** *** 89,96 **** case '\"': ! return PARSER_TOKEN_QUOTED_STRING; case '\n': ! return PARSER_TOKEN_ERROR; /* error to have newline in string constant. */ case '\\': --- 132,139 ---- case '\"': ! return PARSER_ATOM_STRING; case '\n': ! return PARSER_ATOM_ERROR; /* error to have newline in string constant. */ case '\\': *************** *** 100,105 **** ungetc(c2, input->fp); ! if(parse_gobble_line(input) != PARSER_TOKEN_NEWLINE) ! return PARSER_TOKEN_ERROR; else break; --- 143,148 ---- ungetc(c2, input->fp); ! if(parse_gobble_line(input) != PARSER_ATOM_NEWLINE) ! return PARSER_ATOM_ERROR; else break; *************** *** 115,119 **** else { ungetc(c, input->fp); ! return PARSER_TOKEN_ERROR; } } --- 158,162 ---- else { ungetc(c, input->fp); ! return PARSER_ATOM_ERROR; } } *************** *** 122,126 **** /* read a string. */ ! static token_t parse_get_string(parser_t *input) { int c; --- 165,169 ---- /* read a string. */ ! static token_t parse_string(parser_t *input) { int c; *************** *** 137,157 **** case '\n': ungetc(c, input->fp); ! return PARSER_TOKEN_STRING; /* newline terminates string. */ case '\t': case ' ': ungetc(c, input->fp); ! return PARSER_TOKEN_STRING; /* newline terminates string. */ ! ! case '=': ! ungetc(c, input->fp); ! return PARSER_TOKEN_STRING; /* newline terminates string. */ default: ! if(is_valid_string_char(c)) stringbuffer_append_c(input->data_buff, (char)c); ! else { ungetc(c, input->fp); ! return PARSER_TOKEN_ERROR; /* anything else and we've been terminated. */ } } --- 180,202 ---- case '\n': ungetc(c, input->fp); ! return PARSER_ATOM_STRING; /* newline terminates string. */ case '\t': case ' ': ungetc(c, input->fp); ! return PARSER_ATOM_STRING; /* spaces or tabs terminate string */ default: ! ! if(is_special_char(c)) { ! ungetc(c, input->fp); ! return PARSER_ATOM_STRING; ! } ! ! if(is_valid_string_char(c)) { stringbuffer_append_c(input->data_buff, (char)c); ! } else { ungetc(c, input->fp); ! return PARSER_ATOM_ERROR; /* anything else and we've been terminated. */ } } *************** *** 159,172 **** } /* get the next atom. */ atom_t get_next_atom(parser_t *input) { int c, c2; ! token_t token; stringbuffer_clear(input->data_buff); while(1) { - c = fgetc(input->fp); --- 204,252 ---- } + static token_t parse_comment(parser_t *input) + { + return parse_gobble_line(input); + } + + static token_t parse_newline(parser_t *input) + { + input->line_no++; + return PARSER_ATOM_NEWLINE; + } + + static token_t parse_assignment(parser_t *input) + { + return PARSER_ATOM_ASSIGNMENT; + } + + static token_t parse_block_open(parser_t *input) + { + return PARSER_ATOM_BLOCK_OPEN; + } + + static token_t parse_block_close(parser_t *input) + { + return PARSER_ATOM_BLOCK_CLOSE; + } + + static token_t parse_comma(parser_t *input) + { + return PARSER_ATOM_COMMA; + } + + static token_t parse_semicolon(parser_t *input) + { + return PARSER_ATOM_SEMICOLON; + } + /* get the next atom. */ atom_t get_next_atom(parser_t *input) { int c, c2; ! int i; stringbuffer_clear(input->data_buff); while(1) { c = fgetc(input->fp); *************** *** 176,209 **** return PARSER_ATOM_EOF; - case '#': - - token = parse_gobble_line(input); - - if(token == PARSER_TOKEN_NEWLINE || token == PARSER_TOKEN_EOF) - return PARSER_ATOM_END_OF_STATEMENT; - - /* anything else is an error. */ - return PARSER_ATOM_ERROR; - - case '\n': - input->line_no++; - return PARSER_ATOM_END_OF_STATEMENT; - - case '=': - return PARSER_ATOM_ASSIGNMENT; - - case '\t': case ' ': ! break; ! ! case '\"': ! token = parse_get_quoted_string(input); ! ! if(token == PARSER_TOKEN_ERROR) ! return PARSER_ATOM_ERROR; ! ! return PARSER_ATOM_STRING; case '\\': c2 = getc(input->fp); if(c2 != '\\') { --- 256,265 ---- return PARSER_ATOM_EOF; case ' ': ! case '\t': ! continue; case '\\': + c2 = getc(input->fp); if(c2 != '\\') { *************** *** 211,215 **** ungetc(c2, input->fp); ! if(parse_gobble_line(input) != PARSER_TOKEN_NEWLINE) return PARSER_ATOM_ERROR; else --- 267,271 ---- ungetc(c2, input->fp); ! if(parse_gobble_line(input) != PARSER_ATOM_NEWLINE) return PARSER_ATOM_ERROR; else *************** *** 217,236 **** } else ungetc(c2, input->fp); ! /* fall through */ - default: /* if we have an alphanumeric it's a string. read it in. */ ! if(is_valid_string_char(c)) { ungetc(c, input->fp); ! token = parse_get_string(input); ! ! if(token == PARSER_TOKEN_ERROR) ! return PARSER_ATOM_ERROR; ! ! return PARSER_ATOM_STRING; } return PARSER_ATOM_ERROR; } --- 273,295 ---- } else ungetc(c2, input->fp); ! /* fall through */ default: + + for(i = 0;i < NELMS(parsers); i++) { + + if(parsers[i].character == c) + return parsers[i].do_parse(input); + } + /* if we have an alphanumeric it's a string. read it in. */ ! if(is_valid_string_char(c) || c == '\\') { ungetc(c, input->fp); ! return parse_string(input); } + + /* anything else is an error. */ return PARSER_ATOM_ERROR; } Index: dhcp-parser.h =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-parser.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dhcp-parser.h 16 Nov 2002 00:23:43 -0000 1.3 --- dhcp-parser.h 24 Nov 2002 20:54:31 -0000 1.4 *************** *** 31,34 **** --- 31,41 ---- typedef uint8_t atom_t; + typedef token_t (*parse_input)(parser_t *input); + + typedef struct { + char character; + parse_input do_parse; + } parser_input_t; + extern void destroy_parser(parser_t *parser); extern parser_t *create_parser(const char *filename); *************** *** 38,57 **** /* parser return values. */ ! #define PARSER_TOKEN_ERROR 0 ! #define PARSER_TOKEN_NEWLINE 1 ! #define PARSER_TOKEN_EOF 2 ! #define PARSER_TOKEN_QUOTED_STRING 3 ! #define PARSER_TOKEN_STRING 4 ! #define PARSER_TOKEN_ASSIGNMENT 5 ! ! #define PARSER_ATOM_ERROR 0 ! #define PARSER_ATOM_STRING 1 ! #define PARSER_ATOM_ASSIGNMENT 2 ! #define PARSER_ATOM_END_OF_STATEMENT 3 ! #define PARSER_ATOM_EOF 4 ! ! /* Parse types. */ ! #define PARSE_SINGLE_STRING 1 ! #define PARSE_DOUBLE_STRINGS 2 #endif /* DHCP_PARSER_H */ --- 45,51 ---- /* parser return values. */ ! enum parser_atom { PARSER_ATOM_ERROR = 0, PARSER_ATOM_STRING, PARSER_ATOM_ASSIGNMENT, PARSER_ATOM_NEWLINE, ! PARSER_ATOM_EOF, PARSER_ATOM_BLOCK_OPEN, PARSER_ATOM_BLOCK_CLOSE, PARSER_ATOM_SEMICOLON, ! PARSER_ATOM_COMMA }; #endif /* DHCP_PARSER_H */ Index: dhcp-varfile.c =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-varfile.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dhcp-varfile.c 16 Nov 2002 00:23:44 -0000 1.3 --- dhcp-varfile.c 24 Nov 2002 20:54:31 -0000 1.4 *************** *** 20,25 **** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * ! * varfiles -- variable files. All the files which we read are varfiles. * */ --- 20,28 ---- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * ! * varfiles -- variable files. Files with varname or varname = ! * varvalue for statements. * + * This files are meant to be human readable and be cross platform by writing + * the serialized form of all the values. */ *************** *** 84,88 **** atom = get_next_atom(varfile->parser); ! if(atom == PARSER_ATOM_END_OF_STATEMENT) /* skip empty lines/comments. */ continue; --- 87,91 ---- atom = get_next_atom(varfile->parser); ! if(atom == PARSER_ATOM_NEWLINE) /* skip empty lines/comments. */ continue; *************** *** 98,102 **** /* if we don't get an end of statement or eof here it's a parse error. */ ! if(atom != PARSER_ATOM_END_OF_STATEMENT && atom != PARSER_ATOM_EOF) return VARFILE_PARSE_ERROR; --- 101,105 ---- /* 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; *************** *** 114,118 **** atom = get_next_atom(varfile->parser); ! if(atom == PARSER_ATOM_END_OF_STATEMENT) /* skip empty lines/comments. */ continue; --- 117,121 ---- atom = get_next_atom(varfile->parser); ! if(atom == PARSER_ATOM_NEWLINE) /* skip empty lines/comments. */ continue; *************** *** 128,133 **** } - /* the rest should be ASSIGNMENT STRING END_OF_STATEMENT; */ - atom = get_next_atom(varfile->parser); --- 131,134 ---- *************** *** 147,151 **** atom = get_next_atom(varfile->parser); ! if(atom != PARSER_ATOM_END_OF_STATEMENT && atom != PARSER_ATOM_EOF) return VARFILE_PARSE_ERROR; --- 148,152 ---- atom = get_next_atom(varfile->parser); ! if(atom != PARSER_ATOM_NEWLINE && atom != PARSER_ATOM_EOF) return VARFILE_PARSE_ERROR; |