summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure20
-rw-r--r--sysif.c53
-rw-r--r--txr.154
3 files changed, 127 insertions, 0 deletions
diff --git a/configure b/configure
index 4293fb21..b098c717 100755
--- a/configure
+++ b/configure
@@ -2135,6 +2135,26 @@ else
printf "no\n"
fi
+printf "Checking for fnmatch ... "
+
+cat > conftest.c <<!
+#include <fnmatch.h>
+
+int main(int argc, char *argv[])
+{
+ int res = fnmatch("*.txr", "foo.txr", FNM_PATHNAME);
+ return 0;
+}
+!
+
+if conftest ; then
+ printf "yes\n"
+ printf "#define HAVE_FNMATCH 1\n" >> $config_h
+ have_ftw=y
+else
+ printf "no\n"
+fi
+
printf "Checking for windres ... "
if output=$(windres -V 2> /dev/null) ; then
diff --git a/sysif.c b/sysif.c
index 1b9b07d3..70185a49 100644
--- a/sysif.c
+++ b/sysif.c
@@ -61,6 +61,12 @@
#if HAVE_GRGID
#include <grp.h>
#endif
+#if HAVE_FNMATCH
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <fnmatch.h>
+#endif
#include ALLOCA_H
#include "lib.h"
#include "stream.h"
@@ -1214,6 +1220,28 @@ val stdio_fseek(FILE *f, val off, int whence)
#endif
}
+#if HAVE_FNMATCH
+static val fnmatch_wrap(val pattern, val string, val flags)
+{
+ const wchar_t *pattern_ws = c_str(pattern);
+ const wchar_t *string_ws = c_str(string);
+ cnum c_flags = c_num(default_arg(flags, zero));
+ char *pattern_u8 = utf8_dup_to(pattern_ws);
+ char *string_u8 = utf8_dup_to(string_ws);
+ int res = fnmatch(pattern_u8, string_u8, c_flags);
+ free(string_u8);
+ free(pattern_u8);
+ switch (res) {
+ case 0:
+ return t;
+ case FNM_NOMATCH:
+ return nil;
+ default:
+ uw_throwf(error_s, lit("fnmatch: error ~a"), num(res), nao);
+ }
+}
+#endif
+
void sysif_init(void)
{
stat_s = intern(lit("stat"), user_package);
@@ -1493,4 +1521,29 @@ void sysif_init(void)
#if HAVE_SYS_STAT
reg_fun(intern(lit("umask"), user_package), func_n1(umask_wrap));
#endif
+
+#if HAVE_FNMATCH
+ reg_fun(intern(lit("fnmatch"), user_package), func_n3o(fnmatch_wrap, 2));
+#endif
+
+#if HAVE_FNMATCH
+#ifdef FNM_PATHNAME
+ reg_varl(intern(lit("fnm-pathname"), user_package), num_fast(FNM_PATHNAME));
+#endif
+#ifdef FNM_NOESCAPE
+ reg_varl(intern(lit("fnm-noescape"), user_package), num_fast(FNM_NOESCAPE));
+#endif
+#ifdef FNM_PERIOD
+ reg_varl(intern(lit("fnm-period"), user_package), num_fast(FNM_PERIOD));
+#endif
+#ifdef FNM_LEADING_DIR
+ reg_varl(intern(lit("fnm-leading-dir"), user_package), num_fast(FNM_LEADING_DIR));
+#endif
+#ifdef FNM_CASEFOLD
+ reg_varl(intern(lit("fnm-casefold"), user_package), num_fast(FNM_CASEFOLD));
+#endif
+#ifdef FNM_ESTMATCH
+ reg_varl(intern(lit("fnm-extmatch"), user_package), num_fast(FNM_EXTMATCH));
+#endif
+#endif
}
diff --git a/txr.1 b/txr.1
index 42558296..5c68b8f6 100644
--- a/txr.1
+++ b/txr.1
@@ -37777,6 +37777,9 @@ On platforms where the POSIX
.code glob
function is available \*(TX provides this functionality in
the form of a like-named function, and some numeric constants.
+\*(TX also provides access the
+.code fnmatch
+function, where available.
.coNP Variables @, glob-err @, glob-mark @, glob-nosort @, glob-nocheck @, glob-noescape @, glob-period @, glob-altdirfunc @, glob-brace @, glob-nomagic @, glob-tilde @ glob-tilde-check and @ glob-onlydir
@@ -37873,6 +37876,57 @@ function, and the meaning of all the
.meta flags
arguments are given in the documentation for the C function.
+.coNP Variables @, fnm-pathname @, fnm-noescape @, fnm-period @, fnm-leading-dir @ fnm-casefold and @ fnm-extmatch
+
+These variables take on the values of the corresponding C preprocessor
+constants from the
+.code <fnmatch.h>
+header:
+.codn FNM_PATHNAME ,
+.codn FNM_NOESCAPE ,
+.codn FNM_PERIOD ,
+etc.
+
+These values are bit masks which may be combined with the
+.code logior
+function to form the optional third
+.meta flags
+argument of the
+.code fnmatch
+function.
+
+Note that the
+.codn fnm-leading-dir ,
+.code fnm-case-fold
+and
+.code fnm-extmatch
+may not be available. They are GNU extensions, found in the GNU C library.
+
+.coNP Function @ fnmatch
+.synb
+.mets (fnmatch < pattern < string <> [ flags ]])
+.syne
+.desc
+The
+.code fnmatch
+function, if available, provides access
+to the like-named POSIX C library function.
+The
+.meta pattern
+argument specifies a POSIX-shell-style file pattern matching expression.
+Its exact features and dialect are controlled by
+.metn flags .
+If
+.meta string
+matches
+.meta pattern
+then
+.code t
+is returned. If there is no match, then
+.code nil
+is returned. If the C function indicates that an error has occurred,
+an exception is thrown.
+
.SS* Unix Filesystem Traversal
On platforms where the POSIX