X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Fecoli_node.h;h=0867525798a746477208ee16cb845a038b5bd86b;hb=786e4464e886f4e1485ba2beb6ed74c8a5914fbf;hp=1ed896fcc199af1a7ffff2d0a258d1772e36cedb;hpb=0a2b19af9303c4a0ec05bea7afe1803a429517bf;p=protos%2Flibecoli.git diff --git a/lib/ecoli_node.h b/lib/ecoli_node.h index 1ed896f..0867525 100644 --- a/lib/ecoli_node.h +++ b/lib/ecoli_node.h @@ -51,10 +51,12 @@ #define EC_NODE_ENDLIST ((void *)1) struct ec_node; -struct ec_parsed; -struct ec_completed; +struct ec_parse; +struct ec_comp; struct ec_strvec; struct ec_keyval; +struct ec_config; +struct ec_config_schema; #define EC_NODE_TYPE_REGISTER(t) \ static void ec_node_init_##t(void); \ @@ -69,18 +71,20 @@ struct ec_keyval; TAILQ_HEAD(ec_node_type_list, ec_node_type); -/* return 0 on success, else -errno. */ -typedef int (*ec_node_build_t)(struct ec_node *node); - +typedef int (*ec_node_set_config_t)(struct ec_node *node, + const struct ec_config *config); typedef int (*ec_node_parse_t)(const struct ec_node *node, - struct ec_parsed *state, + struct ec_parse *state, const struct ec_strvec *strvec); typedef int (*ec_node_complete_t)(const struct ec_node *node, - struct ec_completed *completed_state, + struct ec_comp *comp_state, const struct ec_strvec *strvec); 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 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. @@ -88,13 +92,18 @@ typedef void (*ec_node_free_priv_t)(struct ec_node *); struct ec_node_type { TAILQ_ENTRY(ec_node_type) next; /**< Next in list. */ const char *name; /**< Node type name. */ - ec_node_build_t build; /**< (Re)build the node */ + /** Configuration schema array, must be terminated by a sentinel + * (.type = EC_CONFIG_TYPE_NONE). */ + const struct ec_config_schema *schema; + ec_node_set_config_t set_config; /* validate/ack a config change */ ec_node_parse_t parse; ec_node_complete_t complete; ec_node_desc_t desc; size_t size; ec_node_init_priv_t init_priv; ec_node_free_priv_t free_priv; + ec_node_get_children_count_t get_children_count; + ec_node_get_child_t get_child; }; /** @@ -116,40 +125,61 @@ int ec_node_type_register(struct ec_node_type *type); * @return * The node type if found, or NULL on error. */ -struct ec_node_type *ec_node_type_lookup(const char *name); +const struct ec_node_type *ec_node_type_lookup(const char *name); /** * Dump registered log types */ void ec_node_type_dump(FILE *out); +enum ec_node_free_state { + EC_NODE_FREE_STATE_NONE, + EC_NODE_FREE_STATE_TRAVERSED, + EC_NODE_FREE_STATE_FREEABLE, + EC_NODE_FREE_STATE_NOT_FREEABLE, + EC_NODE_FREE_STATE_FREEING, +}; + struct ec_node { const struct ec_node_type *type; + struct ec_config *config; /**< Generic configuration. */ char *id; char *desc; struct ec_keyval *attrs; unsigned int refcnt; - struct ec_node **children; /* array of children */ - size_t n_children; /* number of children in the array */ + struct { + enum ec_node_free_state state; /**< State of loop detection */ + unsigned int refcnt; /**< Number of reachable references + * starting from node beeing freed */ + } free; /**< Freeing state: used for loop detection */ }; /* create a new node when the type is known, typically called from the node * code */ -struct ec_node *__ec_node(const struct ec_node_type *type, const char *id); +struct ec_node *ec_node_from_type(const struct ec_node_type *type, const char *id); -/* create a_new node node */ +/* create a new node */ struct ec_node *ec_node(const char *typename, const char *id); struct ec_node *ec_node_clone(struct ec_node *node); void ec_node_free(struct ec_node *node); +/* set configuration of a node + * after a call to this function, the config is + * owned by the node and must not be used by the caller + * on error, the config is freed. */ +int ec_node_set_config(struct ec_node *node, struct ec_config *config); + +/* get the current node configuration. Return NULL if no configuration. */ +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); -int ec_node_add_child(struct ec_node *node, struct ec_node *child); -int ec_node_del_child(struct ec_node *node, struct ec_node *child); +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); struct ec_keyval *ec_node_attrs(const struct ec_node *node); const char *ec_node_id(const struct ec_node *node); const char *ec_node_desc(const struct ec_node *node);