mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-28 04:03:39 +08:00
Continued adoption of tnode in parse_execution.cpp
This commit is contained in:
parent
9c88d71e2f
commit
2bf96493fc
|
@ -170,13 +170,12 @@ tnode_t<g::plain_statement> parse_execution_context_t::infinite_recursive_statem
|
|||
}
|
||||
|
||||
enum process_type_t parse_execution_context_t::process_type_for_command(
|
||||
const parse_node_t &plain_statement, const wcstring &cmd) const {
|
||||
assert(plain_statement.type == symbol_plain_statement);
|
||||
tnode_t<grammar::plain_statement> statement, const wcstring &cmd) const {
|
||||
enum process_type_t process_type = EXTERNAL;
|
||||
|
||||
// Determine the process type, which depends on the statement decoration (command, builtin,
|
||||
// etc).
|
||||
enum parse_statement_decoration_t decoration = get_decoration({&tree(), &plain_statement});
|
||||
enum parse_statement_decoration_t decoration = get_decoration(statement);
|
||||
|
||||
if (decoration == parse_statement_decoration_exec) {
|
||||
// Always exec.
|
||||
|
@ -342,8 +341,10 @@ parse_execution_result_t parse_execution_context_t::run_begin_statement(
|
|||
parse_execution_result_t parse_execution_context_t::run_function_statement(
|
||||
tnode_t<g::function_header> header, tnode_t<g::end_command> block_end_command) {
|
||||
// Get arguments.
|
||||
wcstring_list_t argument_list;
|
||||
parse_execution_result_t result = this->determine_arguments(header, &argument_list, failglob);
|
||||
wcstring_list_t arguments;
|
||||
argument_node_list_t arg_nodes = header.descendants<g::argument>();
|
||||
parse_execution_result_t result =
|
||||
this->expand_arguments_from_nodes(arg_nodes, &arguments, failglob);
|
||||
|
||||
if (result != parse_execution_success) {
|
||||
return result;
|
||||
|
@ -371,8 +372,7 @@ parse_execution_result_t parse_execution_context_t::run_function_statement(
|
|||
wcstring(pstree->src, contents_start, contents_end - contents_start);
|
||||
int definition_line_offset = this->line_offset_of_character_at_offset(contents_start);
|
||||
io_streams_t streams(0); // no limit on the amount of output from builtin_function()
|
||||
int err =
|
||||
builtin_function(*parser, streams, argument_list, contents_str, definition_line_offset);
|
||||
int err = builtin_function(*parser, streams, arguments, contents_str, definition_line_offset);
|
||||
proc_set_last_status(err);
|
||||
|
||||
if (!streams.err.empty()) {
|
||||
|
@ -426,8 +426,9 @@ parse_execution_result_t parse_execution_context_t::run_for_statement(
|
|||
}
|
||||
|
||||
// Get the contents to iterate over.
|
||||
wcstring_list_t argument_sequence;
|
||||
parse_execution_result_t ret = this->determine_arguments(header, &argument_sequence, nullglob);
|
||||
wcstring_list_t arguments;
|
||||
parse_execution_result_t ret = this->expand_arguments_from_nodes(
|
||||
get_argument_nodes(header.child<3>()), &arguments, nullglob);
|
||||
if (ret != parse_execution_success) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -446,14 +447,12 @@ parse_execution_result_t parse_execution_context_t::run_for_statement(
|
|||
for_block_t *fb = parser->push_block<for_block_t>();
|
||||
|
||||
// Now drive the for loop.
|
||||
const size_t arg_count = argument_sequence.size();
|
||||
for (size_t i = 0; i < arg_count; i++) {
|
||||
for (const wcstring &val : arguments) {
|
||||
if (should_cancel_execution(fb)) {
|
||||
ret = parse_execution_cancelled;
|
||||
break;
|
||||
}
|
||||
|
||||
const wcstring &val = argument_sequence.at(i);
|
||||
int retval = env_set_one(for_var_name, ENV_DEFAULT | ENV_USER, val);
|
||||
assert(retval == ENV_OK && "for loop variable should have been successfully set");
|
||||
(void)retval;
|
||||
|
@ -534,15 +533,13 @@ parse_execution_result_t parse_execution_context_t::run_switch_statement(
|
|||
break;
|
||||
}
|
||||
|
||||
// Pull out the argument list.
|
||||
auto arg_list = case_item.child<1>();
|
||||
|
||||
// Expand arguments. A case item list may have a wildcard that fails to expand to
|
||||
// anything. We also report case errors, but don't stop execution; i.e. a case item that
|
||||
// contains an unexpandable process will report and then fail to match.
|
||||
auto arg_nodes = get_argument_nodes(case_item.child<1>());
|
||||
wcstring_list_t case_args;
|
||||
parse_execution_result_t case_result =
|
||||
this->determine_arguments(arg_list, &case_args, failglob);
|
||||
this->expand_arguments_from_nodes(arg_nodes, &case_args, failglob);
|
||||
if (case_result == parse_execution_success) {
|
||||
for (const wcstring &arg : case_args) {
|
||||
// Unescape wildcards so they can be expanded again.
|
||||
|
@ -743,8 +740,9 @@ parse_execution_result_t parse_execution_context_t::handle_command_not_found(
|
|||
// error messages.
|
||||
wcstring_list_t event_args;
|
||||
{
|
||||
auto args = get_argument_nodes(statement.child<1>());
|
||||
parse_execution_result_t arg_result =
|
||||
this->determine_arguments(statement, &event_args, failglob);
|
||||
this->expand_arguments_from_nodes(args, &event_args, failglob);
|
||||
|
||||
if (arg_result != parse_execution_success) {
|
||||
return arg_result;
|
||||
|
@ -836,8 +834,9 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process(
|
|||
} else {
|
||||
const globspec_t glob_behavior = (cmd == L"set" || cmd == L"count") ? nullglob : failglob;
|
||||
// Form the list of arguments. The command is the first argument.
|
||||
argument_node_list_t arg_nodes = statement.descendants<g::argument>();
|
||||
parse_execution_result_t arg_result =
|
||||
this->determine_arguments(statement, &argument_list, glob_behavior);
|
||||
this->expand_arguments_from_nodes(arg_nodes, &argument_list, glob_behavior);
|
||||
if (arg_result != parse_execution_success) {
|
||||
return arg_result;
|
||||
}
|
||||
|
@ -862,17 +861,14 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process(
|
|||
|
||||
// Determine the list of arguments, expanding stuff. Reports any errors caused by expansion. If we
|
||||
// have a wildcard that could not be expanded, report the error and continue.
|
||||
parse_execution_result_t parse_execution_context_t::determine_arguments(
|
||||
const parse_node_t &parent, wcstring_list_t *out_arguments, globspec_t glob_behavior) {
|
||||
parse_execution_result_t parse_execution_context_t::expand_arguments_from_nodes(
|
||||
const argument_node_list_t &argument_nodes, wcstring_list_t *out_arguments,
|
||||
globspec_t glob_behavior) {
|
||||
// Get all argument nodes underneath the statement. We guess we'll have that many arguments (but
|
||||
// may have more or fewer, if there are wildcards involved).
|
||||
const parse_node_tree_t::parse_node_list_t argument_nodes =
|
||||
tree().find_nodes(parent, symbol_argument);
|
||||
out_arguments->reserve(out_arguments->size() + argument_nodes.size());
|
||||
std::vector<completion_t> arg_expanded;
|
||||
for (size_t i = 0; i < argument_nodes.size(); i++) {
|
||||
const parse_node_t &arg_node = *argument_nodes.at(i);
|
||||
|
||||
for (const auto arg_node : argument_nodes) {
|
||||
// Expect all arguments to have source.
|
||||
assert(arg_node.has_source());
|
||||
const wcstring arg_str = arg_node.get_source(pstree->src);
|
||||
|
@ -881,7 +877,7 @@ parse_execution_result_t parse_execution_context_t::determine_arguments(
|
|||
parse_error_list_t errors;
|
||||
arg_expanded.clear();
|
||||
int expand_ret = expand_string(arg_str, &arg_expanded, EXPAND_NO_DESCRIPTIONS, &errors);
|
||||
parse_error_offset_source_start(&errors, arg_node.source_start);
|
||||
parse_error_offset_source_start(&errors, arg_node.source_range()->start);
|
||||
switch (expand_ret) {
|
||||
case EXPAND_ERROR: {
|
||||
this->report_errors(errors);
|
||||
|
|
|
@ -80,7 +80,7 @@ class parse_execution_context_t {
|
|||
/// Indicates whether a job is a simple block (one block, no redirections).
|
||||
bool job_is_simple_block(const parse_node_t &node) const;
|
||||
|
||||
enum process_type_t process_type_for_command(const parse_node_t &plain_statement,
|
||||
enum process_type_t process_type_for_command(tnode_t<grammar::plain_statement> statement,
|
||||
const wcstring &cmd) const;
|
||||
|
||||
// These create process_t structures from statements.
|
||||
|
@ -107,9 +107,10 @@ class parse_execution_context_t {
|
|||
tnode_t<grammar::job_list> contents);
|
||||
|
||||
enum globspec_t { failglob, nullglob };
|
||||
parse_execution_result_t determine_arguments(const parse_node_t &parent,
|
||||
wcstring_list_t *out_arguments,
|
||||
globspec_t glob_behavior);
|
||||
using argument_node_list_t = std::vector<tnode_t<grammar::argument>>;
|
||||
parse_execution_result_t expand_arguments_from_nodes(const argument_node_list_t &argument_nodes,
|
||||
wcstring_list_t *out_arguments,
|
||||
globspec_t glob_behavior);
|
||||
|
||||
// Determines the IO chain. Returns true on success, false on error.
|
||||
bool determine_io_chain(const parse_node_t &statement, io_chain_t *out_chain);
|
||||
|
|
|
@ -1485,3 +1485,11 @@ maybe_t<wcstring> command_for_plain_statement(tnode_t<grammar::plain_statement>
|
|||
}
|
||||
return none();
|
||||
}
|
||||
|
||||
arguments_node_list_t get_argument_nodes(tnode_t<grammar::argument_list> list) {
|
||||
return list.descendants<grammar::argument>();
|
||||
}
|
||||
|
||||
arguments_node_list_t get_argument_nodes(tnode_t<grammar::arguments_or_redirections_list> list) {
|
||||
return list.descendants<grammar::argument>();
|
||||
}
|
||||
|
|
|
@ -428,6 +428,11 @@ parse_statement_decoration_t get_decoration(tnode_t<grammar::plain_statement> st
|
|||
/// Return the type for a boolean statement.
|
||||
enum parse_bool_statement_type_t bool_statement_type(tnode_t<grammar::boolean_statement> stmt);
|
||||
|
||||
/// Return the arguments under an arguments_list or arguments_or_redirection_list
|
||||
using arguments_node_list_t = std::vector<tnode_t<grammar::argument>>;
|
||||
arguments_node_list_t get_argument_nodes(tnode_t<grammar::argument_list>);
|
||||
arguments_node_list_t get_argument_nodes(tnode_t<grammar::arguments_or_redirections_list>);
|
||||
|
||||
/// The big entry point. Parse a string, attempting to produce a tree for the given goal type.
|
||||
bool parse_tree_from_string(const wcstring &str, parse_tree_flags_t flags,
|
||||
parse_node_tree_t *output, parse_error_list_t *errors,
|
||||
|
|
Loading…
Reference in New Issue
Block a user