From 331d87b8f34493ea7eb4db75fa9d90b2e3ed503b Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Fri, 21 Feb 2020 21:56:07 +0100 Subject: [PATCH] api doc and minor changes --- examples/readline/main.c | 14 +- include/ecoli.h | 2 +- include/ecoli_complete.h | 279 ++++++++++++++++++++++++++++------- include/ecoli_node.h | 218 +++++++++++++++++++++------ include/ecoli_node_dynamic.h | 2 +- include/ecoli_parse.h | 10 +- meson.build | 3 +- src/ecoli_complete.c | 124 +++++++--------- src/ecoli_editline.c | 25 ++-- src/ecoli_node.c | 59 +++++--- src/ecoli_node_any.c | 5 +- src/ecoli_node_bypass.c | 4 +- src/ecoli_node_cmd.c | 4 +- src/ecoli_node_cond.c | 68 ++++----- src/ecoli_node_dynamic.c | 2 +- src/ecoli_node_empty.c | 5 +- src/ecoli_node_expr.c | 4 +- src/ecoli_node_file.c | 8 +- src/ecoli_node_int.c | 6 +- src/ecoli_node_many.c | 12 +- src/ecoli_node_once.c | 2 +- src/ecoli_node_option.c | 4 +- src/ecoli_node_or.c | 4 +- src/ecoli_node_re.c | 5 +- src/ecoli_node_re_lex.c | 9 +- src/ecoli_node_seq.c | 8 +- src/ecoli_node_sh_lex.c | 8 +- src/ecoli_node_space.c | 5 +- src/ecoli_node_str.c | 19 ++- src/ecoli_node_subset.c | 20 +-- src/ecoli_parse.c | 16 +- src/ecoli_test.c | 4 +- 32 files changed, 634 insertions(+), 324 deletions(-) diff --git a/examples/readline/main.c b/examples/readline/main.c index 90a25f0..a64d068 100644 --- a/examples/readline/main.c +++ b/examples/readline/main.c @@ -106,16 +106,16 @@ static char **my_attempted_completion(const char *text, int start, int end) static char *get_node_help(const struct ec_comp_item *item) { const struct ec_comp_group *grp; - const struct ec_pnode *state; + const struct ec_pnode *pstate; const struct ec_node *node; char *help = NULL; const char *node_help = NULL; - const char *node_desc = NULL; + char *node_desc = NULL; grp = ec_comp_item_get_grp(item); - for (state = ec_comp_group_get_state(grp); state != NULL; - state = ec_pnode_get_parent(state)) { - node = ec_pnode_get_node(state); + for (pstate = ec_comp_group_get_pstate(grp); pstate != NULL; + pstate = ec_pnode_get_parent(pstate)) { + node = ec_pnode_get_node(pstate); if (node_help == NULL) node_help = ec_dict_get(ec_node_attrs(node), "help"); if (node_desc == NULL) @@ -130,6 +130,8 @@ static char *get_node_help(const struct ec_comp_item *item) if (asprintf(&help, "%-20s %s", node_desc, node_help) < 0) return NULL; + ec_free(node_desc); + return help; } @@ -141,7 +143,7 @@ static int show_help(int ignore, int invoking_key) struct ec_comp *c = NULL; struct ec_pnode *p = NULL; char *line = NULL; - unsigned int count; + size_t count; char **helps = NULL; int match = 0; int cols; diff --git a/include/ecoli.h b/include/ecoli.h index f5c42d2..3a6f328 100644 --- a/include/ecoli.h +++ b/include/ecoli.h @@ -16,7 +16,7 @@ * * The library also provides helpers to create a an interactive command * line based on @ref editline library, and a @ref yaml parser for - * grammar trees. + * grammar graphs. */ #ifndef ECOLI_ diff --git a/include/ecoli_complete.h b/include/ecoli_complete.h index c36019a..8cc28e1 100644 --- a/include/ecoli_complete.h +++ b/include/ecoli_complete.h @@ -6,16 +6,16 @@ * @defgroup complete Complete * @{ * - * @brief Complete string input using a grammar tree + * @brief Complete string input using a grammar graph. * - * This file provide helpers to list and manipulate the possible + * This file provides helpers to list and manipulate the possible * completions for a given input. * * Use @ec_complete_strvec() to complete a vector of strings when * the input is already split into several tokens. You can use * @ec_complete() if you know that the size of the vector is - * 1. This is common if you grammar tree has a lexer that will tokenize - * the input. + * 1. This is common if your grammar graph includes a lexer that + * will tokenize the input. * * These 2 functions return a pointer to an @ec_comp structure, that * lists the possible completions. The completions are grouped into @@ -42,8 +42,8 @@ struct ec_comp; */ enum ec_comp_type { EC_COMP_UNKNOWN = 0x1, - EC_COMP_FULL = 0x2, - EC_COMP_PARTIAL = 0x4, + EC_COMP_FULL = 0x2, /**< The item is fully completed. */ + EC_COMP_PARTIAL = 0x4, /**< The item is partially completed. */ EC_COMP_ALL = 0x7, }; @@ -54,12 +54,12 @@ enum ec_comp_type { * vector that only contains 1 element, the input string. Using this * function is often more convenient if you get your input from a * buffer, because you won't have to create a vector. Usually, it means - * you have a lexer in your grammar tree that will tokenize the input. + * you have a lexer in your grammar graph that will tokenize the input. * * See @ec_complete_strvec() for more details. * * @param node - * The grammar tree. + * The grammar graph. * @param str * The input string. * @return @@ -79,16 +79,16 @@ struct ec_comp *ec_complete(const struct ec_node *node, * vector should be ["cat", "x"]. * * To get the completion list, the engine parses the beginning of the - * input using the grammar tree. The resulting parsing tree is saved and + * input using the grammar graph. The resulting parsing tree is saved and * attached to each completion group. * * The result is a @ec_comp structure pointer, which contains several * groups of completion items. * * @param node - * The grammar tree. - * @param str - * The input string. + * The grammar graph. + * @param strvec + * The input string vector. * @return * A pointer to the completion list on success, or NULL * on error (errno is set). @@ -97,80 +97,159 @@ struct ec_comp *ec_complete_strvec(const struct ec_node *node, const struct ec_strvec *strvec); /** - * Get the list of completions when called from a node completion. + * Get the list of completions of a child node. * - * This function is to be used by ecoli nodes. + * This function is to be used by intermediate ecoli nodes, i.e. nodes + * which have children (ex: ec_node_seq, ec_node_or, ...). It fills an + * existing @ec_comp structure, passed by the parent node. * + * @param node + * The grammar graph. + * @param comp + * The current completion list to be filled. + * @param strvec + * The input string vector. + * @return + * 0 on success, or -1 on error (errno is set). */ int ec_complete_child(const struct ec_node *node, struct ec_comp *comp, const struct ec_strvec *strvec); /** - * Create a completion object (list of completion items). - * + * Create an empty completion object (list of completion items). * + * @return + * A pointer to the completion structure on success, or NULL on error + * (errno is set). */ -struct ec_comp *ec_comp(struct ec_pnode *state); +struct ec_comp *ec_comp(void); /** * Free a completion object and all its items. * - * + * @param comp + * The pointer to the completion structure to free. */ void ec_comp_free(struct ec_comp *comp); /** + * Dump the content of a completions list. * - * - * + * @param out + * The stream where the dump is sent. + * @param comp + * The pointer to the completion list structure. */ -void ec_comp_dump(FILE *out, - const struct ec_comp *comp); +void ec_comp_dump(FILE *out, const struct ec_comp *comp); /** - * Merge items contained in 'from' into 'to' + * Merge items contained in 'from' into 'to'. * * The 'from' comp struct is freed. + * + * @param to + * The destination completion list. + * @param from + * The source completion list. + * @return + * 0 on success, or -1 on error (errno is set). */ -int ec_comp_merge(struct ec_comp *to, - struct ec_comp *from); +int ec_comp_merge(struct ec_comp *to, struct ec_comp *from); /** - * Get current completion state. + * Get current parsing state of completion. + * + * This function can be called by a node during the completion process. * + * When processing the list of completions for a given input, + * an incomplete parsing tree is generated before the completion + * callback is invoked. A node may use it if the completions list + * depend on what was previously parsed. For instance, the "once" + * node checks in the parsing tree if the node is already parsed. + * In this case, no completion is issued. + * + * @param comp + * The current completion list. + * @return + * The current parsing state (cannot be NULL). */ -struct ec_pnode *ec_comp_get_state(const struct ec_comp *comp); +struct ec_pnode *ec_comp_get_cur_pstate(const struct ec_comp *comp); /** * Get current completion group. * + * This function can be called by a node during the completion process. + * + * A completion group is a list of completion items that share the same + * parsing state and are issued by the same grammar node. The completion + * group is created when the first item is added, thus this function + * returns NULL if no item has been added in the group. + * + * @param comp + * The current completion list. + * @return + * The current completion group (can be NULL). */ -struct ec_comp_group *ec_comp_get_group(const struct ec_comp *comp); +struct ec_comp_group *ec_comp_get_cur_group(const struct ec_comp *comp); /** - * Get completion group attributes. + * Get completion attributes. + * + * Arbitrary attributes (stored in a dictionary) can be attached to a + * completion state. * + * @param comp + * The completion list. + * @return + * The associated attributes. */ struct ec_dict *ec_comp_get_attrs(const struct ec_comp *comp); -/* shortcut for ec_comp_item() + ec_comp_item_add() */ -int ec_comp_add_item(struct ec_comp *comp, - const struct ec_node *node, - struct ec_comp_item **p_item, - enum ec_comp_type type, - const char *start, const char *full); - /** + * Add an item in competion list. + * + * This function can be called by a node during the completion process, + * for each completion item that should be added to the list. This is + * typically done in terminal nodes, like ec_node_str or ec_node_file. + * + * Create a new completion item, and add it into the completion + * list. A completion item has a type, which can be: + * - EC_COMP_FULL: the item is fully completed (common case, used + * for instance in the str node) + * - EC_COMP_PARTIAL: the item is only partially completed (this + * happens rarely, for instance in the file node, when a completion + * goes up to the next slash). + * - EC_COMP_UNKNOWN: the node detects a valid token, but does not + * how to complete it (ex: the int node). * + * @param comp + * The current completion list. + * @param node + * The node issuing the completion item. + * @param type + * The type of the item. + * @param start + * The incomplete string being completed. + * @param full + * The string fully completed. + * @return + * The item that was added in the list on success, or NULL + * on error. Note: don't free the returned value, as it is referenced + * by the completion list. It is returned in case it needs to be + * modified, for instance with ec_comp_item_set_display(). */ -int ec_comp_item_set_str(struct ec_comp_item *item, - const char *str); +struct ec_comp_item *ec_comp_add_item(struct ec_comp *comp, + const struct ec_node *node, enum ec_comp_type type, + const char *start, const char *full); /** * Get the string value of a completion item. * - * + * @param item + * The completion item.. + * @return + * The completion string of this item. */ const char * ec_comp_item_get_str(const struct ec_comp_item *item); @@ -178,7 +257,13 @@ ec_comp_item_get_str(const struct ec_comp_item *item); /** * Get the display string value of a completion item. * + * The display string corresponds to what is displayed when + * listing the possible completions. * + * @param item + * The completion item.. + * @return + * The display string of this item. */ const char * ec_comp_item_get_display(const struct ec_comp_item *item); @@ -186,7 +271,13 @@ ec_comp_item_get_display(const struct ec_comp_item *item); /** * Get the completion string value of a completion item. * + * The completion string corresponds to what should be added to + * the incomplete token to complete it. * + * @param item + * The completion item. + * @return + * The completion string of this item. */ const char * ec_comp_item_get_completion(const struct ec_comp_item *item); @@ -194,7 +285,13 @@ ec_comp_item_get_completion(const struct ec_comp_item *item); /** * Get the group of a completion item. * + * The completion group corresponds to the list of items that share + * the same parsing state and are issued by the same node. * + * @param item + * The completion item. + * @return + * The completion group of this item. */ const struct ec_comp_group * ec_comp_item_get_grp(const struct ec_comp_item *item); @@ -202,7 +299,11 @@ ec_comp_item_get_grp(const struct ec_comp_item *item); /** * Get the type of a completion item. * - * + * @param item + * The completion item. + * @return + * The type of this item (EC_COMP_UNKNOWN, EC_COMP_PARTIAL or + * EC_COMP_FULL). */ enum ec_comp_type ec_comp_item_get_type(const struct ec_comp_item *item); @@ -210,15 +311,42 @@ ec_comp_item_get_type(const struct ec_comp_item *item); /** * Get the node associated to a completion item. * - * + * @param item + * The completion item. + * @return + * The node that issued the completion item. */ const struct ec_node * ec_comp_item_get_node(const struct ec_comp_item *item); +/** + * Set the completion item string. + * + * Some intermediate nodes like sh_lex modify the completion string of + * items generated by their children, for instance to add quotes. + * + * @param item + * The completion item to update. + * @param str + * The new item string. + * @return + * 0 on success, or -1 on error (errno is set). + */ +int ec_comp_item_set_str(struct ec_comp_item *item, const char *str); + /** * Set the display value of an item. * + * The display string corresponds to what is displayed when listing the + * possible completions. Some nodes like ec_node_file change the default + * value display the base name instead of the full path. * + * @param item + * The completion item to update. + * @param str + * The new display string. + * @return + * 0 on success, or -1 on error (errno is set). */ int ec_comp_item_set_display(struct ec_comp_item *item, const char *display); @@ -226,7 +354,17 @@ int ec_comp_item_set_display(struct ec_comp_item *item, /** * Set the completion value of an item. * + * The completion string corresponds to what should be added to + * the incomplete token to complete it. Some nodes like sh_lex + * modify it in the items generated by their children, for instance + * to add a terminating quote. * + * @param item + * The completion item to update. + * @param str + * The new completion string. + * @return + * 0 on success, or -1 on error (errno is set). */ int ec_comp_item_set_completion(struct ec_comp_item *item, const char *completion); @@ -234,52 +372,83 @@ int ec_comp_item_set_completion(struct ec_comp_item *item, /** * Get the completion group node. * - * + * @param grp + * The completion group. */ const struct ec_node * ec_comp_group_get_node(const struct ec_comp_group *grp); /** - * Get the completion group parsed state. + * Get the completion group parsing state. * + * All items of a completion group are issued by the same node. + * This function returns a pointer to this node. * + * @param grp + * The completion group. + * @return + * The node that issued the completion group. */ const struct ec_pnode * -ec_comp_group_get_state(const struct ec_comp_group *grp); +ec_comp_group_get_pstate(const struct ec_comp_group *grp); /** * Get the completion group attributes. * + * The parsing state contains the parsing result of the input data + * preceding the completion. All items of a completion group share the + * same parsing state. * + * @param grp + * The completion group. + * @return + * The parsing state of the completion group. */ const struct ec_dict * ec_comp_group_get_attrs(const struct ec_comp_group *grp); /** + * Default node completion callback * + * This function is the default completion method for nodes that do + * not define one. * + * This helper adds a completion item of type EC_COMP_UNKNOWN if the + * input string vector contains one element, to indicate that everything + * before the last element of the string vector has been parsed + * successfully, but the node doesn't know how to complete the last + * element. * + * @param node + * The completion node. + * @param comp + * The completion list to update. + * @param strvec + * The input string vector. + * @return + * 0 on succes, or -1 on error (errno is set). */ int -ec_complete_unknown(const struct ec_node *gen_node, +ec_complete_unknown(const struct ec_node *node, struct ec_comp *comp, const struct ec_strvec *strvec); /** + * Get the number of completion items. * + * Return the number of completion items that match a given type in a + * completion list. * - * - */ -unsigned int ec_comp_count( - const struct ec_comp *comp, - enum ec_comp_type flags); - -/** - * - * - * + * @param comp + * The completion list. + * @param type + * A logical OR of flags among EC_COMP_UNKNOWN, EC_COMP_PARTIAL and + * EC_COMP_FULL, to select the type to match. + * @return + * The number of matching items. */ +size_t ec_comp_count(const struct ec_comp *comp, enum ec_comp_type type); /** * Get the first completion item matching the type. diff --git a/include/ecoli_node.h b/include/ecoli_node.h index 129ca4d..908e47e 100644 --- a/include/ecoli_node.h +++ b/include/ecoli_node.h @@ -3,7 +3,7 @@ */ /** - * @defgroup grammar_tree Grammar Tree + * @defgroup grammar_graph Grammar Graph * @{ * * @brief Libecoli grammar nodes. @@ -39,7 +39,11 @@ * * A node can have child nodes. For instance, a sequence node * ec_node_seq(ec_node_str("foo"), ec_node_str("bar")) will match - * ["foo", "bar"]. + * a sequence: ["foo", "bar"]. + * + * Note: at some places in the documentation and the code, we may talk + * about the grammar tree, but as loops are allowed, we should instead + * talk about grammar graph. */ #ifndef ECOLI_NODE_ @@ -47,6 +51,7 @@ #include #include +#include #include /** @@ -76,7 +81,31 @@ struct ec_config_schema; static void __attribute__((constructor, used)) \ ec_node_init_##t(void) \ { \ - if (ec_node_type_register(&t) < 0) \ + if (ec_node_type_register(&t, 0) < 0) \ + fprintf(stderr, \ + "cannot register node type %s\n", \ + t.name); \ + } + +/** + * Register a node type at library load, overriding previous registration. + * + * The node type is registered in a function that has the the + * constructor attribute: the function is called at library load. + * + * Be careful when using this macro, as the last type with a given name + * is the one that is actually registered. The call order may be hard to + * predict, especially within the same binary. + * + * @param t + * The name of the ec_node_type structure variable. + */ +#define EC_NODE_TYPE_REGISTER_OVERRIDE(t) \ + static void ec_node_init_##t(void); \ + static void __attribute__((constructor, used)) \ + ec_node_init_##t(void) \ + { \ + if (ec_node_type_register(&t, 1) < 0) \ fprintf(stderr, \ "cannot register node type %s\n", \ t.name); \ @@ -93,6 +122,9 @@ TAILQ_HEAD(ec_node_type_list, ec_node_type); * The function pointer is not called directly, the helper * @ec_node_set_config() should be used instead. * + * The configuration passed to this function pointer is valid, + * i.e. @ec_config_validate() returned 0 on it. + * * @param node * The node to configure. * @param config @@ -104,20 +136,20 @@ typedef int (*ec_node_set_config_t)(struct ec_node *node, const struct ec_config *config); /** - * Parse a string vector using the given grammar tree. + * Parse a string vector using the given grammar graph. * * The function pointer is not called directly, the helpers @ec_parse(), * ec_parse_strvec() or ec_parse_child() should be used instead. * * The implementation of this method for a node that manages children - * will call ec_parse_child(child, state, child_strvec). + * will call ec_parse_child(child, pstate, child_strvec). * * @param node - * The root node of the grammar tree. - * @param state + * The grammar graph. + * @param pstate * A pointer to the leaf being parsed in the parsing tree. It can be * used by a node to retrieve information from the current parsing - * tree. To get the root of the tree, @ec_pnode_get_root(state) should + * tree. To get the root of the tree, @ec_pnode_get_root(pstate) should * be used. * @param strvec * The string vector to be parsed. @@ -127,25 +159,27 @@ typedef int (*ec_node_set_config_t)(struct ec_node *node, * vector. On error, a negative value is returned and errno is set. */ typedef int (*ec_parse_t)(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec); /** - * Get completion items using the given grammar tree. + * Get completion items using the given grammar graph. * - * The function pointer is not called directly, the helpers @ec_complete(), - * ec_complete_strvec() or ec_complete_child() should be used instead. + * The function pointer should not be called directly, the helpers + * @ec_complete(), ec_complete_strvec() or ec_complete_child() should be + * used instead. * * This function completes the last element of the string vector. * For instance, node.type->complete(node, comp, ["ls"]) will * list all commands that starts with "ls", while * node.type->complete(node, comp, ["ls", ""]) will list all * possible values for the next argument. - - * The implementation of this function is supposed to either: + * + * The implementation of this function in the node is supposed + * to either: * - call @ec_comp_add_item(node, comp, ...) for each completion item - * that should be added to the list. This is done in terminal nodes, - * for example in ec_node_str or ec_node_file. + * that should be added to the list. This is typically done in + * terminal nodes, for example in ec_node_str or ec_node_file. * - call @ec_complete_child(child, comp, child_strvec) to let * the children nodes add their own completion. This is the * case of ec_node_or which trivially calls @ec_complete_child() @@ -160,7 +194,7 @@ typedef int (*ec_parse_t)(const struct ec_node *node, * complete the last element. * * @param node - * The root node of the grammar tree. + * The root node of the grammar graph. * @param comp * The current list of completion items, to be filled by the * node.type->complete() method. @@ -174,17 +208,95 @@ typedef int (*ec_complete_t)(const struct ec_node *node, const struct ec_strvec *strvec); /** + * Get the short description of a grammar node. + * + * This function pointer should not be called directly. The + * @ec_node_desc() helper should be used instead. + * + * This callback is typically used when building a help string for a + * grammar graph. It is used in ecoli editline interface to generate + * contextual help like this (first column): + * An integer. + * foo The foo string. + * bar The bar string. + * + * If this callback is set to NULL in the node type, the + * default behavior is to return the node type name inside <>, for + * instance "". The string node type implements this method to + * return the string value. An integer node could implement it + * to return its range (ex: "1..10"). + * + * The returned value is a pointer that must be freed by + * the caller with @ec_free(). + * + * On error, NULL is returned and errno is set. + */ +typedef char * (*ec_node_desc_t)(const struct ec_node *); + +/** + * Initialize the node private area. + * + * This function pointer should not be called directly. The @ec_node() + * and ec_node_from_type() helpers, that allocate new nodes, should be + * used instead. + * + * If not NULL, this function is called when a node is instanciated, to + * initialize the private area of a node. In any case, the private area + * is first zeroed. * + * On success, 0 is returned. On error, a negative value is returned and + * errno is set. */ -typedef const char * (*ec_node_desc_t)(const struct ec_node *); typedef int (*ec_node_init_priv_t)(struct ec_node *); + +/** + * Free the node private area. + * + * This function pointer should not be called directly. The + * @ec_node_free() helper should be used instead. + * + * When a node is deleted, this function is called to free the resources + * referenced in the node private area. + */ typedef void (*ec_node_free_priv_t)(struct ec_node *); + +/** + * Count the number of node children. + * + * This function pointer should not be called directly. The + * @ec_node_get_children_count() helper should be used instead. + * + * Some grammar nodes like seq, or, many, (...), reference children + * nodes in the grammar graph. This function returns the number of + * children. + */ typedef size_t (*ec_node_get_children_count_t)(const struct ec_node *); + +/** + * Count the number of node children. + * + * This function pointer should not be called directly. The + * @ec_node_get_child() helper should be used instead. + * + * Some grammar nodes like seq, or, many, (...), reference children + * nodes in the grammar graph. This function sets the i-th child (with i + * lower than the return value of ec_node_get_children_count()) in the + * child pointer. It also returns the number of references to the child + * owned by the parent. This information is used by the algorithm that + * frees a grammar graph taking care of loops. + * + * On success, 0 is returned. On error, a negative value is returned and + * errno is set. + */ 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. + * A structure describing a grammar node type. + * + * It is usually defined as a static const structure in the code + * defining a new grammar node type. Examples can be found in + * ecoli_node_.c files. */ struct ec_node_type { TAILQ_ENTRY(ec_node_type) next; /**< Next in list. */ @@ -192,68 +304,85 @@ struct ec_node_type { /** 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_parse_t parse; - ec_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; + size_t size; /**< Size of private area */ + ec_node_set_config_t set_config; /**< Validate and set configuration. */ + ec_parse_t parse; /**< Parse a string vector. */ + ec_complete_t complete; /**< Get completion items. */ + ec_node_desc_t desc; /**< Get short description. */ + ec_node_init_priv_t init_priv; /**< Initialize private area. */ + ec_node_free_priv_t free_priv; /**< Free node resourses. */ + /** Get children count. */ ec_node_get_children_count_t get_children_count; - ec_node_get_child_t get_child; + ec_node_get_child_t get_child; /**< Get the i-th child. */ }; /** * Register a node type. * + * The name of the type being registered is a uniq identifier. However, + * it is possible to force the registration of a type with an existing + * name by setting "override" to true. Note that the initial type is not + * removed from the list, instead the new one is added before in the + * list. + * * @param type - * A pointer to a ec_test structure describing the test - * to be registered. + * The node type to be registered. + * @param override + * Allow the registration of an existing type. * @return * 0 on success, negative value on error. */ -int ec_node_type_register(struct ec_node_type *type); +int ec_node_type_register(struct ec_node_type *type, bool override); /** - * Lookup node type by name + * Lookup node type by name. * * @param name * The name of the node type to search. * @return - * The node type if found, or NULL on error. + * The (read-only) node type if found, or NULL on error. */ const struct ec_node_type *ec_node_type_lookup(const char *name); /** - * Dump registered log types + * Dump registered log types. + * + * @param out + * The stream where the dump is sent. */ void ec_node_type_dump(FILE *out); /** * Get the config schema of a node type. + * + * @param type + * The node type. + * @return + * The (read-only) config schema of the node type, or NULL + * if the node type has no config schema. */ const struct ec_config_schema * ec_node_type_schema(const struct ec_node_type *type); /** * Get the name of a node type. + * + * @param type + * The node type. + * @return + * The (read-only) name of the node type. */ const char * ec_node_type_name(const struct ec_node_type *type); -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, -}; - -/* create a new node when the type is known, typically called from the node +/** + * create a new node when the type is known, typically called from the node * code */ struct ec_node *ec_node_from_type(const struct ec_node_type *type, const char *id); -/* create a new node */ +/** + * Create a new node from type name. + */ struct ec_node *ec_node(const char *typename, const char *id); struct ec_node *ec_node_clone(struct ec_node *node); @@ -277,7 +406,8 @@ ec_node_get_child(const struct ec_node *node, size_t i, const struct ec_node_type *ec_node_type(const struct ec_node *node); struct ec_dict *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); + +char *ec_node_desc(const struct ec_node *node); void ec_node_dump(FILE *out, const struct ec_node *node); struct ec_node *ec_node_find(struct ec_node *node, const char *id); diff --git a/include/ecoli_node_dynamic.h b/include/ecoli_node_dynamic.h index fd98971..e0aa85c 100644 --- a/include/ecoli_node_dynamic.h +++ b/include/ecoli_node_dynamic.h @@ -16,7 +16,7 @@ struct ec_pnode; /* callback invoked by parse() or complete() to build the dynamic node * the behavior of the node can depend on what is already parsed */ typedef struct ec_node *(*ec_node_dynamic_build_t)( - struct ec_pnode *state, void *opaque); + struct ec_pnode *pstate, void *opaque); struct ec_node *ec_node_dynamic(const char *id, ec_node_dynamic_build_t build, void *opaque); diff --git a/include/ecoli_parse.h b/include/ecoli_parse.h index 9bd98a3..b475522 100644 --- a/include/ecoli_parse.h +++ b/include/ecoli_parse.h @@ -6,7 +6,7 @@ * @defgroup parse Parse * @{ * - * @brief Create parse tree from string input and grammar tree + * @brief Create parse tree from string input and grammar graph * * Node parse API. * @@ -93,10 +93,10 @@ struct ec_pnode *ec_parse_strvec(const struct ec_node *node, /* internal: used by nodes * - * state is the current parse tree, which is built piece by piece while + * pstate is the current parse tree, which is built piece by piece while * parsing the node tree: ec_parse_child() creates a new child in * this state parse tree, and calls the parse() method for the child - * node, with state pointing to this new child. If it does not match, + * node, with pstate pointing to this new child. If it does not match, * the child is removed in the state, else it is kept, with its * possible descendants. * @@ -106,7 +106,7 @@ struct ec_pnode *ec_parse_strvec(const struct ec_node *node, * -1 on error, and errno is set */ int ec_parse_child(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec); /** @@ -234,7 +234,7 @@ struct ec_pnode *ec_pnode_find_next(struct ec_pnode *root, * Iterate among parse tree * * Use it with: - * for (iter = state; iter != NULL; iter = EC_PNODE_ITER_NEXT(state, iter, 1)) + * for (iter = pnode; iter != NULL; iter = EC_PNODE_ITER_NEXT(pnode, iter, 1)) */ struct ec_pnode *__ec_pnode_iter_next(const struct ec_pnode *root, struct ec_pnode *pnode, bool iter_children); diff --git a/meson.build b/meson.build index ca9ddf1..4223dc6 100644 --- a/meson.build +++ b/meson.build @@ -10,8 +10,7 @@ project('libecoli', edit_dep = dependency('libedit', method: 'pkg-config') yaml_dep = dependency('yaml-0.1', method: 'pkg-config') -# XXX if debug -add_global_arguments('-Werror', language : 'c') +add_global_arguments('-Wmissing-prototypes', language : 'c') inc = include_directories('include') priv_inc = include_directories('src') diff --git a/src/ecoli_complete.c b/src/ecoli_complete.c index b1afb33..537de57 100644 --- a/src/ecoli_complete.c +++ b/src/ecoli_complete.c @@ -27,10 +27,10 @@ struct ec_comp_item { TAILQ_ENTRY(ec_comp_item) next; enum ec_comp_type type; struct ec_comp_group *grp; - char *start; /* the initial token */ - char *full; /* the full token after completion */ - char *completion; /* chars that are added, NULL if not applicable */ - char *display; /* what should be displayed by help/completers */ + char *start; /**< The initial token */ + char *full; /**< The full token after completion */ + char *completion; /**< Chars that are added, NULL if not applicable */ + char *display; /**< What should be displayed by help/completers */ struct ec_dict *attrs; }; @@ -39,26 +39,27 @@ TAILQ_HEAD(ec_comp_item_list, ec_comp_item); struct ec_comp_group { /* XXX counts ? */ TAILQ_ENTRY(ec_comp_group) next; + const struct ec_comp *comp; const struct ec_node *node; struct ec_comp_item_list items; - struct ec_pnode *state; + struct ec_pnode *pstate; struct ec_dict *attrs; }; TAILQ_HEAD(ec_comp_group_list, ec_comp_group); struct ec_comp { - unsigned count; - unsigned count_full; - unsigned count_partial; - unsigned count_unknown; - struct ec_pnode *cur_state; + size_t count; + size_t count_full; + size_t count_partial; + size_t count_unknown; + struct ec_pnode *cur_pstate; struct ec_comp_group *cur_group; struct ec_comp_group_list groups; struct ec_dict *attrs; }; -struct ec_comp *ec_comp(struct ec_pnode *state) +struct ec_comp *ec_comp(void) { struct ec_comp *comp = NULL; @@ -72,8 +73,6 @@ struct ec_comp *ec_comp(struct ec_pnode *state) TAILQ_INIT(&comp->groups); - comp->cur_state = state; - return comp; fail: @@ -84,12 +83,12 @@ struct ec_comp *ec_comp(struct ec_pnode *state) return NULL; } -struct ec_pnode *ec_comp_get_state(const struct ec_comp *comp) +struct ec_pnode *ec_comp_get_cur_pstate(const struct ec_comp *comp) { - return comp->cur_state; + return comp->cur_pstate; } -struct ec_comp_group *ec_comp_get_group(const struct ec_comp *comp) +struct ec_comp_group *ec_comp_get_cur_group(const struct ec_comp *comp) { return comp->cur_group; } @@ -104,39 +103,38 @@ ec_complete_child(const struct ec_node *node, struct ec_comp *comp, const struct ec_strvec *strvec) { - struct ec_pnode *child_state, *cur_state; + struct ec_pnode *child_pstate, *cur_pstate; struct ec_comp_group *cur_group; + ec_complete_t complete_cb; int ret; - //XXX call ec_complete_unknown() instead, as - //described in API doc. - if (ec_node_type(node)->complete == NULL) { - errno = ENOTSUP; - return -1; - } + /* get the complete method, falling back to ec_complete_unknown() */ + complete_cb = ec_node_type(node)->complete; + if (complete_cb == NULL) + complete_cb = ec_complete_unknown; /* save previous parse state, prepare child state */ - cur_state = comp->cur_state; - child_state = ec_pnode(node); - if (child_state == NULL) + cur_pstate = comp->cur_pstate; + child_pstate = ec_pnode(node); + if (child_pstate == NULL) return -1; - if (cur_state != NULL) - ec_pnode_link_child(cur_state, child_state); - comp->cur_state = child_state; + if (cur_pstate != NULL) + ec_pnode_link_child(cur_pstate, child_pstate); + comp->cur_pstate = child_pstate; cur_group = comp->cur_group; comp->cur_group = NULL; /* fill the comp struct with items */ - ret = ec_node_type(node)->complete(node, comp, strvec); + ret = complete_cb(node, comp, strvec); /* restore parent parse state */ - if (cur_state != NULL) { - ec_pnode_unlink_child(cur_state, child_state); - assert(!ec_pnode_has_child(child_state)); + if (cur_pstate != NULL) { + ec_pnode_unlink_child(cur_pstate, child_pstate); + assert(!ec_pnode_has_child(child_pstate)); } - ec_pnode_free(child_state); - comp->cur_state = cur_state; + ec_pnode_free(child_pstate); + comp->cur_pstate = cur_pstate; comp->cur_group = cur_group; if (ret < 0) @@ -151,7 +149,7 @@ struct ec_comp *ec_complete_strvec(const struct ec_node *node, struct ec_comp *comp = NULL; int ret; - comp = ec_comp(NULL); + comp = ec_comp(); if (comp == NULL) goto fail; @@ -193,7 +191,8 @@ struct ec_comp *ec_complete(const struct ec_node *node, } static struct ec_comp_group * -ec_comp_group(const struct ec_node *node, struct ec_pnode *parse) +ec_comp_group(const struct ec_comp *comp, const struct ec_node *node, + struct ec_pnode *parse) { struct ec_comp_group *grp = NULL; @@ -201,12 +200,13 @@ ec_comp_group(const struct ec_node *node, struct ec_pnode *parse) if (grp == NULL) return NULL; + grp->comp = comp; grp->attrs = ec_dict(); if (grp->attrs == NULL) goto fail; - grp->state = ec_pnode_dup(parse); - if (grp->state == NULL) + grp->pstate = ec_pnode_dup(parse); + if (grp->pstate == NULL) goto fail; grp->node = node; @@ -216,7 +216,7 @@ ec_comp_group(const struct ec_node *node, struct ec_pnode *parse) fail: if (grp != NULL) { - ec_pnode_free(grp->state); + ec_pnode_free(grp->pstate); ec_dict_free(grp->attrs); } ec_free(grp); @@ -393,7 +393,7 @@ ec_comp_item_add(struct ec_comp *comp, const struct ec_node *node, if (comp->cur_group == NULL) { struct ec_comp_group *grp; - grp = ec_comp_group(node, comp->cur_state); + grp = ec_comp_group(comp, node, comp->cur_pstate); if (grp == NULL) return -1; TAILQ_INSERT_TAIL(&comp->groups, grp, next); @@ -457,50 +457,42 @@ ec_comp_item_free(struct ec_comp_item *item) ec_free(item); } -int ec_comp_add_item(struct ec_comp *comp, - const struct ec_node *node, - struct ec_comp_item **p_item, - enum ec_comp_type type, - const char *start, const char *full) +struct ec_comp_item *ec_comp_add_item(struct ec_comp *comp, + const struct ec_node *node, enum ec_comp_type type, + const char *start, const char *full) { struct ec_comp_item *item = NULL; int ret; item = ec_comp_item(type, start, full); if (item == NULL) - return -1; + return NULL; ret = ec_comp_item_add(comp, node, item); if (ret < 0) goto fail; - if (p_item != NULL) - *p_item = item; - - return 0; + return item; fail: ec_comp_item_free(item); - - return -1; + return NULL; } -/* XXX move in helpers + rename ? */ /* return a completion item of type "unknown" */ int ec_complete_unknown(const struct ec_node *gen_node, struct ec_comp *comp, const struct ec_strvec *strvec) { - int ret; + const struct ec_comp_item *item = NULL; if (ec_strvec_len(strvec) != 1) return 0; - ret = ec_comp_add_item(comp, gen_node, NULL, - EC_COMP_UNKNOWN, NULL, NULL); - if (ret < 0) - return ret; + item = ec_comp_add_item(comp, gen_node, EC_COMP_UNKNOWN, NULL, NULL); + if (item == NULL) + return -1; return 0; } @@ -517,7 +509,7 @@ static void ec_comp_group_free(struct ec_comp_group *grp) TAILQ_REMOVE(&grp->items, item, next); ec_comp_item_free(item); } - ec_pnode_free(ec_pnode_get_root(grp->state)); + ec_pnode_free(ec_pnode_get_root(grp->pstate)); ec_dict_free(grp->attrs); ec_free(grp); } @@ -529,9 +521,9 @@ ec_comp_group_get_node(const struct ec_comp_group *grp) } const struct ec_pnode * -ec_comp_group_get_state(const struct ec_comp_group *grp) +ec_comp_group_get_pstate(const struct ec_comp_group *grp) { - return grp->state; + return grp->pstate; } const struct ec_dict * @@ -566,7 +558,7 @@ void ec_comp_dump(FILE *out, const struct ec_comp *comp) return; } - fprintf(out, "completion: count=%u full=%u partial=%u unknown=%u\n", + fprintf(out, "completion: count=%zu full=%zu partial=%zu unknown=%zu\n", comp->count, comp->count_full, comp->count_partial, comp->count_unknown); @@ -609,11 +601,9 @@ int ec_comp_merge(struct ec_comp *to, return 0; } -unsigned int ec_comp_count( - const struct ec_comp *comp, - enum ec_comp_type type) +size_t ec_comp_count(const struct ec_comp *comp, enum ec_comp_type type) { - unsigned int count = 0; + size_t count = 0; if (comp == NULL) return count; diff --git a/src/ecoli_editline.c b/src/ecoli_editline.c index 42083f8..e3e53cf 100644 --- a/src/ecoli_editline.c +++ b/src/ecoli_editline.c @@ -370,34 +370,34 @@ static int get_node_help(const struct ec_comp_item *item, struct ec_editline_help *help) { const struct ec_comp_group *grp; - const struct ec_pnode *state; + const struct ec_pnode *pstate; const struct ec_node *node; const char *node_help = NULL; - const char *node_desc = NULL; + char *node_desc = NULL; help->desc = NULL; help->help = NULL; grp = ec_comp_item_get_grp(item); - for (state = ec_comp_group_get_state(grp); state != NULL; - state = ec_pnode_get_parent(state)) { - node = ec_pnode_get_node(state); + for (pstate = ec_comp_group_get_pstate(grp); pstate != NULL; + pstate = ec_pnode_get_parent(pstate)) { + node = ec_pnode_get_node(pstate); if (node_help == NULL) node_help = ec_dict_get(ec_node_attrs(node), "help"); - if (node_desc == NULL) + if (node_desc == NULL) { node_desc = ec_node_desc(node); + if (node_desc == NULL) + goto fail; + } } - if (node_help == NULL) - node_help = ""; if (node_desc == NULL) goto fail; + if (node_help == NULL) + node_help = ""; - help->desc = ec_strdup(node_desc); - if (help->desc == NULL) - goto fail; - + help->desc = node_desc; help->help = ec_strdup(node_help); if (help->help == NULL) goto fail; @@ -405,6 +405,7 @@ static int get_node_help(const struct ec_comp_item *item, return 0; fail: + ec_free(node_desc); ec_free(help->desc); ec_free(help->help); return -1; diff --git a/src/ecoli_node.c b/src/ecoli_node.c index 935f4e6..1e9bf6b 100644 --- a/src/ecoli_node.c +++ b/src/ecoli_node.c @@ -25,17 +25,29 @@ EC_LOG_TYPE_REGISTER(node); +/* These states are used to mark the grammar graph when freeing, to + * detect loop. */ +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, +}; + +/** + * The grammar node structure. + */ struct ec_node { - const struct ec_node_type *type; - struct ec_config *config; /**< Generic configuration. */ - char *id; - char *desc; - struct ec_dict *attrs; - unsigned int refcnt; + const struct ec_node_type *type; /**< The node type. */ + struct ec_config *config; /**< Node configuration. */ + char *id; /**< Node identifier (EC_NO_ID if none). */ + struct ec_dict *attrs; /**< Attributes of the node. */ + unsigned int refcnt; /**< Reference counter. */ struct { - enum ec_node_free_state state; /**< State of loop detection */ + enum ec_node_free_state state; /**< State of loop detection. */ unsigned int refcnt; /**< Number of reachable references - * starting from node beeing freed */ + * starting from node beeing freed. */ } free; /**< Freeing state: used for loop detection */ }; @@ -56,14 +68,14 @@ ec_node_type_lookup(const char *name) return NULL; } -int ec_node_type_register(struct ec_node_type *type) +int ec_node_type_register(struct ec_node_type *type, bool override) { - if (ec_node_type_lookup(type->name) != NULL) { + if (!override && ec_node_type_lookup(type->name) != NULL) { errno = EEXIST; return -1; } - TAILQ_INSERT_TAIL(&node_type_list, type, next); + TAILQ_INSERT_HEAD(&node_type_list, type, next); return 0; } @@ -99,9 +111,6 @@ struct ec_node *ec_node_from_type(const struct ec_node_type *type, const char *i if (node->id == NULL) goto fail; - if (ec_asprintf(&node->desc, "<%s>", type->name) < 0) - goto fail; - node->attrs = ec_dict(); if (node->attrs == NULL) goto fail; @@ -116,7 +125,6 @@ struct ec_node *ec_node_from_type(const struct ec_node_type *type, const char *i fail: if (node != NULL) { ec_dict_free(node->attrs); - ec_free(node->desc); ec_free(node->id); } ec_free(node); @@ -256,7 +264,6 @@ void ec_node_free(struct ec_node *node) if (node->type->free_priv != NULL) node->type->free_priv(node); ec_free(node->id); - ec_free(node->desc); ec_dict_free(node->attrs); } @@ -421,12 +428,17 @@ fail: EC_LOG(EC_LOG_ERR, "failed to dump node\n"); } -const char *ec_node_desc(const struct ec_node *node) +char *ec_node_desc(const struct ec_node *node) { + char *desc = NULL; + if (node->type->desc != NULL) return node->type->desc(node); - return node->desc; + if (ec_asprintf(&desc, "<%s>", node->type->name) < 0) + return NULL; + + return desc; } int ec_node_check_type(const struct ec_node *node, @@ -462,6 +474,7 @@ static int ec_node_testcase(void) unsigned int refs; FILE *f = NULL; char *buf = NULL; + char *desc = NULL; size_t buflen = 0; int testres = 0; int ret; @@ -494,11 +507,14 @@ static int ec_node_testcase(void) free(buf); buf = NULL; + desc = ec_node_desc(node); testres |= EC_TEST_CHECK( !strcmp(ec_node_type(node)->name, "seq") && !strcmp(ec_node_id(node), EC_NO_ID) && - !strcmp(ec_node_desc(node), ""), + !strcmp(desc, ""), "bad child 0"); + ec_free(desc); + desc = NULL; testres |= EC_TEST_CHECK( ec_node_get_children_count(node) == 2, @@ -522,11 +538,14 @@ static int ec_node_testcase(void) "child 2 should be NULL"); child = ec_node_find(node, "id_x"); + desc = ec_node_desc(child); testres |= EC_TEST_CHECK(child != NULL && !strcmp(ec_node_type(child)->name, "str") && !strcmp(ec_node_id(child), "id_x") && - !strcmp(ec_node_desc(child), "x"), + !strcmp(desc, "x"), "bad child id_x"); + ec_free(desc); + desc = NULL; child = ec_node_find(node, "id_dezdex"); testres |= EC_TEST_CHECK(child == NULL, "child with wrong id should be NULL"); diff --git a/src/ecoli_node_any.c b/src/ecoli_node_any.c index 43b886a..5bf4984 100644 --- a/src/ecoli_node_any.c +++ b/src/ecoli_node_any.c @@ -25,13 +25,13 @@ struct ec_node_any { }; static int ec_node_any_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_any *priv = ec_node_priv(node); const struct ec_dict *attrs; - (void)state; + (void)pstate; if (ec_strvec_len(strvec) == 0) return EC_PARSE_NOMATCH; @@ -91,7 +91,6 @@ static struct ec_node_type ec_node_any_type = { .schema = ec_node_any_schema, .set_config = ec_node_any_set_config, .parse = ec_node_any_parse, - .complete = ec_complete_unknown, .size = sizeof(struct ec_node_any), .free_priv = ec_node_any_free_priv, }; diff --git a/src/ecoli_node_bypass.c b/src/ecoli_node_bypass.c index 21bb253..7380aeb 100644 --- a/src/ecoli_node_bypass.c +++ b/src/ecoli_node_bypass.c @@ -28,12 +28,12 @@ struct ec_node_bypass { static int ec_node_bypass_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_bypass *priv = ec_node_priv(node); - return ec_parse_child(priv->child, state, strvec); + return ec_parse_child(priv->child, pstate, strvec); } static int diff --git a/src/ecoli_node_cmd.c b/src/ecoli_node_cmd.c index 829c896..1fb006a 100644 --- a/src/ecoli_node_cmd.c +++ b/src/ecoli_node_cmd.c @@ -391,12 +391,12 @@ fail: } static int -ec_node_cmd_parse(const struct ec_node *node, struct ec_pnode *state, +ec_node_cmd_parse(const struct ec_node *node, struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_cmd *priv = ec_node_priv(node); - return ec_parse_child(priv->cmd, state, strvec); + return ec_parse_child(priv->cmd, pstate, strvec); } static int diff --git a/src/ecoli_node_cond.c b/src/ecoli_node_cond.c index 8ff81dc..def5b39 100644 --- a/src/ecoli_node_cond.c +++ b/src/ecoli_node_cond.c @@ -71,10 +71,11 @@ struct cond_result { }; typedef struct cond_result *(cond_func_t)( - const struct ec_pnode *state, + const struct ec_pnode *pstate, struct cond_result **in, size_t in_len); -void cond_result_free(struct cond_result *res) +static void +cond_result_free(struct cond_result *res) { if (res == NULL) return; @@ -94,7 +95,8 @@ void cond_result_free(struct cond_result *res) ec_free(res); } -void cond_result_table_free(struct cond_result **table, size_t len) +static void +cond_result_table_free(struct cond_result **table, size_t len) { size_t i; @@ -204,7 +206,7 @@ fail: } static struct cond_result * -eval_root(const struct ec_pnode *state, struct cond_result **in, size_t in_len) +eval_root(const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { struct cond_result *out = NULL; const struct ec_pnode *root = NULL; @@ -226,7 +228,7 @@ eval_root(const struct ec_pnode *state, struct cond_result **in, size_t in_len) if (out->htable == NULL) goto fail; - root = ec_pnode_get_root(state); + root = ec_pnode_get_root(pstate); if (ec_htable_set(out->htable, &root, sizeof(root), NULL, NULL) < 0) goto fail; @@ -240,7 +242,7 @@ fail: } static struct cond_result * -eval_current(const struct ec_pnode *state, struct cond_result **in, +eval_current(const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { struct cond_result *out = NULL; @@ -262,7 +264,7 @@ eval_current(const struct ec_pnode *state, struct cond_result **in, if (out->htable == NULL) goto fail; - if (ec_htable_set(out->htable, &state, sizeof(state), NULL, NULL) < 0) + if (ec_htable_set(out->htable, &pstate, sizeof(pstate), NULL, NULL) < 0) goto fail; cond_result_table_free(in, in_len); @@ -292,11 +294,11 @@ boolean_value(const struct cond_result *res) } static struct cond_result * -eval_bool(const struct ec_pnode *state, struct cond_result **in, size_t in_len) +eval_bool(const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { struct cond_result *out = NULL; - (void)state; + (void)pstate; if (in_len != 1) { EC_LOG(LOG_ERR, "bool() takes one argument.\n"); @@ -321,12 +323,12 @@ fail: } static struct cond_result * -eval_or(const struct ec_pnode *state, struct cond_result **in, size_t in_len) +eval_or(const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { struct cond_result *out = NULL; size_t i; - (void)state; + (void)pstate; if (in_len < 2) { EC_LOG(LOG_ERR, "or() takes at least two arguments\n"); @@ -355,12 +357,12 @@ fail: } static struct cond_result * -eval_and(const struct ec_pnode *state, struct cond_result **in, size_t in_len) +eval_and(const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { struct cond_result *out = NULL; size_t i; - (void)state; + (void)pstate; if (in_len < 2) { EC_LOG(LOG_ERR, "or() takes at least two arguments\n"); @@ -389,7 +391,7 @@ fail: } static struct cond_result * -eval_first_child(const struct ec_pnode *state, struct cond_result **in, +eval_first_child(const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { struct cond_result *out = NULL; @@ -397,7 +399,7 @@ eval_first_child(const struct ec_pnode *state, struct cond_result **in, const struct ec_pnode * const *pparse; struct ec_pnode *parse; - (void)state; + (void)pstate; if (in_len != 1 || in[0]->type != NODESET) { EC_LOG(LOG_ERR, "first_child() takes one argument of type nodeset.\n"); @@ -435,7 +437,7 @@ fail: } static struct cond_result * -eval_find(const struct ec_pnode *state, struct cond_result **in, +eval_find(const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { struct cond_result *out = NULL; @@ -444,7 +446,7 @@ eval_find(const struct ec_pnode *state, struct cond_result **in, struct ec_pnode *parse; const char *id; - (void)state; + (void)pstate; if (in_len != 2 || in[0]->type != NODESET || in[1]->type != STR) { EC_LOG(LOG_ERR, "find() takes two arguments (nodeset, str).\n"); @@ -485,14 +487,14 @@ fail: } static struct cond_result * -eval_cmp(const struct ec_pnode *state, struct cond_result **in, +eval_cmp(const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { struct cond_result *out = NULL; struct ec_htable_elt_ref *iter; bool eq = false, gt = false; - (void)state; + (void)pstate; if (in_len != 3 || in[0]->type != STR || in[1]->type != in[2]->type) { EC_LOG(LOG_ERR, "cmp() takes 3 arguments (str, , ).\n"); @@ -568,11 +570,11 @@ fail: } static struct cond_result * -eval_count(const struct ec_pnode *state, struct cond_result **in, size_t in_len) +eval_count(const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { struct cond_result *out = NULL; - (void)state; + (void)pstate; if (in_len != 1 || in[0]->type != NODESET) { EC_LOG(LOG_ERR, "count() takes one argument of type nodeset.\n"); @@ -597,7 +599,7 @@ fail: } static struct cond_result * -eval_func(const char *name, const struct ec_pnode *state, +eval_func(const char *name, const struct ec_pnode *pstate, struct cond_result **in, size_t in_len) { cond_func_t *f; @@ -611,12 +613,12 @@ eval_func(const char *name, const struct ec_pnode *state, return NULL; } - return f(state, in, in_len); + return f(pstate, in, in_len); } static struct cond_result * -eval_condition(const struct ec_pnode *cond, const struct ec_pnode *state) +eval_condition(const struct ec_pnode *cond, const struct ec_pnode *pstate) { const struct ec_pnode *iter; struct cond_result *res = NULL; @@ -640,7 +642,7 @@ eval_condition(const struct ec_pnode *cond, const struct ec_pnode *state) iter = ec_pnode_find((void *)arg_list, "id_arg"); while (iter != NULL) { args = ec_realloc(args, (n_arg + 1) * sizeof(*args)); - args[n_arg] = eval_condition(iter, state); + args[n_arg] = eval_condition(iter, pstate); if (args[n_arg] == NULL) goto fail; n_arg++; @@ -649,7 +651,7 @@ eval_condition(const struct ec_pnode *cond, const struct ec_pnode *state) } res = eval_func(ec_strvec_val(ec_pnode_strvec(func_name), 0), - state, args, n_arg); + pstate, args, n_arg); args = NULL; return res; } @@ -686,12 +688,12 @@ fail: } static int -validate_condition(const struct ec_pnode *cond, const struct ec_pnode *state) +validate_condition(const struct ec_pnode *cond, const struct ec_pnode *pstate) { struct cond_result *res; int ret; - res = eval_condition(cond, state); + res = eval_condition(cond, pstate); if (res == NULL) return -1; @@ -702,24 +704,24 @@ validate_condition(const struct ec_pnode *cond, const struct ec_pnode *state) } static int -ec_node_cond_parse(const struct ec_node *node, struct ec_pnode *state, +ec_node_cond_parse(const struct ec_node *node, struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_cond *priv = ec_node_priv(node); struct ec_pnode *child; int ret, valid; - ret = ec_parse_child(priv->child, state, strvec); + ret = ec_parse_child(priv->child, pstate, strvec); if (ret <= 0) return ret; - valid = validate_condition(priv->parsed_cond, state); + valid = validate_condition(priv->parsed_cond, pstate); if (valid < 0) return valid; if (valid == 0) { - child = ec_pnode_get_last_child(state); - ec_pnode_unlink_child(state, child); + child = ec_pnode_get_last_child(pstate); + ec_pnode_unlink_child(pstate, child); ec_pnode_free(child); return EC_PARSE_NOMATCH; } diff --git a/src/ecoli_node_dynamic.c b/src/ecoli_node_dynamic.c index 2ce2e32..03bdd1c 100644 --- a/src/ecoli_node_dynamic.c +++ b/src/ecoli_node_dynamic.c @@ -72,7 +72,7 @@ ec_node_dynamic_complete(const struct ec_node *node, char key[64]; int ret = -1; - parse = ec_comp_get_state(comp); + parse = ec_comp_get_cur_pstate(comp); child = priv->build(parse, priv->opaque); if (child == NULL) goto fail; diff --git a/src/ecoli_node_empty.c b/src/ecoli_node_empty.c index 090808e..c6585aa 100644 --- a/src/ecoli_node_empty.c +++ b/src/ecoli_node_empty.c @@ -22,11 +22,11 @@ struct ec_node_empty { }; static int ec_node_empty_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { (void)node; - (void)state; + (void)pstate; (void)strvec; return 0; } @@ -34,7 +34,6 @@ static int ec_node_empty_parse(const struct ec_node *node, static struct ec_node_type ec_node_empty_type = { .name = "empty", .parse = ec_node_empty_parse, - .complete = ec_complete_unknown, .size = sizeof(struct ec_node_empty), }; diff --git a/src/ecoli_node_expr.c b/src/ecoli_node_expr.c index ff654ef..2a78d4f 100644 --- a/src/ecoli_node_expr.c +++ b/src/ecoli_node_expr.c @@ -43,7 +43,7 @@ struct ec_node_expr { }; static int ec_node_expr_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_expr *priv = ec_node_priv(node); @@ -53,7 +53,7 @@ static int ec_node_expr_parse(const struct ec_node *node, return -1; } - return ec_parse_child(priv->child, state, strvec); + return ec_parse_child(priv->child, pstate, strvec); } static int diff --git a/src/ecoli_node_file.c b/src/ecoli_node_file.c index ff77e01..933b997 100644 --- a/src/ecoli_node_file.c +++ b/src/ecoli_node_file.c @@ -36,11 +36,11 @@ struct ec_node_file { static int ec_node_file_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { (void)node; - (void)state; + (void)pstate; if (ec_strvec_len(strvec) == 0) return EC_PARSE_NOMATCH; @@ -210,8 +210,8 @@ ec_node_file_complete(const struct ec_node *node, if (ec_asprintf(&disp_str, "%s", de->d_name) < 0) goto fail; } - if (ec_comp_add_item(comp, node, &item, - type, input, comp_str) < 0) + item = ec_comp_add_item(comp, node, type, input, comp_str); + if (item == NULL) goto out; /* fix the display string: we don't want to display the full diff --git a/src/ecoli_node_int.c b/src/ecoli_node_int.c index acad9ed..efebae9 100644 --- a/src/ecoli_node_int.c +++ b/src/ecoli_node_int.c @@ -75,7 +75,7 @@ static int parse_ullint(struct ec_node_int_uint *priv, const char *str, } static int ec_node_int_uint_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_int_uint *priv = ec_node_priv(node); @@ -83,7 +83,7 @@ static int ec_node_int_uint_parse(const struct ec_node *node, uint64_t u64; int64_t i64; - (void)state; + (void)pstate; if (ec_strvec_len(strvec) == 0) return EC_PARSE_NOMATCH; @@ -177,7 +177,6 @@ static struct ec_node_type ec_node_int_type = { .schema = ec_node_int_schema, .set_config = ec_node_int_set_config, .parse = ec_node_int_uint_parse, - .complete = ec_complete_unknown, .size = sizeof(struct ec_node_int_uint), .init_priv = ec_node_uint_init_priv, }; @@ -290,7 +289,6 @@ static struct ec_node_type ec_node_uint_type = { .schema = ec_node_uint_schema, .set_config = ec_node_uint_set_config, .parse = ec_node_int_uint_parse, - .complete = ec_complete_unknown, .size = sizeof(struct ec_node_int_uint), }; diff --git a/src/ecoli_node_many.c b/src/ecoli_node_many.c index d99c2e3..54c100c 100644 --- a/src/ecoli_node_many.c +++ b/src/ecoli_node_many.c @@ -30,7 +30,7 @@ struct ec_node_many { }; static int ec_node_many_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_many *priv = ec_node_priv(node); @@ -45,7 +45,7 @@ static int ec_node_many_parse(const struct ec_node *node, if (childvec == NULL) goto fail; - ret = ec_parse_child(priv->child, state, childvec); + ret = ec_parse_child(priv->child, pstate, childvec); if (ret < 0) goto fail; @@ -57,8 +57,8 @@ static int ec_node_many_parse(const struct ec_node *node, /* it matches an empty strvec, no need to continue */ if (ret == 0) { - child_parse = ec_pnode_get_last_child(state); - ec_pnode_unlink_child(state, child_parse); + child_parse = ec_pnode_get_last_child(pstate); + ec_pnode_unlink_child(pstate, child_parse); ec_pnode_free(child_parse); break; } @@ -67,7 +67,7 @@ static int ec_node_many_parse(const struct ec_node *node, } if (count < priv->min) { - ec_pnode_free_children(state); + ec_pnode_free_children(pstate); return EC_PARSE_NOMATCH; } @@ -83,7 +83,7 @@ __ec_node_many_complete(struct ec_node_many *priv, unsigned int max, struct ec_comp *comp, const struct ec_strvec *strvec) { - struct ec_pnode *parse = ec_comp_get_state(comp); + struct ec_pnode *parse = ec_comp_get_cur_pstate(comp); struct ec_strvec *childvec = NULL; unsigned int i; int ret; diff --git a/src/ecoli_node_once.c b/src/ecoli_node_once.c index e3ed96a..f2c8ec1 100644 --- a/src/ecoli_node_once.c +++ b/src/ecoli_node_once.c @@ -70,7 +70,7 @@ ec_node_once_complete(const struct ec_node *node, const struct ec_strvec *strvec) { struct ec_node_once *priv = ec_node_priv(node); - struct ec_pnode *parse = ec_comp_get_state(comp); + struct ec_pnode *parse = ec_comp_get_cur_pstate(comp); unsigned int count; int ret; diff --git a/src/ecoli_node_option.c b/src/ecoli_node_option.c index 85f3451..192288c 100644 --- a/src/ecoli_node_option.c +++ b/src/ecoli_node_option.c @@ -28,13 +28,13 @@ struct ec_node_option { static int ec_node_option_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_option *priv = ec_node_priv(node); int ret; - ret = ec_parse_child(priv->child, state, strvec); + ret = ec_parse_child(priv->child, pstate, strvec); if (ret < 0) return ret; diff --git a/src/ecoli_node_or.c b/src/ecoli_node_or.c index 5f26f62..e9d6c1e 100644 --- a/src/ecoli_node_or.c +++ b/src/ecoli_node_or.c @@ -31,7 +31,7 @@ struct ec_node_or { static int ec_node_or_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_or *priv = ec_node_priv(node); @@ -39,7 +39,7 @@ ec_node_or_parse(const struct ec_node *node, int ret; for (i = 0; i < priv->len; i++) { - ret = ec_parse_child(priv->table[i], state, strvec); + ret = ec_parse_child(priv->table[i], pstate, strvec); if (ret == EC_PARSE_NOMATCH) continue; return ret; diff --git a/src/ecoli_node_re.c b/src/ecoli_node_re.c index 7d68b77..4bbc192 100644 --- a/src/ecoli_node_re.c +++ b/src/ecoli_node_re.c @@ -27,14 +27,14 @@ struct ec_node_re { static int ec_node_re_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_re *priv = ec_node_priv(node); const char *str; regmatch_t pos; - (void)state; + (void)pstate; if (ec_strvec_len(strvec) == 0) return EC_PARSE_NOMATCH; @@ -116,7 +116,6 @@ static struct ec_node_type ec_node_re_type = { .schema = ec_node_re_schema, .set_config = ec_node_re_set_config, .parse = ec_node_re_parse, - .complete = ec_complete_unknown, .size = sizeof(struct ec_node_re), .free_priv = ec_node_re_free_priv, }; diff --git a/src/ecoli_node_re_lex.c b/src/ecoli_node_re_lex.c index 48cf749..726c6cf 100644 --- a/src/ecoli_node_re_lex.c +++ b/src/ecoli_node_re_lex.c @@ -116,7 +116,7 @@ fail: static int ec_node_re_lex_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_re_lex *priv = ec_node_priv(node); @@ -139,15 +139,15 @@ ec_node_re_lex_parse(const struct ec_node *node, if (new_vec == NULL) goto fail; - ret = ec_parse_child(priv->child, state, new_vec); + ret = ec_parse_child(priv->child, pstate, new_vec); if (ret < 0) goto fail; if ((unsigned)ret == ec_strvec_len(new_vec)) { ret = 1; } else if (ret != EC_PARSE_NOMATCH) { - child_parse = ec_pnode_get_last_child(state); - ec_pnode_unlink_child(state, child_parse); + child_parse = ec_pnode_get_last_child(pstate); + ec_pnode_unlink_child(pstate, child_parse); ec_pnode_free(child_parse); ret = EC_PARSE_NOMATCH; } @@ -372,7 +372,6 @@ static struct ec_node_type ec_node_re_lex_type = { .schema = ec_node_re_lex_schema, .set_config = ec_node_re_lex_set_config, .parse = ec_node_re_lex_parse, - .complete = ec_complete_unknown, .size = sizeof(struct ec_node_re_lex), .free_priv = ec_node_re_lex_free_priv, .get_children_count = ec_node_re_lex_get_children_count, diff --git a/src/ecoli_node_seq.c b/src/ecoli_node_seq.c index d06b053..1102f3d 100644 --- a/src/ecoli_node_seq.c +++ b/src/ecoli_node_seq.c @@ -34,7 +34,7 @@ struct ec_node_seq { static int ec_node_seq_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_seq *priv = ec_node_priv(node); @@ -49,7 +49,7 @@ ec_node_seq_parse(const struct ec_node *node, if (childvec == NULL) goto fail; - ret = ec_parse_child(priv->table[i], state, childvec); + ret = ec_parse_child(priv->table[i], pstate, childvec); if (ret < 0) goto fail; @@ -57,7 +57,7 @@ ec_node_seq_parse(const struct ec_node *node, childvec = NULL; if (ret == EC_PARSE_NOMATCH) { - ec_pnode_free_children(state); + ec_pnode_free_children(pstate); return EC_PARSE_NOMATCH; } @@ -76,7 +76,7 @@ __ec_node_seq_complete(struct ec_node **table, size_t table_len, struct ec_comp *comp, const struct ec_strvec *strvec) { - struct ec_pnode *parse = ec_comp_get_state(comp); + struct ec_pnode *parse = ec_comp_get_cur_pstate(comp); struct ec_strvec *childvec = NULL; unsigned int i; int ret; diff --git a/src/ecoli_node_sh_lex.c b/src/ecoli_node_sh_lex.c index c6b6867..7dd0358 100644 --- a/src/ecoli_node_sh_lex.c +++ b/src/ecoli_node_sh_lex.c @@ -214,7 +214,7 @@ static struct ec_strvec *tokenize(const char *str, int completion, static int ec_node_sh_lex_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_sh_lex *priv = ec_node_priv(node); @@ -234,15 +234,15 @@ ec_node_sh_lex_parse(const struct ec_node *node, if (new_vec == NULL) goto fail; - ret = ec_parse_child(priv->child, state, new_vec); + ret = ec_parse_child(priv->child, pstate, new_vec); if (ret < 0) goto fail; if ((unsigned)ret == ec_strvec_len(new_vec)) { ret = 1; } else if (ret != EC_PARSE_NOMATCH) { - child_parse = ec_pnode_get_last_child(state); - ec_pnode_unlink_child(state, child_parse); + child_parse = ec_pnode_get_last_child(pstate); + ec_pnode_unlink_child(pstate, child_parse); ec_pnode_free(child_parse); ret = EC_PARSE_NOMATCH; } diff --git a/src/ecoli_node_space.c b/src/ecoli_node_space.c index 4ab6ad3..ff7ca14 100644 --- a/src/ecoli_node_space.c +++ b/src/ecoli_node_space.c @@ -23,13 +23,13 @@ struct ec_node_space { static int ec_node_space_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { const char *str; size_t len = 0; - (void)state; + (void)pstate; (void)node; if (ec_strvec_len(strvec) == 0) @@ -47,7 +47,6 @@ ec_node_space_parse(const struct ec_node *node, static struct ec_node_type ec_node_space_type = { .name = "space", .parse = ec_node_space_parse, - .complete = ec_complete_unknown, .size = sizeof(struct ec_node_space), }; diff --git a/src/ecoli_node_str.c b/src/ecoli_node_str.c index f333abb..7c37220 100644 --- a/src/ecoli_node_str.c +++ b/src/ecoli_node_str.c @@ -26,13 +26,13 @@ struct ec_node_str { static int ec_node_str_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_str *priv = ec_node_priv(node); const char *str; - (void)state; + (void)pstate; if (priv->string == NULL) { errno = EINVAL; @@ -55,6 +55,7 @@ ec_node_str_complete(const struct ec_node *node, const struct ec_strvec *strvec) { struct ec_node_str *priv = ec_node_priv(node); + const struct ec_comp_item *item; const char *str; size_t n = 0; @@ -72,18 +73,18 @@ ec_node_str_complete(const struct ec_node *node, if (str[n] != '\0') return EC_PARSE_NOMATCH; - if (ec_comp_add_item(comp, node, NULL, EC_COMP_FULL, - str, priv->string) < 0) + item = ec_comp_add_item(comp, node, EC_COMP_FULL, str, priv->string); + if (item == NULL) return -1; return 0; } -static const char *ec_node_str_desc(const struct ec_node *node) +static char *ec_node_str_desc(const struct ec_node *node) { struct ec_node_str *priv = ec_node_priv(node); - return priv->string; + return ec_strdup(priv->string); } static void ec_node_str_free_priv(struct ec_node *node) @@ -201,14 +202,18 @@ static int ec_node_str_testcase(void) { struct ec_node *node; int testres = 0; + char *desc = NULL; node = ec_node_str(EC_NO_ID, "foo"); if (node == NULL) { EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } - testres |= EC_TEST_CHECK(!strcmp(ec_node_desc(node), "foo"), + desc = ec_node_desc(node); + testres |= EC_TEST_CHECK(!strcmp(desc, "foo"), "Invalid node description."); + ec_free(desc); + desc = NULL; testres |= EC_TEST_CHECK_PARSE(node, 1, "foo"); testres |= EC_TEST_CHECK_PARSE(node, 1, "foo", "bar"); testres |= EC_TEST_CHECK_PARSE(node, -1, "foobar"); diff --git a/src/ecoli_node_subset.c b/src/ecoli_node_subset.c index eddef84..7e65170 100644 --- a/src/ecoli_node_subset.c +++ b/src/ecoli_node_subset.c @@ -37,7 +37,7 @@ struct parse_result { * updated accordingly. */ static int __ec_node_subset_parse(struct parse_result *out, struct ec_node **table, - size_t table_len, struct ec_pnode *state, + size_t table_len, struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node **child_table; @@ -58,7 +58,7 @@ __ec_node_subset_parse(struct parse_result *out, struct ec_node **table, for (i = 0; i < table_len; i++) { /* try to parse elt i */ - ret = ec_parse_child(table[i], state, strvec); + ret = ec_parse_child(table[i], pstate, strvec); if (ret < 0) goto fail; @@ -82,7 +82,7 @@ __ec_node_subset_parse(struct parse_result *out, struct ec_node **table, memset(&result, 0, sizeof(result)); ret = __ec_node_subset_parse(&result, child_table, - table_len - 1, state, childvec); + table_len - 1, pstate, childvec); ec_strvec_free(childvec); childvec = NULL; if (ret < 0) @@ -91,14 +91,14 @@ __ec_node_subset_parse(struct parse_result *out, struct ec_node **table, /* if result is not the best, ignore */ if (result.parse_len < best_result.parse_len) { memset(&result, 0, sizeof(result)); - ec_pnode_del_last_child(state); + ec_pnode_del_last_child(pstate); continue; } /* replace the previous best result */ ec_pnode_free(best_parse); - best_parse = ec_pnode_get_last_child(state); - ec_pnode_unlink_child(state, best_parse); + best_parse = ec_pnode_get_last_child(pstate); + ec_pnode_unlink_child(pstate, best_parse); best_result.parse_len = result.parse_len + 1; best_result.len = len + result.len; @@ -109,7 +109,7 @@ __ec_node_subset_parse(struct parse_result *out, struct ec_node **table, *out = best_result; ec_free(child_table); if (best_parse != NULL) - ec_pnode_link_child(state, best_parse); + ec_pnode_link_child(pstate, best_parse); return 0; @@ -122,7 +122,7 @@ __ec_node_subset_parse(struct parse_result *out, struct ec_node **table, static int ec_node_subset_parse(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, const struct ec_strvec *strvec) { struct ec_node_subset *priv = ec_node_priv(node); @@ -133,7 +133,7 @@ ec_node_subset_parse(const struct ec_node *node, memset(&result, 0, sizeof(result)); ret = __ec_node_subset_parse(&result, priv->table, - priv->len, state, strvec); + priv->len, pstate, strvec); if (ret < 0) goto fail; @@ -153,7 +153,7 @@ __ec_node_subset_complete(struct ec_node **table, size_t table_len, struct ec_comp *comp, const struct ec_strvec *strvec) { - struct ec_pnode *parse = ec_comp_get_state(comp); + struct ec_pnode *parse = ec_comp_get_cur_pstate(comp); struct ec_strvec *childvec = NULL; struct ec_node *save; size_t i, len; diff --git a/src/ecoli_parse.c b/src/ecoli_parse.c index e1b6018..9a6eabc 100644 --- a/src/ecoli_parse.c +++ b/src/ecoli_parse.c @@ -35,7 +35,7 @@ struct ec_pnode { }; static int __ec_parse_child(const struct ec_node *node, - struct ec_pnode *state, + struct ec_pnode *pstate, bool is_root, const struct ec_strvec *strvec) { struct ec_strvec *match_strvec; @@ -54,9 +54,9 @@ static int __ec_parse_child(const struct ec_node *node, if (child == NULL) return -1; - ec_pnode_link_child(state, child); + ec_pnode_link_child(pstate, child); } else { - child = state; + child = pstate; } ret = ec_node_type(node)->parse(node, child, strvec); if (ret < 0) @@ -64,7 +64,7 @@ static int __ec_parse_child(const struct ec_node *node, if (ret == EC_PARSE_NOMATCH) { if (!is_root) { - ec_pnode_unlink_child(state, child); + ec_pnode_unlink_child(pstate, child); ec_pnode_free(child); } return ret; @@ -80,17 +80,17 @@ static int __ec_parse_child(const struct ec_node *node, fail: if (!is_root) { - ec_pnode_unlink_child(state, child); + ec_pnode_unlink_child(pstate, child); ec_pnode_free(child); } return -1; } -int ec_parse_child(const struct ec_node *node, struct ec_pnode *state, +int ec_parse_child(const struct ec_node *node, struct ec_pnode *pstate, const struct ec_strvec *strvec) { - assert(state != NULL); - return __ec_parse_child(node, state, false, strvec); + assert(pstate != NULL); + return __ec_parse_child(node, pstate, false, strvec); } // XXX what is returned if no match ?? diff --git a/src/ecoli_test.c b/src/ecoli_test.c index 3e7d625..4ec4d7b 100644 --- a/src/ecoli_test.c +++ b/src/ecoli_test.c @@ -99,7 +99,7 @@ int ec_test_check_complete(struct ec_node *tk, enum ec_comp_type type, ...) struct ec_strvec *vec = NULL; const char *s; int ret = 0; - unsigned int count = 0; + size_t count = 0; va_list ap; va_start(ap, type); @@ -155,7 +155,7 @@ int ec_test_check_complete(struct ec_node *tk, enum ec_comp_type type, ...) /* check if we have more completions (or less) than expected */ if (count != ec_comp_count(c, type)) { EC_LOG(EC_LOG_ERR, - "nb_completion (%d) does not match (%d)\n", + "nb_completion (%zu) does not match (%zu)\n", count, ec_comp_count(c, type)); ec_comp_dump(stdout, c); ret = -1; -- 2.20.1