2 * We don't use input, so don't generate code for it.
7 * We don't use unput, so don't generate code for it.
12 * We don't read from the terminal.
14 %option never-interactive
17 * Prefix scanner routines with "Dtd_Parse_" rather than "yy", so this scanner
18 * can coexist with other scanners.
20 %option prefix="Dtd_Parse_"
22 %option outfile="dtd_parse.c"
27 * an XML dissector for Wireshark
28 * lexical analyzer for DTDs
30 * Copyright 2004, Luis E. Garcia Ontanon <luis@ontanon.org>
34 * Wireshark - Network traffic analyzer
35 * By Gerald Combs <gerald@wireshark.org>
36 * Copyright 1998 Gerald Combs
38 * This program is free software; you can redistribute it and/or
39 * modify it under the terms of the GNU General Public License
40 * as published by the Free Software Foundation; either version 2
41 * of the License, or (at your option) any later version.
43 * This program is distributed in the hope that it will be useful,
44 * but WITHOUT ANY WARRANTY; without even the implied warranty of
45 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46 * GNU General Public License for more details.
48 * You should have received a copy of the GNU General Public License
49 * along with this program; if not, write to the Free Software
50 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
57 #include "dtd_grammar.h"
58 #include "dtd_parse.h"
59 #include "dtd_parse_lex.h"
61 struct _proto_xmlpi_attr {
67 static GString* input_string;
70 static gchar* location;
71 static gchar* attr_name;
73 static int my_yyinput(char* buff,guint size);
75 static dtd_token_data_t* new_token(gchar*);
77 static dtd_build_data_t* build_data;
79 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); }
80 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); }
81 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); }
82 static void set_description (gchar* val) { if(build_data->description) g_free(build_data->description); build_data->description = g_strdup(val); }
83 static void set_recursive (gchar* val) { build_data->recursion = ( g_ascii_strcasecmp(val,"yes") == 0 ) ? TRUE : FALSE; }
85 static struct _proto_xmlpi_attr proto_attrs[] =
87 { "proto_name", set_proto_name },
88 { "media", set_media_type },
89 { "root", set_proto_root },
90 { "description", set_description },
91 { "hierarchy", set_recursive },
95 #ifdef DEBUG_DTD_PARSER
96 #define DEBUG_DTD_TOKEN fprintf(stderr,"->%s (%i)%s\n",location,token_type,yytext)
98 #define DEBUG_DTD_TOKEN
101 #define DTD_PARSE(token_type) \
103 DtdParse(pParser, (token_type), new_token(yytext), build_data); \
104 if(build_data->error->len > 0) yyterminate(); \
108 #define YY_INPUT(buff,result,max_size) ( (result) = my_yyinput((buff),(max_size)) )
111 * Flex (v 2.5.35) uses this symbol to "exclude" unistd.h
114 #define YY_NO_UNISTD_H
124 location_xmlpi "wireshark:location"
125 protocol_xmlpi "wireshark:protocol"
127 get_attr_quote =[:blank:]*["]
130 get_location_xmlpi [^[:blank:]]+
134 notation_tag "<!"[:blank:]*NOTATION
138 whitespace [[:blank:]\r\n]+
175 name [A-Za-z0-9][-a-zA-Z0-9_]*
179 %START DTD XMLPI LOCATION DONE PROTOCOL GET_ATTR_QUOTE GET_ATTR_VAL GET_ATTR_CLOSE_QUOTE IN_COMMENT IN_NOTATION
185 <DTD>{comment_start} { BEGIN IN_COMMENT; }
188 <IN_COMMENT>{comment_stop} { BEGIN DTD; }
190 <DTD>{notation_tag} { BEGIN IN_NOTATION; }
192 <IN_NOTATION>{special_stop} { BEGIN DTD; }
198 <XMLPI>{location_xmlpi} {
202 <XMLPI>{protocol_xmlpi} {
207 <XMLPI>{stop_xmlpi} BEGIN DTD;
209 <LOCATION>{get_location_xmlpi} {
210 if(location) g_free(location);
211 location = g_strdup(yytext);
215 <DONE>{stop_xmlpi} BEGIN DTD;
218 attr_name = g_ascii_strdown(yytext, -1);
219 BEGIN GET_ATTR_QUOTE;
222 <GET_ATTR_QUOTE>{get_attr_quote} { BEGIN GET_ATTR_VAL; }
225 g_string_append_printf(build_data->error,
226 "error in wireshark:protocol xmpli at %s : could not find attribute value!",
231 <GET_ATTR_VAL>[^"]+ {
233 struct _proto_xmlpi_attr* pa;
234 gboolean got_it = FALSE;
236 for(pa = proto_attrs; pa->name; pa++) {
237 if (g_ascii_strcasecmp(attr_name,pa->name) == 0) {
245 g_string_append_printf(build_data->error,
246 "error in wireshark:protocol xmpli at %s : no such parameter %s!",
247 location, attr_name);
254 BEGIN GET_ATTR_CLOSE_QUOTE;
257 <GET_ATTR_CLOSE_QUOTE>{dquote} { BEGIN PROTOCOL;}
259 <PROTOCOL>{stop_xmlpi} BEGIN DTD;
261 <DTD>{special_start} { DTD_PARSE(TOKEN_TAG_START); }
262 <DTD>{special_stop} { DTD_PARSE(TOKEN_TAG_STOP); }
264 <DTD>{attlist_kw} { DTD_PARSE(TOKEN_ATTLIST_KW); }
265 <DTD>{element_kw} { DTD_PARSE(TOKEN_ELEMENT_KW); }
266 <DTD>{doctype_kw} { DTD_PARSE(TOKEN_DOCTYPE_KW); }
268 <DTD>{pcdata} { DTD_PARSE(TOKEN_ELEM_DATA); }
269 <DTD>{any} { DTD_PARSE(TOKEN_ELEM_DATA); }
270 <DTD>{cdata} { DTD_PARSE(TOKEN_ELEM_DATA); }
271 <DTD>{empty} { DTD_PARSE(TOKEN_EMPTY_KW); }
273 <DTD>{iD} { DTD_PARSE(TOKEN_ATT_TYPE); }
274 <DTD>{idref} { DTD_PARSE(TOKEN_ATT_TYPE); }
275 <DTD>{idrefs} { DTD_PARSE(TOKEN_ATT_TYPE); }
276 <DTD>{nmtoken} { DTD_PARSE(TOKEN_ATT_TYPE); }
277 <DTD>{nmtokens} { DTD_PARSE(TOKEN_ATT_TYPE); }
278 <DTD>{entity} { DTD_PARSE(TOKEN_ATT_TYPE); }
279 <DTD>{entities} { DTD_PARSE(TOKEN_ATT_TYPE); }
280 <DTD>{notation} { DTD_PARSE(TOKEN_ATT_TYPE); }
281 <DTD>{cdata_t} { DTD_PARSE(TOKEN_ATT_TYPE); }
282 <DTD>{defaulT} { DTD_PARSE(TOKEN_ATT_DEF_WITH_VALUE); }
283 <DTD>{fixed} { DTD_PARSE(TOKEN_ATT_DEF_WITH_VALUE); }
284 <DTD>{required} { DTD_PARSE(TOKEN_ATT_DEF); }
285 <DTD>{implied} { DTD_PARSE(TOKEN_ATT_DEF); }
287 <DTD>{star} { DTD_PARSE(TOKEN_STAR); }
288 <DTD>{question} { DTD_PARSE(TOKEN_QUESTION); }
289 <DTD>{plus} { DTD_PARSE(TOKEN_PLUS); }
290 <DTD>{comma} { DTD_PARSE(TOKEN_COMMA); }
291 <DTD>{open_parens} { DTD_PARSE(TOKEN_OPEN_PARENS); }
292 <DTD>{close_parens} { DTD_PARSE(TOKEN_CLOSE_PARENS); }
293 <DTD>{open_bracket} { DTD_PARSE(TOKEN_OPEN_BRACKET); }
294 <DTD>{close_bracket} { DTD_PARSE(TOKEN_CLOSE_BRACKET); }
295 <DTD>{pipe} { DTD_PARSE(TOKEN_PIPE); }
298 <DTD>{squoted} { DTD_PARSE(TOKEN_QUOTED); }
299 <DTD>{name} { DTD_PARSE(TOKEN_NAME); }
303 static dtd_token_data_t* new_token(gchar* text) {
304 dtd_token_data_t* t = g_new(dtd_token_data_t,1);
306 t->text = g_strdup(text);
307 t->location = g_strdup(location);
313 static int my_yyinput(char* buff, guint size) {
315 if (offsetx >= len ) {
317 } else if ( offsetx + size <= len ) {
318 memcpy(buff, input_string->str + offsetx,size);
322 size = len - offsetx;
323 memcpy(buff, input_string->str + offsetx,size);
329 extern dtd_build_data_t* dtd_parse(GString* s) {
333 len = (guint) input_string->len;
335 pParser = DtdParseAlloc(g_malloc);
337 #ifdef DEBUG_DTD_PARSER
338 DtdParseTrace(stderr, ">>");
341 build_data = g_new(dtd_build_data_t,1);
343 build_data->proto_name = NULL;
344 build_data->media_type = NULL;
345 build_data->description = NULL;
346 build_data->proto_root = NULL;
347 build_data->recursion = FALSE;
349 build_data->elements = g_ptr_array_new();
350 build_data->attributes = g_ptr_array_new();
352 build_data->error = g_string_new("");
360 DtdParse(pParser, 0, NULL,build_data);
364 if (location) g_free(location);
368 DtdParseFree(pParser, g_free );
374 * We want to stop processing when we get to the end of the input.
375 * (%option noyywrap is not used because if used then
376 * some flex versions (eg: 2.5.35) generate code which causes
377 * warnings by the Windows VC compiler).