From b59904632dd30a5101d459afca56fa3c48f48f12 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 19 Aug 2015 11:35:24 -0700 Subject: [PATCH] Rewrite parse_util_unescape_wildcards Make it simpler, and use wcstring instead of wcsdup --- src/complete.cpp | 6 +-- src/parse_execution.cpp | 3 +- src/parse_tree.cpp | 2 +- src/parse_util.cpp | 91 +++++++++++++---------------------------- src/parse_util.h | 6 +-- 5 files changed, 36 insertions(+), 72 deletions(-) diff --git a/src/complete.cpp b/src/complete.cpp index 25e81c67e..9737060e8 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -935,7 +935,7 @@ void completer_t::complete_strings(const wcstring &wc_escaped, if (! expand_one(tmp, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_WILDCARDS | this->expand_flags(), NULL)) return; - const wchar_t *wc = parse_util_unescape_wildcards(tmp.c_str()); + const wcstring wc = parse_util_unescape_wildcards(tmp); for (size_t i=0; i< possible_comp.size(); i++) { @@ -944,11 +944,9 @@ 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.c_str(), desc, desc_func, &this->completions, this->expand_flags(), flags); } } - - free((void *)wc); } /** diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index e02ad9d78..43e886f59 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -613,9 +613,8 @@ parse_execution_result_t parse_execution_context_t::run_switch_statement(const p const wcstring &arg = case_args.at(i); /* Unescape wildcards so they can be expanded again */ - wchar_t *unescaped_arg = parse_util_unescape_wildcards(arg.c_str()); + wcstring unescaped_arg = parse_util_unescape_wildcards(arg); bool match = wildcard_match(switch_value_expanded, unescaped_arg); - free(unescaped_arg); /* If this matched, we're done */ if (match) diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index 6238ad069..1e16bf15d 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -325,7 +325,7 @@ static wcstring block_type_user_presentable_description(parse_token_type_t type) } /** Returns a string description of the given parse node */ -wcstring parse_node_t::describe(void) const +wcstring parse_node_t::describe() const { wcstring result = token_type_description(type); if (type < FIRST_TERMINAL_TYPE) diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 594416bf7..87468e54a 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -561,75 +561,42 @@ void parse_util_token_extent(const wchar_t *buff, } -wchar_t *parse_util_unescape_wildcards(const wchar_t *str) +wcstring parse_util_unescape_wildcards(const wcstring &str) { - wchar_t *in, *out; - wchar_t *unescaped; - - CHECK(str, 0); - - unescaped = wcsdup(str); - - if (!unescaped) + wcstring result; + result.reserve(str.size()); + + const wchar_t * const cs = str.c_str(); + for (size_t i=0; cs[i] != L'\0'; i++) { - DIE_MEM(); - } - - for (in=out=unescaped; *in; in++) - { - switch (*in) + if (cs[i] == L'*') { - case L'\\': - { - switch (*(in + 1)) - { - case L'*': - case L'?': - { - in++; - *(out++)=*in; - break; - } - case L'\\': - { - in++; - *(out++)=L'\\'; - *(out++)=L'\\'; - break; - } - default: - { - *(out++)=*in; - break; - } - } - break; - } - - case L'*': - { - *(out++)=ANY_STRING; - break; - } - - case L'?': - { - *(out++)=ANY_CHAR; - break; - } - - default: - { - *(out++)=*in; - break; - } + result.push_back(ANY_STRING); + } + else if (cs[i] == L'?') + { + result.push_back(ANY_CHAR); + } + else if (cs[i] == L'\\' && (cs[i+1] == L'*' || cs[i+1] == L'?')) + { + result.push_back(cs[i+1]); + i += 1; + } + else if (cs[i] == L'\\' && cs[i+1] == L'\\') + { + // Not a wildcard, but ensure the next iteration + // doesn't see this escaped backslash + result.append(L"\\\\"); + i += 1; + } + else + { + result.push_back(cs[i]); } } - *out = *in; - return unescaped; + return result; } - /** Find the outermost quoting style of current token. Returns 0 if token is not quoted. diff --git a/src/parse_util.h b/src/parse_util.h index 7c65fc71b..9bafd8e00 100644 --- a/src/parse_util.h +++ b/src/parse_util.h @@ -138,10 +138,10 @@ size_t parse_util_get_offset_from_line(const wcstring &str, int line); size_t parse_util_get_offset(const wcstring &str, int line, long line_offset); /** - Make a duplicate of the specified string, unescape wildcard - characters but not performing any other character transformation. + Return the given string, unescaping wildcard characters but not performing + any other character transformation. */ -wchar_t *parse_util_unescape_wildcards(const wchar_t *in); +wcstring parse_util_unescape_wildcards(const wcstring &in); /** Checks if the specified string is a help option.