Rewrite parse_util_unescape_wildcards

Make it simpler, and use wcstring instead of wcsdup
This commit is contained in:
ridiculousfish 2015-08-19 11:35:24 -07:00
parent c1b9b27f86
commit b59904632d
5 changed files with 36 additions and 72 deletions

View file

@ -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)) if (! expand_one(tmp, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_WILDCARDS | this->expand_flags(), NULL))
return; 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++) 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) 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);
} }
/** /**

View file

@ -613,9 +613,8 @@ parse_execution_result_t parse_execution_context_t::run_switch_statement(const p
const wcstring &arg = case_args.at(i); const wcstring &arg = case_args.at(i);
/* Unescape wildcards so they can be expanded again */ /* 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); bool match = wildcard_match(switch_value_expanded, unescaped_arg);
free(unescaped_arg);
/* If this matched, we're done */ /* If this matched, we're done */
if (match) if (match)

View file

@ -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 */ /** 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); wcstring result = token_type_description(type);
if (type < FIRST_TERMINAL_TYPE) if (type < FIRST_TERMINAL_TYPE)

View file

@ -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; wcstring result;
wchar_t *unescaped; result.reserve(str.size());
CHECK(str, 0); const wchar_t * const cs = str.c_str();
for (size_t i=0; cs[i] != L'\0'; i++)
unescaped = wcsdup(str);
if (!unescaped)
{ {
DIE_MEM(); if (cs[i] == L'*')
}
for (in=out=unescaped; *in; in++)
{
switch (*in)
{ {
case L'\\': result.push_back(ANY_STRING);
{ }
switch (*(in + 1)) else if (cs[i] == L'?')
{ {
case L'*': result.push_back(ANY_CHAR);
case L'?': }
{ else if (cs[i] == L'\\' && (cs[i+1] == L'*' || cs[i+1] == L'?'))
in++; {
*(out++)=*in; result.push_back(cs[i+1]);
break; i += 1;
} }
case L'\\': else if (cs[i] == L'\\' && cs[i+1] == L'\\')
{ {
in++; // Not a wildcard, but ensure the next iteration
*(out++)=L'\\'; // doesn't see this escaped backslash
*(out++)=L'\\'; result.append(L"\\\\");
break; i += 1;
} }
default: else
{ {
*(out++)=*in; result.push_back(cs[i]);
break;
}
}
break;
}
case L'*':
{
*(out++)=ANY_STRING;
break;
}
case L'?':
{
*(out++)=ANY_CHAR;
break;
}
default:
{
*(out++)=*in;
break;
}
} }
} }
*out = *in; return result;
return unescaped;
} }
/** /**
Find the outermost quoting style of current token. Returns 0 if Find the outermost quoting style of current token. Returns 0 if
token is not quoted. token is not quoted.

View file

@ -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); size_t parse_util_get_offset(const wcstring &str, int line, long line_offset);
/** /**
Make a duplicate of the specified string, unescape wildcard Return the given string, unescaping wildcard characters but not performing
characters but not performing any other character transformation. 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. Checks if the specified string is a help option.