197 lines
5.2 KiB
C
197 lines
5.2 KiB
C
#include "command.h"
|
|
|
|
#include <assert.h>
|
|
#include <blue/core/stringstream.h>
|
|
#include <blue/ds/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, args);
|
|
|
|
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, args);
|
|
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);
|
|
assert(opt);
|
|
}
|
|
|
|
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);
|
|
assert(arg);
|
|
}
|
|
|
|
struct b_string *usage = z__b_command_default_usage_string(
|
|
args->list_command, opt, args);
|
|
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;
|
|
}
|