6002f931934dd52ede07fa8d944e6b282dfb7aaa
[protos/libecoli.git] / lib / ecoli_node_weakref.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
3  */
4
5 #ifndef ECOLI_NODE_WEAKREF_
6 #define ECOLI_NODE_WEAKREF_
7
8 #include <ecoli_node.h>
9
10 /* A node that just behaves like its child and that does not free
11  * its child when freed. **The child has to be freed manually**.
12  *
13  * useful to create cyclic graphs of nodes:
14  *   creating a loop (with clones) result in something that is not
15  *   freeable, due to reference counters
16  *
17  * Example:
18  *  val = int(0, 10)
19  *  op = str("!")
20  *  expr = or()
21  *  seq = seq(clone(op), clone(expr))
22  *  expr.add(clone(seq))
23  *  expr.add(clone(val))
24  *  free(val)
25  *  free(op)
26  *  free(seq)
27  *
28  * FAIL: expr cannot be freed due to cyclic refs
29  * The references are like this:
30  *
31  *                   val
32  *                    ^
33  *                    |
34  *        $user ---> expr ---> seq ---> op
35  *                        <---
36  *
37  * It is solved with:
38  *  val = int(0, 10)
39  *  op = str("!")
40  *  expr = or()
41  *  weak = weak(expr)
42  *  seq = seq(clone(op), clone(weak))
43  *  expr.add(clone(seq))
44  *  expr.add(clone(val))
45  *  free(val)
46  *  free(op)
47  *  free(weak)
48  *  free(seq)
49  *
50  *
51  *                   val
52  *                    ^
53  *                    |
54  *        $user ---> expr ---------------> seq ---> op
55  *                        <- - - weak <---
56  *
57  * The node expr can be freed.
58  */
59
60 /* on error, child is *not* freed */
61 struct ec_node *ec_node_weakref(const char *id, struct ec_node *child);
62
63 /* on error, child is *not* freed */
64 int ec_node_weakref_set(struct ec_node *node, struct ec_node *child);
65
66 #endif