mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-01 07:38:46 +00:00
Migrate parse_util_detect_errors to a free function
This commit is contained in:
parent
2c3bc1e857
commit
29dede8139
5 changed files with 39 additions and 43 deletions
|
@ -303,11 +303,10 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||||
prefix.append(cmd);
|
prefix.append(cmd);
|
||||||
prefix.append(L": ");
|
prefix.append(L": ");
|
||||||
|
|
||||||
wcstring err_text;
|
if (maybe_t<wcstring> err_text = parse_util_detect_errors_in_argument_list(comp, prefix)) {
|
||||||
if (parser.detect_errors_in_argument_list(comp, &err_text, prefix.c_str())) {
|
|
||||||
streams.err.append_format(L"%ls: Completion '%ls' contained a syntax error\n", cmd,
|
streams.err.append_format(L"%ls: Completion '%ls' contained a syntax error\n", cmd,
|
||||||
comp);
|
comp);
|
||||||
streams.err.append(err_text);
|
streams.err.append(*err_text);
|
||||||
streams.err.push_back(L'\n');
|
streams.err.push_back(L'\n');
|
||||||
return STATUS_CMD_ERROR;
|
return STATUS_CMD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1333,3 +1333,35 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src,
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybe_t<wcstring> parse_util_detect_errors_in_argument_list(const wcstring &arg_list_src,
|
||||||
|
const wcstring &prefix) {
|
||||||
|
// Helper to return a description of the first error.
|
||||||
|
auto get_error_text = [&](const parse_error_list_t &errors) {
|
||||||
|
assert(!errors.empty() && "Expected an error");
|
||||||
|
return errors.at(0).describe_with_prefix(arg_list_src, prefix, false /* not interactive */,
|
||||||
|
false /* don't skip caret */);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse the string as an argument list.
|
||||||
|
parse_error_list_t errors;
|
||||||
|
parse_node_tree_t tree;
|
||||||
|
if (!parse_tree_from_string(arg_list_src, parse_flag_none, &tree, &errors,
|
||||||
|
symbol_freestanding_argument_list)) {
|
||||||
|
// Failed to parse.
|
||||||
|
return get_error_text(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the root argument list and extract arguments from it.
|
||||||
|
// Test each of these.
|
||||||
|
assert(!tree.empty() && "Should have parsed a tree");
|
||||||
|
tnode_t<grammar::freestanding_argument_list> arg_list(&tree, &tree.at(0));
|
||||||
|
while (auto arg = arg_list.next_in_list<grammar::argument>()) {
|
||||||
|
const wcstring arg_src = arg.get_source(arg_list_src);
|
||||||
|
if (parse_util_detect_errors_in_argument(arg, arg_src, &errors)) {
|
||||||
|
return get_error_text(errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return none();
|
||||||
|
}
|
||||||
|
|
|
@ -132,6 +132,11 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src,
|
||||||
bool allow_incomplete = true,
|
bool allow_incomplete = true,
|
||||||
parsed_source_ref_t *out_pstree = NULL);
|
parsed_source_ref_t *out_pstree = NULL);
|
||||||
|
|
||||||
|
/// Detect errors in the specified string when parsed as an argument list. Returns the text of an
|
||||||
|
/// error, or none if no error occurred.
|
||||||
|
maybe_t<wcstring> parse_util_detect_errors_in_argument_list(const wcstring &arg_list_src,
|
||||||
|
const wcstring &prefix = {});
|
||||||
|
|
||||||
/// Test if this argument contains any errors. Detected errors include syntax errors in command
|
/// Test if this argument contains any errors. Detected errors include syntax errors in command
|
||||||
/// substitutions, improperly escaped characters and improper use of the variable expansion
|
/// substitutions, improperly escaped characters and improper use of the variable expansion
|
||||||
/// operator. This does NOT currently detect unterminated quotes.
|
/// operator. This does NOT currently detect unterminated quotes.
|
||||||
|
|
|
@ -680,41 +680,6 @@ template int parser_t::eval_node(parsed_source_ref_t, tnode_t<grammar::job_list>
|
||||||
const io_chain_t &, enum block_type_t,
|
const io_chain_t &, enum block_type_t,
|
||||||
std::shared_ptr<job_t> parent_job);
|
std::shared_ptr<job_t> parent_job);
|
||||||
|
|
||||||
bool parser_t::detect_errors_in_argument_list(const wcstring &arg_list_src, wcstring *out,
|
|
||||||
const wchar_t *prefix) const {
|
|
||||||
bool errored = false;
|
|
||||||
parse_error_list_t errors;
|
|
||||||
|
|
||||||
// Use empty string for the prefix if it's NULL.
|
|
||||||
if (!prefix) prefix = L""; //!OCLINT(parameter reassignment)
|
|
||||||
|
|
||||||
// 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_freestanding_argument_list)) {
|
|
||||||
// Failed to parse.
|
|
||||||
errored = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!errored) {
|
|
||||||
// Get the root argument list and extract arguments from it.
|
|
||||||
assert(!tree.empty()); //!OCLINT(multiple unary operator)
|
|
||||||
tnode_t<grammar::freestanding_argument_list> arg_list(&tree, &tree.at(0));
|
|
||||||
while (auto arg = arg_list.next_in_list<grammar::argument>()) {
|
|
||||||
const wcstring arg_src = arg.get_source(arg_list_src);
|
|
||||||
if (parse_util_detect_errors_in_argument(arg, arg_src, &errors)) {
|
|
||||||
errored = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parser_t::get_backtrace(const wcstring &src, const parse_error_list_t &errors,
|
void parser_t::get_backtrace(const wcstring &src, const parse_error_list_t &errors,
|
||||||
wcstring &output) const {
|
wcstring &output) const {
|
||||||
if (!errors.empty()) {
|
if (!errors.empty()) {
|
||||||
|
|
|
@ -335,11 +335,6 @@ class parser_t : public std::enable_shared_from_this<parser_t> {
|
||||||
void get_backtrace(const wcstring &src, const parse_error_list_t &errors,
|
void get_backtrace(const wcstring &src, const parse_error_list_t &errors,
|
||||||
wcstring &output) const;
|
wcstring &output) const;
|
||||||
|
|
||||||
/// Detect errors in the specified string when parsed as an argument list. Returns true if an
|
|
||||||
/// error occurred.
|
|
||||||
bool detect_errors_in_argument_list(const wcstring &arg_list_src, wcstring *out_err,
|
|
||||||
const wchar_t *prefix) const;
|
|
||||||
|
|
||||||
/// Tell the parser that the specified function may not be run if not inside of a conditional
|
/// Tell the parser that the specified function may not be run if not inside of a conditional
|
||||||
/// block. This is to remove some possibilities of infinite recursion.
|
/// block. This is to remove some possibilities of infinite recursion.
|
||||||
void forbid_function(const wcstring &function);
|
void forbid_function(const wcstring &function);
|
||||||
|
|
Loading…
Reference in a new issue