cmd: add functions to report option/arg errors to the public API
This commit is contained in:
193
cmd/report.c
Normal file
193
cmd/report.c
Normal file
@@ -0,0 +1,193 @@
|
||||
#include "command.h"
|
||||
|
||||
#include <blue/core/stringstream.h>
|
||||
#include <blue/object/string.h>
|
||||
#include <blue/term/print.h>
|
||||
#include <stdio.h>
|
||||
|
||||
enum b_status b_arglist_report_missing_option(
|
||||
const b_arglist *args, unsigned int opt_id)
|
||||
{
|
||||
struct b_command_option *opt = NULL;
|
||||
|
||||
if (opt_id != B_COMMAND_INVALID_ID) {
|
||||
opt = b_command_get_option_with_id(args->list_command, opt_id);
|
||||
}
|
||||
|
||||
if (!opt) {
|
||||
return B_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
struct b_string *opt_string = b_string_create();
|
||||
z__b_get_option_usage_string(opt, 0, opt_string);
|
||||
|
||||
char opt_name_s[128];
|
||||
struct b_stringstream opt_name;
|
||||
b_stringstream_begin(&opt_name, opt_name_s, sizeof opt_name_s);
|
||||
|
||||
int opt_names = 0;
|
||||
if (opt->opt_short_name) {
|
||||
opt_names++;
|
||||
}
|
||||
|
||||
if (opt->opt_long_name) {
|
||||
opt_names++;
|
||||
}
|
||||
|
||||
if (opt_names == 2) {
|
||||
b_stringstream_addf(
|
||||
&opt_name, "-%c / --%s", opt->opt_short_name,
|
||||
opt->opt_long_name);
|
||||
} else if (opt->opt_short_name) {
|
||||
b_stringstream_addf(&opt_name, "-%c", opt->opt_short_name);
|
||||
} else if (opt->opt_long_name) {
|
||||
b_stringstream_addf(&opt_name, "--%s", opt->opt_long_name);
|
||||
}
|
||||
|
||||
b_err("required option `" F_YELLOW "%s" F_RESET "` was not specified.",
|
||||
opt_name_s);
|
||||
b_i("usage: %s", b_string_ptr(opt_string));
|
||||
b_i("for more information, use `" F_YELLOW "--help" F_RESET "`");
|
||||
|
||||
b_string_release(opt_string);
|
||||
|
||||
return B_SUCCESS;
|
||||
}
|
||||
|
||||
enum b_status b_arglist_report_unexpected_arg(
|
||||
const b_arglist *args, const char *value)
|
||||
{
|
||||
struct b_string *usage
|
||||
= z__b_command_default_usage_string(args->list_command, NULL);
|
||||
|
||||
b_err("unexpected argument '" F_YELLOW "%s" F_RESET "' found.", value);
|
||||
b_i("usage: %s", b_string_ptr(usage));
|
||||
b_i("for more information, use '" F_YELLOW "--help" F_RESET "'");
|
||||
|
||||
return B_SUCCESS;
|
||||
}
|
||||
|
||||
enum b_status b_arglist_report_invalid_arg_value(
|
||||
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
|
||||
const char *value)
|
||||
{
|
||||
struct b_command_option *opt = NULL;
|
||||
struct b_command_arg *arg = NULL;
|
||||
|
||||
if (opt_id != B_COMMAND_INVALID_ID) {
|
||||
opt = b_command_get_option_with_id(args->list_command, opt_id);
|
||||
}
|
||||
|
||||
if (arg_id != B_COMMAND_INVALID_ID) {
|
||||
arg = opt ? b_command_option_get_arg_with_id(opt, arg_id)
|
||||
: b_command_get_arg_with_id(args->list_command, arg_id);
|
||||
}
|
||||
|
||||
struct b_string *usage
|
||||
= z__b_command_default_usage_string(args->list_command, opt);
|
||||
struct b_string *opt_string = b_string_create();
|
||||
|
||||
if (opt) {
|
||||
z__b_get_option_usage_string(opt, 0, opt_string);
|
||||
} else {
|
||||
z__b_get_arg_usage_string(arg, 0, opt_string);
|
||||
}
|
||||
|
||||
b_err("invalid value '" F_YELLOW "%s" F_RESET "' for '" F_YELLOW
|
||||
"%s" F_RESET "'.",
|
||||
value, b_string_ptr(opt_string));
|
||||
|
||||
if (opt) {
|
||||
b_i("'" F_YELLOW "%s" F_RESET
|
||||
"' accepts the following values for '" F_YELLOW "%s" F_RESET
|
||||
"':",
|
||||
b_string_ptr(opt_string), arg->arg_name);
|
||||
} else {
|
||||
b_i("'" F_YELLOW "%s" F_RESET "' accepts the following values:",
|
||||
b_string_ptr(opt_string));
|
||||
}
|
||||
|
||||
for (int i = 0; arg->arg_allowed_values[i]; i++) {
|
||||
b_printf(
|
||||
" * " F_GREEN "%s" F_RESET "\n",
|
||||
arg->arg_allowed_values[i]);
|
||||
}
|
||||
|
||||
b_printf("\n");
|
||||
b_i("usage: %s", b_string_ptr(usage));
|
||||
b_i("for more information, use '" F_YELLOW "--help" F_RESET);
|
||||
|
||||
b_string_release(usage);
|
||||
b_string_release(opt_string);
|
||||
|
||||
return B_SUCCESS;
|
||||
}
|
||||
|
||||
enum b_status b_arglist_report_missing_args(
|
||||
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
|
||||
size_t args_supplied)
|
||||
{
|
||||
struct b_command_option *opt = NULL;
|
||||
struct b_command_arg *arg = NULL;
|
||||
|
||||
if (opt_id != B_COMMAND_INVALID_ID) {
|
||||
opt = b_command_get_option_with_id(args->list_command, opt_id);
|
||||
}
|
||||
|
||||
if (arg_id != B_COMMAND_INVALID_ID) {
|
||||
arg = opt ? b_command_option_get_arg_with_id(opt, arg_id)
|
||||
: b_command_get_arg_with_id(args->list_command, arg_id);
|
||||
}
|
||||
|
||||
struct b_string *usage
|
||||
= z__b_command_default_usage_string(args->list_command, opt);
|
||||
struct b_string *opt_string = b_string_create();
|
||||
|
||||
if (opt) {
|
||||
z__b_get_option_usage_string(opt, 0, opt_string);
|
||||
} else {
|
||||
z__b_get_arg_usage_string(arg, 0, opt_string);
|
||||
}
|
||||
|
||||
char supplied_arg_str[64];
|
||||
if (args_supplied == 0) {
|
||||
snprintf(
|
||||
supplied_arg_str, sizeof supplied_arg_str,
|
||||
F_RED_BOLD "none" F_RESET " were provided");
|
||||
} else if (args_supplied == 1) {
|
||||
snprintf(
|
||||
supplied_arg_str, sizeof supplied_arg_str,
|
||||
"only " F_YELLOW_BOLD "%zu" F_RESET " was provided",
|
||||
args_supplied);
|
||||
} else {
|
||||
snprintf(
|
||||
supplied_arg_str, sizeof supplied_arg_str,
|
||||
"only " F_YELLOW_BOLD "%zu" F_RESET " were provided",
|
||||
args_supplied);
|
||||
}
|
||||
|
||||
char required_arg_count[64];
|
||||
switch (arg->arg_nr_values) {
|
||||
case B_ARG_1_OR_MORE_VALUES:
|
||||
snprintf(
|
||||
required_arg_count, sizeof required_arg_count,
|
||||
"one or more");
|
||||
break;
|
||||
default:
|
||||
snprintf(
|
||||
required_arg_count, sizeof required_arg_count, "%d",
|
||||
arg->arg_nr_values);
|
||||
}
|
||||
|
||||
b_err("argument `" F_YELLOW "%s" F_RESET "` requires " F_GREEN_BOLD
|
||||
"%s" F_RESET " `" F_YELLOW "%s" F_RESET "` value%s, but %s.",
|
||||
b_string_ptr(opt_string), required_arg_count, arg->arg_name,
|
||||
(arg->arg_nr_values == 1) ? "" : "s", supplied_arg_str);
|
||||
b_i("usage: %s", b_string_ptr(usage));
|
||||
b_i("for more information, use '" F_YELLOW "--help" F_RESET "'");
|
||||
|
||||
b_string_release(usage);
|
||||
b_string_release(opt_string);
|
||||
|
||||
return B_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user