From 6e3231a9d705ee043cf827b22c807b0b96ea8893 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 27 Jul 2015 18:45:47 -0700 Subject: [PATCH] Stop passing mutable references to completions around Replace uses of vector& with vector* This makes it clear at the call site that the object may be mutated. --- src/builtin.cpp | 4 ++- src/builtin.h | 4 +-- src/complete.cpp | 41 ++++++++++++------------- src/complete.h | 2 +- src/expand.cpp | 68 ++++++++++++++++++++--------------------- src/expand.h | 2 +- src/fish_tests.cpp | 6 ++-- src/parse_execution.cpp | 4 +-- src/parser.cpp | 3 +- src/parser.h | 2 +- src/wildcard.cpp | 60 ++++++++++++++++++------------------ src/wildcard.h | 4 +-- 12 files changed, 101 insertions(+), 99 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index b31fb6a11..51aa445a1 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -4226,8 +4226,10 @@ wcstring_list_t builtin_get_names(void) return result; } -void builtin_get_names(std::vector &list) +void builtin_get_names(std::vector *list) { + assert(list != NULL); + list->reserve(list->size() + BUILTIN_COUNT); for (size_t i=0; i < BUILTIN_COUNT; i++) { append_completion(list, builtin_datas[i].name); diff --git a/src/builtin.h b/src/builtin.h index 3472995cf..c280cbd0d 100644 --- a/src/builtin.h +++ b/src/builtin.h @@ -142,10 +142,10 @@ int builtin_exists(const wcstring &cmd); int builtin_run(parser_t &parser, const wchar_t * const *argv, const io_chain_t &io); /** Returns a list of all builtin names */ -wcstring_list_t builtin_get_names(void); +wcstring_list_t builtin_get_names(); /** Insert all builtin names into list. */ -void builtin_get_names(std::vector &list); +void builtin_get_names(std::vector *list); /** Pushes a new set of input/output to the stack. The new stdin is supplied, a new set of output strings is created. diff --git a/src/complete.cpp b/src/complete.cpp index da1e7b915..7130311ef 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -461,15 +461,16 @@ void completion_autoload_t::command_removed(const wcstring &cmd) /** Create a new completion entry. */ -void append_completion(std::vector &completions, const wcstring &comp, const wcstring &desc, complete_flags_t flags, string_fuzzy_match_t match) +void append_completion(std::vector *completions, const wcstring &comp, const wcstring &desc, complete_flags_t flags, string_fuzzy_match_t match) { /* If we just constructed the completion and used push_back, we would get two string copies. Try to avoid that by making a stubby completion in the vector first, and then copying our string in. Note that completion_t's constructor will munge 'flags' so it's important that we pass those to the constructor. Nasty hack for #1241 - since the constructor needs the completion string to resolve AUTO_SPACE, and we aren't providing it with the completion, we have to do the resolution ourselves. We should get this resolving out of the constructor. */ + assert(completions != NULL); const wcstring empty; - completions.push_back(completion_t(empty, empty, match, resolve_auto_space(comp, flags))); - completion_t *last = &completions.back(); + completions->push_back(completion_t(empty, empty, match, resolve_auto_space(comp, flags))); + completion_t *last = &completions->back(); last->completion = comp; last->description = desc; } @@ -973,7 +974,7 @@ void completer_t::complete_strings(const wcstring &wc_escaped, if (next_str) { - wildcard_complete(next_str, wc, desc, desc_func, this->completions, this->expand_flags(), flags); + wildcard_complete(next_str, wc, desc, desc_func, &this->completions, this->expand_flags(), flags); } } @@ -1140,7 +1141,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool if (use_command) { - if (expand_string(str_cmd, this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags(), NULL) != EXPAND_ERROR) + if (expand_string(str_cmd, &this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags(), NULL) != EXPAND_ERROR) { if (this->wants_descriptions()) { @@ -1150,7 +1151,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool } if (use_implicit_cd) { - if (!expand_string(str_cmd, this->completions, ACCEPT_INCOMPLETE | DIRECTORIES_ONLY | this->expand_flags(), NULL)) + if (!expand_string(str_cmd, &this->completions, ACCEPT_INCOMPLETE | DIRECTORIES_ONLY | this->expand_flags(), NULL)) { // Not valid as implicit cd. } @@ -1179,7 +1180,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool size_t prev_count = this->completions.size(); if (expand_string(nxt_completion, - this->completions, + &this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags(), NULL) != EXPAND_ERROR) { /* For all new completions, if COMPLETE_NO_CASE is set, then use only the last path component */ @@ -1205,7 +1206,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool wcstring_list_t names = function_get_names(str_cmd.at(0) == L'_'); for (size_t i=0; i < names.size(); i++) { - append_completion(possible_comp, names.at(i)); + append_completion(&possible_comp, names.at(i)); } this->complete_strings(str_cmd, 0, &complete_function_desc, possible_comp, 0); @@ -1215,7 +1216,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool if (use_builtin) { - builtin_get_names(possible_comp); + builtin_get_names(&possible_comp); this->complete_strings(str_cmd, 0, &builtin_get_desc, possible_comp, 0); } @@ -1240,9 +1241,6 @@ void completer_t::complete_from_args(const wcstring &str, const wcstring &desc, complete_flags_t flags) { - - std::vector possible_comp; - bool is_autosuggest = (this->type() == COMPLETE_AUTOSUGGEST); parser_t parser(is_autosuggest ? PARSER_TYPE_COMPLETIONS_ONLY : PARSER_TYPE_GENERAL, false /* don't show errors */); @@ -1250,7 +1248,8 @@ void completer_t::complete_from_args(const wcstring &str, if (! is_autosuggest) proc_push_interactive(0); - parser.expand_argument_list(args, possible_comp); + std::vector possible_comp; + parser.expand_argument_list(args, &possible_comp); if (! is_autosuggest) proc_pop_interactive(); @@ -1538,7 +1537,7 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop completion[0] = o->short_opt; completion[1] = 0; - append_completion(this->completions, completion, desc, 0); + append_completion(&this->completions, completion, desc, 0); } @@ -1593,14 +1592,14 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop homebrew getopt-like functions. */ wcstring completion = format_string(L"%ls=", whole_opt.c_str()+offset); - append_completion(this->completions, + append_completion(&this->completions, completion, C_(o->desc), flags); } - append_completion(this->completions, + append_completion(&this->completions, whole_opt.c_str() + offset, C_(o->desc), flags); @@ -1649,7 +1648,7 @@ void completer_t::complete_param_expand(const wcstring &str, bool do_file, bool const wcstring sep_string = wcstring(str, sep_index + 1); std::vector local_completions; if (expand_string(sep_string, - local_completions, + &local_completions, flags, NULL) == EXPAND_ERROR) { @@ -1678,7 +1677,7 @@ void completer_t::complete_param_expand(const wcstring &str, bool do_file, bool flags &= ~EXPAND_FUZZY_MATCH; if (expand_string(str, - this->completions, + &this->completions, flags, NULL) == EXPAND_ERROR) { debug(3, L"Error while expanding string '%ls'", str.c_str()); @@ -1735,7 +1734,7 @@ bool completer_t::complete_variable(const wcstring &str, size_t start_offset) desc = format_string(COMPLETE_VAR_DESC_VAL, value.c_str()); } - append_completion(this->completions, comp, desc, flags, match); + append_completion(&this->completions, comp, desc, flags, match); res = true; } @@ -1846,7 +1845,7 @@ bool completer_t::try_complete_user(const wcstring &str) if (wcsncmp(user_name, pw_name, name_len)==0) { wcstring desc = format_string(COMPLETE_USER_DESC, pw_name); - append_completion(this->completions, + append_completion(&this->completions, &pw_name[name_len], desc, COMPLETE_NO_SPACE); @@ -1858,7 +1857,7 @@ bool completer_t::try_complete_user(const wcstring &str) wcstring name = format_string(L"~%ls", pw_name); wcstring desc = format_string(COMPLETE_USER_DESC, pw_name); - append_completion(this->completions, + append_completion(&this->completions, name, desc, COMPLETE_REPLACES_TOKEN | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE); diff --git a/src/complete.h b/src/complete.h index 99dcbf6a0..d90077077 100644 --- a/src/complete.h +++ b/src/complete.h @@ -262,7 +262,7 @@ void complete_load(const wcstring &cmd, bool reload); \param flags completion flags */ -void append_completion(std::vector &completions, const wcstring &comp, const wcstring &desc = wcstring(), int flags = 0, string_fuzzy_match_t match = string_fuzzy_match_t(fuzzy_match_exact)); +void append_completion(std::vector *completions, const wcstring &comp, const wcstring &desc = wcstring(), int flags = 0, string_fuzzy_match_t match = string_fuzzy_match_t(fuzzy_match_exact)); /* Function used for testing */ void complete_set_variable_names(const wcstring_list_t *names); diff --git a/src/expand.cpp b/src/expand.cpp index 29cc410f3..5bb2da1f1 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -607,7 +607,7 @@ static int find_job(const struct find_job_data_t *info) { if (!j->command_is_empty()) { - append_completion(completions, to_string(j->pgid)); + append_completion(&completions, to_string(j->pgid)); break; } } @@ -638,7 +638,7 @@ static int find_job(const struct find_job_data_t *info) if (wcsncmp(proc, jid, wcslen(proc))==0) { wcstring desc_buff = format_string(COMPLETE_JOB_DESC_VAL, j->command_wcstr()); - append_completion(completions, + append_completion(&completions, jid+wcslen(proc), desc_buff, 0); @@ -657,7 +657,7 @@ static int find_job(const struct find_job_data_t *info) j = job_get(jid); if ((j != 0) && (j->command_wcstr() != 0) && (!j->command_is_empty())) { - append_completion(completions, to_string(j->pgid)); + append_completion(&completions, to_string(j->pgid)); } } } @@ -682,14 +682,14 @@ static int find_job(const struct find_job_data_t *info) { if (flags & ACCEPT_INCOMPLETE) { - append_completion(completions, + append_completion(&completions, j->command_wcstr() + offset + wcslen(proc), COMPLETE_JOB_DESC, 0); } else { - append_completion(completions, to_string(j->pgid)); + append_completion(&completions, to_string(j->pgid)); found = 1; } } @@ -713,14 +713,14 @@ static int find_job(const struct find_job_data_t *info) { if (flags & ACCEPT_INCOMPLETE) { - append_completion(completions, + append_completion(&completions, wcstring(p->actual_cmd, offset + wcslen(proc)), COMPLETE_CHILD_PROCESS_DESC, 0); } else { - append_completion(completions, + append_completion(&completions, to_string(p->pid), L"", 0); @@ -750,11 +750,11 @@ static int find_job(const struct find_job_data_t *info) understand the contents of the /proc filesystem, all the users processes are searched for matches. */ -static void find_process(const wchar_t *proc, expand_flags_t flags, std::vector &out) +static void find_process(const wchar_t *proc, expand_flags_t flags, std::vector *out) { if (!(flags & EXPAND_SKIP_JOBS)) { - const struct find_job_data_t data = {proc, flags, &out}; + const struct find_job_data_t data = {proc, flags, out}; int found = iothread_perform_on_main(find_job, &data); if (found) { @@ -789,7 +789,7 @@ static void find_process(const wchar_t *proc, expand_flags_t flags, std::vector< /** Process id expansion */ -static bool expand_pid(const wcstring &instr_with_sep, expand_flags_t flags, std::vector &out, parse_error_list_t *errors) +static bool expand_pid(const wcstring &instr_with_sep, expand_flags_t flags, std::vector *out, parse_error_list_t *errors) { /* Hack. If there's no INTERNAL_SEP and no PROCESS_EXPAND, then there's nothing to do. Check out this "null terminated string." */ const wchar_t some_chars[] = {INTERNAL_SEPARATOR, PROCESS_EXPAND, L'\0'}; @@ -852,10 +852,10 @@ static bool expand_pid(const wcstring &instr_with_sep, expand_flags_t flags, std } /* This is sort of crummy - find_process doesn't return any indication of success, so instead we check to see if it inserted any completions */ - const size_t prev_count = out.size(); + const size_t prev_count = out->size(); find_process(in+1, flags, out); - if (prev_count == out.size()) + if (prev_count == out->size()) { if (!(flags & ACCEPT_INCOMPLETE)) { @@ -974,7 +974,7 @@ static size_t parse_slice(const wchar_t *in, wchar_t **end_ptr, std::vector &out, long last_idx, parse_error_list_t *errors) +static int expand_variables(parser_t &parser, const wcstring &instr, std::vector *out, long last_idx, parse_error_list_t *errors) { const size_t insize = instr.size(); @@ -1258,7 +1258,7 @@ static int expand_variables(parser_t &parser, const wcstring &instr, std::vector /** Perform bracket expansion */ -static int expand_brackets(parser_t &parser, const wcstring &instr, int flags, std::vector &out, parse_error_list_t *errors) +static int expand_brackets(parser_t &parser, const wcstring &instr, int flags, std::vector *out, parse_error_list_t *errors) { bool syntax_error = false; int bracket_count=0; @@ -1388,7 +1388,7 @@ static int expand_brackets(parser_t &parser, const wcstring &instr, int flags, s /** Perform cmdsubst expansion */ -static int expand_cmdsubst(parser_t &parser, const wcstring &input, std::vector &out_list, parse_error_list_t *errors) +static int expand_cmdsubst(parser_t &parser, const wcstring &input, std::vector *out_list, parse_error_list_t *errors) { wchar_t *paran_begin=0, *paran_end=0; std::vector sub_res; @@ -1468,7 +1468,7 @@ static int expand_cmdsubst(parser_t &parser, const wcstring &input, std::vector< of the string is inserted into the tail_expand array list */ std::vector tail_expand; - expand_cmdsubst(parser, tail_begin, tail_expand, errors /* TODO: offset error locations */); + expand_cmdsubst(parser, tail_begin, &tail_expand, errors /* TODO: offset error locations */); /* Combine the result of the current command substitution with the @@ -1683,7 +1683,7 @@ static void remove_internal_separator(wcstring &str, bool conv) } -int expand_string(const wcstring &input, std::vector &output, expand_flags_t flags, parse_error_list_t *errors) +int expand_string(const wcstring &input, std::vector *output, expand_flags_t flags, parse_error_list_t *errors) { parser_t parser(PARSER_TYPE_ERRORS_ONLY, true /* show errors */); @@ -1708,11 +1708,11 @@ int expand_string(const wcstring &input, std::vector &output, expa append_cmdsub_error(errors, SOURCE_LOCATION_UNKNOWN, L"Command substitutions not allowed"); return EXPAND_ERROR; } - append_completion(*in, input); + append_completion(in, input); } else { - int cmdsubst_ok = expand_cmdsubst(parser, input, *in, errors); + int cmdsubst_ok = expand_cmdsubst(parser, input, in, errors); if (! cmdsubst_ok) return EXPAND_ERROR; } @@ -1736,11 +1736,11 @@ int expand_string(const wcstring &input, std::vector &output, expa next[i] = L'$'; } } - append_completion(*out, next); + append_completion(out, next); } else { - if (!expand_variables(parser, next, *out, next.size(), errors)) + if (!expand_variables(parser, next, out, next.size(), errors)) { return EXPAND_ERROR; } @@ -1754,7 +1754,7 @@ int expand_string(const wcstring &input, std::vector &output, expa { const wcstring &next = in->at(i).completion; - if (!expand_brackets(parser, next, flags, *out, errors)) + if (!expand_brackets(parser, next, flags, out, errors)) { return EXPAND_ERROR; } @@ -1783,10 +1783,10 @@ int expand_string(const wcstring &input, std::vector &output, expa } else { - append_completion(*out, next); + append_completion(out, next); } } - else if (! expand_pid(next, flags, *out, errors)) + else if (! expand_pid(next, flags, out, errors)) { return EXPAND_ERROR; } @@ -1824,7 +1824,7 @@ int expand_string(const wcstring &input, std::vector &output, expa } std::vector expanded; - wc_res = wildcard_expand_string(rest, start, flags, expanded); + wc_res = wildcard_expand_string(rest, start, flags, &expanded); if (flags & ACCEPT_INCOMPLETE) { out->insert(out->end(), expanded.begin(), expanded.end()); @@ -1860,7 +1860,7 @@ int expand_string(const wcstring &input, std::vector &output, expa { if (!(flags & ACCEPT_INCOMPLETE)) { - append_completion(*out, next); + append_completion(out, next); } } } @@ -1872,7 +1872,7 @@ int expand_string(const wcstring &input, std::vector &output, expa } // Return our output - output.insert(output.end(), out->begin(), out->end()); + output->insert(output->end(), out->begin(), out->end()); return res; } @@ -1887,7 +1887,7 @@ bool expand_one(wcstring &string, expand_flags_t flags, parse_error_list_t *erro return true; } - if (expand_string(string, completions, flags | EXPAND_NO_DESCRIPTIONS, errors)) + if (expand_string(string, &completions, flags | EXPAND_NO_DESCRIPTIONS, errors)) { if (completions.size() == 1) { @@ -1990,19 +1990,19 @@ bool fish_openSUSE_dbus_hack_hack_hack_hack(std::vector *args) val.resize(last_good + 1); args->clear(); - append_completion(*args, L"set"); + append_completion(args, L"set"); if (key == L"DBUS_SESSION_BUS_ADDRESS") - append_completion(*args, L"-x"); - append_completion(*args, key); - append_completion(*args, val); + append_completion(args, L"-x"); + append_completion(args, key); + append_completion(args, val); result = true; } else if (string_prefixes_string(L"export DBUS_SESSION_BUS_ADDRESS;", cmd)) { /* Nothing, we already exported it */ args->clear(); - append_completion(*args, L"echo"); - append_completion(*args, L"-n"); + append_completion(args, L"echo"); + append_completion(args, L"-n"); result = true; } } diff --git a/src/expand.h b/src/expand.h index 1f42982b2..a4c587cc7 100644 --- a/src/expand.h +++ b/src/expand.h @@ -152,7 +152,7 @@ class parser_t; \param errors Resulting errors, or NULL to ignore \return One of EXPAND_OK, EXPAND_ERROR, EXPAND_WILDCARD_MATCH and EXPAND_WILDCARD_NO_MATCH. EXPAND_WILDCARD_NO_MATCH and EXPAND_WILDCARD_MATCH are normal exit conditions used only on strings containing wildcards to tell if the wildcard produced any matches. */ -__warn_unused int expand_string(const wcstring &input, std::vector &output, expand_flags_t flags, parse_error_list_t *errors); +__warn_unused int expand_string(const wcstring &input, std::vector *output, expand_flags_t flags, parse_error_list_t *errors); /** diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index c56593feb..b245dc607 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -739,7 +739,7 @@ static void test_parser() say(L"Testing eval_args"); completion_list_t comps; - parser_t::principal_parser().expand_argument_list(L"alpha 'beta gamma' delta", comps); + parser_t::principal_parser().expand_argument_list(L"alpha 'beta gamma' delta", &comps); do_test(comps.size() == 3); do_test(comps.at(0).completion == L"alpha"); do_test(comps.at(1).completion == L"beta gamma"); @@ -1344,7 +1344,7 @@ static bool expand_test(const wchar_t *in, expand_flags_t flags, ...) wchar_t *arg; parse_error_list_t errors; - if (expand_string(in, output, flags, &errors) == EXPAND_ERROR) + if (expand_string(in, &output, flags, &errors) == EXPAND_ERROR) { if (errors.empty()) { @@ -1583,7 +1583,7 @@ static void test_pager_navigation() completion_list_t completions; for (size_t i=0; i < 19; i++) { - append_completion(completions, L"abcdefghij"); + append_completion(&completions, L"abcdefghij"); } pager_t pager; diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index e190ed8a5..e2a1ee206 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -525,7 +525,7 @@ parse_execution_result_t parse_execution_context_t::run_switch_statement(const p /* Expand it. We need to offset any errors by the position of the string */ std::vector switch_values_expanded; parse_error_list_t errors; - int expand_ret = expand_string(switch_value, switch_values_expanded, EXPAND_NO_DESCRIPTIONS, &errors); + int expand_ret = expand_string(switch_value, &switch_values_expanded, EXPAND_NO_DESCRIPTIONS, &errors); parse_error_offset_source_start(&errors, switch_value_node.source_start); switch (expand_ret) @@ -985,7 +985,7 @@ parse_execution_result_t parse_execution_context_t::determine_arguments(const pa /* Expand this string */ std::vector arg_expanded; parse_error_list_t errors; - int expand_ret = expand_string(arg_str, arg_expanded, EXPAND_NO_DESCRIPTIONS, &errors); + int expand_ret = expand_string(arg_str, &arg_expanded, EXPAND_NO_DESCRIPTIONS, &errors); parse_error_offset_source_start(&errors, arg_node.source_start); switch (expand_ret) { diff --git a/src/parser.cpp b/src/parser.cpp index ec8f22534..810a01c86 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -494,8 +494,9 @@ void parser_t::emit_profiling(const char *path) const } } -void parser_t::expand_argument_list(const wcstring &arg_list_src, std::vector &output_arg_list) +void parser_t::expand_argument_list(const wcstring &arg_list_src, std::vector *output_arg_list) { + assert(output_arg_list != NULL); expand_flags_t eflags = 0; if (! show_errors) eflags |= EXPAND_NO_DESCRIPTIONS; diff --git a/src/parser.h b/src/parser.h index cef0fdb00..1afced173 100644 --- a/src/parser.h +++ b/src/parser.h @@ -314,7 +314,7 @@ public: \param arg_src String to evaluate as an argument list \param output List to insert output into */ - void expand_argument_list(const wcstring &arg_src, std::vector &output); + void expand_argument_list(const wcstring &arg_src, std::vector *output); /** Returns a string describing the current parser pisition in the format 'FILENAME (line LINE_NUMBER): LINE'. diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 24769e807..824177704 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -211,7 +211,7 @@ static bool wildcard_complete_internal(const wcstring &orig, bool is_first, const wchar_t *desc, wcstring(*desc_func)(const wcstring &), - std::vector &out, + std::vector *out, expand_flags_t expand_flags, complete_flags_t flags) { @@ -316,17 +316,17 @@ static bool wildcard_complete_internal(const wcstring &orig, /* Try all submatches */ for (size_t i=0; str[i] != L'\0'; i++) { - const size_t before_count = out.size(); + const size_t before_count = out->size(); if (wildcard_complete_internal(orig, str + i, wc+1, false, desc, desc_func, out, expand_flags, flags)) { res = true; /* #929: if the recursive call gives us a prefix match, just stop. This is sloppy - what we really want to do is say, once we've seen a match of a particular type, ignore all matches of that type further down the string, such that the wildcard produces the "minimal match." */ bool has_prefix_match = false; - const size_t after_count = out.size(); + const size_t after_count = out->size(); for (size_t j = before_count; j < after_count; j++) { - if (out[j].match.type <= fuzzy_match_prefix) + if (out->at(j).match.type <= fuzzy_match_prefix) { has_prefix_match = true; break; @@ -354,13 +354,12 @@ bool wildcard_complete(const wcstring &str, const wchar_t *wc, const wchar_t *desc, wcstring(*desc_func)(const wcstring &), - std::vector &out, + std::vector *out, expand_flags_t expand_flags, complete_flags_t flags) { - bool res; - res = wildcard_complete_internal(str, str.c_str(), wc, true, desc, desc_func, out, expand_flags, flags); - return res; + assert(out != NULL); + return wildcard_complete_internal(str, str.c_str(), wc, true, desc, desc_func, out, expand_flags, flags); } @@ -515,12 +514,13 @@ static wcstring file_get_desc(const wcstring &filename, \param wc the wildcard to match against \param is_cmd whether we are performing command completion */ -static void wildcard_completion_allocate(std::vector &list, +static void wildcard_completion_allocate(std::vector *list, const wcstring &fullname, const wcstring &completion, const wchar_t *wc, expand_flags_t expand_flags) { + assert(list != NULL); struct stat buf, lbuf; wcstring sb; wcstring munged_completion; @@ -644,9 +644,9 @@ static bool test_flags(const wchar_t *filename, expand_flags_t flags) } /** Appends a completion to the completion list, if the string is missing from the set. */ -static void insert_completion_if_missing(const wcstring &str, std::vector &out, std::set &completion_set) +static void insert_completion_if_missing(const wcstring &str, std::vector *out, std::set *completion_set) { - if (completion_set.insert(str).second) + if (completion_set->insert(str).second) append_completion(out, str); } @@ -665,7 +665,7 @@ static void insert_completion_if_missing(const wcstring &str, std::vector &out, + std::vector *out, std::set &completion_set, std::set &visited_files) { @@ -776,7 +776,7 @@ static int wildcard_expand_internal(const wchar_t *wc, else { res = 1; - insert_completion_if_missing(base_dir, out, completion_set); + insert_completion_if_missing(base_dir, out, &completion_set); } } else @@ -792,7 +792,7 @@ static int wildcard_expand_internal(const wchar_t *wc, /* Test for matches before stating file, so as to minimize the number of calls to the much slower stat function. The only expand flag we care about is EXPAND_FUZZY_MATCH; we have no complete flags. */ std::vector test; - if (wildcard_complete(name_str, wc, L"", NULL, test, flags & EXPAND_FUZZY_MATCH, 0)) + if (wildcard_complete(name_str, wc, L"", NULL, &test, flags & EXPAND_FUZZY_MATCH, 0)) { if (test_flags(long_name.c_str(), flags)) { @@ -823,7 +823,7 @@ static int wildcard_expand_internal(const wchar_t *wc, } if (! skip) { - insert_completion_if_missing(long_name, out, completion_set); + insert_completion_if_missing(long_name, out, &completion_set); } res = 1; } @@ -959,17 +959,18 @@ static int wildcard_expand_internal(const wchar_t *wc, } -int wildcard_expand(const wchar_t *wc, - const wchar_t *base_dir, - expand_flags_t flags, - std::vector &out) +static int wildcard_expand(const wchar_t *wc, + const wchar_t *base_dir, + expand_flags_t flags, + std::vector *out) { - size_t c = out.size(); + assert(out != NULL); + size_t c = out->size(); /* Make a set of used completion strings so we can do fast membership tests inside wildcard_expand_internal. Otherwise wildcards like '**' are very slow, because we end up with an N^2 membership test. */ std::set completion_set; - for (std::vector::const_iterator iter = out.begin(); iter != out.end(); ++iter) + for (std::vector::const_iterator iter = out->begin(); iter != out->end(); ++iter) { completion_set.insert(iter->completion); } @@ -986,29 +987,28 @@ int wildcard_expand(const wchar_t *wc, wc_base = wcstring(wc, (wc_base_ptr-wc)+1); } - for (size_t i=c; isize(); i++) { - completion_t &c = out.at(i); + completion_t &c = out->at(i); if (c.flags & COMPLETE_REPLACES_TOKEN) { - c.completion = format_string(L"%ls%ls%ls", base_dir, wc_base.c_str(), c.completion.c_str()); + // completion = base_dir + wc_base + completion + c.completion.insert(0, wc_base); + c.completion.insert(0, base_dir); } } } return res; } -int wildcard_expand_string(const wcstring &wc, const wcstring &base_dir, expand_flags_t flags, std::vector &outputs) +int wildcard_expand_string(const wcstring &wc, const wcstring &base_dir, expand_flags_t flags, std::vector *output) { + assert(output != NULL); /* Hackish fix for 1631. We are about to call c_str(), which will produce a string truncated at any embedded nulls. We could fix this by passing around the size, etc. However embedded nulls are never allowed in a filename, so we just check for them and return 0 (no matches) if there is an embedded null. This isn't quite right, e.g. it will fail for \0?, but that is an edge case. */ if (wc.find(L'\0') != wcstring::npos) { return 0; } - // PCA: not convinced this temporary variable is really necessary - std::vector lst; - int res = wildcard_expand(wc.c_str(), base_dir.c_str(), flags, lst); - outputs.insert(outputs.end(), lst.begin(), lst.end()); - return res; + return wildcard_expand(wc.c_str(), base_dir.c_str(), flags, output); } diff --git a/src/wildcard.h b/src/wildcard.h index 8c542221a..7e0b08188 100644 --- a/src/wildcard.h +++ b/src/wildcard.h @@ -68,7 +68,7 @@ enum \return 1 if matches where found, 0 otherwise. Return -1 on abort (I.e. ^C was pressed). */ -int wildcard_expand_string(const wcstring &wc, const wcstring &base_dir, expand_flags_t flags, std::vector &out); +int wildcard_expand_string(const wcstring &wc, const wcstring &base_dir, expand_flags_t flags, std::vector *out); /** Test whether the given wildcard matches the string. Does not perform any I/O. @@ -90,7 +90,7 @@ bool wildcard_complete(const wcstring &str, const wchar_t *wc, const wchar_t *desc, wcstring(*desc_func)(const wcstring &), - std::vector &out, + std::vector *out, expand_flags_t expand_flags, complete_flags_t flags);