diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2014-03-18 14:14:32 -0700 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2014-03-20 21:32:02 -0700 |
commit | e5ef45e4c04b6126ea74c4010b2d8fe1c0b06cca (patch) | |
tree | d200c10a700c9cfae10d170a600acfda8508086a /parser.cpp | |
parent | e780637cf42bc8d26e0e963f5ff84b11007459c5 (diff) |
Rewrite parser_t::test_args and parser_t::eval_args to use new parser
Diffstat (limited to 'parser.cpp')
-rw-r--r-- | parser.cpp | 95 |
1 files changed, 40 insertions, 55 deletions
@@ -547,7 +547,7 @@ void parser_t::print_errors_stderr() } -void parser_t::eval_args(const wcstring &arg_list_src, std::vector<completion_t> &output_arg_list) +void parser_t::expand_argument_list(const wcstring &arg_list_src, std::vector<completion_t> &output_arg_list) { expand_flags_t eflags = 0; if (! show_errors) @@ -828,14 +828,15 @@ wcstring parser_t::current_line() } } - bool skip_caret = get_is_interactive() && ! is_function(); + bool is_interactive = get_is_interactive(); + bool skip_caret = is_interactive && ! is_function(); /* Use an error with empty text */ assert(source_offset >= 0); parse_error_t empty_error = {}; empty_error.source_start = source_offset; - wcstring line_info = empty_error.describe_with_prefix(context->get_source(), prefix, skip_caret); + wcstring line_info = empty_error.describe_with_prefix(context->get_source(), prefix, is_interactive, skip_caret); if (! line_info.empty()) { line_info.push_back(L'\n'); @@ -1206,69 +1207,52 @@ int parser_t::parser_test_argument(const wchar_t *arg, wcstring *out, const wcha } -int parser_t::test_args(const wchar_t * buff, wcstring *out, const wchar_t *prefix) +bool parser_t::detect_errors_in_argument_list(const wcstring &arg_list_src, wcstring *out, const wchar_t *prefix) { - int do_loop = 1; - int err = 0; - - CHECK(buff, 1); - - tokenizer_t tok(buff, 0); - scoped_push<tokenizer_t*> tokenizer_push(¤t_tokenizer, &tok); - scoped_push<int> tokenizer_pos_push(¤t_tokenizer_pos); + bool errored = false; + parse_error_list_t errors; - for (; do_loop && tok_has_next(&tok); tok_next(&tok)) + /* Use empty string for the prefix if it's NULL */ + if (prefix == NULL) { - current_tokenizer_pos = tok_get_pos(&tok); - switch (tok_last_type(&tok)) - { - - case TOK_STRING: - { - err |= parser_test_argument(tok_last(&tok), out, prefix, tok_get_pos(&tok)); - break; - } + prefix = L""; + } - case TOK_END: - { - break; - } + /* Parse the string as an argument list */ + parse_node_tree_t tree; + if (! parse_tree_from_string(arg_list_src, parse_flag_none, &tree, &errors, symbol_argument_list)) + { + /* Failed to parse. */ + errored = true; + } - case TOK_ERROR: - { - if (out) - { - error(SYNTAX_ERROR, - tok_get_pos(&tok), - TOK_ERR_MSG, - tok_last(&tok)); - print_errors(*out, prefix); - } - err=1; - do_loop=0; - break; - } + if (! errored) + { + /* Get the root argument list */ + assert(! tree.empty()); + const parse_node_t *arg_list = &tree.at(0); + assert(arg_list->type == symbol_argument_list); - default: + /* Extract arguments from it */ + while (arg_list != NULL && ! errored) + { + const parse_node_t *arg_node = tree.next_node_in_node_list(*arg_list, symbol_argument, &arg_list); + if (arg_node != NULL) { - if (out) + const wcstring arg_src = arg_node->get_source(arg_list_src); + if (parse_util_detect_errors_in_argument(*arg_node, arg_src, &errors)) { - error(SYNTAX_ERROR, - tok_get_pos(&tok), - UNEXPECTED_TOKEN_ERR_MSG, - tok_get_desc(tok_last_type(&tok))); - print_errors(*out, prefix); + errored = true; } - err=1; - do_loop=0; - break; } } } - error_code=0; - - return err; + if (! errors.empty() && out != NULL) + { + out->assign(errors.at(0).describe_with_prefix(arg_list_src, prefix, false /* not interactive */, false /* don't skip caret */)); + } + return errored; } // helper type used in parser::test below @@ -1290,7 +1274,8 @@ void parser_t::get_backtrace(const wcstring &src, const parse_error_list_t &erro size_t which_line = 1 + std::count(src.begin(), src.begin() + err.source_start, L'\n'); // Don't include the caret if we're interactive, this is the first line of text, and our source is at its beginning, because then it's obvious - bool skip_caret = (get_is_interactive() && which_line == 1 && err.source_start == 0); + bool is_interactive = get_is_interactive(); + bool skip_caret = (is_interactive && which_line == 1 && err.source_start == 0); wcstring prefix; @@ -1304,7 +1289,7 @@ void parser_t::get_backtrace(const wcstring &src, const parse_error_list_t &erro prefix = L"fish: "; } - const wcstring description = err.describe_with_prefix(src, prefix, skip_caret); + const wcstring description = err.describe_with_prefix(src, prefix, is_interactive, skip_caret); if (! description.empty()) { output->append(description); |