summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-01-11 22:17:15 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-01-11 22:17:15 -0800
commitf46b90032f7bdfee52b699726c42e2687b699a94 (patch)
treeb38b13d3b93cb3b7a2c05f6c38e2e69467c1e572
parent7578fba17d68b6822bd089a0224dd5e736c17365 (diff)
downloadtxr-f46b90032f7bdfee52b699726c42e2687b699a94.tar.gz
txr-f46b90032f7bdfee52b699726c42e2687b699a94.tar.bz2
txr-f46b90032f7bdfee52b699726c42e2687b699a94.zip
* glob.c: New file.
(glob_wrap, glob_init): New functions. (errfunc_thunk): New static function. * glob.h: New file. * txr.c (main): call glob_init if HAVE_GLOB is defined. * configure (have_glob): New variable. (gen_config_make): Add have_glob to config/config.make. Detect glob function and set have_glob, and add HAVE_GLOB to config/config.h. * Makefile (OBJS): Include glob.h if have_glob is "y". * genvim.txr: Scan glob.c for functions and variables also. * txr.1: Documented glob and glob-related variables.
-rw-r--r--ChangeLog21
-rw-r--r--Makefile1
-rwxr-xr-xconfigure30
-rw-r--r--genvim.txr2
-rw-r--r--glob.c104
-rw-r--r--glob.h28
-rw-r--r--txr.183
-rw-r--r--txr.c4
8 files changed, 272 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 2bdadd36..7da255e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
2015-01-11 Kaz Kylheku <kaz@kylheku.com>
+ * glob.c: New file.
+ (glob_wrap, glob_init): New functions.
+ (errfunc_thunk): New static function.
+
+ * glob.h: New file.
+
+ * txr.c (main): call glob_init if HAVE_GLOB is defined.
+
+ * configure (have_glob): New variable.
+ (gen_config_make): Add have_glob to config/config.make.
+ Detect glob function and set have_glob, and add
+ HAVE_GLOB to config/config.h.
+
+ * Makefile (OBJS): Include glob.h if have_glob is "y".
+
+ * genvim.txr: Scan glob.c for functions and variables also.
+
+ * txr.1: Documented glob and glob-related variables.
+
+2015-01-11 Kaz Kylheku <kaz@kylheku.com>
+
* Makefile (retest): New phony target for convenience.
2015-01-11 Kaz Kylheku <kaz@kylheku.com>
diff --git a/Makefile b/Makefile
index 8e1e2733..8cea7f4f 100644
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,7 @@ OBJS := txr.o lex.yy.o y.tab.o match.o lib.o regex.o gc.o unwind.o stream.o
OBJS += arith.o hash.o utf8.o filter.o eval.o rand.o combi.o sysif.o
OBJS-$(debug_support) += debug.o
OBJS-$(have_syslog) += syslog.o
+OBJS-$(have_glob) += glob.o
OBJS-$(have_posix_sigs) += signal.o
ifneq ($(have_git),)
diff --git a/configure b/configure
index 189ad171..20b92858 100755
--- a/configure
+++ b/configure
@@ -117,6 +117,7 @@ have_unistd=
have_sys_time=
have_timegm=
have_syslog=
+have_glob=
have_windows_h=
have_posix_sigs=
need_darwin_c_source=
@@ -623,6 +624,9 @@ conf_dir := $conf_dir
# do we compile in syslog support?
have_syslog := $have_syslog
+# do we compile in glob support?
+have_glob := $have_glob
+
# do we modern posix signal handling?
have_posix_sigs := $have_posix_sigs
@@ -1912,6 +1916,32 @@ else
printf "no\n"
fi
+printf "Checking for glob ... "
+
+cat > conftest.c <<!
+#include <glob.h>
+
+static int errfunc(const char *path, int err)
+{
+ return 0;
+}
+
+int main(void)
+{
+ glob_t gl;
+ int result = glob("*", GLOB_ERR, errfunc, &gl);
+ globfree(&gl);
+ return result;
+}
+!
+if conftest ; then
+ printf "yes\n"
+ printf "#define HAVE_GLOB 1\n" >> $config_h
+ have_glob=y
+else
+ printf "no\n"
+fi
+
#
# Dependent variables
#
diff --git a/genvim.txr b/genvim.txr
index 9d26544c..7bd1e3d7 100644
--- a/genvim.txr
+++ b/genvim.txr
@@ -7,7 +7,7 @@ static void dir_tables_init(void)
@(until)
}
@(end)
-@(next @(open-files '("eval.c" "rand.c" "signal.c" "stream.c" "gc.c"
+@(next @(open-files '("eval.c" "rand.c" "signal.c" "stream.c" "gc.c" "glob.c"
"syslog.c" "filter.c" "txr.c" "arith.c" "sysif.c")))
@(collect)
@ (block)
diff --git a/glob.c b/glob.c
new file mode 100644
index 00000000..c11b7f10
--- /dev/null
+++ b/glob.c
@@ -0,0 +1,104 @@
+/* Copyright 2015
+ * Kaz Kylheku <kaz@kylheku.com>
+ * Vancouver, Canada
+ * All rights reserved.
+ *
+ * Redistribution of this software in source and binary forms, with or without
+ * modification, is permitted provided that the following two conditions are met.
+ *
+ * Use of this software in any manner constitutes agreement with the disclaimer
+ * which follows the two conditions.
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DAMAGES, HOWEVER CAUSED,
+ * AND UNDER ANY THEORY OF LIABILITY, ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <wchar.h>
+#include <signal.h>
+#include <glob.h>
+#include "config.h"
+#include "lib.h"
+#include "hash.h"
+#include "gc.h"
+#include "signal.h"
+#include "unwind.h"
+#include "utf8.h"
+#include "eval.h"
+#include "glob.h"
+
+static val s_errfunc;
+
+static int errfunc_thunk(const char *errpath, int errcode)
+{
+ val result = funcall2(s_errfunc, string_utf8(errpath), num(errcode));
+ return result ? 1 : 0;
+}
+
+val glob_wrap(val pattern, val flags, val errfunc)
+{
+ char *pat_u8 = utf8_dup_to(c_str(pattern));
+ glob_t gl;
+
+ s_errfunc = default_bool_arg(errfunc);
+
+ (void) glob(pat_u8, c_num(default_arg(flags, zero)),
+ s_errfunc ? errfunc_thunk : 0, &gl);
+
+ {
+ int i;
+ list_collect_decl (out, ptail);
+
+ for (i = 0; i < gl.gl_pathc; i++)
+ ptail = list_collect (ptail, string_utf8(gl.gl_pathv[i]));
+
+ globfree(&gl);
+ return out;
+ }
+}
+
+void glob_init(void)
+{
+ prot1(&s_errfunc);
+ reg_fun(intern(lit("glob"), user_package), func_n3o(glob_wrap, 1));
+ reg_var(intern(lit("glob-err"), user_package), num_fast(GLOB_ERR));
+ reg_var(intern(lit("glob-mark"), user_package), num_fast(GLOB_MARK));
+ reg_var(intern(lit("glob-nosort"), user_package), num_fast(GLOB_NOSORT));
+ reg_var(intern(lit("glob-nocheck"), user_package), num_fast(GLOB_NOCHECK));
+ reg_var(intern(lit("glob-noescape"), user_package), num_fast(GLOB_NOESCAPE));
+#ifdef GLOB_PERIOD
+ reg_var(intern(lit("glob-period"), user_package), num_fast(GLOB_PERIOD));
+#endif
+#ifdef GLOB_ALTDIRFUNC
+ reg_var(intern(lit("glob-altdirfunc"), user_package), num_fast(GLOB_ALTDIRFUNC));
+#endif
+#ifdef GLOB_BRACE
+ reg_var(intern(lit("glob-brace"), user_package), num_fast(GLOB_BRACE));
+#endif
+#ifdef GLOB_NOMAGIC
+ reg_var(intern(lit("glob-nomagic"), user_package), num_fast(GLOB_NOMAGIC));
+#endif
+#ifdef GLOB_TILDE
+ reg_var(intern(lit("glob-tilde"), user_package), num_fast(GLOB_TILDE));
+#endif
+#ifdef GLOB_TILDE_CHECK
+ reg_var(intern(lit("glob-tilde-check"), user_package), num_fast(GLOB_TILDE_CHECK));
+#endif
+#ifdef GLOB_ONLYDIR
+ reg_var(intern(lit("glob-onlydir"), user_package), num_fast(GLOB_ONLYDIR));
+#endif
+}
diff --git a/glob.h b/glob.h
new file mode 100644
index 00000000..55a7cc1b
--- /dev/null
+++ b/glob.h
@@ -0,0 +1,28 @@
+/* Copyright 2015
+ * Kaz Kylheku <kaz@kylheku.com>
+ * Vancouver, Canada
+ * All rights reserved.
+ *
+ * Redistribution of this software in source and binary forms, with or without
+ * modification, is permitted provided that the following two conditions are met.
+ *
+ * Use of this software in any manner constitutes agreement with the disclaimer
+ * which follows the two conditions.
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DAMAGES, HOWEVER CAUSED,
+ * AND UNDER ANY THEORY OF LIABILITY, ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+val glob_wrap(val pattern, val flags, val errfunc);
+void glob_init(void);
diff --git a/txr.1 b/txr.1
index fb1b3c37..ab73733e 100644
--- a/txr.1
+++ b/txr.1
@@ -24167,6 +24167,89 @@ C function is currently not supported.
Note that syslog messages are not newline-terminated.
+.SS* Unix Path Globbing
+
+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.
+
+.coNP Special 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
+
+These variables take on the values of the corresponding C preprocessor
+constants from the
+.code <glob.h>
+header:
+.codn GLOB_ERR ,
+.codn GLOB_MARK ,
+.codn GLOB_NOSORT ,
+etc.
+
+These values are passed as the optional second argument of the
+.code glob
+function. They are bitmasks and so multiple values can be combined
+using the
+.code logior
+function.
+
+Note that the
+.codn glob-period ,
+.codn glob-altdirfunc ,
+.codn glob-brace ,
+.codn glob-nomagic ,
+.codn glob-tilde ,
+.code glob-tilde-check
+and
+.code glob-onlydir
+variables may not be avaiable. They are extensions in the GNU C library
+implementation of
+.codn glob .
+
+.coNP Function @ glob
+.synb
+.mets (glob < pattern >> [ flags <> [ error-func ]])
+.syne
+.desc
+The
+.code glob
+function is a interface to the Unix function of the same name.
+The
+.meta pattern
+argument must be a string, which holds a glob pattern: a pattern which
+matches zero or more path names, similar to a regular expression.
+The function tries to expand the pattern and return a list of strings
+representing the matching path names in the file system.
+
+If there are no matches, then an empty list is returned.
+
+The optional
+.meta flags
+argument defaults to zero. If given, it may be a bitwise combination of the
+values of the variables
+.codn glob-err ,
+.codn glob-mark ,
+.code glob-nosort
+and others.
+
+If the
+.meta error-func
+argument is specified, it gives a callback function which is invoked
+when
+.code glob
+encounters errors accessing paths. The function takes two arguments:
+the pathname and the
+.code errno
+value which occurred for that pathname. The function's return value is
+boolean. If the function returns true, then
+.code glob
+will terminate.
+
+Details of the semantics of the
+.code glob
+function, and the meaning of all the
+.meta flags
+arguments are given in the documentation for the C function.
+
.SS* Web Programming Support
.coNP Functions @ url-encode and @ url-decode
diff --git a/txr.c b/txr.c
index 84213c40..9e6fda27 100644
--- a/txr.c
+++ b/txr.c
@@ -50,6 +50,7 @@
#include "utf8.h"
#include "debug.h"
#include "syslog.h"
+#include "glob.h"
#include "eval.h"
#include "regex.h"
#include "arith.h"
@@ -297,6 +298,9 @@ int main(int argc, char **argv)
#if HAVE_SYSLOG
syslog_init();
#endif
+#if HAVE_GLOB
+ glob_init();
+#endif
sysroot_init();
return txr_main(argc, argv);
}