From 9e08609f8543b81e35f5043dc0280cc9c30f0f70 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Wed, 19 Jul 2017 11:44:53 -0700 Subject: [PATCH] fix `argparse --help` Also stop special-casing `printf` as if it were a syntactical keyword with respect to handling `printf --help`. It should use the same pattern as every other builtin command. --- src/builtin.cpp | 6 +++--- src/builtin_argparse.cpp | 2 ++ src/builtin_printf.cpp | 30 ++++++++++++++++++++---------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index 4cb9da31f..de96b9ea6 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -107,7 +107,7 @@ void builtin_wperror(const wchar_t *s, io_streams_t &streams) { } } -static const wchar_t *short_options = L":h"; +static const wchar_t *short_options = L"+:h"; static const struct woption long_options[] = {{L"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}}; @@ -491,9 +491,9 @@ void builtin_destroy() {} /// Is there a builtin command with the given name? bool builtin_exists(const wcstring &cmd) { return static_cast(builtin_lookup(cmd)); } -/// Is the command a keyword or a builtin we need to special-case the handling of `-h` and `--help`. +/// Is the command a keyword we need to special-case the handling of `-h` and `--help`. static const wcstring_list_t help_builtins({L"for", L"while", L"function", L"if", L"end", L"switch", - L"case", L"printf"}); + L"case"}); static bool cmd_needs_help(const wchar_t *cmd) { return contains(help_builtins, cmd); } /// Execute a builtin command diff --git a/src/builtin_argparse.cpp b/src/builtin_argparse.cpp index 55b41bb2f..4488317a4 100644 --- a/src/builtin_argparse.cpp +++ b/src/builtin_argparse.cpp @@ -397,6 +397,8 @@ static int parse_cmd_opts(argparse_cmd_opts_t &opts, int *optind, //!OCLINT(hig } } + if (opts.print_help) return STATUS_CMD_OK; + if (argc == w.woptind || wcscmp(L"--", argv[w.woptind - 1]) == 0) { // The user didn't specify any option specs. streams.err.append_format(_(L"%ls: No option specs were provided\n"), cmd); diff --git a/src/builtin_printf.cpp b/src/builtin_printf.cpp index a6ff9c9fd..8595120d5 100644 --- a/src/builtin_printf.cpp +++ b/src/builtin_printf.cpp @@ -719,21 +719,31 @@ int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wch /// The printf builtin. int builtin_printf(parser_t &parser, io_streams_t &streams, wchar_t **argv) { - UNUSED(parser); - builtin_printf_state_t state(streams); - - wchar_t *format; - int args_used; + const wchar_t *cmd = argv[0]; int argc = builtin_count_args(argv); + help_only_cmd_opts_t opts; - if (argc <= 1) { - state.fatal_error(_(L"printf: not enough arguments")); + int optind; + int retval = parse_help_only_cmd_opts(opts, &optind, argc, argv, parser, streams); + if (retval != STATUS_CMD_OK) return retval; + + if (opts.print_help) { + builtin_print_help(parser, streams, cmd, streams.out); + return STATUS_CMD_OK; + } + + argc -= optind; + argv += optind; + if (argc < 1) { + streams.err.append_format(BUILTIN_ERR_MIN_ARG_COUNT1, cmd, 1, argc); return STATUS_INVALID_ARGS; } - format = argv[1]; - argc -= 2; - argv += 2; + builtin_printf_state_t state(streams); + int args_used; + wchar_t *format = argv[0]; + argc--; + argv++; do { args_used = state.print_formatted(format, argc, argv);