diff options
Diffstat (limited to 'extension')
-rw-r--r-- | extension/ChangeLog | 5 | ||||
-rw-r--r-- | extension/Makefile.am | 18 | ||||
-rw-r--r-- | extension/Makefile.in | 47 | ||||
-rw-r--r-- | extension/aclocal.m4 | 1 | ||||
-rw-r--r-- | extension/configh.in | 11 | ||||
-rwxr-xr-x | extension/configure | 79 | ||||
-rw-r--r-- | extension/configure.ac | 2 | ||||
-rw-r--r-- | extension/m4/ChangeLog | 4 | ||||
-rw-r--r-- | extension/m4/intlmacosx.m4 | 51 | ||||
-rw-r--r-- | extension/readdir.3am | 17 | ||||
-rw-r--r-- | extension/readdir.c | 24 | ||||
-rw-r--r-- | extension/revoutput.c | 136 | ||||
-rw-r--r-- | extension/revtwoway.c | 335 |
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, "") |