ecoli_nodes(3)
β¨ NAME β¨
ecoli_nodes β Grammar nodes π
Libecoli grammar nodes. (yes bestie, this is the ecoli_nodes(3) page, welcome to the node lore π§)
π¦ SYNOPSIS π¦
π¦ Data Structures
struct ec_initstruct ec_node_typestruct ec_node_expr_eval_opsstruct ec_node_file_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 struct ec_strvec *(* ec_node_dynlist_get_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)
π Enumerations
enum ec_node_dynlist_flags { DYNLIST_MATCH_LIST = 1 << 0, DYNLIST_MATCH_REGEXP = 1 << 1, DYNLIST_EXCLUDE_LIST = 1 << 2 }
π₯ 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 (const 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)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)struct ec_node * ec_node_find_next (struct ec_node *root, const struct ec_node *prev, 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)void ec_node_schema_dump (FILE *out, 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_dynlist (const char *id, ec_node_dynlist_get_t get, void *opaque, const char *re_str, enum ec_node_dynlist_flags flags)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)void ec_node_file_set_ops (const struct ec_node_file_ops *ops)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_sh_lex_expand (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)
β Variables
struct ec_node_type_list node_type_list
π DETAILED DESCRIPTION π
Libecoli grammar nodes.
Okay so listen bestie π«Ά β the grammar node is a main structure of the ecoli library, and its whole job is defining how to match and complete the input tokens. A node is a generic object that implements:
- a
parse(node, input)method: check if an input matches β - a
complete(node, input)method: return possible completions for a given input β¨ - some other methods to initialize, free, ... (the little housekeeping ones, they're doing their best π )
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:
["foo"]["foo", "bar", ...]
But will not match:
[]["bar", ...]
A node ec_node_str("foo") will complete with "foo" if the input contains one token, with the same beginning than "foo":
[""]["f"]["fo"]["foo"]
But it will not complete:
[]["bar"]["f", ""]["", "f"]
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"]. iconic honestly π
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. (not me catching that terminology slip π the graph is the moment fr fr)
This node is able to parse a list of object names, returned by a user-defined function as a string vector. π
Some flags can alter the behavior of parsing and completion:
- Match names returned by the user callback. β¨
- Match names from a regular expression pattern. π₯
- Don't match names returned by the user callback, even if it matches the regexp. π
This node matches one string in the vector if it is only composed of spaces, as interpreted by isspace(). πΈ
π¦ Macro Definition Documentation π¦
Okay bestie, welcome to the macro section, where all the magic happens. These are the little spells you cast in your C code to make ecoli do its thing. Let's get into it, no cap. π
#define EC_INIT_REGISTER( t)
Value:
static void ec_init_init_##t(void); \
static void __attribute__((constructor, used)) ec_init_init_##t(void) \
{ \
ec_init_register(&t); \
}
Okay so this one is literally the registration squad for initialization and exit callbacks. The way these callbacks work is by priority: for initialization, the lowest priority gets called first. For exit, the callbacks are invoked in reverse order. So it's giving very organized, very main character energy. β¨
Priority policy, listen up: 0 .. 99 is reserved for libecoli internal use. 100 .. is available for user code (recommended).
Do not use priorities < 100 for application code β internal libecoli components may depend on those priorities, and using them can lead to uninitialized state, crashes, or undefined behaviour. That's not the vibe, bestie. π
Definition at line 27 of file init.h.
#define EC_NO_ID ''
Value: ''
Node has no identifier. Simple as that. Definition at line 59 of file node.h.
#define EC_NODE_TYPE_REGISTER( t)
Value:
static void ec_node_init_##t(void); \
static void __attribute__((constructor, used)) ec_node_init_##t(void) \
{ \
if (ec_node_type_register(&t, 0) < 0) \
fprintf(stderr, "cannot register node type %s\n", t.name); \
}
This macro registers a node type at library load. The registration happens in a function that has the constructor attribute, which means it gets called automatically when the library loads. Iconic. π
Parameters
tβ The name of theec_node_typestructure variable.
Definition at line 80 of file node.h.
#define EC_NODE_TYPE_REGISTER_OVERRIDE( t)
Value:
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); \
}
Same energy as the last one, but this one overrides previous registration. It also uses the constructor attribute, so it runs at library load.
Be careful when using this macro, because the last type with a given name is the one that actually gets registered. The call order may be hard to predict, especially within the same binary. So don't say I didn't warn you, bestie. π
Parameters
tβ The name of theec_node_typestructure variable.
Definition at line 101 of file node.h.
#define EC_NODE_CMD( args...)
Value:
__ec_node_cmd(args, EC_VA_END)
No extra description in the original, just the value and the definition. Definition at line 14 of file node_cmd.h.
#define EC_NODE_OR( args...)
Value:
__ec_node_or(args, EC_VA_END)
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. So it's like a little family, and when the parent goes, everyone goes. Periodt. π
Definition at line 19 of file node_or.h.
#define EC_NODE_SEQ( args...)
Value:
__ec_node_seq(args, EC_VA_END)
No extra description, just the value and the definition. Definition at line 14 of file node_seq.h.
#define EC_NODE_SUBSET( args...)
Value:
__ec_node_subset(args, EC_VA_END)
No extra description, just the value and the definition. Definition at line 14 of file node_subset.h.
π§΅ Typedef Documentation π§΅
okay bestie this is the big one, all the function-pointer typedefs the node system is built out of. no cap, this is where the β¨magicβ¨ lives.
ec_init_t
typedef int ec_init_t(void)
the blueprint for an init function. that's it, that's the whole vibe. return 0 on success, -1 on error. π
Definition at line 37 of file init.h.
ec_exit_t
typedef void ec_exit_t(void)
the blueprint for an exit function. nothing to return, nothing to prove. iconic. β¨
Definition at line 42 of file init.h.
ec_node_set_config_t
typedef int(* ec_node_set_config_t) (struct ec_node *node, const struct ec_config *config)
so this is the function type you use to configure a node. π
the way that you do NOT call this function pointer yourself β you go through the helper ec_node_set_config() instead. periodt.
the config that gets handed to this pointer is already valid, like ec_config_validate() returned 0 on it. so it's clean, okay?
what this function (provided by a node type) is supposed to do is extra checks on the config plus stash whatever private data it needs. if it returns 0, then ec_node_set_config() goes ahead and stores the generic configuration in the node. and if there's literally nothing to store in the private data? just return 0 and vibe. π¦
Parameters
nodeβ the node you're configuring.configβ the configuration being applied to the node.
Returns
0 on success, negative on error (and errno is set).
Definition at line 130 of file node.h.
ec_parse_t
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. π₯
lowkey important: you do NOT call this pointer directly β use the helpers ec_parse(), ec_parse_strvec() or ec_parse_child() instead.
if a node manages children, its implementation of this method will call ec_parse_child(child, pstate, child_strvec).
Parameters
nodeβ the grammar graph.pstateβ a pointer to the leaf being parsed in the parsing tree. a node can use this to pull info out of the current parsing tree. wanna get to the root of the tree? useec_pnode_get_root(pstate).strvecβ the string vector to be parsed.
Returns
on success, the number of consumed items in the string vector (and yes, it can be 0), or EC_PARSE_NOMATCH if the node can't parse the string vector at all. on error, a negative value comes back and errno is set. π
Definition at line 155 of file node.h.
ec_complete_t
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. this is the autocomplete girlie. π
do NOT call the function pointer directly, the helpers ec_complete(), ec_complete_strvec() or ec_complete_child() are right there.
this function completes the last element of the string vector. example time, bestie: node.type->complete(node, comp, ["ls"]) will list all commands that start with "ls", whereas node.type->complete(node, comp, ["ls", ""]) will list all the possible values for the next argument. see the difference? it's giving β¨contextβ¨.
the implementation of this function in the node is supposed to do one of these two things:
- call
ec_comp_add_item()for each completion item that should be added to the list. this is typically what terminal nodes do, for example inec_node_str()orec_node_file(). - call
ec_complete_child()to let the children nodes add their own completions. that's whatec_node_ordoes (it just trivially callsec_complete_child()on all its children), and also whatec_node_seqdoes, except seq has to do a way more complex job (it parsesstrvec).
and if a node doesn't provide any method for completion at all, it falls back to ec_complete_unknown(). that helper returns a completion item of type EC_COMP_UNKNOWN, which is basically just saying "everything before the last element of the string vector parsed fine, but we genuinely don't know how to complete the last element." π
Parameters
nodeβ the root node of the grammar graph.compβ the current list of completion items, which thenode.type->complete()method fills in.strvecβ the string vector to be completed.
Returns
0 on success, or a negative value on error (errno is set).
Definition at line 202 of file node.h.
ec_node_desc_t
typedef char *(* ec_node_desc_t) (const struct ec_node *)
get the short description of a grammar node. π
don't call this pointer yourself! use the ec_node_desc() helper instead.
this callback is typically used when building a help string for a grammar graph. the ecoli editline interface uses it 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 wrapped in <>, 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"). π
heads up: the returned value is a pointer that must be freed by the caller with free().
on error, NULL is returned and errno is set.
Definition at line 233 of file node.h.
ec_node_init_priv_t
typedef int(* ec_node_init_priv_t) (struct ec_node *)
initialize the node private area. π«Ά
do not call this function pointer directly β use the ec_node() and ec_node_from_type() helpers instead, they're the ones that allocate new nodes.
if it's not NULL, this function gets called when a node is instantiated, to initialize that node's private area. and in any case, the private area is first zeroed out. clean slate, main character energy. β¨
on success, 0 is returned. on error, a negative value is returned and errno is set.
Definition at line 249 of file node.h.
ec_node_free_priv_t
typedef void(* ec_node_free_priv_t) (struct ec_node *)
free the node private area. π¦
do NOT call this function pointer directly β use the ec_node_free() helper.
when a node gets deleted, this function is called to free up the resources referenced in the node's private area. it's giving closure. π
Definition at line 260 of file node.h.
ec_node_get_children_count_t
typedef size_t(* ec_node_get_children_count_t) (const struct ec_node *)
count the number of node children. π§
don't call this pointer directly, use the ec_node_get_children_count() helper instead.
some grammar nodes like seq, or, many, (...), reference children nodes in the grammar graph. this function returns how many children there are.
Definition at line 272 of file node.h.
ec_node_get_child_t
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. (yes bestie, the original says this too, we're keeping it exactly as-is π)
do not call this function pointer directly β the ec_node_get_child() helper is the way.
some grammar nodes like seq, or, many, (...), reference children nodes in the grammar graph. this function sets the i-th child (where i is lower than the return value of ec_node_get_children_count()) into the child pointer. it also returns the number of references to the child that the parent owns. that info gets used by the algorithm that frees a grammar graph, and it's specifically how it handles loops. π₯
on success, 0 is returned. on error, a negative value is returned and errno is set.
Definition at line 290 of file node.h.
ec_node_dynamic_build_t
typedef struct ec_node *(* ec_node_dynamic_build_t) (struct ec_pnode *pstate, void *opaque)
callback invoked by parse() or complete() to build the dynamic node β the behavior of the node can depend on what's already been parsed. no cap, it's adaptive like that. π
Definition at line 1 of file node_dynamic.h.
ec_node_dynlist_get_t
typedef struct ec_strvec *(* ec_node_dynlist_get_t) (struct ec_pnode *pstate, void *opaque)
callback invoked by parse() or complete() to build the strvec containing the list of object names. π
Parameters
pstateβ the current parsing state.opaqueβ the user pointer that was passed at node creation.
Returns
a string vector containing the list of object names.
Definition at line 1 of file node_dynlist.h.
ec_node_expr_eval_var_t
typedef int(* ec_node_expr_eval_var_t) (void **result, void *userctx, const struct ec_pnode *var)
callback function type for evaluating a variable. β¨
Parameters
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.
Returns
0 on success (*result must be set), or -errno on error (*result is undefined).
Definition at line 29 of file node_expr.h.
ec_node_expr_eval_pre_op_t
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. πΈ
Parameters
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.
Returns
0 on success (*result must be set, operand is freed), or -errno on error (*result is undefined, operand is not freed).
Definition at line 48 of file node_expr.h.
ec_node_expr_eval_post_op_t
typedef int(* ec_node_expr_eval_post_op_t) (void **result, void *userctx, void *operand, const struct ec_pnode *operator)
Definition at line 55 of file node_expr.h.
ec_node_expr_eval_bin_op_t
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 62 of file node_expr.h.
ec_node_expr_eval_parenthesis_t
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 70 of file node_expr.h.
ec_node_expr_eval_free_t
typedef void(* ec_node_expr_eval_free_t) (void *result, void *userctx)
Definition at line 78 of file node_expr.h.
π Enumeration Type Documentation π
ec_node_dynlist_flags
enum ec_node_dynlist_flags
flags passed at ec_node_dynlist creation. flags are giving options, bestie. π
Enumerator
DYNLIST_MATCH_LISTβ match names returned by the user callback.DYNLIST_MATCH_REGEXPβ match names from regexp pattern.DYNLIST_EXCLUDE_LISTβ don't match names returned by the user callback, even if it matches the regexp.
Definition at line 39 of file node_dynlist.h.
β¨ FUNCTION DOCUMENTATION β¨
void ec_init_register (struct ec_init * test)
okay so this is the "hey bestie, run this when you init" registration vibe. You're registering an initialization function. π
Parameters:
testβ a pointer to aec_initstructure that you want to register. π
int ec_init (void )
This is the main character energy function. It initializes the ecoli library. You must call it before any other function from libecoli. No cap. π«Ά
Returns:
0on success-1on error (errnois set) π
void ec_exit (void )
Uninitialize ecoli library. That's it. It's giving cleanup era. π§Ή
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. π
Parameters:
typeβ The node type to be registered.overrideβ Allow the registration of an existing type.
Returns:
0on success- negative value on error π
const struct ec_node_type * ec_node_type_lookup (const char * name)
Lookup node type by name. Like a little search bar for node types. π
Parameters:
nameβ The name of the node type to search.
Returns:
- The (read-only) node type if found, or
NULLon error. πΈ
void ec_node_type_dump (FILE * out)
Dump registered log types. Yes, log types. That's what it says. π
Parameters:
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.
Parameters:
typeβ The node type.
Returns:
- The (read-only) config schema of the node type, or
NULLif the node type has no config schema. β¨
const char * ec_node_type_name (const struct ec_node_type * type)
Get the name of a node type.
Parameters:
typeβ The node type.
Returns:
- The (read-only) name of the node type. π
struct ec_node * ec_node_from_type (const struct ec_node_type * type, const char * id)
Create a new node from a known type β yes, the type is known. This function is typically called from the node constructor. π οΈ
Parameters:
typeβ The type of the node to create.idβ The node identifier.
Returns:
- The new node on success, or
NULLon error.
struct ec_node * ec_node (const char * typename, const char * id)
Create a new node from its type name. This function is typically called from user code, for node types that do not provide a specific constructor. π
Parameters:
typenameβ The type name of the node to create.idβ The node identifier.
Returns:
- The new node on success, or
NULLon error.
struct ec_node * ec_node_clone (struct ec_node * node)
Clone a grammar node. This function takes a reference to the node. If ec_node_free() is later called on this node, it will decrease only the reference. The free is effective when the reference count reaches 0. The reference counter is initialized to 1 at node creation. π
Parameters:
nodeβ The node to clone.
Returns:
- The pointer to the cloned node, always equal to the parameter. It returns
NULLif the parameter wasNULL: in this case, nothing is done. π
void ec_node_free (struct ec_node * node)
Decrement node reference counter and free the node if it is the last reference. Bye bye bestie. π
Parameters:
nodeβ The grammar node to free.
int ec_node_set_config (struct ec_node * node, struct ec_config * config)
Set node configuration. For a node that supports generic configuration, set its configuration.
After a call to this function, the config is owned by the node and must not be used by the caller anymore. So don't touch it, periodt. π«
Parameters:
nodeβ The grammar node to configure.configβ The configuration to apply on the node.
Returns:
0on success, or a negative value on error (in this case the config passed as parameter is freed). π¬
const struct ec_config * ec_node_get_config (const struct ec_node * node)
Get the current node configuration. For a node that supports generic configuration, get its configuration.
Parameters:
nodeβ The grammar node.
Returns:
- The generic node configuration on success, or
NULLon error. β¨
size_t ec_node_get_children_count (const struct ec_node * node)
Return the number of children for a node.
Parameters:
nodeβ The grammar node.
Returns:
- The number of children. πΆ
int ec_node_get_child (const struct ec_node * node, size_t i, struct ec_node ** child)
Get the n-th child of a node.
Parameters:
nodeβ The grammar node.iβ The index of the child node, that must be lower than the number of children.childβ The pointer where the child node pointer will be stored on success.
Returns:
- The number of children. (Yes, it says number of children. That's the vibe.) π
const struct ec_node_type * ec_node_type (const struct ec_node * node)
Get the type of a node.
Parameters:
nodeβ The grammar node.
Returns:
- The type structure of this node. π·οΈ
struct ec_dict * ec_node_attrs (const struct ec_node * node)
Get the attributes dict of the node. A user can add any attribute to a node. The attributes keys starting with an underscore are reserved. So don't touch keys that start with _, okay? π
ββοΈ
Parameters:
nodeβ The grammar node.
Returns:
- The attribute dictionary of this node. π
const char * ec_node_id (const struct ec_node * node)
Get node identifier.
Parameters:
nodeβ The grammar node.
Returns:
- The node identifier string. π
char * ec_node_desc (const struct ec_node * node)
Get node short description.
Parameters:
nodeβ The grammar node.
Returns:
- An allocated string containing the node short description that must be freed by the caller. Return
NULLon error. π§Ύ
void ec_node_dump (FILE * out, const struct ec_node * node)
Dump a grammar tree.
Parameters:
outβ The stream where the dump is sent.nodeβ The grammar tree to dump.
struct ec_node * ec_node_find (struct ec_node * node, const char * id)
Find a node from its identifier string. Browse the tree using pre-order depth traversal, and return the first node that matches the given identifier. π³
Parameters:
nodeβ The grammar tree.nodeβ The identifier to match. (Yes, it'snodeagain. We don't make the rules. π€·ββοΈ)
Returns:
- A node matching the identifier.
struct ec_node * ec_node_find_next (struct ec_node * root, const struct ec_node * prev, const char * id)
Find the next node matching an identifier. After a successful call to ec_node_find() or ec_node_find_next(), it is possible to get the next node that has the specified id. There are 2 options:
- continue the depth-first search where it was interrupted.
- skip the children of the current node, and continue the depth-first search.
Parameters:
rootβ The root of the search, as passed toec_node_find().prevβ The node returned by the previous search.idβ The node identifier string to match.
Returns:
- The next node matching the identifier, or
NULLif not found. π
int ec_node_check_type (const struct ec_node * node, const struct ec_node_type * type)
Check the type of a node.
Parameters:
nodeβ The grammar node.typeβ The pointer to the type structure.
Returns:
0if the node is of specified type, else-1. β
const char * ec_node_get_type_name (const struct ec_node * node)
Get the type name of a grammar node.
Parameters:
nodeβ The grammar node.
Returns:
- The type name of the node. π·οΈ
void * ec_node_priv (const struct ec_node * node)
Get the pointer to the node private area.
Parameters:
nodeβ The grammar node.
Returns:
- The pointer to the node private area. π
void ec_node_schema_dump (FILE * out, const struct ec_node * node)
Dump the node configuration schema.
Parameters:
outβ The stream where the dump is sent.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. π―
Parameters:
idβ The node identifier.attrβ The strvec attribute to match, orNULL.
Returns:
- The ecoli node. π
struct ec_node * ec_node_bypass (const char * id, struct ec_node * node)
A node that does nothing else than calling the child node. It can be helpful to build loops in a node graph. π
int ec_node_bypass_set_child (struct ec_node * gen_node, struct ec_node * child)
Attach a child to a bypass node.
struct ec_node * ec_node_cond (const char * id, const char * cond_str, struct ec_node * child)
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. π€
Parameters:
idβ The node identifier.cond_strβ The condition string. This is an function-based expression.childβ The ecoli child node.
Returns:
- The new ecoli cond 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_dynlist (const char * id, ec_node_dynlist_get_t get, void * opaque, const char * re_str, enum ec_node_dynlist_flags flags)
Create a dynlist node. The parsing and completion depends on a list returned by a user provided callback, a regular expression, and flags. π§
Parameters:
getβ The function that returns the list of object names as a string vector.opaqueβ A user pointer passed to the get function.re_strβ The regular expression defining the valid pattern for object names.flagsβ Customize parsing and completion behavior.
Returns:
- The dynlist grammar node, or
NULLon error. π
struct ec_node * ec_node_empty (const char * id)
This node always matches an empty string vector. π«
struct ec_node * ec_node_once (const char * id, struct ec_node * child)
This node behaves like its child, but prevent from parsing it several times. (Yes, "prevent". We keep the original grammar. π )
Example:
many(
or(
once(str("foo")),
str("bar")))
Matches: [], ["foo", "bar"], ["bar", "bar"], ["foo", "bar", "bar"], ... But not: ["foo", "foo"], ["foo", "bar", "foo"], ...
on error, child is not freed π
int ec_node_once_set_child (struct ec_node * node, struct ec_node * child)
on error, child is freed π
struct ec_node * ec_node_or (const char * id)
Create an empty "or" node. π
int ec_node_or_add (struct ec_node * node, struct ec_node * child)
Add a child to an "or" node. Child is consumed. π½οΈ
β¨ VARIABLE DOCUMENTATION β¨
struct ec_node_type_list node_type_list [extern]
The list of registered node types. Must not be modified by user, except at initialization using the EC_NODE_TYPE_REGISTER() or EC_NODE_TYPE_REGISTER_OVERRIDE() macros. π
π AUTHOR π
So who wrote this masterpiece? Bestie... it was the robot. π€β¨
This page was generated automatically by Doxygen for Libecoli from the source code. Not a human hand-typed word in sight β the docs literally wrote themselves from the code, which is iconic behaviour if you ask me. No mysterious author bio, no "thanks to my cat for emotional support", just pure automation doing its thing. π
Which means: if something's wrong here, the source code is the source of truth, iykyk. π¦
And that's a wrap on ecoli_nodes(3), bestie! π You read the whole thing. Every flag, every struct, every lil function β all of it. Slay. Go forth and build your ecoli nodes, you absolute main character. π
This page is from Libecoli, Version 0.10.1 β ecoli_nodes(3), brought to you by the fine folks at Doxygen doing their little autogeneration dance. π«ΆπΈ
Kisses, and may your node definitions always compile on the first try. πβ¨
π¦ where this page comes from
- fedora 43: libecoli-devel 0.10.1-1.fc43 Β· BSD-3-Clause AND LicenseRef-Fedora-Public-Domain
- fedora 43: libecoli-devel 0.10.1-1.fc43 Β· BSD-3-Clause AND LicenseRef-Fedora-Public-Domain
- fedora 44: libecoli-devel 0.10.1-2.fc44 Β· BSD-3-Clause AND LicenseRef-Fedora-Public-Domain
- fedora 44: libecoli-devel 0.10.1-2.fc44 Β· BSD-3-Clause AND LicenseRef-Fedora-Public-Domain
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms