From ede052ddd4c753c9d09863b541ad7e2379b41899 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 20 Apr 2016 21:35:21 -0700 Subject: Integrating fnmatch. * configure: new test for fnmatch, introducing HAVE_FNMATCH configure variable into config/config.h. * sysif.c (fnmatch_wrap): New function. (sysif_init): Register intrinsic variables fnm-pathname, fnm-noescape, fnm-period, fnm-leading-dir, fnm-casefold and fnm-extmatch. Register intrinsic function fnmatch. * txr.1: Documented. --- configure | 20 ++++++++++++++++++++ sysif.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ txr.1 | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) 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 < + +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 #endif +#if HAVE_FNMATCH +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#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 +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 -- cgit v1.2.3