diff options
-rw-r--r-- | dfilter-grammar.y | 24 | ||||
-rw-r--r-- | dfilter-int.h | 3 | ||||
-rw-r--r-- | dfilter.c | 70 | ||||
-rw-r--r-- | dfilter.h | 5 | ||||
-rw-r--r-- | ethereal.c | 10 | ||||
-rw-r--r-- | proto.c | 17 | ||||
-rw-r--r-- | proto.h | 7 |
7 files changed, 119 insertions, 17 deletions
diff --git a/dfilter-grammar.y b/dfilter-grammar.y index c8ab1c54b8..d692267fcc 100644 --- a/dfilter-grammar.y +++ b/dfilter-grammar.y @@ -3,7 +3,7 @@ /* dfilter-grammar.y * Parser for display filters * - * $Id: dfilter-grammar.y,v 1.14 1999/08/20 21:19:27 gram Exp $ + * $Id: dfilter-grammar.y,v 1.15 1999/08/26 06:20:48 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -98,6 +98,13 @@ static int ether_str_to_guint8_array(const char *s, guint8 *mac); */ dfilter *global_df = NULL;; +/* list of GNodes allocated during parsing. If the parsing fails, we'll + * use this list to free all the GNodes. If the parsing succeeds, we'll + * just clear this list since dfilter_clear_filter() will take care of + * freeing the GNodes when they're no longer needed. + */ +GSList *gnode_slist = NULL; + %} %union { @@ -363,6 +370,7 @@ dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2) g_node_append(gnode_root, n1); g_node_append(gnode_root, n2); + gnode_slist = g_slist_append(gnode_slist, gnode_root); return gnode_root; } @@ -382,6 +390,7 @@ dfilter_mknode_unary(int operand, GNode *n2) gnode_root = g_node_new(node_root); g_node_append(gnode_root, n2); + gnode_slist = g_slist_append(gnode_slist, gnode_root); return gnode_root; } @@ -400,6 +409,7 @@ dfilter_mknode_numeric_variable(gint id) node->value.variable = id; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -417,6 +427,7 @@ dfilter_mknode_ether_variable(gint id) node->value.variable = id; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -434,6 +445,7 @@ dfilter_mknode_ipxnet_variable(gint id) node->value.variable = id; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -451,6 +463,7 @@ dfilter_mknode_ipv4_variable(gint id) node->value.variable = id; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -470,6 +483,7 @@ dfilter_mknode_bytes_variable(gint id, gint offset, guint length) node->length = length; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -487,6 +501,7 @@ dfilter_mknode_boolean_variable(gint id) node->value.variable = id; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -504,6 +519,7 @@ dfilter_mknode_numeric_value(guint32 val) node->value.numeric = val; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -531,6 +547,7 @@ dfilter_mknode_ether_value(gchar *byte_string) } gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -548,6 +565,7 @@ dfilter_mknode_ipxnet_value(guint32 ipx_net_val) node->value.numeric = ipx_net_val; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -566,6 +584,7 @@ dfilter_mknode_ipv4_value(char *host) node->value.numeric = htonl(node->value.numeric); gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -585,6 +604,7 @@ dfilter_mknode_bytes_value(GByteArray *barray) node->length = barray->len; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -602,6 +622,7 @@ dfilter_mknode_boolean_value(gint truth_value) node->value.boolean = truth_value == TOK_TRUE ? TRUE : FALSE; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } @@ -631,6 +652,7 @@ dfilter_mknode_existence(gint id) node->value.variable = id; gnode = g_node_new(node); + gnode_slist = g_slist_append(gnode_slist, gnode); return gnode; } diff --git a/dfilter-int.h b/dfilter-int.h index 689ff4ebcf..deb785b514 100644 --- a/dfilter-int.h +++ b/dfilter-int.h @@ -2,7 +2,7 @@ * Definitions for routines common to multiple modules in the display * filter code, but not used outside that code. * - * $Id: dfilter-int.h,v 1.2 1999/08/13 23:47:40 gram Exp $ + * $Id: dfilter-int.h,v 1.3 1999/08/26 06:20:48 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -34,6 +34,7 @@ void dfilter_scanner_cleanup(void); /* in dfilter-grammar.y */ extern dfilter *global_df; +extern GSList *gnode_slist; /* Here we provide interfaces to make our scanner act and look like lex */ int yylex(void); @@ -1,7 +1,7 @@ /* dfilter.c * Routines for display filters * - * $Id: dfilter.c,v 1.15 1999/08/25 22:54:17 gram Exp $ + * $Id: dfilter.c,v 1.16 1999/08/26 06:20:48 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -94,6 +94,8 @@ static GArray* get_values_from_ptree(dfilter_node *dnode, proto_tree *ptree, con static GArray* get_values_from_dfilter(dfilter_node *dnode, GNode *gnode); static gboolean check_existence_in_ptree(dfilter_node *dnode, proto_tree *ptree); static void clear_byte_array(gpointer data, gpointer user_data); +static void unlink_gnode_children(gpointer gnode_ptr, gpointer user_data); +static void destroy_gnode(gpointer gnode_ptr, gpointer user_data); /* this is not so pretty. I need my own g_array "function" (macro) to * retreive the pointer to the data stored in an array cell. I need this @@ -120,7 +122,13 @@ dfilter_init(void) } } } -/* XXX - I should eventually g_tree_destroy(dfilter_tokens), when ethereal shuts down */ + +void +dfilter_cleanup(void) +{ + if (dfilter_tokens) + g_tree_destroy(dfilter_tokens); +} /* Compiles the textual representation of the display filter into a tree * of operations to perform. Can be called multiple times, compiling a new @@ -146,7 +154,10 @@ dfilter_compile(dfilter *df, gchar *dfilter_text) /* tell the scanner to use this string as input */ dfilter_scanner_text(df->dftext); - /* Assign global variable so yyparse knows which dfilter we're talking about */ + /* Assign global variable so dfilter_parse knows which dfilter we're + * talking about. Reset the global error message. We don't have to set + * gnode_slist since it will always be NULL by the time we get here. + */ global_df = df; dfilter_error_msg = NULL; @@ -167,6 +178,12 @@ dfilter_compile(dfilter *df, gchar *dfilter_text) } } + /* Clear the list of allocated nodes */ + if (gnode_slist) { + g_slist_free(gnode_slist); + gnode_slist = NULL; + } + return retval; } @@ -233,9 +250,6 @@ dfilter_destroy(dfilter *df) } - - - static void clear_byte_array(gpointer data, gpointer user_data) { @@ -244,15 +258,51 @@ clear_byte_array(gpointer data, gpointer user_data) g_byte_array_free(barray, TRUE); } +/* Called when the yacc grammar finds a parsing error */ void dfilter_error(char *s) { - /* Setting to NULL here is fine, since global_df is a copy of a pointer. - dfilter_clear_filter() will free the memory when called from the - next dfilter_compile() */ - global_df->dftree = NULL; + /* The only data we have to worry about freeing is the + * data used by any GNodes that were allocated during + * parsing. The data in those Gnodes will be cleared + * later via df->node_memchunk. Use gnode_slist to + * clear the GNodes, and set global_df to NULL just + * to be tidy. + */ + global_df = NULL; + + /* I don't want to call g_node_destroy on each GNode ptr, + * since that function frees any children. That could + * mess me up later in the list if I try to free a GNode + * that has already been freed. So, I'll unlink the + * children firs,t then call g_node_destroy on each GNode ptr. + */ + if (!gnode_slist) + return; + + g_slist_foreach(gnode_slist, unlink_gnode_children, NULL); + g_slist_foreach(gnode_slist, destroy_gnode, NULL); + + /* notice we don't clear gnode_slist itself. dfilter_compile() + * will take care of that. + */ +} + +static void +unlink_gnode_children(gpointer gnode_ptr, gpointer user_data) +{ + if (gnode_ptr) + g_node_unlink((GNode*) gnode_ptr); } +static void +destroy_gnode(gpointer gnode_ptr, gpointer user_data) +{ + if (gnode_ptr) + g_node_destroy((GNode*) gnode_ptr); +} + + /* lookup an abbreviation in our token tree, returing the ID # * If the abbreviation doesn't exit, returns 0 */ int dfilter_lookup_token(char *abbrev) @@ -1,7 +1,7 @@ /* dfilter.h * Definitions for display filters * - * $Id: dfilter.h,v 1.9 1999/08/20 20:37:46 gram Exp $ + * $Id: dfilter.h,v 1.10 1999/08/26 06:20:49 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -49,6 +49,9 @@ typedef struct { /* Initialization of the symbol table. Called once during program startup */ void dfilter_init(void); +/* Free the memory used by the symbol table. Called at program shutdown */ +void dfilter_cleanup(void); + /* Allocate and initialize new dfilter struct. Returns pointer to new dfilter */ dfilter* dfilter_new(void); diff --git a/ethereal.c b/ethereal.c index 5fbbea6958..cf342c03d7 100644 --- a/ethereal.c +++ b/ethereal.c @@ -1,6 +1,6 @@ /* ethereal.c * - * $Id: ethereal.c,v 1.107 1999/08/25 22:19:55 gram Exp $ + * $Id: ethereal.c,v 1.108 1999/08/26 06:20:49 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -1008,6 +1008,12 @@ ethereal_proto_init(void) { dfilter_init(); } +static void +ethereal_proto_cleanup(void) { + proto_cleanup(); + dfilter_cleanup(); +} + static void print_usage(void) { @@ -1472,5 +1478,7 @@ main(int argc, char *argv[]) gtk_main(); + ethereal_proto_cleanup(); + exit(0); } @@ -1,7 +1,7 @@ /* proto.c * Routines for protocol tree * - * $Id: proto.c,v 1.16 1999/08/20 06:55:06 guy Exp $ + * $Id: proto.c,v 1.17 1999/08/26 06:20:50 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -167,7 +167,7 @@ proto_init(void) if (gmc_item_labels) g_mem_chunk_destroy(gmc_item_labels); if (gpa_hfinfo) - g_ptr_array_free(gpa_hfinfo, FALSE); /* ever needs to be TRUE? */ + g_ptr_array_free(gpa_hfinfo, FALSE); gmc_hfinfo = g_mem_chunk_new("gmc_hfinfo", sizeof(struct header_field_info), 50 * sizeof(struct @@ -246,6 +246,19 @@ proto_init(void) /* vals[] */ NULL ); } +void +proto_cleanup(void) +{ + if (gmc_hfinfo) + g_mem_chunk_destroy(gmc_hfinfo); + if (gmc_field_info) + g_mem_chunk_destroy(gmc_field_info); + if (gmc_item_labels) + g_mem_chunk_destroy(gmc_item_labels); + if (gpa_hfinfo) + g_ptr_array_free(gpa_hfinfo, FALSE); +} + /* frees the resources that the dissection a proto_tree uses */ void proto_tree_free(proto_tree *tree) @@ -1,7 +1,7 @@ /* proto.h * Definitions for protocol display * - * $Id: proto.h,v 1.6 1999/08/14 01:26:39 gram Exp $ + * $Id: proto.h,v 1.7 1999/08/26 06:20:50 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -118,7 +118,12 @@ typedef struct proto_tree_search_info { const guint8 *packet_data; } proto_tree_search_info; +/* Sets up memory used by proto routines. Called at program startup */ void proto_init(void); + +/* Frees memory used by proto routines. Called at program shutdown */ +void proto_cleanup(void); + void proto_item_set_len(proto_item *ti, gint length); proto_tree* proto_tree_create_root(void); void proto_tree_free(proto_tree *tree); |