aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extension/ChangeLog6
-rw-r--r--extension/Makefile.am3
-rw-r--r--extension/Makefile.in20
-rw-r--r--extension/configh.in6
-rwxr-xr-xextension/configure4
-rw-r--r--extension/configure.ac4
-rw-r--r--extension/fnmatch.c175
-rw-r--r--test/ChangeLog5
-rw-r--r--test/Makefile.am4
-rw-r--r--test/Makefile.in9
-rw-r--r--test/Maketests5
-rw-r--r--test/fnmatch.awk10
-rw-r--r--test/fnmatch.ok9
13 files changed, 250 insertions, 10 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 2ea13e36..4eab7d7a 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,9 @@
+2012-07-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * fnmatch.c: New file.
+ * Makefile.am: Build fnmatch extension.
+ * configure.ac: Look for fnmatch.h and fnmatch function.
+
2012-07-11 Arnold D. Robbins <arnold@skeeve.com>
* filefuncs.c (array_set, do_stat): Use make_const_string.
diff --git a/extension/Makefile.am b/extension/Makefile.am
index 5c6532b4..abe778e2 100644
--- a/extension/Makefile.am
+++ b/extension/Makefile.am
@@ -33,6 +33,7 @@ ACLOCAL_AMFLAGS = -I m4
pkgextension_LTLIBRARIES = \
filefuncs.la \
+ fnmatch.la \
fork.la \
ordchr.la \
readfile.la \
@@ -44,6 +45,8 @@ MY_MODULE_FLAGS = -module -avoid-version -no-undefined
filefuncs_la_SOURCES = filefuncs.c
filefuncs_la_LDFLAGS = $(MY_MODULE_FLAGS)
+fnmatch_la_SOURCES = fnmatch.c
+fnmatch_la_LDFLAGS = $(MY_MODULE_FLAGS)
fork_la_SOURCES = fork.c
fork_la_LDFLAGS = $(MY_MODULE_FLAGS)
ordchr_la_SOURCES = ordchr.c
diff --git a/extension/Makefile.in b/extension/Makefile.in
index 1747bcdb..71920fec 100644
--- a/extension/Makefile.in
+++ b/extension/Makefile.in
@@ -136,6 +136,12 @@ filefuncs_la_OBJECTS = $(am_filefuncs_la_OBJECTS)
filefuncs_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(filefuncs_la_LDFLAGS) $(LDFLAGS) -o $@
+fnmatch_la_LIBADD =
+am_fnmatch_la_OBJECTS = fnmatch.lo
+fnmatch_la_OBJECTS = $(am_fnmatch_la_OBJECTS)
+fnmatch_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(fnmatch_la_LDFLAGS) $(LDFLAGS) -o $@
fork_la_LIBADD =
am_fork_la_OBJECTS = fork.lo
fork_la_OBJECTS = $(am_fork_la_OBJECTS)
@@ -185,11 +191,11 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(filefuncs_la_SOURCES) $(fork_la_SOURCES) \
- $(ordchr_la_SOURCES) $(readfile_la_SOURCES) \
+SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
+ $(fork_la_SOURCES) $(ordchr_la_SOURCES) $(readfile_la_SOURCES) \
$(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
-DIST_SOURCES = $(filefuncs_la_SOURCES) $(fork_la_SOURCES) \
- $(ordchr_la_SOURCES) $(readfile_la_SOURCES) \
+DIST_SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
+ $(fork_la_SOURCES) $(ordchr_la_SOURCES) $(readfile_la_SOURCES) \
$(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
@@ -340,6 +346,7 @@ ACLOCAL_AMFLAGS = -I m4
# Note: rwarray does not currently compile.
pkgextension_LTLIBRARIES = \
filefuncs.la \
+ fnmatch.la \
fork.la \
ordchr.la \
readfile.la \
@@ -350,6 +357,8 @@ pkgextension_LTLIBRARIES = \
MY_MODULE_FLAGS = -module -avoid-version -no-undefined
filefuncs_la_SOURCES = filefuncs.c
filefuncs_la_LDFLAGS = $(MY_MODULE_FLAGS)
+fnmatch_la_SOURCES = fnmatch.c
+fnmatch_la_LDFLAGS = $(MY_MODULE_FLAGS)
fork_la_SOURCES = fork.c
fork_la_LDFLAGS = $(MY_MODULE_FLAGS)
ordchr_la_SOURCES = ordchr.c
@@ -456,6 +465,8 @@ clean-pkgextensionLTLIBRARIES:
}
filefuncs.la: $(filefuncs_la_OBJECTS) $(filefuncs_la_DEPENDENCIES) $(EXTRA_filefuncs_la_DEPENDENCIES)
$(filefuncs_la_LINK) -rpath $(pkgextensiondir) $(filefuncs_la_OBJECTS) $(filefuncs_la_LIBADD) $(LIBS)
+fnmatch.la: $(fnmatch_la_OBJECTS) $(fnmatch_la_DEPENDENCIES) $(EXTRA_fnmatch_la_DEPENDENCIES)
+ $(fnmatch_la_LINK) -rpath $(pkgextensiondir) $(fnmatch_la_OBJECTS) $(fnmatch_la_LIBADD) $(LIBS)
fork.la: $(fork_la_OBJECTS) $(fork_la_DEPENDENCIES) $(EXTRA_fork_la_DEPENDENCIES)
$(fork_la_LINK) -rpath $(pkgextensiondir) $(fork_la_OBJECTS) $(fork_la_LIBADD) $(LIBS)
ordchr.la: $(ordchr_la_OBJECTS) $(ordchr_la_DEPENDENCIES) $(EXTRA_ordchr_la_DEPENDENCIES)
@@ -476,6 +487,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filefuncs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnmatch.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fork.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ordchr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readfile.Plo@am__quote@
diff --git a/extension/configh.in b/extension/configh.in
index 519f8ea3..179b5863 100644
--- a/extension/configh.in
+++ b/extension/configh.in
@@ -3,6 +3,12 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
+/* Define to 1 if you have the `fnmatch' function. */
+#undef HAVE_FNMATCH
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
/* Define to 1 if you have the `GetSystemTimeAsFileTime' function. */
#undef HAVE_GETSYSTEMTIMEASFILETIME
diff --git a/extension/configure b/extension/configure
index 30b162a8..301e3418 100755
--- a/extension/configure
+++ b/extension/configure
@@ -11462,7 +11462,7 @@ then
CFLAGS="$CFLAGS -Wall -Wextra"
fi
-for ac_header in time.h sys/time.h sys/select.h
+for ac_header in fnmatch.h time.h sys/time.h sys/select.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -11476,7 +11476,7 @@ fi
done
-for ac_func in nanosleep select gettimeofday GetSystemTimeAsFileTime
+for ac_func in fnmatch gettimeofday nanosleep select GetSystemTimeAsFileTime
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/extension/configure.ac b/extension/configure.ac
index 838350cf..160d55d8 100644
--- a/extension/configure.ac
+++ b/extension/configure.ac
@@ -45,9 +45,9 @@ then
CFLAGS="$CFLAGS -Wall -Wextra"
fi
-AC_CHECK_HEADERS(time.h sys/time.h sys/select.h)
+AC_CHECK_HEADERS(fnmatch.h time.h sys/time.h sys/select.h)
-AC_CHECK_FUNCS(nanosleep select gettimeofday GetSystemTimeAsFileTime)
+AC_CHECK_FUNCS(fnmatch gettimeofday nanosleep select GetSystemTimeAsFileTime)
dnl checks for compiler characteristics
AC_C_INLINE
diff --git a/extension/fnmatch.c b/extension/fnmatch.c
new file mode 100644
index 00000000..7f050dcd
--- /dev/null
+++ b/extension/fnmatch.c
@@ -0,0 +1,175 @@
+/*
+ * fnmatch.c - Provide an interface to fnmatch(3) routine
+ *
+ * Arnold Robbins
+ * arnold@skeeve.com
+ * Written 7/2012
+ */
+
+/*
+ * Copyright (C) 2012 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "config.h"
+#include "gawkapi.h"
+
+#ifdef HAVE_FNMATCH_H
+#define _GNU_SOURCE 1 /* use GNU extensions if they're there */
+#include <fnmatch.h>
+#endif
+
+/* Provide GNU extensions as no-ops if not defined */
+#ifndef FNM_CASEFOLD
+#define FNM_CASEFOLD 0
+#endif
+#ifndef FNM_LEADING_DIR
+#define FNM_LEADING_DIR 0
+#endif
+#ifndef FNM_FILE_NAME
+#define FNM_FILE_NAME 0
+#endif
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+
+static awk_bool_t init_fnmatch(void);
+static awk_bool_t (*init_func)(void) = init_fnmatch;
+
+int plugin_is_GPL_compatible;
+
+
+/* do_fnmatch --- implement the fnmatch interface */
+
+static awk_value_t *
+do_fnmatch(int nargs, awk_value_t *result)
+{
+ static int flags_mask =
+ FNM_CASEFOLD | FNM_FILE_NAME |
+ FNM_LEADING_DIR | FNM_NOESCAPE |
+ FNM_PATHNAME | FNM_PERIOD ;
+ awk_value_t pattern, string, flags;
+ int int_flags, retval;
+
+ make_number(-1.0, result); /* default return */
+#ifdef HAVE_FNMATCH
+ if (nargs < 3) {
+ warning(ext_id, "fnmatch: called with less than three arguments");
+ goto out;
+ } else if (do_lint && nargs > 3)
+ lintwarn(ext_id, "fnmatch: called with more than three arguments");
+
+ if (! get_argument(0, AWK_STRING, & pattern)) {
+ warning(ext_id, "fnmatch: could not get first argument");
+ goto out;
+ }
+
+ if (! get_argument(1, AWK_STRING, & string)) {
+ warning(ext_id, "fnmatch: could not get second argument");
+ goto out;
+ }
+
+ if (! get_argument(2, AWK_NUMBER, & flags)) {
+ warning(ext_id, "fnmatch: could not get third argument");
+ goto out;
+ }
+
+ int_flags = flags.num_value;
+ int_flags &= flags_mask;
+
+ retval = fnmatch(pattern.str_value.str,
+ string.str_value.str, int_flags);
+ make_number((double) retval, result);
+
+out:
+#else
+ fatal(ext_id, "fnmatch is not implemented on this system\n");
+#endif
+ return result;
+}
+
+static struct fnmflags {
+ const char *name;
+ int value;
+} flagtable[] = {
+ { "CASEFOLD", FNM_CASEFOLD },
+ { "FILE_NAME", FNM_FILE_NAME },
+ { "LEADING_DIR", FNM_LEADING_DIR },
+ { "NOESCAPE", FNM_NOESCAPE },
+ { "PATHNAME", FNM_PATHNAME },
+ { "PERIOD", FNM_PERIOD },
+ { NULL, 0 }
+};
+
+/* init_fnmatch --- load array with flags */
+
+static awk_bool_t
+init_fnmatch(void)
+{
+ int errors = 0;
+#ifdef HAVE_FNMATCH
+ awk_value_t index, value, the_array;
+ awk_array_t new_array;
+ int i;
+
+ if (! sym_update("FNM_NOMATCH", make_number(FNM_NOMATCH, & value))) {
+ warning(ext_id, "fnmatch init: could not add FNM_NOMATCH variable");
+ errors++;
+ }
+
+ new_array = create_array();
+ for (i = 0; flagtable[i].name != NULL; i++) {
+ (void) make_const_string(flagtable[i].name,
+ strlen(flagtable[i].name), & index);
+ (void) make_number(flagtable[i].value, & value);
+ if (! set_array_element(new_array, & index, & value)) {
+ warning(ext_id, "fnmatch init: could not set array element %s",
+ flagtable[i].name);
+ errors++;
+ }
+ }
+
+ the_array.val_type = AWK_ARRAY;
+ the_array.array_cookie = new_array;
+
+ if (! sym_update("FNM", & the_array)) {
+ warning(ext_id, "fnmatch init: could not install FNM array");
+ errors++;
+ }
+
+#endif
+ return errors == 0;
+}
+
+static awk_ext_func_t func_table[] = {
+ { "fnmatch", do_fnmatch, 3 },
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, fnmatch, "")
diff --git a/test/ChangeLog b/test/ChangeLog
index 057434f9..019d2f34 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (fnmatch): New test.
+ * fnmatch.awk, fnmatch.ok: New files.
+
2012-06-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
* time.awk: Avoid possibly throwing a spurious error by protecting
diff --git a/test/Makefile.am b/test/Makefile.am
index 58fddfc0..a244c6a0 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -230,6 +230,8 @@ EXTRA_DIST = \
fnasgnm.awk \
fnasgnm.in \
fnasgnm.ok \
+ fnmatch.awk \
+ fnmatch.ok \
fnmisc.awk \
fnmisc.ok \
fnparydl.awk \
@@ -889,7 +891,7 @@ LOCALE_CHARSET_TESTS = \
mbprintf1 mbprintf2 mbprintf3 rebt8b2 rtlenmb sort1 sprintfc
SHLIB_TESTS = \
- filefuncs fork fork2 ordchr ordchr2 readfile rwarray \
+ fnmatch filefuncs fork fork2 ordchr ordchr2 readfile rwarray \
testext time
# List of the tests which should be run with --lint option:
diff --git a/test/Makefile.in b/test/Makefile.in
index 3e170f84..61e32b1b 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -442,6 +442,8 @@ EXTRA_DIST = \
fnasgnm.awk \
fnasgnm.in \
fnasgnm.ok \
+ fnmatch.awk \
+ fnmatch.ok \
fnmisc.awk \
fnmisc.ok \
fnparydl.awk \
@@ -1097,7 +1099,7 @@ LOCALE_CHARSET_TESTS = \
mbprintf1 mbprintf2 mbprintf3 rebt8b2 rtlenmb sort1 sprintfc
SHLIB_TESTS = \
- filefuncs fork fork2 ordchr ordchr2 readfile rwarray \
+ fnmatch filefuncs fork fork2 ordchr ordchr2 readfile rwarray \
testext time
@@ -3174,6 +3176,11 @@ sprintfc:
@AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+fnmatch:
+ @echo $@
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
filefuncs:
@echo $@
@AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/Maketests b/test/Maketests
index b10e1756..0a4e5820 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -1199,6 +1199,11 @@ sprintfc:
@AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+fnmatch:
+ @echo $@
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
filefuncs:
@echo $@
@AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/fnmatch.awk b/test/fnmatch.awk
new file mode 100644
index 00000000..e8ef9377
--- /dev/null
+++ b/test/fnmatch.awk
@@ -0,0 +1,10 @@
+@load "fnmatch"
+
+BEGIN {
+ print "FNM_NOMATCH =", FNM_NOMATCH
+ for (i in FNM)
+ printf("FNM[\"%s\"] = %d\n", i, FNM[i])
+
+ printf("fnmatch(\"*.a\", \"foo.a\", 0) = %d\n", fnmatch("*.a", "foo.a", 0) )
+ printf("fnmatch(\"*.a\", \"foo.c\", 0) = %d\n", fnmatch("*.a", "foo.c", 0))
+}
diff --git a/test/fnmatch.ok b/test/fnmatch.ok
new file mode 100644
index 00000000..cc17c6b1
--- /dev/null
+++ b/test/fnmatch.ok
@@ -0,0 +1,9 @@
+FNM_NOMATCH = 1
+FNM["LEADING_DIR"] = 8
+FNM["CASEFOLD"] = 16
+FNM["NOESCAPE"] = 2
+FNM["PERIOD"] = 4
+FNM["PATHNAME"] = 1
+FNM["FILE_NAME"] = 1
+fnmatch("*.a", "foo.a", 0) = 0
+fnmatch("*.a", "foo.c", 0) = 1