From 7c07e2a8b3b5851de0c238da830291f041185778 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 19 Jul 2018 20:44:14 +0200 Subject: [PATCH] free children in free_priv --- lib/ecoli_node.c | 13 +++++-------- lib/ecoli_node_cmd.c | 3 +-- lib/ecoli_node_expr.c | 2 +- lib/ecoli_node_many.c | 8 ++++++++ lib/ecoli_node_once.c | 8 ++++++++ lib/ecoli_node_option.c | 8 ++++++++ lib/ecoli_node_or.c | 3 +++ lib/ecoli_node_re_lex.c | 1 + lib/ecoli_node_seq.c | 3 +++ lib/ecoli_node_sh_lex.c | 8 ++++++++ lib/ecoli_node_subset.c | 3 +++ 11 files changed, 49 insertions(+), 11 deletions(-) diff --git a/lib/ecoli_node.c b/lib/ecoli_node.c index 484e25f..a1b10dd 100644 --- a/lib/ecoli_node.c +++ b/lib/ecoli_node.c @@ -185,8 +185,7 @@ static void reset_mark(struct ec_node *node) /* free a node, taking care of loops in the node graph */ void ec_node_free(struct ec_node *node) { - struct ec_node *child; - size_t i, n; + size_t n; if (node == NULL) return; @@ -217,10 +216,10 @@ void ec_node_free(struct ec_node *node) if (node->free.state != EC_NODE_FREE_STATE_FREEING) { node->free.state = EC_NODE_FREE_STATE_FREEING; n = ec_node_get_children_count(node); - for (i = 0; i < n; i++) { - child = ec_node_get_child(node, i); - ec_node_free(child); - } + /* children should be freed by free_priv() */ + assert(n == 0 || node->type->free_priv != NULL); + if (node->type->free_priv != NULL) + node->type->free_priv(node); } node->refcnt--; @@ -230,8 +229,6 @@ void ec_node_free(struct ec_node *node) node->free.state = EC_NODE_FREE_STATE_NONE; node->free.refcnt = 0; - if (node->type != NULL && node->type->free_priv != NULL) - node->type->free_priv(node); ec_free(node->id); ec_free(node->desc); ec_keyval_free(node->attrs); diff --git a/lib/ecoli_node_cmd.c b/lib/ecoli_node_cmd.c index d298c14..5b0d459 100644 --- a/lib/ecoli_node_cmd.c +++ b/lib/ecoli_node_cmd.c @@ -413,11 +413,10 @@ static void ec_node_cmd_free_priv(struct ec_node *gen_node) struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node; size_t i; - /* node->cmd is freed automatically, because it is returned - * by ec_node_cmd_get_child() */ ec_free(node->cmd_str); ec_node_free(node->expr); ec_node_free(node->parser); + ec_node_free(node->cmd); for (i = 0; i < node->len; i++) ec_node_free(node->table[i]); ec_free(node->table); diff --git a/lib/ecoli_node_expr.c b/lib/ecoli_node_expr.c index 2320c0c..eb7bff3 100644 --- a/lib/ecoli_node_expr.c +++ b/lib/ecoli_node_expr.c @@ -78,7 +78,7 @@ static void ec_node_expr_free_priv(struct ec_node *gen_node) struct ec_node_expr *node = (struct ec_node_expr *)gen_node; unsigned int i; - EC_LOG(EC_LOG_DEBUG, "free %p %p %p\n", node, node->child, node->val_node); + ec_node_free(node->child); ec_node_free(node->val_node); for (i = 0; i < node->bin_ops_len; i++) diff --git a/lib/ecoli_node_many.c b/lib/ecoli_node_many.c index 728f1c6..6a5f676 100644 --- a/lib/ecoli_node_many.c +++ b/lib/ecoli_node_many.c @@ -154,6 +154,13 @@ ec_node_many_complete(const struct ec_node *gen_node, strvec); } +static void ec_node_many_free_priv(struct ec_node *gen_node) +{ + struct ec_node_many *node = (struct ec_node_many *)gen_node; + + ec_node_free(node->child); +} + static size_t ec_node_many_get_children_count(const struct ec_node *gen_node) { @@ -180,6 +187,7 @@ static struct ec_node_type ec_node_many_type = { .parse = ec_node_many_parse, .complete = ec_node_many_complete, .size = sizeof(struct ec_node_many), + .free_priv = ec_node_many_free_priv, .get_children_count = ec_node_many_get_children_count, .get_child = ec_node_many_get_child, }; diff --git a/lib/ecoli_node_once.c b/lib/ecoli_node_once.c index 738b43d..5248d13 100644 --- a/lib/ecoli_node_once.c +++ b/lib/ecoli_node_once.c @@ -88,6 +88,13 @@ ec_node_once_complete(const struct ec_node *gen_node, return 0; } +static void ec_node_once_free_priv(struct ec_node *gen_node) +{ + struct ec_node_once *node = (struct ec_node_once *)gen_node; + + ec_node_free(node->child); +} + static size_t ec_node_once_get_children_count(const struct ec_node *gen_node) { @@ -114,6 +121,7 @@ static struct ec_node_type ec_node_once_type = { .parse = ec_node_once_parse, .complete = ec_node_once_complete, .size = sizeof(struct ec_node_once), + .free_priv = ec_node_once_free_priv, .get_children_count = ec_node_once_get_children_count, .get_child = ec_node_once_get_child, }; diff --git a/lib/ecoli_node_option.c b/lib/ecoli_node_option.c index b4bb391..befbb2e 100644 --- a/lib/ecoli_node_option.c +++ b/lib/ecoli_node_option.c @@ -54,6 +54,13 @@ ec_node_option_complete(const struct ec_node *gen_node, return ec_node_complete_child(node->child, comp, strvec); } +static void ec_node_option_free_priv(struct ec_node *gen_node) +{ + struct ec_node_option *node = (struct ec_node_option *)gen_node; + + ec_node_free(node->child); +} + static size_t ec_node_option_get_children_count(const struct ec_node *gen_node) { @@ -80,6 +87,7 @@ static struct ec_node_type ec_node_option_type = { .parse = ec_node_option_parse, .complete = ec_node_option_complete, .size = sizeof(struct ec_node_option), + .free_priv = ec_node_option_free_priv, .get_children_count = ec_node_option_get_children_count, .get_child = ec_node_option_get_child, }; diff --git a/lib/ecoli_node_or.c b/lib/ecoli_node_or.c index 67047b3..b36cbd7 100644 --- a/lib/ecoli_node_or.c +++ b/lib/ecoli_node_or.c @@ -68,7 +68,10 @@ ec_node_or_complete(const struct ec_node *gen_node, static void ec_node_or_free_priv(struct ec_node *gen_node) { struct ec_node_or *node = (struct ec_node_or *)gen_node; + size_t i; + for (i = 0; i < node->len; i++) + ec_node_free(node->table[i]); ec_free(node->table); } diff --git a/lib/ecoli_node_re_lex.c b/lib/ecoli_node_re_lex.c index 79a75eb..4f0f8d3 100644 --- a/lib/ecoli_node_re_lex.c +++ b/lib/ecoli_node_re_lex.c @@ -143,6 +143,7 @@ static void ec_node_re_lex_free_priv(struct ec_node *gen_node) struct ec_node_re_lex *node = (struct ec_node_re_lex *)gen_node; unsigned int i; + ec_node_free(node->child); for (i = 0; i < node->len; i++) { ec_free(node->table[i].pattern); regfree(&node->table[i].r); diff --git a/lib/ecoli_node_seq.c b/lib/ecoli_node_seq.c index 92dc73e..be03f31 100644 --- a/lib/ecoli_node_seq.c +++ b/lib/ecoli_node_seq.c @@ -158,7 +158,10 @@ ec_node_seq_complete(const struct ec_node *gen_node, static void ec_node_seq_free_priv(struct ec_node *gen_node) { struct ec_node_seq *node = (struct ec_node_seq *)gen_node; + size_t i; + for (i = 0; i < node->len; i++) + ec_node_free(node->table[i]); ec_free(node->table); } diff --git a/lib/ecoli_node_sh_lex.c b/lib/ecoli_node_sh_lex.c index a0b7a05..b39ce21 100644 --- a/lib/ecoli_node_sh_lex.c +++ b/lib/ecoli_node_sh_lex.c @@ -336,6 +336,13 @@ ec_node_sh_lex_complete(const struct ec_node *gen_node, return -1; } +static void ec_node_sh_lex_free_priv(struct ec_node *gen_node) +{ + struct ec_node_sh_lex *node = (struct ec_node_sh_lex *)gen_node; + + ec_node_free(node->child); +} + static size_t ec_node_sh_lex_get_children_count(const struct ec_node *gen_node) { @@ -362,6 +369,7 @@ static struct ec_node_type ec_node_sh_lex_type = { .parse = ec_node_sh_lex_parse, .complete = ec_node_sh_lex_complete, .size = sizeof(struct ec_node_sh_lex), + .free_priv = ec_node_sh_lex_free_priv, .get_children_count = ec_node_sh_lex_get_children_count, .get_child = ec_node_sh_lex_get_child, }; diff --git a/lib/ecoli_node_subset.c b/lib/ecoli_node_subset.c index 1afbde7..059b7b9 100644 --- a/lib/ecoli_node_subset.c +++ b/lib/ecoli_node_subset.c @@ -234,7 +234,10 @@ ec_node_subset_complete(const struct ec_node *gen_node, static void ec_node_subset_free_priv(struct ec_node *gen_node) { struct ec_node_subset *node = (struct ec_node_subset *)gen_node; + size_t i; + for (i = 0; i < node->len; i++) + ec_node_free(node->table[i]); ec_free(node->table); } -- 2.20.1