save state in completed objects
[protos/libecoli.git] / lib / todo.txt
1 tk_cmd
2 ======
3
4 X evaluate expression tree in ec_tk_expr
5 X cmd token
6 - example
7 X tk_re
8
9 cleanup / rework
10 ================
11
12 - ec_completed_item_update()
13 - ec_completed_item_set_display_value()
14
15 - add_no_match
16 - add_partial_match
17 - check XXX in code
18 - properly manage quotes in shlex
19 X remove the _new() functions
20 - iterate children nodes without chaining them
21 - add a tk vector type: will be used in several nodes (ex: or, seq, ...)
22 - check allocation model everywhere
23 - checkpatch?
24 - use linux style (update .emacs)
25 - better logs
26 - return values
27 - use errno when returning pointers
28 - missing static / const
29 - license: "s/neither the name...may/the names of its contributors may not/"
30 - check all completion nodes
31 X split ecoli_tk.h
32 - cache results when appropriate?
33 - size_t or unsigned int?
34 X rename:
35   X ec_tk -> ec_node
36   X ec_parsed_tk -> ec_parsed
37   X ec_completed_tk -> ec_completed
38   X tk, gen_tk, token, ... -> node
39   X tokens -> input_str / input_strvec ?
40 - use is_err() or errno for funcs returning ptrs, or use errno for all funcs
41 - save node path in completion to fix help string
42 - code coverage
43 - try to hide structures
44 - anything better than weakref?
45 - add get_max_parse_len() for all relevant nodes
46 - add ec_node_defaults.[ch] providing usual implementations of node methods
47 X use vec for strvec
48
49 dependencies
50 ============
51
52 X pass the current parsed state when parsing/completing
53 X new node "once"
54 - new node "condition"
55
56 logs
57 ====
58
59 X register log types
60
61 yaml
62 ====
63
64 X register nodes by name
65 - interface to add attributes: all nodes must be configurable through a
66   generic api
67   - attr string
68   - attr string list
69   - attr node
70   - attr node list
71   - attr int
72
73 - yaml interface to create nodes
74 - example
75
76 examples
77 ========
78
79 - example which parses arguments (argc/argv)
80 - example that acts as bash completion (ip link ?)
81 - calculator example (var assignation, expression evaluation)
82 - example with libedit
83 - mini script language
84 - configuration file
85 - mini shell: cd, ls, cat, stat
86 - mini network console based on ip
87
88 doc
89 ===
90
91 - overview
92 - add api doc in .h
93 - generate automatic api doc
94 - architecture
95 - coding rules, process
96 - each node
97 - allocation model
98 - say that it stops at first match (no ambigous support)
99 - say that completion must be exhaustive
100
101 build framework
102 ===============
103
104 - .map files for API
105 - split libs, tests and examples
106 - add make help
107 - add make config
108 - -fvisibility=
109
110 tests
111 =====
112
113 - complete automatic tests with "make test"
114
115 new nodes
116 =========
117
118 - regexp
119 - node which always matches
120 - file + partial completion
121 - ether, ip, network
122 - fusion node: need to match several children, same for completion
123 - float
124 - not
125
126 encoding
127 ========
128
129 - support utf-8 and other encodings
130 - example
131 - documentation
132
133 netconf example
134 ===============
135
136 - demonstration example that parses yang file and generate cli
137
138
139
140 -----------------------
141
142 readline:
143
144 [tab]  list possible completions (matches/partial only)
145 [?]    list what is expected, example:
146
147 "command [foo] toto|titi|<int>"
148
149 help("command f") ->
150   foo     (help of foo)
151   toto    (help of toto)
152   titi    (help of titi)
153   <int>   (help of int)
154
155
156 ----------------
157
158 struct names
159 ============
160
161 ideas:
162
163 - ec_node: a node that can be parsed/completed
164 - ec_parse: a tree describing the result of parse(node, input)
165 - ec_comp: a list describing the result of complete(node, input)
166
167 ec_comp_item
168
169
170 ---------------
171
172 node tree
173 =========
174
175 Example:
176
177 1  seq
178 2    option
179 3      str(foo)
180 4    or
181 5      int(1,10)
182 6      str(bar)
183 7      str(foo)
184
185 parse() returns a tree
186 =======
187
188 - each node of the tree refers to a ec_node
189 - each node points to the strvec that matches
190 - parse returns the first matching solution
191 - usually try to match as many str in the vecs (seq node)
192
193 [foo] ->
194 1 seq
195 2   option
196 4   or
197 7     str(foo)
198
199 The parse cb of the node is:
200
201 parse_cb(node, current_parse_state, strvec, *nmatch)
202
203 return values:
204 - 0: success, child->strvec is set by node (NULL = no_match)
205 - -1: error (errno is set)
206 maybe complex to use:
207 - the node must set the match (ex: "return ec_parsed_node_match()")
208 - the caller must use accessor to check if it matches or not
209
210 alternative idea for return values:
211 - >= 0: match, ret == nb_tk
212 - -1: error (errno is set)
213 - -2 or MAX_INT: success, but no match
214 This is strange to have a specific value for no match
215 With MAX_INT, this is the best (less bad) alternative
216
217 alternative idea for return values:
218 - ec_parse_result_match(n_tokens >= 0)
219 - ec_parse_result_nomatch()
220 - ec_parse_result_error(errno)
221
222 A node always try to consume the maximum number of tokens.
223 Example:
224 1  seq
225 2    option
226 3      str(foo)
227 4    str(foo)
228 5    str(bar)
229
230 [foo, foo, bar] matches
231 [foo, bar] does *not* match
232
233 complete() returns a list of possible completions
234 ==========
235
236 problems:
237 - partial completion: in a path dir/file, completion stops once
238   after the directory
239 - displayed value is not the completion token: when completing a
240   file in several subdirectories, the full path is not displayed
241 - any parent node can modify the completions, ex: add missing quotes
242   in ec_node_sh_lex(), filter completions in case of a ec_node_filter()
243 - a command line may want to display the help from the most specific
244   token, or not.
245 - some specific nodes can complete several tokens
246
247 struct item {
248   const char *str;
249   type: full, partial, unknown
250 }
251
252 full: the completion item matches token
253 partial: beginning of a completion, does not match the token
254          (good example is a directory in a path)
255 unknown: could complete, but the node does not know how
256
257 struct completion_item {
258   const char *value;
259   const char *disp;
260 }
261
262 struct completed_elt {
263   ec_parsed *parse_tree; // current tree state
264   ec_node *last;         // last node of the tree
265   list of items;         // list of items for this parse tree
266 }
267
268 struct completed {
269   list(elt)
270 }
271
272 The callback is:
273
274 complete_cb(node, current_complete_state, current_parse_state, strvec)
275 return:
276 - 0 = success, the current complete state is updated
277 - -1 = error (set errno?)
278
279
280 a node can filter the completions
281
282
283 [] ->
284   foo   3 str(foo)
285     seq
286       option
287         str(foo) <-
288
289   ""    5 int(1,10)
290     seq
291       option
292       or
293         int <-
294
295   bar   6 str(bar)
296   foo   7 str(bar)
297 ...
298
299
300 [foo, ] ->
301
302   ?       5 int(1,10)
303   seq
304     option
305       str(foo)
306     or
307       int <-
308
309   bar   6 str(bar)
310   foo   7 str(bar)
311
312
313
314 -----
315
316 changes:
317 - a completion item should contain a strvec for the value
318   (the display string remains a string)
319 - there is maybe no good reason to split in:
320   - ec_completed_item()
321   - ec_completed_item_set()
322   - ec_completed_item_set_display()
323   - ec_completed_item_add()
324
325
326 -----
327
328 #include <stdio.h>
329 #include <stdbool.h>
330
331
332 struct res {
333         int a;
334 };
335
336 static inline bool is_success(struct res r)
337 {
338         if (r.a == 0)
339                 return true;
340         return false;
341 }
342
343
344 static inline struct res res(int a)
345 {
346         struct res r;
347         r.a = a;
348         return r;
349 }
350
351 int main(void)
352 {
353         struct res r;
354
355         r = res(0);
356
357         printf("%d\n", r.a);
358         if (is_success(r))
359                 printf("success: %d\n", r.a);
360
361         r = res(1);
362
363         printf("%d\n", r.a);
364         if (is_success(r))
365                 printf("success: %d\n", r.a);
366
367         return 0;
368 }