- anything better than weakref?
- add get_max_parse_len() for all relevant nodes
- add ec_node_defaults.[ch] providing usual implementations of node methods
-- use vec for strvec
+X use vec for strvec
dependencies
============
logs
====
-- register log types
+X register log types
yaml
====
readline:
-[tab] list possible completions (matches only)
+[tab] list possible completions (matches/partial only)
[?] list what is expected, example:
"command [foo] toto|titi|<int>"
titi (help of titi)
<int> (help of int)
+
+----------------
+
+struct names
+============
+
+ideas:
+
+- ec_node: a node that can be parsed/completed
+- ec_parse: a tree describing the result of parse(node, input)
+- ec_comp: a list describing the result of complete(node, input)
+
+ec_comp_item
+
+
+---------------
+
+node tree
+=========
+
+Example:
+
+1 seq
+2 option
+3 str(foo)
+4 or
+5 int(1,10)
+6 str(bar)
+7 str(foo)
+
+parse() returns a tree
+=======
+
+- each node of the tree refers to a ec_node
+- each node points to the strvec that matches
+- parse returns the first matching solution
+- usually try to match as many str in the vecs (seq node)
+
+[foo] ->
+1 seq
+2 option
+4 or
+7 str(foo)
+
+The parse cb of the node is:
+
+parse_cb(node, current_parse_state, strvec, *nmatch)
+
+return values:
+- 0: success, child->strvec is set by node (NULL = no_match)
+- -1: error (errno is set)
+maybe complex to use:
+- the node must set it (ex: "return ec_parsed_node_match()")
+- the caller must use accessor to check if it matches or not
+
+alternative idea for return values:
+- >= 0: match, ret == nb_tk
+- -1: error (errno is set)
+- -2 or MAX_INT: success, but no match
+This is strange to have a specific value for no match
+
+alternative idea for return values:
+- ec_parse_result_match(n_tokens >= 0)
+- ec_parse_result_nomatch()
+- ec_parse_result_error(errno)
+
+A node always try to consume the maximum number of tokens.
+Example:
+1 seq
+2 option
+3 str(foo)
+4 str(foo)
+5 str(bar)
+
+[foo, foo, bar] matches
+[foo, bar] does *not* match
+
+complete() returns a list of possible completions
+==========
+
+problems:
+- partial completion: in a path dir/file, completion stops once
+ after the directory
+- displayed value is not the completion token: when completing a
+ file in several subdirectories, the full path is not displayed
+- any parent node can modify the completions, ex: add missing quotes
+ in ec_node_sh_lex(), filter completions in case of a ec_node_filter()
+- a command line may want to display the help from the most specific
+ token, or not.
+- some specific nodes can complete several tokens
+
+struct item {
+ const char *str;
+ type: full, partial, unknown
+}
+
+full: the completion item matches token
+partial: beginning of a completion, does not match the token
+ (good example is a directory in a path)
+unknown: could complete, but the node does not know how
+
+struct completed_elt {
+ ec_parsed *parse_tree; // current tree state
+ ec_node *last; // last node of the tree
+ list of items; // list of items for this parse tree
+}
+
+struct completed {
+ list(elt)
+}
+
+The callback is:
+
+complete_cb(node, current_complete_state, current_parse_state, strvec)
+return:
+- 0 = success, the current complete state is updated
+- -1 = error (set errno?)
+
+
+a node can filter the completions
+
+
+[] ->
+ foo 3 str(foo)
+ seq
+ option
+ str(foo) <-
+
+ ? 5 int(1,10)
+ seq
+ option
+ or
+ int <-
+
+ bar 6 str(bar)
+ foo 7 str(bar)
+...
+
+
+[foo, ] ->
+
+ ? 5 int(1,10)
+ seq
+ option
+ str(foo)
+ or
+ int <-
+
+ bar 6 str(bar)
+ foo 7 str(bar)
+
+
+
+-----
+
+changes:
+- a completion item should contain a strvec for the value
+ (the display string remains a string)
+- use a INT_MIN or a specific
+- there is maybe no good reason to split in:
+ - ec_completed_item()
+ - ec_completed_item_set()
+ - ec_completed_item_set_display()
+ - ec_completed_item_add()
+
+
+-----
+
+#include <stdio.h>
+#include <stdbool.h>
+
+
+struct res {
+ int a;
+};
+
+static inline bool is_success(struct res r)
+{
+ if (r.a == 0)
+ return true;
+ return false;
+}
+
+
+static inline struct res res(int a)
+{
+ struct res r;
+ r.a = a;
+ return r;
+}
+
+int main(void)
+{
+ struct res r;
+
+ r = res(0);
+
+ printf("%d\n", r.a);
+ if (is_success(r))
+ printf("success: %d\n", r.a);
+
+ r = res(1);
+
+ printf("%d\n", r.a);
+ if (is_success(r))
+ printf("success: %d\n", r.a);
+
+ return 0;
+}