summaryrefslogtreecommitdiffstats
path: root/usr/klibc/fnmatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/klibc/fnmatch.c')
-rw-r--r--usr/klibc/fnmatch.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/usr/klibc/fnmatch.c b/usr/klibc/fnmatch.c
new file mode 100644
index 0000000..5d0a25f
--- /dev/null
+++ b/usr/klibc/fnmatch.c
@@ -0,0 +1,72 @@
+/*
+ * fnmatch.c
+ *
+ * Original implementation by Kay Sievers, modified by H. Peter Anvin.
+ */
+
+#include <fnmatch.h>
+
+int fnmatch(const char *p, const char *s, int flags)
+{
+ if (flags & FNM_PATHNAME && *s == '/')
+ return (*p != '/') || fnmatch(p+1, s+1, flags);
+ if (flags & FNM_PERIOD && *s == '.')
+ return (*p != '.') || fnmatch(p+1, s+1, flags);
+
+ flags &= ~FNM_PERIOD; /* Only applies at beginning */
+
+ if (!(flags & FNM_NOESCAPE) && *p == '\\') {
+ p++;
+ return (*p != *s) || fnmatch(p+1, s+1, flags);
+ }
+
+ if (*s == '\0') {
+ while (*p == '*')
+ p++;
+ return (*p != '\0');
+ }
+
+ switch (*p) {
+ case '[':
+ {
+ int not = 0;
+ p++;
+ if (*p == '!') {
+ not = 1;
+ p++;
+ }
+ while ((*p != '\0') && (*p != ']')) {
+ int match = 0;
+ if (p[1] == '-') {
+ if ((*s >= *p) && (*s <= p[2]))
+ match = 1;
+ p += 3;
+ } else {
+ match = (*p == *s);
+ p++;
+ }
+ if (match ^ not) {
+ while ((*p != '\0') && (*p != ']'))
+ p++;
+ if (*p == ']')
+ return fnmatch(p+1, s+1, flags);
+ }
+ }
+ }
+ break;
+ case '*':
+ if (fnmatch(p, s+1, flags))
+ return fnmatch(p+1, s, flags);
+ return 0;
+ case '\0':
+ if (*s == '\0') {
+ return 0;
+ }
+ break;
+ default:
+ if ((*p == *s) || (*p == '?'))
+ return fnmatch(p+1, s+1, flags);
+ break;
+ }
+ return 1;
+}