diff --git a/cmd/arglist.c b/cmd/arglist.c index 9314c92..dc3d3c1 100644 --- a/cmd/arglist.c +++ b/cmd/arglist.c @@ -229,6 +229,8 @@ static b_status parse_arg(struct argv_parser *parser) = b_command_get_subcommand_with_name(parser->cmd, value); if (subcmd) { move_to_subcommand(parser, subcmd); + parser->arglist->list_argv_last_command + = parser->index + 1; advance(parser); continue; } @@ -309,13 +311,15 @@ static b_status parse_short_opt(struct argv_parser *parser) if (subcmd) { move_to_subcommand(parser, subcmd); + parser->arglist->list_argv_last_command + = parser->index + 1; flags++; continue; } if (!opt) { struct b_string *usage = z__b_command_default_usage_string( - parser->cmd, NULL); + parser->cmd, NULL, parser->arglist); b_err("unrecognised argument '" F_YELLOW "-%c" F_RESET "'\n\n", flag, b_string_ptr(usage)); @@ -452,8 +456,8 @@ static b_status parse_long_opt(struct argv_parser *parser) } if (!opt && !subcmd) { - struct b_string *usage - = z__b_command_default_usage_string(parser->cmd, NULL); + struct b_string *usage = z__b_command_default_usage_string( + parser->cmd, NULL, parser->arglist); b_err("unrecognised argument '" F_YELLOW "--%s" F_RESET "'\n\nusage: %s\n\nfor more information, use '" F_YELLOW "--help" F_RESET "'\n", @@ -466,7 +470,8 @@ static b_status parse_long_opt(struct argv_parser *parser) advance(parser); if (subcmd) { - parser->cmd = subcmd; + move_to_subcommand(parser, subcmd); + parser->arglist->list_argv_last_command = parser->index + 1; return B_SUCCESS; } @@ -591,8 +596,11 @@ static bool should_show_help(struct b_command *cmd, struct b_arglist *args) b_status b_arglist_parse( struct b_arglist *args, struct b_command **cmd, int argc, const char **argv) { - struct argv_parser parser - = {.arglist = args, .argc = argc - 1, .argv = argv + 1}; + struct argv_parser parser = { + .arglist = args, + .argc = argc - 1, + .argv = argv + 1, + }; move_to_subcommand(&parser, *cmd); diff --git a/cmd/command.c b/cmd/command.c index 60bf16e..b305204 100644 --- a/cmd/command.c +++ b/cmd/command.c @@ -352,8 +352,17 @@ static void prepend_command_name(struct b_command *cmd, b_string *out) } } -static void get_qualified_command_name(struct b_command *cmd, b_string *out) +static void get_qualified_command_name( + struct b_command *cmd, const struct b_arglist *args, b_string *out) { + for (unsigned int i = 0; i <= args->list_argv_last_command; i++) { + if (i > 0) { + b_string_append_cstr(out, " "); + } + + b_string_append_cstr(out, args->list_argv[i]); + } +#if 0 prepend_command_name(cmd, out); cmd = cmd->b_parent; @@ -362,12 +371,14 @@ static void get_qualified_command_name(struct b_command *cmd, b_string *out) prepend_command_name(cmd, out); cmd = cmd->b_parent; } +#endif } static void get_usage_string( - struct b_command *cmd, struct b_command_usage *usage, b_string *out) + struct b_command *cmd, struct b_arglist *args, + struct b_command_usage *usage, b_string *out) { - get_qualified_command_name(cmd, out); + get_qualified_command_name(cmd, args, out); struct b_string *cmd_name = b_string_create(); @@ -421,10 +432,11 @@ static void get_usage_string( } b_string *z__b_command_default_usage_string( - struct b_command *cmd, struct b_command_option *with_opt) + struct b_command *cmd, struct b_command_option *with_opt, + const struct b_arglist *args) { b_string *str = b_string_create(); - get_qualified_command_name(cmd, str); + get_qualified_command_name(cmd, args, str); if (with_opt) { b_string_append_cstr(str, " "); @@ -848,7 +860,7 @@ struct b_command_arg *b_command_get_arg_with_id( return NULL; } -static void print_usage(struct b_command *cmd) +static void print_usage(struct b_command *cmd, struct b_arglist *args) { b_paragraph_format format = {0}; format.p_left_margin = format.p_right_margin = 4; @@ -856,7 +868,8 @@ static void print_usage(struct b_command *cmd) b_tty_puts(OUTPUT_STREAM, 0, F_YELLOW "USAGE:" F_RESET "\n"); if (b_queue_empty(&cmd->b_usage)) { - b_string *usage = z__b_command_default_usage_string(cmd, NULL); + b_string *usage + = z__b_command_default_usage_string(cmd, NULL, args); b_print_paragraph(b_string_ptr(usage), OUTPUT_STREAM, &format); b_string_release(usage); return; @@ -872,14 +885,14 @@ static void print_usage(struct b_command *cmd) } b_string_clear(str); - get_usage_string(cmd, usage, str); + get_usage_string(cmd, args, usage, str); b_print_paragraph(b_string_ptr(str), OUTPUT_STREAM, &format); } b_string_release(str); } -static void print_help(struct b_command *cmd) +static void print_help(struct b_command *cmd, struct b_arglist *args) { b_paragraph_format format = {0}; @@ -894,7 +907,7 @@ static void print_help(struct b_command *cmd) b_tty_putc(OUTPUT_STREAM, 0, '\n'); - print_usage(cmd); + print_usage(cmd, args); if (!b_queue_empty(&cmd->b_opt)) { print_options_list(cmd); @@ -921,12 +934,12 @@ static int execute_command(struct b_command *cmd, struct b_arglist *args) args, B_COMMAND_OPTION_HELP, B_COMMAND_INVALID_ID); if ((cmd->b_flags & B_COMMAND_SHOW_HELP_BY_DEFAULT) && nr_items == 0) { - print_help(cmd); + print_help(cmd, args); return 0; } if (nr_help > 0) { - print_help(cmd); + print_help(cmd, args); return 0; } @@ -978,6 +991,8 @@ int b_command_dispatch(unsigned int cmd_id, int argc, const char **argv) } struct b_arglist *args = b_arglist_create(); + args->list_argc = argc; + args->list_argv = argv; args->list_command = cmd; b_status status = b_arglist_parse(args, &cmd, argc, argv); diff --git a/cmd/command.h b/cmd/command.h index 694f56b..01752ae 100644 --- a/cmd/command.h +++ b/cmd/command.h @@ -98,6 +98,9 @@ struct b_arglist_option { }; struct b_arglist { + size_t list_argc; + const char **list_argv; + unsigned int list_argv_last_command; struct b_command *list_command; struct b_btree list_options; }; @@ -134,7 +137,8 @@ BLUE_API b_status b_arglist_parse( BLUE_API void b_arglist_destroy(struct b_arglist *args); BLUE_API struct b_string *z__b_command_default_usage_string( - struct b_command *cmd, struct b_command_option *with_opt); + struct b_command *cmd, struct b_command_option *with_opt, + const struct b_arglist *args); BLUE_API void z__b_get_arg_usage_string( struct b_command_arg *arg, bool colour, struct b_string *out); diff --git a/cmd/report.c b/cmd/report.c index 74ae677..aebb08a 100644 --- a/cmd/report.c +++ b/cmd/report.c @@ -57,8 +57,8 @@ enum b_status b_arglist_report_missing_option( 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); + 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)); @@ -83,8 +83,8 @@ enum b_status b_arglist_report_invalid_arg_value( : 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 *usage = z__b_command_default_usage_string( + args->list_command, opt, args); struct b_string *opt_string = b_string_create(); if (opt) { @@ -139,8 +139,8 @@ enum b_status b_arglist_report_missing_args( : 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 *usage = z__b_command_default_usage_string( + args->list_command, opt, args); struct b_string *opt_string = b_string_create(); if (opt) {