From 635327bce91d0025e7ba3bfa6a6c276f08c3eb19 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 31 Oct 2024 19:33:48 +0000 Subject: [PATCH] cmd: add support for showing placeholder commands/opts/args in command usage strings --- cmd/command.c | 56 ++++++++++++++++++++++++++++++++++++++++-- cmd/command.h | 6 +++++ cmd/include/blue/cmd.h | 16 ++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/cmd/command.c b/cmd/command.c index d951bb2..926c5a8 100644 --- a/cmd/command.c +++ b/cmd/command.c @@ -305,6 +305,21 @@ b_status b_command_usage_add_arg( 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); + if (!u_cmd) { + return B_ERR_NO_MEMORY; + } + + memset(u_cmd, 0x0, sizeof *u_cmd); + + u_cmd->cmd_id = cmd_id; + + b_queue_push_back(&usage->u_cmd, &u_cmd->cmd_entry); + return B_SUCCESS; +} + static void prepend_command_name(struct b_command *cmd, b_string *out) { int nr_names = 0; @@ -362,7 +377,33 @@ static void get_usage_string( { get_qualified_command_name(cmd, out); + 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); + + if (!subcmd) { + 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 { + struct b_command *subcmd_info + = get_command(&command_list, subcmd->cmd_id); + prepend_command_name(subcmd_info, cmd_name); + + b_string_append_s(out, cmd_name); + } + } + + 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); @@ -372,7 +413,13 @@ static void get_usage_string( } b_string_append_cstr(out, " "); - z__b_get_option_usage_string(opt->opt, CMD_STR_DIRECT_USAGE, out); + + if (opt->opt == (struct b_command_option *)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) { @@ -384,7 +431,12 @@ static void get_usage_string( } b_string_append_cstr(out, " "); - z__b_get_arg_usage_string(arg->arg, false, out); + + if (arg->arg == (struct b_command_arg *)B_COMMAND_INVALID_ID) { + b_string_append_cstr(out, "[ARGS]"); + } else { + z__b_get_arg_usage_string(arg->arg, false, out); + } } } diff --git a/cmd/command.h b/cmd/command.h index dd0794d..8a949df 100644 --- a/cmd/command.h +++ b/cmd/command.h @@ -51,10 +51,16 @@ struct b_command_usage_arg { struct b_command_arg *arg; }; +struct b_command_usage_command { + struct b_queue_entry cmd_entry; + unsigned int cmd_id; +}; + struct b_command_usage { b_command_usage_flags u_flags; struct b_queue_entry u_entry; + struct b_queue u_cmd; struct b_queue u_opt; struct b_queue u_arg; }; diff --git a/cmd/include/blue/cmd.h b/cmd/include/blue/cmd.h index 99989cb..8f0781e 100644 --- a/cmd/include/blue/cmd.h +++ b/cmd/include/blue/cmd.h @@ -94,12 +94,26 @@ this_usage = z__b_unique_name(); \ if (this_usage) +#define B_COMMAND_USAGE_COMMAND(cmd_id) \ + b_command_usage_add_command(this_usage, cmd_id) + +#define B_COMMAND_USAGE_COMMAND_PLACEHOLDER() \ + b_command_usage_add_command(this_usage, B_COMMAND_INVALID_ID) + #define B_COMMAND_USAGE_OPT(opt_id) \ b_command_usage_add_option(this_usage, opt_##opt_id) +#define B_COMMAND_USAGE_OPT_PLACEHOLDER() \ + b_command_usage_add_option( \ + this_usage, (struct b_command_option *)B_COMMAND_INVALID_ID) + #define B_COMMAND_USAGE_ARG(opt_id) \ b_command_usage_add_arg(this_usage, arg_##opt_id) +#define B_COMMAND_USAGE_ARG_PLACEHOLDER() \ + b_command_usage_add_arg( \ + this_usage, (struct b_command_arg *)B_COMMAND_INVALID_ID) + #define B_COMMAND_OPTION_HELP ((unsigned int)0xF0000001) #define B_COMMAND_INVALID_ID ((unsigned int)0xFFFFFFFF) @@ -192,6 +206,8 @@ extern b_status b_command_arg_set_allowed_values( extern b_status b_command_usage_add_option( b_command_usage *usage, b_command_option *opt); extern b_status b_command_usage_add_arg(b_command_usage *usage, b_command_arg *opt); +extern b_status b_command_usage_add_command( + b_command_usage *usage, unsigned int cmd_id); extern b_status b_arglist_get_string( const b_arglist *args, unsigned int opt_id, unsigned int arg_id,