summaryrefslogtreecommitdiff
path: root/fnmatch.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-03-19 22:26:06 -0400
committerRich Felker <dalias@aerifal.cx>2011-03-19 22:26:06 -0400
commita9baddd7d07b9fe15e212985a808a79773ec72e4 (patch)
treefce0a089eedeacef8b25b409c2ba50f5f30a8327 /fnmatch.c
downloadlibc-testsuite-a9baddd7d07b9fe15e212985a808a79773ec72e4.tar.gz
initial check-in, taken from old libc svn repo with significant additions
Diffstat (limited to 'fnmatch.c')
-rw-r--r--fnmatch.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/fnmatch.c b/fnmatch.c
new file mode 100644
index 0000000..0ab8ffb
--- /dev/null
+++ b/fnmatch.c
@@ -0,0 +1,142 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fnmatch.h>
+#include <unistd.h>
+
+/* adapted from dietlibc's test-newfnmatch.c */
+
+/*
+ * xlat / printflags adapted from strace
+ * http://www.liacs.nl/~wichert/strace/
+ */
+
+#define FLAG(f) { f, #f }
+
+struct xlat {
+ int val;
+ char *str;
+} fnmatch_flags[] = {
+ FLAG(FNM_NOESCAPE),
+ FLAG(FNM_PATHNAME),
+ FLAG(FNM_PERIOD),
+ {0, NULL},
+};
+
+static void printflags(const struct xlat *map, int flags) {
+ char * sep;
+
+ if (! flags) {
+ printf("0");
+ return;
+ }
+
+ sep = "";
+ for (; map->str; map++) {
+ if (map->val && (flags & map->val) == map->val) {
+ printf("%s%s", sep, map->str);
+ sep = "|";
+ flags &= ~(map->val);
+ }
+ }
+ if (flags) printf("%sunknown=%#x", sep, flags);
+}
+
+/*
+ * tests harness adapted from glibc testfnm.c
+ */
+struct {
+ const char *pattern;
+ const char *string;
+ int flags;
+ int expected;
+} tests[] = {
+ /* begin dietlibc tests */
+ { "*.c", "foo.c", 0, 0 },
+ { "*.c", ".c", 0, 0 },
+ { "*.a", "foo.c", 0, FNM_NOMATCH },
+ { "*.c", ".foo.c", 0, 0 },
+ { "*.c", ".foo.c", FNM_PERIOD, FNM_NOMATCH },
+ { "*.c", "foo.c", FNM_PERIOD, 0 },
+ { "a\\*.c", "a*.c", FNM_NOESCAPE, FNM_NOMATCH },
+ { "a\\*.c", "ax.c", 0, FNM_NOMATCH },
+ { "a[xy].c", "ax.c", 0, 0 },
+ { "a[!y].c", "ax.c", 0, 0 },
+ { "a[a/z]*.c", "a/x.c", FNM_PATHNAME, FNM_NOMATCH },
+ { "a/*.c", "a/x.c", FNM_PATHNAME, 0 },
+ { "a*.c", "a/x.c", FNM_PATHNAME, FNM_NOMATCH },
+ { "*/foo", "/foo", FNM_PATHNAME, 0 },
+ { "-O[01]", "-O1", 0, 0 },
+ { "[[?*\\]", "\\", 0, 0 },
+ { "[]?*\\]", "]", 0, 0 },
+ /* initial right-bracket tests */
+ { "[!]a-]", "b", 0, 0 },
+ { "[]-_]", "^", 0, 0 }, /* range: ']', '^', '_' */
+ { "[!]-_]", "X", 0, 0 },
+ { "??", "-", 0, FNM_NOMATCH },
+ /* begin glibc tests */
+ { "*LIB*", "lib", FNM_PERIOD, FNM_NOMATCH },
+ { "a[/]b", "a/b", 0, 0 },
+ { "a[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH },
+ { "[a-z]/[a-z]", "a/b", 0, 0 },
+ { "*", "a/b", FNM_PATHNAME, FNM_NOMATCH },
+ { "*[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH },
+ { "*[b]", "a/b", FNM_PATHNAME, FNM_NOMATCH },
+ { "[*]/b", "a/b", 0, FNM_NOMATCH },
+ { "[*]/b", "*/b", 0, 0 },
+ { "[?]/b", "a/b", 0, FNM_NOMATCH },
+ { "[?]/b", "?/b", 0, 0 },
+ { "[[a]/b", "a/b", 0, 0 },
+ { "[[a]/b", "[/b", 0, 0 },
+ { "\\*/b", "a/b", 0, FNM_NOMATCH },
+ { "\\*/b", "*/b", 0, 0 },
+ { "\\?/b", "a/b", 0, FNM_NOMATCH },
+ { "\\?/b", "?/b", 0, 0 },
+ { "[/b", "[/b", 0, -FNM_NOMATCH },
+ { "\\[/b", "[/b", 0, 0 },
+ { "??""/b", "aa/b", 0, 0 },
+ { "???b", "aa/b", 0, 0 },
+ { "???b", "aa/b", FNM_PATHNAME, FNM_NOMATCH },
+ { "?a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
+ { "a/?b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
+ { "*a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
+ { "a/*b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
+ { "[.]a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
+ { "a/[.]b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
+ { "*/?", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 },
+ { "?/*", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 },
+ { ".*/?", ".a/b", FNM_PATHNAME|FNM_PERIOD, 0 },
+ { "*/.?", "a/.b", FNM_PATHNAME|FNM_PERIOD, 0 },
+ { "*/*", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
+ { "*?*/*", "a/.b", FNM_PERIOD, 0 },
+ { "*[.]/b", "a./b", FNM_PATHNAME|FNM_PERIOD, 0 },
+ { "*[[:alpha:]]/*[[:alnum:]]", "a/b", FNM_PATHNAME, 0 },
+ /* These three tests should result in error according to SUSv3.
+ * See XCU 2.13.1, XBD 9.3.5, & fnmatch() */
+ { "*[![:digit:]]*/[![:d-d]", "a/b", FNM_PATHNAME, -FNM_NOMATCH },
+ { "*[![:digit:]]*/[[:d-d]", "a/[", FNM_PATHNAME, -FNM_NOMATCH },
+ { "*[![:digit:]]*/[![:d-d]", "a/[", FNM_PATHNAME, -FNM_NOMATCH },
+ { "a?b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 },
+ { "a*b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 },
+ { "a[.]b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 },
+};
+
+int test_fnmatch(void) {
+ int i;
+ unsigned int failed = 0;
+
+ for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
+ int r, x;
+
+ r = fnmatch(tests[i].pattern, tests[i].string, tests[i].flags);
+ x = tests[i].expected;
+ if (r != x && (r != FNM_NOMATCH || x != -FNM_NOMATCH)) {
+ failed++;
+ printf("fail - fnmatch(\"%s\", \"%s\", ",
+ tests[i].pattern, tests[i].string);
+ printflags(fnmatch_flags, tests[i].flags);
+ printf(") => %d (expected %d)\n", r, tests[i].expected);
+ }
+ }
+
+ return failed;
+}