diff options
Diffstat (limited to 'extension')
-rw-r--r-- | extension/ChangeLog | 7 | ||||
-rw-r--r-- | extension/Makefile.am | 5 | ||||
-rw-r--r-- | extension/Makefile.in | 21 | ||||
-rw-r--r-- | extension/configh.in | 21 | ||||
-rwxr-xr-x | extension/configure | 117 | ||||
-rw-r--r-- | extension/configure.ac | 6 | ||||
-rw-r--r-- | extension/time.c | 167 |
7 files changed, 334 insertions, 10 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog index 56eaa979..5e513f8e 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,5 +1,12 @@ 2012-06-10 Andrew J. Schorr <aschorr@telemetry-investments.com> + * Makefile.am: Add time extension. + * configure.ac: To support time extension, check for some headers + and functions that are needed. + * time.c: New file implementing sleep and gettimeofday. + +2012-06-10 Andrew J. Schorr <aschorr@telemetry-investments.com> + * Makefile.am: Remove comment referring to deleted test extensions arrayparm, dl (zaxxon) and testarg. diff --git a/extension/Makefile.am b/extension/Makefile.am index 5e9a59f7..f2b30ede 100644 --- a/extension/Makefile.am +++ b/extension/Makefile.am @@ -35,7 +35,8 @@ pkgextension_LTLIBRARIES = \ filefuncs.la \ fork.la \ ordchr.la \ - readfile.la + readfile.la \ + time.la MY_MODULE_FLAGS = -module -avoid-version -no-undefined @@ -47,6 +48,8 @@ ordchr_la_SOURCES = ordchr.c ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS) readfile_la_SOURCES = readfile.c readfile_la_LDFLAGS = $(MY_MODULE_FLAGS) +time_la_SOURCES = time.c +time_la_LDFLAGS = $(MY_MODULE_FLAGS) #rwarray_la_SOURCES = rwarray.c #rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS) diff --git a/extension/Makefile.in b/extension/Makefile.in index c90a0b4c..59528912 100644 --- a/extension/Makefile.in +++ b/extension/Makefile.in @@ -154,6 +154,12 @@ 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 $@ +time_la_LIBADD = +am_time_la_OBJECTS = time.lo +time_la_OBJECTS = $(am_time_la_OBJECTS) +time_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(time_la_LDFLAGS) \ + $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles @@ -168,9 +174,9 @@ 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) + $(ordchr_la_SOURCES) $(readfile_la_SOURCES) $(time_la_SOURCES) DIST_SOURCES = $(filefuncs_la_SOURCES) $(fork_la_SOURCES) \ - $(ordchr_la_SOURCES) $(readfile_la_SOURCES) + $(ordchr_la_SOURCES) $(readfile_la_SOURCES) $(time_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -317,15 +323,13 @@ AM_CPPFLAGS = -I$(srcdir)/.. # correctly after changing configure.ac ACLOCAL_AMFLAGS = -I m4 -# The arrayparm, zaxxon (dl), and testarg libraries do not do anything useful, -# so do not build or install them. - # Note: rwarray does not currently compile. pkgextension_LTLIBRARIES = \ filefuncs.la \ fork.la \ ordchr.la \ - readfile.la + readfile.la \ + time.la MY_MODULE_FLAGS = -module -avoid-version -no-undefined filefuncs_la_SOURCES = filefuncs.c @@ -336,6 +340,8 @@ ordchr_la_SOURCES = ordchr.c ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS) readfile_la_SOURCES = readfile.c readfile_la_LDFLAGS = $(MY_MODULE_FLAGS) +time_la_SOURCES = time.c +time_la_LDFLAGS = $(MY_MODULE_FLAGS) #rwarray_la_SOURCES = rwarray.c #rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS) EXTRA_DIST = \ @@ -441,6 +447,8 @@ ordchr.la: $(ordchr_la_OBJECTS) $(ordchr_la_DEPENDENCIES) $(EXTRA_ordchr_la_DEPE $(ordchr_la_LINK) -rpath $(pkgextensiondir) $(ordchr_la_OBJECTS) $(ordchr_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) +time.la: $(time_la_OBJECTS) $(time_la_DEPENDENCIES) $(EXTRA_time_la_DEPENDENCIES) + $(time_la_LINK) -rpath $(pkgextensiondir) $(time_la_OBJECTS) $(time_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -452,6 +460,7 @@ distclean-compile: @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@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/extension/configh.in b/extension/configh.in index e0beaf25..519f8ea3 100644 --- a/extension/configh.in +++ b/extension/configh.in @@ -3,12 +3,24 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the `GetSystemTimeAsFileTime' function. */ +#undef HAVE_GETSYSTEMTIMEASFILETIME + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `nanosleep' function. */ +#undef HAVE_NANOSLEEP + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H @@ -21,12 +33,21 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H +/* Define to 1 if you have the <sys/select.h> header file. */ +#undef HAVE_SYS_SELECT_H + /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the <time.h> header file. */ +#undef HAVE_TIME_H + /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H diff --git a/extension/configure b/extension/configure index 7333bdad..30b162a8 100755 --- a/extension/configure +++ b/extension/configure @@ -1754,6 +1754,97 @@ $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------- ## +## Report this to bug-gawk@gnu.org ## +## ------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. @@ -11371,6 +11462,32 @@ then CFLAGS="$CFLAGS -Wall -Wextra" fi +for ac_header in 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" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_func in nanosleep select gettimeofday 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" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } diff --git a/extension/configure.ac b/extension/configure.ac index 461826e6..838350cf 100644 --- a/extension/configure.ac +++ b/extension/configure.ac @@ -45,9 +45,9 @@ then CFLAGS="$CFLAGS -Wall -Wextra" fi -dnl AC_CHECK_HEADERS(stdarg.h) -dnl AC_CHECK_FUNCS(snprintf) -dnl AC_FUNC_VPRINTF +AC_CHECK_HEADERS(time.h sys/time.h sys/select.h) + +AC_CHECK_FUNCS(nanosleep select gettimeofday GetSystemTimeAsFileTime) dnl checks for compiler characteristics AC_C_INLINE diff --git a/extension/time.c b/extension/time.c new file mode 100644 index 00000000..4f590c88 --- /dev/null +++ b/extension/time.c @@ -0,0 +1,167 @@ +/* + * time.c - Builtin functions that provide time-related functions. + * + */ + +/* + * 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 <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" + +static const gawk_api_t *api; /* for convenience macros to work */ +static awk_ext_id_t *ext_id; + +int plugin_is_GPL_compatible; + +#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) +#include <sys/time.h> +#endif +#if defined(HAVE_SELECT) && defined(HAVE_SYS_SELECT_H) +#include <sys/select.h> +#endif +#if defined(HAVE_NANOSLEEP) && defined(HAVE_TIME_H) +#include <time.h> +#endif + +#define RETURN return tmp_number((AWKNUM) 0) + +/* + * Returns time since 1/1/1970 UTC as a floating point value; should + * have sub-second precision, but the actual precision will vary based + * on the platform + */ +static awk_value_t * +do_gettimeofday(int nargs, awk_value_t *result) +{ + double curtime; + + if (do_lint && nargs > 0) + lintwarn(ext_id, "gettimeofday: ignoring arguments"); + +#if defined(HAVE_GETTIMEOFDAY) + { + struct timeval tv; + gettimeofday(&tv,NULL); + curtime = tv.tv_sec+(tv.tv_usec/1000000.0); + } +#elif defined(HAVE_GETSYSTEMTIMEASFILETIME) + /* based on perl win32/win32.c:win32_gettimeofday() implementation */ + { + union { + unsigned __int64 ft_i64; + FILETIME ft_val; + } ft; + + /* # of 100-nanosecond intervals since January 1, 1601 (UTC) */ + GetSystemTimeAsFileTime(&ft.ft_val); +#ifdef __GNUC__ +#define Const64(x) x##LL +#else +#define Const64(x) x##i64 +#endif +/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */ +#define EPOCH_BIAS Const64(116444736000000000) + curtime = (ft.ft_i64 - EPOCH_BIAS)/10000000.0; +#undef Const64 + } +#else + /* no way to retrieve system time on this platform */ + curtime = -1; + update_ERRNO_string("gettimeofday: not supported on this platform", 1); +#endif + + return make_number(curtime, result); +} + +/* + * Returns 0 if successful in sleeping the requested time; + * returns -1 if there is no platform support, or if the sleep request + * did not complete successfully (perhaps interrupted) + */ +static awk_value_t * +do_sleep(int nargs, awk_value_t *result) +{ + awk_value_t num; + double secs; + int rc; + + if (do_lint && nargs > 1) + lintwarn(ext_id, "sleep: called with too many arguments"); + + + if (get_curfunc_param(0, AWK_NUMBER, &num) == NULL) { + update_ERRNO_string("sleep: missing required numeric argument", 1); + return make_number(-1, result); + } + secs = num.num_value; + + if (secs < 0) { + update_ERRNO_string("sleep: argument is negative", 1); + return make_number(-1, result); + } + +#if defined(HAVE_NANOSLEEP) + { + struct timespec req; + + req.tv_sec = secs; + req.tv_nsec = (secs-(double)req.tv_sec)*1000000000.0; + if ((rc = nanosleep(&req,NULL)) < 0) + /* probably interrupted */ + update_ERRNO_int(errno); + } +#elif defined(HAVE_SELECT) + { + struct timeval timeout; + + timeout.tv_sec = secs; + timeout.tv_usec = (secs-(double)timeout.tv_sec)*1000000.0; + if ((rc = select(0,NULL,NULL,NULL,&timeout)) < 0) + /* probably interrupted */ + update_ERRNO_int(errno); + } +#else + /* no way to sleep on this platform */ + rc = -1; + set_ERRNO("sleep: not supported on this platform"); +#endif + + return make_number(rc, result); +} + +static awk_ext_func_t func_table[] = { + { "gettimeofday", do_gettimeofday, 0 }, + { "sleep", do_sleep, 1 }, +}; + +/* define the dl_load function using the boilerplate macro */ + +dl_load_func(func_table, time, "") |