Blame src/functional/fnmatch.c

Szabolcs Nagy b66768
#define _GNU_SOURCE 1
nsz dda49c
#include <stdio.h>
nsz dda49c
#include <stdlib.h>
nsz dda49c
#include <fnmatch.h>
nsz dda49c
#include <unistd.h>
nsz dda49c
#include "test.h"
nsz dda49c
nsz dda49c
/* adapted from dietlibc's test-newfnmatch.c */
nsz dda49c
nsz dda49c
/* xlat / printflags adapted from http://www.liacs.nl/~wichert/strace/ */
nsz dda49c
#define FLAG(f) { f, #f }
nsz dda49c
nsz dda49c
struct xlat {
nsz dda49c
	int val;
nsz dda49c
	char *str;
nsz dda49c
} fnmatch_flags[] = {
nsz dda49c
	FLAG(FNM_NOESCAPE),
nsz dda49c
	FLAG(FNM_PATHNAME),
nsz dda49c
	FLAG(FNM_PERIOD),
Szabolcs Nagy b66768
#ifdef FNM_CASEFOLD
Szabolcs Nagy b66768
	FLAG(FNM_CASEFOLD),
Szabolcs Nagy b66768
#endif
nsz dda49c
	{0, NULL},
nsz dda49c
};
nsz dda49c
nsz 462b4f
static char *flagstr(const struct xlat *map, int flags)
nsz 462b4f
{
nsz 462b4f
	static char buf[1000];
nsz dda49c
	char *sep;
Szabolcs Nagy fd0899
	int n;
nsz dda49c
nsz dda49c
	if (!flags) {
nsz 462b4f
		sprintf(buf, "0");
nsz 462b4f
		return buf;
nsz dda49c
	}
Szabolcs Nagy fd0899
	n = 0;
nsz dda49c
	sep = "";
nsz dda49c
	for (; map->str; map++) {
nsz dda49c
		if (map->val && (flags & map->val) == map->val) {
Szabolcs Nagy fd0899
			n += sprintf(buf+n, "%s%s", sep, map->str);
nsz dda49c
			sep = "|";
nsz dda49c
			flags &= ~(map->val);
nsz dda49c
		}
nsz dda49c
	}
nsz 462b4f
	if (flags)
nsz 462b4f
		sprintf(buf, "%sunknown=%#x", sep, flags);
nsz 462b4f
	return buf;
nsz dda49c
}
nsz dda49c
nsz dda49c
/* tests harness adapted from glibc testfnm.c */
nsz dda49c
struct {
nsz dda49c
	const char *pattern;
nsz dda49c
	const char *string;
nsz dda49c
	int flags;
nsz dda49c
	int expected;
nsz dda49c
} tests[] = {
nsz dda49c
	/* begin dietlibc tests */
nsz dda49c
	{ "*.c", "foo.c", 0, 0 },
nsz dda49c
	{ "*.c", ".c", 0, 0 },
nsz dda49c
	{ "*.a", "foo.c", 0, FNM_NOMATCH },
nsz dda49c
	{ "*.c", ".foo.c", 0, 0 },
nsz dda49c
	{ "*.c", ".foo.c", FNM_PERIOD, FNM_NOMATCH },
nsz dda49c
	{ "*.c", "foo.c", FNM_PERIOD, 0 },
nsz dda49c
	{ "a\\*.c", "a*.c", FNM_NOESCAPE, FNM_NOMATCH },
nsz dda49c
	{ "a\\*.c", "ax.c", 0, FNM_NOMATCH },
nsz dda49c
	{ "a[xy].c", "ax.c", 0, 0 },
nsz dda49c
	{ "a[!y].c", "ax.c", 0, 0 },
nsz dda49c
	{ "a[a/z]*.c", "a/x.c", FNM_PATHNAME, FNM_NOMATCH },
nsz dda49c
	{ "a/*.c", "a/x.c", FNM_PATHNAME, 0 },
nsz dda49c
	{ "a*.c", "a/x.c", FNM_PATHNAME, FNM_NOMATCH },
nsz dda49c
	{ "*/foo", "/foo", FNM_PATHNAME, 0 },
nsz dda49c
	{ "-O[01]", "-O1", 0, 0 },
nsz dda49c
	{ "[[?*\\]", "\\", 0, 0 },
nsz dda49c
	{ "[]?*\\]", "]", 0, 0 },
nsz dda49c
	/* initial right-bracket tests */
nsz dda49c
	{ "[!]a-]", "b", 0, 0 },
nsz dda49c
	{ "[]-_]", "^", 0, 0 }, /* range: ']', '^', '_' */
nsz dda49c
	{ "[!]-_]", "X", 0, 0 },
nsz dda49c
	{ "??", "-", 0, FNM_NOMATCH },
nsz dda49c
	/* begin glibc tests */
nsz dda49c
	{ "*LIB*", "lib", FNM_PERIOD, FNM_NOMATCH },
nsz dda49c
	{ "a[/]b", "a/b", 0, 0 },
nsz dda49c
	{ "a[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH },
nsz dda49c
	{ "[a-z]/[a-z]", "a/b", 0, 0 },
nsz dda49c
	{ "*", "a/b", FNM_PATHNAME, FNM_NOMATCH },
nsz dda49c
	{ "*[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH },
nsz dda49c
	{ "*[b]", "a/b", FNM_PATHNAME, FNM_NOMATCH },
nsz dda49c
	{ "[*]/b", "a/b", 0, FNM_NOMATCH },
nsz dda49c
	{ "[*]/b", "*/b", 0, 0 },
nsz dda49c
	{ "[?]/b", "a/b", 0, FNM_NOMATCH },
nsz dda49c
	{ "[?]/b", "?/b", 0, 0 },
nsz dda49c
	{ "[[a]/b", "a/b", 0, 0 },
nsz dda49c
	{ "[[a]/b", "[/b", 0, 0 },
nsz dda49c
	{ "\\*/b", "a/b", 0, FNM_NOMATCH },
nsz dda49c
	{ "\\*/b", "*/b", 0, 0 },
nsz dda49c
	{ "\\?/b", "a/b", 0, FNM_NOMATCH },
nsz dda49c
	{ "\\?/b", "?/b", 0, 0 },
nsz 80371a
	{ "[/b", "[/b", 0, 0 },
nsz dda49c
	{ "\\[/b", "[/b", 0, 0 },
nsz dda49c
	{ "??""/b", "aa/b", 0, 0 },
nsz dda49c
	{ "???b", "aa/b", 0, 0 },
nsz dda49c
	{ "???b", "aa/b", FNM_PATHNAME, FNM_NOMATCH },
nsz dda49c
	{ "?a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
nsz dda49c
	{ "a/?b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
nsz dda49c
	{ "*a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
nsz dda49c
	{ "a/*b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
nsz dda49c
	{ "[.]a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
nsz dda49c
	{ "a/[.]b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
nsz dda49c
	{ "*/?", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 },
nsz dda49c
	{ "?/*", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 },
nsz dda49c
	{ ".*/?", ".a/b", FNM_PATHNAME|FNM_PERIOD, 0 },
nsz dda49c
	{ "*/.?", "a/.b", FNM_PATHNAME|FNM_PERIOD, 0 },
nsz dda49c
	{ "*/*", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH },
nsz dda49c
	{ "*?*/*", "a/.b", FNM_PERIOD, 0 },
nsz dda49c
	{ "*[.]/b", "a./b", FNM_PATHNAME|FNM_PERIOD, 0 },
nsz dda49c
	{ "*[[:alpha:]]/*[[:alnum:]]", "a/b", FNM_PATHNAME, 0 },
nsz dda49c
	/* These three tests should result in error according to SUSv3.
nsz dda49c
	 * See XCU 2.13.1, XBD 9.3.5, & fnmatch() */
nsz dda49c
	{ "*[![:digit:]]*/[![:d-d]", "a/b", FNM_PATHNAME, -FNM_NOMATCH },
nsz dda49c
	{ "*[![:digit:]]*/[[:d-d]", "a/[", FNM_PATHNAME, -FNM_NOMATCH },
nsz dda49c
	{ "*[![:digit:]]*/[![:d-d]", "a/[", FNM_PATHNAME, -FNM_NOMATCH },
nsz dda49c
	{ "a?b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 },
nsz dda49c
	{ "a*b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 },
nsz dda49c
	{ "a[.]b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 },
Szabolcs Nagy fd0899
Szabolcs Nagy fd0899
	/* posix 2008 is unclear about these cases */
Szabolcs Nagy fd0899
	{ "\\", "\\", 0, 0 },
Szabolcs Nagy fd0899
	{ "\\", "", 0, FNM_NOMATCH },
Szabolcs Nagy fd0899
Szabolcs Nagy fd0899
	/* musl bug fixed in da0fcdb8e913ca7cdf8931328f2b37e93309b2c5 */
Szabolcs Nagy fd0899
	{ "/", "\0", FNM_PATHNAME, FNM_NOMATCH },
Szabolcs Nagy fd0899
	/* musl bug fixed in 6ec82a3b58ee1b873ff0dfad8fa9d41c3d25dcc0 */
Szabolcs Nagy fd0899
	{ "\\/", "/", FNM_PATHNAME, 0 },
Szabolcs Nagy b66768
Szabolcs Nagy b66768
#ifdef FNM_CASEFOLD
Szabolcs Nagy b66768
	{ "a", "A", FNM_CASEFOLD, 0 },
Szabolcs Nagy b66768
	{ "aaAA", "AaAa", FNM_CASEFOLD, 0 },
Szabolcs Nagy b66768
	{ "[a]", "A", FNM_CASEFOLD, 0 },
Szabolcs Nagy b66768
	{ "[!a]", "A", FNM_CASEFOLD, FNM_NOMATCH },
Szabolcs Nagy b66768
	{ "[!A-C]", "b", FNM_CASEFOLD, FNM_NOMATCH },
Szabolcs Nagy b66768
	{ "[!a-c]", "B", FNM_CASEFOLD, FNM_NOMATCH },
Szabolcs Nagy b66768
	{ "[!a-c]", "d", FNM_CASEFOLD, 0 },
Szabolcs Nagy b66768
#endif
nsz dda49c
};
nsz dda49c
nsz 462b4f
int main(void)
nsz 462b4f
{
nsz dda49c
	int i;
nsz dda49c
nsz dda49c
	for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
nsz dda49c
		int r, x;
nsz dda49c
nsz dda49c
		r = fnmatch(tests[i].pattern, tests[i].string, tests[i].flags);
nsz dda49c
		x = tests[i].expected;
nsz dda49c
		if (r != x && (r != FNM_NOMATCH || x != -FNM_NOMATCH)) {
Szabolcs Nagy cfa23c
			t_error("fnmatch(\"%s\", \"%s\", %s) failed, got %d want %d\n",
nsz 462b4f
				tests[i].pattern, tests[i].string,
nsz 462b4f
				flagstr(fnmatch_flags, tests[i].flags),
nsz 462b4f
				r, x);
nsz dda49c
		}
nsz dda49c
	}
Szabolcs Nagy cfa23c
	return t_status;
nsz dda49c
}