From 8937e9addfe15dfe34ea241884aa10cfb3dc54fb Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Tue, 24 Jul 2018 21:36:42 +0200 Subject: [PATCH] get node children and refs in the same function --- lib/ecoli_node.c | 69 ++++++++++++++++++++++++----------------- lib/ecoli_node.h | 14 +++------ lib/ecoli_node_cmd.c | 11 ++++--- lib/ecoli_node_expr.c | 11 ++++--- lib/ecoli_node_many.c | 11 ++++--- lib/ecoli_node_once.c | 11 ++++--- lib/ecoli_node_option.c | 11 ++++--- lib/ecoli_node_or.c | 11 ++++--- lib/ecoli_node_re_lex.c | 11 ++++--- lib/ecoli_node_seq.c | 21 +++++-------- lib/ecoli_node_sh_lex.c | 11 ++++--- lib/ecoli_node_subset.c | 11 ++++--- 12 files changed, 116 insertions(+), 87 deletions(-) diff --git a/lib/ecoli_node.c b/lib/ecoli_node.c index a1b10dd..1ebbcf1 100644 --- a/lib/ecoli_node.c +++ b/lib/ecoli_node.c @@ -129,6 +129,7 @@ static void count_references(struct ec_node *node, unsigned int refs) { struct ec_node *child; size_t i, n; + int ret; if (node->free.state == EC_NODE_FREE_STATE_TRAVERSED) { node->free.refcnt += refs; @@ -138,8 +139,8 @@ static void count_references(struct ec_node *node, unsigned int refs) node->free.state = EC_NODE_FREE_STATE_TRAVERSED; n = ec_node_get_children_count(node); for (i = 0; i < n; i++) { - child = ec_node_get_child(node, i); - refs = ec_node_get_child_refs(node, i); + ret = ec_node_get_child(node, i, &child, &refs); + assert(ret == 0); count_references(child, refs); } } @@ -147,7 +148,9 @@ static void count_references(struct ec_node *node, unsigned int refs) static void mark_freeable(struct ec_node *node, enum ec_node_free_state mark) { struct ec_node *child; + unsigned int refs; size_t i, n; + int ret; if (mark == node->free.state) return; @@ -159,7 +162,8 @@ static void mark_freeable(struct ec_node *node, enum ec_node_free_state mark) n = ec_node_get_children_count(node); for (i = 0; i < n; i++) { - child = ec_node_get_child(node, i); + ret = ec_node_get_child(node, i, &child, &refs); + assert(ret == 0); mark_freeable(child, mark); } } @@ -167,7 +171,9 @@ static void mark_freeable(struct ec_node *node, enum ec_node_free_state mark) static void reset_mark(struct ec_node *node) { struct ec_node *child; + unsigned int refs; size_t i, n; + int ret; if (node->free.state == EC_NODE_FREE_STATE_NONE) return; @@ -177,7 +183,8 @@ static void reset_mark(struct ec_node *node) n = ec_node_get_children_count(node); for (i = 0; i < n; i++) { - child = ec_node_get_child(node, i); + ret = ec_node_get_child(node, i, &child, &refs); + assert(ret == 0); reset_mark(child); } } @@ -250,20 +257,15 @@ size_t ec_node_get_children_count(const struct ec_node *node) return node->type->get_children_count(node); } -struct ec_node * -ec_node_get_child(const struct ec_node *node, size_t i) +int +ec_node_get_child(const struct ec_node *node, size_t i, + struct ec_node **child, unsigned int *refs) { + *child = NULL; + *refs = 0; if (node->type->get_child == NULL) - return NULL; - return node->type->get_child(node, i); -} - -unsigned int -ec_node_get_child_refs(const struct ec_node *node, size_t i) -{ - if (node->type->get_child_refs == NULL) - return 1; - return node->type->get_child_refs(node, i); + return -1; + return node->type->get_child(node, i, child, refs); } int @@ -298,19 +300,22 @@ const struct ec_config *ec_node_get_config(struct ec_node *node) struct ec_node *ec_node_find(struct ec_node *node, const char *id) { - struct ec_node *child, *ret; + struct ec_node *child, *retnode; const char *node_id = ec_node_id(node); + unsigned int refs; size_t i, n; + int ret; if (id != NULL && node_id != NULL && !strcmp(node_id, id)) return node; n = ec_node_get_children_count(node); for (i = 0; i < n; i++) { - child = ec_node_get_child(node, i); - ret = ec_node_find(child, id); - if (ret != NULL) - return ret; + ret = ec_node_get_child(node, i, &child, &refs); + assert(ret == 0); + retnode = ec_node_find(child, id); + if (retnode != NULL) + return retnode; } return NULL; @@ -336,8 +341,10 @@ static void __ec_node_dump(FILE *out, { const char *id, *typename; struct ec_node *child; + unsigned int refs; char buf[32]; size_t i, n; + int ret; id = ec_node_id(node); typename = node->type->name; @@ -356,7 +363,8 @@ static void __ec_node_dump(FILE *out, n = ec_node_get_children_count(node); for (i = 0; i < n; i++) { - child = ec_node_get_child(node, i); + ret = ec_node_get_child(node, i, &child, &refs); + assert(ret == 0); __ec_node_dump(out, child, indent + 1, dict); } } @@ -410,8 +418,9 @@ static int ec_node_testcase(void) { struct ec_node *node = NULL, *expr = NULL; struct ec_node *expr2 = NULL, *val = NULL, *op = NULL, *seq = NULL; - const struct ec_node *child; const struct ec_node_type *type; + struct ec_node *child; + unsigned int refs; FILE *f = NULL; char *buf = NULL; size_t buflen = 0; @@ -455,17 +464,21 @@ static int ec_node_testcase(void) testres |= EC_TEST_CHECK( ec_node_get_children_count(node) == 2, "bad children count\n"); - child = ec_node_get_child(node, 0); - testres |= EC_TEST_CHECK(child != NULL && + ret = ec_node_get_child(node, 0, &child, &refs); + testres |= EC_TEST_CHECK(ret == 0 && + child != NULL && !strcmp(ec_node_type(child)->name, "str") && !strcmp(ec_node_id(child), "id_x"), "bad child 0"); - child = ec_node_get_child(node, 1); - testres |= EC_TEST_CHECK(child != NULL && + ret = ec_node_get_child(node, 1, &child, &refs); + testres |= EC_TEST_CHECK(ret == 0 && + child != NULL && !strcmp(ec_node_type(child)->name, "str") && !strcmp(ec_node_id(child), "id_y"), "bad child 1"); - child = ec_node_get_child(node, 2); + ret = ec_node_get_child(node, 2, &child, &refs); + testres |= EC_TEST_CHECK(ret != 0, + "ret should be != 0"); testres |= EC_TEST_CHECK(child == NULL, "child 2 should be NULL"); diff --git a/lib/ecoli_node.h b/lib/ecoli_node.h index 67652ab..f66fa3d 100644 --- a/lib/ecoli_node.h +++ b/lib/ecoli_node.h @@ -83,10 +83,8 @@ typedef const char * (*ec_node_desc_t)(const struct ec_node *); typedef int (*ec_node_init_priv_t)(struct ec_node *); typedef void (*ec_node_free_priv_t)(struct ec_node *); typedef size_t (*ec_node_get_children_count_t)(const struct ec_node *); -typedef struct ec_node * (*ec_node_get_child_t)(const struct ec_node *, - size_t i); -typedef unsigned int (*ec_node_get_child_refs_t)(const struct ec_node *, - size_t i); +typedef int (*ec_node_get_child_t)(const struct ec_node *, + size_t i, struct ec_node **child, unsigned int *refs); /** * A structure describing a node type. @@ -106,7 +104,6 @@ struct ec_node_type { ec_node_free_priv_t free_priv; ec_node_get_children_count_t get_children_count; ec_node_get_child_t get_child; - ec_node_get_child_refs_t get_child_refs; }; /** @@ -177,10 +174,9 @@ int ec_node_set_config(struct ec_node *node, struct ec_config *config); const struct ec_config *ec_node_get_config(struct ec_node *node); size_t ec_node_get_children_count(const struct ec_node *node); -struct ec_node * -ec_node_get_child(const struct ec_node *node, size_t i); -unsigned int -ec_node_get_child_refs(const struct ec_node *node, size_t i); +int +ec_node_get_child(const struct ec_node *node, size_t i, + struct ec_node **child, unsigned int *refs); /* XXX add more accessors */ const struct ec_node_type *ec_node_type(const struct ec_node *node); diff --git a/lib/ecoli_node_cmd.c b/lib/ecoli_node_cmd.c index 5b0d459..4ab13bd 100644 --- a/lib/ecoli_node_cmd.c +++ b/lib/ecoli_node_cmd.c @@ -528,15 +528,18 @@ ec_node_cmd_get_children_count(const struct ec_node *gen_node) return 1; } -static struct ec_node * -ec_node_cmd_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_cmd_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node; if (i > 0) - return NULL; + return -1; - return node->cmd; + *child = node->cmd; + *refs = 1; + return 0; } static struct ec_node_type ec_node_cmd_type = { diff --git a/lib/ecoli_node_expr.c b/lib/ecoli_node_expr.c index eb7bff3..3b47d8c 100644 --- a/lib/ecoli_node_expr.c +++ b/lib/ecoli_node_expr.c @@ -237,15 +237,18 @@ ec_node_expr_get_children_count(const struct ec_node *gen_node) return 0; } -static struct ec_node * -ec_node_expr_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_expr_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_expr *node = (struct ec_node_expr *)gen_node; if (i >= 1) - return NULL; + return -1; - return node->child; + *child = node->child; + *refs = 1; + return 0; } static struct ec_node_type ec_node_expr_type = { diff --git a/lib/ecoli_node_many.c b/lib/ecoli_node_many.c index 6a5f676..32e7ad5 100644 --- a/lib/ecoli_node_many.c +++ b/lib/ecoli_node_many.c @@ -171,15 +171,18 @@ ec_node_many_get_children_count(const struct ec_node *gen_node) return 0; } -static struct ec_node * -ec_node_many_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_many_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_many *node = (struct ec_node_many *)gen_node; if (i >= 1) - return NULL; + return -1; - return node->child; + *child = node->child; + *refs = 1; + return 0; } static struct ec_node_type ec_node_many_type = { diff --git a/lib/ecoli_node_once.c b/lib/ecoli_node_once.c index 5248d13..3d4b038 100644 --- a/lib/ecoli_node_once.c +++ b/lib/ecoli_node_once.c @@ -105,15 +105,18 @@ ec_node_once_get_children_count(const struct ec_node *gen_node) return 0; } -static struct ec_node * -ec_node_once_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_once_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_once *node = (struct ec_node_once *)gen_node; if (i >= 1) - return NULL; + return -1; - return node->child; + *child = node->child; + *refs = 1; + return 0; } static struct ec_node_type ec_node_once_type = { diff --git a/lib/ecoli_node_option.c b/lib/ecoli_node_option.c index befbb2e..06cca69 100644 --- a/lib/ecoli_node_option.c +++ b/lib/ecoli_node_option.c @@ -71,15 +71,18 @@ ec_node_option_get_children_count(const struct ec_node *gen_node) return 0; } -static struct ec_node * -ec_node_option_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_option_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_option *node = (struct ec_node_option *)gen_node; if (i >= 1) - return NULL; + return -1; - return node->child; + *child = node->child; + *refs = 1; + return 0; } static struct ec_node_type ec_node_option_type = { diff --git a/lib/ecoli_node_or.c b/lib/ecoli_node_or.c index b36cbd7..aeac206 100644 --- a/lib/ecoli_node_or.c +++ b/lib/ecoli_node_or.c @@ -82,15 +82,18 @@ ec_node_or_get_children_count(const struct ec_node *gen_node) return node->len; } -static struct ec_node * -ec_node_or_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_or_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_or *node = (struct ec_node_or *)gen_node; if (i >= node->len) - return NULL; + return -1; - return node->table[i]; + *child = node->table[i]; + *refs = 1; + return 0; } static struct ec_node_type ec_node_or_type = { diff --git a/lib/ecoli_node_re_lex.c b/lib/ecoli_node_re_lex.c index 4f0f8d3..0120367 100644 --- a/lib/ecoli_node_re_lex.c +++ b/lib/ecoli_node_re_lex.c @@ -162,15 +162,18 @@ ec_node_re_lex_get_children_count(const struct ec_node *gen_node) return 0; } -static struct ec_node * -ec_node_re_lex_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_re_lex_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_re_lex *node = (struct ec_node_re_lex *)gen_node; if (i >= 1) - return NULL; + return -1; - return node->child; + *child = node->child; + *refs = 1; + return 0; } static struct ec_node_type ec_node_re_lex_type = { diff --git a/lib/ecoli_node_seq.c b/lib/ecoli_node_seq.c index be03f31..ae0bb60 100644 --- a/lib/ecoli_node_seq.c +++ b/lib/ecoli_node_seq.c @@ -234,26 +234,20 @@ ec_node_seq_get_children_count(const struct ec_node *gen_node) return node->len; } -static struct ec_node * -ec_node_seq_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_seq_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_seq *node = (struct ec_node_seq *)gen_node; if (i >= node->len) - return NULL; - - return node->table[i]; -} - -static unsigned int -ec_node_seq_get_child_refs(const struct ec_node *gen_node, size_t i) -{ - (void)gen_node; - (void)i; + return -1; + *child = node->table[i]; /* each child node is referenced twice: once in the config and * once in the node->table[] */ - return 2; + *refs = 2; + return 0; } static struct ec_node_type ec_node_seq_type = { @@ -267,7 +261,6 @@ static struct ec_node_type ec_node_seq_type = { .free_priv = ec_node_seq_free_priv, .get_children_count = ec_node_seq_get_children_count, .get_child = ec_node_seq_get_child, - .get_child_refs = ec_node_seq_get_child_refs, }; EC_NODE_TYPE_REGISTER(ec_node_seq_type); diff --git a/lib/ecoli_node_sh_lex.c b/lib/ecoli_node_sh_lex.c index b39ce21..a632f97 100644 --- a/lib/ecoli_node_sh_lex.c +++ b/lib/ecoli_node_sh_lex.c @@ -353,15 +353,18 @@ ec_node_sh_lex_get_children_count(const struct ec_node *gen_node) return 0; } -static struct ec_node * -ec_node_sh_lex_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_sh_lex_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_sh_lex *node = (struct ec_node_sh_lex *)gen_node; if (i >= 1) - return NULL; + return -1; - return node->child; + *refs = 1; + *child = node->child; + return 0; } static struct ec_node_type ec_node_sh_lex_type = { diff --git a/lib/ecoli_node_subset.c b/lib/ecoli_node_subset.c index 059b7b9..bfd7e71 100644 --- a/lib/ecoli_node_subset.c +++ b/lib/ecoli_node_subset.c @@ -248,15 +248,18 @@ ec_node_subset_get_children_count(const struct ec_node *gen_node) return node->len; } -static struct ec_node * -ec_node_subset_get_child(const struct ec_node *gen_node, size_t i) +static int +ec_node_subset_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) { struct ec_node_subset *node = (struct ec_node_subset *)gen_node; if (i >= node->len) - return NULL; + return -1; - return node->table[i]; + *child = node->table[i]; + *refs = 1; + return 0; } static struct ec_node_type ec_node_subset_type = { -- 2.39.5