From 6e56637cf0a6036fdea4105e9f33314a3d6e8e78 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 31 Mar 2018 16:48:57 -0700 Subject: [PATCH] Remove support for the ? wildcard Fixes #4520 --- CHANGELOG.md | 1 + doc_src/index.hdr.in | 9 ++------ share/completions/git.fish | 42 +++++++++++++++++--------------------- src/common.cpp | 13 ------------ src/expand.cpp | 8 ++------ src/fish_tests.cpp | 42 +++++++++++++++++++++----------------- src/highlight.cpp | 2 -- src/parse_util.cpp | 8 ++------ src/wildcard.cpp | 26 ++++++----------------- src/wildcard.h | 4 +--- tests/string.err | 8 ++++---- tests/string.in | 16 +++++++-------- tests/string.out | 8 ++++---- tests/test1.in | 2 +- tests/test5.in | 2 +- 15 files changed, 74 insertions(+), 117 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c51b7852..b1741ff32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ This section is for changes merged to the `major` branch that are not also merge - The machine hostname, where available, is now exposed as `$hostname` which is now a reserved variable. This drops the dependency on the `hostname` executable (#4422). - `functions --handlers` can be used to show event handlers (#4694). - Variables set in `if` and `while` conditions are available outside the block (#4820). +- The `?` wildcard has been removed (#4520). ## Other significant changes - Command substitution output is now limited to 10 MB by default (#3822). diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index 64b830703..d39a41bf1 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -92,7 +92,6 @@ Some characters can not be written directly on the command line. For these chara - '\\$' escapes the dollar character - '\\\\' escapes the backslash character - '\\*' escapes the star character -- '\\?' escapes the question mark character - '\\~' escapes the tilde character - '\\#' escapes the hash character - '\\(' escapes the left parenthesis character @@ -330,7 +329,7 @@ These are the general purpose tab completions that `fish` provides: - Completion of usernames for tilde expansion. -- Completion of filenames, even on strings with wildcards such as '`*`', '`**`' and '`?`'. +- Completion of filenames, even on strings with wildcards such as '`*`' and '`**`'. `fish` provides a large number of program specific completions. Most of these completions are simple options like the `-l` option for `ls`, but some are more advanced. The latter include: @@ -418,9 +417,7 @@ When an argument for a program is given on the commandline, it undergoes the pro \subsection expand-wildcard Wildcards -If a star (`*`) or a question mark (`?`) is present in the parameter, `fish` attempts to match the given parameter to any files in such a way that: - -- `?` can match any single character except '/'. +If a star (`*`) is present in the parameter, `fish` attempts to match the given parameter to any files in such a way that: - `*` can match any string of characters not containing '/'. This includes matching an empty string. @@ -446,8 +443,6 @@ Examples: - `a*` matches any files beginning with an 'a' in the current directory. -- `???` matches any file in the current directory whose name is exactly three characters long. - - `**` matches any files and directories in the current directory and all of its subdirectories. Note that for most commands, if any wildcard fails to expand, the command is not executed, `$status` is set to nonzero, and a warning is printed. This behavior is consistent with setting `shopt -s failglob` in bash. There are exactly 3 exceptions, namely `set`, `count` and `for`. Their globs are permitted to expand to zero arguments, as with `shopt -s nullglob` in bash. diff --git a/share/completions/git.fish b/share/completions/git.fish index 31997c5b5..9018c03a5 100644 --- a/share/completions/git.fish +++ b/share/completions/git.fish @@ -6,25 +6,18 @@ function __fish_git_commits # This allows filtering by subject with the new pager! # Because even subject lines can be quite long, # trim them (abbrev'd hash+tab+subject) to 73 characters - command git log --pretty=tformat:"%h"\t"%s" --all --max-count=1000 ^/dev/null \ - | string replace -r '(.{73}).+' '$1…' + command git log --pretty=tformat:"%h"\t"%s" --all --max-count=1000 ^/dev/null | string replace -r '(.{73}).+' '$1…' end function __fish_git_recent_commits # Like __fish_git_commits, but not on all branches and limited to # the last 50 commits. Used for fixup, where only the current branch # and the latest commits make sense. - command git log --pretty=tformat:"%h"\t"%s" --max-count=50 ^/dev/null \ - | string replace -r '(.{73}).+' '$1…' + command git log --pretty=tformat:"%h"\t"%s" --max-count=50 ^/dev/null | string replace -r '(.{73}).+' '$1…' end function __fish_git_branches - command git branch --no-color -a $argv ^/dev/null \ - # Filter out detached heads and such ("(HEAD detached at SOMESHA)", localized). - | string match -v '\* (*)' | string match -r -v ' -> ' | string trim -c "* " \ - # We assume anything that's not remote is a local branch. - | string replace -r '^(?!remotes/)(.*)' '$1\tLocal Branch' \ - | string replace -r "^remotes/(.*)" '$1\tRemote Branch' + command git branch --no-color -a $argv ^/dev/null # Filter out detached heads and such ("(HEAD detached at SOMESHA)", localized). | string match -v '\* (*)' | string match -r -v ' -> ' | string trim -c "* " # We assume anything that's not remote is a local branch. | string replace -r '^(?!remotes/)(.*)' '$1\tLocal Branch' | string replace -r "^remotes/(.*)" '$1\tRemote Branch' end function __fish_git_tags @@ -96,8 +89,7 @@ function __fish_git_files # E.g. `git reset $submodule` won't do anything (not even print an error). # --ignore-submodules=all was added in git 1.7.2, released July 2010. set -l use_next - command git status --porcelain -z --ignore-submodules=all \ - | while read -lz -d '' line + command git status --porcelain -z --ignore-submodules=all | while read -lz -d '' line # The entire line is the "from" from a rename. if set -q use_next[1] if contains -- $use_next $argv @@ -144,28 +136,31 @@ function __fish_git_files case 'A ' AM AD # Additions are only shown here if they are staged. # Otherwise it's an untracked file. - contains -- added $argv; or contains -- all-staged $argv + contains -- added $argv + or contains -- all-staged $argv and printf '%s\t%s\n' "$file" $added_desc - case '?M' + case '*M' # Modified contains -- modified $argv and printf '%s\t%s\n' "$file" $modified_desc - case 'M?' + case 'M*' # If the character is first ("M "), then that means it's "our" change, # which means it is staged. # This is useless for many commands - e.g. `checkout` won't do anything with this. # So it needs to be requested explicitly. - contains -- modified-staged $argv; or contains -- all-staged $argv + contains -- modified-staged $argv + or contains -- all-staged $argv and printf '%s\t%s\n' "$file" $staged_modified_desc - case '?D' + case '*D' contains -- deleted $argv and printf '%s\t%s\n' "$file" $deleted_desc - case 'D?' + case 'D*' # TODO: The docs are unclear on this. # There is both X unmodified and Y either M or D ("not updated") # and Y is D and X is unmodified or [MARC] ("deleted in work tree"). # For our purposes, we assume this is a staged deletion. - contains -- deleted-staged $argv; or contains -- all-staged $argv + contains -- deleted-staged $argv + or contains -- all-staged $argv and printf '%s\t%s\n' "$file" $staged_deleted_desc case '\?\?' # Untracked @@ -201,7 +196,8 @@ end function __fish_git_needs_command set cmd (commandline -opc) set -l skip_next 1 - set -q cmd[2]; or return 0 + set -q cmd[2] + or return 0 # Skip first word because it's "git" or a wrapper for c in $cmd[2..-1] test $skip_next -eq 0 @@ -555,7 +551,7 @@ complete -f -c git -n '__fish_git_needs_command' -a init -d 'Create an empty git # TODO options ### log -complete -c git -n '__fish_git_needs_command' -a shortlog -d 'Show commit shortlog' +complete -c git -n '__fish_git_needs_command' -a shortlog -d 'Show commit shortlog' complete -c git -n '__fish_git_needs_command' -a log -d 'Show commit logs' complete -c git -n '__fish_git_using_command log; and not contains -- -- (commandline -op)' -a '(__fish_git_refs) (__fish_git_ranges)' @@ -721,8 +717,8 @@ complete -c git -n '__fish_git_using_command log' -l irreversible-delete -s D complete -f -c git -n '__fish_git_using_command log' -s l function __fish__git_append_letters_nosep - set -l token (commandline -tc) - printf "%s\n" $token$argv + set -l token (commandline -tc) + printf "%s\n" $token$argv end complete -x -c git -n '__fish_git_using_command log' -l diff-filter -a '(__fish__git_append_letters_nosep a\tExclude\ added c\tExclude\ copied d\tExclude\ deleted m\tExclude\ modified r\tExclude\ renamed t\tExclude\ type\ changed u\tExclude\ unmerged x\tExclude\ unknown b\tExclude\ broken A\tAdded C\tCopied D\tDeleted M\tModified R\tRenamed T\tType\ Changed U\tUnmerged X\tUnknown B\tBroken)' diff --git a/src/common.cpp b/src/common.cpp index d39a8a5cb..a1612a06e 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -995,12 +995,6 @@ static void escape_string_script(const wchar_t *orig_in, size_t in_len, wcstring out += *in; break; } - case ANY_CHAR: { - // Experimental fix for #1614. The hope is that any time these appear in a - // string, they came from wildcard expansion. - out += L'?'; - break; - } case ANY_STRING: { out += L'*'; break; @@ -1022,7 +1016,6 @@ static void escape_string_script(const wchar_t *orig_in, size_t in_len, wcstring case L']': case L'{': case L'}': - case L'?': case L'*': case L'|': case L';': @@ -1356,12 +1349,6 @@ static bool unescape_string_internal(const wchar_t *const input, const size_t in } break; } - case L'?': { - if (unescape_special) { - to_append_or_none = ANY_CHAR; - } - break; - } case L'$': { if (unescape_special) { to_append_or_none = VARIABLE_EXPAND; diff --git a/src/expand.cpp b/src/expand.cpp index 38309345c..e3e4cbd01 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -823,15 +823,11 @@ static void remove_internal_separator(wcstring *str, bool conv) { // Remove all instances of INTERNAL_SEPARATOR. str->erase(std::remove(str->begin(), str->end(), (wchar_t)INTERNAL_SEPARATOR), str->end()); - // If conv is true, replace all instances of ANY_CHAR with '?', ANY_STRING with '*', + // If conv is true, replace all instances of ANY_STRING with '*', // ANY_STRING_RECURSIVE with '*'. if (conv) { for (size_t idx = 0; idx < str->size(); idx++) { switch (str->at(idx)) { - case ANY_CHAR: { - str->at(idx) = L'?'; - break; - } case ANY_STRING: case ANY_STRING_RECURSIVE: { str->at(idx) = L'*'; @@ -918,7 +914,7 @@ static expand_error_t expand_stage_wildcards(const wcstring &input, std::vector< wcstring path_to_expand = input; remove_internal_separator(&path_to_expand, flags & EXPAND_SKIP_WILDCARDS); - const bool has_wildcard = wildcard_has(path_to_expand, true /* internal, i.e. ANY_CHAR */); + const bool has_wildcard = wildcard_has(path_to_expand, true /* internal, i.e. ANY_STRING */); if (has_wildcard && (flags & EXECUTABLES_ONLY)) { ; // don't do wildcard expansion for executables, see issue #785 diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 71ee33a94..fb080f632 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -4120,15 +4120,16 @@ static void test_string() { {{L"string", L"match", 0}, STATUS_INVALID_ARGS, L""}, {{L"string", L"match", L"", 0}, STATUS_CMD_ERROR, L""}, {{L"string", L"match", L"", L"", 0}, STATUS_CMD_OK, L"\n"}, - {{L"string", L"match", L"?", L"a", 0}, STATUS_CMD_OK, L"a\n"}, + {{L"string", L"match", L"?", L"a", 0}, STATUS_CMD_ERROR, L""}, {{L"string", L"match", L"*", L"", 0}, STATUS_CMD_OK, L"\n"}, {{L"string", L"match", L"**", L"", 0}, STATUS_CMD_OK, L"\n"}, {{L"string", L"match", L"*", L"xyzzy", 0}, STATUS_CMD_OK, L"xyzzy\n"}, {{L"string", L"match", L"**", L"plugh", 0}, STATUS_CMD_OK, L"plugh\n"}, {{L"string", L"match", L"a*b", L"axxb", 0}, STATUS_CMD_OK, L"axxb\n"}, - {{L"string", L"match", L"a??b", L"axxb", 0}, STATUS_CMD_OK, L"axxb\n"}, - {{L"string", L"match", L"-i", L"a??B", L"axxb", 0}, STATUS_CMD_OK, L"axxb\n"}, - {{L"string", L"match", L"-i", L"a??b", L"Axxb", 0}, STATUS_CMD_OK, L"Axxb\n"}, + {{L"string", L"match", L"a??b", L"axxb", 0}, STATUS_CMD_ERROR, L""}, + {{L"string", L"match", L"a??b", L"a??b", 0}, STATUS_CMD_OK, L"a??b\n"}, + {{L"string", L"match", L"-i", L"a??B", L"axxb", 0}, STATUS_CMD_ERROR, L""}, + {{L"string", L"match", L"-i", L"a??b", L"Axxb", 0}, STATUS_CMD_ERROR, L""}, {{L"string", L"match", L"a*", L"axxb", 0}, STATUS_CMD_OK, L"axxb\n"}, {{L"string", L"match", L"*a", L"xxa", 0}, STATUS_CMD_OK, L"xxa\n"}, {{L"string", L"match", L"*a*", L"axa", 0}, STATUS_CMD_OK, L"axa\n"}, @@ -4137,14 +4138,14 @@ static void test_string() { {{L"string", L"match", L"*a", L"a", 0}, STATUS_CMD_OK, L"a\n"}, {{L"string", L"match", L"a*", L"a", 0}, STATUS_CMD_OK, L"a\n"}, {{L"string", L"match", L"a*b*c", L"axxbyyc", 0}, STATUS_CMD_OK, L"axxbyyc\n"}, - {{L"string", L"match", L"a*b?c", L"axxbyc", 0}, STATUS_CMD_OK, L"axxbyc\n"}, - {{L"string", L"match", L"*?", L"a", 0}, STATUS_CMD_OK, L"a\n"}, - {{L"string", L"match", L"*?", L"ab", 0}, STATUS_CMD_OK, L"ab\n"}, - {{L"string", L"match", L"?*", L"a", 0}, STATUS_CMD_OK, L"a\n"}, - {{L"string", L"match", L"?*", L"ab", 0}, STATUS_CMD_OK, L"ab\n"}, + {{L"string", L"match", L"a*b?c", L"axxb?c", 0}, STATUS_CMD_OK, L"axxb?c\n"}, + {{L"string", L"match", L"*?", L"a", 0}, STATUS_CMD_ERROR, L""}, + {{L"string", L"match", L"*?", L"ab", 0}, STATUS_CMD_ERROR, L""}, + {{L"string", L"match", L"?*", L"a", 0}, STATUS_CMD_ERROR, L""}, + {{L"string", L"match", L"?*", L"ab", 0}, STATUS_CMD_ERROR, L""}, {{L"string", L"match", L"\\*", L"*", 0}, STATUS_CMD_OK, L"*\n"}, {{L"string", L"match", L"a*\\", L"abc\\", 0}, STATUS_CMD_OK, L"abc\\\n"}, - {{L"string", L"match", L"a*\\?", L"abc?", 0}, STATUS_CMD_OK, L"abc?\n"}, + {{L"string", L"match", L"a*\\?", L"abc?", 0}, STATUS_CMD_ERROR, L""}, {{L"string", L"match", L"?", L"", 0}, STATUS_CMD_ERROR, L""}, {{L"string", L"match", L"?", L"ab", 0}, STATUS_CMD_ERROR, L""}, @@ -4428,24 +4429,27 @@ static void test_illegal_command_exit_code() { }; const command_result_tuple_t tests[] = { - {L"echo -n", STATUS_CMD_OK}, {L"pwd", STATUS_CMD_OK}, - // a `)` without a matching `(` is now a tokenizer error, and cannot be executed even as an illegal command + {L"echo -n", STATUS_CMD_OK}, + {L"pwd", STATUS_CMD_OK}, + // a `)` without a matching `(` is now a tokenizer error, and cannot be executed even as an + // illegal command // {L")", STATUS_ILLEGAL_CMD}, {L") ", STATUS_ILLEGAL_CMD}, {L") ", STATUS_ILLEGAL_CMD} - {L"*", STATUS_ILLEGAL_CMD}, {L"**", STATUS_ILLEGAL_CMD}, - {L"?", STATUS_ILLEGAL_CMD}, {L"abc?def", STATUS_ILLEGAL_CMD}, + {L"*", STATUS_ILLEGAL_CMD}, + {L"**", STATUS_ILLEGAL_CMD}, + {L"?", STATUS_CMD_UNKNOWN}, + {L"abc?def", STATUS_CMD_UNKNOWN}, }; int res = 0; const io_chain_t empty_ios; parser_t &parser = parser_t::principal_parser(); - size_t i = 0; - for (i = 0; i < sizeof tests / sizeof *tests; i++) { - res = parser.eval(tests[i].txt, empty_ios, TOP); + for (const auto &test : tests) { + res = parser.eval(test.txt, empty_ios, TOP); int exit_status = res ? STATUS_CMD_UNKNOWN : proc_get_last_status(); - if (exit_status != tests[i].result) { - err(L"command '%ls': expected exit code %d , got %d", tests[i].txt, tests[i].result, + if (exit_status != test.result) { + err(L"command '%ls': expected exit code %d , got %d", test.txt, test.result, exit_status); } } diff --git a/src/highlight.cpp b/src/highlight.cpp index 1b94e87fa..8cb8b2f91 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -125,7 +125,6 @@ bool is_potential_path(const wcstring &potential_path_fragment, const wcstring_l case BRACE_BEGIN: case BRACE_END: case BRACE_SEP: - case ANY_CHAR: case ANY_STRING: case ANY_STRING_RECURSIVE: { has_magic = 1; @@ -549,7 +548,6 @@ static void color_argument_internal(const wcstring &buffstr, break; } case L'*': - case L'?': case L'(': case L')': { colors[in_pos] = highlight_spec_operator; diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 2fb17e94a..a40e9cc20 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -423,9 +423,7 @@ wcstring parse_util_unescape_wildcards(const wcstring &str) { for (size_t i = 0; cs[i] != L'\0'; i++) { if (cs[i] == L'*') { 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'?')) { + } else if (cs[i] == L'\\' && cs[i + 1] == L'*') { result.push_back(cs[i + 1]); i += 1; } else if (cs[i] == L'\\' && cs[i + 1] == L'\\') { @@ -892,9 +890,7 @@ void parse_util_expand_variable_error(const wcstring &token, size_t global_token default: { wchar_t token_stop_char = char_after_dollar; // Unescape (see issue #50). - if (token_stop_char == ANY_CHAR) - token_stop_char = L'?'; - else if (token_stop_char == ANY_STRING || token_stop_char == ANY_STRING_RECURSIVE) + if (token_stop_char == ANY_STRING || token_stop_char == ANY_STRING_RECURSIVE) token_stop_char = L'*'; // Determine which error message to use. The format string may not consume all the diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 48ce0671e..f67836800 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -51,7 +51,7 @@ /// Finds an internal (ANY_STRING, etc.) style wildcard, or wcstring::npos. static size_t wildcard_find(const wchar_t *wc) { for (size_t i = 0; wc[i] != L'\0'; i++) { - if (wc[i] == ANY_CHAR || wc[i] == ANY_STRING || wc[i] == ANY_STRING_RECURSIVE) { + if (wc[i] == ANY_STRING || wc[i] == ANY_STRING_RECURSIVE) { return i; } } @@ -64,13 +64,12 @@ static bool wildcard_has_impl(const wchar_t *str, size_t len, bool internal) { const wchar_t *end = str + len; if (internal) { for (; str < end; str++) { - if ((*str == ANY_CHAR) || (*str == ANY_STRING) || (*str == ANY_STRING_RECURSIVE)) - return true; + if (*str == ANY_STRING || *str == ANY_STRING_RECURSIVE) return true; } } else { wchar_t prev = 0; for (; str < end; str++) { - if (((*str == L'*') || (*str == L'?')) && (prev != L'\\')) return true; + if (*str == L'*' && prev != L'\\') return true; prev = *str; } } @@ -128,13 +127,6 @@ static enum fuzzy_match_type_t wildcard_match_internal(const wchar_t *str, const restart_is_out_of_str = (*str_x == 0); wc_x++; continue; - } else if (*wc_x == ANY_CHAR && *str_x != 0) { - if (is_first && *str_x == L'.') { - return fuzzy_match_none; - } - wc_x++; - str_x++; - continue; } else if (*str_x != 0 && *str_x == *wc_x) { // ordinary character wc_x++; str_x++; @@ -212,7 +204,7 @@ static bool wildcard_complete_internal(const wchar_t *str, const wchar_t *wc, return false; } - // Locate the next wildcard character position, e.g. ANY_CHAR or ANY_STRING. + // Locate the next wildcard character position, e.g. ANY_STRING. const size_t next_wc_char_pos = wildcard_find(wc); // Maybe we have no more wildcards at all. This includes the empty string. @@ -265,12 +257,6 @@ static bool wildcard_complete_internal(const wchar_t *str, const wchar_t *wc, // Our first character is a wildcard. assert(next_wc_char_pos == 0); switch (wc[0]) { - case ANY_CHAR: { - if (str[0] == L'\0') { - return false; - } - return wildcard_complete_internal(str + 1, wc + 1, params, flags, out); - } case ANY_STRING: { // Hackish. If this is the last character of the wildcard, then just complete with // the empty string. This fixes cases like "f*" -> "f*o". @@ -789,7 +775,7 @@ void wildcard_expander_t::expand_last_segment(const wcstring &base_dir, DIR *bas /// /// Args: /// base_dir: the "working directory" against which the wildcard is to be resolved -/// wc: the wildcard string itself, e.g. foo*bar/baz (where * is acutally ANY_CHAR) +/// wc: the wildcard string itself, e.g. foo*bar/baz (where * is acutally ANY_STRING) /// prefix: the string that should be prepended for completions that replace their token. // This is usually the same thing as the original wildcard, but for fuzzy matching, we // expand intermediate segments. effective_prefix is always either empty, or ends with a slash @@ -810,7 +796,7 @@ void wildcard_expander_t::expand(const wcstring &base_dir, const wchar_t *wc, const size_t wc_segment_len = next_slash ? next_slash - wc : wc_len; const wcstring wc_segment = wcstring(wc, wc_segment_len); const bool segment_has_wildcards = - wildcard_has(wc_segment, true /* internal, i.e. look for ANY_CHAR instead of ? */); + wildcard_has(wc_segment, true /* internal, i.e. look for ANY_STRING instead of * */); const wchar_t *const wc_remainder = next_slash ? next_slash + 1 : NULL; if (wc_segment.empty()) { diff --git a/src/wildcard.h b/src/wildcard.h index 5229ee027..614f28b83 100644 --- a/src/wildcard.h +++ b/src/wildcard.h @@ -11,10 +11,8 @@ // Enumeration of all wildcard types. enum { - /// Character representing any character except '/' (slash). - ANY_CHAR = WILDCARD_RESERVED_BASE, /// Character representing any character string not containing '/' (slash). - ANY_STRING, + ANY_STRING = WILDCARD_RESERVED_BASE, /// Character representing any character string. ANY_STRING_RECURSIVE, /// This is a special psuedo-char that is not used other than to mark the diff --git a/tests/string.err b/tests/string.err index 611df012b..4c6095d4f 100644 --- a/tests/string.err +++ b/tests/string.err @@ -117,16 +117,16 @@ # string unescape --style=var (string escape --style=var -- -) #################### -# string match "?" a +# string match "*" a #################### # string match "a*b" axxb #################### -# string match -i "a??B" Axxb +# string match -i "a**B" Axxb #################### -# echo "ok?" | string match "*\?" +# echo "ok?" | string match "*?" #################### # string match -r "cat|dog|fish" "nice dog" @@ -190,7 +190,7 @@ string invalidarg; and echo "unexpected exit 0" # string match -r -v "[dcantg].*" dog can cat diz #################### -# string match -v "???" dog can cat diz +# string match -v "*" dog can cat diz #################### # string match -rvn a bbb diff --git a/tests/string.in b/tests/string.in index 61020accc..78b85ea13 100644 --- a/tests/string.in +++ b/tests/string.in @@ -124,17 +124,17 @@ string unescape --style=var -- (string escape --style=var -- -) # The following tests verify that we can correctly match strings. -logmsg 'string match "?" a' -string match "?" a +logmsg 'string match "*" a' +string match "*" a logmsg 'string match "a*b" axxb' string match "a*b" axxb -logmsg 'string match -i "a??B" Axxb' -string match -i "a??B" Axxb +logmsg 'string match -i "a**B" Axxb' +string match -i "a**B" Axxb -logmsg 'echo "ok?" | string match "*\?"' -echo "ok?" | string match "*\?" +logmsg 'echo "ok?" | string match "*?"' +echo "ok?" | string match "*?" logmsg 'string match -r "cat|dog|fish" "nice dog"' string match -r "cat|dog|fish" "nice dog" @@ -199,8 +199,8 @@ string length; or echo "missing argument returns 1" logmsg 'string match -r -v "[dcantg].*" dog can cat diz' string match -r -v "[dcantg].*" dog can cat diz; or echo "no regexp invert match" -logmsg 'string match -v "???" dog can cat diz' -string match -v "???" dog can cat diz; or echo "no glob invert match" +logmsg 'string match -v "*" dog can cat diz' +string match -v "*" dog can cat diz; or echo "no glob invert match" logmsg 'string match -rvn a bbb' string match -rvn a bbb; or echo "exit 1" diff --git a/tests/string.out b/tests/string.out index b50416b04..68f060419 100644 --- a/tests/string.out +++ b/tests/string.out @@ -170,7 +170,7 @@ _a_b_c_ - #################### -# string match "?" a +# string match "*" a a #################### @@ -178,11 +178,11 @@ a axxb #################### -# string match -i "a??B" Axxb +# string match -i "a**B" Axxb Axxb #################### -# echo "ok?" | string match "*\?" +# echo "ok?" | string match "*?" ok? #################### @@ -272,7 +272,7 @@ missing argument returns 1 no regexp invert match #################### -# string match -v "???" dog can cat diz +# string match -v "*" dog can cat diz no glob invert match #################### diff --git a/tests/test1.in b/tests/test1.in index 980b3d889..d2910b6f4 100644 --- a/tests/test1.in +++ b/tests/test1.in @@ -65,7 +65,7 @@ for i in Test for continue break and switch builtins problems; switch $i case Test printf "%s " $i - case "f??" + case "for" printf "%s " 3b case "c*" echo pass diff --git a/tests/test5.in b/tests/test5.in index 3f99fa002..54b2b3693 100644 --- a/tests/test5.in +++ b/tests/test5.in @@ -20,7 +20,7 @@ end switch $smurf case cyan magenta yellow echo Test 3 fail - case "?????" + case "*" echo Test 3 pass end