summaryrefslogtreecommitdiff
path: root/src/fnmatch
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2020-08-14 10:01:36 -0400
committerJakob Kaivo <jkk@ung.org>2020-08-14 10:01:36 -0400
commit345de6edfce3cc49e897ad216602138739794b09 (patch)
tree89be40026dbc0b49279b7b7afa01045ebb4da339 /src/fnmatch
parentc41846b9b95645357be10bf30b89791e4319bf16 (diff)
first draft, still missing quite a few bits
Diffstat (limited to 'src/fnmatch')
-rw-r--r--src/fnmatch/fnmatch.c93
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)
*/
-