3 %option outfile="dtd_parse.c"
4 %option prefix="Dtd_Parse_"
5 %option never-interactive
10 * an XML dissector for ethereal
11 * lexical analyzer for DTDs
13 * Copyright 2004, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
17 * Ethereal - Network traffic analyzer
18 * By Gerald Combs <gerald@ethereal.com>
19 * Copyright 1998 Gerald Combs
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License
23 * as published by the Free Software Foundation; either version 2
24 * of the License, or (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
40 #include "dtd_grammar.h"
42 struct _proto_xmlpi_attr {
47 void DtdParse(void*,int,dtd_token_data_t*,dtd_build_data_t*);
48 void *DtdParseAlloc(void *(*)(gulong));
49 void DtdParseFree( void*, void(*)(void*) );
50 void DtdParseTrace(FILE *TraceFILE, char *zTracePrompt);
52 GString* input_string;
58 static int my_yyinput(char* buff,guint size);
60 static dtd_token_data_t* new_token(gchar*);
62 static dtd_build_data_t* build_data;
64 static void set_proto_name (gchar* val) { if(build_data->proto_name) g_free(build_data->proto_name); build_data->proto_name = g_strdup(val); }
65 static void set_media_type (gchar* val) { if(build_data->media_type) g_free(build_data->media_type); build_data->media_type = g_strdup(val); }
66 static void set_proto_root (gchar* val) { if(build_data->proto_root) g_free(build_data->proto_root); build_data->proto_root = g_strdup(val); }
67 static void set_description (gchar* val) { if(build_data->description) g_free(build_data->description); build_data->description = g_strdup(val); }
69 struct _proto_xmlpi_attr proto_attrs[] =
71 { "name", set_proto_name },
72 { "media", set_media_type },
73 { "root", set_proto_root },
74 { "description", set_description },
78 #define DTD_PARSE(token_type) \
79 { build_data->location = location; \
80 DtdParse(pParser, (token_type), new_token(yytext), build_data); \
81 if(build_data->error->len > 0) yyterminate(); \
84 #define YY_INPUT(buff,result,max_size) ( (result) = my_yyinput((buff),(max_size)) )
90 location_xmlpi "ethereal:location"
91 protocol_xmlpi "ethereal:protocol"
93 get_attr_quote =[:blank:]*["]
96 get_location_xmlpi [^[:blank:]]+
102 whitespace [[:blank:]\r\n]+
139 name [a-z][-a-z0-9_]*
143 %START DTD XMLPI LOCATION DONE PROTOCOL GET_ATTR_QUOTE GET_ATTR_VAL GET_ATTR_CLOSE_QUOTE
152 <XMLPI>{location_xmlpi} {
153 if(location) g_free(location);
157 <XMLPI>{protocol_xmlpi} {
162 <XMLPI>{stop_xmlpi} BEGIN DTD;
164 <LOCATION>{get_location_xmlpi} {
165 location = g_strdup(yytext);
169 <DONE>{stop_xmlpi} BEGIN DTD;
172 attr_name = g_strdup(yytext);
173 BEGIN GET_ATTR_QUOTE;
176 <GET_ATTR_QUOTE>{get_attr_quote} { BEGIN GET_ATTR_VAL; }
179 g_string_sprintfa(build_data->error,
180 "error in ethereal:protocol xmpli at %s : could not find attribute value!",
185 <GET_ATTR_VAL>[^"]+ {
187 struct _proto_xmlpi_attr* pa;
188 gboolean got_it = FALSE;
190 for(pa = proto_attrs; pa->name; pa++) {
191 if (g_strcasecmp(attr_name,pa->name) == 0) {
199 g_string_sprintfa(build_data->error,
200 "error in ethereal:protocol xmpli at %s : no such parameter %s!",
201 location, attr_name);
208 BEGIN GET_ATTR_CLOSE_QUOTE;
211 <GET_ATTR_CLOSE_QUOTE>{dquote} { BEGIN PROTOCOL;}
213 <PROTOCOL>{stop_xmlpi} BEGIN DTD;
215 <DTD>{special_start} { DTD_PARSE(TOKEN_TAG_START); }
216 <DTD>{special_stop} { DTD_PARSE(TOKEN_TAG_STOP); }
218 <DTD>{attlist_kw} { DTD_PARSE(TOKEN_ATTLIST_KW); }
219 <DTD>{element_kw} { DTD_PARSE(TOKEN_ELEMENT_KW); }
220 <DTD>{doctype_kw} { DTD_PARSE(TOKEN_DOCTYPE_KW); }
222 <DTD>{pcdata} { DTD_PARSE(TOKEN_ELEM_DATA); }
223 <DTD>{any} { DTD_PARSE(TOKEN_ELEM_DATA); }
224 <DTD>{cdata} { DTD_PARSE(TOKEN_ELEM_DATA); }
225 <DTD>{empty} { DTD_PARSE(TOKEN_EMPTY_KW); }
227 <DTD>{iD} { DTD_PARSE(TOKEN_ATT_TYPE); }
228 <DTD>{idref} { DTD_PARSE(TOKEN_ATT_TYPE); }
229 <DTD>{idrefs} { DTD_PARSE(TOKEN_ATT_TYPE); }
230 <DTD>{nmtoken} { DTD_PARSE(TOKEN_ATT_TYPE); }
231 <DTD>{nmtokens} { DTD_PARSE(TOKEN_ATT_TYPE); }
232 <DTD>{entity} { DTD_PARSE(TOKEN_ATT_TYPE); }
233 <DTD>{entities} { DTD_PARSE(TOKEN_ATT_TYPE); }
234 <DTD>{notation} { DTD_PARSE(TOKEN_ATT_TYPE); }
235 <DTD>{cdata_t} { DTD_PARSE(TOKEN_ATT_TYPE); }
236 <DTD>{defaulT} { DTD_PARSE(TOKEN_ATT_DEF_WITH_VALUE); }
237 <DTD>{fixed} { DTD_PARSE(TOKEN_ATT_DEF_WITH_VALUE); }
238 <DTD>{required} { DTD_PARSE(TOKEN_ATT_DEF); }
239 <DTD>{implied} { DTD_PARSE(TOKEN_ATT_DEF); }
241 <DTD>{star} { DTD_PARSE(TOKEN_STAR); }
242 <DTD>{question} { DTD_PARSE(TOKEN_QUESTION); }
243 <DTD>{plus} { DTD_PARSE(TOKEN_PLUS); }
244 <DTD>{comma} { DTD_PARSE(TOKEN_COMMA); }
245 <DTD>{open_parens} { DTD_PARSE(TOKEN_OPEN_PARENS); }
246 <DTD>{close_parens} { DTD_PARSE(TOKEN_CLOSE_PARENS); }
247 <DTD>{open_bracket} { DTD_PARSE(TOKEN_OPEN_BRACKET); }
248 <DTD>{close_bracket} { DTD_PARSE(TOKEN_CLOSE_BRACKET); }
249 <DTD>{pipe} { DTD_PARSE(TOKEN_PIPE); }
252 <DTD>{squoted} { DTD_PARSE(TOKEN_QUOTED); }
253 <DTD>{name} { DTD_PARSE(TOKEN_NAME); }
257 static dtd_token_data_t* new_token(gchar* text) {
258 dtd_token_data_t* t = g_malloc(sizeof(dtd_token_data_t));
260 t->text = g_strdup(text);
261 t->location = g_strdup(location);
268 static int my_yyinput(char* buff, guint size) {
270 if (offset >= len ) {
272 } else if ( offset + size <= len ) {
273 memcpy(buff, input_string->str + offset,size);
278 memcpy(buff, input_string->str + offset,size);
284 extern dtd_build_data_t* dtd_parse(GString* s) {
288 len = input_string->len;
290 pParser = DtdParseAlloc(g_malloc);
292 build_data = g_malloc(sizeof(dtd_build_data_t));
294 build_data->proto_name = NULL;
295 build_data->media_type = NULL;
296 build_data->description = NULL;
297 build_data->proto_root = NULL;
299 build_data->elements = g_ptr_array_new();
300 build_data->attributes = g_ptr_array_new();
302 build_data->location = NULL;
303 build_data->error = g_string_new("");
309 DtdParse(pParser, 0, NULL,build_data);
313 DtdParseFree(pParser, g_free );