cmd: add functions to report option/arg errors to the public API
This commit is contained in:
155
cmd/command.c
155
cmd/command.c
@@ -55,10 +55,10 @@ static void command_usage_destroy(struct b_command_usage *usage)
|
||||
{
|
||||
struct b_queue_iterator it = {0};
|
||||
|
||||
b_queue_iterator_begin(&usage->u_arg, &it);
|
||||
b_queue_iterator_begin(&usage->u_parts, &it);
|
||||
while (b_queue_iterator_is_valid(&it)) {
|
||||
struct b_command_usage_arg *arg = b_unbox(
|
||||
struct b_command_usage_arg, it.entry, arg_entry);
|
||||
struct b_command_usage_entry *arg = b_unbox(
|
||||
struct b_command_usage_entry, it.entry, e_entry);
|
||||
if (!arg) {
|
||||
continue;
|
||||
}
|
||||
@@ -67,18 +67,6 @@ static void command_usage_destroy(struct b_command_usage *usage)
|
||||
free(arg);
|
||||
}
|
||||
|
||||
b_queue_iterator_begin(&usage->u_opt, &it);
|
||||
while (b_queue_iterator_is_valid(&it)) {
|
||||
struct b_command_usage_opt *opt = b_unbox(
|
||||
struct b_command_usage_opt, it.entry, opt_entry);
|
||||
if (!opt) {
|
||||
continue;
|
||||
}
|
||||
|
||||
b_queue_iterator_erase(&it);
|
||||
free(opt);
|
||||
}
|
||||
|
||||
free(usage);
|
||||
}
|
||||
|
||||
@@ -277,47 +265,50 @@ struct b_command_usage *b_command_add_usage(struct b_command *cmd)
|
||||
b_status b_command_usage_add_option(
|
||||
struct b_command_usage *usage, struct b_command_option *opt)
|
||||
{
|
||||
struct b_command_usage_opt *u_opt = malloc(sizeof *u_opt);
|
||||
struct b_command_usage_entry *u_opt = malloc(sizeof *u_opt);
|
||||
if (!u_opt) {
|
||||
return B_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
memset(u_opt, 0x0, sizeof *u_opt);
|
||||
|
||||
u_opt->opt = opt;
|
||||
u_opt->e_type = CMD_USAGE_OPT;
|
||||
u_opt->e_opt = opt;
|
||||
|
||||
b_queue_push_back(&usage->u_opt, &u_opt->opt_entry);
|
||||
b_queue_push_back(&usage->u_parts, &u_opt->e_entry);
|
||||
return B_SUCCESS;
|
||||
}
|
||||
|
||||
b_status b_command_usage_add_arg(
|
||||
struct b_command_usage *usage, struct b_command_arg *arg)
|
||||
{
|
||||
struct b_command_usage_arg *u_arg = malloc(sizeof *u_arg);
|
||||
struct b_command_usage_entry *u_arg = malloc(sizeof *u_arg);
|
||||
if (!u_arg) {
|
||||
return B_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
memset(u_arg, 0x0, sizeof *u_arg);
|
||||
|
||||
u_arg->arg = arg;
|
||||
u_arg->e_type = CMD_USAGE_ARG;
|
||||
u_arg->e_arg = arg;
|
||||
|
||||
b_queue_push_back(&usage->u_arg, &u_arg->arg_entry);
|
||||
b_queue_push_back(&usage->u_parts, &u_arg->e_entry);
|
||||
return B_SUCCESS;
|
||||
}
|
||||
|
||||
b_status b_command_usage_add_command(b_command_usage *usage, unsigned int cmd_id)
|
||||
{
|
||||
struct b_command_usage_command *u_cmd = malloc(sizeof *u_cmd);
|
||||
struct b_command_usage_entry *u_cmd = malloc(sizeof *u_cmd);
|
||||
if (!u_cmd) {
|
||||
return B_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
memset(u_cmd, 0x0, sizeof *u_cmd);
|
||||
|
||||
u_cmd->cmd_id = cmd_id;
|
||||
u_cmd->e_type = CMD_USAGE_COMMAND;
|
||||
u_cmd->e_cmd_id = cmd_id;
|
||||
|
||||
b_queue_push_back(&usage->u_cmd, &u_cmd->cmd_entry);
|
||||
b_queue_push_back(&usage->u_parts, &u_cmd->e_entry);
|
||||
return B_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -381,66 +372,52 @@ static void get_usage_string(
|
||||
struct b_string *cmd_name = b_string_create();
|
||||
|
||||
b_queue_iterator it;
|
||||
b_queue_foreach (&it, &usage->u_cmd) {
|
||||
struct b_command_usage_command *subcmd = b_unbox(
|
||||
struct b_command_usage_command, it.entry, cmd_entry);
|
||||
b_queue_foreach (&it, &usage->u_parts) {
|
||||
struct b_command_usage_entry *entry = b_unbox(
|
||||
struct b_command_usage_entry, it.entry, e_entry);
|
||||
|
||||
if (!subcmd) {
|
||||
if (!entry) {
|
||||
break;
|
||||
}
|
||||
|
||||
b_string_clear(cmd_name);
|
||||
b_string_append_cstr(out, " ");
|
||||
|
||||
if (subcmd->cmd_id == B_COMMAND_INVALID_ID) {
|
||||
b_string_append_cstr(out, "[COMMAND]");
|
||||
} else {
|
||||
switch (entry->e_type) {
|
||||
case CMD_USAGE_ARG:
|
||||
if (entry->e_arg) {
|
||||
z__b_get_arg_usage_string(entry->e_arg, false, out);
|
||||
} else {
|
||||
b_string_append_cstr(out, "[[ARGS]");
|
||||
}
|
||||
break;
|
||||
case CMD_USAGE_OPT:
|
||||
if (entry->e_opt) {
|
||||
z__b_get_option_usage_string(
|
||||
entry->e_opt, CMD_STR_DIRECT_USAGE, out);
|
||||
} else {
|
||||
b_string_append_cstr(out, "[[OPTIONS]");
|
||||
}
|
||||
|
||||
break;
|
||||
case CMD_USAGE_COMMAND:
|
||||
if (entry->e_cmd_id == B_COMMAND_INVALID_ID) {
|
||||
b_string_append_cstr(out, "[[COMMAND]");
|
||||
break;
|
||||
}
|
||||
|
||||
struct b_command *subcmd_info
|
||||
= get_command(&command_list, subcmd->cmd_id);
|
||||
= get_command(&command_list, entry->e_cmd_id);
|
||||
prepend_command_name(subcmd_info, cmd_name);
|
||||
|
||||
b_string_append_s(out, cmd_name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
b_string_release(cmd_name);
|
||||
|
||||
b_queue_foreach (&it, &usage->u_opt) {
|
||||
struct b_command_usage_opt *opt = b_unbox(
|
||||
struct b_command_usage_opt, it.entry, opt_entry);
|
||||
|
||||
if (!opt) {
|
||||
break;
|
||||
}
|
||||
|
||||
b_string_append_cstr(out, " ");
|
||||
|
||||
if (opt->opt
|
||||
== (struct b_command_option *)(uintptr_t)B_COMMAND_INVALID_ID) {
|
||||
b_string_append_cstr(out, "[OPTIONS]");
|
||||
} else {
|
||||
z__b_get_option_usage_string(
|
||||
opt->opt, CMD_STR_DIRECT_USAGE, out);
|
||||
}
|
||||
}
|
||||
|
||||
b_queue_foreach (&it, &usage->u_arg) {
|
||||
struct b_command_usage_arg *arg = b_unbox(
|
||||
struct b_command_usage_arg, it.entry, arg_entry);
|
||||
|
||||
if (!arg) {
|
||||
break;
|
||||
}
|
||||
|
||||
b_string_append_cstr(out, " ");
|
||||
|
||||
if (arg->arg
|
||||
== (struct b_command_arg *)(uintptr_t)B_COMMAND_INVALID_ID) {
|
||||
b_string_append_cstr(out, "[ARGS]");
|
||||
} else {
|
||||
z__b_get_arg_usage_string(arg->arg, false, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b_string *z__b_command_default_usage_string(
|
||||
@@ -833,6 +810,44 @@ struct b_command_option *b_command_get_option_with_short_name(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct b_command_option *b_command_get_option_with_id(
|
||||
struct b_command *cmd, unsigned int id)
|
||||
{
|
||||
b_queue_iterator it;
|
||||
b_queue_foreach (&it, &cmd->b_opt) {
|
||||
struct b_command_option *opt
|
||||
= b_unbox(struct b_command_option, it.entry, opt_entry);
|
||||
if (!opt) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opt->opt_id == id) {
|
||||
return opt;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct b_command_arg *b_command_get_arg_with_id(
|
||||
struct b_command *cmd, unsigned int id)
|
||||
{
|
||||
b_queue_iterator it;
|
||||
b_queue_foreach (&it, &cmd->b_arg) {
|
||||
struct b_command_arg *arg
|
||||
= b_unbox(struct b_command_arg, it.entry, arg_entry);
|
||||
if (!arg) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg->arg_id == id) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void print_usage(struct b_command *cmd)
|
||||
{
|
||||
b_paragraph_format format = {0};
|
||||
@@ -963,6 +978,8 @@ int b_command_dispatch(unsigned int cmd_id, int argc, const char **argv)
|
||||
}
|
||||
|
||||
struct b_arglist *args = b_arglist_create();
|
||||
args->list_command = cmd;
|
||||
|
||||
b_status status = b_arglist_parse(args, &cmd, argc, argv);
|
||||
if (B_ERR(status)) {
|
||||
b_arglist_destroy(args);
|
||||
|
||||
Reference in New Issue
Block a user