summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md10
-rw-r--r--lib.c29
2 files changed, 38 insertions, 1 deletions
diff --git a/README.md b/README.md
index b732b1e..210c75c 100644
--- a/README.md
+++ b/README.md
@@ -1138,3 +1138,13 @@ regexp('foo.*bar', 'is'); // equivalent to /foo.*bar/is
regexp('foo.*bar', 'x'); // throws "Type error: Unrecognized flag character 'x'"
regexp('foo.*('); // throws "Syntax error: Unmatched ( or \("
```
+
+#### 6.59. `wildcard(subject, pattern[, nocase])`
+
+Match the given subject against the supplied wildcard (file glob) pattern.
+
+If a truish value is supplied as 3rd argument, case insensitive matching is
+performed. If a non-string value is supplied as subject, it is converted into
+a string before being matched.
+
+Returns `true` when the subject matches the pattern or `false` when not.
diff --git a/lib.c b/lib.c
index a24ed23..e6b7135 100644
--- a/lib.c
+++ b/lib.c
@@ -30,6 +30,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <fnmatch.h>
#include "lexer.h"
#include "compiler.h"
@@ -2525,6 +2526,31 @@ uc_regexp(uc_vm *vm, size_t nargs)
return regex;
}
+static uc_value_t *
+uc_wildcard(uc_vm *vm, size_t nargs)
+{
+ uc_value_t *subject = uc_get_arg(0);
+ uc_value_t *pattern = uc_get_arg(1);
+ uc_value_t *icase = uc_get_arg(2);
+ int flags = 0, rv;
+ bool freeable;
+ char *s;
+
+ if (!subject || ucv_type(pattern) != UC_STRING)
+ return NULL;
+
+ if (uc_val_is_truish(icase))
+ flags |= FNM_CASEFOLD;
+
+ s = uc_cast_string(vm, &subject, &freeable);
+ rv = fnmatch(ucv_string_get(pattern), s, flags);
+
+ if (freeable)
+ free(s);
+
+ return ucv_boolean_new(rv == 0);
+}
+
static const uc_cfunction_list functions[] = {
{ "chr", uc_chr },
{ "delete", uc_delete },
@@ -2577,7 +2603,8 @@ static const uc_cfunction_list functions[] = {
{ "sleep", uc_sleep },
{ "assert", uc_assert },
{ "render", uc_render },
- { "regexp", uc_regexp }
+ { "regexp", uc_regexp },
+ { "wildcard", uc_wildcard }
};