summaryrefslogtreecommitdiff
path: root/epan/dtd_parse.l
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-03-30 18:44:01 -0700
committerGuy Harris <guy@alum.mit.edu>2016-04-03 22:21:29 +0000
commit59816ef00c6dd09532d80b393ba03f8194aba236 (patch)
treef5e84c67ebe0e69542db94d56db70fa476c0db6c /epan/dtd_parse.l
parente42a43bc58a36848316adae19981878a5f430c46 (diff)
downloadwireshark-59816ef00c6dd09532d80b393ba03f8194aba236.tar.gz
Make the Flex scanners and YACC parser in libraries reentrant.
master-branch libpcap now generates a reentrant Flex scanner and Bison/Berkeley YACC parser for capture filter expressions, so it requires versions of Flex and Bison/Berkeley YACC that support that. We might as well do the same. For libwiretap, it means we could actually have multiple K12 text or Ascend/Lucent text files open at the same time. For libwireshark, it might not be as useful, as we only read configuration files at startup (which should only happen once, in one thread) or on demand (in which case, if we ever support multiple threads running libwireshark, we'd need a mutex to ensure that only one file reads it), but it's still the right thing to do. We also require a version of Flex that can write out a header file, so we change the runlex script to generate the header file ourselves. This means we require a version of Flex new enough to support --header-file. Clean up some other stuff encountered in the process. Change-Id: Id23078c6acea549a52fc687779bb55d715b55c16 Reviewed-on: https://code.wireshark.org/review/14719 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/dtd_parse.l')
-rw-r--r--epan/dtd_parse.l151
1 files changed, 100 insertions, 51 deletions
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;
}