diff options
author | Luis Ontanon <luis.ontanon@gmail.com> | 2005-09-10 17:29:15 +0000 |
---|---|---|
committer | Luis Ontanon <luis.ontanon@gmail.com> | 2005-09-10 17:29:15 +0000 |
commit | 96326c0b8617db336cb85d122b1e1e5a00644f2b (patch) | |
tree | ac7c2065c289737d9c131c768c1c153e55747890 /epan/dtd_preparse.l | |
parent | 541fd750b86a0fa3666c4ec2d917ff6c23a332f9 (diff) | |
download | wireshark-96326c0b8617db336cb85d122b1e1e5a00644f2b.tar.gz |
the dtd parser (still missing the glue) and few fixes to packet-xml.c
svn path=/trunk/; revision=15745
Diffstat (limited to 'epan/dtd_preparse.l')
-rw-r--r-- | epan/dtd_preparse.l | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/epan/dtd_preparse.l b/epan/dtd_preparse.l new file mode 100644 index 0000000000..101a9161a4 --- /dev/null +++ b/epan/dtd_preparse.l @@ -0,0 +1,258 @@ +%option noyywrap +%option nounput +%option prefix="Dtd_PreParse_" +%option never-interactive +%option caseless +%option outfile="dtd_preparse.c" + +%{ + /* + * dtd_preparser.l + * + * an XML dissector for ethereal + * + * DTD Preparser - import a dtd file into a GString + * including files, removing comments + * and resolving %entities; + * + * Copyright 2004, Luis E. Garcia Ontanon <luis.ontanon@gmail.com> + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * 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 <glib.h> +#include <string.h> +#include <errno.h> +#include <stdio.h> +#include "dtd.h" + +#define MAX_INCLUDE_DEPTH 10 +YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +int include_stack_ptr = 0; + +#define ECHO g_string_append(current,yytext); + +GString* current; +GString* output; +GHashTable* entities; +gchar* entity_name; +GString* error; + +gchar* dirname; +gchar* filename; +guint linenum; + +static gchar* replace_entity(gchar* s); +static const gchar* location(void); +static gchar* load_entity_file(gchar* filename); + /* [:blank:]+file[:blank:]*=[:blank:]*["] */ + +%} +xmlpi_start "<?" +xmlpi_stop "?>" +xmlpi_chars . + +comment_start "<!--" +comment_stop "-->" +special_start "<!" +special_stop ">" + +entity_start "<!"[[:blank:]\n]*entity[[:blank:]\n]*"%" +system SYSTEM +filename [^"]+ + + +name [A-Za-z][-:A-Za-z0-9_]* + +quote "\"" +percent [%] +escaped_quote "\\\"" +non_quote [^"%]+ + +avoid_editor_bug ["] + +entity [%&][A-Za-z][-A-Za-z0-9_]*; + +whitespace [[blank:]]+ +newline \n +%START OUTSIDE IN_COMMENT IN_ENTITY NAMED_ENTITY IN_QUOTE ENTITY_DONE GET_FNAME_OPEN_QUOTE GET_FNAME GET_FNAME_CLOSE_QUOTE XMLPI +%% + + +{entity} if (current) g_string_sprintfa(current,"%s\n%s\n",replace_entity(yytext),location()); + +{whitespace} if (current) g_string_append(current," "); + +<OUTSIDE>{xmlpi_start} { g_string_append(current,yytext); BEGIN XMLPI; } +<XMLPI>{xmlpi_chars} { g_string_append(current,yytext); } +<XMLPI>{newline} { g_string_append(current,yytext); } +<XMLPI>{xmlpi_stop} { g_string_append(current,yytext); BEGIN OUTSIDE; } + +<OUTSIDE>{comment_start} { current = NULL; BEGIN IN_COMMENT; } +<IN_COMMENT>[^-]? | +<IN_COMMENT>[-] ; +<IN_COMMENT>{comment_stop} { current = output; BEGIN OUTSIDE; } + +{newline} { + linenum++; + if (current) g_string_sprintfa(current,"%s\n",location()); +} + + +<OUTSIDE>{entity_start} { BEGIN IN_ENTITY; } +<IN_ENTITY>{name} { entity_name = g_strdup_printf("%%%s;",yytext); BEGIN NAMED_ENTITY; } +<NAMED_ENTITY>{quote} { current = g_string_new(location()); BEGIN IN_QUOTE; } +<IN_QUOTE>{quote} { g_hash_table_insert(entities,entity_name,current); BEGIN ENTITY_DONE; } +<IN_QUOTE>{percent} | +<IN_QUOTE>{non_quote} | +<IN_QUOTE>{escaped_quote} g_string_append(current,yytext); +<NAMED_ENTITY>{system} { BEGIN GET_FNAME_OPEN_QUOTE; } +<GET_FNAME_OPEN_QUOTE>{quote} { BEGIN GET_FNAME; } +<GET_FNAME>{filename} { g_hash_table_insert(entities,entity_name,load_entity_file(yytext)); BEGIN GET_FNAME_CLOSE_QUOTE; } +<GET_FNAME_CLOSE_QUOTE>{quote} { BEGIN ENTITY_DONE; } +<ENTITY_DONE>{special_stop} { current = output; g_string_append(current,"\n"); BEGIN OUTSIDE; } + +%% + +static gchar* load_entity_file(gchar* fname) { + gchar* fullname = g_strdup_printf("%s%s",dirname,fname); + gchar* save_filename = filename; + guint save_linenum = linenum; + FILE* fp = fopen(fullname,"r"); + GString* filetext; + gchar* retstr; + gchar* line; + size_t linelen; + + g_free(fullname); + + if (!fp) { + g_string_sprintfa(error,"at %s:%u: could not load file %s: %s", filename, linenum, fname, strerror(errno)); + return ""; + } + + filename = fname; + linenum = 1; + + filetext = g_string_new(location()); + + while(( line = fgetln(fp,&linelen) )) { + g_string_append(filetext,location()); + g_string_append_len(filetext,line,linelen); + linenum++; + } + + retstr = filetext->str; + g_string_free(filetext,FALSE); + + if ( ferror(fp) ) { + g_string_sprintfa(error,"at %s:%u: problem reading file %s: %s", filename, linenum, fname, strerror(errno)); + } + + filename = save_filename; + save_linenum = linenum; + + return retstr; +} + +static gchar* replace_entity(gchar* entity) { + GString* replacement; + + *entity = '%'; + + replacement = g_hash_table_lookup(entities,entity); + + if (replacement) { + return replacement->str; + } else { + g_string_sprintfa(error,"dtd_preparse: in file '%s': %s does not exists\n", filename, entity); + return ""; + } + +} + +static const gchar* location(void) { + static GString* loc = NULL; + guint i = include_stack_ptr + 1; + + if (loc) { + g_string_truncate(loc,0); + } else { + loc = g_string_new(""); + } + + g_string_sprintfa(loc,"<? ethereal:location "); + + while (i--) { + g_string_sprintfa(loc, "%s:%u from", + filename, + linenum); + } + + g_string_truncate(loc,(loc->len) - 4); + + g_string_sprintfa(loc,"?>"); + + return loc->str; +} + +static gboolean free_gstring_hash_items(gpointer k,gpointer v,gpointer p _U_) { + g_free(k); + g_string_free(v,TRUE); + return TRUE; +} + +extern GString* dtd_preparse(gchar* dname, gchar* fname, GString* err) { + gchar* fullname = g_strdup_printf("%s%s",dname,fname); + + dirname = dname; + filename = fname; + + yyin = fopen(fullname,"r"); + + g_free(fullname); + + if (!yyin) { + if (err) + g_string_sprintfa(err, "Could not open file: '%s', error: %s",filename,strerror(errno)); + + return NULL; + } + + filename = filename; + linenum = 1; + + error = err; + + entities = g_hash_table_new(g_str_hash,g_str_equal); + current = output = g_string_new(location()); + + BEGIN OUTSIDE; + + yylex(); + + yyrestart(NULL); + + g_hash_table_foreach_remove(entities,free_gstring_hash_items,NULL); + g_hash_table_destroy(entities); + + return output; +} |