aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dfilter-grammar.y24
-rw-r--r--dfilter-int.h3
-rw-r--r--dfilter.c70
-rw-r--r--dfilter.h5
-rw-r--r--ethereal.c10
-rw-r--r--proto.c17
-rw-r--r--proto.h7
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);
diff --git a/dfilter.c b/dfilter.c
index fe3727b330..a271a5c1b1 100644
--- a/dfilter.c
+++ b/dfilter.c
@@ -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)
diff --git a/dfilter.h b/dfilter.h
index b4849cd376..c42676061a 100644
--- a/dfilter.h
+++ b/dfilter.h
@@ -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);
}
diff --git a/proto.c b/proto.c
index d185bf3943..319c428d9a 100644
--- a/proto.c
+++ b/proto.c
@@ -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)
diff --git a/proto.h b/proto.h
index ef317aa17f..6383cae914 100644
--- a/proto.h
+++ b/proto.h
@@ -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);