1 #define COUNT_OF(x) \
2 	((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
3 
4 enum launch_mode {
5 	LAUNCH_UNSET = 0,
6 	LAUNCH_VT100 = 1,
7 	LAUNCH_TUI   = 2,
8 	LAUNCH_WL    = 3,
9 	LAUNCH_X11   = 4,
10 	LAUNCH_SHMIF = 5
11 };
12 
13 struct ext_cmd {
14 	uint32_t id;
15 	int flags;
16 	char** argv;
17 	char** env;
18 	char* wd;
19 	enum launch_mode mode;
20 	bool stall;
21 	void(*closure)(uintptr_t);
22 	uintptr_t closure_tag;
23 };
24 
25 struct cli_state {
26 	char** env;
27 	char* cwd;
28 	enum launch_mode mode;
29 	bool alive;
30 	uint8_t bgalpha;
31 
32 /* set alive to false when last pending ext_cmd has been finished */
33 	bool die_on_finish;
34 
35 	uint32_t id_counter;
36 	struct ext_cmd pending[4];
37 	bool blocked;
38 	char* in_debug;
39 	struct tui_cell* prompt;
40 	size_t prompt_sz;
41 };
42 
43 struct cli_command {
44 	const char* name;
45 	struct ext_cmd* (*exec)(
46 		struct cli_state* state, char** argv, ssize_t* ofs, char** err);
47 
48 /* expect for the first argument, this follows the structure of tui cli_command
49  * for help with completion / expansion */
50 	int (*cli_command)(struct cli_state* state,
51 		const char** const argv, size_t n_elem, int command,
52 		const char** feedback, size_t* n_results);
53 };
54 
55 /*
56  * return the built-in CLI command matching (exec)
57  */
58 struct cli_command* cli_get_builtin(const char* cmd);
59 
60 /*
61  * split up message into a dynamically allocated array of dynamic
62  * strings according to the following rules:
63  *
64  * global-state:
65  *  \ escapes next character
66  *    ends argument
67  *
68  * group_tbl (string of possible group characters, e.g. "'`),
69  *           ends with an empty group (.enter == 0)
70  *
71  * character in group_tbl begins and ends a nested expansion that
72  * will be expanded according to the expand callback and the group.
73  *
74  * the returned string will be added to the resulting string table
75  * verbatim.
76  */
77 struct group_ent;
78 struct group_ent {
79 	char enter;
80 	char leave;
81 	bool leave_eol;
82 	char* (*expand)(struct group_ent*, const char*);
83 };
84 
85 struct argv_parse_opt {
86 	size_t prepad;
87 	struct group_ent* groups;
88 	char sep;
89 };
90 
91 char** extract_argv(const char* message,
92 	struct argv_parse_opt opts, ssize_t* err_ofs);
93