Prepare for handling descriptions
This commit is contained in:
+44
-30
@@ -24,7 +24,7 @@ enum UCCmdRc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct UCCmdArgs;
|
struct UCCmdArgs;
|
||||||
typedef enum UCCmdRc (*uc_cmd_handler)(const struct UCCmdArgs *args);
|
typedef enum UCCmdRc (*UCCmdHandler)(const struct UCCmdArgs *args);
|
||||||
|
|
||||||
enum UCCmdType {
|
enum UCCmdType {
|
||||||
UC_CMD_ROOT = 1,
|
UC_CMD_ROOT = 1,
|
||||||
@@ -34,6 +34,15 @@ enum UCCmdType {
|
|||||||
UC_CMD_END,
|
UC_CMD_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UCCmdWord {
|
||||||
|
char *word;
|
||||||
|
char *descr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdList {
|
||||||
|
struct UCStrv words;
|
||||||
|
struct UCStrv descrs;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command are broken into words and inserted into a tree.
|
* Command are broken into words and inserted into a tree.
|
||||||
@@ -56,18 +65,16 @@ enum UCCmdType {
|
|||||||
*/
|
*/
|
||||||
struct UCCmdNode {
|
struct UCCmdNode {
|
||||||
enum UCCmdType type;
|
enum UCCmdType type;
|
||||||
|
union {
|
||||||
|
struct UCCmdWord word;
|
||||||
|
struct UCCmdList list;
|
||||||
|
struct UCCmdDef *cmd;
|
||||||
|
} data;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
void *data;
|
|
||||||
struct UCCmdNode *next; //next at same level
|
struct UCCmdNode *next; //next at same level
|
||||||
struct UCCmdNode *child;
|
struct UCCmdNode *child;
|
||||||
};
|
};
|
||||||
|
|
||||||
//for UC_CMD_LIST,
|
|
||||||
struct UCCmdList {
|
|
||||||
char *word;
|
|
||||||
struct UCCmdList *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct UCCmdRunner {
|
struct UCCmdRunner {
|
||||||
struct UCCmdNode *root_node;
|
struct UCCmdNode *root_node;
|
||||||
struct UCCmdNode _root;
|
struct UCCmdNode _root;
|
||||||
@@ -75,10 +82,9 @@ struct UCCmdRunner {
|
|||||||
|
|
||||||
struct UCCmdDef {
|
struct UCCmdDef {
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
uc_cmd_handler callback;
|
const char *help;
|
||||||
|
UCCmdHandler callback;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
struct UCCmdDef *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -149,12 +155,14 @@ uc_cmd_node_dealloc(struct UCCmdNode *n)
|
|||||||
uc_cmd_node_dealloc(n->child);
|
uc_cmd_node_dealloc(n->child);
|
||||||
next = n->next;
|
next = n->next;
|
||||||
if (n->type == UC_CMD_KEYWORD) {
|
if (n->type == UC_CMD_KEYWORD) {
|
||||||
free(n->data);
|
free(n->data.word.word);
|
||||||
|
free(n->data.word.descr);
|
||||||
} else if (n->type == UC_CMD_LIST) {
|
} else if (n->type == UC_CMD_LIST) {
|
||||||
uc_strv_destroy(n->data);
|
uc_strv_destroy(&n->data.list.words);
|
||||||
free(n->data);
|
uc_strv_destroy(&n->data.list.descrs);
|
||||||
} else if (n->type == UC_CMD_STRING) {
|
} else if (n->type == UC_CMD_STRING) {
|
||||||
free(n->data);
|
free(n->data.word.word);
|
||||||
|
free(n->data.word.descr);
|
||||||
}
|
}
|
||||||
free(n);
|
free(n);
|
||||||
n = next;
|
n = next;
|
||||||
@@ -169,7 +177,7 @@ uc_cmd_runner_destroy(struct UCCmdRunner *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct UCCmdNode *
|
static struct UCCmdNode *
|
||||||
uc_cmd_node_alloc(enum UCCmdType type, void *data, uint32_t flags)
|
uc_cmd_node_alloc(enum UCCmdType type, uint32_t flags)
|
||||||
{
|
{
|
||||||
struct UCCmdNode *n;
|
struct UCCmdNode *n;
|
||||||
|
|
||||||
@@ -179,7 +187,6 @@ uc_cmd_node_alloc(enum UCCmdType type, void *data, uint32_t flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
n->type = type;
|
n->type = type;
|
||||||
n->data = data;
|
|
||||||
n->flags = flags;
|
n->flags = flags;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
@@ -195,21 +202,23 @@ uc_cmd_node_create(const char *word)
|
|||||||
|
|
||||||
uc_cmd_tokenize(&t, word, "() |\t\v");
|
uc_cmd_tokenize(&t, word, "() |\t\v");
|
||||||
if (t.num_words > 0) {
|
if (t.num_words > 0) {
|
||||||
struct UCStrv *v = malloc(sizeof *v);
|
node = uc_cmd_node_alloc(UC_CMD_LIST, 0);
|
||||||
|
|
||||||
uc_strv_init(v);
|
uc_strv_init(&node->data.list.words);
|
||||||
|
uc_strv_init(&node->data.list.descrs);
|
||||||
|
|
||||||
for (int i = 0 ; i < t.num_words; i++) {
|
for (int i = 0 ; i < t.num_words; i++) {
|
||||||
uc_strv_append(v, t.cmd_words[i]);
|
uc_strv_append(&node->data.list.words, t.cmd_words[i]);
|
||||||
}
|
}
|
||||||
node = uc_cmd_node_alloc(UC_CMD_LIST, v, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uc_cmd_tokenize_destroy(&t);
|
uc_cmd_tokenize_destroy(&t);
|
||||||
} else if (isupper(word[0])) {
|
} else if (isupper(word[0])) {
|
||||||
node = uc_cmd_node_alloc(UC_CMD_STRING, strdup(word), 0);
|
node = uc_cmd_node_alloc(UC_CMD_STRING, 0);
|
||||||
|
node->data.word.word = strdup(word);
|
||||||
} else {
|
} else {
|
||||||
node = uc_cmd_node_alloc(UC_CMD_KEYWORD, strdup(word), 0);
|
node = uc_cmd_node_alloc(UC_CMD_KEYWORD, 0);
|
||||||
|
node->data.word.word = strdup(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
@@ -229,14 +238,14 @@ uc_cmd_node_match(const struct UCCmdNode *n, const char *word, struct UCStrv *ar
|
|||||||
|
|
||||||
if (n->type == UC_CMD_KEYWORD) {
|
if (n->type == UC_CMD_KEYWORD) {
|
||||||
|
|
||||||
if (strncmp(word, n->data, word_len) == 0) {
|
if (strncmp(word, n->data.word.word, word_len) == 0) {
|
||||||
if (args != NULL) {
|
if (args != NULL) {
|
||||||
uc_strv_append(args, n->data);
|
uc_strv_append(args, n->data.word.word);
|
||||||
}
|
}
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
} else if (n->type == UC_CMD_LIST) {
|
} else if (n->type == UC_CMD_LIST) {
|
||||||
struct UCStrv *v = n->data;
|
const struct UCStrv *v = &n->data.list.words;
|
||||||
|
|
||||||
assert(v);
|
assert(v);
|
||||||
|
|
||||||
@@ -318,11 +327,12 @@ uc_cmd_install_noassert(struct UCCmdRunner *r, struct UCCmdDef *cmd)
|
|||||||
|
|
||||||
//TODO, check for duplicate command here.
|
//TODO, check for duplicate command here.
|
||||||
|
|
||||||
new_node = uc_cmd_node_alloc(UC_CMD_END, cmd, 0);
|
new_node = uc_cmd_node_alloc(UC_CMD_END, 0);
|
||||||
if (new_node == NULL) {
|
if (new_node == NULL) {
|
||||||
uc_cmd_tokenize_destroy(&t);
|
uc_cmd_tokenize_destroy(&t);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
new_node->data.cmd = cmd;
|
||||||
new_node->next = node->child;
|
new_node->next = node->child;
|
||||||
node->child = new_node;
|
node->child = new_node;
|
||||||
|
|
||||||
@@ -428,10 +438,10 @@ uc_cmd_complete(struct UCCmdRunner *r, const char *cmd_line)
|
|||||||
if (node->type == UC_CMD_END) {
|
if (node->type == UC_CMD_END) {
|
||||||
uc_strv_append(&completions, "<CR>");
|
uc_strv_append(&completions, "<CR>");
|
||||||
} else if (node->type == UC_CMD_LIST) {
|
} else if (node->type == UC_CMD_LIST) {
|
||||||
uc_strv_append_all(&completions, node->data, 1);
|
uc_strv_append_all(&completions, &node->data.list.words, 1);
|
||||||
} else if (node->type == UC_CMD_STRING ||
|
} else if (node->type == UC_CMD_STRING ||
|
||||||
node->type == UC_CMD_KEYWORD) {
|
node->type == UC_CMD_KEYWORD) {
|
||||||
uc_strv_append(&completions, node->data);
|
uc_strv_append(&completions, node->data.word.word);
|
||||||
}
|
}
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
@@ -472,7 +482,7 @@ uc_cmd_run(struct UCCmdRunner *r, const char *cmd_line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
struct UCCmdDef *cmd = found->data;
|
struct UCCmdDef *cmd = found->data.cmd;
|
||||||
args.cmd = cmd;
|
args.cmd = cmd;
|
||||||
rc = cmd->callback(&args);
|
rc = cmd->callback(&args);
|
||||||
} else {
|
} else {
|
||||||
@@ -536,6 +546,7 @@ int main(int argc, char *argv[])
|
|||||||
struct UCCmdRunner r;
|
struct UCCmdRunner r;
|
||||||
struct UCCmdDef cmd1 = {
|
struct UCCmdDef cmd1 = {
|
||||||
"show all",
|
"show all",
|
||||||
|
"\n\n",
|
||||||
cmd1_cb,
|
cmd1_cb,
|
||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
@@ -543,6 +554,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
struct UCCmdDef cmd2 = {
|
struct UCCmdDef cmd2 = {
|
||||||
"show empty",
|
"show empty",
|
||||||
|
"\n\n",
|
||||||
cmd2_cb,
|
cmd2_cb,
|
||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
@@ -550,6 +562,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
struct UCCmdDef cmd3 = {
|
struct UCCmdDef cmd3 = {
|
||||||
"show empty bottle",
|
"show empty bottle",
|
||||||
|
"\n\n\n",
|
||||||
cmd3_cb,
|
cmd3_cb,
|
||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
@@ -557,6 +570,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
struct UCCmdDef cmd4 = {
|
struct UCCmdDef cmd4 = {
|
||||||
"delete file NAME",
|
"delete file NAME",
|
||||||
|
"\n\nName of the file\n",
|
||||||
cmd4_cb,
|
cmd4_cb,
|
||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
|
|||||||
Reference in New Issue
Block a user