{"thread":{"id":"31780","subject":"[PATCH v4 00/12] Wildmatch v4","startedAt":"2012-10-10T10:40:39Z","lastAt":"2012-10-13T03:49:34Z","messageCount":28,"participants":["Nguyễn Thái Ngọc Duy","Michael Haggerty","Junio C Hamano","Nguyen Thai Ngoc Duy","Johannes Sixt","Torsten Bögershausen"],"isPatch":true,"patchVersion":4,"patchTotal":12},"messages":[{"id":"200897","messageId":"1349865651-31889-1-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":null,"subject":"[PATCH v4 00/12] Wildmatch v4","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:39Z","receivedAt":"2012-10-10T10:40:39Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Really small updates. I did not want to resend it this soon but this\nmay fix the compile errors for Junio. Changes are\n\n - cleanup in wildmatch.c so #include \"cache.h\" is at the top of the\n   file.\n\n - wildmatch() returns no match if it encounters \"**\" without\n   surrounding slashes. It returns a special code so we can actually\n   show a warning at higher level. I don't want to do that now\n   because I want to mark the pattern \"broken\" in attr.c/dir.c so\n   the pattern will never be used again, and the message shown only\n   once. That needs nd/attr-match-optim-more, but I don't want to tie\n   this series to that just yet.\n\nNguyễn Thái Ngọc Duy (12):\n  ctype: make sane_ctype[] const array\n  ctype: support iscntrl, ispunct, isxdigit and isprint\n  Import wildmatch from rsync\n  wildmatch: remove unnecessary functions\n  Integrate wildmatch to git\n  wildmatch: make wildmatch's return value compatible with fnmatch\n  wildmatch: remove static variable force_lower_case\n  wildmatch: fix case-insensitive matching\n  wildmatch: adjust \"**\" behavior\n  wildmatch: make /**/ match zero or more directories\n  Support \"**\" wildcard in .gitignore and .gitattributes\n  t3070: disable two fnmatch tests that have different results on\n    different libc\n\n .gitignore                         |   1 +\n Documentation/gitattributes.txt    |   6 +\n Documentation/gitignore.txt        |  19 +++\n Makefile                           |   3 +\n attr.c                             |   4 +-\n ctype.c                            |  20 +++-\n dir.c                              |   4 +-\n git-compat-util.h                  |  15 ++-\n t/t0003-attributes.sh              |  38 ++++++\n t/t3001-ls-files-others-exclude.sh |  19 +++\n t/t3070-wildmatch.sh               | 187 +++++++++++++++++++++++++++++\n test-wildmatch.c                   |  14 +++\n wildmatch.c                        | 240 +++++++++++++++++++++++++++++++++++++\n wildmatch.h                        |   9 ++\n 14 files changed, 575 insertions(+), 4 deletions(-)\n create mode 100755 t/t3070-wildmatch.sh\n create mode 100644 test-wildmatch.c\n create mode 100644 wildmatch.c\n create mode 100644 wildmatch.h\n\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200898","messageId":"1349865651-31889-2-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 01/12] ctype: make sane_ctype[] const array","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:40Z","receivedAt":"2012-10-10T10:40:40Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n ctype.c           | 2 +-\n git-compat-util.h | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/ctype.c b/ctype.c\nindex 9353271..faeaf34 100644\n--- a/ctype.c\n+++ b/ctype.c\n@@ -14,7 +14,7 @@ enum {\n \tP = GIT_PATHSPEC_MAGIC  /* other non-alnum, except for ] and } */\n };\n \n-unsigned char sane_ctype[256] = {\n+const unsigned char sane_ctype[256] = {\n \t0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0,\t\t/*   0.. 15 */\n \t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\t\t/*  16.. 31 */\n \tS, P, P, P, R, P, P, P, R, R, G, R, P, P, R, P,\t\t/*  32.. 47 */\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 2fbf1fd..f8b859c 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -510,7 +510,7 @@ extern const char tolower_trans_tbl[256];\n #undef isupper\n #undef tolower\n #undef toupper\n-extern unsigned char sane_ctype[256];\n+extern const unsigned char sane_ctype[256];\n #define GIT_SPACE 0x01\n #define GIT_DIGIT 0x02\n #define GIT_ALPHA 0x04\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200899","messageId":"1349865651-31889-3-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 02/12] ctype: support iscntrl, ispunct, isxdigit and isprint","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:41Z","receivedAt":"2012-10-10T10:40:41Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"A new table sane_ctype2[] is added, otherwise we'll need to OR with\ncurrent bits in sane_ctype[] and that looks ugly.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n ctype.c           | 18 ++++++++++++++++++\n git-compat-util.h | 13 +++++++++++++\n 2 files changed, 31 insertions(+)\n\ndiff --git a/ctype.c b/ctype.c\nindex faeaf34..b4bf48a 100644\n--- a/ctype.c\n+++ b/ctype.c\n@@ -26,6 +26,24 @@ const unsigned char sane_ctype[256] = {\n \t/* Nothing in the 128.. range */\n };\n \n+enum {\n+\tCN = GIT_CNTRL,\n+\tPU = GIT_PUNCT,\n+\tXD = GIT_XDIGIT,\n+};\n+\n+const unsigned char sane_ctype2[256] = {\n+\tCN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, /*    0..15 */\n+\tCN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, CN, /*   16..31 */\n+\t0,  PU, PU, PU, PU, PU, PU, PU, PU, PU, PU, PU, PU, PU, PU, PU, /*   32..47 */\n+\tXD, XD, XD, XD, XD, XD, XD, XD, XD, XD, PU, PU, PU, PU, PU, PU, /*   48..63 */\n+\tPU, 0,\tXD, 0,\tXD, 0,\tXD, 0,\t0,  0,\t0,  0,\t0,  0,\t0,  0,\t/*   64..79 */\n+\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  PU, PU, PU, PU, PU, /*   80..95 */\n+\tPU, 0,\tXD, 0,\tXD, 0,\tXD, 0,\t0,  0,\t0,  0,\t0,  0,\t0,  0,\t/*  96..111 */\n+\t0,  0,\t0,  0,\t0,  0,\t0,  0,\t0,  0,\t0,  PU, PU, PU, PU, CN, /* 112..127 */\n+\t/* Nothing in the 128.. range */\n+};\n+\n /* For case-insensitive kwset */\n const char tolower_trans_tbl[256] = {\n \t0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex f8b859c..ea11694 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -510,14 +510,23 @@ extern const char tolower_trans_tbl[256];\n #undef isupper\n #undef tolower\n #undef toupper\n+#undef iscntrl\n+#undef ispunct\n+#undef isxdigit\n+#undef isprint\n extern const unsigned char sane_ctype[256];\n+extern const unsigned char sane_ctype2[256];\n #define GIT_SPACE 0x01\n #define GIT_DIGIT 0x02\n #define GIT_ALPHA 0x04\n #define GIT_GLOB_SPECIAL 0x08\n #define GIT_REGEX_SPECIAL 0x10\n #define GIT_PATHSPEC_MAGIC 0x20\n+#define GIT_CNTRL 0x01\n+#define GIT_PUNCT 0x02\n+#define GIT_XDIGIT 0x04\n #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n+#define sane_istest2(x,mask) ((sane_ctype2[(unsigned char)(x)] & (mask)) != 0)\n #define isascii(x) (((x) & ~0x7f) == 0)\n #define isspace(x) sane_istest(x,GIT_SPACE)\n #define isdigit(x) sane_istest(x,GIT_DIGIT)\n@@ -527,6 +536,10 @@ extern const unsigned char sane_ctype[256];\n #define isupper(x) sane_iscase(x, 0)\n #define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL)\n #define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL)\n+#define iscntrl(x) sane_istest2(x, GIT_CNTRL)\n+#define ispunct(x) sane_istest2(x, GIT_PUNCT)\n+#define isxdigit(x) sane_istest2(x, GIT_XDIGIT)\n+#define isprint(x) (isalnum(x) || isspace(x) || ispunct(x))\n #define tolower(x) sane_case((unsigned char)(x), 0x20)\n #define toupper(x) sane_case((unsigned char)(x), 0)\n #define is_pathspec_magic(x) sane_istest(x,GIT_PATHSPEC_MAGIC)\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200900","messageId":"1349865651-31889-4-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 03/12] Import wildmatch from rsync","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:42Z","receivedAt":"2012-10-10T10:40:42Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"These files are from rsync.git commit\nf92f5b166e3019db42bc7fe1aa2f1a9178cd215d, which was the last commit\nbefore rsync turned GPL-3. All files are imported as-is and\nno-op. Adaptation is done in a separate patch.\n\nrsync.git           ->  git.git\nlib/wildmatch.[ch]      wildmatch.[ch]\nwildtest.txt            t/t3070/wildtest.txt\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t3070/wildtest.txt | 165 +++++++++++++++++++++++\n wildmatch.c          | 368 +++++++++++++++++++++++++++++++++++++++++++++++++++\n wildmatch.h          |   6 +\n 3 files changed, 539 insertions(+)\n create mode 100644 t/t3070/wildtest.txt\n create mode 100644 wildmatch.c\n create mode 100644 wildmatch.h\n\ndiff --git a/t/t3070/wildtest.txt b/t/t3070/wildtest.txt\nnew file mode 100644\nindex 0000000..42c1678\n--- /dev/null\n+++ b/t/t3070/wildtest.txt\n@@ -0,0 +1,165 @@\n+# Input is in the following format (all items white-space separated):\n+#\n+# The first two items are 1 or 0 indicating if the wildmat call is expected to\n+# succeed and if fnmatch works the same way as wildmat, respectively.  After\n+# that is a text string for the match, and a pattern string.  Strings can be\n+# quoted (if desired) in either double or single quotes, as well as backticks.\n+#\n+# MATCH FNMATCH_SAME \"text to match\" 'pattern to use'\n+\n+# Basic wildmat features\n+1 1 foo\t\t\tfoo\n+0 1 foo\t\t\tbar\n+1 1 ''\t\t\t\"\"\n+1 1 foo\t\t\t???\n+0 1 foo\t\t\t??\n+1 1 foo\t\t\t*\n+1 1 foo\t\t\tf*\n+0 1 foo\t\t\t*f\n+1 1 foo\t\t\t*foo*\n+1 1 foobar\t\t*ob*a*r*\n+1 1 aaaaaaabababab\t*ab\n+1 1 foo*\t\tfoo\\*\n+0 1 foobar\t\tfoo\\*bar\n+1 1 f\\oo\t\tf\\\\oo\n+1 1 ball\t\t*[al]?\n+0 1 ten\t\t\t[ten]\n+1 1 ten\t\t\t**[!te]\n+0 1 ten\t\t\t**[!ten]\n+1 1 ten\t\t\tt[a-g]n\n+0 1 ten\t\t\tt[!a-g]n\n+1 1 ton\t\t\tt[!a-g]n\n+1 1 ton\t\t\tt[^a-g]n\n+1 1 a]b\t\t\ta[]]b\n+1 1 a-b\t\t\ta[]-]b\n+1 1 a]b\t\t\ta[]-]b\n+0 1 aab\t\t\ta[]-]b\n+1 1 aab\t\t\ta[]a-]b\n+1 1 ]\t\t\t]\n+\n+# Extended slash-matching features\n+0 1 foo/baz/bar\t\tfoo*bar\n+1 1 foo/baz/bar\t\tfoo**bar\n+0 1 foo/bar\t\tfoo?bar\n+0 1 foo/bar\t\tfoo[/]bar\n+0 1 foo/bar\t\tf[^eiu][^eiu][^eiu][^eiu][^eiu]r\n+1 1 foo-bar\t\tf[^eiu][^eiu][^eiu][^eiu][^eiu]r\n+0 1 foo\t\t\t**/foo\n+1 1 /foo\t\t**/foo\n+1 1 bar/baz/foo\t\t**/foo\n+0 1 bar/baz/foo\t\t*/foo\n+0 0 foo/bar/baz\t\t**/bar*\n+1 1 deep/foo/bar/baz\t**/bar/*\n+0 1 deep/foo/bar/baz/\t**/bar/*\n+1 1 deep/foo/bar/baz/\t**/bar/**\n+0 1 deep/foo/bar\t**/bar/*\n+1 1 deep/foo/bar/\t**/bar/**\n+1 1 foo/bar/baz\t\t**/bar**\n+1 1 foo/bar/baz/x\t*/bar/**\n+0 0 deep/foo/bar/baz/x\t*/bar/**\n+1 1 deep/foo/bar/baz/x\t**/bar/*/*\n+\n+# Various additional tests\n+0 1 acrt\t\ta[c-c]st\n+1 1 acrt\t\ta[c-c]rt\n+0 1 ]\t\t\t[!]-]\n+1 1 a\t\t\t[!]-]\n+0 1 ''\t\t\t\\\n+0 1 \\\t\t\t\\\n+0 1 /\\\t\t\t*/\\\n+1 1 /\\\t\t\t*/\\\\\n+1 1 foo\t\t\tfoo\n+1 1 @foo\t\t@foo\n+0 1 foo\t\t\t@foo\n+1 1 [ab]\t\t\\[ab]\n+1 1 [ab]\t\t[[]ab]\n+1 1 [ab]\t\t[[:]ab]\n+0 1 [ab]\t\t[[::]ab]\n+1 1 [ab]\t\t[[:digit]ab]\n+1 1 [ab]\t\t[\\[:]ab]\n+1 1 ?a?b\t\t\\??\\?b\n+1 1 abc\t\t\t\\a\\b\\c\n+0 1 foo\t\t\t''\n+1 1 foo/bar/baz/to\t**/t[o]\n+\n+# Character class tests\n+1 1 a1B\t\t[[:alpha:]][[:digit:]][[:upper:]]\n+0 1 a\t\t[[:digit:][:upper:][:space:]]\n+1 1 A\t\t[[:digit:][:upper:][:space:]]\n+1 1 1\t\t[[:digit:][:upper:][:space:]]\n+0 1 1\t\t[[:digit:][:upper:][:spaci:]]\n+1 1 ' '\t\t[[:digit:][:upper:][:space:]]\n+0 1 .\t\t[[:digit:][:upper:][:space:]]\n+1 1 .\t\t[[:digit:][:punct:][:space:]]\n+1 1 5\t\t[[:xdigit:]]\n+1 1 f\t\t[[:xdigit:]]\n+1 1 D\t\t[[:xdigit:]]\n+1 1 _\t\t[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n+#1 1 �\t\t[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n+1 1 \t\t[^[:alnum:][:alpha:][:blank:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n+1 1 .\t\t[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]\n+1 1 5\t\t[a-c[:digit:]x-z]\n+1 1 b\t\t[a-c[:digit:]x-z]\n+1 1 y\t\t[a-c[:digit:]x-z]\n+0 1 q\t\t[a-c[:digit:]x-z]\n+\n+# Additional tests, including some malformed wildmats\n+1 1 ]\t\t[\\\\-^]\n+0 1 [\t\t[\\\\-^]\n+1 1 -\t\t[\\-_]\n+1 1 ]\t\t[\\]]\n+0 1 \\]\t\t[\\]]\n+0 1 \\\t\t[\\]]\n+0 1 ab\t\ta[]b\n+0 1 a[]b\ta[]b\n+0 1 ab[\t\tab[\n+0 1 ab\t\t[!\n+0 1 ab\t\t[-\n+1 1 -\t\t[-]\n+0 1 -\t\t[a-\n+0 1 -\t\t[!a-\n+1 1 -\t\t[--A]\n+1 1 5\t\t[--A]\n+1 1 ' '\t\t'[ --]'\n+1 1 $\t\t'[ --]'\n+1 1 -\t\t'[ --]'\n+0 1 0\t\t'[ --]'\n+1 1 -\t\t[---]\n+1 1 -\t\t[------]\n+0 1 j\t\t[a-e-n]\n+1 1 -\t\t[a-e-n]\n+1 1 a\t\t[!------]\n+0 1 [\t\t[]-a]\n+1 1 ^\t\t[]-a]\n+0 1 ^\t\t[!]-a]\n+1 1 [\t\t[!]-a]\n+1 1 ^\t\t[a^bc]\n+1 1 -b]\t\t[a-]b]\n+0 1 \\\t\t[\\]\n+1 1 \\\t\t[\\\\]\n+0 1 \\\t\t[!\\\\]\n+1 1 G\t\t[A-\\\\]\n+0 1 aaabbb\tb*a\n+0 1 aabcaa\t*ba*\n+1 1 ,\t\t[,]\n+1 1 ,\t\t[\\\\,]\n+1 1 \\\t\t[\\\\,]\n+1 1 -\t\t[,-.]\n+0 1 +\t\t[,-.]\n+0 1 -.]\t\t[,-.]\n+1 1 2\t\t[\\1-\\3]\n+1 1 3\t\t[\\1-\\3]\n+0 1 4\t\t[\\1-\\3]\n+1 1 \\\t\t[[-\\]]\n+1 1 [\t\t[[-\\]]\n+1 1 ]\t\t[[-\\]]\n+0 1 -\t\t[[-\\]]\n+\n+# Test recursion and the abort code (use \"wildtest -i\" to see iteration counts)\n+1 1 -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1\t-*-*-*-*-*-*-12-*-*-*-m-*-*-*\n+0 1 -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1\t-*-*-*-*-*-*-12-*-*-*-m-*-*-*\n+0 1 -adobe-courier-bold-o-normal--12-120-75-75-/-70-iso8859-1\t-*-*-*-*-*-*-12-*-*-*-m-*-*-*\n+1 1 /adobe/courier/bold/o/normal//12/120/75/75/m/70/iso8859/1\t/*/*/*/*/*/*/12/*/*/*/m/*/*/*\n+0 1 /adobe/courier/bold/o/normal//12/120/75/75/X/70/iso8859/1\t/*/*/*/*/*/*/12/*/*/*/m/*/*/*\n+1 1 abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txt\t\t**/*a*b*g*n*t\n+0 1 abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txtz\t\t**/*a*b*g*n*t\ndiff --git a/wildmatch.c b/wildmatch.c\nnew file mode 100644\nindex 0000000..f3a1731\n--- /dev/null\n+++ b/wildmatch.c\n@@ -0,0 +1,368 @@\n+/*\n+**  Do shell-style pattern matching for ?, \\, [], and * characters.\n+**  It is 8bit clean.\n+**\n+**  Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.\n+**  Rich $alz is now <rsalz@bbn.com>.\n+**\n+**  Modified by Wayne Davison to special-case '/' matching, to make '**'\n+**  work differently than '*', and to fix the character-class code.\n+*/\n+\n+#include \"rsync.h\"\n+\n+/* What character marks an inverted character class? */\n+#define NEGATE_CLASS\t'!'\n+#define NEGATE_CLASS2\t'^'\n+\n+#define FALSE 0\n+#define TRUE 1\n+#define ABORT_ALL -1\n+#define ABORT_TO_STARSTAR -2\n+\n+#define CC_EQ(class, len, litmatch) ((len) == sizeof (litmatch)-1 \\\n+\t\t\t\t    && *(class) == *(litmatch) \\\n+\t\t\t\t    && strncmp((char*)class, litmatch, len) == 0)\n+\n+#if defined STDC_HEADERS || !defined isascii\n+# define ISASCII(c) 1\n+#else\n+# define ISASCII(c) isascii(c)\n+#endif\n+\n+#ifdef isblank\n+# define ISBLANK(c) (ISASCII(c) && isblank(c))\n+#else\n+# define ISBLANK(c) ((c) == ' ' || (c) == '\\t')\n+#endif\n+\n+#ifdef isgraph\n+# define ISGRAPH(c) (ISASCII(c) && isgraph(c))\n+#else\n+# define ISGRAPH(c) (ISASCII(c) && isprint(c) && !isspace(c))\n+#endif\n+\n+#define ISPRINT(c) (ISASCII(c) && isprint(c))\n+#define ISDIGIT(c) (ISASCII(c) && isdigit(c))\n+#define ISALNUM(c) (ISASCII(c) && isalnum(c))\n+#define ISALPHA(c) (ISASCII(c) && isalpha(c))\n+#define ISCNTRL(c) (ISASCII(c) && iscntrl(c))\n+#define ISLOWER(c) (ISASCII(c) && islower(c))\n+#define ISPUNCT(c) (ISASCII(c) && ispunct(c))\n+#define ISSPACE(c) (ISASCII(c) && isspace(c))\n+#define ISUPPER(c) (ISASCII(c) && isupper(c))\n+#define ISXDIGIT(c) (ISASCII(c) && isxdigit(c))\n+\n+#ifdef WILD_TEST_ITERATIONS\n+int wildmatch_iteration_count;\n+#endif\n+\n+static int force_lower_case = 0;\n+\n+/* Match pattern \"p\" against the a virtually-joined string consisting\n+ * of \"text\" and any strings in array \"a\". */\n+static int dowild(const uchar *p, const uchar *text, const uchar*const *a)\n+{\n+    uchar p_ch;\n+\n+#ifdef WILD_TEST_ITERATIONS\n+    wildmatch_iteration_count++;\n+#endif\n+\n+    for ( ; (p_ch = *p) != '\\0'; text++, p++) {\n+\tint matched, special;\n+\tuchar t_ch, prev_ch;\n+\twhile ((t_ch = *text) == '\\0') {\n+\t    if (*a == NULL) {\n+\t\tif (p_ch != '*')\n+\t\t    return ABORT_ALL;\n+\t\tbreak;\n+\t    }\n+\t    text = *a++;\n+\t}\n+\tif (force_lower_case && ISUPPER(t_ch))\n+\t    t_ch = tolower(t_ch);\n+\tswitch (p_ch) {\n+\t  case '\\\\':\n+\t    /* Literal match with following character.  Note that the test\n+\t     * in \"default\" handles the p[1] == '\\0' failure case. */\n+\t    p_ch = *++p;\n+\t    /* FALLTHROUGH */\n+\t  default:\n+\t    if (t_ch != p_ch)\n+\t\treturn FALSE;\n+\t    continue;\n+\t  case '?':\n+\t    /* Match anything but '/'. */\n+\t    if (t_ch == '/')\n+\t\treturn FALSE;\n+\t    continue;\n+\t  case '*':\n+\t    if (*++p == '*') {\n+\t\twhile (*++p == '*') {}\n+\t\tspecial = TRUE;\n+\t    } else\n+\t\tspecial = FALSE;\n+\t    if (*p == '\\0') {\n+\t\t/* Trailing \"**\" matches everything.  Trailing \"*\" matches\n+\t\t * only if there are no more slash characters. */\n+\t\tif (!special) {\n+\t\t    do {\n+\t\t\tif (strchr((char*)text, '/') != NULL)\n+\t\t\t    return FALSE;\n+\t\t    } while ((text = *a++) != NULL);\n+\t\t}\n+\t\treturn TRUE;\n+\t    }\n+\t    while (1) {\n+\t\tif (t_ch == '\\0') {\n+\t\t    if ((text = *a++) == NULL)\n+\t\t\tbreak;\n+\t\t    t_ch = *text;\n+\t\t    continue;\n+\t\t}\n+\t\tif ((matched = dowild(p, text, a)) != FALSE) {\n+\t\t    if (!special || matched != ABORT_TO_STARSTAR)\n+\t\t\treturn matched;\n+\t\t} else if (!special && t_ch == '/')\n+\t\t    return ABORT_TO_STARSTAR;\n+\t\tt_ch = *++text;\n+\t    }\n+\t    return ABORT_ALL;\n+\t  case '[':\n+\t    p_ch = *++p;\n+#ifdef NEGATE_CLASS2\n+\t    if (p_ch == NEGATE_CLASS2)\n+\t\tp_ch = NEGATE_CLASS;\n+#endif\n+\t    /* Assign literal TRUE/FALSE because of \"matched\" comparison. */\n+\t    special = p_ch == NEGATE_CLASS? TRUE : FALSE;\n+\t    if (special) {\n+\t\t/* Inverted character class. */\n+\t\tp_ch = *++p;\n+\t    }\n+\t    prev_ch = 0;\n+\t    matched = FALSE;\n+\t    do {\n+\t\tif (!p_ch)\n+\t\t    return ABORT_ALL;\n+\t\tif (p_ch == '\\\\') {\n+\t\t    p_ch = *++p;\n+\t\t    if (!p_ch)\n+\t\t\treturn ABORT_ALL;\n+\t\t    if (t_ch == p_ch)\n+\t\t\tmatched = TRUE;\n+\t\t} else if (p_ch == '-' && prev_ch && p[1] && p[1] != ']') {\n+\t\t    p_ch = *++p;\n+\t\t    if (p_ch == '\\\\') {\n+\t\t\tp_ch = *++p;\n+\t\t\tif (!p_ch)\n+\t\t\t    return ABORT_ALL;\n+\t\t    }\n+\t\t    if (t_ch <= p_ch && t_ch >= prev_ch)\n+\t\t\tmatched = TRUE;\n+\t\t    p_ch = 0; /* This makes \"prev_ch\" get set to 0. */\n+\t\t} else if (p_ch == '[' && p[1] == ':') {\n+\t\t    const uchar *s;\n+\t\t    int i;\n+\t\t    for (s = p += 2; (p_ch = *p) && p_ch != ']'; p++) {} /*SHARED ITERATOR*/\n+\t\t    if (!p_ch)\n+\t\t\treturn ABORT_ALL;\n+\t\t    i = p - s - 1;\n+\t\t    if (i < 0 || p[-1] != ':') {\n+\t\t\t/* Didn't find \":]\", so treat like a normal set. */\n+\t\t\tp = s - 2;\n+\t\t\tp_ch = '[';\n+\t\t\tif (t_ch == p_ch)\n+\t\t\t    matched = TRUE;\n+\t\t\tcontinue;\n+\t\t    }\n+\t\t    if (CC_EQ(s,i, \"alnum\")) {\n+\t\t\tif (ISALNUM(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"alpha\")) {\n+\t\t\tif (ISALPHA(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"blank\")) {\n+\t\t\tif (ISBLANK(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"cntrl\")) {\n+\t\t\tif (ISCNTRL(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"digit\")) {\n+\t\t\tif (ISDIGIT(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"graph\")) {\n+\t\t\tif (ISGRAPH(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"lower\")) {\n+\t\t\tif (ISLOWER(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"print\")) {\n+\t\t\tif (ISPRINT(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"punct\")) {\n+\t\t\tif (ISPUNCT(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"space\")) {\n+\t\t\tif (ISSPACE(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"upper\")) {\n+\t\t\tif (ISUPPER(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else if (CC_EQ(s,i, \"xdigit\")) {\n+\t\t\tif (ISXDIGIT(t_ch))\n+\t\t\t    matched = TRUE;\n+\t\t    } else /* malformed [:class:] string */\n+\t\t\treturn ABORT_ALL;\n+\t\t    p_ch = 0; /* This makes \"prev_ch\" get set to 0. */\n+\t\t} else if (t_ch == p_ch)\n+\t\t    matched = TRUE;\n+\t    } while (prev_ch = p_ch, (p_ch = *++p) != ']');\n+\t    if (matched == special || t_ch == '/')\n+\t\treturn FALSE;\n+\t    continue;\n+\t}\n+    }\n+\n+    do {\n+\tif (*text)\n+\t    return FALSE;\n+    } while ((text = *a++) != NULL);\n+\n+    return TRUE;\n+}\n+\n+/* Match literal string \"s\" against the a virtually-joined string consisting\n+ * of \"text\" and any strings in array \"a\". */\n+static int doliteral(const uchar *s, const uchar *text, const uchar*const *a)\n+{\n+    for ( ; *s != '\\0'; text++, s++) {\n+\twhile (*text == '\\0') {\n+\t    if ((text = *a++) == NULL)\n+\t\treturn FALSE;\n+\t}\n+\tif (*text != *s)\n+\t    return FALSE;\n+    }\n+\n+    do {\n+\tif (*text)\n+\t    return FALSE;\n+    } while ((text = *a++) != NULL);\n+\n+    return TRUE;\n+}\n+\n+/* Return the last \"count\" path elements from the concatenated string.\n+ * We return a string pointer to the start of the string, and update the\n+ * array pointer-pointer to point to any remaining string elements. */\n+static const uchar *trailing_N_elements(const uchar*const **a_ptr, int count)\n+{\n+    const uchar*const *a = *a_ptr;\n+    const uchar*const *first_a = a;\n+\n+    while (*a)\n+\t    a++;\n+\n+    while (a != first_a) {\n+\tconst uchar *s = *--a;\n+\ts += strlen((char*)s);\n+\twhile (--s >= *a) {\n+\t    if (*s == '/' && !--count) {\n+\t\t*a_ptr = a+1;\n+\t\treturn s+1;\n+\t    }\n+\t}\n+    }\n+\n+    if (count == 1) {\n+\t*a_ptr = a+1;\n+\treturn *a;\n+    }\n+\n+    return NULL;\n+}\n+\n+/* Match the \"pattern\" against the \"text\" string. */\n+int wildmatch(const char *pattern, const char *text)\n+{\n+    static const uchar *nomore[1]; /* A NULL pointer. */\n+#ifdef WILD_TEST_ITERATIONS\n+    wildmatch_iteration_count = 0;\n+#endif\n+    return dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;\n+}\n+\n+/* Match the \"pattern\" against the forced-to-lower-case \"text\" string. */\n+int iwildmatch(const char *pattern, const char *text)\n+{\n+    static const uchar *nomore[1]; /* A NULL pointer. */\n+    int ret;\n+#ifdef WILD_TEST_ITERATIONS\n+    wildmatch_iteration_count = 0;\n+#endif\n+    force_lower_case = 1;\n+    ret = dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;\n+    force_lower_case = 0;\n+    return ret;\n+}\n+\n+/* Match pattern \"p\" against the a virtually-joined string consisting\n+ * of all the pointers in array \"texts\" (which has a NULL pointer at the\n+ * end).  The int \"where\" can be 0 (normal matching), > 0 (match only\n+ * the trailing N slash-separated filename components of \"texts\"), or < 0\n+ * (match the \"pattern\" at the start or after any slash in \"texts\"). */\n+int wildmatch_array(const char *pattern, const char*const *texts, int where)\n+{\n+    const uchar *p = (const uchar*)pattern;\n+    const uchar*const *a = (const uchar*const*)texts;\n+    const uchar *text;\n+    int matched;\n+\n+#ifdef WILD_TEST_ITERATIONS\n+    wildmatch_iteration_count = 0;\n+#endif\n+\n+    if (where > 0)\n+\ttext = trailing_N_elements(&a, where);\n+    else\n+\ttext = *a++;\n+    if (!text)\n+\treturn FALSE;\n+\n+    if ((matched = dowild(p, text, a)) != TRUE && where < 0\n+     && matched != ABORT_ALL) {\n+\twhile (1) {\n+\t    if (*text == '\\0') {\n+\t\tif ((text = (uchar*)*a++) == NULL)\n+\t\t    return FALSE;\n+\t\tcontinue;\n+\t    }\n+\t    if (*text++ == '/' && (matched = dowild(p, text, a)) != FALSE\n+\t     && matched != ABORT_TO_STARSTAR)\n+\t\tbreak;\n+\t}\n+    }\n+    return matched == TRUE;\n+}\n+\n+/* Match literal string \"s\" against the a virtually-joined string consisting\n+ * of all the pointers in array \"texts\" (which has a NULL pointer at the\n+ * end).  The int \"where\" can be 0 (normal matching), or > 0 (match\n+ * only the trailing N slash-separated filename components of \"texts\"). */\n+int litmatch_array(const char *string, const char*const *texts, int where)\n+{\n+    const uchar *s = (const uchar*)string;\n+    const uchar*const *a = (const uchar* const*)texts;\n+    const uchar *text;\n+\n+    if (where > 0)\n+\ttext = trailing_N_elements(&a, where);\n+    else\n+\ttext = *a++;\n+    if (!text)\n+\treturn FALSE;\n+\n+    return doliteral(s, text, a) == TRUE;\n+}\ndiff --git a/wildmatch.h b/wildmatch.h\nnew file mode 100644\nindex 0000000..e7f1a35\n--- /dev/null\n+++ b/wildmatch.h\n@@ -0,0 +1,6 @@\n+/* wildmatch.h */\n+\n+int wildmatch(const char *pattern, const char *text);\n+int iwildmatch(const char *pattern, const char *text);\n+int wildmatch_array(const char *pattern, const char*const *texts, int where);\n+int litmatch_array(const char *string, const char*const *texts, int where);\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200901","messageId":"1349865651-31889-5-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 04/12] wildmatch: remove unnecessary functions","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:43Z","receivedAt":"2012-10-10T10:40:43Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n wildmatch.c | 161 ++++--------------------------------------------------------\n wildmatch.h |   2 -\n 2 files changed, 9 insertions(+), 154 deletions(-)\n\ndiff --git a/wildmatch.c b/wildmatch.c\nindex f3a1731..71dba76 100644\n--- a/wildmatch.c\n+++ b/wildmatch.c\n@@ -53,33 +53,19 @@\n #define ISUPPER(c) (ISASCII(c) && isupper(c))\n #define ISXDIGIT(c) (ISASCII(c) && isxdigit(c))\n \n-#ifdef WILD_TEST_ITERATIONS\n-int wildmatch_iteration_count;\n-#endif\n-\n static int force_lower_case = 0;\n \n /* Match pattern \"p\" against the a virtually-joined string consisting\n  * of \"text\" and any strings in array \"a\". */\n-static int dowild(const uchar *p, const uchar *text, const uchar*const *a)\n+static int dowild(const uchar *p, const uchar *text)\n {\n     uchar p_ch;\n \n-#ifdef WILD_TEST_ITERATIONS\n-    wildmatch_iteration_count++;\n-#endif\n-\n     for ( ; (p_ch = *p) != '\\0'; text++, p++) {\n \tint matched, special;\n \tuchar t_ch, prev_ch;\n-\twhile ((t_ch = *text) == '\\0') {\n-\t    if (*a == NULL) {\n-\t\tif (p_ch != '*')\n-\t\t    return ABORT_ALL;\n-\t\tbreak;\n-\t    }\n-\t    text = *a++;\n-\t}\n+\tif ((t_ch = *text) == '\\0' && p_ch != '*')\n+\t\treturn ABORT_ALL;\n \tif (force_lower_case && ISUPPER(t_ch))\n \t    t_ch = tolower(t_ch);\n \tswitch (p_ch) {\n@@ -107,21 +93,15 @@ static int dowild(const uchar *p, const uchar *text, const uchar*const *a)\n \t\t/* Trailing \"**\" matches everything.  Trailing \"*\" matches\n \t\t * only if there are no more slash characters. */\n \t\tif (!special) {\n-\t\t    do {\n \t\t\tif (strchr((char*)text, '/') != NULL)\n \t\t\t    return FALSE;\n-\t\t    } while ((text = *a++) != NULL);\n \t\t}\n \t\treturn TRUE;\n \t    }\n \t    while (1) {\n-\t\tif (t_ch == '\\0') {\n-\t\t    if ((text = *a++) == NULL)\n-\t\t\tbreak;\n-\t\t    t_ch = *text;\n-\t\t    continue;\n-\t\t}\n-\t\tif ((matched = dowild(p, text, a)) != FALSE) {\n+\t\tif (t_ch == '\\0')\n+\t\t    break;\n+\t\tif ((matched = dowild(p, text)) != FALSE) {\n \t\t    if (!special || matched != ABORT_TO_STARSTAR)\n \t\t\treturn matched;\n \t\t} else if (!special && t_ch == '/')\n@@ -225,144 +205,21 @@ static int dowild(const uchar *p, const uchar *text, const uchar*const *a)\n \t}\n     }\n \n-    do {\n-\tif (*text)\n-\t    return FALSE;\n-    } while ((text = *a++) != NULL);\n-\n-    return TRUE;\n-}\n-\n-/* Match literal string \"s\" against the a virtually-joined string consisting\n- * of \"text\" and any strings in array \"a\". */\n-static int doliteral(const uchar *s, const uchar *text, const uchar*const *a)\n-{\n-    for ( ; *s != '\\0'; text++, s++) {\n-\twhile (*text == '\\0') {\n-\t    if ((text = *a++) == NULL)\n-\t\treturn FALSE;\n-\t}\n-\tif (*text != *s)\n-\t    return FALSE;\n-    }\n-\n-    do {\n-\tif (*text)\n-\t    return FALSE;\n-    } while ((text = *a++) != NULL);\n-\n-    return TRUE;\n-}\n-\n-/* Return the last \"count\" path elements from the concatenated string.\n- * We return a string pointer to the start of the string, and update the\n- * array pointer-pointer to point to any remaining string elements. */\n-static const uchar *trailing_N_elements(const uchar*const **a_ptr, int count)\n-{\n-    const uchar*const *a = *a_ptr;\n-    const uchar*const *first_a = a;\n-\n-    while (*a)\n-\t    a++;\n-\n-    while (a != first_a) {\n-\tconst uchar *s = *--a;\n-\ts += strlen((char*)s);\n-\twhile (--s >= *a) {\n-\t    if (*s == '/' && !--count) {\n-\t\t*a_ptr = a+1;\n-\t\treturn s+1;\n-\t    }\n-\t}\n-    }\n-\n-    if (count == 1) {\n-\t*a_ptr = a+1;\n-\treturn *a;\n-    }\n-\n-    return NULL;\n+    return *text ? FALSE : TRUE;\n }\n \n /* Match the \"pattern\" against the \"text\" string. */\n int wildmatch(const char *pattern, const char *text)\n {\n-    static const uchar *nomore[1]; /* A NULL pointer. */\n-#ifdef WILD_TEST_ITERATIONS\n-    wildmatch_iteration_count = 0;\n-#endif\n-    return dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;\n+    return dowild((const uchar*)pattern, (const uchar*)text) == TRUE;\n }\n \n /* Match the \"pattern\" against the forced-to-lower-case \"text\" string. */\n int iwildmatch(const char *pattern, const char *text)\n {\n-    static const uchar *nomore[1]; /* A NULL pointer. */\n     int ret;\n-#ifdef WILD_TEST_ITERATIONS\n-    wildmatch_iteration_count = 0;\n-#endif\n     force_lower_case = 1;\n-    ret = dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;\n+    ret = dowild((const uchar*)pattern, (const uchar*)text) == TRUE;\n     force_lower_case = 0;\n     return ret;\n }\n-\n-/* Match pattern \"p\" against the a virtually-joined string consisting\n- * of all the pointers in array \"texts\" (which has a NULL pointer at the\n- * end).  The int \"where\" can be 0 (normal matching), > 0 (match only\n- * the trailing N slash-separated filename components of \"texts\"), or < 0\n- * (match the \"pattern\" at the start or after any slash in \"texts\"). */\n-int wildmatch_array(const char *pattern, const char*const *texts, int where)\n-{\n-    const uchar *p = (const uchar*)pattern;\n-    const uchar*const *a = (const uchar*const*)texts;\n-    const uchar *text;\n-    int matched;\n-\n-#ifdef WILD_TEST_ITERATIONS\n-    wildmatch_iteration_count = 0;\n-#endif\n-\n-    if (where > 0)\n-\ttext = trailing_N_elements(&a, where);\n-    else\n-\ttext = *a++;\n-    if (!text)\n-\treturn FALSE;\n-\n-    if ((matched = dowild(p, text, a)) != TRUE && where < 0\n-     && matched != ABORT_ALL) {\n-\twhile (1) {\n-\t    if (*text == '\\0') {\n-\t\tif ((text = (uchar*)*a++) == NULL)\n-\t\t    return FALSE;\n-\t\tcontinue;\n-\t    }\n-\t    if (*text++ == '/' && (matched = dowild(p, text, a)) != FALSE\n-\t     && matched != ABORT_TO_STARSTAR)\n-\t\tbreak;\n-\t}\n-    }\n-    return matched == TRUE;\n-}\n-\n-/* Match literal string \"s\" against the a virtually-joined string consisting\n- * of all the pointers in array \"texts\" (which has a NULL pointer at the\n- * end).  The int \"where\" can be 0 (normal matching), or > 0 (match\n- * only the trailing N slash-separated filename components of \"texts\"). */\n-int litmatch_array(const char *string, const char*const *texts, int where)\n-{\n-    const uchar *s = (const uchar*)string;\n-    const uchar*const *a = (const uchar* const*)texts;\n-    const uchar *text;\n-\n-    if (where > 0)\n-\ttext = trailing_N_elements(&a, where);\n-    else\n-\ttext = *a++;\n-    if (!text)\n-\treturn FALSE;\n-\n-    return doliteral(s, text, a) == TRUE;\n-}\ndiff --git a/wildmatch.h b/wildmatch.h\nindex e7f1a35..562faa3 100644\n--- a/wildmatch.h\n+++ b/wildmatch.h\n@@ -2,5 +2,3 @@\n \n int wildmatch(const char *pattern, const char *text);\n int iwildmatch(const char *pattern, const char *text);\n-int wildmatch_array(const char *pattern, const char*const *texts, int where);\n-int litmatch_array(const char *string, const char*const *texts, int where);\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200902","messageId":"1349865651-31889-6-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 05/12] Integrate wildmatch to git","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:44Z","receivedAt":"2012-10-10T10:40:44Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n .gitignore           |   1 +\n Makefile             |   3 +\n t/t3070-wildmatch.sh | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++\n t/t3070/wildtest.txt | 165 -----------------------------------------------\n test-wildmatch.c     |  14 ++++\n wildmatch.c          |   5 +-\n 6 files changed, 200 insertions(+), 166 deletions(-)\n create mode 100755 t/t3070-wildmatch.sh\n delete mode 100644 t/t3070/wildtest.txt\n create mode 100644 test-wildmatch.c\n\ndiff --git a/.gitignore b/.gitignore\nindex a188a82..37c3507 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -197,6 +197,7 @@\n /test-string-list\n /test-subprocess\n /test-svn-fe\n+/test-wildmatch\n /common-cmds.h\n *.tar.gz\n *.dsc\ndiff --git a/Makefile b/Makefile\nindex 8413606..9a97379 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -523,6 +523,7 @@ TEST_PROGRAMS_NEED_X += test-sigchain\n TEST_PROGRAMS_NEED_X += test-string-list\n TEST_PROGRAMS_NEED_X += test-subprocess\n TEST_PROGRAMS_NEED_X += test-svn-fe\n+TEST_PROGRAMS_NEED_X += test-wildmatch\n \n TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))\n \n@@ -695,6 +696,7 @@ LIB_H += userdiff.h\n LIB_H += utf8.h\n LIB_H += varint.h\n LIB_H += walker.h\n+LIB_H += wildmatch.h\n LIB_H += wt-status.h\n LIB_H += xdiff-interface.h\n LIB_H += xdiff/xdiff.h\n@@ -826,6 +828,7 @@ LIB_OBJS += utf8.o\n LIB_OBJS += varint.o\n LIB_OBJS += version.o\n LIB_OBJS += walker.o\n+LIB_OBJS += wildmatch.o\n LIB_OBJS += wrapper.o\n LIB_OBJS += write_or_die.o\n LIB_OBJS += ws.o\ndiff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh\nnew file mode 100755\nindex 0000000..bb92f8d\n--- /dev/null\n+++ b/t/t3070-wildmatch.sh\n@@ -0,0 +1,178 @@\n+#!/bin/sh\n+\n+test_description='wildmatch tests'\n+\n+. ./test-lib.sh\n+\n+match() {\n+    test_expect_success \"wildmatch $*\" \"\n+\tif [ $1 = 1 ]; then\n+\t    test-wildmatch wildmatch '$3' '$4'\n+\telse\n+\t    ! test-wildmatch wildmatch '$3' '$4'\n+\tfi &&\n+\tif [ $2 = 1 ]; then\n+\t    test-wildmatch fnmatch '$3' '$4'\n+\telse\n+\t    ! test-wildmatch fnmatch '$3' '$4'\n+\tfi\n+    \"\n+}\n+\n+# Basic wildmat features\n+match 1 1 foo foo\n+match 0 0 foo bar\n+match 1 1 '' \"\"\n+match 1 1 foo '???'\n+match 0 0 foo '??'\n+match 1 1 foo '*'\n+match 1 1 foo 'f*'\n+match 0 0 foo '*f'\n+match 1 1 foo '*foo*'\n+match 1 1 foobar '*ob*a*r*'\n+match 1 1 aaaaaaabababab '*ab'\n+match 1 1 'foo*' 'foo\\*'\n+match 0 0 foobar 'foo\\*bar'\n+match 1 1 'f\\oo' 'f\\\\oo'\n+match 1 1 ball '*[al]?'\n+match 0 0 ten '[ten]'\n+match 1 1 ten '**[!te]'\n+match 0 0 ten '**[!ten]'\n+match 1 1 ten 't[a-g]n'\n+match 0 0 ten 't[!a-g]n'\n+match 1 1 ton 't[!a-g]n'\n+match 1 1 ton 't[^a-g]n'\n+match 1 1 'a]b' 'a[]]b'\n+match 1 1 a-b 'a[]-]b'\n+match 1 1 'a]b' 'a[]-]b'\n+match 0 0 aab 'a[]-]b'\n+match 1 1 aab 'a[]a-]b'\n+match 1 1 ']' ']'\n+\n+# Extended slash-matching features\n+match 0 0 'foo/baz/bar' 'foo*bar'\n+match 1 0 'foo/baz/bar' 'foo**bar'\n+match 0 0 'foo/bar' 'foo?bar'\n+match 0 0 'foo/bar' 'foo[/]bar'\n+match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'\n+match 1 1 'foo-bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'\n+match 0 0 'foo' '**/foo'\n+match 1 1 '/foo' '**/foo'\n+match 1 0 'bar/baz/foo' '**/foo'\n+match 0 0 'bar/baz/foo' '*/foo'\n+match 0 0 'foo/bar/baz' '**/bar*'\n+match 1 0 'deep/foo/bar/baz' '**/bar/*'\n+match 0 0 'deep/foo/bar/baz/' '**/bar/*'\n+match 1 0 'deep/foo/bar/baz/' '**/bar/**'\n+match 0 0 'deep/foo/bar' '**/bar/*'\n+match 1 0 'deep/foo/bar/' '**/bar/**'\n+match 1 0 'foo/bar/baz' '**/bar**'\n+match 1 0 'foo/bar/baz/x' '*/bar/**'\n+match 0 0 'deep/foo/bar/baz/x' '*/bar/**'\n+match 1 0 'deep/foo/bar/baz/x' '**/bar/*/*'\n+\n+# Various additional tests\n+match 0 0 'acrt' 'a[c-c]st'\n+match 1 1 'acrt' 'a[c-c]rt'\n+match 0 0 ']' '[!]-]'\n+match 1 1 'a' '[!]-]'\n+match 0 0 '' '\\'\n+match 0 0 '\\' '\\'\n+match 0 0 '/\\' '*/\\'\n+match 1 1 '/\\' '*/\\\\'\n+match 1 1 'foo' 'foo'\n+match 1 1 '@foo' '@foo'\n+match 0 0 'foo' '@foo'\n+match 1 1 '[ab]' '\\[ab]'\n+match 1 1 '[ab]' '[[]ab]'\n+match 1 1 '[ab]' '[[:]ab]'\n+match 0 0 '[ab]' '[[::]ab]'\n+match 1 1 '[ab]' '[[:digit]ab]'\n+match 1 1 '[ab]' '[\\[:]ab]'\n+match 1 1 '?a?b' '\\??\\?b'\n+match 1 1 'abc' '\\a\\b\\c'\n+match 0 0 'foo' ''\n+match 1 0 'foo/bar/baz/to' '**/t[o]'\n+\n+# Character class tests\n+match 1 1 'a1B' '[[:alpha:]][[:digit:]][[:upper:]]'\n+match 0 0 'a' '[[:digit:][:upper:][:space:]]'\n+match 1 1 'A' '[[:digit:][:upper:][:space:]]'\n+match 1 0 '1' '[[:digit:][:upper:][:space:]]'\n+match 0 0 '1' '[[:digit:][:upper:][:spaci:]]'\n+match 1 1 ' ' '[[:digit:][:upper:][:space:]]'\n+match 0 0 '.' '[[:digit:][:upper:][:space:]]'\n+match 1 1 '.' '[[:digit:][:punct:][:space:]]'\n+match 1 1 '5' '[[:xdigit:]]'\n+match 1 1 'f' '[[:xdigit:]]'\n+match 1 1 'D' '[[:xdigit:]]'\n+match 1 0 '_' '[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'\n+match 1 0 '_' '[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'\n+match 1 1 '.' '[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]'\n+match 1 1 '5' '[a-c[:digit:]x-z]'\n+match 1 1 'b' '[a-c[:digit:]x-z]'\n+match 1 1 'y' '[a-c[:digit:]x-z]'\n+match 0 0 'q' '[a-c[:digit:]x-z]'\n+\n+# Additional tests, including some malformed wildmats\n+match 1 1 ']' '[\\\\-^]'\n+match 0 0 '[' '[\\\\-^]'\n+match 1 1 '-' '[\\-_]'\n+match 1 1 ']' '[\\]]'\n+match 0 0 '\\]' '[\\]]'\n+match 0 0 '\\' '[\\]]'\n+match 0 0 'ab' 'a[]b'\n+match 0 1 'a[]b' 'a[]b'\n+match 0 1 'ab[' 'ab['\n+match 0 0 'ab' '[!'\n+match 0 0 'ab' '[-'\n+match 1 1 '-' '[-]'\n+match 0 0 '-' '[a-'\n+match 0 0 '-' '[!a-'\n+match 1 1 '-' '[--A]'\n+match 1 1 '5' '[--A]'\n+match 1 1 ' ' '[ --]'\n+match 1 1 '$' '[ --]'\n+match 1 1 '-' '[ --]'\n+match 0 0 '0' '[ --]'\n+match 1 1 '-' '[---]'\n+match 1 1 '-' '[------]'\n+match 0 0 'j' '[a-e-n]'\n+match 1 1 '-' '[a-e-n]'\n+match 1 1 'a' '[!------]'\n+match 0 0 '[' '[]-a]'\n+match 1 1 '^' '[]-a]'\n+match 0 0 '^' '[!]-a]'\n+match 1 1 '[' '[!]-a]'\n+match 1 1 '^' '[a^bc]'\n+match 1 1 '-b]' '[a-]b]'\n+match 0 0 '\\' '[\\]'\n+match 1 1 '\\' '[\\\\]'\n+match 0 0 '\\' '[!\\\\]'\n+match 1 1 'G' '[A-\\\\]'\n+match 0 0 'aaabbb' 'b*a'\n+match 0 0 'aabcaa' '*ba*'\n+match 1 1 ',' '[,]'\n+match 1 1 ',' '[\\\\,]'\n+match 1 1 '\\' '[\\\\,]'\n+match 1 1 '-' '[,-.]'\n+match 0 0 '+' '[,-.]'\n+match 0 0 '-.]' '[,-.]'\n+match 1 1 '2' '[\\1-\\3]'\n+match 1 1 '3' '[\\1-\\3]'\n+match 0 0 '4' '[\\1-\\3]'\n+match 1 1 '\\' '[[-\\]]'\n+match 1 1 '[' '[[-\\]]'\n+match 1 1 ']' '[[-\\]]'\n+match 0 0 '-' '[[-\\]]'\n+\n+# Test recursion and the abort code (use \"wildtest -i\" to see iteration counts)\n+match 1 1 '-adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1' '-*-*-*-*-*-*-12-*-*-*-m-*-*-*'\n+match 0 0 '-adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1' '-*-*-*-*-*-*-12-*-*-*-m-*-*-*'\n+match 0 0 '-adobe-courier-bold-o-normal--12-120-75-75-/-70-iso8859-1' '-*-*-*-*-*-*-12-*-*-*-m-*-*-*'\n+match 1 1 '/adobe/courier/bold/o/normal//12/120/75/75/m/70/iso8859/1' '/*/*/*/*/*/*/12/*/*/*/m/*/*/*'\n+match 0 0 '/adobe/courier/bold/o/normal//12/120/75/75/X/70/iso8859/1' '/*/*/*/*/*/*/12/*/*/*/m/*/*/*'\n+match 1 0 'abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txt' '**/*a*b*g*n*t'\n+match 0 0 'abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txtz' '**/*a*b*g*n*t'\n+\n+test_done\ndiff --git a/t/t3070/wildtest.txt b/t/t3070/wildtest.txt\ndeleted file mode 100644\nindex 42c1678..0000000\n--- a/t/t3070/wildtest.txt\n+++ /dev/null\n@@ -1,165 +0,0 @@\n-# Input is in the following format (all items white-space separated):\n-#\n-# The first two items are 1 or 0 indicating if the wildmat call is expected to\n-# succeed and if fnmatch works the same way as wildmat, respectively.  After\n-# that is a text string for the match, and a pattern string.  Strings can be\n-# quoted (if desired) in either double or single quotes, as well as backticks.\n-#\n-# MATCH FNMATCH_SAME \"text to match\" 'pattern to use'\n-\n-# Basic wildmat features\n-1 1 foo\t\t\tfoo\n-0 1 foo\t\t\tbar\n-1 1 ''\t\t\t\"\"\n-1 1 foo\t\t\t???\n-0 1 foo\t\t\t??\n-1 1 foo\t\t\t*\n-1 1 foo\t\t\tf*\n-0 1 foo\t\t\t*f\n-1 1 foo\t\t\t*foo*\n-1 1 foobar\t\t*ob*a*r*\n-1 1 aaaaaaabababab\t*ab\n-1 1 foo*\t\tfoo\\*\n-0 1 foobar\t\tfoo\\*bar\n-1 1 f\\oo\t\tf\\\\oo\n-1 1 ball\t\t*[al]?\n-0 1 ten\t\t\t[ten]\n-1 1 ten\t\t\t**[!te]\n-0 1 ten\t\t\t**[!ten]\n-1 1 ten\t\t\tt[a-g]n\n-0 1 ten\t\t\tt[!a-g]n\n-1 1 ton\t\t\tt[!a-g]n\n-1 1 ton\t\t\tt[^a-g]n\n-1 1 a]b\t\t\ta[]]b\n-1 1 a-b\t\t\ta[]-]b\n-1 1 a]b\t\t\ta[]-]b\n-0 1 aab\t\t\ta[]-]b\n-1 1 aab\t\t\ta[]a-]b\n-1 1 ]\t\t\t]\n-\n-# Extended slash-matching features\n-0 1 foo/baz/bar\t\tfoo*bar\n-1 1 foo/baz/bar\t\tfoo**bar\n-0 1 foo/bar\t\tfoo?bar\n-0 1 foo/bar\t\tfoo[/]bar\n-0 1 foo/bar\t\tf[^eiu][^eiu][^eiu][^eiu][^eiu]r\n-1 1 foo-bar\t\tf[^eiu][^eiu][^eiu][^eiu][^eiu]r\n-0 1 foo\t\t\t**/foo\n-1 1 /foo\t\t**/foo\n-1 1 bar/baz/foo\t\t**/foo\n-0 1 bar/baz/foo\t\t*/foo\n-0 0 foo/bar/baz\t\t**/bar*\n-1 1 deep/foo/bar/baz\t**/bar/*\n-0 1 deep/foo/bar/baz/\t**/bar/*\n-1 1 deep/foo/bar/baz/\t**/bar/**\n-0 1 deep/foo/bar\t**/bar/*\n-1 1 deep/foo/bar/\t**/bar/**\n-1 1 foo/bar/baz\t\t**/bar**\n-1 1 foo/bar/baz/x\t*/bar/**\n-0 0 deep/foo/bar/baz/x\t*/bar/**\n-1 1 deep/foo/bar/baz/x\t**/bar/*/*\n-\n-# Various additional tests\n-0 1 acrt\t\ta[c-c]st\n-1 1 acrt\t\ta[c-c]rt\n-0 1 ]\t\t\t[!]-]\n-1 1 a\t\t\t[!]-]\n-0 1 ''\t\t\t\\\n-0 1 \\\t\t\t\\\n-0 1 /\\\t\t\t*/\\\n-1 1 /\\\t\t\t*/\\\\\n-1 1 foo\t\t\tfoo\n-1 1 @foo\t\t@foo\n-0 1 foo\t\t\t@foo\n-1 1 [ab]\t\t\\[ab]\n-1 1 [ab]\t\t[[]ab]\n-1 1 [ab]\t\t[[:]ab]\n-0 1 [ab]\t\t[[::]ab]\n-1 1 [ab]\t\t[[:digit]ab]\n-1 1 [ab]\t\t[\\[:]ab]\n-1 1 ?a?b\t\t\\??\\?b\n-1 1 abc\t\t\t\\a\\b\\c\n-0 1 foo\t\t\t''\n-1 1 foo/bar/baz/to\t**/t[o]\n-\n-# Character class tests\n-1 1 a1B\t\t[[:alpha:]][[:digit:]][[:upper:]]\n-0 1 a\t\t[[:digit:][:upper:][:space:]]\n-1 1 A\t\t[[:digit:][:upper:][:space:]]\n-1 1 1\t\t[[:digit:][:upper:][:space:]]\n-0 1 1\t\t[[:digit:][:upper:][:spaci:]]\n-1 1 ' '\t\t[[:digit:][:upper:][:space:]]\n-0 1 .\t\t[[:digit:][:upper:][:space:]]\n-1 1 .\t\t[[:digit:][:punct:][:space:]]\n-1 1 5\t\t[[:xdigit:]]\n-1 1 f\t\t[[:xdigit:]]\n-1 1 D\t\t[[:xdigit:]]\n-1 1 _\t\t[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n-#1 1 �\t\t[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n-1 1 \t\t[^[:alnum:][:alpha:][:blank:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n-1 1 .\t\t[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]\n-1 1 5\t\t[a-c[:digit:]x-z]\n-1 1 b\t\t[a-c[:digit:]x-z]\n-1 1 y\t\t[a-c[:digit:]x-z]\n-0 1 q\t\t[a-c[:digit:]x-z]\n-\n-# Additional tests, including some malformed wildmats\n-1 1 ]\t\t[\\\\-^]\n-0 1 [\t\t[\\\\-^]\n-1 1 -\t\t[\\-_]\n-1 1 ]\t\t[\\]]\n-0 1 \\]\t\t[\\]]\n-0 1 \\\t\t[\\]]\n-0 1 ab\t\ta[]b\n-0 1 a[]b\ta[]b\n-0 1 ab[\t\tab[\n-0 1 ab\t\t[!\n-0 1 ab\t\t[-\n-1 1 -\t\t[-]\n-0 1 -\t\t[a-\n-0 1 -\t\t[!a-\n-1 1 -\t\t[--A]\n-1 1 5\t\t[--A]\n-1 1 ' '\t\t'[ --]'\n-1 1 $\t\t'[ --]'\n-1 1 -\t\t'[ --]'\n-0 1 0\t\t'[ --]'\n-1 1 -\t\t[---]\n-1 1 -\t\t[------]\n-0 1 j\t\t[a-e-n]\n-1 1 -\t\t[a-e-n]\n-1 1 a\t\t[!------]\n-0 1 [\t\t[]-a]\n-1 1 ^\t\t[]-a]\n-0 1 ^\t\t[!]-a]\n-1 1 [\t\t[!]-a]\n-1 1 ^\t\t[a^bc]\n-1 1 -b]\t\t[a-]b]\n-0 1 \\\t\t[\\]\n-1 1 \\\t\t[\\\\]\n-0 1 \\\t\t[!\\\\]\n-1 1 G\t\t[A-\\\\]\n-0 1 aaabbb\tb*a\n-0 1 aabcaa\t*ba*\n-1 1 ,\t\t[,]\n-1 1 ,\t\t[\\\\,]\n-1 1 \\\t\t[\\\\,]\n-1 1 -\t\t[,-.]\n-0 1 +\t\t[,-.]\n-0 1 -.]\t\t[,-.]\n-1 1 2\t\t[\\1-\\3]\n-1 1 3\t\t[\\1-\\3]\n-0 1 4\t\t[\\1-\\3]\n-1 1 \\\t\t[[-\\]]\n-1 1 [\t\t[[-\\]]\n-1 1 ]\t\t[[-\\]]\n-0 1 -\t\t[[-\\]]\n-\n-# Test recursion and the abort code (use \"wildtest -i\" to see iteration counts)\n-1 1 -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1\t-*-*-*-*-*-*-12-*-*-*-m-*-*-*\n-0 1 -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1\t-*-*-*-*-*-*-12-*-*-*-m-*-*-*\n-0 1 -adobe-courier-bold-o-normal--12-120-75-75-/-70-iso8859-1\t-*-*-*-*-*-*-12-*-*-*-m-*-*-*\n-1 1 /adobe/courier/bold/o/normal//12/120/75/75/m/70/iso8859/1\t/*/*/*/*/*/*/12/*/*/*/m/*/*/*\n-0 1 /adobe/courier/bold/o/normal//12/120/75/75/X/70/iso8859/1\t/*/*/*/*/*/*/12/*/*/*/m/*/*/*\n-1 1 abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txt\t\t**/*a*b*g*n*t\n-0 1 abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txtz\t\t**/*a*b*g*n*t\ndiff --git a/test-wildmatch.c b/test-wildmatch.c\nnew file mode 100644\nindex 0000000..08962d5\n--- /dev/null\n+++ b/test-wildmatch.c\n@@ -0,0 +1,14 @@\n+#include \"cache.h\"\n+#include \"wildmatch.h\"\n+\n+int main(int argc, char **argv)\n+{\n+\tif (!strcmp(argv[1], \"wildmatch\"))\n+\t\treturn wildmatch(argv[3], argv[2]) ? 0 : 1;\n+\telse if (!strcmp(argv[1], \"iwildmatch\"))\n+\t\treturn iwildmatch(argv[3], argv[2]) ? 0 : 1;\n+\telse if (!strcmp(argv[1], \"fnmatch\"))\n+\t\treturn fnmatch(argv[3], argv[2], FNM_PATHNAME);\n+\telse\n+\t\treturn 1;\n+}\ndiff --git a/wildmatch.c b/wildmatch.c\nindex 71dba76..6092bde 100644\n--- a/wildmatch.c\n+++ b/wildmatch.c\n@@ -9,7 +9,10 @@\n **  work differently than '*', and to fix the character-class code.\n */\n \n-#include \"rsync.h\"\n+#include \"cache.h\"\n+#include \"wildmatch.h\"\n+\n+typedef unsigned char uchar;\n \n /* What character marks an inverted character class? */\n #define NEGATE_CLASS\t'!'\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200903","messageId":"1349865651-31889-7-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 06/12] wildmatch: make wildmatch's return value compatible with fnmatch","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:45Z","receivedAt":"2012-10-10T10:40:45Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"wildmatch returns non-zero if matched, zero otherwise. This patch\nmakes it return zero if matches, non-zero otherwise, like fnmatch().\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n test-wildmatch.c |  4 ++--\n wildmatch.c      | 21 ++++++++++++---------\n 2 files changed, 14 insertions(+), 11 deletions(-)\n\ndiff --git a/test-wildmatch.c b/test-wildmatch.c\nindex 08962d5..596029c 100644\n--- a/test-wildmatch.c\n+++ b/test-wildmatch.c\n@@ -4,9 +4,9 @@\n int main(int argc, char **argv)\n {\n \tif (!strcmp(argv[1], \"wildmatch\"))\n-\t\treturn wildmatch(argv[3], argv[2]) ? 0 : 1;\n+\t\treturn wildmatch(argv[3], argv[2]);\n \telse if (!strcmp(argv[1], \"iwildmatch\"))\n-\t\treturn iwildmatch(argv[3], argv[2]) ? 0 : 1;\n+\t\treturn iwildmatch(argv[3], argv[2]);\n \telse if (!strcmp(argv[1], \"fnmatch\"))\n \t\treturn fnmatch(argv[3], argv[2], FNM_PATHNAME);\n \telse\ndiff --git a/wildmatch.c b/wildmatch.c\nindex 6092bde..7c180e3 100644\n--- a/wildmatch.c\n+++ b/wildmatch.c\n@@ -20,6 +20,9 @@ typedef unsigned char uchar;\n \n #define FALSE 0\n #define TRUE 1\n+\n+#define NOMATCH 1\n+#define MATCH 0\n #define ABORT_ALL -1\n #define ABORT_TO_STARSTAR -2\n \n@@ -79,12 +82,12 @@ static int dowild(const uchar *p, const uchar *text)\n \t    /* FALLTHROUGH */\n \t  default:\n \t    if (t_ch != p_ch)\n-\t\treturn FALSE;\n+\t\treturn NOMATCH;\n \t    continue;\n \t  case '?':\n \t    /* Match anything but '/'. */\n \t    if (t_ch == '/')\n-\t\treturn FALSE;\n+\t\treturn NOMATCH;\n \t    continue;\n \t  case '*':\n \t    if (*++p == '*') {\n@@ -97,14 +100,14 @@ static int dowild(const uchar *p, const uchar *text)\n \t\t * only if there are no more slash characters. */\n \t\tif (!special) {\n \t\t\tif (strchr((char*)text, '/') != NULL)\n-\t\t\t    return FALSE;\n+\t\t\t    return NOMATCH;\n \t\t}\n-\t\treturn TRUE;\n+\t\treturn MATCH;\n \t    }\n \t    while (1) {\n \t\tif (t_ch == '\\0')\n \t\t    break;\n-\t\tif ((matched = dowild(p, text)) != FALSE) {\n+\t\tif ((matched = dowild(p, text)) != NOMATCH) {\n \t\t    if (!special || matched != ABORT_TO_STARSTAR)\n \t\t\treturn matched;\n \t\t} else if (!special && t_ch == '/')\n@@ -203,18 +206,18 @@ static int dowild(const uchar *p, const uchar *text)\n \t\t    matched = TRUE;\n \t    } while (prev_ch = p_ch, (p_ch = *++p) != ']');\n \t    if (matched == special || t_ch == '/')\n-\t\treturn FALSE;\n+\t\treturn NOMATCH;\n \t    continue;\n \t}\n     }\n \n-    return *text ? FALSE : TRUE;\n+    return *text ? NOMATCH : MATCH;\n }\n \n /* Match the \"pattern\" against the \"text\" string. */\n int wildmatch(const char *pattern, const char *text)\n {\n-    return dowild((const uchar*)pattern, (const uchar*)text) == TRUE;\n+    return dowild((const uchar*)pattern, (const uchar*)text);\n }\n \n /* Match the \"pattern\" against the forced-to-lower-case \"text\" string. */\n@@ -222,7 +225,7 @@ int iwildmatch(const char *pattern, const char *text)\n {\n     int ret;\n     force_lower_case = 1;\n-    ret = dowild((const uchar*)pattern, (const uchar*)text) == TRUE;\n+    ret = dowild((const uchar*)pattern, (const uchar*)text);\n     force_lower_case = 0;\n     return ret;\n }\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200904","messageId":"1349865651-31889-8-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 07/12] wildmatch: remove static variable force_lower_case","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:46Z","receivedAt":"2012-10-10T10:40:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"One place less to worry about thread safety. Also combine wildmatch\nand iwildmatch into one.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n test-wildmatch.c |  4 ++--\n wildmatch.c      | 21 +++++----------------\n wildmatch.h      |  3 +--\n 3 files changed, 8 insertions(+), 20 deletions(-)\n\ndiff --git a/test-wildmatch.c b/test-wildmatch.c\nindex 596029c..d716852 100644\n--- a/test-wildmatch.c\n+++ b/test-wildmatch.c\n@@ -4,9 +4,9 @@\n int main(int argc, char **argv)\n {\n \tif (!strcmp(argv[1], \"wildmatch\"))\n-\t\treturn wildmatch(argv[3], argv[2]);\n+\t\treturn wildmatch(argv[3], argv[2], 0);\n \telse if (!strcmp(argv[1], \"iwildmatch\"))\n-\t\treturn iwildmatch(argv[3], argv[2]);\n+\t\treturn wildmatch(argv[3], argv[2], FNM_CASEFOLD);\n \telse if (!strcmp(argv[1], \"fnmatch\"))\n \t\treturn fnmatch(argv[3], argv[2], FNM_PATHNAME);\n \telse\ndiff --git a/wildmatch.c b/wildmatch.c\nindex 7c180e3..d18d721 100644\n--- a/wildmatch.c\n+++ b/wildmatch.c\n@@ -59,11 +59,9 @@ typedef unsigned char uchar;\n #define ISUPPER(c) (ISASCII(c) && isupper(c))\n #define ISXDIGIT(c) (ISASCII(c) && isxdigit(c))\n \n-static int force_lower_case = 0;\n-\n /* Match pattern \"p\" against the a virtually-joined string consisting\n  * of \"text\" and any strings in array \"a\". */\n-static int dowild(const uchar *p, const uchar *text)\n+static int dowild(const uchar *p, const uchar *text, int force_lower_case)\n {\n     uchar p_ch;\n \n@@ -107,7 +105,7 @@ static int dowild(const uchar *p, const uchar *text)\n \t    while (1) {\n \t\tif (t_ch == '\\0')\n \t\t    break;\n-\t\tif ((matched = dowild(p, text)) != NOMATCH) {\n+\t\tif ((matched = dowild(p, text, force_lower_case)) != NOMATCH) {\n \t\t    if (!special || matched != ABORT_TO_STARSTAR)\n \t\t\treturn matched;\n \t\t} else if (!special && t_ch == '/')\n@@ -215,17 +213,8 @@ static int dowild(const uchar *p, const uchar *text)\n }\n \n /* Match the \"pattern\" against the \"text\" string. */\n-int wildmatch(const char *pattern, const char *text)\n-{\n-    return dowild((const uchar*)pattern, (const uchar*)text);\n-}\n-\n-/* Match the \"pattern\" against the forced-to-lower-case \"text\" string. */\n-int iwildmatch(const char *pattern, const char *text)\n+int wildmatch(const char *pattern, const char *text, int flags)\n {\n-    int ret;\n-    force_lower_case = 1;\n-    ret = dowild((const uchar*)pattern, (const uchar*)text);\n-    force_lower_case = 0;\n-    return ret;\n+    return dowild((const uchar*)pattern, (const uchar*)text,\n+\t\t  flags & FNM_CASEFOLD ? 1 : 0);\n }\ndiff --git a/wildmatch.h b/wildmatch.h\nindex 562faa3..e974f9a 100644\n--- a/wildmatch.h\n+++ b/wildmatch.h\n@@ -1,4 +1,3 @@\n /* wildmatch.h */\n \n-int wildmatch(const char *pattern, const char *text);\n-int iwildmatch(const char *pattern, const char *text);\n+int wildmatch(const char *pattern, const char *text, int flags);\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200905","messageId":"1349865651-31889-9-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 08/12] wildmatch: fix case-insensitive matching","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:47Z","receivedAt":"2012-10-10T10:40:47Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"dowild() does case insensitive matching by lower-casing the text. That\nmeans lower case letters in patterns imply case-insensitive matching,\nbut upper case means exact matching.\n\nWe do not want that subtlety. Lower case pattern too so iwildmatch()\nalways does what we expect it to do.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n wildmatch.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/wildmatch.c b/wildmatch.c\nindex d18d721..b700631 100644\n--- a/wildmatch.c\n+++ b/wildmatch.c\n@@ -72,6 +72,8 @@ static int dowild(const uchar *p, const uchar *text, int force_lower_case)\n \t\treturn ABORT_ALL;\n \tif (force_lower_case && ISUPPER(t_ch))\n \t    t_ch = tolower(t_ch);\n+\tif (force_lower_case && ISUPPER(p_ch))\n+\t    p_ch = tolower(p_ch);\n \tswitch (p_ch) {\n \t  case '\\\\':\n \t    /* Literal match with following character.  Note that the test\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200906","messageId":"1349865651-31889-10-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 09/12] wildmatch: adjust \"**\" behavior","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:48Z","receivedAt":"2012-10-10T10:40:48Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Standard wildmatch() sees consecutive asterisks as \"*\" that can also\nmatch slashes. But that may be hard to explain to users as\n\"abc/**/def\" can match \"abcdef\", \"abcxyzdef\", \"abc/def\", \"abc/x/def\",\n\"abc/x/y/def\"...\n\nThis patch changes wildmatch so that users can do\n\n- \"**/def\" -> all paths ending with file/directory 'def'\n- \"abc/**\" - equivalent to \"/abc/\"\n- \"abc/**/def\" -> \"abc/x/def\", \"abc/x/y/def\"...\n- otherwise consider the pattern malformed if \"**\" is found\n\nBasically the magic of \"**\" only remains if it's wrapped around by\nslashes.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t3070-wildmatch.sh |  5 +++--\n wildmatch.c          | 13 +++++++------\n wildmatch.h          |  6 ++++++\n 3 files changed, 16 insertions(+), 8 deletions(-)\n\ndiff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh\nindex bb92f8d..f6c64be 100755\n--- a/t/t3070-wildmatch.sh\n+++ b/t/t3070-wildmatch.sh\n@@ -36,7 +36,7 @@ match 0 0 foobar 'foo\\*bar'\n match 1 1 'f\\oo' 'f\\\\oo'\n match 1 1 ball '*[al]?'\n match 0 0 ten '[ten]'\n-match 1 1 ten '**[!te]'\n+match 0 1 ten '**[!te]'\n match 0 0 ten '**[!ten]'\n match 1 1 ten 't[a-g]n'\n match 0 0 ten 't[!a-g]n'\n@@ -51,7 +51,8 @@ match 1 1 ']' ']'\n \n # Extended slash-matching features\n match 0 0 'foo/baz/bar' 'foo*bar'\n-match 1 0 'foo/baz/bar' 'foo**bar'\n+match 0 0 'foo/baz/bar' 'foo**bar'\n+match 0 1 'foobazbar' 'foo**bar'\n match 0 0 'foo/bar' 'foo?bar'\n match 0 0 'foo/bar' 'foo[/]bar'\n match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'\ndiff --git a/wildmatch.c b/wildmatch.c\nindex b700631..e09a459 100644\n--- a/wildmatch.c\n+++ b/wildmatch.c\n@@ -21,11 +21,6 @@ typedef unsigned char uchar;\n #define FALSE 0\n #define TRUE 1\n \n-#define NOMATCH 1\n-#define MATCH 0\n-#define ABORT_ALL -1\n-#define ABORT_TO_STARSTAR -2\n-\n #define CC_EQ(class, len, litmatch) ((len) == sizeof (litmatch)-1 \\\n \t\t\t\t    && *(class) == *(litmatch) \\\n \t\t\t\t    && strncmp((char*)class, litmatch, len) == 0)\n@@ -91,8 +86,14 @@ static int dowild(const uchar *p, const uchar *text, int force_lower_case)\n \t    continue;\n \t  case '*':\n \t    if (*++p == '*') {\n+\t\tconst uchar *prev_p = p - 2;\n \t\twhile (*++p == '*') {}\n-\t\tspecial = TRUE;\n+\t\tif ((prev_p == text || *prev_p == '/') ||\n+\t\t    (*p == '\\0' || *p == '/' ||\n+\t\t     (p[0] == '\\\\' && p[1] == '/'))) {\n+\t\t    special = TRUE;\n+\t\t} else\n+\t\t    return ABORT_MALFORMED;\n \t    } else\n \t\tspecial = FALSE;\n \t    if (*p == '\\0') {\ndiff --git a/wildmatch.h b/wildmatch.h\nindex e974f9a..984a38c 100644\n--- a/wildmatch.h\n+++ b/wildmatch.h\n@@ -1,3 +1,9 @@\n /* wildmatch.h */\n \n+#define ABORT_MALFORMED 2\n+#define NOMATCH 1\n+#define MATCH 0\n+#define ABORT_ALL -1\n+#define ABORT_TO_STARSTAR -2\n+\n int wildmatch(const char *pattern, const char *text, int flags);\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200907","messageId":"1349865651-31889-11-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 10/12] wildmatch: make /**/ match zero or more directories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:49Z","receivedAt":"2012-10-10T10:40:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\"foo/**/bar\" matches \"foo/x/bar\", \"foo/x/y/bar\"... but not\n\"foo/bar\". We make a special case, when foo/**/ is detected (and\n\"foo/\" part is already matched), try matching \"bar\" with the rest of\nthe string.\n\n\"Match one or more directories\" semantics can be easily achieved using\n\"foo/*/**/bar\".\n\nThis also makes \"**/foo\" match \"foo\" in addition to \"x/foo\",\n\"x/y/foo\"..\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t3070-wildmatch.sh |  8 +++++++-\n wildmatch.c          | 17 +++++++++++++++++\n 2 files changed, 24 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh\nindex f6c64be..f21da6c 100755\n--- a/t/t3070-wildmatch.sh\n+++ b/t/t3070-wildmatch.sh\n@@ -53,11 +53,17 @@ match 1 1 ']' ']'\n match 0 0 'foo/baz/bar' 'foo*bar'\n match 0 0 'foo/baz/bar' 'foo**bar'\n match 0 1 'foobazbar' 'foo**bar'\n+match 1 1 'foo/baz/bar' 'foo/**/bar'\n+match 1 0 'foo/baz/bar' 'foo/**/**/bar'\n+match 1 0 'foo/b/a/z/bar' 'foo/**/bar'\n+match 1 0 'foo/b/a/z/bar' 'foo/**/**/bar'\n+match 1 0 'foo/bar' 'foo/**/bar'\n+match 1 0 'foo/bar' 'foo/**/**/bar'\n match 0 0 'foo/bar' 'foo?bar'\n match 0 0 'foo/bar' 'foo[/]bar'\n match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'\n match 1 1 'foo-bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'\n-match 0 0 'foo' '**/foo'\n+match 1 0 'foo' '**/foo'\n match 1 1 '/foo' '**/foo'\n match 1 0 'bar/baz/foo' '**/foo'\n match 0 0 'bar/baz/foo' '*/foo'\ndiff --git a/wildmatch.c b/wildmatch.c\nindex e09a459..f060bb0 100644\n--- a/wildmatch.c\n+++ b/wildmatch.c\n@@ -91,6 +91,23 @@ static int dowild(const uchar *p, const uchar *text, int force_lower_case)\n \t\tif ((prev_p == text || *prev_p == '/') ||\n \t\t    (*p == '\\0' || *p == '/' ||\n \t\t     (p[0] == '\\\\' && p[1] == '/'))) {\n+\t\t\t/*\n+\t\t\t * Assuming we already match 'foo/' and are at\n+\t\t\t * <star star slash>, just assume it matches\n+\t\t\t * nothing and go ahead match the rest of the\n+\t\t\t * pattern with the remaining string. This\n+\t\t\t * helps make foo/<*><*>/bar (<> because\n+\t\t\t * otherwise it breaks C comment syntax) match\n+\t\t\t * both foo/bar and foo/a/bar.\n+\t\t\t *\n+\t\t\t * Crazy patterns like /<*><*>/<*><*>/ are\n+\t\t\t * treated like /<*><*>/. But undefined\n+\t\t\t * behavior is even appropriate for people\n+\t\t\t * writing such a pattern.\n+\t\t\t */\n+\t\t\tif (p[0] == '/' &&\n+\t\t\t    dowild(p + 1, text, force_lower_case) == MATCH)\n+\t\t\t\treturn MATCH;\n \t\t    special = TRUE;\n \t\t} else\n \t\t    return ABORT_MALFORMED;\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200908","messageId":"1349865651-31889-12-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 11/12] Support \"**\" wildcard in .gitignore and .gitattributes","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:50Z","receivedAt":"2012-10-10T10:40:50Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Documentation/gitattributes.txt    |  6 ++++++\n Documentation/gitignore.txt        | 19 +++++++++++++++++++\n attr.c                             |  4 +++-\n dir.c                              |  4 +++-\n t/t0003-attributes.sh              | 38 ++++++++++++++++++++++++++++++++++++++\n t/t3001-ls-files-others-exclude.sh | 19 +++++++++++++++++++\n 6 files changed, 88 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex 99ed04d..93c542b 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -57,6 +57,12 @@ overrides an earlier line.  This overriding is done per\n attribute.  The rules how the pattern matches paths are the\n same as in `.gitignore` files; see linkgit:gitignore[5].\n \n+Note that if a .gitignore rule matches a directory, the directory\n+is ignored, which may be seen as \"ignore\" attribute propagated to\n+to all files and directories inside. If a .gitattributes rule\n+matches a directory, it manipulates attributes on that directory\n+only, not files and directories inside.\n+\n When deciding what attributes are assigned to a path, git\n consults `$GIT_DIR/info/attributes` file (which has the highest\n precedence), `.gitattributes` file in the same directory as the\ndiff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\nindex 96639e0..b564b4b 100644\n--- a/Documentation/gitignore.txt\n+++ b/Documentation/gitignore.txt\n@@ -104,6 +104,25 @@ PATTERN FORMAT\n    For example, \"/{asterisk}.c\" matches \"cat-file.c\" but not\n    \"mozilla-sha1/sha1.c\".\n \n+Two consecutive asterisks (\"`**`\") in patterns matched against\n+full pathname may have special meaning:\n+\n+ - A leading \"`**`\" followed by a slash means match in all\n+   directories. For example, \"`**/foo`\" matches file or directory\n+   \"`foo`\" anywhere, the same as pattern \"`foo`\". \"**/foo/bar\"\n+   matches file or directory \"`bar`\" anywhere that is directly\n+   under directory \"`foo`\".\n+\n+ - A trailing \"/**\" matches everything inside. For example,\n+   \"abc/**\" matches all files inside directory \"abc\", relative\n+   to the location of the `.gitignore` file, with infinite depth.\n+\n+ - A slash followed by two consecutive asterisks then a slash\n+   matches zero or more directories. For example, \"`a/**/b`\"\n+   matches \"`a/b`\", \"`a/x/b`\", \"`a/x/y/b`\" and so on.\n+\n+ - Other consecutive asterisks are considered invalid.\n+\n NOTES\n -----\n \ndiff --git a/attr.c b/attr.c\nindex 887a9ae..8010429 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -12,6 +12,7 @@\n #include \"exec_cmd.h\"\n #include \"attr.h\"\n #include \"dir.h\"\n+#include \"wildmatch.h\"\n \n const char git_attr__true[] = \"(builtin)true\";\n const char git_attr__false[] = \"\\0(builtin)false\";\n@@ -666,7 +667,8 @@ static int path_matches(const char *pathname, int pathlen,\n \t\treturn 0;\n \tif (baselen != 0)\n \t\tbaselen++;\n-\treturn fnmatch_icase(pattern, pathname + baselen, FNM_PATHNAME) == 0;\n+\treturn wildmatch(pattern, pathname + baselen,\n+\t\t\t ignore_case ? FNM_CASEFOLD : 0) == 0;\n }\n \n static int macroexpand_one(int attr_nr, int rem);\ndiff --git a/dir.c b/dir.c\nindex 4868339..442db1c 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -8,6 +8,7 @@\n #include \"cache.h\"\n #include \"dir.h\"\n #include \"refs.h\"\n+#include \"wildmatch.h\"\n \n struct path_simplify {\n \tint len;\n@@ -575,7 +576,8 @@ int excluded_from_list(const char *pathname,\n \t\t\tnamelen -= prefix;\n \t\t}\n \n-\t\tif (!namelen || !fnmatch_icase(exclude, name, FNM_PATHNAME))\n+\t\tif (!namelen ||\n+\t\t    wildmatch(exclude, name, ignore_case ? FNM_CASEFOLD : 0) == 0)\n \t\t\treturn to_exclude;\n \t}\n \treturn -1; /* undecided */\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex febc45c..67a5694 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -232,4 +232,42 @@ test_expect_success 'bare repository: test info/attributes' '\n \tattr_check subdir/a/i unspecified\n '\n \n+test_expect_success '\"**\" test' '\n+\tcd .. &&\n+\techo \"**/f foo=bar\" >.gitattributes &&\n+\tcat <<\\EOF >expect &&\n+f: foo: bar\n+a/f: foo: bar\n+a/b/f: foo: bar\n+a/b/c/f: foo: bar\n+EOF\n+\tgit check-attr foo -- \"f\" >actual 2>err &&\n+\tgit check-attr foo -- \"a/f\" >>actual 2>>err &&\n+\tgit check-attr foo -- \"a/b/f\" >>actual 2>>err &&\n+\tgit check-attr foo -- \"a/b/c/f\" >>actual 2>>err &&\n+\ttest_cmp expect actual &&\n+\ttest_line_count = 0 err\n+'\n+\n+test_expect_success '\"**\" with no slashes test' '\n+\techo \"a**f foo=bar\" >.gitattributes &&\n+\tgit check-attr foo -- \"f\" >actual &&\n+\tcat <<\\EOF >expect &&\n+f: foo: unspecified\n+af: foo: bar\n+axf: foo: bar\n+a/f: foo: unspecified\n+a/b/f: foo: unspecified\n+a/b/c/f: foo: unspecified\n+EOF\n+\tgit check-attr foo -- \"f\" >actual 2>err &&\n+\tgit check-attr foo -- \"af\" >>actual 2>err &&\n+\tgit check-attr foo -- \"axf\" >>actual 2>err &&\n+\tgit check-attr foo -- \"a/f\" >>actual 2>>err &&\n+\tgit check-attr foo -- \"a/b/f\" >>actual 2>>err &&\n+\tgit check-attr foo -- \"a/b/c/f\" >>actual 2>>err &&\n+\ttest_cmp expect actual &&\n+\ttest_line_count = 0 err\n+'\n+\n test_done\ndiff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh\nindex c8fe978..278315d 100755\n--- a/t/t3001-ls-files-others-exclude.sh\n+++ b/t/t3001-ls-files-others-exclude.sh\n@@ -214,4 +214,23 @@ test_expect_success 'subdirectory ignore (l1)' '\n \ttest_cmp expect actual\n '\n \n+\n+test_expect_success 'ls-files with \"**\" patterns' '\n+\tcat <<\\EOF >expect &&\n+a.1\n+one/a.1\n+one/two/a.1\n+three/a.1\n+EOF\n+\tgit ls-files -o -i --exclude \"**/a.1\" >actual\n+\ttest_cmp expect actual\n+'\n+\n+\n+test_expect_success 'ls-files with \"**\" patterns and no slashes' '\n+\t: >expect &&\n+\tgit ls-files -o -i --exclude \"one**a.1\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200909","messageId":"1349865651-31889-13-git-send-email-pclouds@gmail.com","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 12/12] t3070: disable two fnmatch tests that have different results on different libc","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-10T10:40:51Z","receivedAt":"2012-10-10T10:40:51Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"fnmatch on glibc-2.12.1 returns no match. glibc-2.15 returns ok.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t3070-wildmatch.sh | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh\nindex f21da6c..38042eb 100755\n--- a/t/t3070-wildmatch.sh\n+++ b/t/t3070-wildmatch.sh\n@@ -13,6 +13,8 @@ match() {\n \tfi &&\n \tif [ $2 = 1 ]; then\n \t    test-wildmatch fnmatch '$3' '$4'\n+\telif [ $2 = x ]; then\n+\t    true\n \telse\n \t    ! test-wildmatch fnmatch '$3' '$4'\n \tfi\n@@ -129,8 +131,8 @@ match 1 1 ']' '[\\]]'\n match 0 0 '\\]' '[\\]]'\n match 0 0 '\\' '[\\]]'\n match 0 0 'ab' 'a[]b'\n-match 0 1 'a[]b' 'a[]b'\n-match 0 1 'ab[' 'ab['\n+match 0 x 'a[]b' 'a[]b'\n+match 0 x 'ab[' 'ab['\n match 0 0 'ab' '[!'\n match 0 0 'ab' '[-'\n match 1 1 '-' '[-]'\n-- \n1.7.12.1.406.g6ab07c4\n"},{"id":"200928","messageId":"50759675.1070108@alum.mit.edu","threadId":"31780","inReplyTo":"1349865651-31889-5-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v4 04/12] wildmatch: remove unnecessary functions","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2012-10-10T15:38:29Z","receivedAt":"2012-10-10T15:38:29Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 10/10/2012 12:40 PM, Nguyễn Thái Ngọc Duy wrote:\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  wildmatch.c | 161 ++++--------------------------------------------------------\n>  wildmatch.h |   2 -\n>  2 files changed, 9 insertions(+), 154 deletions(-)\n> \n> diff --git a/wildmatch.c b/wildmatch.c\n> index f3a1731..71dba76 100644\n> --- a/wildmatch.c\n> +++ b/wildmatch.c\n> @@ -53,33 +53,19 @@\n>  #define ISUPPER(c) (ISASCII(c) && isupper(c))\n>  #define ISXDIGIT(c) (ISASCII(c) && isxdigit(c))\n>  \n> -#ifdef WILD_TEST_ITERATIONS\n> -int wildmatch_iteration_count;\n> -#endif\n> -\n>  static int force_lower_case = 0;\n>  \n>  /* Match pattern \"p\" against the a virtually-joined string consisting\n>   * of \"text\" and any strings in array \"a\". */\n> -static int dowild(const uchar *p, const uchar *text, const uchar*const *a)\n> +static int dowild(const uchar *p, const uchar *text)\n\nThe comment still refers to array \"a\".\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"200964","messageId":"7vd30panxo.fsf@alter.siamese.dyndns.org","threadId":"31780","inReplyTo":"1349865651-31889-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-10T23:48:35Z","receivedAt":"2012-10-10T23:48:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> Really small updates. I did not want to resend it this soon but this\n> may fix the compile errors for Junio.\n\nThanks; queued and pushed out on 'pu'.  Comments later.\n"},{"id":"200973","messageId":"7v1uh5aar7.fsf@alter.siamese.dyndns.org","threadId":"31780","inReplyTo":"7vd30panxo.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-11T04:33:16Z","receivedAt":"2012-10-11T04:33:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>\n>> Really small updates. I did not want to resend it this soon but this\n>> may fix the compile errors for Junio.\n\nt3070 seems to break TAP,\n\n    *** prove ***\n    t3070-wildmatch.sh .. Failed 1/151 subtests \n\n    Test Summary Report\n    -------------------\n    t3070-wildmatch.sh (Wstat: 0 Tests: 150 Failed: 0)\n      Parse errors: Tests out of sequence.  Found (76) but expected (75)\n                    Tests out of sequence.  Found (77) but expected (76)\n                    Tests out of sequence.  Found (78) but expected (77)\n                    Tests out of sequence.  Found (79) but expected (78)\n                    Tests out of sequence.  Found (80) but expected (79)\n    Displayed the first 5 of 77 TAP syntax errors.\n\nThis probably is due to this part of the output:\n\n    ok 72 - wildmatch 1 1 [ab] [\\[:]ab]\n    ok 73 - wildmatch 1 1 ?a?b \\??\\?b\n    ok 74 - wildmatch 1 1 abc ^G^Hok 75 - wildmatch 0 0 foo \n    ok 76 - wildmatch 1 0 foo/bar/baz/to **/t[o]\n    ok 77 - wildmatch 1 1 a1B [[:alpha:]][[:digit:]][[:upper:]]\n"},{"id":"200984","messageId":"CACsJy8B2JJmUbjAauMwbg95fCvPdUYqy4CKZp3ac44XHoh1NLQ@mail.gmail.com","threadId":"31780","inReplyTo":"7v1uh5aar7.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-11T11:56:55Z","receivedAt":"2012-10-11T11:56:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Oct 11, 2012 at 11:33 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>>\n>>> Really small updates. I did not want to resend it this soon but this\n>>> may fix the compile errors for Junio.\n>\n> t3070 seems to break TAP,\n>\n>     *** prove ***\n>     t3070-wildmatch.sh .. Failed 1/151 subtests\n>\n>     Test Summary Report\n>     -------------------\n>     t3070-wildmatch.sh (Wstat: 0 Tests: 150 Failed: 0)\n>       Parse errors: Tests out of sequence.  Found (76) but expected (75)\n>                     Tests out of sequence.  Found (77) but expected (76)\n>                     Tests out of sequence.  Found (78) but expected (77)\n>                     Tests out of sequence.  Found (79) but expected (78)\n>                     Tests out of sequence.  Found (80) but expected (79)\n>     Displayed the first 5 of 77 TAP syntax errors.\n>\n> This probably is due to this part of the output:\n>\n>     ok 72 - wildmatch 1 1 [ab] [\\[:]ab]\n>     ok 73 - wildmatch 1 1 ?a?b \\??\\?b\n>     ok 74 - wildmatch 1 1 abc ^G^Hok 75 - wildmatch 0 0 foo\n>     ok 76 - wildmatch 1 0 foo/bar/baz/to **/t[o]\n>     ok 77 - wildmatch 1 1 a1B [[:alpha:]][[:digit:]][[:upper:]]\n>\n\nIt seems to prove fine here with perl 5.12.3, Test-Harness-3.230,\nbash-4.0_p38. What version do you use?\n-- \nDuy\n"},{"id":"200992","messageId":"7vlifd7zz3.fsf@alter.siamese.dyndns.org","threadId":"31780","inReplyTo":"CACsJy8B2JJmUbjAauMwbg95fCvPdUYqy4CKZp3ac44XHoh1NLQ@mail.gmail.com","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-11T16:09:04Z","receivedAt":"2012-10-11T16:09:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> On Thu, Oct 11, 2012 at 11:33 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Junio C Hamano <gitster@pobox.com> writes:\n>>\n>>> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>>>\n>>>> Really small updates. I did not want to resend it this soon but this\n>>>> may fix the compile errors for Junio.\n>>\n>> t3070 seems to break TAP,\n>>\n>>     *** prove ***\n>>     t3070-wildmatch.sh .. Failed 1/151 subtests\n>>\n>>     Test Summary Report\n>>     -------------------\n>>     t3070-wildmatch.sh (Wstat: 0 Tests: 150 Failed: 0)\n>>       Parse errors: Tests out of sequence.  Found (76) but expected (75)\n>>                     Tests out of sequence.  Found (77) but expected (76)\n>>                     Tests out of sequence.  Found (78) but expected (77)\n>>                     Tests out of sequence.  Found (79) but expected (78)\n>>                     Tests out of sequence.  Found (80) but expected (79)\n>>     Displayed the first 5 of 77 TAP syntax errors.\n>>\n>> This probably is due to this part of the output:\n>>\n>>     ok 72 - wildmatch 1 1 [ab] [\\[:]ab]\n>>     ok 73 - wildmatch 1 1 ?a?b \\??\\?b\n>>     ok 74 - wildmatch 1 1 abc ^G^Hok 75 - wildmatch 0 0 foo\n>>     ok 76 - wildmatch 1 0 foo/bar/baz/to **/t[o]\n>>     ok 77 - wildmatch 1 1 a1B [[:alpha:]][[:digit:]][[:upper:]]\n>>\n>\n> It seems to prove fine here with perl 5.12.3, Test-Harness-3.230,\n> bash-4.0_p38. What version do you use?\n\nI seem to have Perl 5.10.1, Test::Harness 3.17, Dash 0.5.5.1.  But\nas you can see above, what is _fed_ to the Perl-side is broken\n(notice the concatenation at the end of \"ok 74\"), so I do not think\nversions of Perl-side matters.\n\nI suspect that this is the immediate culprit:\n\n    match 1 1 'abc' '\\a\\b\\c'\n\nThe symptom looks like that somebody is interpreting \\a as BEL, \\b\nas backspace, etc. when showing the \"ok ...\" line, no?\n"},{"id":"200999","messageId":"7vvceh6imi.fsf@alter.siamese.dyndns.org","threadId":"31780","inReplyTo":"7vlifd7zz3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-11T17:09:09Z","receivedAt":"2012-10-11T17:09:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>>> This probably is due to this part of the output:\n>>>\n>>>     ok 72 - wildmatch 1 1 [ab] [\\[:]ab]\n>>>     ok 73 - wildmatch 1 1 ?a?b \\??\\?b\n>>>     ok 74 - wildmatch 1 1 abc ^G^Hok 75 - wildmatch 0 0 foo\n>>>     ok 76 - wildmatch 1 0 foo/bar/baz/to **/t[o]\n>>>     ok 77 - wildmatch 1 1 a1B [[:alpha:]][[:digit:]][[:upper:]]\n>> ...\n>\n> I suspect that this is the immediate culprit:\n>\n>     match 1 1 'abc' '\\a\\b\\c'\n>\n> The symptom looks like that somebody is interpreting \\a as BEL, \\b\n> as backspace, etc. when showing the \"ok ...\" line, no?\n\nAhh, it must be this bits from t/test-lib.sh\n\n t/test-lib.sh | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git i/t/test-lib.sh w/t/test-lib.sh\nindex 514282c..489bc80 100644\n--- i/t/test-lib.sh\n+++ w/t/test-lib.sh\n@@ -230,7 +230,7 @@ else\n \tsay_color() {\n \t\ttest -z \"$1\" && test -n \"$quiet\" && return\n \t\tshift\n-\t\techo \"$*\"\n+\t\tprintf \"%s\\n\" \"$*\"\n \t}\n fi\n \n"},{"id":"201032","messageId":"7vipag601h.fsf@alter.siamese.dyndns.org","threadId":"31780","inReplyTo":"7vvceh6imi.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-11T23:50:34Z","receivedAt":"2012-10-11T23:50:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Ahh, it must be this bits from t/test-lib.sh\n>\n>  t/test-lib.sh | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git i/t/test-lib.sh w/t/test-lib.sh\n> index 514282c..489bc80 100644\n> --- i/t/test-lib.sh\n> +++ w/t/test-lib.sh\n> @@ -230,7 +230,7 @@ else\n>  \tsay_color() {\n>  \t\ttest -z \"$1\" && test -n \"$quiet\" && return\n>  \t\tshift\n> -\t\techo \"$*\"\n> +\t\tprintf \"%s\\n\" \"$*\"\n>  \t}\n>  fi\n\nI'll queue this fix separately before your series on 'pu'.\n\n-- >8 --\nSubject: [PATCH] test-lib: Fix say_color () not to interpret \\a\\b\\c in the message\n\nWhen running with color disabled (e.g. under prove to produce TAP\noutput), say_color() helper function is defined to use echo to show\nthe message.  With a message that ends with \"\\c\", echo is allowed to\ninterpret it as \"Do not end the line with LF\".\n\nUse printf \"%s\\n\" to emit the message literally.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/test-lib.sh | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex c0d04c4..280b3aa 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -169,7 +169,7 @@ else\n \tsay_color() {\n \t\ttest -z \"$1\" && test -n \"$quiet\" && return\n \t\tshift\n-\t\techo \"$*\"\n+\t\tprintf \"%s\\n\" \"$*\"\n \t}\n fi\n \n-- \n1.8.0.rc1.82.ga68bb49\n"},{"id":"201041","messageId":"5077C52E.2050000@viscovery.net","threadId":"31780","inReplyTo":"1349865651-31889-13-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v4 12/12] t3070: disable two fnmatch tests that have different results on different libc","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2012-10-12T07:22:22Z","receivedAt":"2012-10-12T07:22:22Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 10/10/2012 12:40, schrieb Nguyễn Thái Ngọc Duy:\n> fnmatch on glibc-2.12.1 returns no match. glibc-2.15 returns ok.\n\nThere are many more cases that fail with the fnmatch() that we ship in\ncompat/fnmatch. To test this on Linux, you have to remove the \"#if defined\n_LIBC || !defined __GNU_LIBRARY__\" brackets from compat/fnmatch/fnmatch.c\nand build with NO_FNMATCH.\n\n-- Hannes\n"},{"id":"201042","messageId":"5077C676.3070209@viscovery.net","threadId":"31780","inReplyTo":"1349865651-31889-6-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v4 05/12] Integrate wildmatch to git","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2012-10-12T07:27:50Z","receivedAt":"2012-10-12T07:27:50Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"--- >8 ---\nFrom: Johannes Sixt <j6t@kdbg.org>\nSubject: [PATCH] test-wildmatch: avoid exit code -1\n\nOur bash on Windows does not recognize -1 as failure.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n Please squash this in, in the next round.\n\n test-wildmatch.c | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/test-wildmatch.c b/test-wildmatch.c\nindex d716852..74c0864 100644\n--- a/test-wildmatch.c\n+++ b/test-wildmatch.c\n@@ -4,11 +4,11 @@\n int main(int argc, char **argv)\n {\n \tif (!strcmp(argv[1], \"wildmatch\"))\n-\t\treturn wildmatch(argv[3], argv[2], 0);\n+\t\treturn !!wildmatch(argv[3], argv[2], 0);\n \telse if (!strcmp(argv[1], \"iwildmatch\"))\n-\t\treturn wildmatch(argv[3], argv[2], FNM_CASEFOLD);\n+\t\treturn !!wildmatch(argv[3], argv[2], FNM_CASEFOLD);\n \telse if (!strcmp(argv[1], \"fnmatch\"))\n-\t\treturn fnmatch(argv[3], argv[2], FNM_PATHNAME);\n+\t\treturn !!fnmatch(argv[3], argv[2], FNM_PATHNAME);\n \telse\n \t\treturn 1;\n }\n-- \n1.8.0.rc2.1237.g5522246\n"},{"id":"201050","messageId":"CACsJy8DkxT70M9EWGF4rFebQUcDguJqCHkrW3CL3pBi0cAegUQ@mail.gmail.com","threadId":"31780","inReplyTo":"5077C52E.2050000@viscovery.net","subject":"Re: [PATCH v4 12/12] t3070: disable two fnmatch tests that have different results on different libc","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-12T09:49:05Z","receivedAt":"2012-10-12T09:49:05Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Oct 12, 2012 at 2:22 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n> Am 10/10/2012 12:40, schrieb Nguyễn Thái Ngọc Duy:\n>> fnmatch on glibc-2.12.1 returns no match. glibc-2.15 returns ok.\n>\n> There are many more cases that fail with the fnmatch() that we ship in\n> compat/fnmatch. To test this on Linux, you have to remove the \"#if defined\n> _LIBC || !defined __GNU_LIBRARY__\" brackets from compat/fnmatch/fnmatch.c\n> and build with NO_FNMATCH.\n\nThanks. The point of checking against fnmatch is to make sure that\nwildmatch does not divert in behavior from fnmatch. For some corner\ncases that behavior is undefined, I think it is ok for different\nfnmatch versions to behave differently.\n\nBut some of failed tests make me worry about fnmatch. compat/fnmatch\nfor example does not match '**/foo' with '/foo' (it does '*/foo' with\n'/foo'). 'A' is matched with '[[:digit:][:space:][:upper:]]' but not\n'[[:digit:][:upper:][:space:]]'. Perhaps we better off convert git to\nuse wildmatch only to keep matching behavior more reliable. wildmatch\ndoes not support non-FNM_PATHNAME mode, but that should be easy to\nfix. The only downside I see is fnmatch may support locale while\nwildmatch does not.\n-- \nDuy\n"},{"id":"201064","messageId":"507848DF.6060301@web.de","threadId":"31780","inReplyTo":"CACsJy8B2JJmUbjAauMwbg95fCvPdUYqy4CKZp3ac44XHoh1NLQ@mail.gmail.com","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2012-10-12T16:44:15Z","receivedAt":"2012-10-12T16:44:15Z","isPatch":true,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"On 11.10.12 13:56, Nguyen Thai Ngoc Duy wrote:\n> On Thu, Oct 11, 2012 at 11:33 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Junio C Hamano <gitster@pobox.com> writes:\n>>\n>>> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>>>\n>>>> Really small updates. I did not want to resend it this soon but this\n>>>> may fix the compile errors for Junio.\n>>\n>> t3070 seems to break TAP,\n>>\n>>     *** prove ***\n>>     t3070-wildmatch.sh .. Failed 1/151 subtests\n>>\n>>     Test Summary Report\n>>     -------------------\n>>     t3070-wildmatch.sh (Wstat: 0 Tests: 150 Failed: 0)\n>>       Parse errors: Tests out of sequence.  Found (76) but expected (75)\n>>                     Tests out of sequence.  Found (77) but expected (76)\n>>                     Tests out of sequence.  Found (78) but expected (77)\n>>                     Tests out of sequence.  Found (79) but expected (78)\n>>                     Tests out of sequence.  Found (80) but expected (79)\n>>     Displayed the first 5 of 77 TAP syntax errors.\n>>\n>> This probably is due to this part of the output:\n>>\n>>     ok 72 - wildmatch 1 1 [ab] [\\[:]ab]\n>>     ok 73 - wildmatch 1 1 ?a?b \\??\\?b\n>>     ok 74 - wildmatch 1 1 abc ^G^Hok 75 - wildmatch 0 0 foo\n>>     ok 76 - wildmatch 1 0 foo/bar/baz/to **/t[o]\n>>     ok 77 - wildmatch 1 1 a1B [[:alpha:]][[:digit:]][[:upper:]]\n>>\n> \n> It seems to prove fine here with perl 5.12.3, Test-Harness-3.230,\n> bash-4.0_p38. What version do you use?\n> \nSome problems even here (Mac OS) commit 2aeb6d4d7884f4c4425\n\nnot ok 61 - wildmatch 0 0 \\ \\\nnot ok 62 - wildmatch 0 0 /\\ */\\\nnot ok 69 - wildmatch 1 1 [ab] [[:]ab]\nnot ok 71 - wildmatch 1 1 [ab] [[:digit]ab]\nnot ok 80 - wildmatch 1 0 1 [[:digit:][:upper:][:space:]]\nnot ok 81 - wildmatch 0 0 1 [[:digit:][:upper:][:spaci:]]\nnot ok 88 - wildmatch 1 0 _ [[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\nnot ok 89 - wildmatch 1 0 _ [[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\nnot ok 93 - wildmatch 1 1 y [a-c[:digit:]x-z]\n\nI have 2 perls, I'm not sure which versin is used by git these days.\n\n which perl\n/opt/local/bin/perl\ntb@birne:~/projects/git/git.pu/t> perl --version\n\nThis is perl, v5.8.9 built for darwin-2level\n\n----------------\n/usr/bin/perl --version\n\nThis is perl, v5.10.0 built for darwin-thread-multi-2level\n(with 2 registered patches, see perl -V for more detail)\n----------\n\nIf I can do more debugging/testing please let me know\n/Torsten\n"},{"id":"201067","messageId":"7vbog74o59.fsf@alter.siamese.dyndns.org","threadId":"31780","inReplyTo":"507848DF.6060301@web.de","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-12T17:05:06Z","receivedAt":"2012-10-12T17:05:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Torsten Bögershausen <tboegi@web.de> writes:\n\n> On 11.10.12 13:56, Nguyen Thai Ngoc Duy wrote:\n>> On Thu, Oct 11, 2012 at 11:33 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Junio C Hamano <gitster@pobox.com> writes:\n>>>\n>>>> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>>>>\n>>>>> Really small updates. I did not want to resend it this soon but this\n>>>>> may fix the compile errors for Junio.\n>>>\n>>> t3070 seems to break TAP,\n>>>\n>>>     *** prove ***\n>>>     t3070-wildmatch.sh .. Failed 1/151 subtests\n>>>\n>>>     Test Summary Report\n>>>     -------------------\n>>>     t3070-wildmatch.sh (Wstat: 0 Tests: 150 Failed: 0)\n>>>       Parse errors: Tests out of sequence.  Found (76) but expected (75)\n>>>                     Tests out of sequence.  Found (77) but expected (76)\n>>>                     Tests out of sequence.  Found (78) but expected (77)\n>>>                     Tests out of sequence.  Found (79) but expected (78)\n>>>                     Tests out of sequence.  Found (80) but expected (79)\n>>>     Displayed the first 5 of 77 TAP syntax errors.\n>>>\n>>> This probably is due to this part of the output:\n>>>\n>>>     ok 72 - wildmatch 1 1 [ab] [\\[:]ab]\n>>>     ok 73 - wildmatch 1 1 ?a?b \\??\\?b\n>>>     ok 74 - wildmatch 1 1 abc ^G^Hok 75 - wildmatch 0 0 foo\n>>>     ok 76 - wildmatch 1 0 foo/bar/baz/to **/t[o]\n>>>     ok 77 - wildmatch 1 1 a1B [[:alpha:]][[:digit:]][[:upper:]]\n>>>\n>> \n>> It seems to prove fine here with perl 5.12.3, Test-Harness-3.230,\n>> bash-4.0_p38. What version do you use?\n>> \n> Some problems even here (Mac OS) commit 2aeb6d4d7884f4c4425\n>\n> not ok 61 - wildmatch 0 0 \\ \\\n> not ok 62 - wildmatch 0 0 /\\ */\\\n> not ok 69 - wildmatch 1 1 [ab] [[:]ab]\n> not ok 71 - wildmatch 1 1 [ab] [[:digit]ab]\n> not ok 80 - wildmatch 1 0 1 [[:digit:][:upper:][:space:]]\n> not ok 81 - wildmatch 0 0 1 [[:digit:][:upper:][:spaci:]]\n> not ok 88 - wildmatch 1 0 _ [[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n> not ok 89 - wildmatch 1 0 _ [[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n> not ok 93 - wildmatch 1 1 y [a-c[:digit:]x-z]\n>\n> I have 2 perls,...\n\nThe problem under discussion was that the output from passing tests\nwere mangled and not interpreted correctly by a program that\nanalyzes them, which happens to be written in Perl.  Even in that\ncontext, it was pointless to ask for Perl versions, as it was clear\nthat the input to that Perl-written program, i.e. output from the\ntests, were not formatted correctly to say \"ok NN message\".\n\nIf you are getting \"not ok\", I do not think you need to look at your\nPerl.  The wildmatch tests are failing, and it is far more likely\nthat the wildmatch code is failing in your environment, than the\ntest harness that runs wildmatch code is failing.\n\nNeither the wildmatch code itself (in C), nor the test harness that\nis giving you the above \"not ok\" (in shell) depends on Perl.\n\nThanks for a report, but the debugging needs to see how the matching\ncode in mildmatch misbehaves.\n\nI suspect it is another case where the platform fnmatch (from MacOS)\nis not behaving as these tests expect.\n\nNguyen, how about updating the match () shell function in 3070 so\nthat it not just says not-ok, but indicates what failed (wildmatch\nfailed, or wildmatch passed but fnmatch failed), at least when the\ntest is run as \"./t3070-*.sh -v -i\"?\n"},{"id":"201071","messageId":"7v7gqv4my7.fsf@alter.siamese.dyndns.org","threadId":"31780","inReplyTo":"5077C676.3070209@viscovery.net","subject":"Re: [PATCH v4 05/12] Integrate wildmatch to git","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-12T17:30:56Z","receivedAt":"2012-10-12T17:30:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> --- >8 ---\n> From: Johannes Sixt <j6t@kdbg.org>\n> Subject: [PATCH] test-wildmatch: avoid exit code -1\n>\n> Our bash on Windows does not recognize -1 as failure.\n>\n> Signed-off-by: Johannes Sixt <j6t@kdbg.org>\n> ---\n>  Please squash this in, in the next round.\n\nI do think the patch is good, but I am curious if people who ported\nbash to windows consider this a bug.\n\nShouldn't the argument to exit() be truncated to its least\nsignificant 8 bits (that is, status & 0377) and be made available to\nthe waiting parent process (which is bash in this case)?\n\n>  test-wildmatch.c | 6 +++---\n>  1 file changed, 3 insertions(+), 3 deletions(-)\n>\n> diff --git a/test-wildmatch.c b/test-wildmatch.c\n> index d716852..74c0864 100644\n> --- a/test-wildmatch.c\n> +++ b/test-wildmatch.c\n> @@ -4,11 +4,11 @@\n>  int main(int argc, char **argv)\n>  {\n>  \tif (!strcmp(argv[1], \"wildmatch\"))\n> -\t\treturn wildmatch(argv[3], argv[2], 0);\n> +\t\treturn !!wildmatch(argv[3], argv[2], 0);\n>  \telse if (!strcmp(argv[1], \"iwildmatch\"))\n> -\t\treturn wildmatch(argv[3], argv[2], FNM_CASEFOLD);\n> +\t\treturn !!wildmatch(argv[3], argv[2], FNM_CASEFOLD);\n>  \telse if (!strcmp(argv[1], \"fnmatch\"))\n> -\t\treturn fnmatch(argv[3], argv[2], FNM_PATHNAME);\n> +\t\treturn !!fnmatch(argv[3], argv[2], FNM_PATHNAME);\n>  \telse\n>  \t\treturn 1;\n>  }\n"},{"id":"201073","messageId":"50787D5D.3080509@web.de","threadId":"31780","inReplyTo":"7vbog74o59.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2012-10-12T20:28:13Z","receivedAt":"2012-10-12T20:28:13Z","isPatch":true,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"On 10/12/2012 07:05 PM, Junio C Hamano wrote:\n>> Some problems even here (Mac OS) commit 2aeb6d4d7884f4c4425\n>>\n>> not ok 61 - wildmatch 0 0 \\ \\\n>> not ok 62 - wildmatch 0 0 /\\ */\\\n>> not ok 69 - wildmatch 1 1 [ab] [[:]ab]\n>> not ok 71 - wildmatch 1 1 [ab] [[:digit]ab]\n>> not ok 80 - wildmatch 1 0 1 [[:digit:][:upper:][:space:]]\n>> not ok 81 - wildmatch 0 0 1 [[:digit:][:upper:][:spaci:]]\n>> not ok 88 - wildmatch 1 0 _ [[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n>> not ok 89 - wildmatch 1 0 _ [[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]\n>> not ok 93 - wildmatch 1 1 y [a-c[:digit:]x-z]\n\n> Nguyen, how about updating the match () shell function in 3070 so\n> that it not just says not-ok, but indicates what failed (wildmatch\n> failed, or wildmatch passed but fnmatch failed), at least when the\n> test is run as \"./t3070-*.sh -v -i\"?\n\nIt seams to be the fnmatch, since removing the\nfnmatch makes t3070 pass.\n\nHowever, pullling in compat/fnmatch in the Makefile\n\n  ifeq ($(uname_S),Darwin)\n+       NO_FNMATCH = YesPlease\n\n================\ngives this result:\n  ./t3070-wildmatch.sh 2>&1 | grep \"not ok\"\nnot ok 23 - wildmatch 1 1 a]b a[]]b\nnot ok 25 - wildmatch 1 1 a]b a[]-]b\nnot ok 43 - wildmatch 1 1 /foo **/foo\nnot ok 79 - wildmatch 1 1 A [[:digit:][:upper:][:space:]]\nnot ok 84 - wildmatch 1 1 . [[:digit:][:punct:][:space:]]\nnot ok 85 - wildmatch 1 1 5 [[:xdigit:]]\nnot ok 86 - wildmatch 1 1 f [[:xdigit:]]\nnot ok 87 - wildmatch 1 1 D [[:xdigit:]]\nnot ok 90 - wildmatch 1 1 . \n[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]\nnot ok 92 - wildmatch 1 1 b [a-c[:digit:]x-z]\nnot ok 95 - wildmatch 1 1 ] [\\\\-^]\nnot ok 98 - wildmatch 1 1 ] [\\]]\n\n(Confused)\n"},{"id":"201076","messageId":"20121013034934.GA27791@do","threadId":"31780","inReplyTo":"7vbog74o59.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v4 00/12] Wildmatch v4","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-10-13T03:49:34Z","receivedAt":"2012-10-13T03:49:34Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Oct 12, 2012 at 10:05:06AM -0700, Junio C Hamano wrote:\n> Nguyen, how about updating the match () shell function in 3070 so\n> that it not just says not-ok, but indicates what failed (wildmatch\n> failed, or wildmatch passed but fnmatch failed), at least when the\n> test is run as \"./t3070-*.sh -v -i\"?\n\nYou could squash this to the \"Integrate wildmatch to git\" patch, or\njust put it at the end of the series (I'll need to send a series\nupdate anyway). This splits fnmatch and wildmatch tests separately so\nwe can easily identify which one fails.\n\n-- 8< --\ndiff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh\nindex c3ee729..4f97923 100755\n--- a/t/t3070-wildmatch.sh\n+++ b/t/t3070-wildmatch.sh\n@@ -5,20 +5,28 @@ test_description='wildmatch tests'\n . ./test-lib.sh\n \n match() {\n-    test_expect_success \"wildmatch $*\" \"\n-\tif [ $1 = 1 ]; then\n+    if [ $1 = 1 ]; then\n+\ttest_expect_success \"wildmatch:    match $3 $4\" \"\n \t    test-wildmatch wildmatch '$3' '$4'\n-\telse\n+\t\"\n+    else\n+\ttest_expect_success \"wildmatch: no match $3 $4\" \"\n \t    ! test-wildmatch wildmatch '$3' '$4'\n-\tfi &&\n-\tif [ $2 = 1 ]; then\n+\t\"\n+    fi\n+    if [ $2 = 1 ]; then\n+\ttest_expect_success \"fnmatch:      match $3 $4\" \"\n \t    test-wildmatch fnmatch '$3' '$4'\n-\telif [ $2 = x ]; then\n-\t    true\n-\telse\n+\t\"\n+    elif [ $2 = 0 ]; then\n+\ttest_expect_success \"fnmatch:   no match $3 $4\" \"\n \t    ! test-wildmatch fnmatch '$3' '$4'\n-\tfi\n-    \"\n+\t\"\n+#    else\n+#\ttest_expect_success BROKEN_FNMATCH \"fnmatch:       $3 $4\" \"\n+#\t    test-wildmatch fnmatch '$3' '$4'\n+#\t\"\n+    fi\n }\n \n # Basic wildmat features\n-- 8< --\n-- \nDuy\n"}]}