diff options
author | Jakob Kaivo <jkk@ung.org> | 2020-08-14 10:01:36 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2020-08-14 10:01:36 -0400 |
commit | 345de6edfce3cc49e897ad216602138739794b09 (patch) | |
tree | 89be40026dbc0b49279b7b7afa01045ebb4da339 /src/fnmatch | |
parent | c41846b9b95645357be10bf30b89791e4319bf16 (diff) |
first draft, still missing quite a few bits
Diffstat (limited to 'src/fnmatch')
-rw-r--r-- | src/fnmatch/fnmatch.c | 93 |
1 files changed, 85 insertions, 8 deletions
diff --git a/src/fnmatch/fnmatch.c b/src/fnmatch/fnmatch.c index 09559c96..3453d64f 100644 --- a/src/fnmatch/fnmatch.c +++ b/src/fnmatch/fnmatch.c @@ -1,22 +1,99 @@ #include <fnmatch.h> +#include "string.h" #include "_assert.h" int fnmatch(const char * pattern, const char * string, int flags) { - (void)pattern; - (void)string; - (void)flags; ASSERT_NONNULL(pattern); ASSERT_NONNULL(string); /* __ASSERT_FLAGS(flags, FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD); */ - /* - const char *ppos = pattern; - const char *spos = string; - */ + const int period = flags & FNM_PERIOD; + const int pathname = flags & FNM_PATHNAME; + const int noescape = flags & FNM_NOESCAPE; + char last = '/'; + + while (*pattern && *string) { + if (*pattern == '?') { + pattern++; + if (pathname && *string == '/') { + return FNM_NOMATCH; + } + + if (period && *string == '.') { + if (pathname && !(last == '/')) { + return FNM_NOMATCH; + } + /* TODO: period & !pathname */ + } + + last = *string; + string++; + + continue; + } + + if (*pattern == '[') { + char *ket = strchr(pattern, ']'); + if (ket) { + /* TODO: FNM_PATHNAME */ + /* TODO: FNM_PERIOD */ + /* match all or none */ + pattern = ket + 1; + if (0) { + return FNM_NOMATCH; + } + + last = *string; + string++; + continue; + } + /* match a literal bracket, handled by main branch */ + } + + if (*pattern == '*') { + /* multiple * is the same as one * */ + while (*pattern == '*') { + pattern++; + } + + /* TODO: period and pathname */ + if (*pattern == '\0') { + return 0; + } + + while (*string) { + /* TODO: period and pathname */ + if (fnmatch(pattern, string, flags) == 0) { + return 0; + } + string++; + } + return FNM_NOMATCH; + } + + if (*pattern == '\\' && !noescape) { + pattern++; + if (*string != *pattern) { + return FNM_NOMATCH; + } + } + + if (*pattern != *string) { + return FNM_NOMATCH; + } + + last = *string; + pattern++; + string++; + } + + if (*pattern || *string) { + return FNM_NOMATCH; + } return 0; } + /* POSIX(2) */ - |