From 77e358a001eea9a36e0c466b0af253d992c370bd Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 12 Oct 2013 01:46:22 -0700 Subject: [PATCH] Support for parsing e.g. 'command --' as a plain statement, instead of executing the command '--'. --- fish_tests.cpp | 2 ++ parse_productions.cpp | 33 ++++++++++++++++++++++++--------- parse_tree.cpp | 2 ++ parse_tree.h | 2 ++ 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/fish_tests.cpp b/fish_tests.cpp index 0cd7dbf08..3884e470e 100644 --- a/fish_tests.cpp +++ b/fish_tests.cpp @@ -2002,6 +2002,8 @@ static void test_new_parser_ll2(void) {L"command --help", L"command", L"--help", parse_statement_decoration_none}, {L"command -h", L"command", L"-h", parse_statement_decoration_none}, {L"command", L"command", L"", parse_statement_decoration_none}, + {L"command -", L"command", L"-", parse_statement_decoration_none}, + {L"command --", L"command", L"--", parse_statement_decoration_none}, {L"function", L"function", L"", parse_statement_decoration_none}, {L"function --help", L"function", L"--help", parse_statement_decoration_none} }; diff --git a/parse_productions.cpp b/parse_productions.cpp index 90e4a99b8..bb415e603 100644 --- a/parse_productions.cpp +++ b/parse_productions.cpp @@ -26,19 +26,32 @@ static bool production_is_valid(const production_options_t production_list, prod return nonempty_found; } -/* Helper function indicates whether a token (typically second token) means 'help'. This is so we can treat e.g. 'command --help' as "invoke the 'command' builtin with --help' instead of 'run the --help command'. +/* Helper function indicates whether a token (typically second token) causes the preceding token to be treated as a command instead of giving it a special role. This is so we can treat e.g. 'command --help' as "invoke the 'command' builtin with --help' instead of 'run the --help command'. if naked_invocation_invokes_help is true, then we treat an invalid type or something other than a string as indicating help; this means that the user ran e.g. 'command' with no arguments. */ -static inline bool token_means_help(parse_token_type_t type, parse_keyword_t keyword, bool naked_invocation_invokes_help) +static inline bool token_implies_previous_keyword_is_command(parse_token_type_t type, parse_keyword_t keyword, bool naked_invocation_invokes_help) { - if (keyword == parse_keyword_dash_h || keyword == parse_keyword_dashdash_help) - return true; + bool result = false; + switch (keyword) + { + case parse_keyword_dash: + case parse_keyword_dashdash: + case parse_keyword_dash_h: + case parse_keyword_dashdash_help: + result = true; + break; + + default: + break; + } - if (naked_invocation_invokes_help && type != parse_token_type_string) - return true; + if (! result) + { + result = naked_invocation_invokes_help && type != parse_token_type_string; + } - return false; + return result; } #define PRODUCTIONS(sym) static const production_options_t productions_##sym @@ -135,7 +148,7 @@ RESOLVE(statement) if (token_type == parse_token_type_string) { bool naked_invocation_invokes_help = (token_keyword != parse_keyword_begin && token_keyword != parse_keyword_end); - if (token_means_help(token_type2, token_keyword2, naked_invocation_invokes_help)) + if (token_implies_previous_keyword_is_command(token_type2, token_keyword2, naked_invocation_invokes_help)) { return 4; //decorated statement } @@ -175,6 +188,8 @@ RESOLVE(statement) case parse_keyword_command: case parse_keyword_builtin: case parse_keyword_case: + case parse_keyword_dash: + case parse_keyword_dashdash: case parse_keyword_dash_h: case parse_keyword_dashdash_help: return 4; @@ -365,7 +380,7 @@ PRODUCTIONS(decorated_statement) = RESOLVE(decorated_statement) { /* If this is e.g. 'command --help' then the command is 'command' and not a decoration */ - if (token_means_help(token_type2, token_keyword2, true /* naked_invocation_is_help */)) + if (token_implies_previous_keyword_is_command(token_type2, token_keyword2, true /* naked_invocation_is_help */)) return 0; switch (token_keyword) diff --git a/parse_tree.cpp b/parse_tree.cpp index a1acdb13b..793715ecb 100644 --- a/parse_tree.cpp +++ b/parse_tree.cpp @@ -784,6 +784,8 @@ static parse_keyword_t keyword_for_token(token_type tok, const wchar_t *tok_txt) {L"not", parse_keyword_not}, {L"command", parse_keyword_command}, {L"builtin", parse_keyword_builtin}, + {L"-", parse_keyword_dash}, + {L"--", parse_keyword_dashdash}, {L"-h", parse_keyword_dash_h}, {L"--help", parse_keyword_dashdash_help} }; diff --git a/parse_tree.h b/parse_tree.h index f6e913c25..c46eb9116 100644 --- a/parse_tree.h +++ b/parse_tree.h @@ -114,6 +114,8 @@ enum parse_keyword_t parse_keyword_builtin, /* The following are not really keywords but are necessary for e.g. "command --help" to work */ + parse_keyword_dash, + parse_keyword_dashdash, parse_keyword_dash_h, parse_keyword_dashdash_help,