diff --git a/builtin.cpp b/builtin.cpp index b52c8e9eb..e4a3bf6ff 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -1038,20 +1038,22 @@ static int builtin_emit(parser_t &parser, wchar_t **argv) static int builtin_generic(parser_t &parser, wchar_t **argv) { int argc=builtin_count_args(argv); + + /* Hackish - if we have no arguments other than the command, we are a "naked invocation" and we just print help */ + if (argc == 1) + { + builtin_print_help(parser, argv[0], stdout_buffer); + return STATUS_BUILTIN_ERROR; + } + woptind=0; static const struct woption long_options[] = { - { - L"help", no_argument, 0, 'h' - } - , - { - 0, 0, 0, 0 - } - } - ; + { L"help", no_argument, 0, 'h' }, + { 0, 0, 0, 0 } + }; while (1) { @@ -2060,6 +2062,13 @@ int define_function(parser_t &parser, const wcstring_list_t &c_args, const wcstr */ static int builtin_function(parser_t &parser, wchar_t **argv) { + /* Hack hack hack - with the new parser, this is only invoked for help */ + if (parser_use_ast()) + { + builtin_print_help(parser, argv[0], stdout_buffer); + return STATUS_BUILTIN_OK; + } + int argc = builtin_count_args(argv); int res=STATUS_BUILTIN_OK; wchar_t *desc=0; @@ -3662,6 +3671,12 @@ static int builtin_for(parser_t &parser, wchar_t **argv) int argc = builtin_count_args(argv); int res=STATUS_BUILTIN_ERROR; + /* Hackish - if we have no arguments other than the command, we are a "naked invocation" and we just print help */ + if (argc == 1) + { + builtin_print_help(parser, argv[0], stdout_buffer); + return STATUS_BUILTIN_ERROR; + } if (argc < 3) { @@ -4048,6 +4063,13 @@ static int builtin_switch(parser_t &parser, wchar_t **argv) { int res=STATUS_BUILTIN_OK; int argc = builtin_count_args(argv); + + /* Hackish - if we have no arguments other than the command, we are a "naked invocation" and we just print help */ + if (argc == 1) + { + builtin_print_help(parser, argv[0], stdout_buffer); + return STATUS_BUILTIN_ERROR; + } if (argc != 2) { diff --git a/parse_tree.cpp b/parse_tree.cpp index ee401a451..536520fc8 100644 --- a/parse_tree.cpp +++ b/parse_tree.cpp @@ -240,6 +240,39 @@ wcstring keyword_description(parse_keyword_t k) return format_string(L"Unknown keyword type %ld", static_cast(k)); } +static wcstring token_type_user_presentable_description(parse_token_type_t type, parse_keyword_t keyword) +{ + if (keyword != parse_keyword_none) + { + return format_string(L"keyword '%ls'", keyword_description(keyword).c_str()); + } + + switch (type) + { + /* Hackish. We only support the following types. */ + case symbol_statement: + return L"a command"; + + case parse_token_type_string: + return L"a string"; + + case parse_token_type_pipe: + return L"a pipe"; + + case parse_token_type_redirection: + return L"a redirection"; + + case parse_token_type_background: + return L"a '&'"; + + case parse_token_type_end: + return L"end of the statement"; + + default: + return format_string(L"a %ls", token_type_description(type).c_str()); + } +} + /** Returns a string description of the given parse node */ wcstring parse_node_t::describe(void) const { @@ -263,32 +296,7 @@ wcstring parse_token_t::describe() const /** A string description appropriate for presentation to the user */ wcstring parse_token_t::user_presentable_description() const { - if (keyword != parse_keyword_none) - { - return format_string(L"keyword %ls", keyword_description(keyword).c_str()); - } - - switch (type) - { - /* Hackish. We only support the */ - case parse_token_type_string: - return L"a string"; - - case parse_token_type_pipe: - return L"a pipe"; - - case parse_token_type_redirection: - return L"a redirection"; - - case parse_token_type_background: - return L"a '&'"; - - case parse_token_type_end: - return L"statement terminator"; - - default: - return format_string(L"a %ls", this->describe().c_str()); - } + return token_type_user_presentable_description(type, keyword); } /* Convert from tokenizer_t's token type to a parse_token_t type */ @@ -443,20 +451,7 @@ struct parse_stack_element_t /* Returns a name that we can show to the user, e.g. "a command" */ wcstring user_presentable_description(void) const { - if (keyword != parse_keyword_none) - { - return format_string(L"keyword %ls", keyword_description(keyword).c_str()); - } - - switch (type) - { - /* Hackish, the only one we support now */ - case symbol_statement: - return L"a command"; - - default: - return format_string(L"a %ls", this->describe().c_str()); - } + return token_type_user_presentable_description(type, keyword); } }; @@ -751,7 +746,8 @@ void parse_ll_t::parse_error_unbalancing_token(parse_token_t token) // This is a 'generic' parse error when we can't match the top of the stack element void parse_ll_t::parse_error_failed_production(struct parse_stack_element_t &stack_elem, parse_token_t token) { - this->parse_error(token, parse_error_generic, L"Expected %ls, but instead found %ls", stack_elem.user_presentable_description().c_str(), token.user_presentable_description().c_str()); + const wcstring expected = stack_elem.user_presentable_description(); + this->parse_error(expected.c_str(), token); } void parse_ll_t::report_tokenizer_error(parse_token_t token, const wchar_t *tok_error) @@ -765,8 +761,7 @@ void parse_ll_t::parse_error(const wchar_t *expected, parse_token_t token) fatal_errored = true; if (this->should_generate_error_messages) { - wcstring desc = token.user_presentable_description(); - this->parse_error(token, parse_error_generic, L"Expected a %ls, instead got a token of type %ls", expected, desc.c_str()); + this->parse_error(token, parse_error_generic, L"Expected %ls, but instead found %ls", expected, token.user_presentable_description().c_str()); } }