aboutsummaryrefslogtreecommitdiffstats
path: root/extension
diff options
context:
space:
mode:
Diffstat (limited to 'extension')
-rw-r--r--extension/ChangeLog5
-rw-r--r--extension/Makefile.am18
-rw-r--r--extension/Makefile.in47
-rw-r--r--extension/aclocal.m41
-rw-r--r--extension/configh.in11
-rwxr-xr-xextension/configure79
-rw-r--r--extension/configure.ac2
-rw-r--r--extension/m4/ChangeLog4
-rw-r--r--extension/m4/intlmacosx.m451
-rw-r--r--extension/readdir.3am17
-rw-r--r--extension/readdir.c24
-rw-r--r--extension/revoutput.c136
-rw-r--r--extension/revtwoway.c335
13 files changed, 705 insertions, 25 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog
index bc4b060b..0a15220a 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,8 @@
+2012-08-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * revoutput.c: New testing extension for output wrapper.
+ * Makefile.am: Build revoutput extension.
+
2012-08-08 Arnold D. Robbins <arnold@skeeve.com>
Add fts() to filefuncs.
diff --git a/extension/Makefile.am b/extension/Makefile.am
index bf9a715f..f7d939a4 100644
--- a/extension/Makefile.am
+++ b/extension/Makefile.am
@@ -38,6 +38,8 @@ pkgextension_LTLIBRARIES = \
ordchr.la \
readdir.la \
readfile.la \
+ revoutput.la \
+ revtwoway.la \
rwarray.la \
testext.la \
time.la
@@ -49,27 +51,43 @@ MY_LIBS = $(LIBINTL)
filefuncs_la_SOURCES = filefuncs.c stack.h stack.c
filefuncs_la_LDFLAGS = $(MY_MODULE_FLAGS)
filefuncs_la_LIBADD = $(MY_LIBS)
+
fnmatch_la_SOURCES = fnmatch.c
fnmatch_la_LDFLAGS = $(MY_MODULE_FLAGS)
fnmatch_la_LIBADD = $(MY_LIBS)
+
fork_la_SOURCES = fork.c
fork_la_LDFLAGS = $(MY_MODULE_FLAGS)
fork_la_LIBADD = $(MY_LIBS)
+
ordchr_la_SOURCES = ordchr.c
ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS)
ordchr_la_LIBADD = $(MY_LIBS)
+
readdir_la_SOURCES = readdir.c
readdir_la_LDFLAGS = $(MY_MODULE_FLAGS)
readdir_la_LIBADD = $(MY_LIBS)
+
readfile_la_SOURCES = readfile.c
readfile_la_LDFLAGS = $(MY_MODULE_FLAGS)
readfile_la_LIBADD = $(MY_LIBS)
+
+revoutput_la_SOURCES = revoutput.c
+revoutput_la_LDFLAGS = $(MY_MODULE_FLAGS)
+revoutput_la_LIBADD = $(MY_LIBS)
+
+revtwoway_la_SOURCES = revtwoway.c
+revtwoway_la_LDFLAGS = $(MY_MODULE_FLAGS)
+revtwoway_la_LIBADD = $(MY_LIBS)
+
rwarray_la_SOURCES = rwarray.c
rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS)
rwarray_la_LIBADD = $(MY_LIBS)
+
time_la_SOURCES = time.c
time_la_LDFLAGS = $(MY_MODULE_FLAGS)
time_la_LIBADD = $(MY_LIBS)
+
testext_la_SOURCES = testext.c
testext_la_LDFLAGS = $(MY_MODULE_FLAGS)
testext_la_LIBADD = $(MY_LIBS)
diff --git a/extension/Makefile.in b/extension/Makefile.in
index 59ead43b..bebc006b 100644
--- a/extension/Makefile.in
+++ b/extension/Makefile.in
@@ -90,13 +90,13 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
build-aux/install-sh build-aux/ltmain.sh build-aux/missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
- $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
- $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
- $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
- $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
- $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
- $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
@@ -173,6 +173,18 @@ readfile_la_OBJECTS = $(am_readfile_la_OBJECTS)
readfile_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(readfile_la_LDFLAGS) $(LDFLAGS) -o $@
+revoutput_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_revoutput_la_OBJECTS = revoutput.lo
+revoutput_la_OBJECTS = $(am_revoutput_la_OBJECTS)
+revoutput_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(revoutput_la_LDFLAGS) $(LDFLAGS) -o $@
+revtwoway_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_revtwoway_la_OBJECTS = revtwoway.lo
+revtwoway_la_OBJECTS = $(am_revtwoway_la_OBJECTS)
+revtwoway_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(revtwoway_la_LDFLAGS) $(LDFLAGS) -o $@
rwarray_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_rwarray_la_OBJECTS = rwarray.lo
rwarray_la_OBJECTS = $(am_rwarray_la_OBJECTS)
@@ -206,11 +218,13 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
$(fork_la_SOURCES) $(ordchr_la_SOURCES) $(readdir_la_SOURCES) \
- $(readfile_la_SOURCES) $(rwarray_la_SOURCES) \
+ $(readfile_la_SOURCES) $(revoutput_la_SOURCES) \
+ $(revtwoway_la_SOURCES) $(rwarray_la_SOURCES) \
$(testext_la_SOURCES) $(time_la_SOURCES)
DIST_SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
$(fork_la_SOURCES) $(ordchr_la_SOURCES) $(readdir_la_SOURCES) \
- $(readfile_la_SOURCES) $(rwarray_la_SOURCES) \
+ $(readfile_la_SOURCES) $(revoutput_la_SOURCES) \
+ $(revtwoway_la_SOURCES) $(rwarray_la_SOURCES) \
$(testext_la_SOURCES) $(time_la_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
@@ -312,6 +326,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBICONV = @LIBICONV@
@@ -422,6 +437,8 @@ pkgextension_LTLIBRARIES = \
ordchr.la \
readdir.la \
readfile.la \
+ revoutput.la \
+ revtwoway.la \
rwarray.la \
testext.la \
time.la
@@ -447,6 +464,12 @@ readdir_la_LIBADD = $(MY_LIBS)
readfile_la_SOURCES = readfile.c
readfile_la_LDFLAGS = $(MY_MODULE_FLAGS)
readfile_la_LIBADD = $(MY_LIBS)
+revoutput_la_SOURCES = revoutput.c
+revoutput_la_LDFLAGS = $(MY_MODULE_FLAGS)
+revoutput_la_LIBADD = $(MY_LIBS)
+revtwoway_la_SOURCES = revtwoway.c
+revtwoway_la_LDFLAGS = $(MY_MODULE_FLAGS)
+revtwoway_la_LIBADD = $(MY_LIBS)
rwarray_la_SOURCES = rwarray.c
rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS)
rwarray_la_LIBADD = $(MY_LIBS)
@@ -567,6 +590,10 @@ readdir.la: $(readdir_la_OBJECTS) $(readdir_la_DEPENDENCIES) $(EXTRA_readdir_la_
$(readdir_la_LINK) -rpath $(pkgextensiondir) $(readdir_la_OBJECTS) $(readdir_la_LIBADD) $(LIBS)
readfile.la: $(readfile_la_OBJECTS) $(readfile_la_DEPENDENCIES) $(EXTRA_readfile_la_DEPENDENCIES)
$(readfile_la_LINK) -rpath $(pkgextensiondir) $(readfile_la_OBJECTS) $(readfile_la_LIBADD) $(LIBS)
+revoutput.la: $(revoutput_la_OBJECTS) $(revoutput_la_DEPENDENCIES) $(EXTRA_revoutput_la_DEPENDENCIES)
+ $(revoutput_la_LINK) -rpath $(pkgextensiondir) $(revoutput_la_OBJECTS) $(revoutput_la_LIBADD) $(LIBS)
+revtwoway.la: $(revtwoway_la_OBJECTS) $(revtwoway_la_DEPENDENCIES) $(EXTRA_revtwoway_la_DEPENDENCIES)
+ $(revtwoway_la_LINK) -rpath $(pkgextensiondir) $(revtwoway_la_OBJECTS) $(revtwoway_la_LIBADD) $(LIBS)
rwarray.la: $(rwarray_la_OBJECTS) $(rwarray_la_DEPENDENCIES) $(EXTRA_rwarray_la_DEPENDENCIES)
$(rwarray_la_LINK) -rpath $(pkgextensiondir) $(rwarray_la_OBJECTS) $(rwarray_la_LIBADD) $(LIBS)
testext.la: $(testext_la_OBJECTS) $(testext_la_DEPENDENCIES) $(EXTRA_testext_la_DEPENDENCIES)
@@ -586,6 +613,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ordchr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readdir.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revoutput.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revtwoway.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rwarray.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testext.Plo@am__quote@
diff --git a/extension/aclocal.m4 b/extension/aclocal.m4
index db5d9f86..18cab755 100644
--- a/extension/aclocal.m4
+++ b/extension/aclocal.m4
@@ -1003,6 +1003,7 @@ AC_SUBST([am__untar])
m4_include([m4/gettext.m4])
m4_include([m4/iconv.m4])
+m4_include([m4/intlmacosx.m4])
m4_include([m4/lib-ld.m4])
m4_include([m4/lib-link.m4])
m4_include([m4/lib-prefix.m4])
diff --git a/extension/configh.in b/extension/configh.in
index 73ce026c..571b7a7e 100644
--- a/extension/configh.in
+++ b/extension/configh.in
@@ -4,6 +4,14 @@
language is requested. */
#undef ENABLE_NLS
+/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
+ CoreFoundation framework. */
+#undef HAVE_CFLOCALECOPYCURRENT
+
+/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in
+ the CoreFoundation framework. */
+#undef HAVE_CFPREFERENCESCOPYAPPVALUE
+
/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
#undef HAVE_DCGETTEXT
@@ -32,6 +40,9 @@
/* Define to 1 if you have the `fts_read' function. */
#undef HAVE_FTS_READ
+/* Define to 1 if you have the `getdtablesize' function. */
+#undef HAVE_GETDTABLESIZE
+
/* Define to 1 if you have the `GetSystemTimeAsFileTime' function. */
#undef HAVE_GETSYSTEMTIMEASFILETIME
diff --git a/extension/configure b/extension/configure
index 732bfc93..7030c8b1 100755
--- a/extension/configure
+++ b/extension/configure
@@ -662,6 +662,7 @@ LIBINTL
INTLLIBS
LTLIBICONV
LIBICONV
+INTL_MACOSX_LIBS
EGREP
GREP
CPP
@@ -5090,7 +5091,81 @@ fi
- gt_INTL_MACOSX
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5
+$as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; }
+if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <CoreFoundation/CFPreferences.h>
+int
+main ()
+{
+CFPreferencesCopyAppValue(NULL, NULL)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gt_cv_func_CFPreferencesCopyAppValue=yes
+else
+ gt_cv_func_CFPreferencesCopyAppValue=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$gt_save_LIBS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5
+$as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; }
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+
+$as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5
+$as_echo_n "checking for CFLocaleCopyCurrent... " >&6; }
+if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <CoreFoundation/CFLocale.h>
+int
+main ()
+{
+CFLocaleCopyCurrent();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gt_cv_func_CFLocaleCopyCurrent=yes
+else
+ gt_cv_func_CFLocaleCopyCurrent=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$gt_save_LIBS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5
+$as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; }
+ if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+
+$as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h
+
+ fi
+ INTL_MACOSX_LIBS=
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+ fi
+
+
@@ -13453,7 +13528,7 @@ done
for ac_func in fdopendir fnmatch fts_open fts_read gettimeofday \
- nanosleep select GetSystemTimeAsFileTime
+ getdtablesize 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 33009611..4869584b 100644
--- a/extension/configure.ac
+++ b/extension/configure.ac
@@ -51,7 +51,7 @@ fi
AC_CHECK_HEADERS(dirent.h fnmatch.h fts.h time.h sys/time.h sys/select.h)
AC_CHECK_FUNCS(fdopendir fnmatch fts_open fts_read gettimeofday \
- nanosleep select GetSystemTimeAsFileTime)
+ getdtablesize nanosleep select GetSystemTimeAsFileTime)
dnl checks for compiler characteristics
AC_C_INLINE
diff --git a/extension/m4/ChangeLog b/extension/m4/ChangeLog
index 9ce57384..c1223391 100644
--- a/extension/m4/ChangeLog
+++ b/extension/m4/ChangeLog
@@ -1,3 +1,7 @@
+2012-08-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * intlmacosx.m4: New file.
+
2012-07-30 Arnold D. Robbins <arnold@skeeve.com>
* gettext.m4, iconv.m4, lib-ld.m4, lib-link.m4, lib-prefix.m4,
diff --git a/extension/m4/intlmacosx.m4 b/extension/m4/intlmacosx.m4
new file mode 100644
index 00000000..dd910259
--- /dev/null
+++ b/extension/m4/intlmacosx.m4
@@ -0,0 +1,51 @@
+# intlmacosx.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2004-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Checks for special options needed on MacOS X.
+dnl Defines INTL_MACOSX_LIBS.
+AC_DEFUN([gt_INTL_MACOSX],
+[
+ dnl Check for API introduced in MacOS X 10.2.
+ AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
+ [gt_cv_func_CFPreferencesCopyAppValue],
+ [gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>],
+ [CFPreferencesCopyAppValue(NULL, NULL)],
+ [gt_cv_func_CFPreferencesCopyAppValue=yes],
+ [gt_cv_func_CFPreferencesCopyAppValue=no])
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+ AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1],
+ [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.])
+ fi
+ dnl Check for API introduced in MacOS X 10.3.
+ AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent],
+ [gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();],
+ [gt_cv_func_CFLocaleCopyCurrent=yes],
+ [gt_cv_func_CFLocaleCopyCurrent=no])
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1],
+ [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.])
+ fi
+ INTL_MACOSX_LIBS=
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+ fi
+ AC_SUBST([INTL_MACOSX_LIBS])
+])
diff --git a/extension/readdir.3am b/extension/readdir.3am
index 5f6ae06f..9cb4862e 100644
--- a/extension/readdir.3am
+++ b/extension/readdir.3am
@@ -1,4 +1,4 @@
-.TH READDIR 3am "Aug 08 2012" "Free Software Foundation" "GNU Awk Extension Modules"
+.TH READDIR 3am "Aug 23 2012" "Free Software Foundation" "GNU Awk Extension Modules"
.SH NAME
readdir \- directory input parser for gawk
.SH SYNOPSIS
@@ -49,7 +49,20 @@ causes the extension to use
to retrieve the appropriate information. This is not the default, since
.IR stat (2)
is a potentially expensive operation.
-... .SH NOTES
+.SH NOTES
+On GNU/Linux systems, there are filesystems that don't support the
+.B d_type
+entry (see
+.IR readdir (3)),
+and so the file type is always
+.BR u .
+Therefore, using
+.B readdir_do_ftype(1)
+is advisable even on GNU/Linux systems. In this case, the
+.I readdir
+extension will fall back to using
+.IR stat (2)
+when it encounters an unknown file type.
... .SH BUGS
.SH EXAMPLE
.ft CW
diff --git a/extension/readdir.c b/extension/readdir.c
index c28764e8..3eae4079 100644
--- a/extension/readdir.c
+++ b/extension/readdir.c
@@ -60,17 +60,15 @@ static awk_bool_t (*init_func)(void) = init_readdir;
int plugin_is_GPL_compatible;
-#ifdef DT_BLK
-static const int do_ftype = 1;
-#else
static int do_ftype;
-#endif
/* ftype --- return type of file as a single character string */
static const char *
ftype(struct dirent *entry)
{
+ struct stat sbuf;
+
#ifdef DT_BLK
switch (entry->d_type) {
case DT_BLK: return "b";
@@ -81,12 +79,17 @@ ftype(struct dirent *entry)
case DT_REG: return "f";
case DT_SOCK: return "s";
default:
- case DT_UNKNOWN: return "u";
+ case DT_UNKNOWN:
+ /*
+ * Could be that filesystem doesn't support d_type,
+ * even if the OS does. (E.g., XFS on GNU/Linux).
+ * So let lstat() do it.
+ */
+ break;
}
-#else
- struct stat sbuf;
+#endif
- if (lstat(entry->d_name, & sbuf) < 0)
+ if (! do_ftype || lstat(entry->d_name, & sbuf) < 0)
return "u";
switch (sbuf.st_mode & S_IFMT) {
@@ -108,9 +111,9 @@ ftype(struct dirent *entry)
#endif /* S_IFDOOR */
}
return "u";
-#endif
}
+/* data type for the opaque pointer: */
typedef struct open_directory {
DIR *dp;
@@ -138,6 +141,7 @@ dir_get_record(char **out, struct iobuf_public *iobuf, int *errcode,
the_dir = (open_directory_t *) iobuf->opaque;
dp = the_dir->dp;
+
/*
* Initialize errno, since readdir does not set it to zero on EOF.
*/
@@ -280,9 +284,7 @@ do_readdir_do_ftype(int nargs, awk_value_t *result)
goto out;
}
-#ifndef DT_BLK
do_ftype = (flag.num_value != 0.0);
-#endif
out:
return result;
diff --git a/extension/revoutput.c b/extension/revoutput.c
new file mode 100644
index 00000000..c1ea1ddc
--- /dev/null
+++ b/extension/revoutput.c
@@ -0,0 +1,136 @@
+/*
+ * revoutput.c --- Provide an output wrapper that reverses lines.
+ *
+ * Arnold Robbins
+ * arnold@skeeve.com
+ * Written 8/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 <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "config.h"
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+
+static awk_bool_t init_revout(void);
+static awk_bool_t (*init_func)(void) = init_revout;
+
+int plugin_is_GPL_compatible;
+
+/* rev_fwrite --- write out characters in reverse order */
+
+static size_t
+rev_fwrite(const void *buf, size_t size, size_t count, FILE *fp, void *opaque)
+{
+ const char *cp = buf;
+ int nbytes = size * count;
+
+ (void) opaque;
+
+ for (; nbytes >= 1; nbytes--)
+ putc(cp[nbytes-1], fp);
+
+ return (size * count);
+}
+
+
+/* revout_can_take_file --- return true if we want the file */
+
+static int
+revout_can_take_file(const awk_output_buf_t *outbuf)
+{
+ awk_value_t value;
+
+ if (outbuf == NULL)
+ return 0;
+
+ if (! sym_lookup("REVOUT", AWK_NUMBER, & value))
+ return 0;
+
+ return (value.num_value != 0);
+}
+
+/*
+ * revout_take_control_of --- set up output wrapper.
+ * We can assume that revout_can_take_file just returned true,
+ * and no state has changed since then.
+ */
+
+static int
+revout_take_control_of(awk_output_buf_t *outbuf)
+{
+ if (outbuf == NULL)
+ return 0;
+
+ outbuf->gawk_fwrite = rev_fwrite;
+ outbuf->redirected = 1;
+ return 1;
+}
+
+static awk_output_wrapper_t output_wrapper = {
+ "revout",
+ revout_can_take_file,
+ revout_take_control_of,
+ NULL
+};
+
+/* init_revout --- set things ups */
+
+static awk_bool_t
+init_revout()
+{
+ awk_value_t value;
+
+ register_output_wrapper(& output_wrapper);
+
+ make_number(0.0, & value); /* init to false */
+ if (! sym_update("REVOUT", & value)) {
+ warning(ext_id, _("revout: could not initialize REVOUT variable"));
+
+ return 0;
+ }
+
+ return 1;
+}
+
+static awk_ext_func_t func_table[] = {
+ { NULL, NULL, 0 }
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, revout, "")
diff --git a/extension/revtwoway.c b/extension/revtwoway.c
new file mode 100644
index 00000000..7ab9366e
--- /dev/null
+++ b/extension/revtwoway.c
@@ -0,0 +1,335 @@
+/*
+ * revtwoway.c --- Provide a two-way processor that reverses lines.
+ *
+ * Arnold Robbins
+ * arnold@skeeve.com
+ * Written 8/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"
+
+#include "gettext.h"
+#define _(msgid) gettext(msgid)
+#define N_(msgid) msgid
+
+static const gawk_api_t *api; /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+
+static awk_bool_t init_revtwoway(void);
+static awk_bool_t (*init_func)(void) = init_revtwoway;
+
+int plugin_is_GPL_compatible;
+
+/*
+ * Use this variable to provide a value != INVALID_HANDLE in the IOBUF_PUBLIC
+ * and != NULL in the awk_output_buf_t. The idea is to have a value that
+ * is greater than the largest allowable file descriptor.
+ */
+static size_t max_fds;
+
+#ifndef HAVE_GETDTABLESIZE
+/* getdtablesize --- replacement version that should be good enough */
+
+static inline int
+getdtablesize()
+{
+ /*
+ * Algorithm for the GNULIB folks:
+ *
+ * Set up a bitmap of 2048 elements.
+ * Initialize it to zero.
+ * In a loop, do
+ * fd = open("/dev/null", O_RDONLY)
+ * set the bit corresponding to fd in the bit map
+ * until it fails.
+ * Get the highest value that succeeded and increment it by one
+ * --> that is how many descriptors we have.
+ * Loop over the bitmap to close all the file descriptors we opened.
+ *
+ * Do all this upon the first call and return static values upon
+ * subsequent calls.
+ */
+
+ /* In the meantime, this is good enough for us: */
+ return 1024;
+}
+#endif
+
+/*
+ * IMPORTANT NOTE: This is a NOT a true general purpose
+ * extension. It is intended to demonstrate how to set up
+ * all the "plumbing" and to work one record at a time, ONLY.
+ *
+ * While it would be possible to set up buffering and manage it,
+ * that would duplicate a large chunk of the code in gawk's
+ * get_a_record() function, and there's no real point in doing that.
+ */
+
+/* the data in the opaque pointer */
+typedef struct two_way_proc_data {
+ size_t size; /* size of allocated buffer */
+ size_t len; /* how much is actually in use */
+ char *data;
+ size_t in_use; /* use count, must hit zero to be freed */
+} two_way_proc_data_t;
+
+/* close_two_proc_data --- release the data */
+
+static void
+close_two_proc_data(two_way_proc_data_t *proc_data)
+{
+ if (proc_data->in_use > 1) {
+ proc_data->in_use--;
+ return;
+ }
+
+ free(proc_data->data);
+ free(proc_data);
+}
+
+/*
+ * Input side of the two-way processor (input TO gawk)
+ */
+
+/* rev2way_get_record --- get one record at a time out of a directory */
+
+static int
+rev2way_get_record(char **out, struct iobuf_public *iobuf, int *errcode,
+ char **rt_start, size_t *rt_len)
+{
+ int len = 0; /* for now */
+ two_way_proc_data_t *proc_data;
+
+ /*
+ * The caller sets *errcode to 0, so we should set it only if an
+ * error occurs.
+ */
+
+ if (out == NULL || iobuf == NULL || iobuf->opaque == NULL)
+ return EOF;
+
+ proc_data = (two_way_proc_data_t *) iobuf->opaque;
+ if (proc_data->len == 0)
+ return 0;
+
+ *out = proc_data->data;
+
+ len = proc_data->len;
+ proc_data->len = 0;
+
+ *rt_len = 0; /* default: set RT to "" */
+ if (proc_data->data[len-1] == '\n') {
+ while (proc_data->data[len-1] == '\n') {
+ len--;
+ (*rt_len)++;
+ }
+ *rt_start = proc_data->data + len;
+ }
+
+ return len;
+}
+
+/* rev2way_close --- close up input side when done */
+
+static void
+rev2way_close(struct iobuf_public *iobuf)
+{
+ two_way_proc_data_t *proc_data;
+
+ if (iobuf == NULL || iobuf->opaque == NULL)
+ return;
+
+ proc_data = (two_way_proc_data_t *) iobuf->opaque;
+ close_two_proc_data(proc_data);
+
+ iobuf->fd = INVALID_HANDLE;
+}
+
+
+/*
+ * Output side of the two-way processor (output FROM gawk)
+ */
+
+/* rev2way_fwrite --- write out characters in reverse order */
+
+static size_t
+rev2way_fwrite(const void *buf, size_t size, size_t count, FILE *fp, void *opaque)
+{
+ two_way_proc_data_t *proc_data;
+ size_t amount, char_count;
+ char *src, *dest;
+
+ if (opaque == NULL)
+ return 0; /* error */
+
+ proc_data = (two_way_proc_data_t *) opaque;
+ amount = size * count;
+
+ /* do the dance */
+ if (amount > proc_data->size || proc_data->len > 0) {
+ if (proc_data->data == NULL)
+ emalloc(proc_data->data, char *, amount, "rev2way_fwrite");
+ else
+ erealloc(proc_data->data, char *, proc_data->size + amount, "rev2way_fwrite");
+ proc_data->size += amount;
+ }
+
+ src = (char *) buf + amount -1;
+ dest = proc_data->data + proc_data->len;
+ for (char_count = amount; char_count > 0; char_count--) {
+ /* copy in backwards */
+ *dest++ = *src--;
+ }
+ proc_data->len += amount;
+
+ return amount;
+}
+
+/* rev2way_fflush --- do nothing hook for fflush */
+
+static int
+rev2way_fflush(FILE *fp, void *opaque)
+{
+ (void) fp;
+ (void) opaque;
+
+ return 0;
+}
+
+/* rev2way_ferror --- do nothing hook for ferror */
+
+static int
+rev2way_ferror(FILE *fp, void *opaque)
+{
+ (void) fp;
+ (void) opaque;
+
+ return 0;
+}
+
+/* rev2way_fclose --- close output side of two-way processor */
+
+static int
+rev2way_fclose(FILE *fp, void *opaque)
+{
+ two_way_proc_data_t *proc_data;
+
+ if (opaque == NULL)
+ return EOF; /* error */
+
+ (void) fp;
+
+ proc_data = (two_way_proc_data_t *) opaque;
+ close_two_proc_data(proc_data);
+
+ return 0;
+}
+
+
+/* revtwoway_can_two_way --- return true if we want the file */
+
+static int
+revtwoway_can_take_two_way(const char *name)
+{
+ return (name != NULL && strcmp(name, "/magic/mirror") == 0);
+}
+
+/*
+ * revtwoway_take_control_of --- set up two way processor
+ * We can assume that revtwoway_can_take_two_way just returned true,
+ * and no state has changed since then.
+ */
+
+static int
+revtwoway_take_control_of(const char *name, IOBUF_PUBLIC *inbuf, awk_output_buf_t *outbuf)
+{
+ two_way_proc_data_t *proc_data;
+
+ if (inbuf == NULL || outbuf == NULL)
+ return 0;
+
+ emalloc(proc_data, two_way_proc_data_t *, sizeof(two_way_proc_data_t), "revtwoway_take_control_of");
+ proc_data->in_use = 2;
+ proc_data->size = 0;
+ proc_data->len = 0;
+ proc_data->data = NULL;
+
+ if (max_fds + 1 == 0) /* wrapped. ha! */
+ max_fds = getdtablesize();
+
+ /* input side: */
+ inbuf->get_record = rev2way_get_record;
+ inbuf->close_func = rev2way_close;
+ inbuf->fd = max_fds;
+ inbuf->opaque = proc_data;
+
+ /* output side: */
+ outbuf->fp = (FILE *) max_fds++;
+ outbuf->opaque = proc_data;
+ outbuf->gawk_fwrite = rev2way_fwrite;
+ outbuf->gawk_fflush = rev2way_fflush;
+ outbuf->gawk_ferror = rev2way_ferror;
+ outbuf->gawk_fclose = rev2way_fclose;
+ outbuf->redirected = 1;
+ return 1;
+}
+
+static awk_two_way_processor_t two_way_processor = {
+ "revtwoway",
+ revtwoway_can_take_two_way,
+ revtwoway_take_control_of,
+ NULL
+};
+
+/* init_revtwoway --- set things ups */
+
+static awk_bool_t
+init_revtwoway()
+{
+ register_two_way_processor(& two_way_processor);
+
+ max_fds = getdtablesize();
+
+ return 1;
+}
+
+static awk_ext_func_t func_table[] = {
+ { NULL, NULL, 0 }
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, revtwoway, "")