diff options
author | Guy Harris <guy@alum.mit.edu> | 2015-01-18 02:22:19 -0800 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2015-01-18 10:22:59 +0000 |
commit | cfcbb286712ae392689e7cd1a640b57b611dd277 (patch) | |
tree | c41ab4705bb0b790da02bc8b29768b5879543474 /epan/dfilter/dfilter.c | |
parent | c60fb3038e4a449c5488a32574d838a6599cb33f (diff) |
Clean up ftype-conversion and dfilter error message string handling.
Have dfilter_compile() take an additional gchar ** argument, pointing to
a gchar * item that, on error, gets set to point to a g_malloc()ed error
string. That removes one bit of global state from the display filter
parser, and doesn't impose a fixed limit on the error message strings.
Have fvalue_from_string() and fvalue_from_unparsed() take a gchar **
argument, pointer to a gchar * item, rather than an error-reporting
function, and set the gchar * item to point to a g_malloc()ed error
string on an error.
Allow either gchar ** argument to be null; if the argument is null, no
error message is allocated or provided.
Change-Id: Ibd36b8aaa9bf4234aa6efa1e7fb95f7037493b4c
Reviewed-on: https://code.wireshark.org/review/6608
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/dfilter/dfilter.c')
-rw-r--r-- | epan/dfilter/dfilter.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c index 8e21d30853..903ec33868 100644 --- a/epan/dfilter/dfilter.c +++ b/epan/dfilter/dfilter.c @@ -34,10 +34,6 @@ #define DFILTER_TOKEN_ID_OFFSET 1 -/* Global error message space for dfilter_compile errors */ -static gchar dfilter_error_msg_buf[1024]; -const gchar *dfilter_error_msg; /* NULL when no error resulted */ - /* From scanner.c */ void df_scanner_text(const char *text); void df_scanner_cleanup(void); @@ -46,24 +42,26 @@ int df_lex(void); /* Holds the singular instance of our Lemon parser object */ static void* ParserObj = NULL; +/* + * XXX - if we're using a version of Flex that supports reentrant lexical + * analyzers, we should put this into the lexical analyzer's state. + */ +dfwork_t *global_dfw; + void -dfilter_fail(const char *format, ...) +dfilter_fail(dfwork_t *dfw, const char *format, ...) { va_list args; /* If we've already reported one error, don't overwite it */ - if (dfilter_error_msg != NULL) + if (dfw->error_message != NULL) return; va_start(args, format); - - g_vsnprintf(dfilter_error_msg_buf, sizeof(dfilter_error_msg_buf), - format, args); - dfilter_error_msg = dfilter_error_msg_buf; + dfw->error_message = g_strdup_vprintf(format, args); va_end(args); } - /* Initialize the dfilter module */ void dfilter_init(void) @@ -110,7 +108,7 @@ dfilter_new(void) df = g_new0(dfilter_t, 1); df->insns = NULL; - df->deprecated = NULL; + df->deprecated = NULL; return df; } @@ -202,11 +200,15 @@ dfwork_free(dfwork_t *dfw) free_insns(dfw->consts); } + /* + * We don't free the error message string; our caller will return + * it to its caller. + */ g_free(dfw); } gboolean -dfilter_compile(const gchar *text, dfilter_t **dfp) +dfilter_compile(const gchar *text, dfilter_t **dfp, gchar **err_msg) { int token; dfilter_t *dfilter; @@ -216,26 +218,28 @@ dfilter_compile(const gchar *text, dfilter_t **dfp) guint i; /* XXX, GHashTable */ GPtrArray *deprecated; - gchar *temp_error_msg; g_assert(dfp); if (!text) { *dfp = NULL; + if (err_msg != NULL) + *err_msg = g_strdup("BUG: NULL text pointer passed to dfilter_compile()"); return FALSE; } - dfilter_error_msg = NULL; - - if ( !( text = dfilter_macro_apply(text, &temp_error_msg) ) ) { - /* Move the ep_ allocation up a layer */ - dfilter_error_msg = ep_strdup(temp_error_msg); - wmem_free(NULL, temp_error_msg); + if ( !( text = dfilter_macro_apply(text, err_msg) ) ) { return FALSE; } 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; + df_scanner_text(text); deprecated = g_ptr_array_new(); @@ -353,12 +357,18 @@ dfilter_compile(const gchar *text, dfilter_t **dfp) *dfp = dfilter; } /* SUCCESS */ + global_dfw = NULL; dfwork_free(dfw); wmem_free(NULL, (char*)text); return TRUE; FAILURE: if (dfw) { + if (err_msg != NULL) + *err_msg = dfw->error_message; + else + g_free(dfw->error_message); + global_dfw = NULL; dfwork_free(dfw); } for (i = 0; i < deprecated->len; ++i) { @@ -366,11 +376,18 @@ FAILURE: g_free(depr); } g_ptr_array_free(deprecated, TRUE); - dfilter_fail("Unable to parse filter string \"%s\".", text); - wmem_free(NULL, (char*)text); + if (err_msg != NULL) { + /* + * Default error message. + * + * XXX - we should really make sure that this is never the + * case for any error. + */ + if (*err_msg == NULL) + *err_msg = g_strdup_printf("Unable to parse filter string \"%s\".", text); + } *dfp = NULL; return FALSE; - } |