fx.cmdline: convert to new assembly build system

This commit is contained in:
2026-05-03 16:49:33 +01:00
parent 44fed67d43
commit f4469c9eb0
10 changed files with 591 additions and 279 deletions
+12 -1
View File
@@ -15,7 +15,8 @@ set(fx_all_assemblies
fx.compression fx.compression
fx.io fx.io
fx.serial fx.serial
fx.term) fx.term
fx.cmdline)
if (NOT DEFINED fx_assemblies) if (NOT DEFINED fx_assemblies)
set(fx_assemblies ${fx_all_assemblies}) set(fx_assemblies ${fx_all_assemblies})
@@ -83,4 +84,14 @@ if ("fx.term" IN_LIST fx_assemblies)
DEPENDENCIES fx.runtime fx.collections) DEPENDENCIES fx.runtime fx.collections)
endif () endif ()
if ("fx.cmdline" IN_LIST fx_assemblies)
add_fx_assembly(
NAME fx.cmdline
NAMESPACES fx.cmdline
DEPENDENCIES
fx.runtime
fx.collections
fx.term)
endif ()
add_executable(dynamic-test test/dynamic-test.c) add_executable(dynamic-test test/dynamic-test.c)
+7
View File
@@ -0,0 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.cmdline");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
+1 -3
View File
@@ -1,3 +1 @@
include(../cmake/Templates.cmake) export_fx_namespace_details(fx.cmdline)
add_fx_module(NAME cmd DEPENDENCIES core ds term)
+20 -8
View File
@@ -1,7 +1,7 @@
#include "command.h" #include "command.h"
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -54,7 +54,8 @@ fx_status fx_command_arg_set_name(struct fx_command_arg *arg, const char *name)
} }
fx_status fx_command_arg_set_description( fx_status fx_command_arg_set_description(
struct fx_command_arg *arg, const char *description) struct fx_command_arg *arg,
const char *description)
{ {
char *desc = fx_strdup(description); char *desc = fx_strdup(description);
if (!desc) { if (!desc) {
@@ -71,14 +72,16 @@ fx_status fx_command_arg_set_description(
} }
fx_status fx_command_arg_set_nr_values( fx_status fx_command_arg_set_nr_values(
struct fx_command_arg *arg, enum fx_command_arg_value_count nr_values) struct fx_command_arg *arg,
enum fx_command_arg_value_count nr_values)
{ {
arg->arg_nr_values = nr_values; arg->arg_nr_values = nr_values;
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_arg_set_allowed_values( fx_status fx_command_arg_set_allowed_values(
struct fx_command_arg *arg, const char **allowed_values) struct fx_command_arg *arg,
const char **allowed_values)
{ {
size_t count; size_t count;
for (count = 0; allowed_values[count]; count++) for (count = 0; allowed_values[count]; count++)
@@ -102,7 +105,10 @@ fx_status fx_command_arg_set_allowed_values(
return FX_SUCCESS; return FX_SUCCESS;
} }
void z__fx_get_arg_usage_string(struct fx_command_arg *arg, bool colour, fx_string *out) void z__fx_get_arg_usage_string(
struct fx_command_arg *arg,
bool colour,
fx_string *out)
{ {
bool optional = false, multi = false; bool optional = false, multi = false;
switch (arg->arg_nr_values) { switch (arg->arg_nr_values) {
@@ -126,10 +132,14 @@ void z__fx_get_arg_usage_string(struct fx_command_arg *arg, bool colour, fx_stri
if (optional) { if (optional) {
fx_string_append_cstrf( fx_string_append_cstrf(
out, colour ? F_GREEN "[[%s]" : "[[%s]", arg->arg_name); out,
colour ? F_GREEN "[[%s]" : "[[%s]",
arg->arg_name);
} else { } else {
fx_string_append_cstrf( fx_string_append_cstrf(
out, colour ? F_GREEN "<%s>" : "<%s>", arg->arg_name); out,
colour ? F_GREEN "<%s>" : "<%s>",
arg->arg_name);
} }
for (int i = 1; i < arg->arg_nr_values; i++) { for (int i = 1; i < arg->arg_nr_values; i++) {
@@ -167,7 +177,9 @@ void z__fx_get_arg_description(struct fx_command_arg *arg, fx_string *out)
} }
fx_string_append_cstrf( fx_string_append_cstrf(
out, " " F_GREEN "%s" F_RESET, arg->arg_allowed_values[i]); out,
" " F_GREEN "%s" F_RESET,
arg->arg_allowed_values[i]);
} }
fx_string_append_cstr(out, "]"); fx_string_append_cstr(out, "]");
+133 -53
View File
@@ -1,8 +1,8 @@
#include "command.h" #include "command.h"
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <fx/term/print.h> #include <fx/term/print.h>
#include <fx/term/tty.h> #include <fx/term/tty.h>
#include <stdarg.h> #include <stdarg.h>
@@ -11,14 +11,28 @@
#include <string.h> #include <string.h>
FX_BST_DEFINE_SIMPLE_INSERT( FX_BST_DEFINE_SIMPLE_INSERT(
struct fx_arglist_option, opt_node, opt_id, put_arglist_option) struct fx_arglist_option,
opt_node,
opt_id,
put_arglist_option)
FX_BST_DEFINE_SIMPLE_GET( FX_BST_DEFINE_SIMPLE_GET(
struct fx_arglist_option, unsigned int, opt_node, opt_id, get_arglist_option) struct fx_arglist_option,
unsigned int,
opt_node,
opt_id,
get_arglist_option)
FX_BST_DEFINE_SIMPLE_INSERT( FX_BST_DEFINE_SIMPLE_INSERT(
struct fx_arglist_value, val_node, val_id, put_arglist_value) struct fx_arglist_value,
val_node,
val_id,
put_arglist_value)
FX_BST_DEFINE_SIMPLE_GET( FX_BST_DEFINE_SIMPLE_GET(
struct fx_arglist_value, unsigned int, val_node, val_id, get_arglist_value) struct fx_arglist_value,
unsigned int,
val_node,
val_id,
get_arglist_value)
struct argv_parser { struct argv_parser {
struct fx_command *cmd; struct fx_command *cmd;
@@ -62,7 +76,9 @@ struct fx_arglist *fx_arglist_create(void)
return out; return out;
} }
static void move_to_subcommand(struct argv_parser *parser, struct fx_command *cmd) static void move_to_subcommand(
struct argv_parser *parser,
struct fx_command *cmd)
{ {
parser->cmd = cmd; parser->cmd = cmd;
parser->arglist->list_command = cmd; parser->arglist->list_command = cmd;
@@ -86,10 +102,13 @@ static fx_status set_opt(struct fx_arglist *args, struct fx_command_option *opt)
} }
static fx_status put_arg( static fx_status put_arg(
struct fx_arglist *args, struct fx_command_arg *arg, const char *value) struct fx_arglist *args,
struct fx_command_arg *arg,
const char *value)
{ {
struct fx_arglist_option *arglist_opt struct fx_arglist_option *arglist_opt = get_arglist_option(
= get_arglist_option(&args->list_options, FX_COMMAND_INVALID_ID); &args->list_options,
FX_COMMAND_INVALID_ID);
if (!arglist_opt) { if (!arglist_opt) {
arglist_opt = malloc(sizeof *arglist_opt); arglist_opt = malloc(sizeof *arglist_opt);
@@ -134,8 +153,10 @@ static fx_status put_arg(
} }
static fx_status put_opt_arg( static fx_status put_opt_arg(
struct fx_arglist_option *arglist_opt, struct fx_command_option *opt, struct fx_arglist_option *arglist_opt,
struct fx_command_arg *arg, const char *value) struct fx_command_option *opt,
struct fx_command_arg *arg,
const char *value)
{ {
if (arg->arg_allowed_values) { if (arg->arg_allowed_values) {
@@ -202,14 +223,18 @@ static fx_status check_required_args(struct argv_parser *parser)
} }
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, FX_COMMAND_INVALID_ID, arg->arg_id, parser->arglist,
FX_COMMAND_INVALID_ID,
arg->arg_id,
parser->nr_values_cur_arg); parser->nr_values_cur_arg);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
if (parser->nr_values_cur_arg != arg->arg_nr_values) { if (parser->nr_values_cur_arg != arg->arg_nr_values) {
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, FX_COMMAND_INVALID_ID, arg->arg_id, parser->arglist,
FX_COMMAND_INVALID_ID,
arg->arg_id,
parser->nr_values_cur_arg); parser->nr_values_cur_arg);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -225,8 +250,9 @@ static fx_status parse_arg(struct argv_parser *parser)
break; break;
} }
struct fx_command *subcmd struct fx_command *subcmd = fx_command_get_subcommand_with_name(
= fx_command_get_subcommand_with_name(parser->cmd, value); parser->cmd,
value);
if (subcmd) { if (subcmd) {
move_to_subcommand(parser, subcmd); move_to_subcommand(parser, subcmd);
parser->arglist->list_argv_last_command parser->arglist->list_argv_last_command
@@ -236,10 +262,14 @@ static fx_status parse_arg(struct argv_parser *parser)
} }
struct fx_command_arg *arg = fx_unbox( struct fx_command_arg *arg = fx_unbox(
struct fx_command_arg, parser->arg_it, arg_entry); struct fx_command_arg,
parser->arg_it,
arg_entry);
if (!arg) { if (!arg) {
fx_arglist_report_unexpected_arg(parser->arglist, value); fx_arglist_report_unexpected_arg(
parser->arglist,
value);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -249,8 +279,10 @@ static fx_status parse_arg(struct argv_parser *parser)
if (status == FX_ERR_INVALID_ARGUMENT) { if (status == FX_ERR_INVALID_ARGUMENT) {
fx_arglist_report_invalid_arg_value( fx_arglist_report_invalid_arg_value(
parser->arglist, FX_COMMAND_INVALID_ID, parser->arglist,
arg->arg_id, value); FX_COMMAND_INVALID_ID,
arg->arg_id,
value);
} }
if (FX_ERR(status)) { if (FX_ERR(status)) {
@@ -306,7 +338,8 @@ static fx_status parse_short_opt(struct argv_parser *parser)
opt = fx_command_get_option_with_short_name(parser->cmd, flag); opt = fx_command_get_option_with_short_name(parser->cmd, flag);
if (!opt) { if (!opt) {
subcmd = fx_command_get_subcommand_with_short_name( subcmd = fx_command_get_subcommand_with_short_name(
parser->cmd, flag); parser->cmd,
flag);
} }
if (subcmd) { if (subcmd) {
@@ -319,10 +352,13 @@ static fx_status parse_short_opt(struct argv_parser *parser)
if (!opt) { if (!opt) {
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
parser->cmd, NULL, parser->arglist); parser->cmd,
NULL,
parser->arglist);
fx_err("unrecognised argument '" F_YELLOW "-%c" F_RESET fx_err("unrecognised argument '" F_YELLOW "-%c" F_RESET
"'\n\n", "'\n\n",
flag, fx_string_get_cstr(usage)); flag,
fx_string_get_cstr(usage));
fx_i("usage: %s", fx_string_get_cstr(usage)); fx_i("usage: %s", fx_string_get_cstr(usage));
fx_i("for more information, use '" F_YELLOW fx_i("for more information, use '" F_YELLOW
"--help" F_RESET "'\n"); "--help" F_RESET "'\n");
@@ -382,8 +418,10 @@ static fx_status parse_short_opt(struct argv_parser *parser)
if (status == FX_ERR_INVALID_ARGUMENT) { if (status == FX_ERR_INVALID_ARGUMENT) {
fx_arglist_report_invalid_arg_value( fx_arglist_report_invalid_arg_value(
parser->arglist, FX_COMMAND_INVALID_ID, parser->arglist,
arg->arg_id, value); FX_COMMAND_INVALID_ID,
arg->arg_id,
value);
} }
if (FX_ERR(status)) { if (FX_ERR(status)) {
@@ -408,7 +446,9 @@ static fx_status parse_short_opt(struct argv_parser *parser)
} }
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, opt->opt_id, arg->arg_id, parser->arglist,
opt->opt_id,
arg->arg_id,
nr_args_cur_opt); nr_args_cur_opt);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -420,7 +460,9 @@ static fx_status parse_short_opt(struct argv_parser *parser)
if (!value) { if (!value) {
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, opt->opt_id, arg->arg_id, parser->arglist,
opt->opt_id,
arg->arg_id,
nr_args_cur_opt); nr_args_cur_opt);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -443,16 +485,20 @@ static fx_status parse_long_opt(struct argv_parser *parser)
opt = fx_command_get_option_with_long_name(parser->cmd, opt_name); opt = fx_command_get_option_with_long_name(parser->cmd, opt_name);
if (!opt) { if (!opt) {
subcmd = fx_command_get_subcommand_with_long_name( subcmd = fx_command_get_subcommand_with_long_name(
parser->cmd, opt_name); parser->cmd,
opt_name);
} }
if (!opt && !subcmd) { if (!opt && !subcmd) {
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
parser->cmd, NULL, parser->arglist); parser->cmd,
NULL,
parser->arglist);
fx_err("unrecognised argument '" F_YELLOW "--%s" F_RESET fx_err("unrecognised argument '" F_YELLOW "--%s" F_RESET
"'\n\nusage: %s\n\nfor more information, use '" F_YELLOW "'\n\nusage: %s\n\nfor more information, use '" F_YELLOW
"--help" F_RESET "'\n", "--help" F_RESET "'\n",
opt_name, fx_string_get_cstr(usage)); opt_name,
fx_string_get_cstr(usage));
fx_string_unref(usage); fx_string_unref(usage);
return FX_ERR_NO_ENTRY; return FX_ERR_NO_ENTRY;
@@ -504,8 +550,10 @@ static fx_status parse_long_opt(struct argv_parser *parser)
if (status == FX_ERR_INVALID_ARGUMENT) { if (status == FX_ERR_INVALID_ARGUMENT) {
fx_arglist_report_invalid_arg_value( fx_arglist_report_invalid_arg_value(
parser->arglist, FX_COMMAND_INVALID_ID, parser->arglist,
arg->arg_id, value); FX_COMMAND_INVALID_ID,
arg->arg_id,
value);
} }
if (FX_ERR(status)) { if (FX_ERR(status)) {
@@ -533,7 +581,9 @@ static fx_status parse_long_opt(struct argv_parser *parser)
} }
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, opt->opt_id, arg->arg_id, parser->arglist,
opt->opt_id,
arg->arg_id,
nr_args_cur_opt); nr_args_cur_opt);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -546,7 +596,9 @@ static fx_status parse_long_opt(struct argv_parser *parser)
if (!value) { if (!value) {
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, opt->opt_id, arg->arg_id, parser->arglist,
opt->opt_id,
arg->arg_id,
nr_args_cur_opt); nr_args_cur_opt);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -580,7 +632,9 @@ static bool should_show_help(struct fx_command *cmd, struct fx_arglist *args)
} }
fx_status fx_arglist_parse( fx_status fx_arglist_parse(
struct fx_arglist *args, struct fx_command **cmd, int argc, struct fx_arglist *args,
struct fx_command **cmd,
int argc,
const char **argv) const char **argv)
{ {
struct argv_parser parser = { struct argv_parser parser = {
@@ -665,7 +719,9 @@ void fx_arglist_destroy(struct fx_arglist *args)
args_it = fx_bst_first(&opt->opt_values); args_it = fx_bst_first(&opt->opt_values);
while (args_it) { while (args_it) {
struct fx_arglist_value *val = fx_unbox( struct fx_arglist_value *val = fx_unbox(
struct fx_arglist_value, args_it, val_node); struct fx_arglist_value,
args_it,
val_node);
args_next = fx_bst_next(args_it); args_next = fx_bst_next(args_it);
if (val) { if (val) {
@@ -686,8 +742,11 @@ void fx_arglist_destroy(struct fx_arglist *args)
} }
fx_status fx_arglist_get_string( fx_status fx_arglist_get_string(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, const char **out) unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
const char **out)
{ {
fx_arglist_iterator it = {0}; fx_arglist_iterator it = {0};
fx_arglist_iterator_begin(args, opt_id, arg_id, &it); fx_arglist_iterator_begin(args, opt_id, arg_id, &it);
@@ -710,8 +769,11 @@ fx_status fx_arglist_get_string(
} }
fx_status fx_arglist_get_int( fx_status fx_arglist_get_int(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, long long *out) unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
long long *out)
{ {
fx_arglist_iterator it = {0}; fx_arglist_iterator it = {0};
fx_arglist_iterator_begin(args, opt_id, arg_id, &it); fx_arglist_iterator_begin(args, opt_id, arg_id, &it);
@@ -734,8 +796,11 @@ fx_status fx_arglist_get_int(
} }
fx_status fx_arglist_get_uint( fx_status fx_arglist_get_uint(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, unsigned long long *out) unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
unsigned long long *out)
{ {
fx_arglist_iterator it = {0}; fx_arglist_iterator it = {0};
fx_arglist_iterator_begin(args, opt_id, arg_id, &it); fx_arglist_iterator_begin(args, opt_id, arg_id, &it);
@@ -758,7 +823,9 @@ fx_status fx_arglist_get_uint(
} }
fx_status fx_arglist_get_option( fx_status fx_arglist_get_option(
const fx_arglist *args, unsigned int opt_id, unsigned int index, const fx_arglist *args,
unsigned int opt_id,
unsigned int index,
fx_arglist_option **out) fx_arglist_option **out)
{ {
struct fx_bst_node *node = fx_bst_first(&args->list_options); struct fx_bst_node *node = fx_bst_first(&args->list_options);
@@ -785,7 +852,9 @@ fx_status fx_arglist_get_option(
} }
size_t fx_arglist_get_count( size_t fx_arglist_get_count(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id) const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id)
{ {
size_t count = 0; size_t count = 0;
fx_arglist_iterator it; fx_arglist_iterator it;
@@ -799,12 +868,15 @@ size_t fx_arglist_get_count(
} }
fx_status fx_arglist_option_get_value( fx_status fx_arglist_option_get_value(
const fx_arglist_option *opt, unsigned int arg_id, unsigned int index, const fx_arglist_option *opt,
unsigned int arg_id,
unsigned int index,
fx_arglist_value **out) fx_arglist_value **out)
{ {
struct fx_bst_node *node = fx_bst_first(&opt->opt_values); struct fx_bst_node *node = fx_bst_first(&opt->opt_values);
while (node) { while (node) {
fx_arglist_value *cur = fx_unbox(fx_arglist_value, node, val_node); fx_arglist_value *cur
= fx_unbox(fx_arglist_value, node, val_node);
if (cur->val_id != arg_id) { if (cur->val_id != arg_id) {
node = fx_bst_next(node); node = fx_bst_next(node);
@@ -825,7 +897,8 @@ fx_status fx_arglist_option_get_value(
/************************ arglist iterator functions **************************/ /************************ arglist iterator functions **************************/
static struct fx_arglist_option *advance_to_next_opt(struct fx_arglist_iterator *it) static struct fx_arglist_option *advance_to_next_opt(
struct fx_arglist_iterator *it)
{ {
struct fx_arglist_option *opt; struct fx_arglist_option *opt;
@@ -846,7 +919,8 @@ static struct fx_arglist_option *advance_to_next_opt(struct fx_arglist_iterator
return NULL; return NULL;
} }
static struct fx_arglist_value *advance_to_next_arg(struct fx_arglist_iterator *it) static struct fx_arglist_value *advance_to_next_arg(
struct fx_arglist_iterator *it)
{ {
struct fx_arglist_value *val; struct fx_arglist_value *val;
@@ -868,8 +942,10 @@ static struct fx_arglist_value *advance_to_next_arg(struct fx_arglist_iterator *
} }
int fx_arglist_iterator_begin( int fx_arglist_iterator_begin(
const struct fx_arglist *args, unsigned int opt_filter, const struct fx_arglist *args,
unsigned int arg_filter, struct fx_arglist_iterator *it) unsigned int opt_filter,
unsigned int arg_filter,
struct fx_arglist_iterator *it)
{ {
memset(it, 0x0, sizeof *it); memset(it, 0x0, sizeof *it);
@@ -909,7 +985,9 @@ int fx_arglist_iterator_begin(
} }
val = fx_unbox( val = fx_unbox(
struct fx_arglist_value, it->_arg_it, val_node); struct fx_arglist_value,
it->_arg_it,
val_node);
if (!val if (!val
|| (arg_filter != val->val_id || (arg_filter != val->val_id
&& arg_filter != FX_COMMAND_INVALID_ID)) { && arg_filter != FX_COMMAND_INVALID_ID)) {
@@ -994,7 +1072,8 @@ static struct fx_arglist_option *advance_to_next_opt2(
} }
int fx_arglist_option_iterator_begin( int fx_arglist_option_iterator_begin(
const struct fx_arglist *args, unsigned int opt_filter, const struct fx_arglist *args,
unsigned int opt_filter,
struct fx_arglist_option_iterator *it) struct fx_arglist_option_iterator *it)
{ {
memset(it, 0x0, sizeof *it); memset(it, 0x0, sizeof *it);
@@ -1047,7 +1126,8 @@ bool fx_arglist_option_iterator_next(struct fx_arglist_option_iterator *it)
return true; return true;
} }
bool fx_arglist_option_iterator_is_valid(const struct fx_arglist_option_iterator *it) bool fx_arglist_option_iterator_is_valid(
const struct fx_arglist_option_iterator *it)
{ {
return it->opt_id != FX_COMMAND_INVALID_ID || it->opt != NULL; return it->opt_id != FX_COMMAND_INVALID_ID || it->opt != NULL;
} }
+142 -64
View File
@@ -1,8 +1,8 @@
#include "command.h" #include "command.h"
#include <fx/bst.h>
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/core/bst.h> #include <fx/string.h>
#include <fx/ds/string.h>
#include <fx/term/print.h> #include <fx/term/print.h>
#include <fx/term/tty.h> #include <fx/term/tty.h>
#include <stdio.h> #include <stdio.h>
@@ -13,7 +13,12 @@
static struct fx_bst command_list = {0}; static struct fx_bst command_list = {0};
FX_BST_DEFINE_SIMPLE_GET(struct fx_command, unsigned int, c_node, c_id, get_command) FX_BST_DEFINE_SIMPLE_GET(
struct fx_command,
unsigned int,
c_node,
c_id,
get_command)
FX_BST_DEFINE_SIMPLE_INSERT(struct fx_command, c_node, c_id, put_command) FX_BST_DEFINE_SIMPLE_INSERT(struct fx_command, c_node, c_id, put_command)
enum item_type { enum item_type {
@@ -26,7 +31,8 @@ static void command_list_cleanup(void)
{ {
struct fx_bst_node *node = fx_bst_first(&command_list); struct fx_bst_node *node = fx_bst_first(&command_list);
while (node) { while (node) {
struct fx_command *cmd = fx_unbox(struct fx_command, node, c_node); struct fx_command *cmd
= fx_unbox(struct fx_command, node, c_node);
if (!cmd) { if (!cmd) {
break; break;
} }
@@ -57,8 +63,10 @@ static void command_usage_destroy(struct fx_command_usage *usage)
{ {
struct fx_queue_entry *entry = fx_queue_first(&usage->u_parts); struct fx_queue_entry *entry = fx_queue_first(&usage->u_parts);
while (entry) { while (entry) {
struct fx_command_usage_entry *arg struct fx_command_usage_entry *arg = fx_unbox(
= fx_unbox(struct fx_command_usage_entry, entry, e_entry); struct fx_command_usage_entry,
entry,
e_entry);
if (!arg) { if (!arg) {
continue; continue;
} }
@@ -216,7 +224,9 @@ fx_status fx_command_set_flags(struct fx_command *cmd, fx_command_flags flags)
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_set_description(struct fx_command *cmd, const char *description) fx_status fx_command_set_description(
struct fx_command *cmd,
const char *description)
{ {
char *desc = fx_strdup(description); char *desc = fx_strdup(description);
if (!desc) { if (!desc) {
@@ -233,7 +243,8 @@ fx_status fx_command_set_description(struct fx_command *cmd, const char *descrip
} }
fx_status fx_command_set_callback( fx_status fx_command_set_callback(
struct fx_command *cmd, fx_command_callback callback) struct fx_command *cmd,
fx_command_callback callback)
{ {
cmd->c_callback = callback; cmd->c_callback = callback;
return FX_SUCCESS; return FX_SUCCESS;
@@ -284,7 +295,8 @@ struct fx_command_usage *fx_command_add_usage(struct fx_command *cmd)
} }
const struct fx_command_option *fx_command_get_option( const struct fx_command_option *fx_command_get_option(
const struct fx_command *cmd, int id) const struct fx_command *cmd,
int id)
{ {
struct fx_queue_entry *cur = fx_queue_first(&cmd->c_opt); struct fx_queue_entry *cur = fx_queue_first(&cmd->c_opt);
while (cur) { while (cur) {
@@ -302,7 +314,8 @@ const struct fx_command_option *fx_command_get_option(
} }
fx_status fx_command_usage_add_option( fx_status fx_command_usage_add_option(
struct fx_command_usage *usage, struct fx_command_option *opt) struct fx_command_usage *usage,
struct fx_command_option *opt)
{ {
struct fx_command_usage_entry *u_opt = malloc(sizeof *u_opt); struct fx_command_usage_entry *u_opt = malloc(sizeof *u_opt);
if (!u_opt) { if (!u_opt) {
@@ -319,7 +332,8 @@ fx_status fx_command_usage_add_option(
} }
fx_status fx_command_usage_add_arg( fx_status fx_command_usage_add_arg(
struct fx_command_usage *usage, struct fx_command_arg *arg) struct fx_command_usage *usage,
struct fx_command_arg *arg)
{ {
struct fx_command_usage_entry *u_arg = malloc(sizeof *u_arg); struct fx_command_usage_entry *u_arg = malloc(sizeof *u_arg);
if (!u_arg) { if (!u_arg) {
@@ -335,7 +349,9 @@ fx_status fx_command_usage_add_arg(
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_usage_add_command(fx_command_usage *usage, unsigned int cmd_id) fx_status fx_command_usage_add_command(
fx_command_usage *usage,
unsigned int cmd_id)
{ {
struct fx_command_usage_entry *u_cmd = malloc(sizeof *u_cmd); struct fx_command_usage_entry *u_cmd = malloc(sizeof *u_cmd);
if (!u_cmd) { if (!u_cmd) {
@@ -392,7 +408,9 @@ static void prepend_command_name(struct fx_command *cmd, fx_string *out)
} }
static void get_qualified_command_name( static void get_qualified_command_name(
struct fx_command *cmd, const struct fx_arglist *args, fx_string *out) struct fx_command *cmd,
const struct fx_arglist *args,
fx_string *out)
{ {
for (unsigned int i = 0; i <= args->list_argv_last_command; i++) { for (unsigned int i = 0; i <= args->list_argv_last_command; i++) {
if (i > 0) { if (i > 0) {
@@ -414,8 +432,10 @@ static void get_qualified_command_name(
} }
static void get_usage_string( static void get_usage_string(
struct fx_command *cmd, struct fx_arglist *args, struct fx_command *cmd,
struct fx_command_usage *usage, fx_string *out) struct fx_arglist *args,
struct fx_command_usage *usage,
fx_string *out)
{ {
get_qualified_command_name(cmd, args, out); get_qualified_command_name(cmd, args, out);
@@ -424,7 +444,9 @@ static void get_usage_string(
struct fx_queue_entry *q_entry = fx_queue_first(&usage->u_parts); struct fx_queue_entry *q_entry = fx_queue_first(&usage->u_parts);
while (q_entry) { while (q_entry) {
struct fx_command_usage_entry *entry = fx_unbox( struct fx_command_usage_entry *entry = fx_unbox(
struct fx_command_usage_entry, q_entry, e_entry); struct fx_command_usage_entry,
q_entry,
e_entry);
if (!entry) { if (!entry) {
break; break;
@@ -436,7 +458,10 @@ static void get_usage_string(
switch (entry->e_type) { switch (entry->e_type) {
case CMD_USAGE_ARG: case CMD_USAGE_ARG:
if (entry->e_arg) { if (entry->e_arg) {
z__fx_get_arg_usage_string(entry->e_arg, false, out); z__fx_get_arg_usage_string(
entry->e_arg,
false,
out);
} else { } else {
fx_string_append_cstr(out, "[[ARGS]"); fx_string_append_cstr(out, "[[ARGS]");
} }
@@ -444,7 +469,9 @@ static void get_usage_string(
case CMD_USAGE_OPT: case CMD_USAGE_OPT:
if (entry->e_opt) { if (entry->e_opt) {
z__fx_get_option_usage_string( z__fx_get_option_usage_string(
entry->e_opt, CMD_STR_DIRECT_USAGE, out); entry->e_opt,
CMD_STR_DIRECT_USAGE,
out);
} else { } else {
fx_string_append_cstr(out, "[[OPTIONS]"); fx_string_append_cstr(out, "[[OPTIONS]");
} }
@@ -473,7 +500,8 @@ static void get_usage_string(
} }
fx_string *z__fx_command_default_usage_string( fx_string *z__fx_command_default_usage_string(
struct fx_command *cmd, struct fx_command_option *with_opt, struct fx_command *cmd,
struct fx_command_option *with_opt,
const struct fx_arglist *args) const struct fx_arglist *args)
{ {
fx_string *str = fx_string_create(); fx_string *str = fx_string_create();
@@ -481,7 +509,10 @@ fx_string *z__fx_command_default_usage_string(
if (with_opt) { if (with_opt) {
fx_string_append_cstr(str, " "); fx_string_append_cstr(str, " ");
z__fx_get_option_usage_string(with_opt, CMD_STR_DIRECT_USAGE, str); z__fx_get_option_usage_string(
with_opt,
CMD_STR_DIRECT_USAGE,
str);
} else if (!fx_queue_empty(&cmd->c_opt)) { } else if (!fx_queue_empty(&cmd->c_opt)) {
fx_string_append_cstr(str, " [OPTIONS]"); fx_string_append_cstr(str, " [OPTIONS]");
} }
@@ -519,7 +550,9 @@ static void get_command_string(struct fx_command *cmd, fx_string *out)
} }
fx_string_append_cstrf( fx_string_append_cstrf(
out, F_GREEN "-%c" F_RESET, cmd->c_short_name); out,
F_GREEN "-%c" F_RESET,
cmd->c_short_name);
r++; r++;
} }
@@ -529,7 +562,9 @@ static void get_command_string(struct fx_command *cmd, fx_string *out)
} }
fx_string_append_cstrf( fx_string_append_cstrf(
out, F_GREEN "--%s" F_RESET, cmd->c_long_name); out,
F_GREEN "--%s" F_RESET,
cmd->c_long_name);
r++; r++;
} }
} }
@@ -544,7 +579,8 @@ static void get_command_description(struct fx_command *cmd, fx_string *out)
* 2) the length of the description string exceeds the remaining line length * 2) the length of the description string exceeds the remaining line length
* (once the usage string has been printed. * (once the usage string has been printed.
* or, * or,
* 3) the length of the description string is more than three terminal lines. * 3) the length of the description string is more than three terminal
* lines.
*/ */
#define description_on_separate_line(opt_len, desc_len) \ #define description_on_separate_line(opt_len, desc_len) \
((opt_len >= newline_threshold \ ((opt_len >= newline_threshold \
@@ -578,12 +614,14 @@ static void print_options_list(struct fx_command *cmd)
z__fx_get_option_usage_string(opt, CMD_STR_COLOUR, opt_str); z__fx_get_option_usage_string(opt, CMD_STR_COLOUR, opt_str);
z__fx_get_option_description(opt, desc_str); z__fx_get_option_description(opt, desc_str);
size_t opt_len = fx_string_get_size( size_t opt_len
opt_str, FX_STRLEN_IGNORE_ESC = fx_string_get_size(
| FX_STRLEN_IGNORE_MOD) opt_str,
+ 4; FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4;
size_t desc_len = fx_string_get_size( size_t desc_len = fx_string_get_size(
desc_str, FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD); desc_str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD);
if (description_on_separate_line(opt_len, desc_len)) { if (description_on_separate_line(opt_len, desc_len)) {
goto skip; goto skip;
@@ -616,12 +654,14 @@ static void print_options_list(struct fx_command *cmd)
z__fx_get_option_usage_string(opt, CMD_STR_COLOUR, opt_str); z__fx_get_option_usage_string(opt, CMD_STR_COLOUR, opt_str);
z__fx_get_option_description(opt, desc_str); z__fx_get_option_description(opt, desc_str);
size_t opt_len = fx_string_get_size( size_t opt_len
opt_str, FX_STRLEN_IGNORE_ESC = fx_string_get_size(
| FX_STRLEN_IGNORE_MOD) opt_str,
+ 4; FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4;
size_t desc_len = fx_string_get_size( size_t desc_len = fx_string_get_size(
desc_str, FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD); desc_str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD);
bool new_paragraph bool new_paragraph
= description_on_separate_line(opt_len, desc_len); = description_on_separate_line(opt_len, desc_len);
@@ -650,7 +690,10 @@ static void print_options_list(struct fx_command *cmd)
len++; len++;
} }
fx_print_paragraph(fx_string_get_cstr(desc_str), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(desc_str),
OUTPUT_STREAM,
&format);
if (new_paragraph) { if (new_paragraph) {
fx_tty_putc(OUTPUT_STREAM, 0, '\n'); fx_tty_putc(OUTPUT_STREAM, 0, '\n');
@@ -678,9 +721,11 @@ static void print_args_list(struct fx_command *cmd)
fx_string_clear(str); fx_string_clear(str);
z__fx_get_arg_usage_string(arg, true, str); z__fx_get_arg_usage_string(arg, true, str);
size_t len = fx_string_get_size( size_t len
str, FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD) = fx_string_get_size(
+ 4; str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4;
if (len > desc_margin) { if (len > desc_margin) {
desc_margin = len; desc_margin = len;
@@ -705,10 +750,11 @@ static void print_args_list(struct fx_command *cmd)
fx_tty_puts(OUTPUT_STREAM, 0, " "); fx_tty_puts(OUTPUT_STREAM, 0, " ");
fx_tty_puts(OUTPUT_STREAM, 0, fx_string_get_cstr(str)); fx_tty_puts(OUTPUT_STREAM, 0, fx_string_get_cstr(str));
unsigned int len = fx_string_get_size( unsigned int len
str, FX_STRLEN_IGNORE_ESC = fx_string_get_size(
| FX_STRLEN_IGNORE_MOD) str,
+ 4; FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4;
while (len < format.p_left_margin) { while (len < format.p_left_margin) {
fx_tty_putc(OUTPUT_STREAM, 0, ' '); fx_tty_putc(OUTPUT_STREAM, 0, ' ');
len++; len++;
@@ -717,7 +763,10 @@ static void print_args_list(struct fx_command *cmd)
fx_string_clear(str); fx_string_clear(str);
z__fx_get_arg_description(arg, str); z__fx_get_arg_description(arg, str);
fx_print_paragraph(fx_string_get_cstr(str), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(str),
OUTPUT_STREAM,
&format);
entry = fx_queue_next(entry); entry = fx_queue_next(entry);
} }
@@ -738,9 +787,11 @@ static void print_commands_list(struct fx_command *cmd)
fx_string_clear(str); fx_string_clear(str);
get_command_string(sub, str); get_command_string(sub, str);
size_t len = fx_string_get_size( size_t len
str, FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD) = fx_string_get_size(
+ 4; str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4;
if (len > desc_margin) { if (len > desc_margin) {
desc_margin = len; desc_margin = len;
@@ -765,10 +816,11 @@ static void print_commands_list(struct fx_command *cmd)
fx_tty_puts(OUTPUT_STREAM, 0, " "); fx_tty_puts(OUTPUT_STREAM, 0, " ");
fx_tty_puts(OUTPUT_STREAM, 0, fx_string_get_cstr(str)); fx_tty_puts(OUTPUT_STREAM, 0, fx_string_get_cstr(str));
unsigned int len = fx_string_get_size( unsigned int len
str, FX_STRLEN_IGNORE_ESC = fx_string_get_size(
| FX_STRLEN_IGNORE_MOD) str,
+ 4; FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4;
while (len < format.p_left_margin) { while (len < format.p_left_margin) {
fx_tty_putc(OUTPUT_STREAM, 0, ' '); fx_tty_putc(OUTPUT_STREAM, 0, ' ');
len++; len++;
@@ -777,7 +829,10 @@ static void print_commands_list(struct fx_command *cmd)
fx_string_clear(str); fx_string_clear(str);
get_command_description(sub, str); get_command_description(sub, str);
fx_print_paragraph(fx_string_get_cstr(str), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(str),
OUTPUT_STREAM,
&format);
entry = fx_queue_next(entry); entry = fx_queue_next(entry);
} }
@@ -786,7 +841,8 @@ static void print_commands_list(struct fx_command *cmd)
} }
struct fx_command *fx_command_get_subcommand_with_name( struct fx_command *fx_command_get_subcommand_with_name(
struct fx_command *cmd, const char *name) struct fx_command *cmd,
const char *name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands);
while (entry) { while (entry) {
@@ -808,7 +864,8 @@ struct fx_command *fx_command_get_subcommand_with_name(
} }
struct fx_command *fx_command_get_subcommand_with_long_name( struct fx_command *fx_command_get_subcommand_with_long_name(
struct fx_command *cmd, const char *long_name) struct fx_command *cmd,
const char *long_name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands);
while (entry) { while (entry) {
@@ -830,7 +887,8 @@ struct fx_command *fx_command_get_subcommand_with_long_name(
} }
struct fx_command *fx_command_get_subcommand_with_short_name( struct fx_command *fx_command_get_subcommand_with_short_name(
struct fx_command *cmd, char short_name) struct fx_command *cmd,
char short_name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands);
while (entry) { while (entry) {
@@ -852,7 +910,8 @@ struct fx_command *fx_command_get_subcommand_with_short_name(
} }
struct fx_command_option *fx_command_get_option_with_long_name( struct fx_command_option *fx_command_get_option_with_long_name(
struct fx_command *cmd, const char *long_name) struct fx_command *cmd,
const char *long_name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt);
while (entry) { while (entry) {
@@ -874,7 +933,8 @@ struct fx_command_option *fx_command_get_option_with_long_name(
} }
struct fx_command_option *fx_command_get_option_with_short_name( struct fx_command_option *fx_command_get_option_with_short_name(
struct fx_command *cmd, char short_name) struct fx_command *cmd,
char short_name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt);
while (entry) { while (entry) {
@@ -896,7 +956,8 @@ struct fx_command_option *fx_command_get_option_with_short_name(
} }
struct fx_command_option *fx_command_get_option_with_id( struct fx_command_option *fx_command_get_option_with_id(
struct fx_command *cmd, unsigned int id) struct fx_command *cmd,
unsigned int id)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt);
while (entry) { while (entry) {
@@ -914,7 +975,8 @@ struct fx_command_option *fx_command_get_option_with_id(
} }
struct fx_command_arg *fx_command_get_arg_with_id( struct fx_command_arg *fx_command_get_arg_with_id(
struct fx_command *cmd, unsigned int id) struct fx_command *cmd,
unsigned int id)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_arg); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_arg);
while (entry) { while (entry) {
@@ -941,7 +1003,10 @@ static void print_usage(struct fx_command *cmd, struct fx_arglist *args)
if (fx_queue_empty(&cmd->c_usage)) { if (fx_queue_empty(&cmd->c_usage)) {
fx_string *usage fx_string *usage
= z__fx_command_default_usage_string(cmd, NULL, args); = z__fx_command_default_usage_string(cmd, NULL, args);
fx_print_paragraph(fx_string_get_cstr(usage), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(usage),
OUTPUT_STREAM,
&format);
fx_string_unref(usage); fx_string_unref(usage);
return; return;
} }
@@ -954,7 +1019,10 @@ static void print_usage(struct fx_command *cmd, struct fx_arglist *args)
fx_string_clear(str); fx_string_clear(str);
get_usage_string(cmd, args, usage, str); get_usage_string(cmd, args, usage, str);
fx_print_paragraph(fx_string_get_cstr(str), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(str),
OUTPUT_STREAM,
&format);
entry = fx_queue_next(entry); entry = fx_queue_next(entry);
} }
@@ -968,7 +1036,10 @@ static void print_help(struct fx_command *cmd, struct fx_arglist *args)
if (!cmd->c_parent) { if (!cmd->c_parent) {
fx_tty_printf( fx_tty_printf(
OUTPUT_STREAM, 0, F_GREEN "%s" F_RESET "\n", cmd->c_name); OUTPUT_STREAM,
0,
F_GREEN "%s" F_RESET "\n",
cmd->c_name);
} }
if (cmd->c_description) { if (cmd->c_description) {
@@ -999,9 +1070,13 @@ static int execute_command(struct fx_command *cmd, struct fx_arglist *args)
} }
size_t nr_items = fx_arglist_get_count( size_t nr_items = fx_arglist_get_count(
args, FX_COMMAND_INVALID_ID, FX_COMMAND_INVALID_ID); args,
FX_COMMAND_INVALID_ID,
FX_COMMAND_INVALID_ID);
size_t nr_help = fx_arglist_get_count( size_t nr_help = fx_arglist_get_count(
args, FX_COMMAND_OPTION_HELP, FX_COMMAND_INVALID_ID); args,
FX_COMMAND_OPTION_HELP,
FX_COMMAND_INVALID_ID);
if ((cmd->c_flags & FX_COMMAND_SHOW_HELP_BY_DEFAULT) && nr_items == 0) { if ((cmd->c_flags & FX_COMMAND_SHOW_HELP_BY_DEFAULT) && nr_items == 0) {
print_help(cmd, args); print_help(cmd, args);
@@ -1020,7 +1095,9 @@ static int execute_command(struct fx_command *cmd, struct fx_arglist *args)
return -1; return -1;
} }
static fx_status add_subcommand(struct fx_command *parent, struct fx_command *child) static fx_status add_subcommand(
struct fx_command *parent,
struct fx_command *child)
{ {
fx_queue_push_back(&parent->c_subcommands, &child->c_entry); fx_queue_push_back(&parent->c_subcommands, &child->c_entry);
child->c_parent = parent; child->c_parent = parent;
@@ -1032,7 +1109,8 @@ static int resolve_command_parents(struct fx_bst *commands)
{ {
struct fx_bst_node *node = fx_bst_first(commands); struct fx_bst_node *node = fx_bst_first(commands);
while (node) { while (node) {
struct fx_command *cmd = fx_unbox(struct fx_command, node, c_node); struct fx_command *cmd
= fx_unbox(struct fx_command, node, c_node);
if (cmd->c_parent_id == FX_COMMAND_INVALID_ID) { if (cmd->c_parent_id == FX_COMMAND_INVALID_ID) {
goto skip; goto skip;
+35 -17
View File
@@ -1,10 +1,10 @@
#ifndef _FX_COMMAND_H_ #ifndef _FX_COMMAND_H_
#define _FX_COMMAND_H_ #define _FX_COMMAND_H_
#include <fx/bst.h>
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/core/bst.h> #include <fx/queue.h>
#include <fx/core/queue.h> #include <fx/string.h>
#include <fx/ds/string.h>
#define F_RED "[bright_red]" #define F_RED "[bright_red]"
#define F_GREEN "[bright_green]" #define F_GREEN "[bright_green]"
@@ -105,23 +105,31 @@ struct fx_arglist {
}; };
FX_API struct fx_command *fx_command_get_subcommand_with_name( FX_API struct fx_command *fx_command_get_subcommand_with_name(
struct fx_command *cmd, const char *name); struct fx_command *cmd,
const char *name);
FX_API struct fx_command *fx_command_get_subcommand_with_long_name( FX_API struct fx_command *fx_command_get_subcommand_with_long_name(
struct fx_command *cmd, const char *long_name); struct fx_command *cmd,
const char *long_name);
FX_API struct fx_command *fx_command_get_subcommand_with_short_name( FX_API struct fx_command *fx_command_get_subcommand_with_short_name(
struct fx_command *cmd, char short_name); struct fx_command *cmd,
char short_name);
FX_API struct fx_command_option *fx_command_get_option_with_long_name( FX_API struct fx_command_option *fx_command_get_option_with_long_name(
struct fx_command *cmd, const char *long_name); struct fx_command *cmd,
const char *long_name);
FX_API struct fx_command_option *fx_command_get_option_with_short_name( FX_API struct fx_command_option *fx_command_get_option_with_short_name(
struct fx_command *cmd, char short_name); struct fx_command *cmd,
char short_name);
FX_API struct fx_command_option *fx_command_get_option_with_id( FX_API struct fx_command_option *fx_command_get_option_with_id(
struct fx_command *cmd, unsigned int id); struct fx_command *cmd,
unsigned int id);
FX_API struct fx_command_arg *fx_command_get_arg_with_id( FX_API struct fx_command_arg *fx_command_get_arg_with_id(
struct fx_command *cmd, unsigned int id); struct fx_command *cmd,
unsigned int id);
FX_API struct fx_command_arg *fx_command_option_get_arg_with_id( FX_API struct fx_command_arg *fx_command_option_get_arg_with_id(
struct fx_command_option *opt, unsigned int id); struct fx_command_option *opt,
unsigned int id);
FX_API struct fx_command_option *fx_command_option_create(void); FX_API struct fx_command_option *fx_command_option_create(void);
FX_API void fx_command_option_destroy(struct fx_command_option *opt); FX_API void fx_command_option_destroy(struct fx_command_option *opt);
@@ -131,21 +139,31 @@ FX_API void fx_command_arg_destroy(struct fx_command_arg *arg);
FX_API struct fx_arglist *fx_arglist_create(void); FX_API struct fx_arglist *fx_arglist_create(void);
FX_API fx_status fx_arglist_parse( FX_API fx_status fx_arglist_parse(
struct fx_arglist *args, struct fx_command **cmd, int argc, struct fx_arglist *args,
struct fx_command **cmd,
int argc,
const char **argv); const char **argv);
FX_API void fx_arglist_destroy(struct fx_arglist *args); FX_API void fx_arglist_destroy(struct fx_arglist *args);
FX_API fx_string *z__fx_command_default_usage_string( FX_API fx_string *z__fx_command_default_usage_string(
struct fx_command *cmd, struct fx_command_option *with_opt, struct fx_command *cmd,
struct fx_command_option *with_opt,
const struct fx_arglist *args); const struct fx_arglist *args);
FX_API void z__fx_get_arg_usage_string( FX_API void z__fx_get_arg_usage_string(
struct fx_command_arg *arg, bool colour, fx_string *out); struct fx_command_arg *arg,
FX_API void z__fx_get_arg_description(struct fx_command_arg *arg, fx_string *out); bool colour,
fx_string *out);
FX_API void z__fx_get_arg_description(
struct fx_command_arg *arg,
fx_string *out);
FX_API void z__fx_get_option_usage_string( FX_API void z__fx_get_option_usage_string(
struct fx_command_option *opt, enum cmd_string_flags flags, fx_string *out); struct fx_command_option *opt,
enum cmd_string_flags flags,
fx_string *out);
FX_API void z__fx_get_option_description( FX_API void z__fx_get_option_description(
struct fx_command_option *opt, fx_string *out); struct fx_command_option *opt,
fx_string *out);
#endif #endif
+155 -93
View File
@@ -1,53 +1,64 @@
#ifndef FX_CMD_H_ #ifndef FX_CMD_H_
#define FX_CMD_H_ #define FX_CMD_H_
#include <fx/core/bst.h> #include <fx/bst.h>
#include <fx/core/init.h> #include <fx/collections/array.h>
#include <fx/core/iterator.h> #include <fx/init.h>
#include <fx/core/queue.h> #include <fx/iterator.h>
#include <fx/ds/array.h> #include <fx/queue.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#define fx_arglist_foreach(it, q) \ #define fx_arglist_foreach(it, q) \
for (int z__fx_unique_name() = fx_arglist_iterator_begin( \ for (int z__fx_unique_name() = fx_arglist_iterator_begin( \
q, FX_COMMAND_INVALID_ID, FX_COMMAND_INVALID_ID, (it)); \ q, \
fx_arglist_iterator_is_valid(it); fx_arglist_iterator_next(it)) FX_COMMAND_INVALID_ID, \
FX_COMMAND_INVALID_ID, \
(it)); \
fx_arglist_iterator_is_valid(it); \
fx_arglist_iterator_next(it))
#define fx_arglist_foreach_filtered(it, q, opt_id, arg_id) \ #define fx_arglist_foreach_filtered(it, q, opt_id, arg_id) \
for (int z__fx_unique_name() \ for (int z__fx_unique_name() \
= fx_arglist_iterator_begin(q, opt_id, arg_id, (it)); \ = fx_arglist_iterator_begin(q, opt_id, arg_id, (it)); \
fx_arglist_iterator_is_valid(it); fx_arglist_iterator_next(it)) fx_arglist_iterator_is_valid(it); \
fx_arglist_iterator_next(it))
#define fx_arglist_option_foreach(it, q) \ #define fx_arglist_option_foreach(it, q) \
for (int z__fx_unique_name() \ for (int z__fx_unique_name() = fx_arglist_option_iterator_begin( \
= fx_arglist_option_iterator_begin(q, FX_COMMAND_INVALID_ID, (it)); \ q, \
fx_arglist_option_iterator_is_valid(it); \ FX_COMMAND_INVALID_ID, \
(it)); \
fx_arglist_option_iterator_is_valid(it); \
fx_arglist_option_iterator_next(it)) fx_arglist_option_iterator_next(it))
#define fx_arglist_option_foreach_filtered(it, q, opt_id) \ #define fx_arglist_option_foreach_filtered(it, q, opt_id) \
for (int z__fx_unique_name() \ for (int z__fx_unique_name() \
= fx_arglist_option_iterator_begin(q, opt_id, (it)); \ = fx_arglist_option_iterator_begin(q, opt_id, (it)); \
fx_arglist_option_iterator_is_valid(it); \ fx_arglist_option_iterator_is_valid(it); \
fx_arglist_option_iterator_next(it)) fx_arglist_option_iterator_next(it))
#define FX_COMMAND(id, parent_id) \ #define FX_COMMAND(id, parent_id) \
static fx_command *command_##id = NULL; \ static fx_command *command_##id = NULL; \
static void __init_##id( \ static void __init_##id( \
fx_command *, fx_command_option *, fx_command_arg *, \ fx_command *, \
fx_command_usage *); \ fx_command_option *, \
FX_INIT(init_##id) \ fx_command_arg *, \
fx_command_usage *); \
FX_INIT(init_##id) \
{ \ { \
command_##id = fx_command_create(id); \ command_##id = fx_command_create(id); \
if ((parent_id) != FX_COMMAND_INVALID_ID) { \ if ((parent_id) != FX_COMMAND_INVALID_ID) { \
fx_command_set_parent(command_##id, parent_id); \ fx_command_set_parent(command_##id, parent_id); \
} \ } \
__init_##id(command_##id, NULL, NULL, NULL); \ __init_##id(command_##id, NULL, NULL, NULL); \
fx_command_register(command_##id); \ fx_command_register(command_##id); \
} \ } \
static void __init_##id( \ static void __init_##id( \
fx_command *this_cmd, fx_command_option *this_opt, \ fx_command *this_cmd, \
fx_command_arg *this_arg, fx_command_usage *this_usage) fx_command_option *this_opt, \
fx_command_arg *this_arg, \
fx_command_usage *this_usage)
#define FX_COMMAND_NAME(name) fx_command_set_name(this_cmd, (name)) #define FX_COMMAND_NAME(name) fx_command_set_name(this_cmd, (name))
#define FX_COMMAND_LONG_NAME(name) fx_command_set_long_name(this_cmd, (name)) #define FX_COMMAND_LONG_NAME(name) fx_command_set_long_name(this_cmd, (name))
@@ -56,41 +67,44 @@
#define FX_COMMAND_FLAGS(flags) fx_command_set_flags(this_cmd, (flags)) #define FX_COMMAND_FLAGS(flags) fx_command_set_flags(this_cmd, (flags))
#define FX_COMMAND_FUNCTION(fn) fx_command_set_callback(this_cmd, (fn)) #define FX_COMMAND_FUNCTION(fn) fx_command_set_callback(this_cmd, (fn))
#define FX_COMMAND_OPTION(id) \ #define FX_COMMAND_OPTION(id) \
fx_command_option *opt_##id = fx_command_add_option(this_cmd, (id)); \ fx_command_option *opt_##id = fx_command_add_option(this_cmd, (id)); \
this_opt = opt_##id; \ this_opt = opt_##id; \
if (this_opt) if (this_opt)
#define FX_COMMAND_OPTION_GEN(id) \ #define FX_COMMAND_OPTION_GEN(id) \
fx_command_option *z__fx_unique_name() \ fx_command_option *z__fx_unique_name() \
= fx_command_add_option(this_cmd, (id)); \ = fx_command_add_option(this_cmd, (id)); \
this_opt = z__fx_unique_name(); \ this_opt = z__fx_unique_name(); \
if (this_opt) if (this_opt)
#define FX_COMMAND_HELP_OPTION() \ #define FX_COMMAND_HELP_OPTION() \
do { \ do { \
fx_command_option *opt \ fx_command_option *opt = fx_command_add_option( \
= fx_command_add_option(this_cmd, FX_COMMAND_OPTION_HELP); \ this_cmd, \
fx_command_option_set_description(opt, "Show this help message"); \ FX_COMMAND_OPTION_HELP); \
fx_command_option_set_short_name(opt, 'h'); \ fx_command_option_set_description( \
fx_command_option_set_long_name(opt, "help"); \ opt, \
"Show this help message"); \
fx_command_option_set_short_name(opt, 'h'); \
fx_command_option_set_long_name(opt, "help"); \
} while (0) } while (0)
#define FX_OPTION_LONG_NAME(name) \ #define FX_OPTION_LONG_NAME(name) \
fx_command_option_set_long_name(this_opt, (name)) fx_command_option_set_long_name(this_opt, (name))
#define FX_OPTION_SHORT_NAME(name) \ #define FX_OPTION_SHORT_NAME(name) \
fx_command_option_set_short_name(this_opt, (name)) fx_command_option_set_short_name(this_opt, (name))
#define FX_OPTION_DESC(desc) fx_command_option_set_description(this_opt, (desc)) #define FX_OPTION_DESC(desc) fx_command_option_set_description(this_opt, (desc))
#define FX_OPTION_ARG(id) \ #define FX_OPTION_ARG(id) \
fx_command_arg *arg_##id = fx_command_option_add_arg(this_opt, (id)); \ fx_command_arg *arg_##id = fx_command_option_add_arg(this_opt, (id)); \
this_arg = arg_##id; \ this_arg = arg_##id; \
if (this_arg) if (this_arg)
#define FX_COMMAND_ARG(id) \ #define FX_COMMAND_ARG(id) \
fx_command_arg *arg_##id = fx_command_add_arg(this_cmd, (id)); \ fx_command_arg *arg_##id = fx_command_add_arg(this_cmd, (id)); \
this_arg = arg_##id; \ this_arg = arg_##id; \
if (this_arg) if (this_arg)
@@ -98,37 +112,38 @@
#define FX_ARG_DESC(desc) fx_command_arg_set_description(this_arg, (desc)) #define FX_ARG_DESC(desc) fx_command_arg_set_description(this_arg, (desc))
#define FX_ARG_NR_VALUES(nr_values) \ #define FX_ARG_NR_VALUES(nr_values) \
fx_command_arg_set_nr_values(this_arg, (nr_values)) fx_command_arg_set_nr_values(this_arg, (nr_values))
#define FX_ARG_ALLOWED_VALUES(...) \ #define FX_ARG_ALLOWED_VALUES(...) \
static const char *allowed_values[] = { \ static const char *allowed_values[] = { \
__VA_ARGS__, \ __VA_ARGS__, \
NULL, \ NULL, \
}; \ }; \
fx_command_arg_set_allowed_values(this_arg, allowed_values) fx_command_arg_set_allowed_values(this_arg, allowed_values)
#define FX_COMMAND_USAGE() \ #define FX_COMMAND_USAGE() \
fx_command_usage *z__fx_unique_name() = fx_command_add_usage(this_cmd); \ fx_command_usage *z__fx_unique_name() \
this_usage = z__fx_unique_name(); \ = fx_command_add_usage(this_cmd); \
this_usage = z__fx_unique_name(); \
if (this_usage) if (this_usage)
#define FX_COMMAND_USAGE_COMMAND(cmd_id) \ #define FX_COMMAND_USAGE_COMMAND(cmd_id) \
fx_command_usage_add_command(this_usage, cmd_id) fx_command_usage_add_command(this_usage, cmd_id)
#define FX_COMMAND_USAGE_COMMAND_PLACEHOLDER() \ #define FX_COMMAND_USAGE_COMMAND_PLACEHOLDER() \
fx_command_usage_add_command(this_usage, FX_COMMAND_INVALID_ID) fx_command_usage_add_command(this_usage, FX_COMMAND_INVALID_ID)
#define FX_COMMAND_USAGE_OPT(opt_id) \ #define FX_COMMAND_USAGE_OPT(opt_id) \
fx_command_usage_add_option(this_usage, opt_##opt_id) fx_command_usage_add_option(this_usage, opt_##opt_id)
#define FX_COMMAND_USAGE_OPT_PLACEHOLDER() \ #define FX_COMMAND_USAGE_OPT_PLACEHOLDER() \
fx_command_usage_add_option(this_usage, NULL) fx_command_usage_add_option(this_usage, NULL)
#define FX_COMMAND_USAGE_ARG(opt_id) \ #define FX_COMMAND_USAGE_ARG(opt_id) \
fx_command_usage_add_arg(this_usage, arg_##opt_id) fx_command_usage_add_arg(this_usage, arg_##opt_id)
#define FX_COMMAND_USAGE_ARG_PLACEHOLDER() \ #define FX_COMMAND_USAGE_ARG_PLACEHOLDER() \
fx_command_usage_add_arg(this_usage, NULL) fx_command_usage_add_arg(this_usage, NULL)
#define FX_COMMAND_OPTION_HELP ((uintptr_t)0xF0000001) #define FX_COMMAND_OPTION_HELP ((uintptr_t)0xF0000001)
@@ -197,90 +212,137 @@ typedef struct fx_arglist fx_arglist;
typedef struct fx_arglist_option fx_arglist_option; typedef struct fx_arglist_option fx_arglist_option;
typedef int (*fx_command_callback)( typedef int (*fx_command_callback)(
const fx_command *, const fx_arglist *, const fx_array *); const fx_command *,
const fx_arglist *,
const fx_array *);
FX_API fx_command *fx_command_create(unsigned int id); FX_API fx_command *fx_command_create(unsigned int id);
FX_API void fx_command_destroy(fx_command *cmd); FX_API void fx_command_destroy(fx_command *cmd);
FX_API fx_status fx_command_register(fx_command *cmd); FX_API fx_status fx_command_register(fx_command *cmd);
FX_API int fx_command_dispatch(unsigned int cmd_id, int argc, const char **argv); FX_API int fx_command_dispatch(
unsigned int cmd_id,
int argc,
const char **argv);
FX_API fx_status fx_command_set_name(fx_command *cmd, const char *name); FX_API fx_status fx_command_set_name(fx_command *cmd, const char *name);
FX_API fx_status fx_command_set_long_name(fx_command *cmd, const char *name); FX_API fx_status fx_command_set_long_name(fx_command *cmd, const char *name);
FX_API fx_status fx_command_set_short_name(fx_command *cmd, char name); FX_API fx_status fx_command_set_short_name(fx_command *cmd, char name);
FX_API fx_status fx_command_set_flags(fx_command *cmd, fx_command_flags flags); FX_API fx_status fx_command_set_flags(fx_command *cmd, fx_command_flags flags);
FX_API fx_status fx_command_set_description(fx_command *cmd, const char *description); FX_API fx_status fx_command_set_description(
fx_command *cmd,
const char *description);
FX_API fx_status fx_command_set_callback( FX_API fx_status fx_command_set_callback(
fx_command *cmd, fx_command_callback callback); fx_command *cmd,
fx_command_callback callback);
FX_API fx_status fx_command_set_parent(fx_command *cmd, unsigned int parent_id); FX_API fx_status fx_command_set_parent(fx_command *cmd, unsigned int parent_id);
FX_API fx_command_option *fx_command_add_option(fx_command *cmd, int id); FX_API fx_command_option *fx_command_add_option(fx_command *cmd, int id);
FX_API fx_command_arg *fx_command_add_arg(fx_command *cmd, int id); FX_API fx_command_arg *fx_command_add_arg(fx_command *cmd, int id);
FX_API fx_command_usage *fx_command_add_usage(fx_command *cmd); FX_API fx_command_usage *fx_command_add_usage(fx_command *cmd);
FX_API const fx_command_option *fx_command_get_option(const fx_command *cmd, int id); FX_API const fx_command_option *fx_command_get_option(
const fx_command *cmd,
int id);
FX_API const char *fx_command_option_get_long_name(const fx_command_option *opt); FX_API const char *fx_command_option_get_long_name(
const fx_command_option *opt);
FX_API char fx_command_option_get_short_name(const fx_command_option *opt); FX_API char fx_command_option_get_short_name(const fx_command_option *opt);
FX_API const char *fx_command_option_get_description(fx_command_option *opt); FX_API const char *fx_command_option_get_description(fx_command_option *opt);
FX_API fx_status fx_command_option_set_long_name( FX_API fx_status fx_command_option_set_long_name(
fx_command_option *opt, const char *name); fx_command_option *opt,
FX_API fx_status fx_command_option_set_short_name(fx_command_option *opt, char name); const char *name);
FX_API fx_status fx_command_option_set_short_name(
fx_command_option *opt,
char name);
FX_API fx_status fx_command_option_set_description( FX_API fx_status fx_command_option_set_description(
fx_command_option *opt, const char *description); fx_command_option *opt,
FX_API fx_command_arg *fx_command_option_add_arg(fx_command_option *opt, int id); const char *description);
FX_API fx_command_arg *fx_command_option_add_arg(
fx_command_option *opt,
int id);
FX_API fx_status fx_command_arg_set_name(fx_command_arg *arg, const char *name); FX_API fx_status fx_command_arg_set_name(fx_command_arg *arg, const char *name);
FX_API fx_status fx_command_arg_set_description( FX_API fx_status fx_command_arg_set_description(
fx_command_arg *arg, const char *description); fx_command_arg *arg,
const char *description);
FX_API fx_status fx_command_arg_set_nr_values( FX_API fx_status fx_command_arg_set_nr_values(
fx_command_arg *arg, fx_command_arg_value_count nr_values); fx_command_arg *arg,
fx_command_arg_value_count nr_values);
FX_API fx_status fx_command_arg_set_allowed_values( FX_API fx_status fx_command_arg_set_allowed_values(
fx_command_arg *arg, const char **allowed_values); fx_command_arg *arg,
const char **allowed_values);
FX_API fx_status fx_command_usage_add_option( FX_API fx_status fx_command_usage_add_option(
fx_command_usage *usage, fx_command_option *opt); fx_command_usage *usage,
fx_command_option *opt);
FX_API fx_status fx_command_usage_add_arg( FX_API fx_status fx_command_usage_add_arg(
fx_command_usage *usage, fx_command_arg *opt); fx_command_usage *usage,
fx_command_arg *opt);
FX_API fx_status fx_command_usage_add_command( FX_API fx_status fx_command_usage_add_command(
fx_command_usage *usage, unsigned int cmd_id); fx_command_usage *usage,
unsigned int cmd_id);
FX_API fx_status fx_arglist_get_string( FX_API fx_status fx_arglist_get_string(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, const char **out); unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
const char **out);
FX_API fx_status fx_arglist_get_int( FX_API fx_status fx_arglist_get_int(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, long long *out); unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
long long *out);
FX_API fx_status fx_arglist_get_uint( FX_API fx_status fx_arglist_get_uint(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, unsigned long long *out); unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
unsigned long long *out);
FX_API fx_status fx_arglist_get_option( FX_API fx_status fx_arglist_get_option(
const fx_arglist *args, unsigned int opt_id, unsigned int index, const fx_arglist *args,
unsigned int opt_id,
unsigned int index,
fx_arglist_option **out); fx_arglist_option **out);
FX_API size_t fx_arglist_get_count( FX_API size_t fx_arglist_get_count(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id); const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id);
FX_API fx_status fx_arglist_report_missing_option( FX_API fx_status fx_arglist_report_missing_option(
const fx_arglist *args, unsigned int opt_id); const fx_arglist *args,
unsigned int opt_id);
FX_API fx_status fx_arglist_report_unexpected_arg( FX_API fx_status fx_arglist_report_unexpected_arg(
const fx_arglist *args, const char *value); const fx_arglist *args,
const char *value);
FX_API fx_status fx_arglist_report_invalid_arg_value( FX_API fx_status fx_arglist_report_invalid_arg_value(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id,
const char *value); const char *value);
FX_API fx_status fx_arglist_report_missing_args( FX_API fx_status fx_arglist_report_missing_args(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id,
size_t nr_supplied); size_t nr_supplied);
FX_API fx_status fx_arglist_option_get_value( FX_API fx_status fx_arglist_option_get_value(
const fx_arglist_option *opt, unsigned int arg_id, unsigned int index, const fx_arglist_option *opt,
unsigned int arg_id,
unsigned int index,
fx_arglist_value **out); fx_arglist_value **out);
FX_API int fx_arglist_iterator_begin( FX_API int fx_arglist_iterator_begin(
const fx_arglist *args, unsigned int opt_filter, unsigned int arg_filter, const fx_arglist *args,
unsigned int opt_filter,
unsigned int arg_filter,
fx_arglist_iterator *it); fx_arglist_iterator *it);
FX_API bool fx_arglist_iterator_next(fx_arglist_iterator *it); FX_API bool fx_arglist_iterator_next(fx_arglist_iterator *it);
FX_API bool fx_arglist_iterator_is_valid(const fx_arglist_iterator *it); FX_API bool fx_arglist_iterator_is_valid(const fx_arglist_iterator *it);
FX_API int fx_arglist_option_iterator_begin( FX_API int fx_arglist_option_iterator_begin(
const fx_arglist *args, unsigned int opt_filter, const fx_arglist *args,
unsigned int opt_filter,
fx_arglist_option_iterator *it); fx_arglist_option_iterator *it);
FX_API bool fx_arglist_option_iterator_next(fx_arglist_option_iterator *it); FX_API bool fx_arglist_option_iterator_next(fx_arglist_option_iterator *it);
FX_API bool fx_arglist_option_iterator_is_valid( FX_API bool fx_arglist_option_iterator_is_valid(
+27 -12
View File
@@ -1,7 +1,7 @@
#include "command.h" #include "command.h"
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -58,7 +58,8 @@ const char *fx_command_option_get_description(struct fx_command_option *opt)
} }
fx_status fx_command_option_set_long_name( fx_status fx_command_option_set_long_name(
struct fx_command_option *opt, const char *name) struct fx_command_option *opt,
const char *name)
{ {
char *n = fx_strdup(name); char *n = fx_strdup(name);
if (!n) { if (!n) {
@@ -74,14 +75,17 @@ fx_status fx_command_option_set_long_name(
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_option_set_short_name(struct fx_command_option *opt, char name) fx_status fx_command_option_set_short_name(
struct fx_command_option *opt,
char name)
{ {
opt->opt_short_name = name; opt->opt_short_name = name;
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_option_set_description( fx_status fx_command_option_set_description(
struct fx_command_option *opt, const char *description) struct fx_command_option *opt,
const char *description)
{ {
char *desc = fx_strdup(description); char *desc = fx_strdup(description);
if (!desc) { if (!desc) {
@@ -97,7 +101,9 @@ fx_status fx_command_option_set_description(
return FX_SUCCESS; return FX_SUCCESS;
} }
struct fx_command_arg *fx_command_option_add_arg(struct fx_command_option *opt, int id) struct fx_command_arg *fx_command_option_add_arg(
struct fx_command_option *opt,
int id)
{ {
struct fx_command_arg *arg = malloc(sizeof *arg); struct fx_command_arg *arg = malloc(sizeof *arg);
if (!arg) { if (!arg) {
@@ -139,7 +145,9 @@ void z__fx_get_option_description(struct fx_command_option *opt, fx_string *out)
if (nr_args > 1) { if (nr_args > 1) {
fx_string_append_cstrf( fx_string_append_cstrf(
out, "values for `%s`:", arg->arg_name); out,
"values for `%s`:",
arg->arg_name);
} else { } else {
fx_string_append_cstr(out, "values:"); fx_string_append_cstr(out, "values:");
} }
@@ -150,7 +158,8 @@ void z__fx_get_option_description(struct fx_command_option *opt, fx_string *out)
} }
fx_string_append_cstrf( fx_string_append_cstrf(
out, " " F_GREEN "%s" F_RESET, out,
" " F_GREEN "%s" F_RESET,
arg->arg_allowed_values[i]); arg->arg_allowed_values[i]);
} }
@@ -165,7 +174,9 @@ void z__fx_get_option_description(struct fx_command_option *opt, fx_string *out)
} }
void z__fx_get_option_usage_string( void z__fx_get_option_usage_string(
struct fx_command_option *opt, enum cmd_string_flags flags, fx_string *out) struct fx_command_option *opt,
enum cmd_string_flags flags,
fx_string *out)
{ {
if (flags & CMD_STR_DIRECT_USAGE) { if (flags & CMD_STR_DIRECT_USAGE) {
fx_string_append_cstr(out, "{"); fx_string_append_cstr(out, "{");
@@ -174,19 +185,22 @@ void z__fx_get_option_usage_string(
if (opt->opt_short_name) { if (opt->opt_short_name) {
fx_string_append_cstrf( fx_string_append_cstrf(
out, out,
(flags & CMD_STR_COLOUR) ? F_GREEN "-%c" F_RESET : "-%c", (flags & CMD_STR_COLOUR) ? F_GREEN "-%c" F_RESET
: "-%c",
opt->opt_short_name); opt->opt_short_name);
} }
if (opt->opt_short_name && opt->opt_long_name) { if (opt->opt_short_name && opt->opt_long_name) {
fx_string_append_cstr( fx_string_append_cstr(
out, (flags & CMD_STR_DIRECT_USAGE) ? "|" : ", "); out,
(flags & CMD_STR_DIRECT_USAGE) ? "|" : ", ");
} }
if (opt->opt_long_name) { if (opt->opt_long_name) {
fx_string_append_cstrf( fx_string_append_cstrf(
out, out,
(flags & CMD_STR_COLOUR) ? F_GREEN "--%s" F_RESET : "--%s", (flags & CMD_STR_COLOUR) ? F_GREEN "--%s" F_RESET
: "--%s",
opt->opt_long_name); opt->opt_long_name);
} }
@@ -254,7 +268,8 @@ void z__fx_get_option_usage_string(
} }
struct fx_command_arg *fx_command_option_get_arg_with_id( struct fx_command_arg *fx_command_option_get_arg_with_id(
struct fx_command_option *opt, unsigned int id) struct fx_command_option *opt,
unsigned int id)
{ {
struct fx_queue_entry *entry = fx_queue_first(&opt->opt_args); struct fx_queue_entry *entry = fx_queue_first(&opt->opt_args);
+59 -28
View File
@@ -1,13 +1,14 @@
#include "command.h" #include "command.h"
#include <assert.h> #include <assert.h>
#include <fx/core/stringstream.h> #include <fx/string.h>
#include <fx/ds/string.h> #include <fx/stringstream.h>
#include <fx/term/print.h> #include <fx/term/print.h>
#include <stdio.h> #include <stdio.h>
enum fx_status fx_arglist_report_missing_option( enum fx_status fx_arglist_report_missing_option(
const fx_arglist *args, unsigned int opt_id) const fx_arglist *args,
unsigned int opt_id)
{ {
struct fx_command_option *opt = NULL; struct fx_command_option *opt = NULL;
@@ -35,7 +36,10 @@ enum fx_status fx_arglist_report_missing_option(
if (opt_names == 2) { if (opt_names == 2) {
fx_stream_write_fmt( fx_stream_write_fmt(
opt_name, NULL, "-%c / --%s", opt->opt_short_name, opt_name,
NULL,
"-%c / --%s",
opt->opt_short_name,
opt->opt_long_name); opt->opt_long_name);
} else if (opt->opt_short_name) { } else if (opt->opt_short_name) {
fx_stream_write_fmt(opt_name, NULL, "-%c", opt->opt_short_name); fx_stream_write_fmt(opt_name, NULL, "-%c", opt->opt_short_name);
@@ -44,7 +48,7 @@ enum fx_status fx_arglist_report_missing_option(
} }
fx_err("required option `" F_YELLOW "%s" F_RESET "` was not specified.", fx_err("required option `" F_YELLOW "%s" F_RESET "` was not specified.",
fx_stringstream_ptr(opt_name)); fx_stringstream_ptr(opt_name));
fx_i("usage: %s", fx_string_get_cstr(opt_string)); fx_i("usage: %s", fx_string_get_cstr(opt_string));
fx_i("for more information, use `" F_YELLOW "--help" F_RESET "`"); fx_i("for more information, use `" F_YELLOW "--help" F_RESET "`");
@@ -55,10 +59,13 @@ enum fx_status fx_arglist_report_missing_option(
} }
enum fx_status fx_arglist_report_unexpected_arg( enum fx_status fx_arglist_report_unexpected_arg(
const fx_arglist *args, const char *value) const fx_arglist *args,
const char *value)
{ {
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
args->list_command, NULL, args); args->list_command,
NULL,
args);
fx_err("unexpected argument '" F_YELLOW "%s" F_RESET "' found.", value); fx_err("unexpected argument '" F_YELLOW "%s" F_RESET "' found.", value);
fx_i("usage: %s", fx_string_get_cstr(usage)); fx_i("usage: %s", fx_string_get_cstr(usage));
@@ -68,7 +75,9 @@ enum fx_status fx_arglist_report_unexpected_arg(
} }
enum fx_status fx_arglist_report_invalid_arg_value( enum fx_status fx_arglist_report_invalid_arg_value(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id,
const char *value) const char *value)
{ {
struct fx_command_option *opt = NULL; struct fx_command_option *opt = NULL;
@@ -80,11 +89,15 @@ enum fx_status fx_arglist_report_invalid_arg_value(
if (arg_id != FX_COMMAND_INVALID_ID) { if (arg_id != FX_COMMAND_INVALID_ID) {
arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id) arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id)
: fx_command_get_arg_with_id(args->list_command, arg_id); : fx_command_get_arg_with_id(
args->list_command,
arg_id);
} }
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
args->list_command, opt, args); args->list_command,
opt,
args);
fx_string *opt_string = fx_string_create(); fx_string *opt_string = fx_string_create();
if (opt) { if (opt) {
@@ -94,17 +107,20 @@ enum fx_status fx_arglist_report_invalid_arg_value(
} }
fx_err("invalid value '" F_YELLOW "%s" F_RESET "' for '" F_YELLOW fx_err("invalid value '" F_YELLOW "%s" F_RESET "' for '" F_YELLOW
"%s" F_RESET "'.", "%s" F_RESET "'.",
value, fx_string_get_cstr(opt_string)); value,
fx_string_get_cstr(opt_string));
if (opt) { if (opt) {
fx_i("'" F_YELLOW "%s" F_RESET fx_i("'" F_YELLOW "%s" F_RESET
"' accepts the following values for '" F_YELLOW "%s" F_RESET "' accepts the following values for '" F_YELLOW
"':", "%s" F_RESET "':",
fx_string_get_cstr(opt_string), arg->arg_name); fx_string_get_cstr(opt_string),
arg->arg_name);
} else { } else {
fx_i("'" F_YELLOW "%s" F_RESET "' accepts the following values:", fx_i("'" F_YELLOW "%s" F_RESET
fx_string_get_cstr(opt_string)); "' accepts the following values:",
fx_string_get_cstr(opt_string));
} }
for (int i = 0; arg->arg_allowed_values[i]; i++) { for (int i = 0; arg->arg_allowed_values[i]; i++) {
@@ -124,7 +140,9 @@ enum fx_status fx_arglist_report_invalid_arg_value(
} }
enum fx_status fx_arglist_report_missing_args( enum fx_status fx_arglist_report_missing_args(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id,
size_t args_supplied) size_t args_supplied)
{ {
struct fx_command_option *opt = NULL; struct fx_command_option *opt = NULL;
@@ -137,12 +155,16 @@ enum fx_status fx_arglist_report_missing_args(
if (arg_id != FX_COMMAND_INVALID_ID) { if (arg_id != FX_COMMAND_INVALID_ID) {
arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id) arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id)
: fx_command_get_arg_with_id(args->list_command, arg_id); : fx_command_get_arg_with_id(
args->list_command,
arg_id);
assert(arg); assert(arg);
} }
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
args->list_command, opt, args); args->list_command,
opt,
args);
fx_string *opt_string = fx_string_create(); fx_string *opt_string = fx_string_create();
if (opt) { if (opt) {
@@ -154,16 +176,19 @@ enum fx_status fx_arglist_report_missing_args(
char supplied_arg_str[64]; char supplied_arg_str[64];
if (args_supplied == 0) { if (args_supplied == 0) {
snprintf( snprintf(
supplied_arg_str, sizeof supplied_arg_str, supplied_arg_str,
sizeof supplied_arg_str,
F_RED_BOLD "none" F_RESET " were provided"); F_RED_BOLD "none" F_RESET " were provided");
} else if (args_supplied == 1) { } else if (args_supplied == 1) {
snprintf( snprintf(
supplied_arg_str, sizeof supplied_arg_str, supplied_arg_str,
sizeof supplied_arg_str,
"only " F_YELLOW_BOLD "%zu" F_RESET " was provided", "only " F_YELLOW_BOLD "%zu" F_RESET " was provided",
args_supplied); args_supplied);
} else { } else {
snprintf( snprintf(
supplied_arg_str, sizeof supplied_arg_str, supplied_arg_str,
sizeof supplied_arg_str,
"only " F_YELLOW_BOLD "%zu" F_RESET " were provided", "only " F_YELLOW_BOLD "%zu" F_RESET " were provided",
args_supplied); args_supplied);
} }
@@ -172,19 +197,25 @@ enum fx_status fx_arglist_report_missing_args(
switch (arg->arg_nr_values) { switch (arg->arg_nr_values) {
case FX_ARG_1_OR_MORE_VALUES: case FX_ARG_1_OR_MORE_VALUES:
snprintf( snprintf(
required_arg_count, sizeof required_arg_count, required_arg_count,
sizeof required_arg_count,
"one or more"); "one or more");
break; break;
default: default:
snprintf( snprintf(
required_arg_count, sizeof required_arg_count, "%d", required_arg_count,
sizeof required_arg_count,
"%d",
arg->arg_nr_values); arg->arg_nr_values);
} }
fx_err("argument `" F_YELLOW "%s" F_RESET "` requires " F_GREEN_BOLD fx_err("argument `" F_YELLOW "%s" F_RESET "` requires " F_GREEN_BOLD
"%s" F_RESET " `" F_YELLOW "%s" F_RESET "` value%s, but %s.", "%s" F_RESET " `" F_YELLOW "%s" F_RESET "` value%s, but %s.",
fx_string_get_cstr(opt_string), required_arg_count, arg->arg_name, fx_string_get_cstr(opt_string),
(arg->arg_nr_values == 1) ? "" : "s", supplied_arg_str); required_arg_count,
arg->arg_name,
(arg->arg_nr_values == 1) ? "" : "s",
supplied_arg_str);
fx_i("usage: %s", fx_string_get_cstr(usage)); fx_i("usage: %s", fx_string_get_cstr(usage));
fx_i("for more information, use '" F_YELLOW "--help" F_RESET "'"); fx_i("for more information, use '" F_YELLOW "--help" F_RESET "'");