From 765ebfc0b57ea5ddcd5079fce261c05c1eeb0f65 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Fri, 13 Jul 2018 22:28:49 +0200 Subject: [PATCH] remove weakref node --- lib/Makefile | 1 - lib/ecoli_node_expr.c | 25 +++---- lib/ecoli_node_weakref.c | 155 --------------------------------------- lib/ecoli_node_weakref.h | 60 --------------- 4 files changed, 11 insertions(+), 230 deletions(-) delete mode 100644 lib/ecoli_node_weakref.c delete mode 100644 lib/ecoli_node_weakref.h diff --git a/lib/Makefile b/lib/Makefile index 9c70312..0d5f1e1 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -50,7 +50,6 @@ srcs += ecoli_node_sh_lex.c srcs += ecoli_node_space.c srcs += ecoli_node_str.c srcs += ecoli_node_subset.c -srcs += ecoli_node_weakref.c srcs += ecoli_parse.c srcs += ecoli_string.c srcs += ecoli_vec.c diff --git a/lib/ecoli_node_expr.c b/lib/ecoli_node_expr.c index 41a14bb..c92749e 100644 --- a/lib/ecoli_node_expr.c +++ b/lib/ecoli_node_expr.c @@ -21,7 +21,6 @@ #include #include #include -#include #include EC_LOG_TYPE_REGISTER(node_expr); @@ -104,8 +103,8 @@ static void ec_node_expr_free_priv(struct ec_node *gen_node) static int ec_node_expr_build(struct ec_node_expr *node) { struct ec_node *term = NULL, *expr = NULL, *next = NULL, - *pre_op = NULL, *post_op = NULL, - *post = NULL, *weak = NULL; + *pre_op = NULL, *post_op = NULL, *ref = NULL, + *post = NULL; unsigned int i; ec_node_free(node->child); @@ -136,10 +135,9 @@ static int ec_node_expr_build(struct ec_node_expr *node) * expr = sum */ - /* create the object, we will initialize it later: this is - * needed because we have a circular dependency */ - weak = ec_node("weakref", "weak"); - if (weak == NULL) + /* we use this as a ref, will be set later */ + ref = ec_node("seq", "ref"); + if (ref == NULL) return -1; /* prefix unary operators */ @@ -168,12 +166,12 @@ static int ec_node_expr_build(struct ec_node_expr *node) if (ec_node_or_add(post, EC_NODE_SEQ(EC_NO_ID, ec_node_clone(pre_op), - ec_node_clone(weak))) < 0) + ec_node_clone(ref))) < 0) goto fail; for (i = 0; i < node->paren_len; i++) { if (ec_node_or_add(post, EC_NODE_SEQ(EC_NO_ID, ec_node_clone(node->open_ops[i]), - ec_node_clone(weak), + ec_node_clone(ref), ec_node_clone(node->close_ops[i]))) < 0) goto fail; } @@ -211,11 +209,10 @@ static int ec_node_expr_build(struct ec_node_expr *node) ec_node_free(post); post = NULL; - /* no need to clone here, the node is not consumed */ - if (ec_node_weakref_set(weak, expr) < 0) + if (ec_node_seq_add(ref, ec_node_clone(expr)) < 0) goto fail; - ec_node_free(weak); - weak = NULL; + ec_node_free(ref); + ref = NULL; node->child = expr; @@ -227,7 +224,7 @@ fail: ec_node_free(pre_op); ec_node_free(post_op); ec_node_free(post); - ec_node_free(weak); + ec_node_free(ref); return -1; } diff --git a/lib/ecoli_node_weakref.c b/lib/ecoli_node_weakref.c deleted file mode 100644 index 0a097aa..0000000 --- a/lib/ecoli_node_weakref.c +++ /dev/null @@ -1,155 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2016, Olivier MATZ - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -EC_LOG_TYPE_REGISTER(node_weakref); - -struct ec_node_weakref { - struct ec_node gen; - struct ec_node *child; -}; - -static int -ec_node_weakref_parse(const struct ec_node *gen_node, - struct ec_parse *state, - const struct ec_strvec *strvec) -{ - struct ec_node_weakref *node = (struct ec_node_weakref *)gen_node; - - return ec_node_parse_child(node->child, state, strvec); -} - -static int -ec_node_weakref_complete(const struct ec_node *gen_node, - struct ec_comp *comp, - const struct ec_strvec *strvec) -{ - struct ec_node_weakref *node = (struct ec_node_weakref *)gen_node; - - return ec_node_complete_child(node->child, comp, strvec); -} - -static struct ec_node_type ec_node_weakref_type = { - .name = "weakref", - .parse = ec_node_weakref_parse, - .complete = ec_node_weakref_complete, - .size = sizeof(struct ec_node_weakref), -}; - -EC_NODE_TYPE_REGISTER(ec_node_weakref_type); - -int ec_node_weakref_set(struct ec_node *gen_node, struct ec_node *child) -{ - struct ec_node_weakref *node = (struct ec_node_weakref *)gen_node; - - assert(node != NULL); - - if (child == NULL) { - errno = EINVAL; - goto fail; - } - - if (ec_node_check_type(gen_node, &ec_node_weakref_type) < 0) - goto fail; - - node->child = child; - - return 0; - -fail: - /* do not free child */ - return -1; -} - -struct ec_node *ec_node_weakref(const char *id, struct ec_node *child) -{ - struct ec_node *gen_node = NULL; - - if (child == NULL) - return NULL; - - gen_node = __ec_node(&ec_node_weakref_type, id); - if (gen_node == NULL) - return NULL; - - ec_node_weakref_set(gen_node, child); - - return gen_node; -} - -/* LCOV_EXCL_START */ -static int ec_node_weakref_testcase(void) -{ - struct ec_node *weak = NULL, *expr = NULL, *val = NULL; - struct ec_node *seq = NULL, *op = NULL; - int testres = 0; - - expr = ec_node("or", EC_NO_ID); - val = ec_node_int(EC_NO_ID, 0, 10, 10); - op = ec_node_str(EC_NO_ID, "!"); - weak = ec_node_weakref(EC_NO_ID, expr); - if (weak == NULL || expr == NULL || val == NULL || op == NULL) - goto fail; - seq = EC_NODE_SEQ(EC_NO_ID, op, weak); - op = NULL; - weak = NULL; - - if (ec_node_or_add(expr, seq) < 0) - goto fail; - seq = NULL; - if (ec_node_or_add(expr, val) < 0) - goto fail; - val = NULL; - - testres |= EC_TEST_CHECK_PARSE(expr, 1, "1"); - testres |= EC_TEST_CHECK_PARSE(expr, 2, "!", "1"); - testres |= EC_TEST_CHECK_PARSE(expr, 3, "!", "!", "1"); - - testres |= EC_TEST_CHECK_COMPLETE(expr, - "", EC_NODE_ENDLIST, - "!", EC_NODE_ENDLIST); - testres |= EC_TEST_CHECK_COMPLETE(expr, - "!", "", EC_NODE_ENDLIST, - "!", EC_NODE_ENDLIST); - - ec_node_free(expr); - - return testres; - -fail: - ec_node_free(weak); - ec_node_free(expr); - ec_node_free(val); - ec_node_free(seq); - ec_node_free(op); - return -1; -} -/* LCOV_EXCL_STOP */ - -static struct ec_test ec_node_weakref_test = { - .name = "node_weakref", - .test = ec_node_weakref_testcase, -}; - -EC_TEST_REGISTER(ec_node_weakref_test); diff --git a/lib/ecoli_node_weakref.h b/lib/ecoli_node_weakref.h deleted file mode 100644 index cb2aed1..0000000 --- a/lib/ecoli_node_weakref.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2016, Olivier MATZ - */ - -#ifndef ECOLI_NODE_WEAKREF_ -#define ECOLI_NODE_WEAKREF_ - -#include - -/* A node that just behaves like its child and that does not free - * its child when freed. **The child has to be freed manually**. - * - * useful to create cyclic graphs of nodes: - * creating a loop (with clones) result in something that is not - * freeable, due to reference counters - * - * Example: - * expr = or() - * val = int(0, 10) - * op = str("!") - * seq = seq(op, clone(expr)) - * expr.add(seq) - * expr.add(val) - * free(expr) // just decrease ref - * - * FAIL: expr cannot be freed due to cyclic refs - * The references are like this: - * - * val - * ^ - * | - * $user ~ ~ ~ > expr ---> seq ---> op - * <--- - * - * It is solved with: - * expr = or() - * val = int(0, 10) - * op = str("!") - * weak = weak(expr) - * seq = seq(op, weak) - * expr.add(op) - * expr.add(val) - * - * - * val - * ^ - * | - * $user ~ ~ ~ > expr ---------------> seq ---> op - * <- - - weak <--- - * - * The node expr can be freed. - */ - -/* on error, child is *not* freed */ -struct ec_node *ec_node_weakref(const char *id, struct ec_node *child); - -/* on error, child is *not* freed */ -int ec_node_weakref_set(struct ec_node *node, struct ec_node *child); - -#endif -- 2.20.1