Libecoli 0.3.0
Extensible COmmand LIne library
|
Libecoli grammar nodes. More...
Data Structures | |
struct | ec_init |
struct | ec_node_type |
struct | ec_node_expr_eval_ops |
Macros | |
#define | EC_INIT_REGISTER(t) |
#define | EC_NO_ID "" |
#define | EC_NODE_TYPE_REGISTER(t) |
#define | EC_NODE_TYPE_REGISTER_OVERRIDE(t) |
#define | EC_NODE_CMD(args...) |
#define | EC_NODE_OR(args...) |
#define | EC_NODE_SEQ(args...) |
#define | EC_NODE_SUBSET(args...) |
Typedefs | |
typedef int | ec_init_t(void) |
typedef void | ec_exit_t(void) |
typedef int(* | ec_node_set_config_t) (struct ec_node *node, const struct ec_config *config) |
typedef int(* | ec_parse_t) (const struct ec_node *node, struct ec_pnode *pstate, const struct ec_strvec *strvec) |
typedef int(* | ec_complete_t) (const struct ec_node *node, struct ec_comp *comp, const struct ec_strvec *strvec) |
typedef 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) |
typedef struct ec_node *(* | ec_node_dynamic_build_t) (struct ec_pnode *pstate, void *opaque) |
typedef int(* | ec_node_expr_eval_var_t) (void **result, void *userctx, const struct ec_pnode *var) |
typedef int(* | ec_node_expr_eval_pre_op_t) (void **result, void *userctx, void *operand, const struct ec_pnode *operator) |
typedef int(* | ec_node_expr_eval_post_op_t) (void **result, void *userctx, void *operand, const struct ec_pnode *operator) |
typedef int(* | ec_node_expr_eval_bin_op_t) (void **result, void *userctx, void *operand1, const struct ec_pnode *operator, void *operand2) |
typedef int(* | ec_node_expr_eval_parenthesis_t) (void **result, void *userctx, const struct ec_pnode *open_paren, const struct ec_pnode *close_paren, void *value) |
typedef void(* | ec_node_expr_eval_free_t) (void *result, void *userctx) |
Functions | |
void | ec_init_register (struct ec_init *test) |
int | ec_init (void) |
void | ec_exit (void) |
int | ec_node_type_register (struct ec_node_type *type, bool override) |
const struct ec_node_type * | ec_node_type_lookup (const char *name) |
void | ec_node_type_dump (FILE *out) |
const struct ec_config_schema * | ec_node_type_schema (const struct ec_node_type *type) |
const char * | ec_node_type_name (const struct ec_node_type *type) |
struct ec_node * | ec_node_from_type (const struct ec_node_type *type, const char *id) |
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) |
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) |
int | ec_node_get_child (const struct ec_node *node, size_t i, struct ec_node **child, unsigned int *refs) |
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) |
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) |
int | ec_node_check_type (const struct ec_node *node, const struct ec_node_type *type) |
const char * | ec_node_get_type_name (const struct ec_node *node) |
void * | ec_node_priv (const struct ec_node *node) |
struct ec_node * | ec_node_any (const char *id, const char *attr) |
struct ec_node * | ec_node_bypass (const char *id, struct ec_node *node) |
int | ec_node_bypass_set_child (struct ec_node *gen_node, struct ec_node *child) |
struct ec_node * | ec_node_cond (const char *id, const char *cond_str, struct ec_node *child) |
struct ec_node * | ec_node_dynamic (const char *id, ec_node_dynamic_build_t build, void *opaque) |
struct ec_node * | ec_node_empty (const char *id) |
struct ec_node * | ec_node_expr (const char *id) |
int | ec_node_expr_set_val_node (struct ec_node *gen_node, struct ec_node *val_node) |
int | ec_node_expr_add_bin_op (struct ec_node *gen_node, struct ec_node *op) |
int | ec_node_expr_add_pre_op (struct ec_node *gen_node, struct ec_node *op) |
int | ec_node_expr_add_post_op (struct ec_node *gen_node, struct ec_node *op) |
int | ec_node_expr_add_parenthesis (struct ec_node *gen_node, struct ec_node *open, struct ec_node *close) |
int | ec_node_expr_eval (void **result, const struct ec_node *node, struct ec_pnode *parse, const struct ec_node_expr_eval_ops *ops, void *userctx) |
struct ec_node * | ec_node_file (const char *id, const char *file) |
int | ec_node_file_set_str (struct ec_node *node, const char *file) |
struct ec_node * | ec_node_int (const char *id, int64_t min, int64_t max, unsigned int base) |
int | ec_node_int_getval (const struct ec_node *node, const char *str, int64_t *result) |
struct ec_node * | ec_node_uint (const char *id, uint64_t min, uint64_t max, unsigned int base) |
int | ec_node_uint_getval (const struct ec_node *node, const char *str, uint64_t *result) |
struct ec_node * | ec_node_many (const char *id, struct ec_node *child, unsigned int min, unsigned int max) |
int | ec_node_many_set_params (struct ec_node *gen_node, struct ec_node *child, unsigned int min, unsigned int max) |
struct ec_node * | ec_node_once (const char *id, struct ec_node *child) |
int | ec_node_once_set_child (struct ec_node *node, struct ec_node *child) |
struct ec_node * | ec_node_option (const char *id, struct ec_node *node) |
int | ec_node_option_set_child (struct ec_node *gen_node, struct ec_node *child) |
struct ec_node * | ec_node_or (const char *id) |
int | ec_node_or_add (struct ec_node *node, struct ec_node *child) |
struct ec_node * | ec_node_re (const char *id, const char *str) |
int | ec_node_re_set_regexp (struct ec_node *node, const char *re) |
struct ec_node * | ec_node_re_lex (const char *id, struct ec_node *child) |
int | ec_node_re_lex_add (struct ec_node *gen_node, const char *pattern, int keep, const char *attr_name) |
struct ec_node * | ec_node_seq (const char *id) |
int | ec_node_seq_add (struct ec_node *node, struct ec_node *child) |
struct ec_node * | ec_node_sh_lex (const char *id, struct ec_node *child) |
struct ec_node * | ec_node_str (const char *id, const char *str) |
int | ec_node_str_set_str (struct ec_node *node, const char *str) |
struct ec_node * | ec_node_subset (const char *id) |
int | ec_node_subset_add (struct ec_node *node, struct ec_node *child) |
Libecoli grammar nodes.
The grammar node is a main structure of the ecoli library, used to define how to match and complete the input tokens. A node is a generic object that implements:
One basic example is the string node (ec_node_str). A node ec_node_str("foo") will match any token list starting with "foo", for example:
A node ec_node_str("foo") will complete with "foo" if the input contains one token, with the same beginning than "foo":
A node can have child nodes. For instance, a sequence node ec_node_seq(ec_node_str("foo"), ec_node_str("bar")) will match 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.
This node matches one string in the vector if it is only composed of spaces, as interpreted by isspace().
#define EC_INIT_REGISTER | ( | t | ) |
Register initialization and exit callbacks. These callbacks are ordered by priority: for initialization, the lowest priority is called first. For exit, the callbacks are invoked in reverse order.
Definition at line 23 of file ecoli_init.h.
#define EC_NO_ID "" |
Node has no identifier.
Definition at line 60 of file ecoli_node.h.
#define EC_NODE_TYPE_REGISTER | ( | t | ) |
Register a node type at library load.
The node type is registered in a function that has the the constructor attribute: the function is called at library load.
t | The name of the ec_node_type structure variable. |
Definition at line 81 of file ecoli_node.h.
#define EC_NODE_TYPE_REGISTER_OVERRIDE | ( | t | ) |
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.
t | The name of the ec_node_type structure variable. |
Definition at line 105 of file ecoli_node.h.
#define EC_NODE_CMD | ( | args... | ) |
Definition at line 15 of file ecoli_node_cmd.h.
#define EC_NODE_OR | ( | args... | ) |
Create a new "or" node from an arbitrary list of child nodes. All nodes given in the list will be freed when freeing this one.
Definition at line 20 of file ecoli_node_or.h.
#define EC_NODE_SEQ | ( | args... | ) |
Definition at line 15 of file ecoli_node_seq.h.
#define EC_NODE_SUBSET | ( | args... | ) |
Definition at line 15 of file ecoli_node_subset.h.
typedef int ec_init_t(void) |
Type of init function. Return 0 on success, -1 on error.
Definition at line 34 of file ecoli_init.h.
typedef void ec_exit_t(void) |
Type of exit function.
Definition at line 39 of file ecoli_init.h.
Function type used to configure a node.
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.
node | The node to configure. |
config | The configuration to apply to the node. |
Definition at line 137 of file ecoli_node.h.
typedef int(* ec_parse_t) (const struct ec_node *node, struct ec_pnode *pstate, const struct ec_strvec *strvec) |
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, pstate, child_strvec).
node | The grammar graph. |
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(pstate) should be used. |
strvec | The string vector to be parsed. |
Definition at line 163 of file ecoli_node.h.
typedef int(* ec_complete_t) (const struct ec_node *node, struct ec_comp *comp, const struct ec_strvec *strvec) |
Get completion items using the given grammar graph.
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 in the node is supposed to either:
A node that does not provide any method for the completion will fallback to ec_complete_unknown(): this helper returns a completion item of type EC_COMP_UNKNOWN, just to indicate that everything before the last element of the string vector has been parsed successfully, but we don't know how to complete the last element.
node | The root node of the grammar graph. |
comp | The current list of completion items, to be filled by the node.type->complete() method. |
strvec | The string vector to be completed. |
Definition at line 208 of file ecoli_node.h.
typedef char *(* ec_node_desc_t) (const struct ec_node *) |
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):
<int>
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 <int>
. 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.
Definition at line 237 of file ecoli_node.h.
typedef int(* ec_node_init_priv_t) (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.
Definition at line 253 of file ecoli_node.h.
typedef void(* ec_node_free_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.
Definition at line 264 of file ecoli_node.h.
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_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.
Definition at line 276 of file ecoli_node.h.
typedef int(* ec_node_get_child_t) (const struct ec_node *, size_t i, struct ec_node **child, unsigned int *refs) |
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.
Definition at line 294 of file ecoli_node.h.
callback invoked by parse() or complete() to build the dynamic node the behavior of the node can depend on what is already parsed
Definition at line 1 of file ecoli_node_dynamic.h.
typedef int(* ec_node_expr_eval_var_t) (void **result, void *userctx, const struct ec_pnode *var) |
Callback function type for evaluating a variable
result | On success, this pointer must be set by the user to point to a user structure describing the evaluated result. |
userctx | A user-defined context passed to all callback functions, which can be used to maintain a state or store global information. |
var | The parse result referencing the variable. |
Definition at line 30 of file ecoli_node_expr.h.
typedef int(* ec_node_expr_eval_pre_op_t) (void **result, void *userctx, void *operand, const struct ec_pnode *operator) |
Callback function type for evaluating a prefix-operator
result | On success, this pointer must be set by the user to point to a user structure describing the evaluated result. |
userctx | A user-defined context passed to all callback functions, which can be used to maintain a state or store global information. |
operand | The evaluated expression on which the operation should be applied. |
operator | The parse result referencing the operator. |
Definition at line 51 of file ecoli_node_expr.h.
typedef int(* ec_node_expr_eval_post_op_t) (void **result, void *userctx, void *operand, const struct ec_pnode *operator) |
Definition at line 56 of file ecoli_node_expr.h.
typedef int(* ec_node_expr_eval_bin_op_t) (void **result, void *userctx, void *operand1, const struct ec_pnode *operator,void *operand2) |
Definition at line 61 of file ecoli_node_expr.h.
typedef int(* ec_node_expr_eval_parenthesis_t) (void **result, void *userctx, const struct ec_pnode *open_paren, const struct ec_pnode *close_paren, void *value) |
Definition at line 67 of file ecoli_node_expr.h.
typedef void(* ec_node_expr_eval_free_t) (void *result, void *userctx) |
Definition at line 73 of file ecoli_node_expr.h.
void ec_init_register | ( | struct ec_init * | test | ) |
Register an initialization function.
test | A pointer to a ec_init structure to be registered. |
int ec_init | ( | void | ) |
Initialize ecoli library.
Must be called before any other function from libecoli, except ec_malloc_register().
void ec_exit | ( | void | ) |
Uninitialize ecoli library.
int ec_node_type_register | ( | struct ec_node_type * | type, |
bool | override ) |
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.
type | The node type to be registered. |
override | Allow the registration of an existing type. |
const struct ec_node_type * ec_node_type_lookup | ( | const char * | name | ) |
Lookup node type by name.
name | The name of the node type to search. |
void ec_node_type_dump | ( | FILE * | out | ) |
Dump registered log types.
out | The stream where the dump is sent. |
const struct ec_config_schema * ec_node_type_schema | ( | const struct ec_node_type * | type | ) |
Get the config schema of a node type.
type | The node type. |
const char * ec_node_type_name | ( | const struct ec_node_type * | type | ) |
Get the name of a node type.
type | The node type. |
struct ec_node * ec_node_from_type | ( | const struct ec_node_type * | type, |
const char * | id ) |
create a new node when the type is known, typically called from the node code
struct ec_node * ec_node | ( | const char * | typename, |
const char * | id ) |
Create a new node from type name.
void * ec_node_priv | ( | const struct ec_node * | node | ) |
Get the pointer to the node private area.
node | The grammar node. |
struct ec_node * ec_node_any | ( | const char * | id, |
const char * | attr ) |
Create a "any" node.
This node always matches 1 string in the vector. An optional strvec attribute can be checked too. These attributes are usually set by a lexer node.
id | The node identifier. |
attr | The strvec attribute to match, or NULL. |
A node that does nothing else than calling the child node. It can be helpful to build loops in a node graph.
Attach a child to a bypass node.
Create a condition node.
The condition node checks that an expression is true before parsing/completing the child node. If it is false, the node doesn't match anything.
id | The node identifier. |
cond_str | The condition string. This is an function-based expression. |
child | The ecoli child node. |
struct ec_node * ec_node_dynamic | ( | const char * | id, |
ec_node_dynamic_build_t | build, | ||
void * | opaque ) |
Dynamic node where parsing/validation is done in a user provided callback.
struct ec_node * ec_node_empty | ( | const char * | id | ) |
This node always matches an empty string vector
This node behaves like its child, but prevent from parsing it several times.
Example:
Matches: [], ["foo", "bar"], ["bar", "bar"], ["foo", "bar", "bar"], ... But not: ["foo", "foo"], ["foo", "bar", "foo"], ...
on error, child is not freed
on error, child is freed
struct ec_node * ec_node_or | ( | const char * | id | ) |
Create an empty "or" node.