/* * We don't use input, so don't generate code for it. */ %option noinput /* * We don't use unput, so don't generate code for it. */ %option nounput /* * We don't read from the terminal. */ %option never-interactive /* * The language we're scanning is case-insensitive. */ %option caseless /* * Prefix scanner routines with "Dtd_PreParse_" rather than "yy", so this * scanner can coexist with other scanners. */ %option prefix="Dtd_PreParse_" %option outfile="dtd_preparse.c" %{ /* * dtd_preparser.l * * an XML dissector for wireshark * * DTD Preparser - import a dtd file into a GString * including files, removing comments * and resolving %entities; * * Copyright 2004, Luis E. Garcia Ontanon * * Wireshark - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include #include #include #include #include "dtd.h" #include "dtd_preparse_lex.h" #include #define ECHO g_string_append(current,yytext); static GString* current; static GString* output; static GHashTable* entities; static gchar* entity_name; static GString* error; static const gchar* dtd_dirname; static const gchar* filename; static guint linenum; static const gchar* replace_entity(gchar* s); static const gchar* location(void); /* * Flex (v 2.5.35) uses this symbol to "exclude" unistd.h */ #ifdef _WIN32 #define YY_NO_UNISTD_H #endif #ifdef _WIN32 /* disable Windows VC compiler warning "signed/unsigned mismatch" associated */ /* with YY_INPUT code generated by flex versions such as 2.5.35. */ #pragma warning (disable:4018) #endif %} xmlpi_start "" xmlpi_chars . comment_start "" special_start "" entity_start "{xmlpi_start} { g_string_append(current,yytext); BEGIN XMLPI; } {xmlpi_chars} { g_string_append(current,yytext); } {newline} { g_string_append(current,yytext); } {xmlpi_stop} { g_string_append(current,yytext); BEGIN OUTSIDE; } {comment_start} { current = NULL; BEGIN IN_COMMENT; } [^-]? | [-] ; {comment_stop} { current = output; BEGIN OUTSIDE; } {newline} { linenum++; if (current) g_string_append_printf(current,"%s\n",location()); } {entity_start} { BEGIN IN_ENTITY; } {name} { entity_name = g_strdup_printf("%%%s;",yytext); BEGIN NAMED_ENTITY; } {quote} { current = g_string_new(location()); BEGIN IN_QUOTE; } {quote} { g_hash_table_insert(entities,entity_name,current); BEGIN ENTITY_DONE; } {percent} | {non_quote} | {escaped_quote} g_string_append(current,yytext); {system} { g_string_append_printf(error,"at %s:%u: file inclusion is not supported!", filename, linenum); yyterminate(); } {special_stop} { current = output; g_string_append(current,"\n"); BEGIN OUTSIDE; } %% static const gchar* replace_entity(gchar* entity) { GString* replacement; *entity = '%'; replacement = (GString*)g_hash_table_lookup(entities,entity); if (replacement) { return replacement->str; } else { g_string_append_printf(error,"dtd_preparse: in file '%s': entity %s does not exists\n", filename, entity); return ""; } } static const gchar* location(void) { static gchar* loc = NULL; if (loc) g_free(loc); loc = g_strdup_printf("", filename, linenum); return loc; } static gboolean free_gstring_hash_items(gpointer k,gpointer v,gpointer p _U_) { g_free(k); g_string_free((GString*)v,TRUE); return TRUE; } extern GString* dtd_preparse(const gchar* dname,const gchar* fname, GString* err) { gchar* fullname = g_strdup_printf("%s%c%s",dname,G_DIR_SEPARATOR,fname); dtd_dirname = dname; filename = fname; linenum = 1; yyin = ws_fopen(fullname,"r"); if (!yyin) { if (err) g_string_append_printf(err, "Could not open file: '%s', error: %s",fullname,g_strerror(errno)); return NULL; } error = err; entities = g_hash_table_new(g_str_hash,g_str_equal); current = output = g_string_new(location()); BEGIN OUTSIDE; yylex(); fclose(yyin); yyrestart(NULL); g_hash_table_foreach_remove(entities,free_gstring_hash_items,NULL); g_hash_table_destroy(entities); g_free(fullname); return output; } /* * We want to stop processing when we get to the end of the input. * (%option noyywrap is not used because if used then * some flex versions (eg: 2.5.35) generate code which causes * warnings by the Windows VC compiler). */ int yywrap(void) { return 1; }