diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 31d2782be..22a9f576d 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -700,9 +700,7 @@ static wcstring reconstruct_orig_str(wcstring tokenized_str) { /// Handle the case of command not found. parse_execution_result_t parse_execution_context_t::handle_command_not_found( - const wcstring &cmd_str, const parse_node_t &statement_node, int err_code) { - assert(statement_node.type == symbol_plain_statement); - + const wcstring &cmd_str, tnode_t statement_node, int err_code) { // We couldn't find the specified command. This is a non-fatal error. We want to set the exit // status to 127, which is the standard number used by other shells like bash and zsh. @@ -771,16 +769,15 @@ parse_execution_result_t parse_execution_context_t::handle_command_not_found( /// Creates a 'normal' (non-block) process. parse_execution_result_t parse_execution_context_t::populate_plain_process( - job_t *job, process_t *proc, const parse_node_t &statement) { + job_t *job, process_t *proc, tnode_t statement) { assert(job != NULL); assert(proc != NULL); - assert(statement.type == symbol_plain_statement); // We may decide that a command should be an implicit cd. bool use_implicit_cd = false; // Get the command. We expect to always get it here. - wcstring cmd = *command_for_plain_statement({&tree(), &statement}, pstree->src); + wcstring cmd = *command_for_plain_statement(statement, pstree->src); // Expand it as a command. Return an error on failure. bool expanded = expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES, NULL); @@ -810,12 +807,10 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process( const int no_cmd_err_code = errno; // If the specified command does not exist, and is undecorated, try using an implicit cd. - if (!has_command && - get_decoration({&tree(), &statement}) == parse_statement_decoration_none) { + if (!has_command && get_decoration(statement) == parse_statement_decoration_none) { // Implicit cd requires an empty argument and redirection list. - const parse_node_t *args = - get_child(statement, 1, symbol_arguments_or_redirections_list); - if (args->child_count == 0) { + tnode_t args = statement.child<1>(); + if (!args.try_get_child()) { // Ok, no arguments or redirections; check to see if the first argument is a // directory. wcstring implicit_cd_path; @@ -1070,8 +1065,8 @@ parse_execution_result_t parse_execution_context_t::populate_job_process( } case symbol_decorated_statement: { // Get the plain statement. It will pull out the decoration itself. - const parse_node_t &plain_statement = - tree().find_child(specific_statement, symbol_plain_statement); + tnode_t dec_stat{&tree(), &specific_statement}; + auto plain_statement = dec_stat.find_child(); result = this->populate_plain_process(job, proc, plain_statement); break; } diff --git a/src/parse_execution.h b/src/parse_execution.h index b0632e10e..6fbbc7347 100644 --- a/src/parse_execution.h +++ b/src/parse_execution.h @@ -65,7 +65,7 @@ class parse_execution_context_t { /// Command not found support. parse_execution_result_t handle_command_not_found(const wcstring &cmd, - const parse_node_t &statement_node, + tnode_t statement, int err_code); // Utilities @@ -89,7 +89,7 @@ class parse_execution_context_t { parse_execution_result_t populate_boolean_process( job_t *job, process_t *proc, tnode_t bool_statement); parse_execution_result_t populate_plain_process(job_t *job, process_t *proc, - const parse_node_t &statement); + tnode_t statement); parse_execution_result_t populate_block_process(job_t *job, process_t *proc, const parse_node_t &statement_node); diff --git a/src/parse_tree.h b/src/parse_tree.h index e6d39a6e0..6b870c571 100644 --- a/src/parse_tree.h +++ b/src/parse_tree.h @@ -357,6 +357,15 @@ class tnode_t { return result; } + /// Find the first direct child of the given node of the given type. asserts on failure. + template + tnode_t find_child() const { + assert(nodeptr && "receiver is missing in find_child()"); + tnode_t result{tree, &tree->find_child(*nodeptr, ChildType::token)}; + assert(result && "cannot find child"); + return result; + } + /// Type-safe access to a node's parent. /// If the parent exists and has type ParentType, return it. /// Otherwise return a missing tnode.