diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 8b31a3958..e3a148f80 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -601,9 +601,9 @@ static parser_test_error_bits_t detect_argument_errors(const wcstring &src) { } assert(!tree.empty()); //!OCLINT(multiple unary operator) - const parse_node_t *first_arg = tree.next_node_in_node_list(tree.at(0), symbol_argument, NULL); - assert(first_arg != NULL); - return parse_util_detect_errors_in_argument(*first_arg, first_arg->get_source(src)); + tnode_t arg_list{&tree, &tree.at(0)}; + auto first_arg = arg_list.next_in_list(); + return parse_util_detect_errors_in_argument(first_arg, first_arg.get_source(src)); } /// Test the parser. diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 931123d14..ed2f8e77f 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -940,11 +940,11 @@ static parser_test_error_bits_t detect_dollar_cmdsub_errors(size_t arg_src_offse /// 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 /// operator. -parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t &node, +parser_test_error_bits_t parse_util_detect_errors_in_argument(tnode_t node, const wcstring &arg_src, parse_error_list_t *out_errors) { - assert(node.type == symbol_argument); - + assert(node.has_source() && "argument has no source"); + auto source_start = node.source_range()->start; int err = 0; wchar_t *paran_begin, *paran_end; int do_loop = 1; @@ -956,7 +956,7 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t case -1: { err = 1; if (out_errors) { - append_syntax_error(out_errors, node.source_start, L"Mismatched parenthesis"); + append_syntax_error(out_errors, source_start, L"Mismatched parenthesis"); } return err; } @@ -979,7 +979,7 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t // Our command substitution produced error offsets relative to its source. Tweak the // offsets of the errors in the command substitution to account for both its offset // within the string, and the offset of the node. - size_t error_offset = cmd_sub_start + 1 + node.source_start; + size_t error_offset = cmd_sub_start + 1 + source_start; parse_error_offset_source_start(&subst_errors, error_offset); if (out_errors != NULL) { @@ -990,9 +990,8 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t // "" and (), and also we no longer have the source of the command substitution. // As an optimization, this is only necessary if the last character is a $. if (cmd_sub_start > 0 && working_copy.at(cmd_sub_start - 1) == L'$') { - err |= detect_dollar_cmdsub_errors(node.source_start, - working_copy.substr(0, cmd_sub_start), - subst, out_errors); + err |= detect_dollar_cmdsub_errors( + source_start, working_copy.substr(0, cmd_sub_start), subst, out_errors); } } break; @@ -1007,7 +1006,7 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t wcstring unesc; if (!unescape_string(working_copy, &unesc, UNESCAPE_SPECIAL)) { if (out_errors) { - append_syntax_error(out_errors, node.source_start, L"Invalid token '%ls'", + append_syntax_error(out_errors, source_start, L"Invalid token '%ls'", working_copy.c_str()); } return 1; @@ -1031,8 +1030,7 @@ parser_test_error_bits_t parse_util_detect_errors_in_argument(const parse_node_t unesc.at(first_dollar - 1) == VARIABLE_EXPAND_SINGLE)) { first_dollar--; } - parse_util_expand_variable_error(unesc, node.source_start, first_dollar, - out_errors); + parse_util_expand_variable_error(unesc, source_start, first_dollar, out_errors); } } } @@ -1160,8 +1158,9 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src, (type == parse_bool_and) ? L"and" : L"or"); } } else if (node.type == symbol_argument) { + tnode_t arg{&node_tree, &node}; const wcstring arg_src = node.get_source(buff_src); - res |= parse_util_detect_errors_in_argument(node, arg_src, &parse_errors); + res |= parse_util_detect_errors_in_argument(arg, arg_src, &parse_errors); } else if (node.type == symbol_job) { // Disallow background in the following cases: // diff --git a/src/parse_util.h b/src/parse_util.h index 332737cbe..147971090 100644 --- a/src/parse_util.h +++ b/src/parse_util.h @@ -136,7 +136,8 @@ parser_test_error_bits_t parse_util_detect_errors(const wcstring &buff_src, /// operator. This does NOT currently detect unterminated quotes. class parse_node_t; parser_test_error_bits_t parse_util_detect_errors_in_argument( - const parse_node_t &node, const wcstring &arg_src, parse_error_list_t *out_errors = NULL); + tnode_t node, const wcstring &arg_src, + parse_error_list_t *out_errors = NULL); /// Given a string containing a variable expansion error, append an appropriate error to the errors /// list. The global_token_pos is the offset of the token in the larger source, and the dollar_pos diff --git a/src/parser.cpp b/src/parser.cpp index 37af8911a..4ee773271 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -329,20 +329,13 @@ void parser_t::expand_argument_list(const wcstring &arg_list_src, expand_flags_t return; } - // Get the root argument list. + // Get the root argument list and extract arguments from it. assert(!tree.empty()); //!OCLINT(multiple unary operator) - const parse_node_t *arg_list = &tree.at(0); - assert(arg_list->type == symbol_freestanding_argument_list); - - // Extract arguments from it. - while (arg_list != NULL) { - const parse_node_t *arg_node = - tree.next_node_in_node_list(*arg_list, symbol_argument, &arg_list); - if (arg_node != NULL) { - const wcstring arg_src = arg_node->get_source(arg_list_src); - if (expand_string(arg_src, output_arg_list, eflags, NULL) == EXPAND_ERROR) { - break; // failed to expand a string - } + tnode_t arg_list(&tree, &tree.at(0)); + while (auto arg = arg_list.next_in_list()) { + const wcstring arg_src = arg.get_source(arg_list_src); + if (expand_string(arg_src, output_arg_list, eflags, NULL) == EXPAND_ERROR) { + break; // failed to expand a string } } } @@ -742,20 +735,13 @@ bool parser_t::detect_errors_in_argument_list(const wcstring &arg_list_src, wcst } if (!errored) { - // Get the root argument list. + // Get the root argument list and extract arguments from it. assert(!tree.empty()); //!OCLINT(multiple unary operator) - const parse_node_t *arg_list = &tree.at(0); - assert(arg_list->type == symbol_freestanding_argument_list); - - // 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) { - const wcstring arg_src = arg_node->get_source(arg_list_src); - if (parse_util_detect_errors_in_argument(*arg_node, arg_src, &errors)) { - errored = true; - } + tnode_t arg_list(&tree, &tree.at(0)); + while (auto arg = arg_list.next_in_list()) { + const wcstring arg_src = arg.get_source(arg_list_src); + if (parse_util_detect_errors_in_argument(arg, arg_src, &errors)) { + errored = true; } } }