From 96326c0b8617db336cb85d122b1e1e5a00644f2b Mon Sep 17 00:00:00 2001 From: Luis Ontanon Date: Sat, 10 Sep 2005 17:29:15 +0000 Subject: the dtd parser (still missing the glue) and few fixes to packet-xml.c svn path=/trunk/; revision=15745 --- epan/dtd_parse.l | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 epan/dtd_parse.l (limited to 'epan/dtd_parse.l') diff --git a/epan/dtd_parse.l b/epan/dtd_parse.l new file mode 100644 index 0000000000..8c33ee26e6 --- /dev/null +++ b/epan/dtd_parse.l @@ -0,0 +1,316 @@ +%option noyywrap +%option nounput +%option outfile="dtd_parse.c" +%option prefix="Dtd_Parse_" +%option never-interactive + +%{ + + /* dtd_lexer.l + * an XML dissector for ethereal + * lexical analyzer for DTDs + * + * Copyright 2004, Luis E. Garcia Ontanon + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "dtd.h" +#include "dtd_grammar.h" + + struct _proto_xmlpi_attr { + gchar* name; + void (*act)(gchar*); + }; + + void DtdParse(void*,int,dtd_token_data_t*,dtd_build_data_t*); + void *DtdParseAlloc(void *(*)(gulong)); + void DtdParseFree( void*, void(*)(void*) ); + void DtdParseTrace(FILE *TraceFILE, char *zTracePrompt); + void* pParser; + GString* input_string; + guint offset; + guint len; + gchar* location; + gchar* attr_name; + + static int my_yyinput(char* buff,guint size); + + static dtd_token_data_t* new_token(gchar*); + + static dtd_build_data_t* build_data; + + 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); } + 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); } + 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); } + static void set_description (gchar* val) { if(build_data->description) g_free(build_data->description); build_data->description = g_strdup(val); } + + struct _proto_xmlpi_attr proto_attrs[] = + { + { "name", set_proto_name }, + { "media", set_media_type }, + { "root", set_proto_root }, + { "description", set_description }, + {NULL,NULL} + }; + +#define DTD_PARSE(token_type) \ + { build_data->location = location; \ + DtdParse(pParser, (token_type), new_token(yytext), build_data); \ + if(build_data->error->len > 0) yyterminate(); \ + } + +#define YY_INPUT(buff,result,max_size) ( (result) = my_yyinput((buff),(max_size)) ) + +%} + +start_xmlpi "" + +special_start "" +whitespace [[:blank:]\r\n]+ +newline \n +attlist_kw ATTLIST +doctype_kw DOCTYPE +element_kw ELEMENT + +pcdata #PCDATA +any ANY +cdata #CDATA + +iD ID +idref IDREF +idrefs IDREFS +nmtoken NMTOKEN +nmtokens NMTOKENS +entity ENTITY +entities ENTITIES +notation NOTATION +cdata_t CDATA + +empty EMPTY +defaulT #DEFAULT +fixed #FIXED +required #REQUIRED +implied #IMPLIED + +star "*" +question "?" +plus "+" +open_parens "(" +close_parens ")" +open_bracket "[" +close_bracket "]" +comma "," +pipe "|" +dquote ["] + +name [a-z][-a-z0-9_]* +dquoted ["][^\"]*["] +squoted ['][^\']*['] + +%START DTD XMLPI LOCATION DONE PROTOCOL GET_ATTR_QUOTE GET_ATTR_VAL GET_ATTR_CLOSE_QUOTE +%% + +{whitespace} ; + +{start_xmlpi} { + BEGIN XMLPI; +} + +{location_xmlpi} { + if(location) g_free(location); + BEGIN LOCATION; +} + +{protocol_xmlpi} { + BEGIN PROTOCOL; +} + +<.> ; +{stop_xmlpi} BEGIN DTD; + +{get_location_xmlpi} { + location = g_strdup(yytext); + BEGIN DONE; +} + +{stop_xmlpi} BEGIN DTD; + +{name} { + attr_name = g_strdup(yytext); + BEGIN GET_ATTR_QUOTE; +} + +{get_attr_quote} { BEGIN GET_ATTR_VAL; } + +. { + g_string_sprintfa(build_data->error, + "error in ethereal:protocol xmpli at %s : could not find attribute value!", + location); + yyterminate(); +} + +[^"]+ { + /*"*/ + struct _proto_xmlpi_attr* pa; + gboolean got_it = FALSE; + + for(pa = proto_attrs; pa->name; pa++) { + if (g_strcasecmp(attr_name,pa->name) == 0) { + pa->act(yytext); + got_it = TRUE; + break; + } + } + + if (! got_it) { + g_string_sprintfa(build_data->error, + "error in ethereal:protocol xmpli at %s : no such parameter %s!", + location, attr_name); + g_free(attr_name); + yyterminate(); + } + + g_free(attr_name); + + BEGIN GET_ATTR_CLOSE_QUOTE; +} + +{dquote} { BEGIN PROTOCOL;} + +{stop_xmlpi} BEGIN DTD; + +{special_start} { DTD_PARSE(TOKEN_TAG_START); } +{special_stop} { DTD_PARSE(TOKEN_TAG_STOP); } + +{attlist_kw} { DTD_PARSE(TOKEN_ATTLIST_KW); } +{element_kw} { DTD_PARSE(TOKEN_ELEMENT_KW); } +{doctype_kw} { DTD_PARSE(TOKEN_DOCTYPE_KW); } + +{pcdata} { DTD_PARSE(TOKEN_ELEM_DATA); } +{any} { DTD_PARSE(TOKEN_ELEM_DATA); } +{cdata} { DTD_PARSE(TOKEN_ELEM_DATA); } +{empty} { DTD_PARSE(TOKEN_EMPTY_KW); } + +{iD} { DTD_PARSE(TOKEN_ATT_TYPE); } +{idref} { DTD_PARSE(TOKEN_ATT_TYPE); } +{idrefs} { DTD_PARSE(TOKEN_ATT_TYPE); } +{nmtoken} { DTD_PARSE(TOKEN_ATT_TYPE); } +{nmtokens} { DTD_PARSE(TOKEN_ATT_TYPE); } +{entity} { DTD_PARSE(TOKEN_ATT_TYPE); } +{entities} { DTD_PARSE(TOKEN_ATT_TYPE); } +{notation} { DTD_PARSE(TOKEN_ATT_TYPE); } +{cdata_t} { DTD_PARSE(TOKEN_ATT_TYPE); } +{defaulT} { DTD_PARSE(TOKEN_ATT_DEF_WITH_VALUE); } +{fixed} { DTD_PARSE(TOKEN_ATT_DEF_WITH_VALUE); } +{required} { DTD_PARSE(TOKEN_ATT_DEF); } +{implied} { DTD_PARSE(TOKEN_ATT_DEF); } + +{star} { DTD_PARSE(TOKEN_STAR); } +{question} { DTD_PARSE(TOKEN_QUESTION); } +{plus} { DTD_PARSE(TOKEN_PLUS); } +{comma} { DTD_PARSE(TOKEN_COMMA); } +{open_parens} { DTD_PARSE(TOKEN_OPEN_PARENS); } +{close_parens} { DTD_PARSE(TOKEN_CLOSE_PARENS); } +{open_bracket} { DTD_PARSE(TOKEN_OPEN_BRACKET); } +{close_bracket} { DTD_PARSE(TOKEN_CLOSE_BRACKET); } +{pipe} { DTD_PARSE(TOKEN_PIPE); } + +{dquoted} | +{squoted} { DTD_PARSE(TOKEN_QUOTED); } +{name} { DTD_PARSE(TOKEN_NAME); } + +%% + +static dtd_token_data_t* new_token(gchar* text) { + dtd_token_data_t* t = g_malloc(sizeof(dtd_token_data_t)); + + t->text = g_strdup(text); + t->location = g_strdup(location); + + return t; +} + + + +static int my_yyinput(char* buff, guint size) { + + if (offset >= len ) { + return YY_NULL; + } else if ( offset + size <= len ) { + memcpy(buff, input_string->str + offset,size); + offset += size; + return size; + } else { + size = len - offset; + memcpy(buff, input_string->str + offset,size); + offset = len; + return size; + } +} + +extern dtd_build_data_t* dtd_parse(GString* s) { + + input_string = s; + offset = 0; + len = input_string->len; + + pParser = DtdParseAlloc(g_malloc); + + build_data = g_malloc(sizeof(dtd_build_data_t)); + + build_data->proto_name = NULL; + build_data->media_type = NULL; + build_data->description = NULL; + build_data->proto_root = NULL; + + build_data->elements = g_ptr_array_new(); + build_data->attributes = g_ptr_array_new(); + + build_data->location = NULL; + build_data->error = g_string_new(""); + + BEGIN DTD; + + yylex(); + + DtdParse(pParser, 0, NULL,build_data); + + yyrestart(NULL); + + DtdParseFree(pParser, g_free ); + + return build_data; +} -- cgit v1.2.1