# from [d025d9c8472782f0ca2ee251348281a219837504]
# to [fc5d09de50f5b8dd7fa0c6713b3d8b47267591db]
---
+++
@@ -0,0 +1,302 @@
+// Copyright (C) 2005 Nathaniel Smith
+// 2007 Zack Weinberg
+//
+// This program is made available under the GNU GPL version 2.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#include "base.hh"
+#include "unit_tests.hh"
+#include "globish.hh"
+#include "option.hh"
+
+using std::string;
+using std::vector;
+
+UNIT_TEST(syntax)
+{
+ struct tcase
+ {
+ char const * in;
+ char const * out;
+ };
+ tcase const good[] = {
+ { "a", "a" },
+ { "\\a", "a" },
+ { "[a]", "a" },
+ { "[!a]", "[!a]" },
+ { "[^a]", "[!a]" },
+ { "[\\!a]", "[\\!a]" },
+ { "[\\^a]", "[\\^a]" },
+ { "[ab]", "[ab]" },
+ { "[a-b]", "[ab]" },
+ { "[a-c]", "[abc]" },
+ { "[ac-]", "[\\-ac]" },
+ { "[-ac]", "[\\-ac]" },
+ { "[+-/]", "[+\\,\\-./]" },
+
+ { "\xC2\xA1", "\xC2\xA1" }, // U+00A1 in UTF8
+
+ { "*", "*" },
+ { "\\*", "\\*" },
+ { "[*]", "\\*" },
+ { "?", "?" },
+ { "\\?", "\\?" },
+ { "[?]", "\\?" },
+ { ",", "\\," },
+ { "\\,", "\\," },
+ { "[,]", "\\," },
+ { "\\{", "\\{" },
+ { "[{]", "\\{" },
+ { "[}]", "\\}" },
+ { "\\[", "\\[" },
+ { "\\]", "\\]" },
+ { "\\\\", "\\\\" },
+
+ { "**", "*" },
+ { "*?", "?*" },
+ { "*???*?*", "????*" },
+ { "*a?*?b*", "*a??*b*" },
+
+ { "{a,b,c}d", "{a,b,c}d" },
+ { "foo{a,{b,c},?*}d", "foo{a,{b,c},?*}d" },
+ { "\\a\\b\\|\\{\\*", "ab|\\{\\*" },
+ { ".+$^{}", ".+$\\^{}" },
+ { "\\.\\+\\$\\^\\(\\)", ".+$\\^()" },
+ { 0, 0 }
+ };
+
+ char const * const bad[] = {
+ "[",
+ "[!",
+ "[\\",
+ "[\\]",
+ "[foo",
+ "[!foo",
+ "foo]",
+ "[\003]",
+ "[a-a]",
+ "[f-a]",
+ "[]",
+ "[\xC2\xA1]",
+ "[\xC2\xA1\xC2\xA2]",
+ "[\xC2\xA1-\xC2\xA2]",
+ "[-\xC2\xA1]",
+ "[[]",
+ "[]",
+
+ "\003",
+ "foo\\",
+ "{foo",
+ "{foo,bar{baz,quux}",
+ "foo}",
+ "foo,bar{baz,quux}}",
+ "{{{{{{{{{{a,b},c},d},e},f},g},h},i},j},k}",
+ 0
+ };
+ char const dummy[] = "";
+
+ for (tcase const * p = good; p->in; p++)
+ {
+ globish g(p->in, origin::internal);
+ string s;
+ dump(g, s);
+ L(FL("globish syntax: %s -> %s [expect %s]") % p->in % s % p->out);
+ UNIT_TEST_CHECK(s == p->out);
+ }
+
+ for (char const * const * p = bad; *p; p++)
+ {
+ L(FL("globish syntax: invalid %s") % *p);
+ UNIT_TEST_CHECK_THROW(I(globish(*p, origin::user).matches(dummy)), recoverable_failure);
+ UNIT_TEST_CHECK_THROW(I(globish(*p, origin::internal).matches(dummy)), unrecoverable_failure);
+ }
+}
+
+UNIT_TEST(from_vector)
+{
+ vector v;
+ v.push_back(arg_type("a", origin::internal));
+ v.push_back(arg_type("b", origin::internal));
+ v.push_back(arg_type("c", origin::internal));
+ globish combined(v);
+ string s;
+ dump(combined, s);
+ UNIT_TEST_CHECK(s == "{a,b,c}");
+}
+
+UNIT_TEST(simple_matches)
+{
+ UNIT_TEST_CHECK(globish("abc", origin::internal).matches("abc"));
+ UNIT_TEST_CHECK(!globish("abc", origin::internal).matches("aac"));
+
+ UNIT_TEST_CHECK(globish("a[bc]d", origin::internal).matches("abd"));
+ UNIT_TEST_CHECK(globish("a[bc]d", origin::internal).matches("acd"));
+ UNIT_TEST_CHECK(!globish("a[bc]d", origin::internal).matches("and"));
+ UNIT_TEST_CHECK(!globish("a[bc]d", origin::internal).matches("ad"));
+ UNIT_TEST_CHECK(!globish("a[bc]d", origin::internal).matches("abbd"));
+
+ UNIT_TEST_CHECK(globish("a[!bc]d", origin::internal).matches("and"));
+ UNIT_TEST_CHECK(globish("a[!bc]d", origin::internal).matches("a#d"));
+ UNIT_TEST_CHECK(!globish("a[!bc]d", origin::internal).matches("abd"));
+ UNIT_TEST_CHECK(!globish("a[!bc]d", origin::internal).matches("acd"));
+ UNIT_TEST_CHECK(!globish("a[!bc]d", origin::internal).matches("ad"));
+ UNIT_TEST_CHECK(!globish("a[!bc]d", origin::internal).matches("abbd"));
+
+ UNIT_TEST_CHECK(globish("a?c", origin::internal).matches("abc"));
+ UNIT_TEST_CHECK(globish("a?c", origin::internal).matches("aac"));
+ UNIT_TEST_CHECK(globish("a?c", origin::internal).matches("a%c"));
+ UNIT_TEST_CHECK(!globish("a?c", origin::internal).matches("a%d"));
+ UNIT_TEST_CHECK(!globish("a?c", origin::internal).matches("d%d"));
+ UNIT_TEST_CHECK(!globish("a?c", origin::internal).matches("d%c"));
+ UNIT_TEST_CHECK(!globish("a?c", origin::internal).matches("a%%d"));
+
+ UNIT_TEST_CHECK(globish("a*c", origin::internal).matches("ac"));
+ UNIT_TEST_CHECK(globish("a*c", origin::internal).matches("abc"));
+ UNIT_TEST_CHECK(globish("a*c", origin::internal).matches("abac"));
+ UNIT_TEST_CHECK(globish("a*c", origin::internal).matches("abbcc"));
+ UNIT_TEST_CHECK(globish("a*c", origin::internal).matches("abcbbc"));
+ UNIT_TEST_CHECK(!globish("a*c", origin::internal).matches("abcbb"));
+ UNIT_TEST_CHECK(!globish("a*c", origin::internal).matches("abcb"));
+ UNIT_TEST_CHECK(!globish("a*c", origin::internal).matches("aba"));
+ UNIT_TEST_CHECK(!globish("a*c", origin::internal).matches("ab"));
+
+ UNIT_TEST_CHECK(globish("*.bak", origin::internal).matches(".bak"));
+ UNIT_TEST_CHECK(globish("*.bak", origin::internal).matches("a.bak"));
+ UNIT_TEST_CHECK(globish("*.bak", origin::internal).matches("foo.bak"));
+ UNIT_TEST_CHECK(globish("*.bak", origin::internal).matches(".bak.bak"));
+ UNIT_TEST_CHECK(globish("*.bak", origin::internal).matches("fwibble.bak.bak"));
+
+ UNIT_TEST_CHECK(globish("a*b*[cd]", origin::internal).matches("abc"));
+ UNIT_TEST_CHECK(globish("a*b*[cd]", origin::internal).matches("abcd"));
+ UNIT_TEST_CHECK(globish("a*b*[cd]", origin::internal).matches("aabrd"));
+ UNIT_TEST_CHECK(globish("a*b*[cd]", origin::internal).matches("abbbbbbbccd"));
+ UNIT_TEST_CHECK(!globish("a*b*[cd]", origin::internal).matches("ab"));
+ UNIT_TEST_CHECK(!globish("a*b*[cd]", origin::internal).matches("abde"));
+ UNIT_TEST_CHECK(!globish("a*b*[cd]", origin::internal).matches("aaaaaaab"));
+ UNIT_TEST_CHECK(!globish("a*b*[cd]", origin::internal).matches("axxxxd"));
+ UNIT_TEST_CHECK(!globish("a*b*[cd]", origin::internal).matches("adb"));
+}
+
+UNIT_TEST(complex_matches)
+{ {
+ globish_matcher m(globish("{a,b}?*\\*|", origin::internal),
+ globish("*c*", origin::internal));
+ UNIT_TEST_CHECK(m("aq*|"));
+ UNIT_TEST_CHECK(m("bq*|"));
+ UNIT_TEST_CHECK(!m("bc*|"));
+ UNIT_TEST_CHECK(!m("bq|"));
+ UNIT_TEST_CHECK(!m("b*|"));
+ UNIT_TEST_CHECK(!m(""));
+ }
+ {
+ globish_matcher m(globish("{a,\\\\,b*}", origin::internal),
+ globish("*c*", origin::internal));
+ UNIT_TEST_CHECK(m("a"));
+ UNIT_TEST_CHECK(!m("ab"));
+ UNIT_TEST_CHECK(m("\\"));
+ UNIT_TEST_CHECK(!m("\\\\"));
+ UNIT_TEST_CHECK(m("b"));
+ UNIT_TEST_CHECK(m("bfoobar"));
+ UNIT_TEST_CHECK(!m("bfoobarcfoobar"));
+ }
+ {
+ globish_matcher m(globish("*", origin::internal),
+ globish("", origin::internal));
+ UNIT_TEST_CHECK(m("foo"));
+ UNIT_TEST_CHECK(m(""));
+ }
+ {
+ globish_matcher m(globish("{foo}", origin::internal),
+ globish("", origin::internal));
+ UNIT_TEST_CHECK(m("foo"));
+ UNIT_TEST_CHECK(!m("bar"));
+ }
+}
+
+UNIT_TEST(nested_matches)
+{ {
+ globish g("a.{i.{x,y},j}", origin::internal);
+ UNIT_TEST_CHECK(g.matches("a.i.x"));
+ UNIT_TEST_CHECK(g.matches("a.i.y"));
+ UNIT_TEST_CHECK(g.matches("a.j"));
+ UNIT_TEST_CHECK(!g.matches("q"));
+ UNIT_TEST_CHECK(!g.matches("a.q"));
+ UNIT_TEST_CHECK(!g.matches("a.j.q"));
+ UNIT_TEST_CHECK(!g.matches("a.i.q"));
+ UNIT_TEST_CHECK(!g.matches("a.i.x.q"));
+ }
+ {
+ globish g("a.b{,.c}", origin::internal);
+ UNIT_TEST_CHECK(g.matches("a.b"));
+ UNIT_TEST_CHECK(g.matches("a.b.c"));
+ UNIT_TEST_CHECK(!g.matches("a.b."));
+ UNIT_TEST_CHECK(!g.matches("a.b.\\,"));
+ UNIT_TEST_CHECK(!g.matches("a.b.\\,.c"));
+ }
+ {
+ globish g("a.b{.c,}", origin::internal);
+ UNIT_TEST_CHECK(g.matches("a.b"));
+ UNIT_TEST_CHECK(g.matches("a.b.c"));
+ UNIT_TEST_CHECK(!g.matches("a.b.c\\,"));
+ }
+ {
+ globish g("a.b{.c,,.d}", origin::internal);
+ UNIT_TEST_CHECK(g.matches("a.b"));
+ UNIT_TEST_CHECK(g.matches("a.b.c"));
+ UNIT_TEST_CHECK(g.matches("a.b.d"));
+ UNIT_TEST_CHECK(!g.matches("a.b."));
+ UNIT_TEST_CHECK(!g.matches("a.b.c\\,"));
+ UNIT_TEST_CHECK(!g.matches("a.b.c\\,\\,"));
+ UNIT_TEST_CHECK(!g.matches("a.b.c\\,\\,.d"));
+ UNIT_TEST_CHECK(!g.matches("a.b.c\\,.d"));
+ UNIT_TEST_CHECK(!g.matches("a.b.c.d"));
+ }
+ {
+ globish g("a.b{.c,}.d", origin::internal);
+ UNIT_TEST_CHECK(g.matches("a.b.d"));
+ UNIT_TEST_CHECK(g.matches("a.b.c.d"));
+ UNIT_TEST_CHECK(!g.matches("a.b.c\\,.d"));
+ }
+ {
+ globish g("a.b{,.c}.d", origin::internal);
+ UNIT_TEST_CHECK(g.matches("a.b.d"));
+ UNIT_TEST_CHECK(g.matches("a.b.c.d"));
+ UNIT_TEST_CHECK(!g.matches("a.b.c\\,.d"));
+ }
+ {
+ globish g("a.b{.c,,.e}.d", origin::internal);
+ UNIT_TEST_CHECK(g.matches("a.b.d"));
+ UNIT_TEST_CHECK(g.matches("a.b.c.d"));
+ UNIT_TEST_CHECK(g.matches("a.b.e.d"));
+ }
+ {
+ globish g("{a.,}b", origin::internal);
+ UNIT_TEST_CHECK(g.matches("a.b"));
+ UNIT_TEST_CHECK(g.matches("b"));
+ UNIT_TEST_CHECK(!g.matches("a.\\,b"));
+ }
+ {
+ globish g("{,a.}b", origin::internal);
+ UNIT_TEST_CHECK(g.matches("b"));
+ UNIT_TEST_CHECK(g.matches("a.b"));
+ UNIT_TEST_CHECK(!g.matches("\\,a.b"));
+ }
+ {
+ globish g("{a.,,c.}b", origin::internal);
+ UNIT_TEST_CHECK(g.matches("a.b"));
+ UNIT_TEST_CHECK(g.matches("c.b"));
+ UNIT_TEST_CHECK(g.matches("b"));
+ }
+}
+
+// Local Variables:
+// mode: C++
+// fill-column: 76
+// c-file-style: "gnu"
+// indent-tabs-mode: nil
+// End:
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: