aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
Diffstat (limited to 'epan')
-rw-r--r--epan/Makefile.am3
-rw-r--r--epan/dfilter/dfilter-int.h8
-rw-r--r--epan/dfilter/dfilter.c37
-rw-r--r--epan/dfilter/scanner.l75
-rw-r--r--epan/diam_dict.l537
-rw-r--r--epan/dtd_parse.h1
-rw-r--r--epan/dtd_parse.l151
-rw-r--r--epan/dtd_preparse.l165
-rw-r--r--epan/radius_dict.l449
-rw-r--r--epan/uat_load.l267
10 files changed, 1064 insertions, 629 deletions
diff --git a/epan/Makefile.am b/epan/Makefile.am
index a1394b6e67..66270fe8bc 100644
--- a/epan/Makefile.am
+++ b/epan/Makefile.am
@@ -116,7 +116,8 @@ MAINTAINERCLEANFILES = \
Makefile.in
BUILT_SOURCES = \
- dtd_grammar.h
+ $(LIBWIRESHARK_GENERATED_HEADER_FILES) \
+ $(NODIST_LIBWIRESHARK_GENERATED_HEADER_FILES)
#
# Add the object files for missing routines, if any.
diff --git a/epan/dfilter/dfilter-int.h b/epan/dfilter/dfilter-int.h
index 40e55488b5..f94c78f139 100644
--- a/epan/dfilter/dfilter-int.h
+++ b/epan/dfilter/dfilter-int.h
@@ -56,10 +56,12 @@ typedef struct {
} dfwork_t;
/*
- * XXX - if we're using a version of Flex that supports reentrant lexical
- * analyzers, we should put this into the lexical analyzer's state.
+ * State kept by the scanner.
*/
-extern dfwork_t *global_dfw;
+typedef struct {
+ dfwork_t *dfw;
+ GString* quoted_string;
+} df_scanner_state_t;
/* Constructor/Destructor prototypes for Lemon Parser */
void *DfilterAlloc(void* (*)(gsize));
diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c
index df24b1ced7..151bb5ec7d 100644
--- a/epan/dfilter/dfilter.c
+++ b/epan/dfilter/dfilter.c
@@ -31,14 +31,10 @@
#include <epan/epan_dissect.h>
#include "dfilter.h"
#include "dfilter-macro.h"
+#include "scanner_lex.h"
#define DFILTER_TOKEN_ID_OFFSET 1
-/* From scanner.c */
-void df_scanner_text(const char *text);
-void df_scanner_cleanup(void);
-int df_lex(void);
-
/* Holds the singular instance of our Lemon parser object */
static void* ParserObj = NULL;
@@ -214,6 +210,9 @@ dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
int token;
dfilter_t *dfilter;
dfwork_t *dfw;
+ df_scanner_state_t state;
+ yyscan_t scanner;
+ YY_BUFFER_STATE in_buffer;
gboolean failure = FALSE;
const char *depr_test;
guint i;
@@ -233,21 +232,28 @@ dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
return FALSE;
}
+ if (df_lex_init(&scanner) != 0) {
+ *dfp = NULL;
+ if (err_msg != NULL)
+ *err_msg = g_strdup_printf("Can't initialize scanner: %s",
+ g_strerror(errno));
+ return FALSE;
+ }
+
+ in_buffer = df__scan_string(expanded_text, scanner);
+
dfw = dfwork_new();
- /*
- * XXX - if we're using a version of Flex that supports reentrant lexical
- * analyzers, we should put this into the lexical analyzer's state.
- */
- global_dfw = dfw;
+ state.dfw = dfw;
+ state.quoted_string = NULL;
- df_scanner_text(expanded_text);
+ df_set_extra(&state, scanner);
deprecated = g_ptr_array_new();
while (1) {
df_lval = stnode_new(STTYPE_UNINITIALIZED, NULL);
- token = df_lex();
+ token = df_lex(scanner);
/* Check for scanner failure */
if (token == SCAN_FAILED) {
@@ -307,8 +313,11 @@ dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg)
if (dfw->syntax_error)
failure = TRUE;
- /* Reset flex */
- df_scanner_cleanup();
+ /* Free scanner state */
+ if (state.quoted_string != NULL)
+ g_string_free(state.quoted_string, TRUE);
+ df__delete_buffer(in_buffer, scanner);
+ df_lex_destroy(scanner);
if (failure)
goto FAILURE;
diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l
index c213ac8351..ce138da8b6 100644
--- a/epan/dfilter/scanner.l
+++ b/epan/dfilter/scanner.l
@@ -1,4 +1,9 @@
/*
+ * We want a reentrant scanner.
+ */
+%option reentrant
+
+/*
* We don't use input, so don't generate code for it.
*/
%option noinput
@@ -24,6 +29,24 @@
*/
%option noyywrap
+/*
+ * The type for the state we keep for a scanner.
+ */
+%option extra-type="df_scanner_state_t *"
+
+/*
+ * We have to override the memory allocators so that we don't get
+ * "unused argument" warnings from the yyscanner argument (which
+ * we don't use, as we have a global memory allocator).
+ *
+ * We provide, as macros, our own versions of the routines generated by Flex,
+ * which just call malloc()/realloc()/free() (as the Flex versions do),
+ * discarding the extra argument.
+ */
+%option noyyalloc
+%option noyyrealloc
+%option noyyfree
+
%{
/*
* Wireshark - Network traffic analyzer
@@ -54,7 +77,6 @@
#include "syntax-tree.h"
#include "grammar.h"
#include "dfunctions.h"
-#include "scanner_lex.h"
#ifdef _WIN32
/* disable Windows VC compiler warning "signed/unsigned mismatch" associated */
@@ -76,9 +98,20 @@ static int set_lval(int token, gpointer data);
static int set_lval_int(dfwork_t *dfw, int token, char *s);
static int simple(int token);
static gboolean str_to_gint32(dfwork_t *dfw, char *s, gint32* pint);
-GString* quoted_string = NULL;
static void mark_lval_deprecated(const char *s);
+/*
+ * Sleazy hack to suppress compiler warnings in yy_fatal_error().
+ */
+#define YY_EXIT_FAILURE ((void)yyscanner, 2)
+
+/*
+ * Macros for the allocators, to discard the extra argument.
+ */
+#define df_alloc(size, yyscanner) (void *)malloc(size)
+#define df_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
+#define df_free(ptr, yyscanner) free((char *)ptr)
+
%}
%x RANGE_INT
@@ -136,12 +169,12 @@ static void mark_lval_deprecated(const char *s);
<RANGE_INT>[+-]?[[:digit:]]+ {
BEGIN(RANGE_PUNCT);
- return set_lval_int(global_dfw, TOKEN_INTEGER, yytext);
+ return set_lval_int(yyextra->dfw, TOKEN_INTEGER, yytext);
}
<RANGE_INT>[+-]?0x[[:xdigit:]]+ {
BEGIN(RANGE_PUNCT);
- return set_lval_int(global_dfw, TOKEN_INTEGER, yytext);
+ return set_lval_int(yyextra->dfw, TOKEN_INTEGER, yytext);
}
<RANGE_INT,RANGE_PUNCT>":" {
@@ -167,7 +200,7 @@ static void mark_lval_deprecated(const char *s);
/* Error if none of the above while scanning a range (slice) */
<RANGE_PUNCT>[^:\-,\]]+ {
- dfilter_fail(global_dfw, "Invalid string \"%s\" found while scanning slice.", yytext);
+ dfilter_fail(yyextra->dfw, "Invalid string \"%s\" found while scanning slice.", yytext);
return SCAN_FAILED;
}
@@ -176,7 +209,7 @@ static void mark_lval_deprecated(const char *s);
*/
<RANGE_INT>. {
- dfilter_fail(global_dfw, "Invalid character \"%s\" found while scanning slice; expected integer.", yytext);
+ dfilter_fail(yyextra->dfw, "Invalid character \"%s\" found while scanning slice; expected integer.", yytext);
return SCAN_FAILED;
}
@@ -192,13 +225,13 @@ static void mark_lval_deprecated(const char *s);
a missing end quote will have left quoted_string set
to something. Clear it now that we are starting
a new quoted string. */
- if (quoted_string) {
- g_string_free(quoted_string, TRUE);
+ if (yyextra->quoted_string) {
+ g_string_free(yyextra->quoted_string, TRUE);
/* Don't set quoted_string to NULL, as we
do in other quoted_string-cleanup code, as we're
about to set it in the next line. */
}
- quoted_string = g_string_new("");
+ yyextra->quoted_string = g_string_new("");
}
<DQUOTE><<EOF>> {
@@ -208,7 +241,7 @@ static void mark_lval_deprecated(const char *s);
See:
http://www.gnu.org/software/flex/manual/html_node/flex_13.html */
- dfilter_fail(global_dfw, "The final quote was missing from a quoted string.");
+ dfilter_fail(yyextra->dfw, "The final quote was missing from a quoted string.");
return SCAN_FAILED;
}
@@ -216,9 +249,9 @@ static void mark_lval_deprecated(const char *s);
/* end quote */
int token;
BEGIN(INITIAL);
- token = set_lval(TOKEN_STRING, quoted_string->str);
- g_string_free(quoted_string, TRUE);
- quoted_string = NULL;
+ token = set_lval(TOKEN_STRING, yyextra->quoted_string->str);
+ g_string_free(yyextra->quoted_string, TRUE);
+ yyextra->quoted_string = NULL;
return token;
}
@@ -227,30 +260,30 @@ static void mark_lval_deprecated(const char *s);
unsigned long result;
result = strtoul(yytext + 1, NULL, 8);
if (result > 0xff) {
- g_string_free(quoted_string, TRUE);
- quoted_string = NULL;
- dfilter_fail(global_dfw, "%s is larger than 255.", yytext);
+ g_string_free(yyextra->quoted_string, TRUE);
+ yyextra->quoted_string = NULL;
+ dfilter_fail(yyextra->dfw, "%s is larger than 255.", yytext);
return SCAN_FAILED;
}
- g_string_append_c(quoted_string, (gchar) result);
+ g_string_append_c(yyextra->quoted_string, (gchar) result);
}
<DQUOTE>\\x[[:xdigit:]]{1,2} {
/* hex sequence */
unsigned long result;
result = strtoul(yytext + 2, NULL, 16);
- g_string_append_c(quoted_string, (gchar) result);
+ g_string_append_c(yyextra->quoted_string, (gchar) result);
}
<DQUOTE>\\. {
/* escaped character */
- g_string_append_c(quoted_string, yytext[1]);
+ g_string_append_c(yyextra->quoted_string, yytext[1]);
}
<DQUOTE>[^\\\042]+ {
/* non-escaped string */
- g_string_append(quoted_string, yytext);
+ g_string_append(yyextra->quoted_string, yytext);
}
@@ -429,5 +462,3 @@ mark_lval_deprecated(const char *s)
{
df_lval->deprecated_token = s;
}
-
-#include <lemonflex-tail.inc>
diff --git a/epan/diam_dict.l b/epan/diam_dict.l
index e97ca8d821..3c450465dc 100644
--- a/epan/diam_dict.l
+++ b/epan/diam_dict.l
@@ -1,4 +1,9 @@
/*
+ * We want a reentrant scanner.
+ */
+%option reentrant
+
+/*
* We don't use input, so don't generate code for it.
*/
%option noinput
@@ -29,13 +34,31 @@
%option noyywrap
/*
- * Prefix scanner routines with "DiamDict" rather than "yy", so this scanner
+ * The type for the state we keep for a scanner.
+ */
+%option extra-type="DiamDict_scanner_state_t *"
+
+/*
+ * Prefix scanner routines with "DiamDict_" rather than "yy", so this scanner
* can coexist with other scanners.
*/
-%option prefix="DiamDict"
+%option prefix="DiamDict_"
%option outfile="diam_dict.c"
+/*
+ * We have to override the memory allocators so that we don't get
+ * "unused argument" warnings from the yyscanner argument (which
+ * we don't use, as we have a global memory allocator).
+ *
+ * We provide, as macros, our own versions of the routines generated by Flex,
+ * which just call malloc()/realloc()/free() (as the Flex versions do),
+ * discarding the extra argument.
+ */
+%option noyyalloc
+%option noyyrealloc
+%option noyyfree
+
%{
/*
** diam_dict.h
@@ -68,7 +91,6 @@
#include <stdlib.h>
#include <stdarg.h>
#include "diam_dict.h"
-#include "diam_dict_lex.h"
#include <epan/to_str.h>
#include <wsutil/file_util.h>
@@ -78,48 +100,80 @@ typedef struct entity_t {
struct entity_t* next;
} entity_t;
-#define ATTR_UINT(cont) do { D(("attr_uint " #cont "\t" )); attr_uint = &(cont); yy_push_state(GET_UINT_ATTR); } while(0)
-#define ATTR_STR(cont) do { D(("attr_str " #cont "\t" )); attr_str = &(cont); yy_push_state(GET_ATTR); } while(0)
-#define IGNORE() do { D(("ignore: %s\t",yytext)); yy_push_state(IGNORE_ATTR); } while(0)
+#define ATTR_UINT(cont) do { D(("attr_uint " #cont "\t" )); yyextra->attr_uint = &(cont); yy_push_state(GET_UINT_ATTR, yyscanner); } while(0)
+#define ATTR_STR(cont) do { D(("attr_str " #cont "\t" )); yyextra->attr_str = &(cont); yy_push_state(GET_ATTR, yyscanner); } while(0)
+#define IGNORE() do { D(("ignore: %s\t",yytext)); yy_push_state(IGNORE_ATTR, yyscanner); } while(0)
#define D(args) ddict_debug args
#define MAX_INCLUDE_DEPTH 10
-#define YY_INPUT(buf,result,max_size) { result = current_yyinput(buf,max_size); }
+#define YY_INPUT(buf,result,max_size) { result = yyextra->current_yyinput(buf,max_size,yyscanner); }
+#define YY_USER_INIT { \
+ DiamDict_scanner_state_t *scanner_state = DiamDict_get_extra(yyscanner); \
+ BEGIN(scanner_state->start_state); \
+}
#define ECHO
-#define APPEND(txt,len) append_to_buffer(txt,len)
-
-static entity_t ents;
-static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
-static int include_stack_ptr = 0;
-static size_t (*current_yyinput)(char*,size_t);
-static const char* sys_dir;
-static ddict_t* dict;
-static ddict_application_t* appl;
-static ddict_avp_t* avp;
-static ddict_enum_t* enumitem;
-static ddict_gavp_t* gavp;
-static ddict_typedefn_t* typedefn;
-static ddict_cmd_t* cmd;
-static ddict_vendor_t* vnd;
-static ddict_xmlpi_t* xmlpi;
-
-static ddict_application_t* last_appl;
-static ddict_avp_t* last_avp;
-static ddict_enum_t* last_enumitem;
-static ddict_gavp_t* last_gavp;
-static ddict_typedefn_t* last_typedefn;
-static ddict_cmd_t* last_cmd;
-static ddict_vendor_t* last_vnd;
-static ddict_xmlpi_t* last_xmlpi;
-
-static char** attr_str;
-static unsigned* attr_uint;
+#define APPEND(txt,len) append_to_buffer(txt,len,yyextra)
+
+typedef struct {
+ const char* sys_dir;
+
+ char* write_ptr;
+ char* read_ptr;
+
+ char* strbuf;
+ unsigned size_strbuf;
+ unsigned len_strbuf;
+
+ ddict_t* dict;
+
+ ddict_application_t* appl;
+ ddict_avp_t* avp;
+ ddict_enum_t* enumitem;
+ ddict_gavp_t* gavp;
+ ddict_typedefn_t* typedefn;
+ ddict_cmd_t* cmd;
+ ddict_vendor_t* vnd;
+ ddict_xmlpi_t* xmlpi;
+
+ ddict_application_t* last_appl;
+ ddict_avp_t* last_avp;
+ ddict_enum_t* last_enumitem;
+ ddict_gavp_t* last_gavp;
+ ddict_typedefn_t* last_typedefn;
+ ddict_cmd_t* last_cmd;
+ ddict_vendor_t* last_vnd;
+ ddict_xmlpi_t* last_xmlpi;
+
+ entity_t *ents;
+
+ char** attr_str;
+ unsigned* attr_uint;
+
+ size_t (*current_yyinput)(char*,size_t,yyscan_t);
+
+ YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+ int include_stack_ptr;
+
+ int start_state;
+} DiamDict_scanner_state_t;
static void ddict_debug(const char* fmt, ...) G_GNUC_PRINTF(1, 2);
-static void append_to_buffer(const char* txt, unsigned len);
+static void append_to_buffer(const char* txt, unsigned len, DiamDict_scanner_state_t *statep);
static FILE* ddict_open(const char*, const char*);
+/*
+ * Sleazy hack to suppress compiler warnings in yy_fatal_error().
+ */
+#define YY_EXIT_FAILURE ((void)yyscanner, 2)
+
+/*
+ * Macros for the allocators, to discard the extra argument.
+ */
+#define DiamDict_alloc(size, yyscanner) (void *)malloc(size)
+#define DiamDict_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
+#define DiamDict_free(ptr, yyscanner) free((char *)ptr)
+
%}
@@ -215,23 +269,25 @@ description_attr description=\042
<LOADING>{xmlpi_start} BEGIN LOADING_XMLPI;
<LOADING_XMLPI>{whitespace} ;
<LOADING_XMLPI>{entityname} {
- xmlpi = g_new(ddict_xmlpi_t,1);
- xmlpi->name = g_strdup(yytext);
- xmlpi->key = NULL;
- xmlpi->value = NULL;
- xmlpi->next = NULL;
+ yyextra->xmlpi = g_new(ddict_xmlpi_t,1);
+ yyextra->xmlpi->name = g_strdup(yytext);
+ yyextra->xmlpi->key = NULL;
+ yyextra->xmlpi->value = NULL;
+ yyextra->xmlpi->next = NULL;
- if (!dict->xmlpis) last_xmlpi = dict->xmlpis = xmlpi;
- else last_xmlpi = last_xmlpi->next = xmlpi;
+ if (!yyextra->dict->xmlpis)
+ yyextra->last_xmlpi = yyextra->dict->xmlpis = yyextra->xmlpi;
+ else
+ yyextra->last_xmlpi = yyextra->last_xmlpi->next = yyextra->xmlpi;
BEGIN XMLPI_ATTRS;
}
<XMLPI_ATTRS>{xmlpi_key_attr} BEGIN XMLPI_GETKEY;
-<XMLPI_GETKEY>{ndquot} { xmlpi->key = strdup(yytext); BEGIN XMLPI_ATTRS; }
+<XMLPI_GETKEY>{ndquot} { yyextra->xmlpi->key = strdup(yytext); BEGIN XMLPI_ATTRS; }
<XMLPI_ATTRS>{xmlpi_value_attr} BEGIN XMLPI_GETVAL;
-<XMLPI_GETVAL>{ndquot} { xmlpi->value = strdup(yytext); BEGIN XMLPI_ATTRS; }
+<XMLPI_GETVAL>{ndquot} { yyextra->xmlpi->value = strdup(yytext); BEGIN XMLPI_ATTRS; }
<XMLPI_ATTRS>.
<XMLPI_ATTRS>{xmlpi_end} BEGIN LOADING;
@@ -241,13 +297,13 @@ description_attr description=\042
<ENTITY>{entityname} {
entity_t* e = g_new(entity_t,1);
e->name = strdup(yytext);
- e->next = ents.next;
- ents.next = e;
+ e->next = yyextra->ents;
+ yyextra->ents = e;
BEGIN GET_SYSTEM;
};
<GET_SYSTEM>{system} BEGIN GET_FILE;
<GET_FILE>{ndquot} {
- ents.next->file = strdup(yytext);
+ yyextra->ents->file = strdup(yytext);
BEGIN END_ENTITY;
}
<END_ENTITY>{end_entity} BEGIN LOADING;
@@ -278,14 +334,14 @@ description_attr description=\042
D(("looking for entity: %s\n",yytext));
- if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
+ if ( yyextra->include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
fprintf(stderr, "included files nested to deeply\n");
yyterminate();
}
- for (e = ents.next; e; e = e->next) {
+ for (e = yyextra->ents; e; e = e->next) {
if (strcmp(e->name,yytext) == 0) {
- yyin = ddict_open(sys_dir,e->file);
+ yyin = ddict_open(yyextra->sys_dir,e->file);
D(("entity: %s filename: %s yyin: %p\n",e->name,e->file,(void*)yyin));
if (!yyin) {
if (errno)
@@ -294,8 +350,8 @@ description_attr description=\042
fprintf(stderr, "Could not open file: '%s', error unknown (errno == 0)\n", e->file );
yyterminate();
} else {
- include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
- yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
+ yyextra->include_stack[yyextra->include_stack_ptr++] = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner), yyscanner);
BEGIN LOADING;
}
break;
@@ -313,35 +369,35 @@ description_attr description=\042
if (!yyin) yyterminate();
fclose(yyin);
- D(("closing: %p %i\n",(void*)yyin,include_stack_ptr));
+ D(("closing: %p %i\n",(void*)yyin,yyextra->include_stack_ptr));
- if ( --include_stack_ptr < 0 ) {
+ if ( --yyextra->include_stack_ptr < 0 ) {
D(("DONE READING\n"));
yyin = NULL;
yyterminate();
} else {
- yy_delete_buffer( YY_CURRENT_BUFFER );
- yy_switch_to_buffer(include_stack[include_stack_ptr]);
+ yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner);
+ yy_switch_to_buffer(yyextra->include_stack[yyextra->include_stack_ptr], yyscanner);
BEGIN LOADING;
}
}
<GET_ATTR>{ndquot} {
- *attr_str = strdup(yytext);
+ *(yyextra->attr_str) = strdup(yytext);
D(("%s\n",yytext));
- attr_str = NULL;
+ yyextra->attr_str = NULL;
BEGIN END_ATTR;
}
<GET_UINT_ATTR>{number} {
- *attr_uint = (unsigned) strtoul(yytext,NULL,10);
+ *(yyextra->attr_uint) = (unsigned) strtoul(yytext,NULL,10);
D(("%s\n",yytext););
- attr_uint = NULL;
+ yyextra->attr_uint = NULL;
BEGIN END_ATTR;
}
-<END_ATTR>{dquot} { yy_pop_state(); }
+<END_ATTR>{dquot} { yy_pop_state(yyscanner); }
<IGNORE_ATTR>. {
/* XXX: should go?*/
@@ -350,7 +406,7 @@ description_attr description=\042
<IGNORE_ATTR>{ignored_quoted} {
D(("=>%s<=\n",yytext));
- yy_pop_state();
+ yy_pop_state(yyscanner);
}
<OUTSIDE>{dictionary_start} {
@@ -367,19 +423,21 @@ description_attr description=\042
<IN_DICT>{application_start} {
D(("application_start\n"));
- appl = g_new(ddict_application_t,1);
- appl->name = NULL;
- appl->code = 0;
- appl->next = NULL;
+ yyextra->appl = g_new(ddict_application_t,1);
+ yyextra->appl->name = NULL;
+ yyextra->appl->code = 0;
+ yyextra->appl->next = NULL;
- if (!dict->applications) last_appl = dict->applications = appl;
- else last_appl = last_appl->next = appl;
+ if (!yyextra->dict->applications)
+ yyextra->last_appl = yyextra->dict->applications = yyextra->appl;
+ else
+ yyextra->last_appl = yyextra->last_appl->next = yyextra->appl;
BEGIN APPL_ATTRS;
}
-<APPL_ATTRS>{name_attr} { ATTR_STR(appl->name); }
-<APPL_ATTRS>{id_attr} { ATTR_UINT(appl->code); }
+<APPL_ATTRS>{name_attr} { ATTR_STR(yyextra->appl->name); }
+<APPL_ATTRS>{id_attr} { ATTR_UINT(yyextra->appl->code); }
<APPL_ATTRS>{stop} BEGIN IN_APPL;
<APPL_ATTRS>{stop_end} BEGIN IN_DICT;
@@ -389,60 +447,66 @@ description_attr description=\042
<IN_APPL>{command_start} {
D(("command_start\n"));
- cmd = g_new(ddict_cmd_t,1);
- cmd->name = NULL;
- cmd->vendor = NULL;
- cmd->code = 0;
- cmd->next = NULL;
+ yyextra->cmd = g_new(ddict_cmd_t,1);
+ yyextra->cmd->name = NULL;
+ yyextra->cmd->vendor = NULL;
+ yyextra->cmd->code = 0;
+ yyextra->cmd->next = NULL;
- if (!dict->cmds) last_cmd = dict->cmds = cmd;
- else last_cmd = last_cmd->next = cmd;
+ if (!yyextra->dict->cmds)
+ yyextra->last_cmd = yyextra->dict->cmds = yyextra->cmd;
+ else
+ yyextra->last_cmd = yyextra->last_cmd->next = yyextra->cmd;
BEGIN COMMAND_ATTRS;
}
-<COMMAND_ATTRS>{name_attr} { ATTR_STR(cmd->name); }
-<COMMAND_ATTRS>{vendor_attr} { ATTR_STR(cmd->vendor); }
-<COMMAND_ATTRS>{code_attr} { ATTR_UINT(cmd->code); }
+<COMMAND_ATTRS>{name_attr} { ATTR_STR(yyextra->cmd->name); }
+<COMMAND_ATTRS>{vendor_attr} { ATTR_STR(yyextra->cmd->vendor); }
+<COMMAND_ATTRS>{code_attr} { ATTR_UINT(yyextra->cmd->code); }
<COMMAND_ATTRS>{stop} |
<COMMAND_ATTRS>{stop_end} { BEGIN IN_APPL; }
<IN_DICT>{vendor_start} {
D(("vendor_start\n"));
- vnd = g_new(ddict_vendor_t,1);
- vnd->name = NULL;
- vnd->code = 0;
- vnd->next = NULL;
+ yyextra->vnd = g_new(ddict_vendor_t,1);
+ yyextra->vnd->name = NULL;
+ yyextra->vnd->code = 0;
+ yyextra->vnd->next = NULL;
- if (!dict->vendors) last_vnd = dict->vendors = vnd;
- else last_vnd = last_vnd->next = vnd;
+ if (!yyextra->dict->vendors)
+ yyextra->last_vnd = yyextra->dict->vendors = yyextra->vnd;
+ else
+ yyextra->last_vnd = yyextra->last_vnd->next = yyextra->vnd;
BEGIN VENDOR_ATTRS;
}
-<VENDOR_ATTRS>{name_attr} { ATTR_STR(vnd->desc); }
-<VENDOR_ATTRS>{vendor_attr} { ATTR_STR(vnd->name); }
-<VENDOR_ATTRS>{code_attr} { ATTR_UINT(vnd->code); }
+<VENDOR_ATTRS>{name_attr} { ATTR_STR(yyextra->vnd->desc); }
+<VENDOR_ATTRS>{vendor_attr} { ATTR_STR(yyextra->vnd->name); }
+<VENDOR_ATTRS>{code_attr} { ATTR_UINT(yyextra->vnd->code); }
<VENDOR_ATTRS>{stop} { BEGIN IN_APPL; }
<VENDOR_ATTRS>{stop_end} { BEGIN IN_DICT; }
<IN_APPL>{typedefn_start} {
D(("typedefn_start\n"));
- typedefn = g_new(ddict_typedefn_t,1);
- typedefn->name = NULL;
- typedefn->parent = NULL;
- typedefn->next = NULL;
+ yyextra->typedefn = g_new(ddict_typedefn_t,1);
+ yyextra->typedefn->name = NULL;
+ yyextra->typedefn->parent = NULL;
+ yyextra->typedefn->next = NULL;
- if (!dict->typedefns) last_typedefn = dict->typedefns = typedefn;
- else last_typedefn = last_typedefn->next = typedefn;
+ if (!yyextra->dict->typedefns)
+ yyextra->last_typedefn = yyextra->dict->typedefns = yyextra->typedefn;
+ else
+ yyextra->last_typedefn = yyextra->last_typedefn->next = yyextra->typedefn;
BEGIN TYPEDEFN_ATTRS;
}
-<TYPEDEFN_ATTRS>{typename_attr} { ATTR_STR(typedefn->name); }
-<TYPEDEFN_ATTRS>{typeparent_attr} { ATTR_STR(typedefn->parent); }
+<TYPEDEFN_ATTRS>{typename_attr} { ATTR_STR(yyextra->typedefn->name); }
+<TYPEDEFN_ATTRS>{typeparent_attr} { ATTR_STR(yyextra->typedefn->parent); }
<TYPEDEFN_ATTRS>{stop} |
<TYPEDEFN_ATTRS>{stop_end} { BEGIN IN_APPL; }
@@ -450,71 +514,77 @@ description_attr description=\042
<IN_APPL>{avp_start} {
D(("avp_start\n"));
- avp = g_new(ddict_avp_t,1);
- avp->name = NULL;
- avp->description = NULL;
- avp->vendor = NULL;
- avp->code = 0;
- avp->type = NULL;
- avp->enums = NULL;
- avp->gavps = NULL;
- avp->next = NULL;
-
- if (! dict->avps ) last_avp = dict->avps = avp;
- else last_avp = last_avp->next = avp;
+ yyextra->avp = g_new(ddict_avp_t,1);
+ yyextra->avp->name = NULL;
+ yyextra->avp->description = NULL;
+ yyextra->avp->vendor = NULL;
+ yyextra->avp->code = 0;
+ yyextra->avp->type = NULL;
+ yyextra->avp->enums = NULL;
+ yyextra->avp->gavps = NULL;
+ yyextra->avp->next = NULL;
+
+ if (! yyextra->dict->avps )
+ yyextra->last_avp = yyextra->dict->avps = yyextra->avp;
+ else
+ yyextra->last_avp = yyextra->last_avp->next = yyextra->avp;
BEGIN AVP_ATTRS;
}
-<AVP_ATTRS>{name_attr} { ATTR_STR(avp->name); }
-<AVP_ATTRS>{description_attr} { ATTR_STR(avp->description); }
-<AVP_ATTRS>{vendor_attr} { ATTR_STR(avp->vendor); }
-<AVP_ATTRS>{code_attr} { ATTR_UINT(avp->code); }
+<AVP_ATTRS>{name_attr} { ATTR_STR(yyextra->avp->name); }
+<AVP_ATTRS>{description_attr} { ATTR_STR(yyextra->avp->description); }
+<AVP_ATTRS>{vendor_attr} { ATTR_STR(yyextra->avp->vendor); }
+<AVP_ATTRS>{code_attr} { ATTR_UINT(yyextra->avp->code); }
<AVP_ATTRS>{stop} { BEGIN IN_AVP; }
<AVP_ATTRS>{stop_end} { BEGIN IN_APPL; }
-<IN_AVP>{grouped_start} { avp->type = strdup("Grouped"); };
+<IN_AVP>{grouped_start} { yyextra->avp->type = strdup("Grouped"); };
<IN_AVP>{grouped_end} ;
<IN_AVP>{type_start} { BEGIN TYPE_ATTRS; }
-<TYPE_ATTRS>{typename_attr} { ATTR_STR(avp->type); }
+<TYPE_ATTRS>{typename_attr} { ATTR_STR(yyextra->avp->type); }
<IN_AVP>{gavp_start} {
D(("gavp_start\n"));
- gavp = g_new(ddict_gavp_t,1);
- gavp->name = NULL;
- gavp->code = 0;
- gavp->next = NULL;
+ yyextra->gavp = g_new(ddict_gavp_t,1);
+ yyextra->gavp->name = NULL;
+ yyextra->gavp->code = 0;
+ yyextra->gavp->next = NULL;
- if (!avp->gavps) last_gavp = avp->gavps = gavp;
- else last_gavp = last_gavp->next = gavp;
+ if (!yyextra->avp->gavps)
+ yyextra->last_gavp = yyextra->avp->gavps = yyextra->gavp;
+ else
+ yyextra->last_gavp = yyextra->last_gavp->next = yyextra->gavp;
BEGIN GAVP_ATTRS;
}
-<GAVP_ATTRS>{name_attr} { ATTR_STR(gavp->name); }
+<GAVP_ATTRS>{name_attr} { ATTR_STR(yyextra->gavp->name); }
<IN_AVP>{enum_start} {
D(("enum_start\n"));
- enumitem = g_new(ddict_enum_t,1);
- enumitem->name = NULL;
- enumitem->code = 0;
- enumitem->next = NULL;
+ yyextra->enumitem = g_new(ddict_enum_t,1);
+ yyextra->enumitem->name = NULL;
+ yyextra->enumitem->code = 0;
+ yyextra->enumitem->next = NULL;
- if (!avp->enums) last_enumitem = avp->enums = enumitem;
- else last_enumitem = last_enumitem->next = enumitem;
+ if (!yyextra->avp->enums)
+ yyextra->last_enumitem = yyextra->avp->enums = yyextra->enumitem;
+ else
+ yyextra->last_enumitem = yyextra->last_enumitem->next = yyextra->enumitem;
BEGIN ENUM_ATTRS;
}
-<ENUM_ATTRS>{name_attr} { ATTR_STR(enumitem->name); }
-<ENUM_ATTRS>{code_attr} { ATTR_UINT(enumitem->code); }
+<ENUM_ATTRS>{name_attr} { ATTR_STR(yyextra->enumitem->name); }
+<ENUM_ATTRS>{code_attr} { ATTR_UINT(yyextra->enumitem->code); }
<TYPE_ATTRS,GAVP_ATTRS,ENUM_ATTRS>{stop} { BEGIN IN_AVP; }
<TYPE_ATTRS,GAVP_ATTRS,ENUM_ATTRS>{stop_end} { BEGIN IN_AVP; }
@@ -561,45 +631,44 @@ static void ddict_debug(const char* fmt, ...) {
fflush(stderr);
}
+/*
+ * Sleazy hack to avoid unused function warnings for yy_top_state.
+ */
+extern void ddict_unused(yyscan_t yyscanner);
-static char* strbuf = NULL;
-static char* write_ptr = NULL;
-static char* read_ptr = NULL;
-
-static unsigned size_strbuf = 8192;
-static unsigned len_strbuf = 0;
-
-extern void ddict_unused(void);
void
-ddict_unused(void)
+ddict_unused(yyscan_t yyscanner)
{
- yy_top_state();
+ yy_top_state(yyscanner);
}
static void
-append_to_buffer(const char* txt, unsigned len)
+append_to_buffer(const char* txt, unsigned len, DiamDict_scanner_state_t *statep)
{
- if (strbuf == NULL) {
- read_ptr = write_ptr = strbuf = (char*)g_malloc(size_strbuf);
+ if (statep->strbuf == NULL) {
+ statep->strbuf = (char*)g_malloc(statep->size_strbuf);
+ statep->read_ptr = statep->strbuf;
+ statep->write_ptr = statep->strbuf;
}
- if ( (len_strbuf + len) >= size_strbuf ) {
- read_ptr = strbuf = (char*)g_realloc(strbuf,size_strbuf *= 2);
+ if ( (statep->len_strbuf + len) >= statep->size_strbuf ) {
+ statep->strbuf = (char*)g_realloc(statep->strbuf,statep->size_strbuf *= 2);
+ statep->read_ptr = statep->strbuf;
}
- write_ptr = strbuf + len_strbuf;
- strncpy(write_ptr,txt,len);
- len_strbuf += len;
-
+ statep->write_ptr = statep->strbuf + statep->len_strbuf;
+ strncpy(statep->write_ptr,txt,len);
+ statep->len_strbuf += len;
}
static size_t
-file_input(char* buf, size_t max)
+file_input(char* buf, size_t max, yyscan_t scanner)
{
+ FILE *in = yyget_in(scanner);
size_t read_cnt;
- read_cnt = fread(buf,1,max,yyin);
+ read_cnt = fread(buf,1,max,in);
if ( read_cnt == max ) {
return max;
@@ -612,16 +681,18 @@ file_input(char* buf, size_t max)
static size_t
-string_input(char* buf, size_t max)
+string_input(char* buf, size_t max, yyscan_t scanner)
{
- if (read_ptr >= write_ptr ) {
+ DiamDict_scanner_state_t *statep = yyget_extra(scanner);
+
+ if (statep->read_ptr >= statep->write_ptr ) {
return YY_NULL;
- } else if ( read_ptr + max > write_ptr ) {
- max = write_ptr - read_ptr;
+ } else if ( statep->read_ptr + max > statep->write_ptr ) {
+ max = statep->write_ptr - statep->read_ptr;
}
- memcpy(buf,read_ptr,max);
- read_ptr += max;
+ memcpy(buf,statep->read_ptr,max);
+ statep->read_ptr += max;
return max;
}
@@ -651,64 +722,114 @@ ddict_open(const char* system_directory, const char* filename)
ddict_t *
ddict_scan(const char* system_directory, const char* filename, int dbg)
{
+ DiamDict_scanner_state_t state;
+ FILE *in;
+ yyscan_t scanner;
debugging = dbg;
- sys_dir = system_directory;
+ state.sys_dir = system_directory;
+
+ state.write_ptr = NULL;
+ state.read_ptr = NULL;
+
+ state.strbuf = NULL;
+ state.size_strbuf = 8192;
+ state.len_strbuf = 0;
+
+ state.dict = g_new(ddict_t,1);
+ state.dict->applications = NULL;
+ state.dict->cmds = NULL;
+ state.dict->vendors = NULL;
+ state.dict->typedefns = NULL;
+ state.dict->avps = NULL;
+ state.dict->xmlpis = NULL;
+
+ state.appl = NULL;
+ state.avp = NULL;
+ state.enumitem = NULL;
+ state.gavp = NULL;
+ state.typedefn = NULL;
+ state.cmd = NULL;
+ state.vnd = NULL;
+ state.xmlpi = NULL;
+
+ state.last_appl = NULL;
+ state.last_avp = NULL;
+ state.last_enumitem = NULL;
+ state.last_gavp = NULL;
+ state.last_typedefn = NULL;
+ state.last_cmd = NULL;
+ state.last_vnd = NULL;
+ state.last_xmlpi = NULL;
+
+ state.ents = NULL;
+
+ state.attr_str = NULL;
+ state.attr_uint = NULL;
- yyin = ddict_open(sys_dir,filename);
+ /*
+ * Pass 1.
+ *
+ * Reads the file, does some work, and stores a modified version
+ * of the file contents in memory.
+ */
+ state.current_yyinput = file_input;
+ state.include_stack_ptr = 0;
- if (yyin == NULL) {
- D(("unable to open %s\n", filename));
+ in = ddict_open(system_directory,filename);
+
+ if (in == NULL) {
+ D(("unable to open %s: %s\n", filename, g_strerror(errno)));
+ g_free(state.dict);
return NULL;
}
- write_ptr = NULL;
- read_ptr = NULL;
-
- dict = g_new(ddict_t,1);
- dict->applications = NULL;
- dict->cmds = NULL;
- dict->vendors = NULL;
- dict->typedefns = NULL;
- dict->avps = NULL;
- dict->xmlpis = NULL;
-
- appl = NULL;
- avp = NULL;
- enumitem = NULL;
- gavp = NULL;
- typedefn = NULL;
- cmd = NULL;
- vnd = NULL;
- xmlpi = NULL;
-
- last_appl = NULL;
- last_avp = NULL;
- last_enumitem = NULL;
- last_gavp = NULL;
- last_typedefn = NULL;
- last_cmd = NULL;
- last_vnd = NULL;
- last_xmlpi = NULL;
-
- ents.next = NULL;
- current_yyinput = file_input;
- BEGIN LOADING;
- yylex();
-
- D(("\n---------------\n%s\n------- %u -------\n",strbuf,len_strbuf));
-
- current_yyinput = string_input;
-
- BEGIN OUTSIDE;
- yylex();
-
- g_free(strbuf);
- strbuf = NULL;
- size_strbuf = 8192;
-
- return dict;
+ if (DiamDict_lex_init(&scanner) != 0) {
+ D(("Can't initialize scanner: %s\n", g_strerror(errno)));
+ fclose(in);
+ g_free(state.dict);
+ return NULL;
+ }
+
+ DiamDict_set_in(in, scanner);
+
+ /* Associate the state with the scanner */
+ DiamDict_set_extra(&state, scanner);
+
+ state.start_state = LOADING;
+ DiamDict_lex(scanner);
+
+ DiamDict_lex_destroy(scanner);
+ fclose(in);
+
+ D(("\n---------------\n%s\n------- %u -------\n",state.strbuf,state.len_strbuf));
+
+ /*
+ * Pass 2.
+ *
+ * Reads the modified version of the file contents and does the
+ * rest of the work.
+ */
+ state.current_yyinput = string_input;
+
+ if (DiamDict_lex_init(&scanner) != 0) {
+ D(("Can't initialize scanner: %s\n", g_strerror(errno)));
+ g_free(state.dict);
+ g_free(state.strbuf);
+ return NULL;
+ }
+
+ /* Associate the state with the scanner */
+ DiamDict_set_extra(&state, scanner);
+
+ state.start_state = OUTSIDE;
+ DiamDict_lex(scanner);
+
+ DiamDict_lex_destroy(scanner);
+ g_free(state.strbuf);
+
+ return state.dict;
}
void
diff --git a/epan/dtd_parse.h b/epan/dtd_parse.h
index 01c2983dbd..a9c3c6117d 100644
--- a/epan/dtd_parse.h
+++ b/epan/dtd_parse.h
@@ -28,4 +28,3 @@ extern void DtdParse(void*,int,dtd_token_data_t*,dtd_build_data_t*);
extern void *DtdParseAlloc(void *(*)(gsize));
extern void DtdParseFree( void*, void(*)(void*) );
extern void DtdParseTrace(FILE *TraceFILE, char *zTracePrompt);
-extern int Dtd_Parse_lex(void);
diff --git a/epan/dtd_parse.l b/epan/dtd_parse.l
index 1c9554478a..ae67cd4a5d 100644
--- a/epan/dtd_parse.l
+++ b/epan/dtd_parse.l
@@ -1,4 +1,9 @@
/*
+ * We want a reentrant scanner.
+ */
+%option reentrant
+
+/*
* We don't use input, so don't generate code for it.
*/
%option noinput
@@ -19,6 +24,11 @@
%option noyywrap
/*
+ * The type for the state we keep for a scanner.
+ */
+%option extra-type="Dtd_Parse_scanner_state_t *"
+
+/*
* Prefix scanner routines with "Dtd_Parse_" rather than "yy", so this scanner
* can coexist with other scanners.
*/
@@ -26,6 +36,19 @@
%option outfile="dtd_parse.c"
+/*
+ * We have to override the memory allocators so that we don't get
+ * "unused argument" warnings from the yyscanner argument (which
+ * we don't use, as we have a global memory allocator).
+ *
+ * We provide, as macros, our own versions of the routines generated by Flex,
+ * which just call malloc()/realloc()/free() (as the Flex versions do),
+ * discarding the extra argument.
+ */
+%option noyyalloc
+%option noyyrealloc
+%option noyyfree
+
%{
/* dtd_parse.l
@@ -53,29 +76,32 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "config.h"
+
#include <glib.h>
#include <string.h>
#include "dtd.h"
#include "dtd_grammar.h"
#include "dtd_parse.h"
-#include "dtd_parse_lex.h"
struct _proto_xmlpi_attr {
const gchar* name;
void (*act)(gchar*);
};
- static void* pParser;
- static GString* input_string;
- static size_t offsetx;
- static size_t len;
- static gchar* location;
- static gchar* attr_name;
+ typedef struct {
+ GString* input_string;
+ size_t offsetx;
+ size_t len;
+ void* pParser;
+ gchar* location;
+ gchar* attr_name;
+ } Dtd_Parse_scanner_state_t;
- static size_t my_yyinput(char* buff,size_t size);
+ static size_t my_yyinput(Dtd_Parse_scanner_state_t *state,char* buff,size_t size);
- static dtd_token_data_t* new_token(gchar*);
+ static dtd_token_data_t* new_token(gchar*,gchar*);
static dtd_build_data_t* build_data;
@@ -85,16 +111,6 @@
static void set_description (gchar* val) { if(build_data->description) g_free(build_data->description); build_data->description = g_strdup(val); }
static void set_recursive (gchar* val) { build_data->recursion = ( g_ascii_strcasecmp(val,"yes") == 0 ) ? TRUE : FALSE; }
- static struct _proto_xmlpi_attr proto_attrs[] =
- {
- { "proto_name", set_proto_name },
- { "media", set_media_type },
- { "root", set_proto_root },
- { "description", set_description },
- { "hierarchy", set_recursive },
- {NULL,NULL}
- };
-
#ifdef DEBUG_DTD_PARSER
#define DEBUG_DTD_TOKEN fprintf(stderr,"->%s (%i)%s\n",location,token_type,yytext)
#else
@@ -103,12 +119,13 @@
#define DTD_PARSE(token_type) \
{ DEBUG_DTD_TOKEN; \
- DtdParse(pParser, (token_type), new_token(yytext), build_data); \
+ DtdParse(yyextra->pParser, (token_type), new_token(yytext, yyextra->location), build_data); \
if(build_data->error->len > 0) yyterminate(); \
}
-#define YY_INPUT(buff,result,max_size) ( (result) = my_yyinput((buff),(max_size)) )
+#define YY_INPUT(buff,result,max_size) ( (result) = my_yyinput(yyextra,(buff),(max_size)) )
+#define YY_USER_INIT BEGIN DTD;
/*
* Flex (v 2.5.35) uses this symbol to "exclude" unistd.h
@@ -117,6 +134,18 @@
#define YY_NO_UNISTD_H
#endif
+/*
+ * Sleazy hack to suppress compiler warnings in yy_fatal_error().
+ */
+#define YY_EXIT_FAILURE ((void)yyscanner, 2)
+
+/*
+ * Macros for the allocators, to discard the extra argument.
+ */
+#define Dtd_Parse_alloc(size, yyscanner) (void *)malloc(size)
+#define Dtd_Parse_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
+#define Dtd_Parse_free(ptr, yyscanner) free((char *)ptr)
+
%}
comment_start "<!--"
@@ -210,15 +239,15 @@ squoted ['][^\']*[']
<XMLPI>{stop_xmlpi} BEGIN DTD;
<LOCATION>{get_location_xmlpi} {
- if(location) g_free(location);
- location = g_strdup(yytext);
+ if(yyextra->location) g_free(yyextra->location);
+ yyextra->location = g_strdup(yytext);
BEGIN DONE;
}
<DONE>{stop_xmlpi} BEGIN DTD;
<PROTOCOL>{name} {
- attr_name = g_ascii_strdown(yytext, -1);
+ yyextra->attr_name = g_ascii_strdown(yytext, -1);
BEGIN GET_ATTR_QUOTE;
}
@@ -227,7 +256,7 @@ squoted ['][^\']*[']
<GET_ATTR_QUOTE>. {
g_string_append_printf(build_data->error,
"error in wireshark:protocol xmpli at %s : could not find attribute value!",
- location);
+ yyextra->location);
yyterminate();
}
@@ -235,9 +264,18 @@ squoted ['][^\']*[']
/*"*/
struct _proto_xmlpi_attr* pa;
gboolean got_it = FALSE;
+ static struct _proto_xmlpi_attr proto_attrs[] =
+ {
+ { "proto_name", set_proto_name },
+ { "media", set_media_type },
+ { "root", set_proto_root },
+ { "description", set_description },
+ { "hierarchy", set_recursive },
+ {NULL,NULL}
+ };
for(pa = proto_attrs; pa->name; pa++) {
- if (g_ascii_strcasecmp(attr_name,pa->name) == 0) {
+ if (g_ascii_strcasecmp(yyextra->attr_name,pa->name) == 0) {
pa->act(yytext);
got_it = TRUE;
break;
@@ -247,12 +285,12 @@ squoted ['][^\']*[']
if (! got_it) {
g_string_append_printf(build_data->error,
"error in wireshark:protocol xmpli at %s : no such parameter %s!",
- location, attr_name);
- g_free(attr_name);
+ yyextra->location, yyextra->attr_name);
+ g_free(yyextra->attr_name);
yyterminate();
}
- g_free(attr_name);
+ g_free(yyextra->attr_name);
BEGIN GET_ATTR_CLOSE_QUOTE;
}
@@ -303,7 +341,7 @@ squoted ['][^\']*[']
%%
-static dtd_token_data_t* new_token(gchar* text) {
+static dtd_token_data_t* new_token(gchar* text, gchar* location) {
dtd_token_data_t* t = g_new(dtd_token_data_t,1);
t->text = g_strdup(text);
@@ -313,29 +351,39 @@ static dtd_token_data_t* new_token(gchar* text) {
}
-static size_t my_yyinput(char* buff, size_t size) {
+static size_t my_yyinput(Dtd_Parse_scanner_state_t *state, char* buff, size_t size) {
- if (offsetx >= len ) {
+ if (state->offsetx >= state->len) {
return YY_NULL;
- } else if ( offsetx + size <= len ) {
- memcpy(buff, input_string->str + offsetx,size);
- offsetx += size;
+ } else if (state->offsetx + size <= state->len) {
+ memcpy(buff, state->input_string->str + state->offsetx, size);
+ state->offsetx += size;
return size;
} else {
- size = len - offsetx;
- memcpy(buff, input_string->str + offsetx,size);
- offsetx = len;
+ size = state->len - state->offsetx;
+ memcpy(buff, state->input_string->str + state->offsetx, size);
+ state->offsetx = state->len;
return size;
}
}
extern dtd_build_data_t* dtd_parse(GString* s) {
+ yyscan_t scanner;
+ Dtd_Parse_scanner_state_t state;
- input_string = s;
- offsetx = 0;
- len = input_string->len;
+ if (Dtd_Parse_lex_init(&scanner) != 0) {
+#ifdef DEBUG_DTD_PARSER
+ fprintf(stderr, "Can't initialize scanner: %s\n",
+ strerror(errno));
+#endif
+ return NULL;
+ }
- pParser = DtdParseAlloc(g_malloc);
+ state.input_string = s;
+ state.offsetx = 0;
+ state.len = state.input_string->len;
+
+ state.pParser = DtdParseAlloc(g_malloc);
#ifdef DEBUG_DTD_PARSER
DtdParseTrace(stderr, ">>");
@@ -354,21 +402,22 @@ extern dtd_build_data_t* dtd_parse(GString* s) {
build_data->error = g_string_new("");
- location = NULL;
-
- BEGIN DTD;
+ state.location = NULL;
+ state.attr_name = NULL;
- yylex();
+ /* Associate the state with the scanner */
+ Dtd_Parse_set_extra(&state, scanner);
- DtdParse(pParser, 0, NULL,build_data);
+ Dtd_Parse_lex(scanner);
- yyrestart(NULL);
+ DtdParse(state.pParser, 0, NULL, build_data);
- if (location) g_free(location);
+ Dtd_Parse_lex_destroy(scanner);
- location = NULL;
+ if (state.location)
+ g_free(state.location);
- DtdParseFree(pParser, g_free );
+ DtdParseFree(state.pParser, g_free);
return build_data;
}
diff --git a/epan/dtd_preparse.l b/epan/dtd_preparse.l
index 5188fbae02..f51f1c7f7a 100644
--- a/epan/dtd_preparse.l
+++ b/epan/dtd_preparse.l
@@ -1,4 +1,9 @@
/*
+ * We want a reentrant scanner.
+ */
+%option reentrant
+
+/*
* We don't use input, so don't generate code for it.
*/
%option noinput
@@ -19,6 +24,11 @@
%option noyywrap
/*
+ * The type for the state we keep for a scanner.
+ */
+%option extra-type="Dtd_PreParse_scanner_state_t *"
+
+/*
* The language we're scanning is case-insensitive.
*/
%option caseless
@@ -31,14 +41,27 @@
%option outfile="dtd_preparse.c"
+/*
+ * We have to override the memory allocators so that we don't get
+ * "unused argument" warnings from the yyscanner argument (which
+ * we don't use, as we have a global memory allocator).
+ *
+ * We provide, as macros, our own versions of the routines generated by Flex,
+ * which just call malloc()/realloc()/free() (as the Flex versions do),
+ * discarding the extra argument.
+ */
+%option noyyalloc
+%option noyyrealloc
+%option noyyfree
+
%{
/*
- * dtd_preparser.l
+ * dtd_preparse.l
*
* an XML dissector for wireshark
*
* DTD Preparser - import a dtd file into a GString
- * including files, removing comments
+ * including files, removing comments
* and resolving %entities;
*
* Copyright 2004, Luis E. Garcia Ontanon <luis@ontanon.org>
@@ -69,23 +92,29 @@
#include <errno.h>
#include <stdio.h>
#include "dtd.h"
-#include "dtd_preparse_lex.h"
#include <wsutil/file_util.h>
-#define ECHO g_string_append(current,yytext);
+#define ECHO g_string_append(yyextra->current,yytext);
-static GString* current;
-static GString* output;
-static GHashTable* entities;
-static gchar* entity_name;
-static GString* error;
+typedef struct {
+ const gchar* dtd_dirname;
+ const gchar* filename;
+ guint linenum;
-static const gchar* dtd_dirname;
-static const gchar* filename;
-static guint linenum;
+ GString* error;
-static const gchar* replace_entity(gchar* s);
-static const gchar* location(void);
+ GHashTable* entities;
+ GString* current;
+ GString* output;
+ gchar* entity_name;
+} Dtd_PreParse_scanner_state_t;
+
+static const gchar* replace_entity(Dtd_PreParse_scanner_state_t* state, gchar* s);
+static const gchar* location(Dtd_PreParse_scanner_state_t* state);
+
+#define YY_USER_INIT { \
+ BEGIN OUTSIDE; \
+}
/*
* Flex (v 2.5.35) uses this symbol to "exclude" unistd.h
@@ -100,6 +129,18 @@ static const gchar* location(void);
#pragma warning (disable:4018)
#endif
+/*
+ * Sleazy hack to suppress compiler warnings in yy_fatal_error().
+ */
+#define YY_EXIT_FAILURE ((void)yyscanner, 2)
+
+/*
+ * Macros for the allocators, to discard the extra argument.
+ */
+#define Dtd_PreParse_alloc(size, yyscanner) (void *)malloc(size)
+#define Dtd_PreParse_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
+#define Dtd_PreParse_free(ptr, yyscanner) free((char *)ptr)
+
%}
xmlpi_start "<?"
xmlpi_stop "?>"
@@ -132,63 +173,63 @@ newline \n
%%
-{entity} if (current) g_string_append_printf(current,"%s\n%s\n",replace_entity(yytext),location());
+{entity} if (yyextra->current) g_string_append_printf(yyextra->current,"%s\n%s\n",replace_entity(yyextra, yytext),location(yyextra));
-{whitespace} if (current) g_string_append(current," ");
+{whitespace} if (yyextra->current) g_string_append(yyextra->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>{xmlpi_start} { g_string_append(yyextra->current,yytext); BEGIN XMLPI; }
+<XMLPI>{xmlpi_chars} { g_string_append(yyextra->current,yytext); }
+<XMLPI>{newline} { g_string_append(yyextra->current,yytext); }
+<XMLPI>{xmlpi_stop} { g_string_append(yyextra->current,yytext); BEGIN OUTSIDE; }
-<OUTSIDE>{comment_start} { current = NULL; BEGIN IN_COMMENT; }
-<IN_COMMENT>[^-]? |
-<IN_COMMENT>[-] ;
-<IN_COMMENT>{comment_stop} { current = output; BEGIN OUTSIDE; }
+<OUTSIDE>{comment_start} { yyextra->current = NULL; BEGIN IN_COMMENT; }
+<IN_COMMENT>[^-]? |
+<IN_COMMENT>[-] ;
+<IN_COMMENT>{comment_stop} { yyextra->current = yyextra->output; BEGIN OUTSIDE; }
-{newline} {
- linenum++;
- if (current) g_string_append_printf(current,"%s\n",location());
+{newline} {
+ yyextra->linenum++;
+ if (yyextra->current) g_string_append_printf(yyextra->current,"%s\n",location(yyextra));
}
<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_ENTITY>{name} { yyextra->entity_name = g_strdup_printf("%%%s;",yytext); BEGIN NAMED_ENTITY; }
+<NAMED_ENTITY>{quote} { yyextra->current = g_string_new(location(yyextra)); BEGIN IN_QUOTE; }
+<IN_QUOTE>{quote} { g_hash_table_insert(yyextra->entities,yyextra->entity_name,yyextra->current); BEGIN ENTITY_DONE; }
+<IN_QUOTE>{percent} |
<IN_QUOTE>{non_quote} |
-<IN_QUOTE>{escaped_quote} g_string_append(current,yytext);
+<IN_QUOTE>{escaped_quote} g_string_append(yyextra->current,yytext);
<NAMED_ENTITY>{system} {
- g_string_append_printf(error,"at %s:%u: file inclusion is not supported!", filename, linenum);
+ g_string_append_printf(yyextra->error,"at %s:%u: file inclusion is not supported!", yyextra->filename, yyextra->linenum);
yyterminate();
}
-<ENTITY_DONE>{special_stop} { current = output; g_string_append(current,"\n"); BEGIN OUTSIDE; }
+<ENTITY_DONE>{special_stop} { yyextra->current = yyextra->output; g_string_append(yyextra->current,"\n"); BEGIN OUTSIDE; }
%%
-static const gchar* replace_entity(gchar* entity) {
+static const gchar* replace_entity(Dtd_PreParse_scanner_state_t* state, gchar* entity) {
GString* replacement;
*entity = '%';
- replacement = (GString*)g_hash_table_lookup(entities,entity);
+ replacement = (GString*)g_hash_table_lookup(state->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);
+ g_string_append_printf(state->error,"dtd_preparse: in file '%s': entity %s does not exists\n", state->filename, entity);
return "";
}
}
-static const gchar* location(void) {
+static const gchar* location(Dtd_PreParse_scanner_state_t* state) {
static gchar* loc = NULL;
if (loc) g_free(loc);
- loc = g_strdup_printf("<? wireshark:location %s:%u ?>", filename, linenum);
+ loc = g_strdup_printf("<? wireshark:location %s:%u ?>", state->filename, state->linenum);
return loc;
}
@@ -201,37 +242,51 @@ static gboolean free_gstring_hash_items(gpointer k,gpointer v,gpointer p _U_) {
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);
+ FILE *in;
+ yyscan_t scanner;
+ Dtd_PreParse_scanner_state_t state;
- dtd_dirname = dname;
- filename = fname;
- linenum = 1;
+ in = ws_fopen(fullname,"r");
- yyin = ws_fopen(fullname,"r");
-
- if (!yyin) {
+ if (!in) {
if (err)
g_string_append_printf(err, "Could not open file: '%s', error: %s",fullname,g_strerror(errno));
return NULL;
}
- error = err;
+ if (Dtd_PreParse_lex_init(&scanner) != 0) {
+ if (err)
+ g_string_append_printf(err, "Can't initialize scanner: %s",
+ strerror(errno));
+ fclose(in);
+ return FALSE;
+ }
+
+ Dtd_PreParse_set_in(in, scanner);
+
+ state.dtd_dirname = dname;
+ state.filename = fname;
+ state.linenum = 1;
- entities = g_hash_table_new(g_str_hash,g_str_equal);
- current = output = g_string_new(location());
+ state.error = err;
- BEGIN OUTSIDE;
+ state.entities = g_hash_table_new(g_str_hash,g_str_equal);
+ state.current = state.output = g_string_new(location(&state));
+ state.entity_name = NULL;
- yylex();
+ /* Associate the state with the scanner */
+ Dtd_PreParse_set_extra(&state, scanner);
- fclose(yyin);
+ Dtd_PreParse_lex(scanner);
- yyrestart(NULL);
+ Dtd_PreParse_lex_destroy(scanner);
+ fclose(in);
- g_hash_table_foreach_remove(entities,free_gstring_hash_items,NULL);
- g_hash_table_destroy(entities);
+ g_hash_table_foreach_remove(state.entities,free_gstring_hash_items,NULL);
+ g_hash_table_destroy(state.entities);
g_free(fullname);
- return output;
+ return state.output;
}
diff --git a/epan/radius_dict.l b/epan/radius_dict.l
index ebbf2a060a..86a8428f07 100644
--- a/epan/radius_dict.l
+++ b/epan/radius_dict.l
@@ -1,4 +1,9 @@
/*
+ * We want a reentrant scanner.
+ */
+%option reentrant
+
+/*
* We don't use input, so don't generate code for it.
*/
%option noinput
@@ -24,10 +29,28 @@
%option caseless
/*
- * Prefix scanner routines with "Radius" rather than "yy", so this scanner
+ * The type for the state we keep for a scanner.
+ */
+%option extra-type="Radius_scanner_state_t*"
+
+/*
+ * We have to override the memory allocators so that we don't get
+ * "unused argument" warnings from the yyscanner argument (which
+ * we don't use, as we have a global memory allocator).
+ *
+ * We provide, as macros, our own versions of the routines generated by Flex,
+ * which just call malloc()/realloc()/free() (as the Flex versions do),
+ * discarding the extra argument.
+ */
+%option noyyalloc
+%option noyyrealloc
+%option noyyfree
+
+/*
+ * Prefix scanner routines with "Radius_" rather than "yy", so this scanner
* can coexist with other scanners.
*/
-%option prefix="Radius"
+%option prefix="Radius_"
%option outfile="radius_dict.c"
@@ -64,9 +87,10 @@
#include <errno.h>
#include <epan/packet.h>
#include <epan/dissectors/packet-radius.h>
-#include "radius_dict_lex.h"
#include <wsutil/file_util.h>
+#define YY_USER_INIT BEGIN WS_OUT;
+
#ifdef _WIN32
/* disable Windows VC compiler warning "signed/unsigned mismatch" associated */
/* with YY_INPUT code generated by flex versions such as 2.5.35. */
@@ -76,36 +100,51 @@
#define ECHO
#define MAX_INCLUDE_DEPTH 10
- static void add_vendor(const gchar* name, guint32 id, guint type_octets, guint length_octets, gboolean has_flags);
- static void add_value(const gchar* attrib_name,const gchar* repr, guint32 value);
- static void add_tlv(const gchar* name, const gchar* code, radius_attr_dissector_t type, const gchar* attr);
- static void add_attribute(const gchar*,const gchar*, radius_attr_dissector_t,const gchar*, guint, gboolean, const gchar*);
-
- static YY_BUFFER_STATE include_stack[10];
- static int include_stack_ptr = 0;
-
- static radius_dictionary_t* dict = NULL;
- static GHashTable* value_strings = NULL; /* GArray(value_string) by attribute name */
-
- static gchar* attr_name = NULL;
- static gchar* attr_id = NULL;
- static radius_attr_dissector_t* attr_type = NULL;
- static gchar* attr_vendor = NULL;
- static gchar* vendor_name = NULL;
- static guint32 vendor_id = 0;
- static guint vendor_type_octets = 1;
- static guint vendor_length_octets = 1;
- static gboolean vendor_has_flags = FALSE;
- static gchar* value_repr = NULL;
- static guint encrypted = 0;
- static gboolean has_tag = FALSE;
- static gchar* current_vendor = NULL;
- static gchar* current_attr = NULL;
-
- static GString* error = NULL;
- static gchar* directory = NULL;
- static int linenums[] = {1,1,1,1,1,1,1,1,1,1};
- static gchar* fullpaths[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+typedef struct {
+ YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+ int include_stack_ptr;
+
+ radius_dictionary_t* dict;
+ GHashTable* value_strings; /* GArray(value_string) by attribute name */
+
+ gchar* attr_name;
+ gchar* attr_id;
+ radius_attr_dissector_t* attr_type;
+ gchar* attr_vendor;
+ gchar* vendor_name;
+ guint32 vendor_id;
+ guint vendor_type_octets;
+ guint vendor_length_octets;
+ gboolean vendor_has_flags;
+ gchar* value_repr;
+ guint encrypted;
+ gboolean has_tag;
+ gchar* current_vendor;
+ gchar* current_attr;
+
+ gchar* directory;
+ gchar* fullpaths[MAX_INCLUDE_DEPTH];
+ int linenums[MAX_INCLUDE_DEPTH];
+
+ GString* error;
+} Radius_scanner_state_t;
+
+static void add_vendor(Radius_scanner_state_t* state, const gchar* name, guint32 id, guint type_octets, guint length_octets, gboolean has_flags);
+static gboolean add_attribute(Radius_scanner_state_t* state, const gchar*,const gchar*, radius_attr_dissector_t,const gchar*, guint, gboolean, const gchar*);
+static gboolean add_tlv(Radius_scanner_state_t* state, const gchar* name, const gchar* code, radius_attr_dissector_t type, const gchar* attr);
+static void add_value(Radius_scanner_state_t* state, const gchar* attrib_name, const gchar* repr, guint32 value);
+
+/*
+ * Sleazy hack to suppress compiler warnings in yy_fatal_error().
+ */
+#define YY_EXIT_FAILURE ((void)yyscanner, 2)
+
+/*
+ * Macros for the allocators, to discard the extra argument.
+ */
+#define Radius_alloc(size, yyscanner) (void *)malloc(size)
+#define Radius_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
+#define Radius_free(ptr, yyscanner) free((char *)ptr)
%}
@@ -132,63 +171,63 @@
<WS_OUT>END-TLV { BEGIN END_TLV; }
<BEGIN_VENDOR>[0-9a-z_-]+ {
- if (current_vendor) {
- g_free(current_vendor);
+ if (yyextra->current_vendor) {
+ g_free(yyextra->current_vendor);
}
- current_vendor = g_strdup(yytext);
+ yyextra->current_vendor = g_strdup(yytext);
BEGIN WS_OUT;
}
<END_VENDOR>[^\n]* {
- if (current_vendor) {
- g_free(current_vendor);
- current_vendor = NULL;
+ if (yyextra->current_vendor) {
+ g_free(yyextra->current_vendor);
+ yyextra->current_vendor = NULL;
}
BEGIN WS_OUT;
}
<BEGIN_TLV>[0-9a-z_-]+ {
- if (current_attr) {
- g_free(current_attr);
+ if (yyextra->current_attr) {
+ g_free(yyextra->current_attr);
}
- current_attr = g_strdup(yytext);
+ yyextra->current_attr = g_strdup(yytext);
BEGIN WS_OUT;
}
<END_TLV>[^\n]* {
- if (current_attr) {
- g_free(current_attr);
- current_attr = NULL;
+ if (yyextra->current_attr) {
+ g_free(yyextra->current_attr);
+ yyextra->current_attr = NULL;
}
BEGIN WS_OUT;
}
<VENDOR>[0-9a-z_-]+ {
- vendor_name = g_strdup(yytext);
- vendor_type_octets = 1;
- vendor_length_octets = 1;
- vendor_has_flags = FALSE;
+ yyextra->vendor_name = g_strdup(yytext);
+ yyextra->vendor_type_octets = 1;
+ yyextra->vendor_length_octets = 1;
+ yyextra->vendor_has_flags = FALSE;
BEGIN VENDOR_W_NAME;
}
<VENDOR_W_NAME>[0-9]+ {
- vendor_id = (guint32) strtoul(yytext,NULL,10);
+ yyextra->vendor_id = (guint32) strtoul(yytext,NULL,10);
BEGIN VENDOR_W_ID;
}
<VENDOR_W_NAME>0x[0-9a-f]+ {
- vendor_id = (guint32) strtoul(yytext,NULL,16);
+ yyextra->vendor_id = (guint32) strtoul(yytext,NULL,16);
BEGIN VENDOR_W_ID;
}
<VENDOR_W_ID>format= {
BEGIN VENDOR_W_FORMAT;
}
<VENDOR_W_FORMAT>[124] {
- vendor_type_octets = (guint) strtoul(yytext,NULL,10);
+ yyextra->vendor_type_octets = (guint) strtoul(yytext,NULL,10);
BEGIN VENDOR_W_TYPE_OCTETS;
}
<VENDOR_W_TYPE_OCTETS>,[012] {
- vendor_length_octets = (guint) strtoul(yytext+1,NULL,10);
+ yyextra->vendor_length_octets = (guint) strtoul(yytext+1,NULL,10);
BEGIN VENDOR_W_LENGTH_OCTETS;
}
<VENDOR_W_LENGTH_OCTETS>,c {
- vendor_has_flags = TRUE;
+ yyextra->vendor_has_flags = TRUE;
BEGIN VENDOR_W_CONTINUATION;
}
<VENDOR_W_FORMAT>\n |
@@ -196,98 +235,103 @@
<VENDOR_W_LENGTH_OCTETS>\n |
<VENDOR_W_CONTINUATION>\n |
<VENDOR_W_ID>\n {
- add_vendor(vendor_name, vendor_id, vendor_type_octets, vendor_length_octets, vendor_has_flags);
- g_free(vendor_name);
+ add_vendor(yyextra, yyextra->vendor_name, yyextra->vendor_id, yyextra->vendor_type_octets, yyextra->vendor_length_octets, yyextra->vendor_has_flags);
+ g_free(yyextra->vendor_name);
BEGIN WS_OUT;
}
-<ATTR>[0-9a-z_/.-]+ { attr_name = g_strdup(yytext); encrypted = 0; has_tag = FALSE; BEGIN ATTR_W_NAME; }
-<ATTR_W_NAME>[0-9]+ { attr_id = g_strdup(yytext); BEGIN ATTR_W_ID;}
-<ATTR_W_NAME>0x[0-9a-f]+ { attr_id = g_strdup_printf("%u",(int)strtoul(yytext,NULL,16)); BEGIN ATTR_W_ID;}
-<ATTR_W_ID>integer { attr_type = radius_integer; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>string { attr_type = radius_string; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>octets { attr_type = radius_octets; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>ipaddr { attr_type = radius_ipaddr; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>ipv6addr { attr_type = radius_ipv6addr; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>ipv6prefix { attr_type = radius_ipv6prefix; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>ipxnet { attr_type = radius_ipxnet; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>date { attr_type = radius_date; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>abinary { attr_type = radius_abinary; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>ether { attr_type = radius_ether; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>ifid { attr_type = radius_ifid; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>byte { attr_type = radius_integer; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>short { attr_type = radius_integer; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>signed { attr_type = radius_signed; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>combo-ip { attr_type = radius_combo_ip; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>tlv { attr_type = radius_tlv; BEGIN ATTR_W_TYPE; }
-<ATTR_W_ID>[0-9a-z_-]+ { attr_type = radius_octets; BEGIN ATTR_W_TYPE; }
-<ATTR_W_TYPE>has_tag[,]? { has_tag = TRUE; }
-<ATTR_W_TYPE>encrypt=[123][,]? { encrypted = (guint) strtoul(yytext+8,NULL,10); }
+<ATTR>[0-9a-z_/.-]+ { yyextra->attr_name = g_strdup(yytext); yyextra->encrypted = 0; yyextra->has_tag = FALSE; BEGIN ATTR_W_NAME; }
+<ATTR_W_NAME>[0-9]+ { yyextra->attr_id = g_strdup(yytext); BEGIN ATTR_W_ID;}
+<ATTR_W_NAME>0x[0-9a-f]+ { yyextra->attr_id = g_strdup_printf("%u",(int)strtoul(yytext,NULL,16)); BEGIN ATTR_W_ID;}
+<ATTR_W_ID>integer { yyextra->attr_type = radius_integer; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>string { yyextra->attr_type = radius_string; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>octets { yyextra->attr_type = radius_octets; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>ipaddr { yyextra->attr_type = radius_ipaddr; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>ipv6addr { yyextra->attr_type = radius_ipv6addr; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>ipv6prefix { yyextra->attr_type = radius_ipv6prefix; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>ipxnet { yyextra->attr_type = radius_ipxnet; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>date { yyextra->attr_type = radius_date; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>abinary { yyextra->attr_type = radius_abinary; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>ether { yyextra->attr_type = radius_ether; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>ifid { yyextra->attr_type = radius_ifid; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>byte { yyextra->attr_type = radius_integer; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>short { yyextra->attr_type = radius_integer; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>signed { yyextra->attr_type = radius_signed; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>combo-ip { yyextra->attr_type = radius_combo_ip; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>tlv { yyextra->attr_type = radius_tlv; BEGIN ATTR_W_TYPE; }
+<ATTR_W_ID>[0-9a-z_-]+ { yyextra->attr_type = radius_octets; BEGIN ATTR_W_TYPE; }
+<ATTR_W_TYPE>has_tag[,]? { yyextra->has_tag = TRUE; }
+<ATTR_W_TYPE>encrypt=[123][,]? { yyextra->encrypted = (guint) strtoul(yytext+8,NULL,10); }
<ATTR_W_TYPE>[0-9a-z_-]+=([^\n]*) ;
<ATTR_W_TYPE>[0-9a-z_-]+ {
- attr_vendor = g_strdup(yytext);
- add_attribute(attr_name,attr_id,attr_type,attr_vendor,encrypted,has_tag,current_attr);
- g_free(attr_id);
- g_free(attr_vendor);
- g_free(attr_name);
- attr_id = NULL;
- attr_vendor = NULL;
- attr_name = NULL;
- BEGIN WS_OUT;
+ gboolean attribute_ok;
+
+ yyextra->attr_vendor = g_strdup(yytext);
+ attribute_ok = add_attribute(yyextra, yyextra->attr_name, yyextra->attr_id, yyextra->attr_type, yyextra->attr_vendor, yyextra->encrypted, yyextra->has_tag, yyextra->current_attr);
+ g_free(yyextra->attr_id);
+ g_free(yyextra->attr_vendor);
+ g_free(yyextra->attr_name);
+ yyextra->attr_id = NULL;
+ yyextra->attr_vendor = NULL;
+ yyextra->attr_name = NULL;
+ if (attribute_ok)
+ BEGIN WS_OUT;
+ else
+ BEGIN JUNK;
}
<ATTR_W_TYPE>\n {
- add_attribute(attr_name,attr_id,attr_type,current_vendor,encrypted,has_tag,current_attr);
- g_free(attr_id);
- g_free(attr_name);
- linenums[include_stack_ptr]++;
- has_tag = FALSE;
- encrypted=FALSE;
+ add_attribute(yyextra, yyextra->attr_name, yyextra->attr_id, yyextra->attr_type, yyextra->current_vendor, yyextra->encrypted, yyextra->has_tag, yyextra->current_attr);
+ g_free(yyextra->attr_id);
+ g_free(yyextra->attr_name);
+ yyextra->linenums[yyextra->include_stack_ptr]++;
+ yyextra->has_tag = FALSE;
+ yyextra->encrypted=FALSE;
BEGIN WS_OUT;
}
<ATTR_W_VENDOR>\n {
- add_attribute(attr_name,attr_id,attr_type,attr_vendor,encrypted,has_tag,current_attr);
- g_free(attr_id);
- g_free(attr_vendor);
- g_free(attr_name);
- linenums[include_stack_ptr]++;
+ add_attribute(yyextra, yyextra->attr_name, yyextra->attr_id, yyextra->attr_type, yyextra->attr_vendor, yyextra->encrypted, yyextra->has_tag, yyextra->current_attr);
+ g_free(yyextra->attr_id);
+ g_free(yyextra->attr_vendor);
+ g_free(yyextra->attr_name);
+ yyextra->linenums[yyextra->include_stack_ptr]++;
BEGIN WS_OUT;
};
-<VALUE>[0-9a-z_/-]+ { attr_name = g_strdup(yytext); BEGIN VALUE_W_ATTR; }
-<VALUE_W_ATTR>[^[:blank:]]+ { value_repr = g_strdup(yytext); BEGIN VALUE_W_NAME; }
-<VALUE_W_NAME>[0-9]+ { add_value(attr_name,value_repr, (guint32) strtoul(yytext,NULL,10)); g_free(attr_name); g_free(value_repr); BEGIN WS_OUT;}
-<VALUE_W_NAME>0x[0-9a-f]+ { add_value(attr_name,value_repr, (guint32) strtoul(yytext,NULL,16)); g_free(attr_name); g_free(value_repr); BEGIN WS_OUT;}
+<VALUE>[0-9a-z_/-]+ { yyextra->attr_name = g_strdup(yytext); BEGIN VALUE_W_ATTR; }
+<VALUE_W_ATTR>[^[:blank:]]+ { yyextra->value_repr = g_strdup(yytext); BEGIN VALUE_W_NAME; }
+<VALUE_W_NAME>[0-9]+ { add_value(yyextra, yyextra->attr_name,yyextra->value_repr, (guint32) strtoul(yytext,NULL,10)); g_free(yyextra->attr_name); g_free(yyextra->value_repr); BEGIN WS_OUT;}
+<VALUE_W_NAME>0x[0-9a-f]+ { add_value(yyextra, yyextra->attr_name,yyextra->value_repr, (guint32) strtoul(yytext,NULL,16)); g_free(yyextra->attr_name); g_free(yyextra->value_repr); BEGIN WS_OUT;}
<INCLUDE>[^[:blank:]\n]+ {
- if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
- g_string_append_printf(error, "$INCLUDE files nested to deeply\n");
+ if ( yyextra->include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
+ g_string_append_printf(yyextra->error, "$INCLUDE files nested too deeply\n");
yyterminate();
}
- include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
+ yyextra->include_stack[yyextra->include_stack_ptr++] = YY_CURRENT_BUFFER;
- fullpaths[include_stack_ptr] = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
- directory,yytext);
+ yyextra->fullpaths[yyextra->include_stack_ptr] = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
+ yyextra->directory,yytext);
- yyin = ws_fopen( fullpaths[include_stack_ptr], "r" );
+ yyin = ws_fopen( yyextra->fullpaths[yyextra->include_stack_ptr], "r" );
if (!yyin) {
if (errno) {
- g_string_append_printf(error,
+ g_string_append_printf(yyextra->error,
"Could not open file: '%s', error: %s\n",
- fullpaths[include_stack_ptr],
+ yyextra->fullpaths[yyextra->include_stack_ptr],
g_strerror(errno) );
} else {
- g_string_append_printf(error,
+ g_string_append_printf(yyextra->error,
"Could not open file: '%s', no errno\n",
- fullpaths[include_stack_ptr]);
+ yyextra->fullpaths[yyextra->include_stack_ptr]);
}
- g_free(fullpaths[include_stack_ptr]);
- fullpaths[include_stack_ptr] = NULL;
- include_stack_ptr--;
+ g_free(yyextra->fullpaths[yyextra->include_stack_ptr]);
+ yyextra->fullpaths[yyextra->include_stack_ptr] = NULL;
+ yyextra->include_stack_ptr--;
} else {
- linenums[include_stack_ptr] = 1;
- yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
+ yyextra->linenums[yyextra->include_stack_ptr] = 1;
+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner), yyscanner);
}
@@ -299,28 +343,28 @@
fclose(yyin);
yyin = NULL;
- if ( --include_stack_ptr < 0 ) {
+ if ( --yyextra->include_stack_ptr < 0 ) {
yyterminate();
} else {
- g_free(fullpaths[include_stack_ptr+1]);
- fullpaths[include_stack_ptr+1] = NULL;
+ g_free(yyextra->fullpaths[yyextra->include_stack_ptr+1]);
+ yyextra->fullpaths[yyextra->include_stack_ptr+1] = NULL;
- yy_delete_buffer( YY_CURRENT_BUFFER );
- yy_switch_to_buffer(include_stack[include_stack_ptr]);
+ Radius__delete_buffer(YY_CURRENT_BUFFER, yyscanner);
+ Radius__switch_to_buffer(yyextra->include_stack[yyextra->include_stack_ptr], yyscanner);
}
BEGIN WS_OUT;
}
-\n { linenums[include_stack_ptr]++; BEGIN WS_OUT; }
+\n { yyextra->linenums[yyextra->include_stack_ptr]++; BEGIN WS_OUT; }
%%
-static void add_vendor(const gchar* name, guint32 id, guint type_octets, guint length_octets, gboolean has_flags) {
+static void add_vendor(Radius_scanner_state_t* state, const gchar* name, guint32 id, guint type_octets, guint length_octets, gboolean has_flags) {
radius_vendor_info_t* v;
- v = (radius_vendor_info_t *)g_hash_table_lookup(dict->vendors_by_id, GUINT_TO_POINTER(id));
+ v = (radius_vendor_info_t *)g_hash_table_lookup(state->dict->vendors_by_id, GUINT_TO_POINTER(id));
if (!v) {
/*
@@ -337,8 +381,8 @@ static void add_vendor(const gchar* name, guint32 id, guint type_octets, guint l
v->length_octets = length_octets;
v->has_flags = has_flags;
- g_hash_table_insert(dict->vendors_by_id,GUINT_TO_POINTER(v->code),v);
- g_hash_table_insert(dict->vendors_by_name, (gpointer) v->name, v);
+ g_hash_table_insert(state->dict->vendors_by_id,GUINT_TO_POINTER(v->code),v);
+ g_hash_table_insert(state->dict->vendors_by_name, (gpointer) v->name, v);
} else {
/*
* This vendor is already in the table.
@@ -367,38 +411,36 @@ static void add_vendor(const gchar* name, guint32 id, guint type_octets, guint l
* Yes. Remove the entry from the by-name hash table
* and re-insert it with the new name.
*/
- g_hash_table_remove(dict->vendors_by_name, (gpointer) v->name);
+ g_hash_table_remove(state->dict->vendors_by_name, (gpointer) v->name);
g_free((gpointer) v->name);
v->name = g_strdup(name);
- g_hash_table_insert(dict->vendors_by_name, (gpointer) v->name, v);
+ g_hash_table_insert(state->dict->vendors_by_name, (gpointer) v->name, v);
}
}
}
-static void add_attribute(const gchar* name, const gchar* codestr, radius_attr_dissector_t type, const gchar* vendor, guint encrypted_flag, gboolean tagged, const gchar* attr) {
+static gboolean add_attribute(Radius_scanner_state_t* state, const gchar* name, const gchar* codestr, radius_attr_dissector_t type, const gchar* vendor, guint encrypted_flag, gboolean tagged, const gchar* attr) {
radius_attr_info_t* a;
GHashTable* by_id;
guint32 code;
if (attr){
- add_tlv(name, codestr, type, attr);
- return;
+ return add_tlv(state, name, codestr, type, attr);
}
if (vendor) {
radius_vendor_info_t* v;
- v = (radius_vendor_info_t *)g_hash_table_lookup(dict->vendors_by_name,vendor);
+ v = (radius_vendor_info_t *)g_hash_table_lookup(state->dict->vendors_by_name,vendor);
if (! v) {
- g_string_append_printf(error, "Vendor: '%s', does not exist in %s:%i \n", vendor, fullpaths[include_stack_ptr], linenums[include_stack_ptr] );
- BEGIN JUNK;
- return;
+ g_string_append_printf(state->error, "Vendor: '%s', does not exist in %s:%i \n", vendor, state->fullpaths[state->include_stack_ptr], state->linenums[state->include_stack_ptr] );
+ return FALSE;
} else {
by_id = v->attrs_by_id;
}
} else {
- by_id = dict->attrs_by_id;
+ by_id = state->dict->attrs_by_id;
}
code= (guint32) strtoul(codestr, NULL, 10);
@@ -426,7 +468,7 @@ static void add_attribute(const gchar* name, const gchar* codestr, radius_attr_
a->ett = -1;
a->tlvs_by_id = NULL;
g_hash_table_insert(by_id, GUINT_TO_POINTER(code),a);
- g_hash_table_insert(dict->attrs_by_name,(gpointer) (a->name),a);
+ g_hash_table_insert(state->dict->attrs_by_name,(gpointer) (a->name),a);
} else {
/*
* This attribute is already in the table.
@@ -454,31 +496,30 @@ static void add_attribute(const gchar* name, const gchar* codestr, radius_attr_
* Yes. Remove the entry from the by-name hash table
* and re-insert it with the new name.
*/
- g_hash_table_remove(dict->attrs_by_name, (gpointer) (a->name));
+ g_hash_table_remove(state->dict->attrs_by_name, (gpointer) (a->name));
g_free((gpointer) a->name);
a->name = g_strdup(name);
- g_hash_table_insert(dict->attrs_by_name, (gpointer) (a->name),a);
+ g_hash_table_insert(state->dict->attrs_by_name, (gpointer) (a->name),a);
}
}
+ return TRUE;
}
-static void add_tlv(const gchar* name, const gchar* codestr, radius_attr_dissector_t type, const gchar* attr) {
+static gboolean add_tlv(Radius_scanner_state_t* state, const gchar* name, const gchar* codestr, radius_attr_dissector_t type, const gchar* attr) {
radius_attr_info_t* a;
radius_attr_info_t* s;
guint32 code;
- a = (radius_attr_info_t*)g_hash_table_lookup(dict->attrs_by_name, attr);
+ a = (radius_attr_info_t*)g_hash_table_lookup(state->dict->attrs_by_name, attr);
if (! a) {
- g_string_append_printf(error, "Attr: '%s', does not exist in %s:%i \n", attr, fullpaths[include_stack_ptr], linenums[include_stack_ptr]);
- BEGIN JUNK;
- return;
+ g_string_append_printf(state->error, "Attr: '%s', does not exist in %s:%i \n", attr, state->fullpaths[state->include_stack_ptr], state->linenums[state->include_stack_ptr]);
+ return FALSE;
}
if (type == radius_tlv) {
- g_string_append_printf(error, "sub-TLV: '%s', sub-TLV's type is specified as tlv in %s:%i \n", name, fullpaths[include_stack_ptr], linenums[include_stack_ptr]);
- BEGIN JUNK;
- return;
+ g_string_append_printf(state->error, "sub-TLV: '%s', sub-TLV's type is specified as tlv in %s:%i \n", name, state->fullpaths[state->include_stack_ptr], state->linenums[state->include_stack_ptr]);
+ return FALSE;
}
@@ -512,7 +553,7 @@ static void add_tlv(const gchar* name, const gchar* codestr, radius_attr_dissec
s->tlvs_by_id = NULL;
g_hash_table_insert(a->tlvs_by_id,GUINT_TO_POINTER(s->code),s);
- g_hash_table_insert(dict->tlvs_by_name,(gpointer) (s->name),s);
+ g_hash_table_insert(state->dict->tlvs_by_name,(gpointer) (s->name),s);
}
/*
@@ -522,17 +563,18 @@ static void add_tlv(const gchar* name, const gchar* codestr, radius_attr_dissec
* one adding some TLV values), and we don't directly add entries
* for TLVs in the RADIUS dissector.
*
- * XXX - report the duplicate entries?
+ * XXX - report the duplicate entries?
*/
+ return TRUE;
}
-void add_value(const gchar* attrib_name, const gchar* repr, guint32 value) {
+void add_value(Radius_scanner_state_t* state, const gchar* attrib_name, const gchar* repr, guint32 value) {
value_string v;
- GArray* a = (GArray*)g_hash_table_lookup(value_strings,attrib_name);
+ GArray* a = (GArray*)g_hash_table_lookup(state->value_strings,attrib_name);
if (! a) {
a = g_array_new(TRUE,TRUE,sizeof(value_string));
- g_hash_table_insert(value_strings,g_strdup(attrib_name),a);
+ g_hash_table_insert(state->value_strings,g_strdup(attrib_name),a);
}
v.value = value;
@@ -541,8 +583,9 @@ void add_value(const gchar* attrib_name, const gchar* repr, guint32 value) {
g_array_append_val(a,v);
}
-static void setup_tlvs(gpointer k _U_, gpointer v, gpointer p _U_) {
+static void setup_tlvs(gpointer k _U_, gpointer v, gpointer p) {
radius_attr_info_t* s = (radius_attr_info_t*)v;
+ Radius_scanner_state_t* state = (Radius_scanner_state_t*)p;
gpointer key;
union {
@@ -550,16 +593,17 @@ static void setup_tlvs(gpointer k _U_, gpointer v, gpointer p _U_) {
gpointer p;
} vs;
- if (g_hash_table_lookup_extended(value_strings, s->name, &key, &vs.p)) {
+ if (g_hash_table_lookup_extended(state->value_strings, s->name, &key, &vs.p)) {
s->vs = (value_string*)(void *)vs.a->data;
g_array_free(vs.a, FALSE);
- g_hash_table_remove(value_strings, key);
+ g_hash_table_remove(state->value_strings, key);
g_free(key);
}
}
-static void setup_attrs(gpointer k _U_, gpointer v, gpointer p _U_) {
+static void setup_attrs(gpointer k _U_, gpointer v, gpointer p) {
radius_attr_info_t* a = (radius_attr_info_t*)v;
+ Radius_scanner_state_t* state = (Radius_scanner_state_t*)p;
gpointer key;
union {
@@ -567,10 +611,10 @@ static void setup_attrs(gpointer k _U_, gpointer v, gpointer p _U_) {
gpointer p;
} vs;
- if (g_hash_table_lookup_extended(value_strings,a->name,&key,&vs.p) ) {
+ if (g_hash_table_lookup_extended(state->value_strings,a->name,&key,&vs.p) ) {
a->vs = (value_string*)(void *)vs.a->data;
g_array_free(vs.a,FALSE);
- g_hash_table_remove(value_strings,key);
+ g_hash_table_remove(state->value_strings,key);
g_free(key);
}
@@ -599,48 +643,89 @@ static gboolean destroy_value_strings(gpointer k, gpointer v, gpointer p _U_) {
}
gboolean radius_load_dictionary (radius_dictionary_t* d, gchar* dir, const gchar* filename, gchar** err_str) {
+ FILE *in;
+ yyscan_t scanner;
+ Radius_scanner_state_t state;
int i;
- dict = d;
- directory = dir;
+ state.include_stack_ptr = 0;
+
+ state.dict = d;
+ state.value_strings = NULL;
+
+ state.attr_name = NULL;
+ state.attr_id = NULL;
+ state.attr_type = NULL;
+ state.attr_vendor = NULL;
+ state.vendor_name = NULL;
+ state.vendor_id = 0;
+ state.vendor_type_octets = 1;
+ state.vendor_length_octets = 1;
+ state.vendor_has_flags = FALSE;
+ state.value_repr = NULL;
+ state.encrypted = 0;
+ state.has_tag = FALSE;
+ state.current_vendor = NULL;
+ state.current_attr = NULL;
+
+ state.directory = dir;
+
+ state.fullpaths[0] = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
+ state.directory,filename);
+ state.linenums[0] = 1;
+ for (i = 1; i < MAX_INCLUDE_DEPTH; i++) {
+ state.fullpaths[i] = NULL;
+ state.linenums[i] = 1;
+ }
- fullpaths[include_stack_ptr] = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
- directory,filename);
+ state.error = g_string_new("");
- error = g_string_new("");
+ in = ws_fopen(state.fullpaths[0],"r");
- yyin = ws_fopen(fullpaths[include_stack_ptr],"r");
+ if (!in) {
+ g_string_append_printf(state.error, "Could not open file: '%s', error: %s\n", state.fullpaths[0], g_strerror(errno));
+ g_free(state.fullpaths[0]);
+ *err_str = g_string_free(state.error,FALSE);
+ return FALSE;
+ }
- if (!yyin) {
- g_string_append_printf(error, "Could not open file: '%s', error: %s\n", fullpaths[include_stack_ptr], g_strerror(errno) );
- g_free(fullpaths[include_stack_ptr]);
- *err_str = g_string_free(error,FALSE);
+ state.value_strings = g_hash_table_new(g_str_hash,g_str_equal);
+
+ if (Radius_lex_init(&scanner) != 0) {
+ g_string_append_printf(state.error, "Can't initialize scanner: %s",
+ strerror(errno));
+ fclose(in);
+ g_free(state.fullpaths[0]);
+ *err_str = g_string_free(state.error,FALSE);
return FALSE;
}
- value_strings = g_hash_table_new(g_str_hash,g_str_equal);
+ Radius_set_in(in, scanner);
- BEGIN WS_OUT;
+ /* Associate the state with the scanner */
+ Radius_set_extra(&state, scanner);
- yylex();
+ Radius_lex(scanner);
- if (yyin != NULL) fclose(yyin);
- yyin = NULL;
+ Radius_lex_destroy(scanner);
+
+ fclose(in);
- for (i=0; i < 10; i++) {
- if (fullpaths[i]) g_free(fullpaths[i]);
+ for (i = 0; i < MAX_INCLUDE_DEPTH; i++) {
+ if (state.fullpaths[i])
+ g_free(state.fullpaths[i]);
}
- g_hash_table_foreach(dict->attrs_by_id,setup_attrs,NULL);
- g_hash_table_foreach(dict->vendors_by_id,setup_vendors,NULL);
- g_hash_table_foreach_remove(value_strings,destroy_value_strings,NULL);
+ g_hash_table_foreach(state.dict->attrs_by_id,setup_attrs,&state);
+ g_hash_table_foreach(state.dict->vendors_by_id,setup_vendors,&state);
+ g_hash_table_foreach_remove(state.value_strings,destroy_value_strings,NULL);
- if (error->len > 0) {
- *err_str = g_string_free(error,FALSE);
+ if (state.error->len > 0) {
+ *err_str = g_string_free(state.error,FALSE);
return FALSE;
} else {
*err_str = NULL;
- g_string_free(error,TRUE);
+ g_string_free(state.error,TRUE);
return TRUE;
}
}
diff --git a/epan/uat_load.l b/epan/uat_load.l
index 149c03226b..a27fb2ff2d 100644
--- a/epan/uat_load.l
+++ b/epan/uat_load.l
@@ -1,4 +1,9 @@
/*
+ * We want a reentrant scanner.
+ */
+%option reentrant
+
+/*
* We don't use input, so don't generate code for it.
*/
%option noinput
@@ -19,11 +24,41 @@
%option noyywrap
/*
+ * The type for the state we keep for a scanner.
+ */
+%option extra-type="uat_load_scanner_state_t *"
+
+/*
+ * We have to override the memory allocators so that we don't get
+ * "unused argument" warnings from the yyscanner argument (which
+ * we don't use, as we have a global memory allocator).
+ *
+ * We provide our own versions of the routines generated by Flex, which
+ * have a "yes, this is unused, don't complain about it" flag for yyscanner.
+ */
+%option noyyalloc
+%option noyyrealloc
+%option noyyfree
+
+/*
* Prefix scanner routines with "uat_load_" rather than "yy", so this scanner
* can coexist with other scanners.
*/
%option prefix="uat_load_"
+/*
+ * We have to override the memory allocators so that we don't get
+ * "unused argument" warnings from the yyscanner argument (which
+ * we don't use, as we have a global memory allocator).
+ *
+ * We provide, as macros, our own versions of the routines generated by Flex,
+ * which just call malloc()/realloc()/free() (as the Flex versions do),
+ * discarding the extra argument.
+ */
+%option noyyalloc
+%option noyyrealloc
+%option noyyfree
+
%{
/*
* uat_load.l
@@ -62,7 +97,6 @@
#include <glib.h>
#include "uat-int.h"
-#include "uat_load_lex.h"
#include <wsutil/file_util.h>
#ifdef _WIN32
@@ -71,41 +105,44 @@
#pragma warning (disable:4018)
#endif
-static uat_t* uat;
-static gboolean valid_record;
-static guint colnum;
-static gchar* ptrx;
-static guint len;
-static gchar* error;
-static void* record;
-static guint linenum;
-static gchar *parse_str;
-static size_t parse_str_pos;
+typedef struct {
+ uat_t* uat;
+ gchar *parse_str;
+
+ gchar* error;
+ gboolean valid_record;
+ guint colnum;
+ gchar* ptrx;
+ guint len;
+ void* record;
+ guint linenum;
+ size_t parse_str_pos;
+} uat_load_scanner_state_t;
#define ERROR(fmtd) do { \
char* fmt_str = g_strdup_printf fmtd; \
- error = g_strdup_printf("%s:%d: %s",uat->filename,linenum,fmt_str); \
+ yyextra->error = g_strdup_printf("%s:%d: %s",yyextra->uat->filename,yyextra->linenum,fmt_str); \
g_free(fmt_str); \
yyterminate(); \
} while(0)
#define SET_FIELD() \
{ gchar* errx; \
- if (uat->fields[colnum].cb.chk) { \
- if ( ! uat->fields[colnum].cb.chk(record, ptrx, len, uat->fields[colnum].cbdata.chk, uat->fields[colnum].fld_data, &errx) ) { \
- error = g_strdup_printf("%s:%d: %s",uat->filename,linenum,errx); \
+ if (yyextra->uat->fields[yyextra->colnum].cb.chk) { \
+ if ( ! yyextra->uat->fields[yyextra->colnum].cb.chk(yyextra->record, yyextra->ptrx, yyextra->len, yyextra->uat->fields[yyextra->colnum].cbdata.chk, yyextra->uat->fields[yyextra->colnum].fld_data, &errx) ) { \
+ yyextra->error = g_strdup_printf("%s:%d: %s",yyextra->uat->filename,yyextra->linenum,errx); \
g_free(errx); \
- valid_record = FALSE; \
+ yyextra->valid_record = FALSE; \
}\
}\
- uat->fields[colnum].cb.set(record, ptrx, len, uat->fields[colnum].cbdata.chk, uat->fields[colnum].fld_data);\
- g_free(ptrx);\
- colnum++; \
+ yyextra->uat->fields[yyextra->colnum].cb.set(yyextra->record, yyextra->ptrx, yyextra->len, yyextra->uat->fields[yyextra->colnum].cbdata.chk, yyextra->uat->fields[yyextra->colnum].fld_data);\
+ g_free(yyextra->ptrx);\
+ yyextra->colnum++; \
} while(0)
#ifdef DEBUG_UAT_LOAD
#define DUMP_FIELD(str) \
- { guint i; printf("%s: %s='",str,uat->fields[colnum].name); for(i=0;i<len;i++) if (uat->fields[colnum].mode == PT_TXTMOD_HEXBYTES) { printf("%.2x ",((guint8*)ptrx)[i]); } else putc(ptrx[i],stdout); printf("'[%d]\n",len); }
+ { guint i; printf("%s: %s='",str,yyextra->uat->fields[yyextra->colnum].name); for(i=0;i<yyextra->len;i++) if (yyextra->uat->fields[yyextra->colnum].mode == PT_TXTMOD_HEXBYTES) { printf("%.2x ",((guint8*)yyextra->ptrx)[i]); } else putc(yyextra->ptrx[i],stdout); printf("'[%d]\n",yyextra->len); }
#define DUMP(str) printf("%s\n",str)
#else
@@ -115,16 +152,16 @@ static size_t parse_str_pos;
/* Modified version of YY_INPUT generated by Flex 2.91 */
#define YY_INPUT(buf,result,max_size) \
- if ( parse_str ) \
+ if ( yyextra->parse_str ) \
{ \
size_t n = 0; \
- size_t pslen = strlen(parse_str); \
- if (parse_str_pos < pslen) \
+ size_t pslen = strlen(yyextra->parse_str); \
+ if (yyextra->parse_str_pos < pslen) \
{ \
- n = pslen - parse_str_pos; \
+ n = pslen - yyextra->parse_str_pos; \
if (n > max_size) n = max_size; \
- memcpy(buf, parse_str + parse_str_pos, n); \
- parse_str_pos += n; \
+ memcpy(buf, yyextra->parse_str + yyextra->parse_str_pos, n); \
+ yyextra->parse_str_pos += n; \
} \
result = n; \
} \
@@ -148,6 +185,21 @@ static size_t parse_str_pos;
* quoted_string below fails badly on "...\\"
* workarround in uat_save(), using /x5c and /x22
*/
+
+#define YY_USER_INIT BEGIN START_OF_LINE;
+
+/*
+ * Sleazy hack to suppress compiler warnings in yy_fatal_error().
+ */
+#define YY_EXIT_FAILURE ((void)yyscanner, 2)
+
+/*
+ * Macros for the allocators, to discard the extra argument.
+ */
+#define uat_load_alloc(size, yyscanner) (void *)malloc(size)
+#define uat_load_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
+#define uat_load_free(ptr, yyscanner) free((char *)ptr)
+
%}
quoted_string \042([^\042]|\134\042)*\042
@@ -160,18 +212,18 @@ comment #[^\n]*\n
%x START_OF_LINE NEXT_FIELD SEPARATOR END_OF_RECORD ERRORED
%%
<START_OF_LINE,NEXT_FIELD>{ws} ;
-<START_OF_LINE>{newline} linenum++;
-<START_OF_LINE>{comment} linenum++;
+<START_OF_LINE>{newline} yyextra->linenum++;
+<START_OF_LINE>{comment} yyextra->linenum++;
<START_OF_LINE,NEXT_FIELD>{separator} {
- ptrx = g_strdup("");
- len = 0;
+ yyextra->ptrx = g_strdup("");
+ yyextra->len = 0;
DUMP_FIELD("empty->next");
SET_FIELD();
- if ( colnum >= uat->ncols ) {
+ if ( yyextra->colnum >= yyextra->uat->ncols ) {
ERROR(("more fields than required"));
}
@@ -179,8 +231,8 @@ comment #[^\n]*\n
}
<START_OF_LINE,NEXT_FIELD>{newline} {
- ptrx = g_strdup("");
- len = 0;
+ yyextra->ptrx = g_strdup("");
+ yyextra->len = 0;
BEGIN END_OF_RECORD;
@@ -188,10 +240,10 @@ comment #[^\n]*\n
}
<START_OF_LINE,NEXT_FIELD>{quoted_string} {
- ptrx = uat_undquote(yytext, (guint) yyleng, &len);
+ yyextra->ptrx = uat_undquote(yytext, (guint) yyleng, &yyextra->len);
- if (colnum < uat->ncols - 1) {
+ if (yyextra->colnum < yyextra->uat->ncols - 1) {
DUMP("quoted_str->s");
BEGIN SEPARATOR;
} else {
@@ -201,13 +253,13 @@ comment #[^\n]*\n
}
<START_OF_LINE,NEXT_FIELD>{binstring} {
- ptrx = uat_unbinstring(yytext, (guint) yyleng, &len);
+ yyextra->ptrx = uat_unbinstring(yytext, (guint) yyleng, &yyextra->len);
- if (!ptrx) {
- ERROR(("uneven hexstring for field %s",uat->fields[colnum].name));
+ if (!yyextra->ptrx) {
+ ERROR(("uneven hexstring for field %s",yyextra->uat->fields[yyextra->colnum].name));
}
- if ( colnum < uat->ncols - 1 ) {
+ if ( yyextra->colnum < yyextra->uat->ncols - 1 ) {
DUMP("binstring->s");
BEGIN SEPARATOR;
} else {
@@ -222,7 +274,7 @@ comment #[^\n]*\n
SET_FIELD();
- if ( colnum >= uat->ncols ) {
+ if ( yyextra->colnum >= yyextra->uat->ncols ) {
ERROR(("more fields than required"));
}
@@ -230,12 +282,12 @@ comment #[^\n]*\n
}
<SEPARATOR>{newline} {
- linenum++;
- ERROR(("expecting field %s in previous line",uat->fields[colnum].name));
+ yyextra->linenum++;
+ ERROR(("expecting field %s in previous line",yyextra->uat->fields[yyextra->colnum].name));
}
<SEPARATOR>. {
- ERROR(("unexpected char '%s' while looking for field %s",yytext,uat->fields[colnum].name));
+ ERROR(("unexpected char '%s' while looking for field %s",yytext,yyextra->uat->fields[yyextra->colnum].name));
}
<END_OF_RECORD>{separator} {
@@ -246,28 +298,28 @@ comment #[^\n]*\n
void* rec;
char* err = NULL;
- linenum++;
+ yyextra->linenum++;
DUMP_FIELD("newline->start");
SET_FIELD();
- rec = uat_add_record(uat, record, valid_record);
+ rec = uat_add_record(yyextra->uat, yyextra->record, yyextra->valid_record);
- if ((uat->update_cb) && (rec != NULL)) {
- if (!uat->update_cb(rec,&err)) {
- error = err;
+ if ((yyextra->uat->update_cb) && (rec != NULL)) {
+ if (!yyextra->uat->update_cb(rec,&err)) {
+ yyextra->error = err;
yyterminate();
}
}
- valid_record = TRUE;
- colnum = 0;
- ptrx = NULL;
- len = 0;
+ yyextra->valid_record = TRUE;
+ yyextra->colnum = 0;
+ yyextra->ptrx = NULL;
+ yyextra->len = 0;
/* XXX is this necessary since we free it before reusing anyway? */
- memset(record,0,uat->record_size);
+ memset(yyextra->record,0,yyextra->uat->record_size);
BEGIN START_OF_LINE;
}
@@ -276,10 +328,10 @@ comment #[^\n]*\n
ERROR(("unexpected char while looking for end of line"));
}
-<ERRORED>{newline} { linenum++; BEGIN START_OF_LINE; }
+<ERRORED>{newline} { yyextra->linenum++; BEGIN START_OF_LINE; }
<ERRORED>. ;
-{newline} { linenum++; ERROR(("incomplete record")); }
+{newline} { yyextra->linenum++; ERROR(("incomplete record")); }
. { ERROR(("unexpected input")); }
%%
@@ -288,12 +340,12 @@ comment #[^\n]*\n
gboolean
-uat_load(uat_t *uat_in, char **errx)
+uat_load(uat_t *uat, char **errx)
{
- gchar *fname = uat_get_actual_filename(uat_in, FALSE);
-
- uat = uat_in;
- parse_str = NULL;
+ gchar *fname = uat_get_actual_filename(uat, FALSE);
+ FILE *in;
+ yyscan_t scanner;
+ uat_load_scanner_state_t state;
if (!fname) {
UAT_UPDATE(uat);
@@ -305,33 +357,51 @@ uat_load(uat_t *uat_in, char **errx)
}
- if (!(yyin = ws_fopen(fname,"r"))) {
+ if (!(in = ws_fopen(fname,"r"))) {
*errx = g_strdup(g_strerror(errno));
g_free(fname);
return FALSE;
}
- error = NULL;
- valid_record = TRUE;
- colnum = 0;
- g_free(record);
- record = g_malloc0(uat->record_size);
- linenum = 1;
+ if (uat_load_lex_init(&scanner) != 0) {
+ *errx = g_strdup(g_strerror(errno));
+ fclose(in);
+ g_free(fname);
+ return FALSE;
+ }
+
+ uat_load_set_in(in, scanner);
+
+ state.uat = uat;
+ state.parse_str = NULL; /* we're reading from a file */
+
+ state.error = NULL;
+ state.valid_record = TRUE;
+ state.colnum = 0;
+ state.ptrx = NULL;
+ state.len = 0;
+ state.record = g_malloc0(uat->record_size);
+ state.linenum = 1;
+ state.parse_str_pos = 0;
- BEGIN START_OF_LINE;
DUMP(fname);
g_free(fname); /* we're done with the file name now */
- yylex();
- fclose(yyin);
- yyrestart(NULL);
+ /* Associate the state with the scanner */
+ uat_load_set_extra(&state, scanner);
+
+ uat_load_lex(scanner);
+
+ uat_load_lex_destroy(scanner);
+ g_free(state.record);
+ fclose(in);
uat->changed = FALSE;
uat->loaded = TRUE;
UAT_UPDATE(uat);
- if (error) {
- *errx = error;
+ if (state.error) {
+ *errx = state.error;
return FALSE;
}
@@ -343,34 +413,47 @@ uat_load(uat_t *uat_in, char **errx)
}
gboolean
-uat_load_str(uat_t *uat_in, char *entry, char **err)
+uat_load_str(uat_t *uat, char *entry, char **err)
{
- uat = uat_in;
- parse_str = g_strdup_printf("%s\n", entry); /* Records must end with a newline */
- parse_str_pos = 0;
- yyin = NULL;
-
- error = NULL;
- valid_record = TRUE;
- colnum = 0;
- g_free(record);
- record = g_malloc0(uat->record_size);
- linenum = 1;
+ yyscan_t scanner;
+ uat_load_scanner_state_t state;
+
+ state.uat = uat;
+ state.parse_str = g_strdup_printf("%s\n", entry); /* Records must end with a newline */
+
+ state.error = NULL;
+ state.valid_record = TRUE;
+ state.colnum = 0;
+ state.ptrx = NULL;
+ state.len = 0;
+ state.record = g_malloc0(uat->record_size);
+ state.linenum = 1;
+ state.parse_str_pos = 0;
+
+ if (uat_load_lex_init(&scanner) != 0) {
+ *err = g_strdup(g_strerror(errno));
+ g_free(state.parse_str);
+ g_free(state.record);
+ return FALSE;
+ }
- BEGIN START_OF_LINE;
DUMP(entry);
- yylex();
- yyrestart(NULL);
- g_free(parse_str);
- parse_str = NULL;
+ /* Associate the state with the scanner */
+ uat_load_set_extra(&state, scanner);
+
+ uat_load_lex(scanner);
+
+ uat_load_lex_destroy(scanner);
+ g_free(state.record);
+ g_free(state.parse_str);
uat->changed = TRUE;
uat->loaded = TRUE;
UAT_UPDATE(uat);
- if (error) {
- *err = error;
+ if (state.error) {
+ *err = state.error;
return FALSE;
}