From 9ef43720d1b2b3125f4367f3ccf2cb7129d1a9ba Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Fri, 6 Jan 2017 14:48:53 -0500 Subject: Enhance API to support extended-precision arithmetic and implement intdiv as a demonstration. --- ChangeLog | 42 ++++++++++ awk.h | 17 ++++ extension/ChangeLog | 10 +++ extension/Makefile.am | 5 ++ extension/Makefile.in | 41 +++++++--- extension/aclocal.m4 | 1 + extension/configh.in | 6 ++ extension/configure | 86 ++++++++++++++++++++- extension/configure.ac | 11 ++- extension/intdiv.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++ gawkapi.c | 115 +++++++++++++++++++++++++-- gawkapi.h | 97 +++++++++++++++++++++-- mpfr.c | 18 +---- node.c | 15 ++-- 14 files changed, 621 insertions(+), 49 deletions(-) create mode 100644 extension/intdiv.c diff --git a/ChangeLog b/ChangeLog index 9d4bcd64..6ec93776 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,45 @@ +2017-01-06 Andrew J. Schorr + + Enhance API to support extended-precision arithmetic. + * awk.h (enum block_id): Add new values BLOCK_MPFR and BLOCK_MPZ. + (make_number_node): New inline function to reduce code duplication + for creating numeric nodes. + * gawkapi.h (gawk_api_major_version): Bump to 3. + (awk_number_t): New typedef to represent numbers with varying internal + representations. + (awk_value_t): For numbers, replace double with awk_number_t. + (num_value): Redefine. + (num_type, num_ptr): New defines for awk_number_t union members. + (gawk_api_t): Add constants for version checking: gmp_major_version, + gmp_minor_version, mpfr_major_version, and mpfr_minor_version. + Add functions api_get_mpfr and api_get_mpz to allocate memory for + extended-precision numbers to hand to gawk. + (get_mpfr_ptr, get_mpz_ptr): Helper macros to warp api_get_mpfr and + api_get_mpz. + (make_number): Modify to populate awk_number_t correctly. + (make_number_mpz, make_number_mpfr): New helper functions to create + extended-precision numeric nodes. + (check_mpfr_version): New macro to check GMP/MPFR version compatibility + in extensions that want to support extended-precision math. + * gawkapi.c (getmpfr, freempfr, getmpz, freempz): New macros to + allocate and free memory blocks for extended-precision math. + (awk_value_to_node): For AWK_NUMBER values, support 3 different kinds + of internal numbers: double, mpz_t, and mpfr_t. + (assign_number): New helper function to convert a numeric node to + an awk_value_t. + (node_to_awk_value): Use assign_number in a couple of places to + pass numbers properly. + (api_get_mpfr): Implement new api_get_mpfr hook. + (api_get_mpfz): Implement new api_get_mpz hook. + (api_impl): Add GMP & MPFR versions, api_get_mpfr, and api_get_mpz. + * node.c (r_make_number): Use new make_number_node inline function + to reduce code duplication. + (nextfree): Add block allocators for mpfr_t and mpz_t. + (more_blocks): Add an assert to protect against cases where the block + size is too small to hold our structure. + * mpfr.c (mpg_node): Use new make_number_node inline function + to reduce code duplication. + 2016-12-27 Juergen Kahrs * CMakeLists.txt: Updated after adding support library. diff --git a/awk.h b/awk.h index 278f54c5..514dfdcb 100644 --- a/awk.h +++ b/awk.h @@ -1060,6 +1060,8 @@ enum block_id { BLOCK_INVALID = 0, /* not legal */ BLOCK_NODE, BLOCK_BUCKET, + BLOCK_MPFR, + BLOCK_MPZ, BLOCK_MAX /* count */ }; @@ -1945,3 +1947,18 @@ erealloc_real(void *ptr, size_t count, const char *where, const char *var, const return ret; } + +static inline NODE * +make_number_node(unsigned int tp) +{ + NODE *r; + getnode(r); + r->type = Node_val; + r->valref = 1; + r->flags = (tp|MALLOC|NUMBER|NUMCUR); + r->stptr = NULL; + r->stlen = 0; + r->wstptr = NULL; + r->wstlen = 0; + return r; +} diff --git a/extension/ChangeLog b/extension/ChangeLog index 20834b01..84f14679 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,13 @@ +2017-01-06 Andrew J. Schorr + + * intdiv.c: New extension to demonstrate how to implement intdiv + using the new extended-precision math API. + * Makefile.am (pkgextension_LTLIBRARIES): Add intdiv.la. + (intdiv_la_SOURCES, intdiv_la_LDFLAGS, intdiv_la_LIBADD): Add support + for new intdiv library. + * configure.ac (AC_CHECK_FUNCS): Check for fmod needed by intdiv. + (GNUPG_CHECK_MPFR): Add check for MPFR support. + 2016-12-22 Arnold D. Robbins * testext.c (valrep2str): Update for new API types. diff --git a/extension/Makefile.am b/extension/Makefile.am index 59c5cb8e..398ca818 100644 --- a/extension/Makefile.am +++ b/extension/Makefile.am @@ -39,6 +39,7 @@ pkgextension_LTLIBRARIES = \ fnmatch.la \ fork.la \ inplace.la \ + intdiv.la \ ordchr.la \ readdir.la \ readfile.la \ @@ -69,6 +70,10 @@ inplace_la_SOURCES = inplace.c inplace_la_LDFLAGS = $(MY_MODULE_FLAGS) inplace_la_LIBADD = $(MY_LIBS) +intdiv_la_SOURCES = intdiv.c +intdiv_la_LDFLAGS = $(MY_MODULE_FLAGS) +intdiv_la_LIBADD = $(MY_LIBS) + ordchr_la_SOURCES = ordchr.c ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS) ordchr_la_LIBADD = $(MY_LIBS) diff --git a/extension/Makefile.in b/extension/Makefile.in index 23bb5cf1..9ec585a8 100644 --- a/extension/Makefile.in +++ b/extension/Makefile.in @@ -114,10 +114,10 @@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../m4/arch.m4 \ - $(top_srcdir)/m4/dirfd.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)/configure.ac + $(top_srcdir)/../m4/mpfr.m4 $(top_srcdir)/m4/dirfd.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)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ @@ -187,6 +187,12 @@ inplace_la_OBJECTS = $(am_inplace_la_OBJECTS) inplace_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(inplace_la_LDFLAGS) $(LDFLAGS) -o $@ +intdiv_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_intdiv_la_OBJECTS = intdiv.lo +intdiv_la_OBJECTS = $(am_intdiv_la_OBJECTS) +intdiv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(intdiv_la_LDFLAGS) $(LDFLAGS) -o $@ ordchr_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_ordchr_la_OBJECTS = ordchr.lo ordchr_la_OBJECTS = $(am_ordchr_la_OBJECTS) @@ -270,15 +276,17 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \ - $(fork_la_SOURCES) $(inplace_la_SOURCES) $(ordchr_la_SOURCES) \ - $(readdir_la_SOURCES) $(readfile_la_SOURCES) \ - $(revoutput_la_SOURCES) $(revtwoway_la_SOURCES) \ - $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES) + $(fork_la_SOURCES) $(inplace_la_SOURCES) $(intdiv_la_SOURCES) \ + $(ordchr_la_SOURCES) $(readdir_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) $(inplace_la_SOURCES) $(ordchr_la_SOURCES) \ - $(readdir_la_SOURCES) $(readfile_la_SOURCES) \ - $(revoutput_la_SOURCES) $(revtwoway_la_SOURCES) \ - $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES) + $(fork_la_SOURCES) $(inplace_la_SOURCES) $(intdiv_la_SOURCES) \ + $(ordchr_la_SOURCES) $(readdir_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 cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -413,6 +421,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBMPFR = @LIBMPFR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -511,6 +520,7 @@ pkgextension_LTLIBRARIES = \ fnmatch.la \ fork.la \ inplace.la \ + intdiv.la \ ordchr.la \ readdir.la \ readfile.la \ @@ -537,6 +547,9 @@ fork_la_LIBADD = $(MY_LIBS) inplace_la_SOURCES = inplace.c inplace_la_LDFLAGS = $(MY_MODULE_FLAGS) inplace_la_LIBADD = $(MY_LIBS) +intdiv_la_SOURCES = intdiv.c +intdiv_la_LDFLAGS = $(MY_MODULE_FLAGS) +intdiv_la_LIBADD = $(MY_LIBS) ordchr_la_SOURCES = ordchr.c ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS) ordchr_la_LIBADD = $(MY_LIBS) @@ -679,6 +692,9 @@ fork.la: $(fork_la_OBJECTS) $(fork_la_DEPENDENCIES) $(EXTRA_fork_la_DEPENDENCIES inplace.la: $(inplace_la_OBJECTS) $(inplace_la_DEPENDENCIES) $(EXTRA_inplace_la_DEPENDENCIES) $(AM_V_CCLD)$(inplace_la_LINK) -rpath $(pkgextensiondir) $(inplace_la_OBJECTS) $(inplace_la_LIBADD) $(LIBS) +intdiv.la: $(intdiv_la_OBJECTS) $(intdiv_la_DEPENDENCIES) $(EXTRA_intdiv_la_DEPENDENCIES) + $(AM_V_CCLD)$(intdiv_la_LINK) -rpath $(pkgextensiondir) $(intdiv_la_OBJECTS) $(intdiv_la_LIBADD) $(LIBS) + ordchr.la: $(ordchr_la_OBJECTS) $(ordchr_la_DEPENDENCIES) $(EXTRA_ordchr_la_DEPENDENCIES) $(AM_V_CCLD)$(ordchr_la_LINK) -rpath $(pkgextensiondir) $(ordchr_la_OBJECTS) $(ordchr_la_LIBADD) $(LIBS) @@ -714,6 +730,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fork.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gawkfts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inplace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intdiv.Plo@am__quote@ @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@ diff --git a/extension/aclocal.m4 b/extension/aclocal.m4 index 5665d48e..1e7a343c 100644 --- a/extension/aclocal.m4 +++ b/extension/aclocal.m4 @@ -1211,6 +1211,7 @@ AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([../m4/arch.m4]) +m4_include([../m4/mpfr.m4]) m4_include([m4/dirfd.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) diff --git a/extension/configh.in b/extension/configh.in index d3a226a5..9d3d9919 100644 --- a/extension/configh.in +++ b/extension/configh.in @@ -27,6 +27,9 @@ /* Define to 1 if you have the `fdopendir' function. */ #undef HAVE_FDOPENDIR +/* Define to 1 if you have the `fmod' function. */ +#undef HAVE_FMOD + /* Define to 1 if you have the `fnmatch' function. */ #undef HAVE_FNMATCH @@ -51,6 +54,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have fully functional mpfr and gmp libraries. */ +#undef HAVE_MPFR + /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP diff --git a/extension/configure b/extension/configure index 40601550..580cc150 100755 --- a/extension/configure +++ b/extension/configure @@ -635,6 +635,7 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +LIBMPFR pkgextensiondir LT_SYS_LIBRARY_PATH OTOOL64 @@ -763,6 +764,7 @@ with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock +with_mpfr ' ac_precious_vars='build_alias host_alias @@ -1416,6 +1418,7 @@ Optional Packages: --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). + --with-mpfr=DIR look for the mpfr and gmp libraries in DIR Some influential environment variables: CC C compiler command @@ -12859,7 +12862,88 @@ $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi -for ac_func in fdopendir fnmatch gettimeofday \ +case `uname -m` in +*'Power Macintosh'*) + : ;; +*) + + +# Check whether --with-mpfr was given. +if test "${with_mpfr+set}" = set; then : + withval=$with_mpfr; _do_mpfr=$withval +else + _do_mpfr=yes +fi + + + if test "$_do_mpfr" != "no" ; then + if test -d "$withval" ; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + + _mpfr_save_libs=$LIBS + _combo="-lmpfr -lgmp" + LIBS="$LIBS $_combo" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mpfr via \"$_combo\" is present and usable" >&5 +$as_echo_n "checking whether mpfr via \"$_combo\" is present and usable... " >&6; } + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#include +#include +#include + +int +main () +{ + +mpfr_t p; +mpz_t z; +mpfr_init(p); +mpz_init(z); +mpfr_printf("%Rf%Zd", p, z); +mpfr_clear(p); +mpz_clear(z); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + _found_mpfr=yes +else + _found_mpfr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_found_mpfr" >&5 +$as_echo "$_found_mpfr" >&6; } + + LIBS=$_mpfr_save_libs + + if test $_found_mpfr = yes ; then + +$as_echo "#define HAVE_MPFR 1" >>confdefs.h + + LIBMPFR=$_combo + + break + fi + + unset _mpfr_save_libs + unset _combo + unset _found_mpfr + fi + + ;; +esac + +for ac_func in fdopendir fnmatch gettimeofday fmod \ getdtablesize nanosleep select statvfs GetSystemTimeAsFileTime do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` diff --git a/extension/configure.ac b/extension/configure.ac index b5b27d03..58935b69 100644 --- a/extension/configure.ac +++ b/extension/configure.ac @@ -69,7 +69,16 @@ AC_HEADER_DIRENT AC_HEADER_MAJOR AC_HEADER_TIME -AC_CHECK_FUNCS(fdopendir fnmatch gettimeofday \ +dnl check for mpfr support +case `uname -m` in +*'Power Macintosh'*) + : ;; +*) + GNUPG_CHECK_MPFR + ;; +esac + +AC_CHECK_FUNCS(fdopendir fnmatch gettimeofday fmod \ getdtablesize nanosleep select statvfs GetSystemTimeAsFileTime) GAWK_FUNC_DIRFD diff --git a/extension/intdiv.c b/extension/intdiv.c new file mode 100644 index 00000000..2f446c47 --- /dev/null +++ b/extension/intdiv.c @@ -0,0 +1,206 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "gawkapi.h" + +#ifdef HAVE_MPFR +#include +#include +#endif + +#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 const char *ext_version = "intdiv extension: version 1.0"; + +int plugin_is_GPL_compatible; + +static double +double_to_int(double d) +{ + if (d >= 0) + d = floor(d); + else + d = ceil(d); + return d; +} + +static void +array_set_number(awk_array_t array, const char *sub, size_t sublen, double num) +{ + awk_value_t index, tmp; + + set_array_element(array, make_const_string(sub, sublen, & index), make_number(num, & tmp)); +} + +#ifdef HAVE_MPFR + +static mpz_ptr +mpz_conv(const awk_value_t *arg, mpz_ptr tmp) +{ + switch (arg->num_type) { + case AWK_NUMBER_TYPE_MPZ: + return arg->num_ptr; + case AWK_NUMBER_TYPE_MPFR: + if (! mpfr_number_p(arg->num_ptr)) + return NULL; + mpz_init(tmp); + mpfr_get_z(tmp, arg->num_ptr, MPFR_RNDZ); + return tmp; + case AWK_NUMBER_TYPE_DOUBLE: /* can this happen? */ + mpz_init(tmp); + mpz_set_d(tmp, double_to_int(arg->num_value)); + return tmp; + default: /* should never happen */ + fatal(ext_id, _("intdiv: invalid numeric type `%d'"), arg->num_type); + return NULL; + } +} + +static void +array_set_mpz(awk_array_t array, const char *sub, size_t sublen, mpz_ptr num) +{ + awk_value_t index, tmp; + + set_array_element(array, make_const_string(sub, sublen, & index), make_number_mpz(num, & tmp)); +} + +#endif + +/* do_intdiv --- do integer division, return quotient and remainder in dest array */ + +/* + * We define the semantics as: + * numerator = int(numerator) + * denominator = int(denonmator) + * quotient = int(numerator / denomator) + * remainder = int(numerator % denomator) + */ + +static awk_value_t * +do_intdiv(int nargs, awk_value_t *result, struct awk_ext_func *unused) +{ + awk_value_t nv, dv, array_param; + awk_array_t array; + + if (! get_argument(0, AWK_NUMBER, & nv)) { + warning(ext_id, _("intdiv: first argument must be numeric")); + return make_number(-1, result); + } + if (! get_argument(1, AWK_NUMBER, & dv)) { + warning(ext_id, _("intdiv: second argument must be numeric")); + return make_number(-1, result); + } + if (! get_argument(2, AWK_ARRAY, & array_param)) { + warning(ext_id, _("intdiv: third argument must be an array")); + return make_number(-1, result); + } + array = array_param.array_cookie; + clear_array(array); + +#ifdef HAVE_MPFR + if (nv.num_type == AWK_NUMBER_TYPE_DOUBLE && dv.num_type == AWK_NUMBER_TYPE_DOUBLE) { +#endif + /* regular precision */ + double num, denom, quotient, remainder; + + num = double_to_int(nv.num_value); + denom = double_to_int(dv.num_value); + + if (denom == 0.0) + fatal(ext_id, _("intdiv: division by zero attempted")); + + quotient = double_to_int(num / denom); +#ifdef HAVE_FMOD + remainder = fmod(num, denom); +#else /* ! HAVE_FMOD */ + (void) modf(num / denom, & remainder); + remainder = num - remainder * denom; +#endif /* ! HAVE_FMOD */ + remainder = double_to_int(remainder); + + array_set_number(array, "quotient", 8, quotient); + array_set_number(array, "remainder", 9, remainder); +#ifdef HAVE_MPFR + } + else { + /* extended precision */ + mpz_ptr numer, denom; + mpz_t numer_tmp, denom_tmp; + mpz_ptr quotient, remainder; + + /* convert numerator and denominator to integer */ + if (!(numer = mpz_conv(&nv, numer_tmp))) { + warning(ext_id, _("intdiv: numerator is not finite")); + return make_number(-1, result); + } + if (!(denom = mpz_conv(&dv, denom_tmp))) { + warning(ext_id, _("intdiv: denominator is not finite")); + if (numer == numer_tmp) + mpz_clear(numer); + return make_number(-1, result); + } + if (mpz_sgn(denom) == 0) { + warning(ext_id, _("intdiv: division by zero attempted")); + if (numer == numer_tmp) + mpz_clear(numer); + if (denom == denom_tmp) + mpz_clear(denom); + return make_number(-1, result); + } + + /* ask gawk to allocate return values for us */ + quotient = get_mpz_ptr(); + remainder = get_mpz_ptr(); + + /* do the division */ + mpz_tdiv_qr(quotient, remainder, numer, denom); + + array_set_mpz(array, "quotient", 8, quotient); + array_set_mpz(array, "remainder", 9, remainder); + + /* release temporary variables */ + if (numer == numer_tmp) + mpz_clear(numer); + if (denom == denom_tmp) + mpz_clear(denom); + } +#endif + + return make_number(0, result); +} + +static awk_ext_func_t func_table[] = { + { "api_intdiv", do_intdiv, 3, 3, awk_false, NULL }, +}; + +/* init_intdiv --- initialization routine */ + +static awk_bool_t +init_intdiv(void) +{ +#ifdef HAVE_MPFR + check_mpfr_version(intdiv) +#endif + return awk_true; +} + +static awk_bool_t (*init_func)(void) = init_intdiv; + +/* define the dl_load function using the boilerplate macro */ + +dl_load_func(func_table, intdiv, "") diff --git a/gawkapi.c b/gawkapi.c index 4c6a2f8f..914d4fe7 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -25,6 +25,14 @@ #include "awk.h" +#ifdef HAVE_MPFR +#define getmpfr(n) getblock(n, BLOCK_MPFR, mpfr_ptr) +#define freempfr(n) freeblock(n, BLOCK_MPFR) + +#define getmpz(n) getblock(n, BLOCK_MPZ, mpz_ptr) +#define freempz(n) freeblock(n, BLOCK_MPZ) +#endif + /* Declare some globals used by api_get_file: */ extern IOBUF *curfile; extern INSTRUCTION *main_beginfile; @@ -159,7 +167,36 @@ awk_value_to_node(const awk_value_t *retval) ext_ret_val = dupnode(Nnull_string); break; case AWK_NUMBER: - ext_ret_val = make_number(retval->num_value); + switch (retval->num_type) { + case AWK_NUMBER_TYPE_DOUBLE: + ext_ret_val = make_number(retval->num_value); + break; + case AWK_NUMBER_TYPE_MPFR: +#ifdef HAVE_MPFR + if (! do_mpfr) + fatal(_("awk_value_to_node: not in MPFR mode")); + ext_ret_val = make_number_node(MPFN); + memcpy(&ext_ret_val->mpg_numbr, retval->num_ptr, sizeof(ext_ret_val->mpg_numbr)); + freempfr(retval->num_ptr); +#else + fatal(_("awk_value_to_node: MPFR not supported")); +#endif + break; + case AWK_NUMBER_TYPE_MPZ: +#ifdef HAVE_MPFR + if (! do_mpfr) + fatal(_("awk_value_to_node: not in MPFR mode")); + ext_ret_val = make_number_node(MPZN); + memcpy(&ext_ret_val->mpg_i, retval->num_ptr, sizeof(ext_ret_val->mpg_i)); + freempz(retval->num_ptr); +#else + fatal(_("awk_value_to_node: MPFR not supported")); +#endif + break; + default: + fatal(_("awk_value_to_node: invalid number type `%d'"), retval->num_type); + break; + } break; case AWK_STRING: ext_ret_val = make_str_node(retval->str_value.str, @@ -450,6 +487,34 @@ assign_string(NODE *node, awk_value_t *val, awk_valtype_t val_type) val->str_value.len = node->stlen; } +/* assign_number -- return a number node */ + +static inline void +assign_number(NODE *node, awk_value_t *val) +{ + val->val_type = AWK_NUMBER; + switch (node->flags & (MPFN|MPZN)) { + case 0: + val->num_value = node->numbr; + val->num_type = AWK_NUMBER_TYPE_DOUBLE; + val->num_ptr = NULL; + break; + case MPFN: + val->num_value = mpfr_get_d(node->mpg_numbr, ROUND_MODE); + val->num_type = AWK_NUMBER_TYPE_MPFR; + val->num_ptr = &node->mpg_numbr; + break; + case MPZN: + val->num_value = mpz_get_d(node->mpg_i); + val->num_type = AWK_NUMBER_TYPE_MPZ; + val->num_ptr = &node->mpg_i; + break; + default: + fatal(_("node_to_awk_value: detected invalid numeric flags combination `%s'; please file a bug report."), flags2str(node->flags)); + break; + } +} + /* assign_regex --- return a regex node */ static inline void @@ -502,9 +567,8 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) if (node->flags & REGEX) val->val_type = AWK_REGEX; else { - val->val_type = AWK_NUMBER; (void) force_number(node); - val->num_value = get_number_d(node); + assign_number(node, val); ret = awk_true; } break; @@ -606,8 +670,7 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) ret = awk_true; break; case NUMBER: - val->val_type = AWK_NUMBER; - val->num_value = get_number_d(node); + assign_number(node, val); ret = awk_true; break; case NUMBER|USER_INPUT: @@ -1220,6 +1283,36 @@ api_release_value(awk_ext_id_t id, awk_value_cookie_t value) return awk_true; } +/* api_get_mpfr --- allocate an mpfr_ptr */ + +static void * +api_get_mpfr(awk_ext_id_t id) +{ +#ifdef HAVE_MPFR + mpfr_ptr p; + getmpfr(p); + mpfr_init(p); + return p; +#else + fatal(_("api_get_mpfr: MPFR not supported")); +#endif +} + +/* api_get_mpz --- allocate an mpz_ptr */ + +static void * +api_get_mpz(awk_ext_id_t id) +{ +#ifdef HAVE_MPFR + mpz_ptr p; + getmpz(p); + mpz_init(p); + return p; +#else + fatal(_("api_get_mpfr: MPFR not supported")); +#endif +} + /* api_get_file --- return a handle to an existing or newly opened file */ static awk_bool_t @@ -1347,6 +1440,16 @@ gawk_api_t api_impl = { /* data */ GAWK_API_MAJOR_VERSION, /* major and minor versions */ GAWK_API_MINOR_VERSION, + +#ifdef HAVE_MPFR + __GNU_MP_VERSION, + __GNU_MP_VERSION_MINOR, + MPFR_VERSION_MAJOR, + MPFR_VERSION_MINOR, +#else + 0, 0, 0, 0, +#endif + { 0 }, /* do_flags */ /* registration functions */ @@ -1399,6 +1502,8 @@ gawk_api_t api_impl = { calloc, realloc, free, + api_get_mpfr, + api_get_mpz, /* Find/open a file */ api_get_file, diff --git a/gawkapi.h b/gawkapi.h index 5071adce..5323bcea 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -260,7 +260,7 @@ typedef struct awk_two_way_processor { awk_const struct awk_two_way_processor *awk_const next; /* for use by gawk */ } awk_two_way_processor_t; -#define gawk_api_major_version 2 +#define gawk_api_major_version 3 #define gawk_api_minor_version 0 /* Current version of the API. */ @@ -286,6 +286,16 @@ typedef struct awk_string { size_t len; /* length thereof, in chars */ } awk_string_t; +typedef struct awk_number { + double d; /* always populated in data received from gawk */ + enum AWK_NUMBER_TYPE { + AWK_NUMBER_TYPE_DOUBLE, + AWK_NUMBER_TYPE_MPFR, + AWK_NUMBER_TYPE_MPZ + } type; + void *ptr; /* either NULL or mpfr_ptr or mpz_ptr */ +} awk_number_t; + /* Arrays are represented as an opaque type. */ typedef void *awk_array_t; @@ -321,7 +331,7 @@ typedef struct awk_value { awk_valtype_t val_type; union { awk_string_t s; - double d; + awk_number_t n; awk_array_t a; awk_scalar_t scl; awk_value_cookie_t vc; @@ -329,7 +339,9 @@ typedef struct awk_value { #define str_value u.s #define strnum_value str_value #define regex_value str_value -#define num_value u.d +#define num_value u.n.d +#define num_type u.n.type +#define num_ptr u.n.ptr #define array_cookie u.a #define scalar_cookie u.scl #define value_cookie u.vc @@ -415,6 +427,12 @@ typedef struct gawk_api { awk_const int major_version; awk_const int minor_version; + /* GMP/MPFR versions, if extended-precision is available */ + awk_const int gmp_major_version; + awk_const int gmp_minor_version; + awk_const int mpfr_major_version; + awk_const int mpfr_minor_version; + /* * These can change on the fly as things happen within gawk. * Currently only do_lint is prone to change, but we reserve @@ -711,6 +729,20 @@ typedef struct gawk_api { void *(*api_realloc)(void *ptr, size_t size); void (*api_free)(void *ptr); + /* + * A function that returns mpfr data should call this function + * to allocate and initialize an mpfr_ptr for use in an + * awk_value_t structure that will be handed to gawk. + */ + void *(*api_get_mpfr)(awk_ext_id_t id); + + /* + * A function that returns mpz data should call this function + * to allocate and initialize an mpz_ptr for use in an + * awk_value_t structure that will be handed to gawk. + */ + void *(*api_get_mpz)(awk_ext_id_t id); + /* * Look up a file. If the name is NULL or name_len is 0, it returns * data for the currently open input file corresponding to FILENAME @@ -743,7 +775,6 @@ typedef struct gawk_api { */ const awk_input_buf_t **ibufp, const awk_output_buf_t **obufp); - } gawk_api_t; #ifndef GAWK /* these are not for the gawk code itself! */ @@ -833,6 +864,9 @@ typedef struct gawk_api { #define get_file(name, namelen, filetype, fd, ibuf, obuf) \ (api->api_get_file(ext_id, name, namelen, filetype, fd, ibuf, obuf)) +#define get_mpfr_ptr() (api->api_get_mpfr(ext_id)) +#define get_mpz_ptr() (api->api_get_mpz(ext_id)) + #define register_ext_version(version) \ (api->api_register_ext_version(ext_id, version)) @@ -923,11 +957,39 @@ make_null_string(awk_value_t *result) static inline awk_value_t * make_number(double num, awk_value_t *result) { - memset(result, 0, sizeof(*result)); - result->val_type = AWK_NUMBER; result->num_value = num; + result->num_type = AWK_NUMBER_TYPE_DOUBLE; + return result; +} + +/* + * make_number_mpz --- make an mpz number value in result. + * The mpz_ptr must be from a call to get_mpz_ptr. Gawk will now + * take ownership of this memory. + */ +static inline awk_value_t * +make_number_mpz(void *mpz_ptr, awk_value_t *result) +{ + result->val_type = AWK_NUMBER; + result->num_type = AWK_NUMBER_TYPE_MPZ; + result->num_ptr = mpz_ptr; + return result; +} + +/* + * make_number_mpfr --- make an mpfr number value in result. + * The mpfr_ptr must be from a call to get_mpfr_ptr. Gawk will now + * take ownership of this memory. + */ + +static inline awk_value_t * +make_number_mpfr(void *mpfr_ptr, awk_value_t *result) +{ + result->val_type = AWK_NUMBER; + result->num_type = AWK_NUMBER_TYPE_MPFR; + result->num_ptr = mpfr_ptr; return result; } @@ -1020,6 +1082,29 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ return (errors == 0); \ } +/* + * If you are using extended-precision calculations in your library, please + * call this macro from your init_func. + */ +#define check_mpfr_version(extension) { \ + if (api->gmp_major_version != __GNU_MP_VERSION \ + || api->gmp_minor_version < __GNU_MP_VERSION_MINOR) { \ + fprintf(stderr, #extension ": GMP version mismatch with gawk!\n"); \ + fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n", \ + __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, \ + api->gmp_major_version, api->gmp_minor_version); \ + exit(1); \ + } \ + if (api->mpfr_major_version != MPFR_VERSION_MAJOR \ + || api->mpfr_minor_version < MPFR_VERSION_MINOR) { \ + fprintf(stderr, #extension ": MPFR version mismatch with gawk!\n"); \ + fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n", \ + MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR, \ + api->mpfr_major_version, api->mpfr_minor_version); \ + exit(1); \ + } \ +} + #endif /* GAWK */ #ifdef __cplusplus diff --git a/mpfr.c b/mpfr.c index c0f1ff0c..4b875668 100644 --- a/mpfr.c +++ b/mpfr.c @@ -105,26 +105,14 @@ cleanup_mpfr(void) NODE * mpg_node(unsigned int tp) { - NODE *r; - getnode(r); - r->type = Node_val; + NODE *r = make_number_node(tp); - if (tp == MPFN) { + if (tp == MPFN) /* Initialize, set precision to the default precision, and value to NaN */ mpfr_init(r->mpg_numbr); - r->flags = MPFN; - } else { + else /* Initialize and set value to 0 */ mpz_init(r->mpg_i); - r->flags = MPZN; - } - - r->valref = 1; - r->flags |= MALLOC|NUMBER|NUMCUR; - r->stptr = NULL; - r->stlen = 0; - r->wstptr = NULL; - r->wstlen = 0; return r; } diff --git a/node.c b/node.c index 97f65fa3..b83d2ac2 100644 --- a/node.c +++ b/node.c @@ -332,16 +332,8 @@ r_dupnode(NODE *n) static NODE * r_make_number(double x) { - NODE *r; - getnode(r); - r->type = Node_val; + NODE *r = make_number_node(0); r->numbr = x; - r->flags = MALLOC|NUMBER|NUMCUR; - r->valref = 1; - r->stptr = NULL; - r->stlen = 0; - r->wstptr = NULL; - r->wstlen = 0; return r; } @@ -1005,6 +997,10 @@ BLOCK nextfree[BLOCK_MAX] = { { 0, NULL}, /* invalid */ { sizeof(NODE), NULL }, { sizeof(BUCKET), NULL }, +#ifdef HAVE_MPFR + { sizeof(mpfr_t), NULL }, + { sizeof(mpz_t), NULL }, +#endif }; @@ -1021,6 +1017,7 @@ more_blocks(int id) size = nextfree[id].size; + assert(size >= sizeof(BLOCK)); emalloc(freep, BLOCK *, BLOCKCHUNK * size, "more_blocks"); p = (char *) freep; endp = p + BLOCKCHUNK * size; -- cgit v1.2.3 From bb25148a8e3c8d953f632eb635669abaccedc9a4 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 12 Apr 2017 11:33:05 +0300 Subject: Fix a compiler warning. --- ChangeLog | 5 +++++ gawkapi.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 70b0856e..a785ed5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2017-04-12 Arnold D. Robbins + + * gawkapi.c (awk_value_to_node): Initialize ext_ret_val to NULL + to avoid compiler warnings. + 2017-04-10 Andrew J. Schorr * field.c (set_FIELDWIDTHS): Set use_chars to awk_true, since its diff --git a/gawkapi.c b/gawkapi.c index 914d4fe7..6928c1ce 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -153,7 +153,7 @@ api_set_argument(awk_ext_id_t id, NODE * awk_value_to_node(const awk_value_t *retval) { - NODE *ext_ret_val; + NODE *ext_ret_val = NULL; NODE *v; if (retval == NULL) -- cgit v1.2.3 From 3e6d7cb2ac0e05aaca43b923cc9e2b408f390d01 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 13 Apr 2017 11:40:24 +0300 Subject: Make MPFR division by zero fatal in intdiv.c. Some other cleanups. --- ChangeLog | 14 +++++++++----- awk.h | 11 ++++------- extension/ChangeLog | 6 ++++++ extension/Makefile.in | 16 ++++++++-------- extension/configure | 4 ++-- extension/configure.ac | 4 ++-- extension/intdiv.c | 15 ++++++++++++--- mpfr.c | 6 +++--- 8 files changed, 46 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0a391e15..12e9ab06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2017-04-13 Arnold D. Robbins + + * awk.h (make_number_node): Simplify. + * mpfr.c (mpg_node): Change parameter name to `flags'. + 2017-04-12 Arnold D. Robbins * mpfr.c (mpg_format_val): Set STRCUR flag when we're done. @@ -503,7 +508,7 @@ gmp_minor_version, mpfr_major_version, and mpfr_minor_version. Add functions api_get_mpfr and api_get_mpz to allocate memory for extended-precision numbers to hand to gawk. - (get_mpfr_ptr, get_mpz_ptr): Helper macros to warp api_get_mpfr and + (get_mpfr_ptr, get_mpz_ptr): Helper macros to wrap api_get_mpfr and api_get_mpz. (make_number): Modify to populate awk_number_t correctly. (make_number_mpz, make_number_mpfr): New helper functions to create @@ -512,12 +517,11 @@ in extensions that want to support extended-precision math. * gawkapi.c (getmpfr, freempfr, getmpz, freempz): New macros to allocate and free memory blocks for extended-precision math. - (awk_value_to_node): For AWK_NUMBER values, support 3 different kinds - of internal numbers: double, mpz_t, and mpfr_t. + (awk_value_to_node): For AWK_NUMBER values, support three different + kinds of internal numbers: double, mpz_t, and mpfr_t. (assign_number): New helper function to convert a numeric node to an awk_value_t. - (node_to_awk_value): Use assign_number in a couple of places to - pass numbers properly. + (node_to_awk_value): Use assign_number to pass numbers properly. (api_get_mpfr): Implement new api_get_mpfr hook. (api_get_mpfz): Implement new api_get_mpz hook. (api_impl): Add GMP & MPFR versions, api_get_mpfr, and api_get_mpz. diff --git a/awk.h b/awk.h index 0ab47914..f2ad3ebe 100644 --- a/awk.h +++ b/awk.h @@ -1976,20 +1976,17 @@ erealloc_real(void *ptr, size_t count, const char *where, const char *var, const return ret; } -/* make_number_node --- make node with the give flags */ +/* make_number_node --- make node with the given flags */ static inline NODE * -make_number_node(unsigned int tp) +make_number_node(unsigned int flags) { NODE *r; getnode(r); + memset(r, 0, sizeof(*r)); r->type = Node_val; r->valref = 1; - r->flags = (tp|MALLOC|NUMBER|NUMCUR); - r->stptr = NULL; - r->stlen = 0; - r->wstptr = NULL; - r->wstlen = 0; + r->flags = (flags|MALLOC|NUMBER|NUMCUR); return r; } diff --git a/extension/ChangeLog b/extension/ChangeLog index 87d4358d..784daf21 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,9 @@ +2017-04-13 Arnold D. Robbins + + * configure.ac: Alphabetize function list in AC_CHECK_FUNCS. + * intdiv.c: Add descriptive comments to some functions. + (do_intdiv): Make division by zero fatal in MPFR case. + 2017-04-03 Arnold D. Robbins * inplace.c (inplace_end): Correct the function name in the diff --git a/extension/Makefile.in b/extension/Makefile.in index c386eac6..000c3b78 100644 --- a/extension/Makefile.in +++ b/extension/Makefile.in @@ -284,16 +284,16 @@ am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \ $(fork_la_SOURCES) $(inplace_la_SOURCES) $(intdiv_la_SOURCES) \ - $(ordchr_la_SOURCES) $(readdir_la_SOURCES) $(readdir_test_la_SOURCES) \ - $(readfile_la_SOURCES) $(revoutput_la_SOURCES) \ - $(revtwoway_la_SOURCES) $(rwarray_la_SOURCES) \ - $(testext_la_SOURCES) $(time_la_SOURCES) + $(ordchr_la_SOURCES) $(readdir_la_SOURCES) \ + $(readdir_test_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) $(inplace_la_SOURCES) $(intdiv_la_SOURCES) \ - $(ordchr_la_SOURCES) $(readdir_la_SOURCES) $(readdir_test_la_SOURCES) \ - $(readfile_la_SOURCES) $(revoutput_la_SOURCES) \ - $(revtwoway_la_SOURCES) $(rwarray_la_SOURCES) \ - $(testext_la_SOURCES) $(time_la_SOURCES) + $(ordchr_la_SOURCES) $(readdir_la_SOURCES) \ + $(readdir_test_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 cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ diff --git a/extension/configure b/extension/configure index 580cc150..7ae66543 100755 --- a/extension/configure +++ b/extension/configure @@ -12943,8 +12943,8 @@ $as_echo "#define HAVE_MPFR 1" >>confdefs.h ;; esac -for ac_func in fdopendir fnmatch gettimeofday fmod \ - getdtablesize nanosleep select statvfs GetSystemTimeAsFileTime +for ac_func in fdopendir fmod fnmatch getdtablesize \ + gettimeofday nanosleep select statvfs 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 58935b69..bde6e3d3 100644 --- a/extension/configure.ac +++ b/extension/configure.ac @@ -78,8 +78,8 @@ case `uname -m` in ;; esac -AC_CHECK_FUNCS(fdopendir fnmatch gettimeofday fmod \ - getdtablesize nanosleep select statvfs GetSystemTimeAsFileTime) +AC_CHECK_FUNCS(fdopendir fmod fnmatch getdtablesize \ + gettimeofday nanosleep select statvfs GetSystemTimeAsFileTime) GAWK_FUNC_DIRFD GAWK_PREREQ_DIRFD diff --git a/extension/intdiv.c b/extension/intdiv.c index 2f446c47..bde92893 100644 --- a/extension/intdiv.c +++ b/extension/intdiv.c @@ -29,6 +29,8 @@ static const char *ext_version = "intdiv extension: version 1.0"; int plugin_is_GPL_compatible; +/* double_to_int --- get the integer part of a double */ + static double double_to_int(double d) { @@ -39,6 +41,8 @@ double_to_int(double d) return d; } +/* array_set_number --- set an array element to a numeric value */ + static void array_set_number(awk_array_t array, const char *sub, size_t sublen, double num) { @@ -49,6 +53,8 @@ array_set_number(awk_array_t array, const char *sub, size_t sublen, double num) #ifdef HAVE_MPFR +/* mpz_conv --- convert an awk_value_t to an MPZ value */ + static mpz_ptr mpz_conv(const awk_value_t *arg, mpz_ptr tmp) { @@ -71,6 +77,8 @@ mpz_conv(const awk_value_t *arg, mpz_ptr tmp) } } +/* array_set_mpz --- set an array element to an MPZ value */ + static void array_set_mpz(awk_array_t array, const char *sub, size_t sublen, mpz_ptr num) { @@ -136,8 +144,7 @@ do_intdiv(int nargs, awk_value_t *result, struct awk_ext_func *unused) array_set_number(array, "quotient", 8, quotient); array_set_number(array, "remainder", 9, remainder); #ifdef HAVE_MPFR - } - else { + } else { /* extended precision */ mpz_ptr numer, denom; mpz_t numer_tmp, denom_tmp; @@ -155,11 +162,13 @@ do_intdiv(int nargs, awk_value_t *result, struct awk_ext_func *unused) return make_number(-1, result); } if (mpz_sgn(denom) == 0) { - warning(ext_id, _("intdiv: division by zero attempted")); if (numer == numer_tmp) mpz_clear(numer); if (denom == denom_tmp) mpz_clear(denom); + + fatal(ext_id, _("intdiv: division by zero attempted")); + // won't get here, but keep the compiler happy return make_number(-1, result); } diff --git a/mpfr.c b/mpfr.c index 447e23c6..ea1d5a5b 100644 --- a/mpfr.c +++ b/mpfr.c @@ -103,11 +103,11 @@ cleanup_mpfr(void) /* mpg_node --- allocate a node to store MPFR float or GMP integer */ NODE * -mpg_node(unsigned int tp) +mpg_node(unsigned int flags) { - NODE *r = make_number_node(tp); + NODE *r = make_number_node(flags); - if (tp == MPFN) + if (flags == MPFN) /* Initialize, set precision to the default precision, and value to NaN */ mpfr_init(r->mpg_numbr); else -- cgit v1.2.3 From 3978dea8ddf29e8185cf61d5fba897d58439cade Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 13 Apr 2017 12:47:18 -0400 Subject: For intdiv mpfr division by zero, call fatal without further ado. --- extension/ChangeLog | 5 +++++ extension/intdiv.c | 10 +--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/extension/ChangeLog b/extension/ChangeLog index 784daf21..d8eb6187 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,8 @@ +2017-04-13 Andrew J. Schorr + + * intdiv.c (do_intdiv): On a division by zero fatal error, there's + no need to clear the numerator and denominator and add a fake return. + 2017-04-13 Arnold D. Robbins * configure.ac: Alphabetize function list in AC_CHECK_FUNCS. diff --git a/extension/intdiv.c b/extension/intdiv.c index bde92893..e3dd0eef 100644 --- a/extension/intdiv.c +++ b/extension/intdiv.c @@ -161,16 +161,8 @@ do_intdiv(int nargs, awk_value_t *result, struct awk_ext_func *unused) mpz_clear(numer); return make_number(-1, result); } - if (mpz_sgn(denom) == 0) { - if (numer == numer_tmp) - mpz_clear(numer); - if (denom == denom_tmp) - mpz_clear(denom); - + if (mpz_sgn(denom) == 0) fatal(ext_id, _("intdiv: division by zero attempted")); - // won't get here, but keep the compiler happy - return make_number(-1, result); - } /* ask gawk to allocate return values for us */ quotient = get_mpz_ptr(); -- cgit v1.2.3 From e176d2c3808ae99e805c402ffaccf1fc937e318d Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Fri, 14 Apr 2017 10:27:24 -0400 Subject: In the intdiv extension, division by zero now gives a warning and returns -1 instead of throwing a fatal error. --- extension/ChangeLog | 5 +++++ extension/intdiv.c | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/extension/ChangeLog b/extension/ChangeLog index d8eb6187..ef668467 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,8 @@ +2017-04-14 Andrew J. Schorr + + * intdiv.c (do_intdiv): On division by zero, return -1 and issue a + warning instead of throwing a fatal error. + 2017-04-13 Andrew J. Schorr * intdiv.c (do_intdiv): On a division by zero fatal error, there's diff --git a/extension/intdiv.c b/extension/intdiv.c index e3dd0eef..aa1afd18 100644 --- a/extension/intdiv.c +++ b/extension/intdiv.c @@ -129,8 +129,10 @@ do_intdiv(int nargs, awk_value_t *result, struct awk_ext_func *unused) num = double_to_int(nv.num_value); denom = double_to_int(dv.num_value); - if (denom == 0.0) - fatal(ext_id, _("intdiv: division by zero attempted")); + if (denom == 0.0) { + warning(ext_id, _("intdiv: division by zero attempted")); + return make_number(-1, result); + } quotient = double_to_int(num / denom); #ifdef HAVE_FMOD @@ -161,8 +163,14 @@ do_intdiv(int nargs, awk_value_t *result, struct awk_ext_func *unused) mpz_clear(numer); return make_number(-1, result); } - if (mpz_sgn(denom) == 0) - fatal(ext_id, _("intdiv: division by zero attempted")); + if (mpz_sgn(denom) == 0) { + warning(ext_id, _("intdiv: division by zero attempted")); + if (numer == numer_tmp) + mpz_clear(numer); + if (denom == denom_tmp) + mpz_clear(denom); + return make_number(-1, result); + } /* ask gawk to allocate return values for us */ quotient = get_mpz_ptr(); -- cgit v1.2.3 From 7c3d14eb1d103061939fdcad66bf2b27d78bc5b5 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 16 Apr 2017 12:53:35 +0300 Subject: Rename intdiv to intdiv0, require it to be configured in. --- ChangeLog | 11 + awkgram.c | 6 +- awkgram.y | 6 +- awklib/eg/lib/intdiv.awk | 7 +- builtin.c | 2 + configh.in | 3 + configure | 18 ++ configure.ac | 11 + doc/ChangeLog | 7 + doc/awkcard.in | 6 +- doc/gawk.1 | 2 + doc/gawk.info | 771 +++++++++++++++++++++-------------------------- doc/gawk.texi | 32 +- doc/gawktexi.in | 32 +- extension/ChangeLog | 4 + extension/intdiv.c | 2 +- mpfr.c | 2 + test/ChangeLog | 5 + test/dumpvars.ok | 2 +- test/id.ok | 1 - test/mpfrsqrt.awk | 2 + test/symtab6.ok | 2 +- test/symtab8.ok | 2 +- 23 files changed, 480 insertions(+), 456 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1affea1..cc24d750 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2017-04-16 Arnold D. Robbins + + Rename intdiv it intdiv0 and require enabling at configure time. + + * awkgram.y (tokentab): Bracket intdiv0 in #ifdef SUPPLY_INTDIV. + (snode): Similar. + * builtin.c (do_intdiv): Bracket in #ifdef SUPPLY_INTDIV. + * mpfr.c (do_mpfr_intdiv): Bracket in #ifdef SUPPLY_INTDIV. + * configure.ac: Add --enable-builtin-intdiv0 option. If enabled, + also revise doc/gawktexi.in. + 2017-04-16 Arnold D. Robbins * builtin.c (do_intdiv): Use DEREF on the arguments. diff --git a/awkgram.c b/awkgram.c index 3ad04500..fc935dc4 100644 --- a/awkgram.c +++ b/awkgram.c @@ -4547,7 +4547,9 @@ static const struct token tokentab[] = { {"include", Op_symbol, LEX_INCLUDE, GAWKX, 0, 0}, {"index", Op_builtin, LEX_BUILTIN, A(2), do_index, 0}, {"int", Op_builtin, LEX_BUILTIN, A(1), do_int, MPF(int)}, -{"intdiv", Op_builtin, LEX_BUILTIN, GAWKX|A(3), do_intdiv, MPF(intdiv)}, +#ifdef SUPPLY_INTDIV +{"intdiv0", Op_builtin, LEX_BUILTIN, GAWKX|A(3), do_intdiv, MPF(intdiv)}, +#endif {"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray, 0}, {"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length, 0}, {"load", Op_symbol, LEX_LOAD, GAWKX, 0, 0}, @@ -6846,6 +6848,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) arg = subn->nexti; if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ +#ifdef SUPPLY_INTDIV } else if (r->builtin == do_intdiv #ifdef HAVE_MPFR || r->builtin == MPF(intdiv) @@ -6855,6 +6858,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) ip = arg->lasti; if (ip->opcode == Op_push) ip->opcode = Op_push_array; +#endif /* SUPPLY_INTDIV */ } else if (r->builtin == do_match) { static bool warned = false; diff --git a/awkgram.y b/awkgram.y index 46970eee..3cdb77d3 100644 --- a/awkgram.y +++ b/awkgram.y @@ -2127,7 +2127,9 @@ static const struct token tokentab[] = { {"include", Op_symbol, LEX_INCLUDE, GAWKX, 0, 0}, {"index", Op_builtin, LEX_BUILTIN, A(2), do_index, 0}, {"int", Op_builtin, LEX_BUILTIN, A(1), do_int, MPF(int)}, -{"intdiv", Op_builtin, LEX_BUILTIN, GAWKX|A(3), do_intdiv, MPF(intdiv)}, +#ifdef SUPPLY_INTDIV +{"intdiv0", Op_builtin, LEX_BUILTIN, GAWKX|A(3), do_intdiv, MPF(intdiv)}, +#endif {"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray, 0}, {"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length, 0}, {"load", Op_symbol, LEX_LOAD, GAWKX, 0, 0}, @@ -4426,6 +4428,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) arg = subn->nexti; if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ +#ifdef SUPPLY_INTDIV } else if (r->builtin == do_intdiv #ifdef HAVE_MPFR || r->builtin == MPF(intdiv) @@ -4435,6 +4438,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) ip = arg->lasti; if (ip->opcode == Op_push) ip->opcode = Op_push_array; +#endif /* SUPPLY_INTDIV */ } else if (r->builtin == do_match) { static bool warned = false; diff --git a/awklib/eg/lib/intdiv.awk b/awklib/eg/lib/intdiv.awk index dbc553b0..9de5978e 100644 --- a/awklib/eg/lib/intdiv.awk +++ b/awklib/eg/lib/intdiv.awk @@ -1,4 +1,4 @@ -# intdiv --- do integer division +# intdiv0 --- do integer division # # Arnold Robbins, arnold@skeeve.com, Public Domain @@ -6,8 +6,11 @@ # # Name changed from div() to intdiv() # April, 2015 +# +# Changed to intdiv0() +# April, 2016 -function intdiv(numerator, denominator, result) +function intdiv0(numerator, denominator, result) { split("", result) diff --git a/builtin.c b/builtin.c index 87d9dcb8..b60d8b42 100644 --- a/builtin.c +++ b/builtin.c @@ -3971,6 +3971,7 @@ do_bindtextdomain(int nargs) return make_string(the_result, strlen(the_result)); } +#ifdef SUPPLY_INTDIV /* do_intdiv --- do integer division, return quotient and remainder in dest array */ /* @@ -4039,6 +4040,7 @@ do_intdiv(int nargs) return make_number((AWKNUM) 0.0); } +#endif /* SUPPLY_INTDIV */ /* do_typeof --- return a string with the type of the arg */ diff --git a/configh.in b/configh.in index 41f63d4f..4d5ce95e 100644 --- a/configh.in +++ b/configh.in @@ -377,6 +377,9 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* enable built-in intdiv0 function */ +#undef SUPPLY_INTDIV + /* some systems define this type here */ #undef TIME_T_IN_SYS_TYPES_H diff --git a/configure b/configure index 6832d9da..e7a491bb 100755 --- a/configure +++ b/configure @@ -766,6 +766,7 @@ enable_silent_rules with_whiny_user_strftime enable_lint enable_severe_portability_problems +enable_builtin_intdiv0 enable_dependency_tracking enable_largefile enable_nls @@ -1412,6 +1413,8 @@ Optional Features: --disable-lint Disable gawk lint checking --enable-severe-portability-problems Enable really nasty portability problems + --enable-builtin-intdiv0 + Enable built-in intdiv0 function --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking @@ -3243,6 +3246,21 @@ $as_echo "#define I_DONT_KNOW_WHAT_IM_DOING 1" >>confdefs.h fi +# Check whether --enable-builtin-intdiv0 was given. +if test "${enable_builtin_intdiv0+set}" = set; then : + enableval=$enable_builtin_intdiv0; if test "$enableval" = yes + then + +$as_echo "#define SUPPLY_INTDIV 1" >>confdefs.h + + sed '/^@set PATCHLEVEL/a\ +@set INTDIV' < "$srcdir"/doc/gawktexi.in > foo + cp foo "$srcdir"/doc/gawktexi.in + rm foo + fi + +fi + # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || diff --git a/configure.ac b/configure.ac index 338973b2..e2226ad9 100644 --- a/configure.ac +++ b/configure.ac @@ -67,6 +67,17 @@ AC_ARG_ENABLE([severe-portability-problems], AC_DEFINE(I_DONT_KNOW_WHAT_IM_DOING, 1, [enable severe portability problems]) fi ) +AC_ARG_ENABLE([builtin-intdiv0], + [AS_HELP_STRING([--enable-builtin-intdiv0],[Enable built-in intdiv0 function])], + if test "$enableval" = yes + then + AC_DEFINE(SUPPLY_INTDIV, 1, [enable built-in intdiv0 function]) + sed '/^@set PATCHLEVEL/a\ +@set INTDIV' < "$srcdir"/doc/gawktexi.in > foo + cp foo "$srcdir"/doc/gawktexi.in + rm foo + fi +) AC_CANONICAL_HOST AC_USE_SYSTEM_EXTENSIONS diff --git a/doc/ChangeLog b/doc/ChangeLog index 39fc8021..45876892 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,10 @@ +2017-04-16 Arnold D. Robbins + + * awkcard.in: Comment out description of intdiv(). + * gawk.1: Ditto. + * gawktexi.in: References to intdiv changed to intdiv0 and + bracketed inside @ifset INTDIV. Not set by default. + 2017-04-16 Arnold D. Robbins * gawktexi.in: Improve documentation of the intdiv() function. diff --git a/doc/awkcard.in b/doc/awkcard.in index 86aeee2e..165fca43 100644 --- a/doc/awkcard.in +++ b/doc/awkcard.in @@ -1617,9 +1617,9 @@ l lw(1.9i). \*(FCcos(\*(FIexpr\*(FC)\*(FR The cosine of \*(FIexpr\fP, which is in radians. \*(FCexp(\*(FIexpr\*(FC)\*(FR The exponential function (\*(FIe \*(FC^ \*(FIx\*(FR). \*(FCint(\*(FIexpr\*(FC)\*(FR Truncate to integer. -\*(CB\*(FCintdiv(\*(FIn\*(FR\*(FC,\*(FI d\*(FR\*(FC,\*(FI r\*(FR\*(FC)\*(FR T{ -Return result of integer division in \*(FIr\*(FR.\*(CD -T} +.\" \*(CB\*(FCintdiv(\*(FIn\*(FR\*(FC,\*(FI d\*(FR\*(FC,\*(FI r\*(FR\*(FC)\*(FR T{ +.\" Return result of integer division in \*(FIr\*(FR.\*(CD +.\" T} \*(FClog(\*(FIexpr\*(FC)\*(FR The natural logarithm function (base \*(FIe\^\*(FR). \*(FCrand()\fP A random number \*(FIN\fP such that 0 \(<= \*(FIN\fP < 1. \*(FCsin(\*(FIexpr\*(FC)\*(FR The sine of \*(FIexpr\fP, which is in radians. diff --git a/doc/gawk.1 b/doc/gawk.1 index b04cb013..1b42cc90 100644 --- a/doc/gawk.1 +++ b/doc/gawk.1 @@ -2711,6 +2711,7 @@ The exponential function. .TP .BI int( expr ) Truncate to integer. +.ig .TP .BI intdiv( num ", " denom ", " result ) Truncate @@ -2728,6 +2729,7 @@ This is a .I gawk extension, primarily of value when working with arbitrarily large integers. +.. .TP .BI log( expr ) The natural logarithm function. diff --git a/doc/gawk.info b/doc/gawk.info index 238df1dc..25e9409d 100644 --- a/doc/gawk.info +++ b/doc/gawk.info @@ -12267,24 +12267,6 @@ brackets ([ ]): truncated toward zero. For example, 'int(3)' is 3, 'int(3.9)' is 3, 'int(-3.9)' is -3, and 'int(-3)' is -3 as well. -'intdiv(NUMERATOR, DENOMINATOR, RESULT)' - Perform integer division, similar to the standard C 'div()' - function. First, truncate 'numerator' and 'denominator' towards - zero, creating integer values. Clear the 'result' array, and then - set 'result["quotient"]' to the result of 'numerator / - denominator', truncated towards zero to an integer, and set - 'result["remainder"]' to the result of 'numerator % denominator', - truncated towards zero to an integer. Attempting division by zero - causes a fatal error. The function returns zero upon success, and - -1 upon error. - - This function is primarily intended for use with arbitrary length - integers; it avoids creating MPFR arbitrary precision - floating-point values (*note Arbitrary Precision Integers::). - - This function is a 'gawk' extension. It is not available in - compatibility mode (*note Options::). - 'log(X)' Return the natural logarithm of X, if X is positive; otherwise, return 'NaN' ("not a number") on IEEE 754 systems. Additionally, @@ -23081,59 +23063,7 @@ the following: When dividing two arbitrary precision integers with either '/' or '%', the result is typically an arbitrary precision floating point value -(unless the denominator evenly divides into the numerator). In order to -do integer division or remainder with arbitrary precision integers, use -the built-in 'intdiv()' function (*note Numeric Functions::). - - You can simulate the 'intdiv()' function in standard 'awk' using this -user-defined function: - - # intdiv --- do integer division - - function intdiv(numerator, denominator, result) - { - split("", result) - - numerator = int(numerator) - denominator = int(denominator) - result["quotient"] = int(numerator / denominator) - result["remainder"] = int(numerator % denominator) - - return 0.0 - } - - The following example program, contributed by Katie Wasserman, uses -'intdiv()' to compute the digits of pi to as many places as you choose -to set: - - # pi.awk --- compute the digits of pi - - BEGIN { - digits = 100000 - two = 2 * 10 ^ digits - pi = two - for (m = digits * 4; m > 0; --m) { - d = m * 2 + 1 - x = pi * m - intdiv(x, d, result) - pi = result["quotient"] - pi = pi + two - } - print pi - } - - When asked about the algorithm used, Katie replied: - - It's not that well known but it's not that obscure either. It's - Euler's modification to Newton's method for calculating pi. Take a - look at lines (23) - (25) here: - . - - The algorithm I wrote simply expands the multiply by 2 and works - from the innermost expression outwards. I used this to program HP - calculators because it's quite easy to modify for tiny memory - devices with smallish word sizes. See - . +(unless the denominator evenly divides into the numerator). ---------- Footnotes ---------- @@ -27408,9 +27338,6 @@ current version of 'gawk'. - The 'bindtextdomain()', 'dcgettext()', and 'dcngettext()' functions for internationalization (*note Programmer i18n::) - - The 'intdiv()' function for doing integer division and - remainder (*note Numeric Functions::) - * Changes and/or additions in the command-line options: - The 'AWKPATH' environment variable for specifying a path @@ -27873,8 +27800,6 @@ POSIX 'awk', in the order they were added to 'gawk'. * The 'igawk' program and its manual page are no longer installed when 'gawk' is built. *Note Igawk Program::. - * The 'intdiv()' function. *Note Numeric Functions::. - * The maximum number of hexadecimal digits in '\x' escapes is now two. *Note Escape Sequences::. @@ -34274,8 +34199,6 @@ Index * instruction tracing, in debugger: Debugger Info. (line 90) * int: Numeric Functions. (line 24) * INT signal (MS-Windows): Profiling. (line 212) -* intdiv: Numeric Functions. (line 29) -* intdiv <1>: Numeric Functions. (line 29) * integer array indices: Numeric Array Subscripts. (line 31) * integers, arbitrary precision: Arbitrary Precision Integers. @@ -34425,9 +34348,9 @@ Index * localization: I18N and L10N. (line 6) * localization, See internationalization, localization: I18N and L10N. (line 6) -* log: Numeric Functions. (line 47) +* log: Numeric Functions. (line 29) * log files, timestamps in: Time Functions. (line 6) -* logarithm: Numeric Functions. (line 47) +* logarithm: Numeric Functions. (line 29) * logical false/true: Truth Values. (line 6) * logical operators, See Boolean expressions: Boolean Ops. (line 6) * login information: Passwd Functions. (line 16) @@ -34890,12 +34813,12 @@ Index * Rakitzis, Byron: History Sorting. (line 25) * Ramey, Chet: Acknowledgments. (line 60) * Ramey, Chet <1>: General Data Types. (line 6) -* rand: Numeric Functions. (line 52) +* rand: Numeric Functions. (line 34) * random numbers, Cliff: Cliff Random Function. (line 6) * random numbers, rand()/srand() functions: Numeric Functions. - (line 52) -* random numbers, seed of: Numeric Functions. (line 82) + (line 34) +* random numbers, seed of: Numeric Functions. (line 64) * range expressions (regexps): Bracket Expressions. (line 6) * range patterns: Ranges. (line 6) * range patterns, line continuation and: Ranges. (line 64) @@ -35073,7 +34996,7 @@ Index * sed utility: Full Line Fields. (line 22) * sed utility <1>: Simple Sed. (line 6) * sed utility <2>: Glossary. (line 16) -* seeding random number generator: Numeric Functions. (line 82) +* seeding random number generator: Numeric Functions. (line 64) * semicolon (;), AWKPATH variable and: PC Using. (line 9) * semicolon (;), separating statements in actions: Statements/Lines. (line 90) @@ -35177,8 +35100,8 @@ Index * SIGUSR1 signal, for dynamic profiling: Profiling. (line 186) * silent debugger command: Debugger Execution Control. (line 10) -* sin: Numeric Functions. (line 93) -* sine: Numeric Functions. (line 93) +* sin: Numeric Functions. (line 75) +* sine: Numeric Functions. (line 75) * single quote ('): One-shot. (line 15) * single quote (') in gawk command lines: Long. (line 35) * single quote ('), in shell commands: Quoting. (line 48) @@ -35228,10 +35151,10 @@ Index * sprintf() function, OFMT variable and: User-modified. (line 116) * sprintf() function, print/printf statements and: Round Function. (line 6) -* sqrt: Numeric Functions. (line 96) +* sqrt: Numeric Functions. (line 78) * square brackets ([]), regexp operator: Regexp Operators. (line 56) -* square root: Numeric Functions. (line 96) -* srand: Numeric Functions. (line 100) +* square root: Numeric Functions. (line 78) +* srand: Numeric Functions. (line 82) * stack frame: Debugging Terms. (line 10) * Stallman, Richard: Manual History. (line 6) * Stallman, Richard <1>: Acknowledgments. (line 18) @@ -35791,340 +35714,340 @@ Node: Functions516532 Node: Built-in517570 Node: Calling Built-in518651 Node: Numeric Functions520647 -Ref: Numeric Functions-Footnote-1525592 -Ref: Numeric Functions-Footnote-2525949 -Ref: Numeric Functions-Footnote-3525997 -Node: String Functions526269 -Ref: String Functions-Footnote-1549927 -Ref: String Functions-Footnote-2550055 -Ref: String Functions-Footnote-3550303 -Node: Gory Details550390 -Ref: table-sub-escapes552181 -Ref: table-sub-proposed553700 -Ref: table-posix-sub555063 -Ref: table-gensub-escapes556604 -Ref: Gory Details-Footnote-1557427 -Node: I/O Functions557581 -Ref: table-system-return-values564163 -Ref: I/O Functions-Footnote-1566143 -Ref: I/O Functions-Footnote-2566291 -Node: Time Functions566411 -Ref: Time Functions-Footnote-1577078 -Ref: Time Functions-Footnote-2577146 -Ref: Time Functions-Footnote-3577304 -Ref: Time Functions-Footnote-4577415 -Ref: Time Functions-Footnote-5577527 -Ref: Time Functions-Footnote-6577754 -Node: Bitwise Functions578020 -Ref: table-bitwise-ops578614 -Ref: Bitwise Functions-Footnote-1584647 -Ref: Bitwise Functions-Footnote-2584820 -Node: Type Functions585011 -Node: I18N Functions587686 -Node: User-defined589337 -Node: Definition Syntax590142 -Ref: Definition Syntax-Footnote-1595829 -Node: Function Example595900 -Ref: Function Example-Footnote-1598822 -Node: Function Caveats598844 -Node: Calling A Function599362 -Node: Variable Scope600320 -Node: Pass By Value/Reference603314 -Node: Return Statement606813 -Node: Dynamic Typing609792 -Node: Indirect Calls610722 -Ref: Indirect Calls-Footnote-1620973 -Node: Functions Summary621101 -Node: Library Functions623806 -Ref: Library Functions-Footnote-1627413 -Ref: Library Functions-Footnote-2627556 -Node: Library Names627727 -Ref: Library Names-Footnote-1631187 -Ref: Library Names-Footnote-2631410 -Node: General Functions631496 -Node: Strtonum Function632599 -Node: Assert Function635621 -Node: Round Function638947 -Node: Cliff Random Function640488 -Node: Ordinal Functions641504 -Ref: Ordinal Functions-Footnote-1644567 -Ref: Ordinal Functions-Footnote-2644819 -Node: Join Function645029 -Ref: Join Function-Footnote-1646799 -Node: Getlocaltime Function646999 -Node: Readfile Function650741 -Node: Shell Quoting652713 -Node: Data File Management654114 -Node: Filetrans Function654746 -Node: Rewind Function658842 -Node: File Checking660748 -Ref: File Checking-Footnote-1662082 -Node: Empty Files662283 -Node: Ignoring Assigns664262 -Node: Getopt Function665812 -Ref: Getopt Function-Footnote-1677281 -Node: Passwd Functions677481 -Ref: Passwd Functions-Footnote-1686320 -Node: Group Functions686408 -Ref: Group Functions-Footnote-1694306 -Node: Walking Arrays694513 -Node: Library Functions Summary697521 -Node: Library Exercises698927 -Node: Sample Programs699392 -Node: Running Examples700162 -Node: Clones700890 -Node: Cut Program702114 -Node: Egrep Program712043 -Ref: Egrep Program-Footnote-1719555 -Node: Id Program719665 -Node: Split Program723345 -Ref: Split Program-Footnote-1726804 -Node: Tee Program726933 -Node: Uniq Program729723 -Node: Wc Program737149 -Ref: Wc Program-Footnote-1741404 -Node: Miscellaneous Programs741498 -Node: Dupword Program742711 -Node: Alarm Program744741 -Node: Translate Program749596 -Ref: Translate Program-Footnote-1754161 -Node: Labels Program754431 -Ref: Labels Program-Footnote-1757782 -Node: Word Sorting757866 -Node: History Sorting761938 -Node: Extract Program763773 -Node: Simple Sed771302 -Node: Igawk Program774376 -Ref: Igawk Program-Footnote-1788707 -Ref: Igawk Program-Footnote-2788909 -Ref: Igawk Program-Footnote-3789031 -Node: Anagram Program789146 -Node: Signature Program792208 -Node: Programs Summary793455 -Node: Programs Exercises794669 -Ref: Programs Exercises-Footnote-1798798 -Node: Advanced Features798889 -Node: Nondecimal Data800879 -Node: Array Sorting802470 -Node: Controlling Array Traversal803170 -Ref: Controlling Array Traversal-Footnote-1811537 -Node: Array Sorting Functions811655 -Ref: Array Sorting Functions-Footnote-1816746 -Node: Two-way I/O816942 -Ref: Two-way I/O-Footnote-1823493 -Ref: Two-way I/O-Footnote-2823680 -Node: TCP/IP Networking823762 -Node: Profiling826880 -Ref: Profiling-Footnote-1835552 -Node: Advanced Features Summary835875 -Node: Internationalization837719 -Node: I18N and L10N839199 -Node: Explaining gettext839886 -Ref: Explaining gettext-Footnote-1845778 -Ref: Explaining gettext-Footnote-2845963 -Node: Programmer i18n846128 -Ref: Programmer i18n-Footnote-1851077 -Node: Translator i18n851126 -Node: String Extraction851920 -Ref: String Extraction-Footnote-1853052 -Node: Printf Ordering853138 -Ref: Printf Ordering-Footnote-1855924 -Node: I18N Portability855988 -Ref: I18N Portability-Footnote-1858444 -Node: I18N Example858507 -Ref: I18N Example-Footnote-1861313 -Node: Gawk I18N861386 -Node: I18N Summary862031 -Node: Debugger863372 -Node: Debugging864394 -Node: Debugging Concepts864835 -Node: Debugging Terms866644 -Node: Awk Debugging869219 -Node: Sample Debugging Session870125 -Node: Debugger Invocation870659 -Node: Finding The Bug872045 -Node: List of Debugger Commands878523 -Node: Breakpoint Control879856 -Node: Debugger Execution Control883550 -Node: Viewing And Changing Data886912 -Node: Execution Stack890286 -Node: Debugger Info891923 -Node: Miscellaneous Debugger Commands895994 -Node: Readline Support901082 -Node: Limitations901978 -Node: Debugging Summary904087 -Node: Arbitrary Precision Arithmetic905366 -Node: Computer Arithmetic906782 -Ref: table-numeric-ranges910373 -Ref: Computer Arithmetic-Footnote-1911095 -Node: Math Definitions911152 -Ref: table-ieee-formats914466 -Ref: Math Definitions-Footnote-1915069 -Node: MPFR features915174 -Node: FP Math Caution916891 -Ref: FP Math Caution-Footnote-1917963 -Node: Inexactness of computations918332 -Node: Inexact representation919292 -Node: Comparing FP Values920652 -Node: Errors accumulate921734 -Node: Getting Accuracy923167 -Node: Try To Round925877 -Node: Setting precision926776 -Ref: table-predefined-precision-strings927473 -Node: Setting the rounding mode929303 -Ref: table-gawk-rounding-modes929677 -Ref: Setting the rounding mode-Footnote-1933085 -Node: Arbitrary Precision Integers933264 -Ref: Arbitrary Precision Integers-Footnote-1938181 -Node: POSIX Floating Point Problems938330 -Ref: POSIX Floating Point Problems-Footnote-1942212 -Node: Floating point summary942250 -Node: Dynamic Extensions944440 -Node: Extension Intro945993 -Node: Plugin License947259 -Node: Extension Mechanism Outline948056 -Ref: figure-load-extension948495 -Ref: figure-register-new-function950060 -Ref: figure-call-new-function951152 -Node: Extension API Description953214 -Node: Extension API Functions Introduction954856 -Node: General Data Types960190 -Ref: General Data Types-Footnote-1967395 -Node: Memory Allocation Functions967694 -Ref: Memory Allocation Functions-Footnote-1970539 -Node: Constructor Functions970638 -Node: Registration Functions973637 -Node: Extension Functions974322 -Node: Exit Callback Functions979535 -Node: Extension Version String980785 -Node: Input Parsers981448 -Node: Output Wrappers994155 -Node: Two-way processors998667 -Node: Printing Messages1000932 -Ref: Printing Messages-Footnote-11002103 -Node: Updating ERRNO1002256 -Node: Requesting Values1002995 -Ref: table-value-types-returned1003732 -Node: Accessing Parameters1004668 -Node: Symbol Table Access1005903 -Node: Symbol table by name1006415 -Node: Symbol table by cookie1008204 -Ref: Symbol table by cookie-Footnote-11012389 -Node: Cached values1012453 -Ref: Cached values-Footnote-11015989 -Node: Array Manipulation1016080 -Ref: Array Manipulation-Footnote-11017171 -Node: Array Data Types1017208 -Ref: Array Data Types-Footnote-11019866 -Node: Array Functions1019958 -Node: Flattening Arrays1024357 -Node: Creating Arrays1031298 -Node: Redirection API1036067 -Node: Extension API Variables1038909 -Node: Extension Versioning1039542 -Ref: gawk-api-version1039979 -Node: Extension API Informational Variables1041707 -Node: Extension API Boilerplate1042771 -Node: Changes from API V11046633 -Node: Finding Extensions1047293 -Node: Extension Example1047852 -Node: Internal File Description1048650 -Node: Internal File Ops1052730 -Ref: Internal File Ops-Footnote-11064130 -Node: Using Internal File Ops1064270 -Ref: Using Internal File Ops-Footnote-11066653 -Node: Extension Samples1066927 -Node: Extension Sample File Functions1068456 -Node: Extension Sample Fnmatch1076105 -Node: Extension Sample Fork1077592 -Node: Extension Sample Inplace1078810 -Node: Extension Sample Ord1082020 -Node: Extension Sample Readdir1082856 -Ref: table-readdir-file-types1083745 -Node: Extension Sample Revout1084550 -Node: Extension Sample Rev2way1085139 -Node: Extension Sample Read write array1085879 -Node: Extension Sample Readfile1087821 -Node: Extension Sample Time1088916 -Node: Extension Sample API Tests1090264 -Node: gawkextlib1090756 -Node: Extension summary1093203 -Node: Extension Exercises1096905 -Node: Language History1098403 -Node: V7/SVR3.11100059 -Node: SVR41102211 -Node: POSIX1103645 -Node: BTL1105024 -Node: POSIX/GNU1105753 -Node: Feature History1111645 -Node: Common Extensions1126015 -Node: Ranges and Locales1127298 -Ref: Ranges and Locales-Footnote-11131914 -Ref: Ranges and Locales-Footnote-21131941 -Ref: Ranges and Locales-Footnote-31132176 -Node: Contributors1132397 -Node: History summary1137957 -Node: Installation1139337 -Node: Gawk Distribution1140281 -Node: Getting1140765 -Node: Extracting1141726 -Node: Distribution contents1143364 -Node: Unix Installation1149706 -Node: Quick Installation1150388 -Node: Shell Startup Files1152802 -Node: Additional Configuration Options1153891 -Node: Configuration Philosophy1155696 -Node: Non-Unix Installation1158065 -Node: PC Installation1158525 -Node: PC Binary Installation1159363 -Node: PC Compiling1159798 -Node: PC Using1160915 -Node: Cygwin1163960 -Node: MSYS1164730 -Node: VMS Installation1165231 -Node: VMS Compilation1166022 -Ref: VMS Compilation-Footnote-11167251 -Node: VMS Dynamic Extensions1167309 -Node: VMS Installation Details1168994 -Node: VMS Running1171247 -Node: VMS GNV1175526 -Node: VMS Old Gawk1176261 -Node: Bugs1176732 -Node: Bug address1177395 -Node: Usenet1179792 -Node: Maintainers1180569 -Node: Other Versions1181945 -Node: Installation summary1188529 -Node: Notes1189564 -Node: Compatibility Mode1190429 -Node: Additions1191211 -Node: Accessing The Source1192136 -Node: Adding Code1193571 -Node: New Ports1199789 -Node: Derived Files1204277 -Ref: Derived Files-Footnote-11209762 -Ref: Derived Files-Footnote-21209797 -Ref: Derived Files-Footnote-31210395 -Node: Future Extensions1210509 -Node: Implementation Limitations1211167 -Node: Extension Design1212350 -Node: Old Extension Problems1213504 -Ref: Old Extension Problems-Footnote-11215022 -Node: Extension New Mechanism Goals1215079 -Ref: Extension New Mechanism Goals-Footnote-11218443 -Node: Extension Other Design Decisions1218632 -Node: Extension Future Growth1220745 -Node: Old Extension Mechanism1221581 -Node: Notes summary1223344 -Node: Basic Concepts1224526 -Node: Basic High Level1225207 -Ref: figure-general-flow1225489 -Ref: figure-process-flow1226174 -Ref: Basic High Level-Footnote-11229475 -Node: Basic Data Typing1229660 -Node: Glossary1232988 -Node: Copying1264935 -Node: GNU Free Documentation License1302474 -Node: Index1327592 +Ref: Numeric Functions-Footnote-1524675 +Ref: Numeric Functions-Footnote-2525032 +Ref: Numeric Functions-Footnote-3525080 +Node: String Functions525352 +Ref: String Functions-Footnote-1549010 +Ref: String Functions-Footnote-2549138 +Ref: String Functions-Footnote-3549386 +Node: Gory Details549473 +Ref: table-sub-escapes551264 +Ref: table-sub-proposed552783 +Ref: table-posix-sub554146 +Ref: table-gensub-escapes555687 +Ref: Gory Details-Footnote-1556510 +Node: I/O Functions556664 +Ref: table-system-return-values563246 +Ref: I/O Functions-Footnote-1565226 +Ref: I/O Functions-Footnote-2565374 +Node: Time Functions565494 +Ref: Time Functions-Footnote-1576161 +Ref: Time Functions-Footnote-2576229 +Ref: Time Functions-Footnote-3576387 +Ref: Time Functions-Footnote-4576498 +Ref: Time Functions-Footnote-5576610 +Ref: Time Functions-Footnote-6576837 +Node: Bitwise Functions577103 +Ref: table-bitwise-ops577697 +Ref: Bitwise Functions-Footnote-1583730 +Ref: Bitwise Functions-Footnote-2583903 +Node: Type Functions584094 +Node: I18N Functions586769 +Node: User-defined588420 +Node: Definition Syntax589225 +Ref: Definition Syntax-Footnote-1594912 +Node: Function Example594983 +Ref: Function Example-Footnote-1597905 +Node: Function Caveats597927 +Node: Calling A Function598445 +Node: Variable Scope599403 +Node: Pass By Value/Reference602397 +Node: Return Statement605896 +Node: Dynamic Typing608875 +Node: Indirect Calls609805 +Ref: Indirect Calls-Footnote-1620056 +Node: Functions Summary620184 +Node: Library Functions622889 +Ref: Library Functions-Footnote-1626496 +Ref: Library Functions-Footnote-2626639 +Node: Library Names626810 +Ref: Library Names-Footnote-1630270 +Ref: Library Names-Footnote-2630493 +Node: General Functions630579 +Node: Strtonum Function631682 +Node: Assert Function634704 +Node: Round Function638030 +Node: Cliff Random Function639571 +Node: Ordinal Functions640587 +Ref: Ordinal Functions-Footnote-1643650 +Ref: Ordinal Functions-Footnote-2643902 +Node: Join Function644112 +Ref: Join Function-Footnote-1645882 +Node: Getlocaltime Function646082 +Node: Readfile Function649824 +Node: Shell Quoting651796 +Node: Data File Management653197 +Node: Filetrans Function653829 +Node: Rewind Function657925 +Node: File Checking659831 +Ref: File Checking-Footnote-1661165 +Node: Empty Files661366 +Node: Ignoring Assigns663345 +Node: Getopt Function664895 +Ref: Getopt Function-Footnote-1676364 +Node: Passwd Functions676564 +Ref: Passwd Functions-Footnote-1685403 +Node: Group Functions685491 +Ref: Group Functions-Footnote-1693389 +Node: Walking Arrays693596 +Node: Library Functions Summary696604 +Node: Library Exercises698010 +Node: Sample Programs698475 +Node: Running Examples699245 +Node: Clones699973 +Node: Cut Program701197 +Node: Egrep Program711126 +Ref: Egrep Program-Footnote-1718638 +Node: Id Program718748 +Node: Split Program722428 +Ref: Split Program-Footnote-1725887 +Node: Tee Program726016 +Node: Uniq Program728806 +Node: Wc Program736232 +Ref: Wc Program-Footnote-1740487 +Node: Miscellaneous Programs740581 +Node: Dupword Program741794 +Node: Alarm Program743824 +Node: Translate Program748679 +Ref: Translate Program-Footnote-1753244 +Node: Labels Program753514 +Ref: Labels Program-Footnote-1756865 +Node: Word Sorting756949 +Node: History Sorting761021 +Node: Extract Program762856 +Node: Simple Sed770385 +Node: Igawk Program773459 +Ref: Igawk Program-Footnote-1787790 +Ref: Igawk Program-Footnote-2787992 +Ref: Igawk Program-Footnote-3788114 +Node: Anagram Program788229 +Node: Signature Program791291 +Node: Programs Summary792538 +Node: Programs Exercises793752 +Ref: Programs Exercises-Footnote-1797881 +Node: Advanced Features797972 +Node: Nondecimal Data799962 +Node: Array Sorting801553 +Node: Controlling Array Traversal802253 +Ref: Controlling Array Traversal-Footnote-1810620 +Node: Array Sorting Functions810738 +Ref: Array Sorting Functions-Footnote-1815829 +Node: Two-way I/O816025 +Ref: Two-way I/O-Footnote-1822576 +Ref: Two-way I/O-Footnote-2822763 +Node: TCP/IP Networking822845 +Node: Profiling825963 +Ref: Profiling-Footnote-1834635 +Node: Advanced Features Summary834958 +Node: Internationalization836802 +Node: I18N and L10N838282 +Node: Explaining gettext838969 +Ref: Explaining gettext-Footnote-1844861 +Ref: Explaining gettext-Footnote-2845046 +Node: Programmer i18n845211 +Ref: Programmer i18n-Footnote-1850160 +Node: Translator i18n850209 +Node: String Extraction851003 +Ref: String Extraction-Footnote-1852135 +Node: Printf Ordering852221 +Ref: Printf Ordering-Footnote-1855007 +Node: I18N Portability855071 +Ref: I18N Portability-Footnote-1857527 +Node: I18N Example857590 +Ref: I18N Example-Footnote-1860396 +Node: Gawk I18N860469 +Node: I18N Summary861114 +Node: Debugger862455 +Node: Debugging863477 +Node: Debugging Concepts863918 +Node: Debugging Terms865727 +Node: Awk Debugging868302 +Node: Sample Debugging Session869208 +Node: Debugger Invocation869742 +Node: Finding The Bug871128 +Node: List of Debugger Commands877606 +Node: Breakpoint Control878939 +Node: Debugger Execution Control882633 +Node: Viewing And Changing Data885995 +Node: Execution Stack889369 +Node: Debugger Info891006 +Node: Miscellaneous Debugger Commands895077 +Node: Readline Support900165 +Node: Limitations901061 +Node: Debugging Summary903170 +Node: Arbitrary Precision Arithmetic904449 +Node: Computer Arithmetic905865 +Ref: table-numeric-ranges909456 +Ref: Computer Arithmetic-Footnote-1910178 +Node: Math Definitions910235 +Ref: table-ieee-formats913549 +Ref: Math Definitions-Footnote-1914152 +Node: MPFR features914257 +Node: FP Math Caution915974 +Ref: FP Math Caution-Footnote-1917046 +Node: Inexactness of computations917415 +Node: Inexact representation918375 +Node: Comparing FP Values919735 +Node: Errors accumulate920817 +Node: Getting Accuracy922250 +Node: Try To Round924960 +Node: Setting precision925859 +Ref: table-predefined-precision-strings926556 +Node: Setting the rounding mode928386 +Ref: table-gawk-rounding-modes928760 +Ref: Setting the rounding mode-Footnote-1932168 +Node: Arbitrary Precision Integers932347 +Ref: Arbitrary Precision Integers-Footnote-1935534 +Node: POSIX Floating Point Problems935683 +Ref: POSIX Floating Point Problems-Footnote-1939565 +Node: Floating point summary939603 +Node: Dynamic Extensions941793 +Node: Extension Intro943346 +Node: Plugin License944612 +Node: Extension Mechanism Outline945409 +Ref: figure-load-extension945848 +Ref: figure-register-new-function947413 +Ref: figure-call-new-function948505 +Node: Extension API Description950567 +Node: Extension API Functions Introduction952209 +Node: General Data Types957543 +Ref: General Data Types-Footnote-1964748 +Node: Memory Allocation Functions965047 +Ref: Memory Allocation Functions-Footnote-1967892 +Node: Constructor Functions967991 +Node: Registration Functions970990 +Node: Extension Functions971675 +Node: Exit Callback Functions976888 +Node: Extension Version String978138 +Node: Input Parsers978801 +Node: Output Wrappers991508 +Node: Two-way processors996020 +Node: Printing Messages998285 +Ref: Printing Messages-Footnote-1999456 +Node: Updating ERRNO999609 +Node: Requesting Values1000348 +Ref: table-value-types-returned1001085 +Node: Accessing Parameters1002021 +Node: Symbol Table Access1003256 +Node: Symbol table by name1003768 +Node: Symbol table by cookie1005557 +Ref: Symbol table by cookie-Footnote-11009742 +Node: Cached values1009806 +Ref: Cached values-Footnote-11013342 +Node: Array Manipulation1013433 +Ref: Array Manipulation-Footnote-11014524 +Node: Array Data Types1014561 +Ref: Array Data Types-Footnote-11017219 +Node: Array Functions1017311 +Node: Flattening Arrays1021710 +Node: Creating Arrays1028651 +Node: Redirection API1033420 +Node: Extension API Variables1036262 +Node: Extension Versioning1036895 +Ref: gawk-api-version1037332 +Node: Extension API Informational Variables1039060 +Node: Extension API Boilerplate1040124 +Node: Changes from API V11043986 +Node: Finding Extensions1044646 +Node: Extension Example1045205 +Node: Internal File Description1046003 +Node: Internal File Ops1050083 +Ref: Internal File Ops-Footnote-11061483 +Node: Using Internal File Ops1061623 +Ref: Using Internal File Ops-Footnote-11064006 +Node: Extension Samples1064280 +Node: Extension Sample File Functions1065809 +Node: Extension Sample Fnmatch1073458 +Node: Extension Sample Fork1074945 +Node: Extension Sample Inplace1076163 +Node: Extension Sample Ord1079373 +Node: Extension Sample Readdir1080209 +Ref: table-readdir-file-types1081098 +Node: Extension Sample Revout1081903 +Node: Extension Sample Rev2way1082492 +Node: Extension Sample Read write array1083232 +Node: Extension Sample Readfile1085174 +Node: Extension Sample Time1086269 +Node: Extension Sample API Tests1087617 +Node: gawkextlib1088109 +Node: Extension summary1090556 +Node: Extension Exercises1094258 +Node: Language History1095756 +Node: V7/SVR3.11097412 +Node: SVR41099564 +Node: POSIX1100998 +Node: BTL1102377 +Node: POSIX/GNU1103106 +Node: Feature History1108884 +Node: Common Extensions1123195 +Node: Ranges and Locales1124478 +Ref: Ranges and Locales-Footnote-11129094 +Ref: Ranges and Locales-Footnote-21129121 +Ref: Ranges and Locales-Footnote-31129356 +Node: Contributors1129577 +Node: History summary1135137 +Node: Installation1136517 +Node: Gawk Distribution1137461 +Node: Getting1137945 +Node: Extracting1138906 +Node: Distribution contents1140544 +Node: Unix Installation1146886 +Node: Quick Installation1147568 +Node: Shell Startup Files1149982 +Node: Additional Configuration Options1151071 +Node: Configuration Philosophy1152876 +Node: Non-Unix Installation1155245 +Node: PC Installation1155705 +Node: PC Binary Installation1156543 +Node: PC Compiling1156978 +Node: PC Using1158095 +Node: Cygwin1161140 +Node: MSYS1161910 +Node: VMS Installation1162411 +Node: VMS Compilation1163202 +Ref: VMS Compilation-Footnote-11164431 +Node: VMS Dynamic Extensions1164489 +Node: VMS Installation Details1166174 +Node: VMS Running1168427 +Node: VMS GNV1172706 +Node: VMS Old Gawk1173441 +Node: Bugs1173912 +Node: Bug address1174575 +Node: Usenet1176972 +Node: Maintainers1177749 +Node: Other Versions1179125 +Node: Installation summary1185709 +Node: Notes1186744 +Node: Compatibility Mode1187609 +Node: Additions1188391 +Node: Accessing The Source1189316 +Node: Adding Code1190751 +Node: New Ports1196969 +Node: Derived Files1201457 +Ref: Derived Files-Footnote-11206942 +Ref: Derived Files-Footnote-21206977 +Ref: Derived Files-Footnote-31207575 +Node: Future Extensions1207689 +Node: Implementation Limitations1208347 +Node: Extension Design1209530 +Node: Old Extension Problems1210684 +Ref: Old Extension Problems-Footnote-11212202 +Node: Extension New Mechanism Goals1212259 +Ref: Extension New Mechanism Goals-Footnote-11215623 +Node: Extension Other Design Decisions1215812 +Node: Extension Future Growth1217925 +Node: Old Extension Mechanism1218761 +Node: Notes summary1220524 +Node: Basic Concepts1221706 +Node: Basic High Level1222387 +Ref: figure-general-flow1222669 +Ref: figure-process-flow1223354 +Ref: Basic High Level-Footnote-11226655 +Node: Basic Data Typing1226840 +Node: Glossary1230168 +Node: Copying1262115 +Node: GNU Free Documentation License1299654 +Node: Index1324772  End Tag Table diff --git a/doc/gawk.texi b/doc/gawk.texi index fa8c6664..d374c93a 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -17458,9 +17458,10 @@ truncated toward zero. For example, @code{int(3)} is 3, @code{int(3.9)} is 3, @code{int(-3.9)} is @minus{}3, and @code{int(-3)} is @minus{}3 as well. -@item @code{intdiv(@var{numerator}, @var{denominator}, @var{result})} -@cindexawkfunc{intdiv} -@cindex intdiv +@ifset INTDIV +@item @code{intdiv0(@var{numerator}, @var{denominator}, @var{result})} +@cindexawkfunc{intdiv0} +@cindex intdiv0 Perform integer division, similar to the standard C @code{div()} function. First, truncate @code{numerator} and @code{denominator} towards zero, creating integer values. Clear the @code{result} @@ -17478,6 +17479,7 @@ Precision Integers}). This function is a @code{gawk} extension. It is not available in compatibility mode (@pxref{Options}). +@end ifset @item @code{log(@var{x})} @cindexawkfunc{log} @@ -31907,16 +31909,18 @@ gawk -M 'BEGIN @{ n = 13; print n % 2 @}' When dividing two arbitrary precision integers with either @samp{/} or @samp{%}, the result is typically an arbitrary precision floating point value (unless the denominator evenly -divides into the numerator). In order to do integer division +divides into the numerator). +@ifset INTDIV +In order to do integer division or remainder with arbitrary precision integers, use the built-in -@code{intdiv()} function (@pxref{Numeric Functions}). +@code{intdiv0()} function (@pxref{Numeric Functions}). -You can simulate the @code{intdiv()} function in standard @command{awk} +You can simulate the @code{intdiv0()} function in standard @command{awk} using this user-defined function: @example @c file eg/lib/intdiv.awk -# intdiv --- do integer division +# intdiv0 --- do integer division @c endfile @ignore @@ -31927,12 +31931,15 @@ using this user-defined function: # # Name changed from div() to intdiv() # April, 2015 +# +# Changed to intdiv0() +# April, 2016 @c endfile @end ignore @c file eg/lib/intdiv.awk -function intdiv(numerator, denominator, result) +function intdiv0(numerator, denominator, result) @{ split("", result) @@ -32019,6 +32026,7 @@ because it's quite easy to modify for tiny memory devices with smallish word sizes. See @uref{http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899}. @end quotation +@end ifset @node POSIX Floating Point Problems @section Standards Versus Existing Practice @@ -37067,10 +37075,12 @@ The @code{bindtextdomain()}, @code{dcgettext()}, and @code{dcngettext()} functions for internationalization (@pxref{Programmer i18n}) +@ifset INTDIV @item -The @code{intdiv()} function for doing integer +The @code{intdiv0()} function for doing integer division and remainder (@pxref{Numeric Functions}) +@end ifset @end itemize @item @@ -37862,9 +37872,11 @@ The @command{igawk} program and its manual page are no longer installed when @command{gawk} is built. @xref{Igawk Program}. +@ifset INTDIV @item -The @code{intdiv()} function. +The @code{intdiv0()} function. @xref{Numeric Functions}. +@end ifset @item The maximum number of hexadecimal digits in @samp{\x} escapes diff --git a/doc/gawktexi.in b/doc/gawktexi.in index 21c6e506..9d7be49a 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -16731,9 +16731,10 @@ truncated toward zero. For example, @code{int(3)} is 3, @code{int(3.9)} is 3, @code{int(-3.9)} is @minus{}3, and @code{int(-3)} is @minus{}3 as well. -@item @code{intdiv(@var{numerator}, @var{denominator}, @var{result})} -@cindexawkfunc{intdiv} -@cindex intdiv +@ifset INTDIV +@item @code{intdiv0(@var{numerator}, @var{denominator}, @var{result})} +@cindexawkfunc{intdiv0} +@cindex intdiv0 Perform integer division, similar to the standard C @code{div()} function. First, truncate @code{numerator} and @code{denominator} towards zero, creating integer values. Clear the @code{result} @@ -16751,6 +16752,7 @@ Precision Integers}). This function is a @code{gawk} extension. It is not available in compatibility mode (@pxref{Options}). +@end ifset @item @code{log(@var{x})} @cindexawkfunc{log} @@ -30921,16 +30923,18 @@ gawk -M 'BEGIN @{ n = 13; print n % 2 @}' When dividing two arbitrary precision integers with either @samp{/} or @samp{%}, the result is typically an arbitrary precision floating point value (unless the denominator evenly -divides into the numerator). In order to do integer division +divides into the numerator). +@ifset INTDIV +In order to do integer division or remainder with arbitrary precision integers, use the built-in -@code{intdiv()} function (@pxref{Numeric Functions}). +@code{intdiv0()} function (@pxref{Numeric Functions}). -You can simulate the @code{intdiv()} function in standard @command{awk} +You can simulate the @code{intdiv0()} function in standard @command{awk} using this user-defined function: @example @c file eg/lib/intdiv.awk -# intdiv --- do integer division +# intdiv0 --- do integer division @c endfile @ignore @@ -30941,12 +30945,15 @@ using this user-defined function: # # Name changed from div() to intdiv() # April, 2015 +# +# Changed to intdiv0() +# April, 2016 @c endfile @end ignore @c file eg/lib/intdiv.awk -function intdiv(numerator, denominator, result) +function intdiv0(numerator, denominator, result) @{ split("", result) @@ -31033,6 +31040,7 @@ because it's quite easy to modify for tiny memory devices with smallish word sizes. See @uref{http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899}. @end quotation +@end ifset @node POSIX Floating Point Problems @section Standards Versus Existing Practice @@ -36081,10 +36089,12 @@ The @code{bindtextdomain()}, @code{dcgettext()}, and @code{dcngettext()} functions for internationalization (@pxref{Programmer i18n}) +@ifset INTDIV @item -The @code{intdiv()} function for doing integer +The @code{intdiv0()} function for doing integer division and remainder (@pxref{Numeric Functions}) +@end ifset @end itemize @item @@ -36876,9 +36886,11 @@ The @command{igawk} program and its manual page are no longer installed when @command{gawk} is built. @xref{Igawk Program}. +@ifset INTDIV @item -The @code{intdiv()} function. +The @code{intdiv0()} function. @xref{Numeric Functions}. +@end ifset @item The maximum number of hexadecimal digits in @samp{\x} escapes diff --git a/extension/ChangeLog b/extension/ChangeLog index ef668467..7307a11a 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,7 @@ +2017-04-16 Arnold D. Robbins + + * intdiv.c (func_table): Function is now named intdiv. + 2017-04-14 Andrew J. Schorr * intdiv.c (do_intdiv): On division by zero, return -1 and issue a diff --git a/extension/intdiv.c b/extension/intdiv.c index aa1afd18..77b4290b 100644 --- a/extension/intdiv.c +++ b/extension/intdiv.c @@ -194,7 +194,7 @@ do_intdiv(int nargs, awk_value_t *result, struct awk_ext_func *unused) } static awk_ext_func_t func_table[] = { - { "api_intdiv", do_intdiv, 3, 3, awk_false, NULL }, + { "intdiv", do_intdiv, 3, 3, awk_false, NULL }, }; /* init_intdiv --- initialization routine */ diff --git a/mpfr.c b/mpfr.c index f02c27b4..a8a517c3 100644 --- a/mpfr.c +++ b/mpfr.c @@ -1169,6 +1169,7 @@ do_mpfr_srand(int nargs) return res; } +#ifdef SUPPLY_INTDIV /* do_mpfr_intdiv --- do integer division, return quotient and remainder in dest array */ /* @@ -1262,6 +1263,7 @@ do_mpfr_intdiv(int nargs) return make_number((AWKNUM) 0.0); } +#endif /* SUPPLY_INTDIV */ /* * mpg_tofloat --- convert an arbitrary-precision integer operand to diff --git a/test/ChangeLog b/test/ChangeLog index ecac0519..04077f1e 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2017-04-16 Arnold D. Robbins + + * mpfrsqrt.awk: Add `@load intdiv'. + * dumpvars.ok, id.ok, symtab6.ok, symtab8.ok: Updated. + 2017-04-12 Manuel Collado * Makefile.am (fpat6): New test. diff --git a/test/dumpvars.ok b/test/dumpvars.ok index 7caecd35..85d1c859 100644 --- a/test/dumpvars.ok +++ b/test/dumpvars.ok @@ -9,7 +9,7 @@ FILENAME: "-" FNR: 3 FPAT: "[^[:space:]]+" FS: " " -FUNCTAB: array, 42 elements +FUNCTAB: array, 41 elements IGNORECASE: 0 LINT: 0 NF: 1 diff --git a/test/id.ok b/test/id.ok index 7454a4fc..79130657 100644 --- a/test/id.ok +++ b/test/id.ok @@ -47,7 +47,6 @@ gsub -> builtin i -> untyped index -> builtin int -> builtin -intdiv -> builtin isarray -> builtin length -> builtin log -> builtin diff --git a/test/mpfrsqrt.awk b/test/mpfrsqrt.awk index 3fb1f5f8..8cc416bb 100644 --- a/test/mpfrsqrt.awk +++ b/test/mpfrsqrt.awk @@ -9,6 +9,8 @@ # # Running this program (sqrt-bug.awk): # -------------------------------------------------------------------- + +@load "intdiv" BEGIN { a=11111111111111111111111111111111111111111111111111111111111 print sqrt(a^2) diff --git a/test/symtab6.ok b/test/symtab6.ok index 34c10636..7de717a0 100644 --- a/test/symtab6.ok +++ b/test/symtab6.ok @@ -9,7 +9,7 @@ FILENAME: "" FNR: 0 FPAT: "[^[:space:]]+" FS: " " -FUNCTAB: array, 42 elements +FUNCTAB: array, 41 elements IGNORECASE: 0 LINT: 0 NF: 0 diff --git a/test/symtab8.ok b/test/symtab8.ok index 0cf40fe9..da29b585 100644 --- a/test/symtab8.ok +++ b/test/symtab8.ok @@ -9,7 +9,7 @@ FIELDWIDTHS: "" FNR: 1 FPAT: "[^[:space:]]+" FS: " " -FUNCTAB: array, 42 elements +FUNCTAB: array, 41 elements IGNORECASE: 0 LINT: 0 NF: 1 -- cgit v1.2.3 From 454efb85895d4194da67e0dcc244a54bcc9a1964 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Mon, 26 Jun 2017 06:17:38 +0300 Subject: Minor edit in configure.ac. --- ChangeLog | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f11b08d0..a6039f5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-06-26 Arnold D. Robbins + + * configure.ac: Turn a tab into a space in AC_DEFINE(SUPPLY_INTDIV). + 2017-06-22 Arnold D. Robbins Make pretty-printing include parentheses that were explicitly diff --git a/configure.ac b/configure.ac index 79a70e3f..785f5c5b 100644 --- a/configure.ac +++ b/configure.ac @@ -71,7 +71,7 @@ AC_ARG_ENABLE([builtin-intdiv0], [AS_HELP_STRING([--enable-builtin-intdiv0],[enable built-in intdiv0 function])], if test "$enableval" = yes then - AC_DEFINE(SUPPLY_INTDIV, 1, [enable built-in intdiv0 function]) + AC_DEFINE(SUPPLY_INTDIV, 1, [enable built-in intdiv0 function]) sed '/^@set PATCHLEVEL/a\ @set INTDIV' < "$srcdir"/doc/gawktexi.in > foo cp foo "$srcdir"/doc/gawktexi.in -- cgit v1.2.3 From 2d4dafd7cd5b9c11acfdf54c4ba04d53f361307e Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 27 Jun 2017 06:17:11 +0300 Subject: Fix intdiv extension to build on Cygwin. --- extension/ChangeLog | 5 +++++ extension/Makefile.am | 5 +++-- extension/Makefile.in | 8 +++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/extension/ChangeLog b/extension/ChangeLog index 7c8a828a..9315f752 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,8 @@ +2017-06-27 Arnold D. Robbins + + * Makfile.am (intdiv_la_LIBADD): Add LIBMPFR for Cygwin. + Thanks to Eli Zaretskii for the tip that this is necessary. + 2017-06-22 Andrew J. Schorr * rwarray.c (read_value): Use malloc instead of calloc, since diff --git a/extension/Makefile.am b/extension/Makefile.am index 54975b8e..1d8e5b03 100644 --- a/extension/Makefile.am +++ b/extension/Makefile.am @@ -53,7 +53,7 @@ noinst_LTLIBRARIES = \ testext.la MY_MODULE_FLAGS = -module -avoid-version -no-undefined -# on Cygwin, gettext requires that we link with -lintl +# On Cygwin, gettext requires that we link with -lintl MY_LIBS = $(LTLIBINTL) filefuncs_la_SOURCES = filefuncs.c stack.h stack.c gawkfts.h \ @@ -73,9 +73,10 @@ inplace_la_SOURCES = inplace.c inplace_la_LDFLAGS = $(MY_MODULE_FLAGS) inplace_la_LIBADD = $(MY_LIBS) +# On Cygwin, intdiv has to be linked with the MPFR and GMP libraries intdiv_la_SOURCES = intdiv.c intdiv_la_LDFLAGS = $(MY_MODULE_FLAGS) -intdiv_la_LIBADD = $(MY_LIBS) +intdiv_la_LIBADD = $(MY_LIBS) $(LIBMPFR) ordchr_la_SOURCES = ordchr.c ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS) diff --git a/extension/Makefile.in b/extension/Makefile.in index 000c3b78..6c0f2544 100644 --- a/extension/Makefile.in +++ b/extension/Makefile.in @@ -187,7 +187,7 @@ inplace_la_OBJECTS = $(am_inplace_la_OBJECTS) inplace_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(inplace_la_LDFLAGS) $(LDFLAGS) -o $@ -intdiv_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +intdiv_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_intdiv_la_OBJECTS = intdiv.lo intdiv_la_OBJECTS = $(am_intdiv_la_OBJECTS) intdiv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -541,7 +541,7 @@ noinst_LTLIBRARIES = \ testext.la MY_MODULE_FLAGS = -module -avoid-version -no-undefined -# on Cygwin, gettext requires that we link with -lintl +# On Cygwin, gettext requires that we link with -lintl MY_LIBS = $(LTLIBINTL) filefuncs_la_SOURCES = filefuncs.c stack.h stack.c gawkfts.h \ gawkfts.c gawkdirfd.h @@ -557,9 +557,11 @@ fork_la_LIBADD = $(MY_LIBS) inplace_la_SOURCES = inplace.c inplace_la_LDFLAGS = $(MY_MODULE_FLAGS) inplace_la_LIBADD = $(MY_LIBS) + +# On Cygwin, intdiv has to be linked with the MPFR and GMP libraries intdiv_la_SOURCES = intdiv.c intdiv_la_LDFLAGS = $(MY_MODULE_FLAGS) -intdiv_la_LIBADD = $(MY_LIBS) +intdiv_la_LIBADD = $(MY_LIBS) $(LIBMPFR) ordchr_la_SOURCES = ordchr.c ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS) ordchr_la_LIBADD = $(MY_LIBS) -- cgit v1.2.3 From e9786ddcfcdeae8e6230f9c4b8f51445a3ff1d9c Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 9 Aug 2017 21:08:08 +0300 Subject: Improve checking for MPFR in API at dl_load time. --- ChangeLog | 6 ++++++ gawkapi.h | 14 ++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d715177..9d50ff41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-08-09 Arnold D. Robbins + + * gawkapi.h (check_mpfr_versions): Define differently based on if + MPFR version macro is defined. Enhance body to use do/while(0). + (dl_load): Call check_mpfr_versions unconditionally. + 2017-08-09 Arnold D. Robbins * main.c (usage): Add URL for Bug reporting info to the help message. diff --git a/gawkapi.h b/gawkapi.h index d87ddb76..1c6c74ec 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -1114,6 +1114,8 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ api->major_version, api->minor_version); \ exit(1); \ } \ +\ + check_mpfr_version(extension); \ \ /* load functions */ \ for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { \ @@ -1139,11 +1141,8 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ return (errors == 0); \ } -/* - * If you are using extended-precision calculations in your library, please - * call this macro from your init_func. - */ -#define check_mpfr_version(extension) { \ +#if defined __GNU_MP_VERSION && defined MPFR_VERSION_MAJOR +#define check_mpfr_version(extension) do { \ if (api->gmp_major_version != __GNU_MP_VERSION \ || api->gmp_minor_version < __GNU_MP_VERSION_MINOR) { \ fprintf(stderr, #extension ": GMP version mismatch with gawk!\n"); \ @@ -1160,7 +1159,10 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ api->mpfr_major_version, api->mpfr_minor_version); \ exit(1); \ } \ -} +} while (0) +#else +#define check_mpfr_version(extension) /* nothing */ +#endif #endif /* GAWK */ -- cgit v1.2.3 From 46aec4c0db140886ce19d81e99ef106aea9beced Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 10 Aug 2017 10:56:24 -0400 Subject: Fix initialization in intdiv extension, since MPFR version check is now automatic. --- extension/ChangeLog | 6 ++++++ extension/intdiv.c | 14 +------------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/extension/ChangeLog b/extension/ChangeLog index b7643571..99a6ac12 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,9 @@ +2017-08-10 Andrew J. Schorr + + * intdiv.c (init_intdiv): Remove function, since dl_load_func now + calls check_mpfr_version automatically. + (init_func): Initialize to NULL instead of init_intdiv. + 2017-08-04 Arnold D. Robbins * Makefile.am: Update copyright year. diff --git a/extension/intdiv.c b/extension/intdiv.c index 77b4290b..78fadd5a 100644 --- a/extension/intdiv.c +++ b/extension/intdiv.c @@ -26,6 +26,7 @@ static const gawk_api_t *api; /* for convenience macros to work */ static awk_ext_id_t *ext_id; static const char *ext_version = "intdiv extension: version 1.0"; +static awk_bool_t (*init_func)(void) = NULL; int plugin_is_GPL_compatible; @@ -197,19 +198,6 @@ static awk_ext_func_t func_table[] = { { "intdiv", do_intdiv, 3, 3, awk_false, NULL }, }; -/* init_intdiv --- initialization routine */ - -static awk_bool_t -init_intdiv(void) -{ -#ifdef HAVE_MPFR - check_mpfr_version(intdiv) -#endif - return awk_true; -} - -static awk_bool_t (*init_func)(void) = init_intdiv; - /* define the dl_load function using the boilerplate macro */ dl_load_func(func_table, intdiv, "") -- cgit v1.2.3 From d2f829ccb51da24a52c566010fc2e8a650eed116 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Fri, 11 Aug 2017 09:41:15 -0400 Subject: Stop including in the intdiv extension, since grabs this for us. --- extension/ChangeLog | 5 +++++ extension/intdiv.c | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/extension/ChangeLog b/extension/ChangeLog index 99a6ac12..c6be068a 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,8 @@ +2017-08-11 Andrew J. Schorr + + * intdiv.c: No need to include explicitly, since + does this for us. + 2017-08-10 Andrew J. Schorr * intdiv.c (init_intdiv): Remove function, since dl_load_func now diff --git a/extension/intdiv.c b/extension/intdiv.c index 78fadd5a..11045858 100644 --- a/extension/intdiv.c +++ b/extension/intdiv.c @@ -15,7 +15,6 @@ #include "gawkapi.h" #ifdef HAVE_MPFR -#include #include #endif -- cgit v1.2.3 From a9c174139581f6f23f17d09e2a72f77e5594e166 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 13 Aug 2017 21:20:52 +0300 Subject: Document MPFR/GMP additions to the extension API. --- doc/ChangeLog | 5 + doc/gawk.info | 1314 ++++++++++++++++++++++++++++++------------------------- doc/gawk.texi | 148 ++++++- doc/gawktexi.in | 148 ++++++- 4 files changed, 992 insertions(+), 623 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index b7d06538..971d0027 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2017-08-13 Arnold D. Robbins + + * gawktexi.in: Update API chapter with info about additions + for accessing and/or creating MPZ and MPFR values. + 2017-08-04 Arnold D. Robbins * texinfo.tex: Updated. diff --git a/doc/gawk.info b/doc/gawk.info index 2c0f9493..4faa99c6 100644 --- a/doc/gawk.info +++ b/doc/gawk.info @@ -573,6 +573,8 @@ in (a) below. A copy of the license is included in the section entitled redirections. * Extension API Variables:: Variables provided by the API. * Extension Versioning:: API Version information. +* Extension GMP/MPFR Versioning:: Version information about GMP and + MPFR. * Extension API Informational Variables:: Variables providing information about 'gawk''s invocation. * Extension API Boilerplate:: Boilerplate code for using the API. @@ -23689,6 +23691,10 @@ operations: order to keep 'gawkapi.h' clean, instead of becoming a portability hodge-podge as can be seen in some parts of the 'gawk' source code. + * If your extension uses MPFR facilities, and you wish to receive + such values from 'gawk' and/or pass such values to it, you must + include the '' header before including ''. + * The 'gawkapi.h' file may be included more than once without ill effect. Doing so, however, is poor coding practice. @@ -23808,7 +23814,7 @@ use them. ' awk_valtype_t val_type;' ' union {' ' awk_string_t s;' -' double d;' +' awknum_t n;' ' awk_array_t a;' ' awk_scalar_t scl;' ' awk_value_cookie_t vc;' @@ -23821,13 +23827,36 @@ use them. '#define str_value u.s' '#define strnum_value str_value' '#define regex_value str_value' -'#define num_value u.d' +'#define num_value u.n.d' +'#define num_type u.n.type' +'#define num_ptr u.n.ptr' '#define array_cookie u.a' '#define scalar_cookie u.scl' '#define value_cookie u.vc' Using these macros makes accessing the fields of the 'awk_value_t' more readable. +'typedef struct awk_number {' +' double d;' +' enum AWK_NUMBER_TYPE {' +' AWK_NUMBER_TYPE_DOUBLE,' +' AWK_NUMBER_TYPE_MPFR,' +' AWK_NUMBER_TYPE_MPZ' +' } type;' +' void *ptr;' +'} awk_number_t;' + This represents a numeric value. Internally, 'gawk' stores every + number as either a C 'double', a GMP integer, or an MPFR + arbitrary-precision floating-point value. In order to allow + extensions to also support GMP and MPFR values, numeric values are + passed in this structure. + + The double-precision 'd' element is always populated in data + received from 'gawk'. In addition, by examining the 'type' member, + an extension can determine if the 'ptr' member is either a GMP + integer (type 'mpz_ptr'), or an MPFR floating-point value (type + 'mpfr_ptr_t'), and cast it appropriately. + 'typedef void *awk_scalar_t;' Scalars can be represented as an opaque type. These values are obtained from 'gawk' and then passed back into it. This is @@ -23991,6 +24020,28 @@ value: 'gawk_malloc()'. The arguments are the same as for the 'emalloc()' macro. + Two additional functions allocate MPFR and GMP objects for use by +extension functions that need to create and then return such values: + +'void *get_mpfr_ptr();' + Allocate and initialize an MPFR object and return a pointer to it. + If the allocation fails, 'gawk' exits with a fatal "out of memory" + error. If 'gawk' was compiled without MPFR support, calling this + function causes a fatal error. + +'void *get_mpz_ptr();' + Allocate and initialize a GMP object and return a pointer to it. + If the allocation fails, 'gawk' exits with a fatal "out of memory" + error. If 'gawk' was compiled without MPFR support, calling this + function causes a fatal error. + + Both of these functions return 'void *', since the 'gawkapi.h' header +file should not have dependency upon '' (and '', which is +included from ''). The actual return values are of types +'mpfr_ptr' and 'mpz_ptr' respectively, and you should cast the return +values appropriately before assigning the results to variables of the +correct types. + ---------- Footnotes ---------- (1) This is more common on MS-Windows systems, but it can happen on @@ -24034,6 +24085,18 @@ code would use them: This function simply creates a numeric value in the 'awk_value_t' variable pointed to by 'result'. +'static inline awk_value_t *' +'make_number_mpz(void *mpz, awk_value_t *result);' + This function creates a GMP number value in 'result'. The 'mpz' + must be from a call to 'get_mpz_ptr()' (and thus be or real + underlying type 'mpz_ptr'). 'gawk' takes ownership of this memory. + +'static inline awk_value_t *' +'make_number_mpfr(void *mpfr, awk_value_t *result);' + This function creates an MPFR number value in 'result'. The 'mpfr' + must be from a call to 'get_mpfr_ptr()'. (and thus be or real + underlying type 'mpfr_ptr') 'gawk' takes ownership of this memory. + 'static inline awk_value_t *' 'make_const_user_input(const char *string, size_t length, awk_value_t *result);' This function is identical to 'make_const_string()', but the string @@ -24508,10 +24571,10 @@ structure, which looks like this: provide the information for '$1', and so on through the 'fields[nf-1]' element containing the information for '$NF'. - A convenience macro 'awk_fieldwidth_info_size(NF)' is provided to -calculate the appropriate size of a variable-length -'awk_fieldwidth_info_t' structure containing 'NF' fields. This can be -used as an argument to 'malloc()' or in a union to allocate space + A convenience macro 'awk_fieldwidth_info_size(numfields)' is provided +to calculate the appropriate size of a variable-length +'awk_fieldwidth_info_t' structure containing 'numfields' fields. This +can be used as an argument to 'malloc()' or in a union to allocate space statically. Please refer to the 'readdir_test' sample extension for an example. @@ -25047,7 +25110,8 @@ using 'release_value()'. ---------- Footnotes ---------- (1) Numeric values are clearly less problematic, requiring only a C -'double' to store. +'double' to store. But of course, GMP and MPFR values _do_ take up more +memory.  File: gawk.info, Node: Array Manipulation, Next: Redirection API, Prev: Symbol Table Access, Up: Extension API Description @@ -25207,7 +25271,10 @@ The following functions relate to individual array elements: array, but after calling this function, it has no elements. This is equivalent to using the 'delete' statement (*note Delete::). -'awk_bool_t flatten_array_typed(awk_array_t a_cookie, awk_flat_array_t **data, awk_valtype_t index_type, awk_valtype_t value_type);' +'awk_bool_t flatten_array_typed(awk_array_t a_cookie,' +' awk_flat_array_t **data,' +' awk_valtype_t index_type,' +' awk_valtype_t value_type);' For the array represented by 'a_cookie', create an 'awk_flat_array_t' structure and fill it in with indices and values of the requested types. Set the pointer whose address is passed as @@ -25323,7 +25390,8 @@ count of elements in the array and print it: double-check that the count in the 'awk_flat_array_t' is the same as the count just retrieved: - if (! flatten_array_typed(value2.array_cookie, & flat_array, AWK_STRING, AWK_UNDEFINED)) { + if (! flatten_array_typed(value2.array_cookie, & flat_array, + AWK_STRING, AWK_UNDEFINED)) { printf("dump_array_and_delete: could not flatten array\n"); goto out; } @@ -25582,13 +25650,14 @@ redirections. '"|&"' A two-way coprocess. - On error, return an 'awk_false' value. Otherwise, return - 'awk_true', and return additional information about the redirection - in the 'ibufp' and 'obufp' pointers. For input redirections, the - '*ibufp' value should be non-'NULL', and '*obufp' should be 'NULL'. - For output redirections, the '*obufp' value should be non-'NULL', - and '*ibufp' should be 'NULL'. For two-way coprocesses, both - values should be non-'NULL'. + On error, return 'awk_false'. Otherwise, return 'awk_true', and + return additional information about the redirection in the 'ibufp' + and 'obufp' pointers. + + For input redirections, the '*ibufp' value should be non-'NULL', + and '*obufp' should be 'NULL'. For output redirections, the + '*obufp' value should be non-'NULL', and '*ibufp' should be 'NULL'. + For two-way coprocesses, both values should be non-'NULL'. In the usual case, the extension is interested in '(*ibufp)->fd' and/or 'fileno((*obufp)->fp)'. If the file is not already open, @@ -25624,12 +25693,13 @@ information about how 'gawk' was invoked. * Menu: -* Extension Versioning:: API Version information. +* Extension Versioning:: API Version information. +* Extension GMP/MPFR Versioning:: Version information about GMP and MPFR. * Extension API Informational Variables:: Variables providing information about - 'gawk''s invocation. + 'gawk''s invocation.  -File: gawk.info, Node: Extension Versioning, Next: Extension API Informational Variables, Up: Extension API Variables +File: gawk.info, Node: Extension Versioning, Next: Extension GMP/MPFR Versioning, Up: Extension API Variables 16.4.13.1 API Version Constants and Variables ............................................. @@ -25681,9 +25751,51 @@ provided in 'gawkapi.h' (discussed in *note Extension API Boilerplate::).  -File: gawk.info, Node: Extension API Informational Variables, Prev: Extension Versioning, Up: Extension API Variables +File: gawk.info, Node: Extension GMP/MPFR Versioning, Next: Extension API Informational Variables, Prev: Extension Versioning, Up: Extension API Variables + +16.4.13.2 GMP and MPFR Version Information +.......................................... + +The API also includes information about the versions of GMP and MPFR +with which the running 'gawk' was compiled (if any). They are included +in the API 'struct' as read-only constant integers: + +'api->gmp_major_version' + The major version of the GMP library used to compile 'gawk'. + +'api->gmp_minor_version' + The minor version of the GMP library used to compile 'gawk'. + +'api->mpfr_major_version' + The major version of the MPFR library used to compile 'gawk'. + +'api->mpfr_minor_version' + The minor version of the MPFR library used to compile 'gawk'. + + These fields are set to zero if 'gawk' was compiled without MPFR +support. + + You can check if the versions of MPFR and GMP that you are using +match those of 'gawk' with the following macro: + +'check_mpfr_version(extension)' + The 'extension' is the extension id passed to all the other macros + and functions defined in 'gawkapi.h'. If you have not included the + '' header file, then this macro will be defined to do + nothing. + + If you have included that file, then this macro compares the MPFR + and GMP major and minor versions against those of the library you + are compiling against. If your libraries are newer than 'gawk''s, + it produces a fatal error message. + + The 'dl_load_func()' macro (*note Extension API Boilerplate::) + calls 'check_mpfr_version()'. + + +File: gawk.info, Node: Extension API Informational Variables, Prev: Extension GMP/MPFR Versioning, Up: Extension API Variables -16.4.13.2 Informational Variables +16.4.13.3 Informational Variables ................................. The API provides access to several variables that describe whether the @@ -25807,13 +25919,16 @@ does the following: match 'gawk''s, or if the extension minor version is greater than 'gawk''s, it prints a fatal error message and exits. - 2. Load the functions defined in 'func_table'. If any of them fails + 2. Check the MPFR and GMP versions. If there is a mismatch, it prints + a fatal error message and exits. + + 3. Load the functions defined in 'func_table'. If any of them fails to load, it prints a warning message but continues on. - 3. If the 'init_func' pointer is not 'NULL', call the function it + 4. If the 'init_func' pointer is not 'NULL', call the function it points to. If it returns 'awk_false', print a warning message. - 4. If 'ext_version' is not 'NULL', register the version string with + 5. If 'ext_version' is not 'NULL', register the version string with 'gawk'.  @@ -35682,580 +35797,581 @@ Index  Tag Table: Node: Top1200 -Node: Foreword343279 -Node: Foreword447721 -Node: Preface49253 -Ref: Preface-Footnote-152112 -Ref: Preface-Footnote-252219 -Ref: Preface-Footnote-352453 -Node: History52595 -Node: Names54947 -Ref: Names-Footnote-156041 -Node: This Manual56188 -Ref: This Manual-Footnote-162673 -Node: Conventions62773 -Node: Manual History65127 -Ref: Manual History-Footnote-168122 -Ref: Manual History-Footnote-268163 -Node: How To Contribute68237 -Node: Acknowledgments68888 -Node: Getting Started73774 -Node: Running gawk76213 -Node: One-shot77403 -Node: Read Terminal78666 -Node: Long80659 -Node: Executable Scripts82172 -Ref: Executable Scripts-Footnote-184967 -Node: Comments85070 -Node: Quoting87554 -Node: DOS Quoting93071 -Node: Sample Data Files95127 -Node: Very Simple97722 -Node: Two Rules102624 -Node: More Complex104509 -Node: Statements/Lines107375 -Ref: Statements/Lines-Footnote-1111834 -Node: Other Features112099 -Node: When113035 -Ref: When-Footnote-1114789 -Node: Intro Summary114854 -Node: Invoking Gawk115738 -Node: Command Line117252 -Node: Options118050 -Ref: Options-Footnote-1134669 -Ref: Options-Footnote-2134899 -Node: Other Arguments134924 -Node: Naming Standard Input137871 -Node: Environment Variables138964 -Node: AWKPATH Variable139522 -Ref: AWKPATH Variable-Footnote-1142933 -Ref: AWKPATH Variable-Footnote-2142967 -Node: AWKLIBPATH Variable143228 -Node: Other Environment Variables144485 -Node: Exit Status148306 -Node: Include Files148983 -Node: Loading Shared Libraries152578 -Node: Obsolete154006 -Node: Undocumented154698 -Node: Invoking Summary154995 -Node: Regexp156655 -Node: Regexp Usage158109 -Node: Escape Sequences160146 -Node: Regexp Operators166378 -Ref: Regexp Operators-Footnote-1173794 -Ref: Regexp Operators-Footnote-2173941 -Node: Bracket Expressions174039 -Ref: table-char-classes176515 -Node: Leftmost Longest179652 -Node: Computed Regexps180955 -Node: GNU Regexp Operators184382 -Node: Case-sensitivity188061 -Ref: Case-sensitivity-Footnote-1190948 -Ref: Case-sensitivity-Footnote-2191183 -Node: Regexp Summary191291 -Node: Reading Files192757 -Node: Records195026 -Node: awk split records195759 -Node: gawk split records200690 -Ref: gawk split records-Footnote-1205230 -Node: Fields205267 -Node: Nonconstant Fields208008 -Ref: Nonconstant Fields-Footnote-1210244 -Node: Changing Fields210448 -Node: Field Separators216376 -Node: Default Field Splitting219074 -Node: Regexp Field Splitting220192 -Node: Single Character Fields223545 -Node: Command Line Field Separator224605 -Node: Full Line Fields227823 -Ref: Full Line Fields-Footnote-1229345 -Ref: Full Line Fields-Footnote-2229391 -Node: Field Splitting Summary229492 -Node: Constant Size231566 -Node: Fixed width data232298 -Node: Skipping intervening235765 -Node: Allowing trailing data236563 -Node: Fields with fixed data237600 -Node: Splitting By Content239118 -Ref: Splitting By Content-Footnote-1242768 -Node: Testing field creation242931 -Node: Multiple Line244552 -Ref: Multiple Line-Footnote-1250436 -Node: Getline250615 -Node: Plain Getline253084 -Node: Getline/Variable255725 -Node: Getline/File256876 -Node: Getline/Variable/File258264 -Ref: Getline/Variable/File-Footnote-1259869 -Node: Getline/Pipe259957 -Node: Getline/Variable/Pipe262664 -Node: Getline/Coprocess263799 -Node: Getline/Variable/Coprocess265066 -Node: Getline Notes265808 -Node: Getline Summary268605 -Ref: table-getline-variants269029 -Node: Read Timeout269777 -Ref: Read Timeout-Footnote-1273683 -Node: Retrying Input273741 -Node: Command-line directories274940 -Node: Input Summary275846 -Node: Input Exercises279018 -Node: Printing279746 -Node: Print281580 -Node: Print Examples283037 -Node: Output Separators285817 -Node: OFMT287834 -Node: Printf289190 -Node: Basic Printf289975 -Node: Control Letters291549 -Node: Format Modifiers295537 -Node: Printf Examples301552 -Node: Redirection304038 -Node: Special FD310879 -Ref: Special FD-Footnote-1314047 -Node: Special Files314121 -Node: Other Inherited Files314738 -Node: Special Network315739 -Node: Special Caveats316599 -Node: Close Files And Pipes317548 -Ref: table-close-pipe-return-values324455 -Ref: Close Files And Pipes-Footnote-1325238 -Ref: Close Files And Pipes-Footnote-2325386 -Node: Nonfatal325538 -Node: Output Summary327863 -Node: Output Exercises329085 -Node: Expressions329764 -Node: Values330952 -Node: Constants331630 -Node: Scalar Constants332321 -Ref: Scalar Constants-Footnote-1333185 -Node: Nondecimal-numbers333435 -Node: Regexp Constants336436 -Node: Using Constant Regexps336962 -Node: Standard Regexp Constants337584 -Node: Strong Regexp Constants340772 -Node: Variables343730 -Node: Using Variables344387 -Node: Assignment Options346297 -Node: Conversion348170 -Node: Strings And Numbers348694 -Ref: Strings And Numbers-Footnote-1351757 -Node: Locale influences conversions351866 -Ref: table-locale-affects354624 -Node: All Operators355242 -Node: Arithmetic Ops355871 -Node: Concatenation358377 -Ref: Concatenation-Footnote-1361224 -Node: Assignment Ops361331 -Ref: table-assign-ops366322 -Node: Increment Ops367635 -Node: Truth Values and Conditions371095 -Node: Truth Values372169 -Node: Typing and Comparison373217 -Node: Variable Typing374037 -Ref: Variable Typing-Footnote-1380500 -Ref: Variable Typing-Footnote-2380572 -Node: Comparison Operators380649 -Ref: table-relational-ops381068 -Node: POSIX String Comparison384563 -Ref: POSIX String Comparison-Footnote-1386258 -Ref: POSIX String Comparison-Footnote-2386397 -Node: Boolean Ops386481 -Ref: Boolean Ops-Footnote-1390963 -Node: Conditional Exp391055 -Node: Function Calls392791 -Node: Precedence396668 -Node: Locales400327 -Node: Expressions Summary401959 -Node: Patterns and Actions404532 -Node: Pattern Overview405652 -Node: Regexp Patterns407329 -Node: Expression Patterns407871 -Node: Ranges411652 -Node: BEGIN/END414760 -Node: Using BEGIN/END415521 -Ref: Using BEGIN/END-Footnote-1418257 -Node: I/O And BEGIN/END418363 -Node: BEGINFILE/ENDFILE420677 -Node: Empty423584 -Node: Using Shell Variables423901 -Node: Action Overview426175 -Node: Statements428500 -Node: If Statement430348 -Node: While Statement431843 -Node: Do Statement433871 -Node: For Statement435019 -Node: Switch Statement438177 -Node: Break Statement440563 -Node: Continue Statement442655 -Node: Next Statement444482 -Node: Nextfile Statement446865 -Node: Exit Statement449517 -Node: Built-in Variables451920 -Node: User-modified453053 -Node: Auto-set460820 -Ref: Auto-set-Footnote-1476417 -Ref: Auto-set-Footnote-2476623 -Node: ARGC and ARGV476679 -Node: Pattern Action Summary480892 -Node: Arrays483322 -Node: Array Basics484651 -Node: Array Intro485495 -Ref: figure-array-elements487470 -Ref: Array Intro-Footnote-1490174 -Node: Reference to Elements490302 -Node: Assigning Elements492766 -Node: Array Example493257 -Node: Scanning an Array495016 -Node: Controlling Scanning498038 -Ref: Controlling Scanning-Footnote-1503437 -Node: Numeric Array Subscripts503753 -Node: Uninitialized Subscripts505937 -Node: Delete507556 -Ref: Delete-Footnote-1510308 -Node: Multidimensional510365 -Node: Multiscanning513460 -Node: Arrays of Arrays515051 -Node: Arrays Summary519818 -Node: Functions521911 -Node: Built-in522949 -Node: Calling Built-in524030 -Node: Numeric Functions526026 -Ref: Numeric Functions-Footnote-1530054 -Ref: Numeric Functions-Footnote-2530411 -Ref: Numeric Functions-Footnote-3530459 -Node: String Functions530731 -Ref: String Functions-Footnote-1554389 -Ref: String Functions-Footnote-2554517 -Ref: String Functions-Footnote-3554765 -Node: Gory Details554852 -Ref: table-sub-escapes556643 -Ref: table-sub-proposed558162 -Ref: table-posix-sub559525 -Ref: table-gensub-escapes561066 -Ref: Gory Details-Footnote-1561889 -Node: I/O Functions562043 -Ref: table-system-return-values568625 -Ref: I/O Functions-Footnote-1570605 -Ref: I/O Functions-Footnote-2570753 -Node: Time Functions570873 -Ref: Time Functions-Footnote-1581540 -Ref: Time Functions-Footnote-2581608 -Ref: Time Functions-Footnote-3581766 -Ref: Time Functions-Footnote-4581877 -Ref: Time Functions-Footnote-5581989 -Ref: Time Functions-Footnote-6582216 -Node: Bitwise Functions582482 -Ref: table-bitwise-ops583076 -Ref: Bitwise Functions-Footnote-1589109 -Ref: Bitwise Functions-Footnote-2589282 -Node: Type Functions589473 -Node: I18N Functions592390 -Node: User-defined594041 -Node: Definition Syntax594846 -Ref: Definition Syntax-Footnote-1600533 -Node: Function Example600604 -Ref: Function Example-Footnote-1603526 -Node: Function Caveats603548 -Node: Calling A Function604066 -Node: Variable Scope605024 -Node: Pass By Value/Reference608018 -Node: Return Statement611517 -Node: Dynamic Typing614496 -Node: Indirect Calls615426 -Ref: Indirect Calls-Footnote-1625677 -Node: Functions Summary625805 -Node: Library Functions628510 -Ref: Library Functions-Footnote-1632117 -Ref: Library Functions-Footnote-2632260 -Node: Library Names632431 -Ref: Library Names-Footnote-1635891 -Ref: Library Names-Footnote-2636114 -Node: General Functions636200 -Node: Strtonum Function637303 -Node: Assert Function640325 -Node: Round Function643651 -Node: Cliff Random Function645192 -Node: Ordinal Functions646208 -Ref: Ordinal Functions-Footnote-1649271 -Ref: Ordinal Functions-Footnote-2649523 -Node: Join Function649733 -Ref: Join Function-Footnote-1651503 -Node: Getlocaltime Function651703 -Node: Readfile Function655445 -Node: Shell Quoting657417 -Node: Data File Management658818 -Node: Filetrans Function659450 -Node: Rewind Function663546 -Node: File Checking665456 -Ref: File Checking-Footnote-1666790 -Node: Empty Files666991 -Node: Ignoring Assigns668970 -Node: Getopt Function670520 -Ref: Getopt Function-Footnote-1681989 -Node: Passwd Functions682189 -Ref: Passwd Functions-Footnote-1691028 -Node: Group Functions691116 -Ref: Group Functions-Footnote-1699014 -Node: Walking Arrays699221 -Node: Library Functions Summary702229 -Node: Library Exercises703635 -Node: Sample Programs704100 -Node: Running Examples704870 -Node: Clones705598 -Node: Cut Program706822 -Node: Egrep Program716751 -Ref: Egrep Program-Footnote-1724263 -Node: Id Program724373 -Node: Split Program728053 -Ref: Split Program-Footnote-1731512 -Node: Tee Program731641 -Node: Uniq Program734431 -Node: Wc Program741857 -Ref: Wc Program-Footnote-1746112 -Node: Miscellaneous Programs746206 -Node: Dupword Program747419 -Node: Alarm Program749449 -Node: Translate Program754304 -Ref: Translate Program-Footnote-1758869 -Node: Labels Program759139 -Ref: Labels Program-Footnote-1762490 -Node: Word Sorting762574 -Node: History Sorting766646 -Node: Extract Program768481 -Node: Simple Sed776010 -Node: Igawk Program779084 -Ref: Igawk Program-Footnote-1793415 -Ref: Igawk Program-Footnote-2793617 -Ref: Igawk Program-Footnote-3793739 -Node: Anagram Program793854 -Node: Signature Program796916 -Node: Programs Summary798163 -Node: Programs Exercises799377 -Ref: Programs Exercises-Footnote-1803506 -Node: Advanced Features803597 -Node: Nondecimal Data805587 -Node: Array Sorting807178 -Node: Controlling Array Traversal807878 -Ref: Controlling Array Traversal-Footnote-1816245 -Node: Array Sorting Functions816363 -Ref: Array Sorting Functions-Footnote-1821454 -Node: Two-way I/O821650 -Ref: Two-way I/O-Footnote-1828201 -Ref: Two-way I/O-Footnote-2828388 -Node: TCP/IP Networking828470 -Node: Profiling831588 -Ref: Profiling-Footnote-1840260 -Node: Advanced Features Summary840583 -Node: Internationalization842427 -Node: I18N and L10N843907 -Node: Explaining gettext844594 -Ref: Explaining gettext-Footnote-1850486 -Ref: Explaining gettext-Footnote-2850671 -Node: Programmer i18n850836 -Ref: Programmer i18n-Footnote-1855785 -Node: Translator i18n855834 -Node: String Extraction856628 -Ref: String Extraction-Footnote-1857760 -Node: Printf Ordering857846 -Ref: Printf Ordering-Footnote-1860632 -Node: I18N Portability860696 -Ref: I18N Portability-Footnote-1863152 -Node: I18N Example863215 -Ref: I18N Example-Footnote-1866021 -Node: Gawk I18N866094 -Node: I18N Summary866739 -Node: Debugger868080 -Node: Debugging869102 -Node: Debugging Concepts869543 -Node: Debugging Terms871352 -Node: Awk Debugging873927 -Node: Sample Debugging Session874833 -Node: Debugger Invocation875367 -Node: Finding The Bug876753 -Node: List of Debugger Commands883231 -Node: Breakpoint Control884564 -Node: Debugger Execution Control888258 -Node: Viewing And Changing Data891620 -Node: Execution Stack894994 -Node: Debugger Info896631 -Node: Miscellaneous Debugger Commands900702 -Node: Readline Support905790 -Node: Limitations906686 -Node: Debugging Summary908795 -Node: Arbitrary Precision Arithmetic910074 -Node: Computer Arithmetic911559 -Ref: table-numeric-ranges915150 -Ref: Computer Arithmetic-Footnote-1915872 -Node: Math Definitions915929 -Ref: table-ieee-formats919243 -Ref: Math Definitions-Footnote-1919846 -Node: MPFR features919951 -Node: FP Math Caution921668 -Ref: FP Math Caution-Footnote-1922740 -Node: Inexactness of computations923109 -Node: Inexact representation924069 -Node: Comparing FP Values925429 -Node: Errors accumulate926511 -Node: Getting Accuracy927944 -Node: Try To Round930654 -Node: Setting precision931553 -Ref: table-predefined-precision-strings932250 -Node: Setting the rounding mode934080 -Ref: table-gawk-rounding-modes934454 -Ref: Setting the rounding mode-Footnote-1937862 -Node: Arbitrary Precision Integers938041 -Ref: Arbitrary Precision Integers-Footnote-1941216 -Node: Checking for MPFR941365 -Node: POSIX Floating Point Problems942662 -Ref: POSIX Floating Point Problems-Footnote-1946533 -Node: Floating point summary946571 -Node: Dynamic Extensions948761 -Node: Extension Intro950314 -Node: Plugin License951580 -Node: Extension Mechanism Outline952377 -Ref: figure-load-extension952816 -Ref: figure-register-new-function954381 -Ref: figure-call-new-function955473 -Node: Extension API Description957535 -Node: Extension API Functions Introduction959177 -Node: General Data Types964511 -Ref: General Data Types-Footnote-1971716 -Node: Memory Allocation Functions972015 -Ref: Memory Allocation Functions-Footnote-1975167 -Node: Constructor Functions975266 -Node: Registration Functions978265 -Node: Extension Functions978950 -Node: Exit Callback Functions984163 -Node: Extension Version String985413 -Node: Input Parsers986076 -Node: Output Wrappers998783 -Node: Two-way processors1003295 -Node: Printing Messages1005560 -Ref: Printing Messages-Footnote-11006731 -Node: Updating ERRNO1006884 -Node: Requesting Values1007623 -Ref: table-value-types-returned1008360 -Node: Accessing Parameters1009296 -Node: Symbol Table Access1010531 -Node: Symbol table by name1011043 -Node: Symbol table by cookie1012832 -Ref: Symbol table by cookie-Footnote-11017017 -Node: Cached values1017081 -Ref: Cached values-Footnote-11020617 -Node: Array Manipulation1020708 -Ref: Array Manipulation-Footnote-11021799 -Node: Array Data Types1021836 -Ref: Array Data Types-Footnote-11024494 -Node: Array Functions1024586 -Node: Flattening Arrays1028985 -Node: Creating Arrays1035926 -Node: Redirection API1040695 -Node: Extension API Variables1043537 -Node: Extension Versioning1044170 -Ref: gawk-api-version1044607 -Node: Extension API Informational Variables1046335 -Node: Extension API Boilerplate1047399 -Node: Changes from API V11051261 -Node: Finding Extensions1051921 -Node: Extension Example1052480 -Node: Internal File Description1053278 -Node: Internal File Ops1057358 -Ref: Internal File Ops-Footnote-11068758 -Node: Using Internal File Ops1068898 -Ref: Using Internal File Ops-Footnote-11071281 -Node: Extension Samples1071555 -Node: Extension Sample File Functions1073084 -Node: Extension Sample Fnmatch1080733 -Node: Extension Sample Fork1082220 -Node: Extension Sample Inplace1083438 -Node: Extension Sample Ord1086655 -Node: Extension Sample Readdir1087491 -Ref: table-readdir-file-types1088380 -Node: Extension Sample Revout1089185 -Node: Extension Sample Rev2way1089774 -Node: Extension Sample Read write array1090514 -Node: Extension Sample Readfile1092456 -Node: Extension Sample Time1093551 -Node: Extension Sample API Tests1094899 -Node: gawkextlib1095391 -Node: Extension summary1097838 -Node: Extension Exercises1101540 -Node: Language History1103038 -Node: V7/SVR3.11104694 -Node: SVR41106846 -Node: POSIX1108280 -Node: BTL1109659 -Node: POSIX/GNU1110388 -Node: Feature History1116166 -Node: Common Extensions1130531 -Node: Ranges and Locales1131814 -Ref: Ranges and Locales-Footnote-11136430 -Ref: Ranges and Locales-Footnote-21136457 -Ref: Ranges and Locales-Footnote-31136692 -Node: Contributors1136913 -Node: History summary1142541 -Node: Installation1143921 -Node: Gawk Distribution1144865 -Node: Getting1145349 -Node: Extracting1146310 -Node: Distribution contents1147948 -Node: Unix Installation1154290 -Node: Quick Installation1154972 -Node: Shell Startup Files1157386 -Node: Additional Configuration Options1158475 -Node: Configuration Philosophy1160464 -Node: Non-Unix Installation1162833 -Node: PC Installation1163293 -Node: PC Binary Installation1164131 -Node: PC Compiling1164566 -Node: PC Using1165683 -Node: Cygwin1168728 -Node: MSYS1169498 -Node: VMS Installation1169999 -Node: VMS Compilation1170790 -Ref: VMS Compilation-Footnote-11172019 -Node: VMS Dynamic Extensions1172077 -Node: VMS Installation Details1173762 -Node: VMS Running1176015 -Node: VMS GNV1180294 -Node: VMS Old Gawk1181029 -Node: Bugs1181500 -Node: Bug address1182163 -Node: Usenet1184560 -Node: Maintainers1185337 -Node: Other Versions1186598 -Node: Installation summary1193182 -Node: Notes1194217 -Node: Compatibility Mode1195082 -Node: Additions1195864 -Node: Accessing The Source1196789 -Node: Adding Code1198224 -Node: New Ports1204442 -Node: Derived Files1208930 -Ref: Derived Files-Footnote-11214415 -Ref: Derived Files-Footnote-21214450 -Ref: Derived Files-Footnote-31215048 -Node: Future Extensions1215162 -Node: Implementation Limitations1215820 -Node: Extension Design1217003 -Node: Old Extension Problems1218157 -Ref: Old Extension Problems-Footnote-11219675 -Node: Extension New Mechanism Goals1219732 -Ref: Extension New Mechanism Goals-Footnote-11223096 -Node: Extension Other Design Decisions1223285 -Node: Extension Future Growth1225398 -Node: Old Extension Mechanism1226234 -Node: Notes summary1227997 -Node: Basic Concepts1229179 -Node: Basic High Level1229860 -Ref: figure-general-flow1230142 -Ref: figure-process-flow1230827 -Ref: Basic High Level-Footnote-11234128 -Node: Basic Data Typing1234313 -Node: Glossary1237641 -Node: Copying1269588 -Node: GNU Free Documentation License1307127 -Node: Index1332245 +Node: Foreword343399 +Node: Foreword447841 +Node: Preface49373 +Ref: Preface-Footnote-152232 +Ref: Preface-Footnote-252339 +Ref: Preface-Footnote-352573 +Node: History52715 +Node: Names55067 +Ref: Names-Footnote-156161 +Node: This Manual56308 +Ref: This Manual-Footnote-162793 +Node: Conventions62893 +Node: Manual History65247 +Ref: Manual History-Footnote-168242 +Ref: Manual History-Footnote-268283 +Node: How To Contribute68357 +Node: Acknowledgments69008 +Node: Getting Started73894 +Node: Running gawk76333 +Node: One-shot77523 +Node: Read Terminal78786 +Node: Long80779 +Node: Executable Scripts82292 +Ref: Executable Scripts-Footnote-185087 +Node: Comments85190 +Node: Quoting87674 +Node: DOS Quoting93191 +Node: Sample Data Files95247 +Node: Very Simple97842 +Node: Two Rules102744 +Node: More Complex104629 +Node: Statements/Lines107495 +Ref: Statements/Lines-Footnote-1111954 +Node: Other Features112219 +Node: When113155 +Ref: When-Footnote-1114909 +Node: Intro Summary114974 +Node: Invoking Gawk115858 +Node: Command Line117372 +Node: Options118170 +Ref: Options-Footnote-1134789 +Ref: Options-Footnote-2135019 +Node: Other Arguments135044 +Node: Naming Standard Input137991 +Node: Environment Variables139084 +Node: AWKPATH Variable139642 +Ref: AWKPATH Variable-Footnote-1143053 +Ref: AWKPATH Variable-Footnote-2143087 +Node: AWKLIBPATH Variable143348 +Node: Other Environment Variables144605 +Node: Exit Status148426 +Node: Include Files149103 +Node: Loading Shared Libraries152698 +Node: Obsolete154126 +Node: Undocumented154818 +Node: Invoking Summary155115 +Node: Regexp156775 +Node: Regexp Usage158229 +Node: Escape Sequences160266 +Node: Regexp Operators166498 +Ref: Regexp Operators-Footnote-1173914 +Ref: Regexp Operators-Footnote-2174061 +Node: Bracket Expressions174159 +Ref: table-char-classes176635 +Node: Leftmost Longest179772 +Node: Computed Regexps181075 +Node: GNU Regexp Operators184502 +Node: Case-sensitivity188181 +Ref: Case-sensitivity-Footnote-1191068 +Ref: Case-sensitivity-Footnote-2191303 +Node: Regexp Summary191411 +Node: Reading Files192877 +Node: Records195146 +Node: awk split records195879 +Node: gawk split records200810 +Ref: gawk split records-Footnote-1205350 +Node: Fields205387 +Node: Nonconstant Fields208128 +Ref: Nonconstant Fields-Footnote-1210364 +Node: Changing Fields210568 +Node: Field Separators216496 +Node: Default Field Splitting219194 +Node: Regexp Field Splitting220312 +Node: Single Character Fields223665 +Node: Command Line Field Separator224725 +Node: Full Line Fields227943 +Ref: Full Line Fields-Footnote-1229465 +Ref: Full Line Fields-Footnote-2229511 +Node: Field Splitting Summary229612 +Node: Constant Size231686 +Node: Fixed width data232418 +Node: Skipping intervening235885 +Node: Allowing trailing data236683 +Node: Fields with fixed data237720 +Node: Splitting By Content239238 +Ref: Splitting By Content-Footnote-1242888 +Node: Testing field creation243051 +Node: Multiple Line244672 +Ref: Multiple Line-Footnote-1250556 +Node: Getline250735 +Node: Plain Getline253204 +Node: Getline/Variable255845 +Node: Getline/File256996 +Node: Getline/Variable/File258384 +Ref: Getline/Variable/File-Footnote-1259989 +Node: Getline/Pipe260077 +Node: Getline/Variable/Pipe262784 +Node: Getline/Coprocess263919 +Node: Getline/Variable/Coprocess265186 +Node: Getline Notes265928 +Node: Getline Summary268725 +Ref: table-getline-variants269149 +Node: Read Timeout269897 +Ref: Read Timeout-Footnote-1273803 +Node: Retrying Input273861 +Node: Command-line directories275060 +Node: Input Summary275966 +Node: Input Exercises279138 +Node: Printing279866 +Node: Print281700 +Node: Print Examples283157 +Node: Output Separators285937 +Node: OFMT287954 +Node: Printf289310 +Node: Basic Printf290095 +Node: Control Letters291669 +Node: Format Modifiers295657 +Node: Printf Examples301672 +Node: Redirection304158 +Node: Special FD310999 +Ref: Special FD-Footnote-1314167 +Node: Special Files314241 +Node: Other Inherited Files314858 +Node: Special Network315859 +Node: Special Caveats316719 +Node: Close Files And Pipes317668 +Ref: table-close-pipe-return-values324575 +Ref: Close Files And Pipes-Footnote-1325358 +Ref: Close Files And Pipes-Footnote-2325506 +Node: Nonfatal325658 +Node: Output Summary327983 +Node: Output Exercises329205 +Node: Expressions329884 +Node: Values331072 +Node: Constants331750 +Node: Scalar Constants332441 +Ref: Scalar Constants-Footnote-1333305 +Node: Nondecimal-numbers333555 +Node: Regexp Constants336556 +Node: Using Constant Regexps337082 +Node: Standard Regexp Constants337704 +Node: Strong Regexp Constants340892 +Node: Variables343850 +Node: Using Variables344507 +Node: Assignment Options346417 +Node: Conversion348290 +Node: Strings And Numbers348814 +Ref: Strings And Numbers-Footnote-1351877 +Node: Locale influences conversions351986 +Ref: table-locale-affects354744 +Node: All Operators355362 +Node: Arithmetic Ops355991 +Node: Concatenation358497 +Ref: Concatenation-Footnote-1361344 +Node: Assignment Ops361451 +Ref: table-assign-ops366442 +Node: Increment Ops367755 +Node: Truth Values and Conditions371215 +Node: Truth Values372289 +Node: Typing and Comparison373337 +Node: Variable Typing374157 +Ref: Variable Typing-Footnote-1380620 +Ref: Variable Typing-Footnote-2380692 +Node: Comparison Operators380769 +Ref: table-relational-ops381188 +Node: POSIX String Comparison384683 +Ref: POSIX String Comparison-Footnote-1386378 +Ref: POSIX String Comparison-Footnote-2386517 +Node: Boolean Ops386601 +Ref: Boolean Ops-Footnote-1391083 +Node: Conditional Exp391175 +Node: Function Calls392911 +Node: Precedence396788 +Node: Locales400447 +Node: Expressions Summary402079 +Node: Patterns and Actions404652 +Node: Pattern Overview405772 +Node: Regexp Patterns407449 +Node: Expression Patterns407991 +Node: Ranges411772 +Node: BEGIN/END414880 +Node: Using BEGIN/END415641 +Ref: Using BEGIN/END-Footnote-1418377 +Node: I/O And BEGIN/END418483 +Node: BEGINFILE/ENDFILE420797 +Node: Empty423704 +Node: Using Shell Variables424021 +Node: Action Overview426295 +Node: Statements428620 +Node: If Statement430468 +Node: While Statement431963 +Node: Do Statement433991 +Node: For Statement435139 +Node: Switch Statement438297 +Node: Break Statement440683 +Node: Continue Statement442775 +Node: Next Statement444602 +Node: Nextfile Statement446985 +Node: Exit Statement449637 +Node: Built-in Variables452040 +Node: User-modified453173 +Node: Auto-set460940 +Ref: Auto-set-Footnote-1476537 +Ref: Auto-set-Footnote-2476743 +Node: ARGC and ARGV476799 +Node: Pattern Action Summary481012 +Node: Arrays483442 +Node: Array Basics484771 +Node: Array Intro485615 +Ref: figure-array-elements487590 +Ref: Array Intro-Footnote-1490294 +Node: Reference to Elements490422 +Node: Assigning Elements492886 +Node: Array Example493377 +Node: Scanning an Array495136 +Node: Controlling Scanning498158 +Ref: Controlling Scanning-Footnote-1503557 +Node: Numeric Array Subscripts503873 +Node: Uninitialized Subscripts506057 +Node: Delete507676 +Ref: Delete-Footnote-1510428 +Node: Multidimensional510485 +Node: Multiscanning513580 +Node: Arrays of Arrays515171 +Node: Arrays Summary519938 +Node: Functions522031 +Node: Built-in523069 +Node: Calling Built-in524150 +Node: Numeric Functions526146 +Ref: Numeric Functions-Footnote-1530174 +Ref: Numeric Functions-Footnote-2530531 +Ref: Numeric Functions-Footnote-3530579 +Node: String Functions530851 +Ref: String Functions-Footnote-1554509 +Ref: String Functions-Footnote-2554637 +Ref: String Functions-Footnote-3554885 +Node: Gory Details554972 +Ref: table-sub-escapes556763 +Ref: table-sub-proposed558282 +Ref: table-posix-sub559645 +Ref: table-gensub-escapes561186 +Ref: Gory Details-Footnote-1562009 +Node: I/O Functions562163 +Ref: table-system-return-values568745 +Ref: I/O Functions-Footnote-1570725 +Ref: I/O Functions-Footnote-2570873 +Node: Time Functions570993 +Ref: Time Functions-Footnote-1581660 +Ref: Time Functions-Footnote-2581728 +Ref: Time Functions-Footnote-3581886 +Ref: Time Functions-Footnote-4581997 +Ref: Time Functions-Footnote-5582109 +Ref: Time Functions-Footnote-6582336 +Node: Bitwise Functions582602 +Ref: table-bitwise-ops583196 +Ref: Bitwise Functions-Footnote-1589229 +Ref: Bitwise Functions-Footnote-2589402 +Node: Type Functions589593 +Node: I18N Functions592510 +Node: User-defined594161 +Node: Definition Syntax594966 +Ref: Definition Syntax-Footnote-1600653 +Node: Function Example600724 +Ref: Function Example-Footnote-1603646 +Node: Function Caveats603668 +Node: Calling A Function604186 +Node: Variable Scope605144 +Node: Pass By Value/Reference608138 +Node: Return Statement611637 +Node: Dynamic Typing614616 +Node: Indirect Calls615546 +Ref: Indirect Calls-Footnote-1625797 +Node: Functions Summary625925 +Node: Library Functions628630 +Ref: Library Functions-Footnote-1632237 +Ref: Library Functions-Footnote-2632380 +Node: Library Names632551 +Ref: Library Names-Footnote-1636011 +Ref: Library Names-Footnote-2636234 +Node: General Functions636320 +Node: Strtonum Function637423 +Node: Assert Function640445 +Node: Round Function643771 +Node: Cliff Random Function645312 +Node: Ordinal Functions646328 +Ref: Ordinal Functions-Footnote-1649391 +Ref: Ordinal Functions-Footnote-2649643 +Node: Join Function649853 +Ref: Join Function-Footnote-1651623 +Node: Getlocaltime Function651823 +Node: Readfile Function655565 +Node: Shell Quoting657537 +Node: Data File Management658938 +Node: Filetrans Function659570 +Node: Rewind Function663666 +Node: File Checking665576 +Ref: File Checking-Footnote-1666910 +Node: Empty Files667111 +Node: Ignoring Assigns669090 +Node: Getopt Function670640 +Ref: Getopt Function-Footnote-1682109 +Node: Passwd Functions682309 +Ref: Passwd Functions-Footnote-1691148 +Node: Group Functions691236 +Ref: Group Functions-Footnote-1699134 +Node: Walking Arrays699341 +Node: Library Functions Summary702349 +Node: Library Exercises703755 +Node: Sample Programs704220 +Node: Running Examples704990 +Node: Clones705718 +Node: Cut Program706942 +Node: Egrep Program716871 +Ref: Egrep Program-Footnote-1724383 +Node: Id Program724493 +Node: Split Program728173 +Ref: Split Program-Footnote-1731632 +Node: Tee Program731761 +Node: Uniq Program734551 +Node: Wc Program741977 +Ref: Wc Program-Footnote-1746232 +Node: Miscellaneous Programs746326 +Node: Dupword Program747539 +Node: Alarm Program749569 +Node: Translate Program754424 +Ref: Translate Program-Footnote-1758989 +Node: Labels Program759259 +Ref: Labels Program-Footnote-1762610 +Node: Word Sorting762694 +Node: History Sorting766766 +Node: Extract Program768601 +Node: Simple Sed776130 +Node: Igawk Program779204 +Ref: Igawk Program-Footnote-1793535 +Ref: Igawk Program-Footnote-2793737 +Ref: Igawk Program-Footnote-3793859 +Node: Anagram Program793974 +Node: Signature Program797036 +Node: Programs Summary798283 +Node: Programs Exercises799497 +Ref: Programs Exercises-Footnote-1803626 +Node: Advanced Features803717 +Node: Nondecimal Data805707 +Node: Array Sorting807298 +Node: Controlling Array Traversal807998 +Ref: Controlling Array Traversal-Footnote-1816365 +Node: Array Sorting Functions816483 +Ref: Array Sorting Functions-Footnote-1821574 +Node: Two-way I/O821770 +Ref: Two-way I/O-Footnote-1828321 +Ref: Two-way I/O-Footnote-2828508 +Node: TCP/IP Networking828590 +Node: Profiling831708 +Ref: Profiling-Footnote-1840380 +Node: Advanced Features Summary840703 +Node: Internationalization842547 +Node: I18N and L10N844027 +Node: Explaining gettext844714 +Ref: Explaining gettext-Footnote-1850606 +Ref: Explaining gettext-Footnote-2850791 +Node: Programmer i18n850956 +Ref: Programmer i18n-Footnote-1855905 +Node: Translator i18n855954 +Node: String Extraction856748 +Ref: String Extraction-Footnote-1857880 +Node: Printf Ordering857966 +Ref: Printf Ordering-Footnote-1860752 +Node: I18N Portability860816 +Ref: I18N Portability-Footnote-1863272 +Node: I18N Example863335 +Ref: I18N Example-Footnote-1866141 +Node: Gawk I18N866214 +Node: I18N Summary866859 +Node: Debugger868200 +Node: Debugging869222 +Node: Debugging Concepts869663 +Node: Debugging Terms871472 +Node: Awk Debugging874047 +Node: Sample Debugging Session874953 +Node: Debugger Invocation875487 +Node: Finding The Bug876873 +Node: List of Debugger Commands883351 +Node: Breakpoint Control884684 +Node: Debugger Execution Control888378 +Node: Viewing And Changing Data891740 +Node: Execution Stack895114 +Node: Debugger Info896751 +Node: Miscellaneous Debugger Commands900822 +Node: Readline Support905910 +Node: Limitations906806 +Node: Debugging Summary908915 +Node: Arbitrary Precision Arithmetic910194 +Node: Computer Arithmetic911679 +Ref: table-numeric-ranges915270 +Ref: Computer Arithmetic-Footnote-1915992 +Node: Math Definitions916049 +Ref: table-ieee-formats919363 +Ref: Math Definitions-Footnote-1919966 +Node: MPFR features920071 +Node: FP Math Caution921788 +Ref: FP Math Caution-Footnote-1922860 +Node: Inexactness of computations923229 +Node: Inexact representation924189 +Node: Comparing FP Values925549 +Node: Errors accumulate926631 +Node: Getting Accuracy928064 +Node: Try To Round930774 +Node: Setting precision931673 +Ref: table-predefined-precision-strings932370 +Node: Setting the rounding mode934200 +Ref: table-gawk-rounding-modes934574 +Ref: Setting the rounding mode-Footnote-1937982 +Node: Arbitrary Precision Integers938161 +Ref: Arbitrary Precision Integers-Footnote-1941336 +Node: Checking for MPFR941485 +Node: POSIX Floating Point Problems942782 +Ref: POSIX Floating Point Problems-Footnote-1946653 +Node: Floating point summary946691 +Node: Dynamic Extensions948881 +Node: Extension Intro950434 +Node: Plugin License951700 +Node: Extension Mechanism Outline952497 +Ref: figure-load-extension952936 +Ref: figure-register-new-function954501 +Ref: figure-call-new-function955593 +Node: Extension API Description957655 +Node: Extension API Functions Introduction959297 +Node: General Data Types964837 +Ref: General Data Types-Footnote-1972958 +Node: Memory Allocation Functions973257 +Ref: Memory Allocation Functions-Footnote-1977465 +Node: Constructor Functions977564 +Node: Registration Functions981150 +Node: Extension Functions981835 +Node: Exit Callback Functions987048 +Node: Extension Version String988298 +Node: Input Parsers988961 +Node: Output Wrappers1001682 +Node: Two-way processors1006194 +Node: Printing Messages1008459 +Ref: Printing Messages-Footnote-11009630 +Node: Updating ERRNO1009783 +Node: Requesting Values1010522 +Ref: table-value-types-returned1011259 +Node: Accessing Parameters1012195 +Node: Symbol Table Access1013430 +Node: Symbol table by name1013942 +Node: Symbol table by cookie1015731 +Ref: Symbol table by cookie-Footnote-11019916 +Node: Cached values1019980 +Ref: Cached values-Footnote-11023516 +Node: Array Manipulation1023669 +Ref: Array Manipulation-Footnote-11024760 +Node: Array Data Types1024797 +Ref: Array Data Types-Footnote-11027455 +Node: Array Functions1027547 +Node: Flattening Arrays1032045 +Node: Creating Arrays1039021 +Node: Redirection API1043790 +Node: Extension API Variables1046623 +Node: Extension Versioning1047334 +Ref: gawk-api-version1047763 +Node: Extension GMP/MPFR Versioning1049491 +Node: Extension API Informational Variables1051119 +Node: Extension API Boilerplate1052192 +Node: Changes from API V11056166 +Node: Finding Extensions1056826 +Node: Extension Example1057385 +Node: Internal File Description1058183 +Node: Internal File Ops1062263 +Ref: Internal File Ops-Footnote-11073663 +Node: Using Internal File Ops1073803 +Ref: Using Internal File Ops-Footnote-11076186 +Node: Extension Samples1076460 +Node: Extension Sample File Functions1077989 +Node: Extension Sample Fnmatch1085638 +Node: Extension Sample Fork1087125 +Node: Extension Sample Inplace1088343 +Node: Extension Sample Ord1091560 +Node: Extension Sample Readdir1092396 +Ref: table-readdir-file-types1093285 +Node: Extension Sample Revout1094090 +Node: Extension Sample Rev2way1094679 +Node: Extension Sample Read write array1095419 +Node: Extension Sample Readfile1097361 +Node: Extension Sample Time1098456 +Node: Extension Sample API Tests1099804 +Node: gawkextlib1100296 +Node: Extension summary1102743 +Node: Extension Exercises1106445 +Node: Language History1107943 +Node: V7/SVR3.11109599 +Node: SVR41111751 +Node: POSIX1113185 +Node: BTL1114564 +Node: POSIX/GNU1115293 +Node: Feature History1121071 +Node: Common Extensions1135436 +Node: Ranges and Locales1136719 +Ref: Ranges and Locales-Footnote-11141335 +Ref: Ranges and Locales-Footnote-21141362 +Ref: Ranges and Locales-Footnote-31141597 +Node: Contributors1141818 +Node: History summary1147446 +Node: Installation1148826 +Node: Gawk Distribution1149770 +Node: Getting1150254 +Node: Extracting1151215 +Node: Distribution contents1152853 +Node: Unix Installation1159195 +Node: Quick Installation1159877 +Node: Shell Startup Files1162291 +Node: Additional Configuration Options1163380 +Node: Configuration Philosophy1165369 +Node: Non-Unix Installation1167738 +Node: PC Installation1168198 +Node: PC Binary Installation1169036 +Node: PC Compiling1169471 +Node: PC Using1170588 +Node: Cygwin1173633 +Node: MSYS1174403 +Node: VMS Installation1174904 +Node: VMS Compilation1175695 +Ref: VMS Compilation-Footnote-11176924 +Node: VMS Dynamic Extensions1176982 +Node: VMS Installation Details1178667 +Node: VMS Running1180920 +Node: VMS GNV1185199 +Node: VMS Old Gawk1185934 +Node: Bugs1186405 +Node: Bug address1187068 +Node: Usenet1189465 +Node: Maintainers1190242 +Node: Other Versions1191503 +Node: Installation summary1198087 +Node: Notes1199122 +Node: Compatibility Mode1199987 +Node: Additions1200769 +Node: Accessing The Source1201694 +Node: Adding Code1203129 +Node: New Ports1209347 +Node: Derived Files1213835 +Ref: Derived Files-Footnote-11219320 +Ref: Derived Files-Footnote-21219355 +Ref: Derived Files-Footnote-31219953 +Node: Future Extensions1220067 +Node: Implementation Limitations1220725 +Node: Extension Design1221908 +Node: Old Extension Problems1223062 +Ref: Old Extension Problems-Footnote-11224580 +Node: Extension New Mechanism Goals1224637 +Ref: Extension New Mechanism Goals-Footnote-11228001 +Node: Extension Other Design Decisions1228190 +Node: Extension Future Growth1230303 +Node: Old Extension Mechanism1231139 +Node: Notes summary1232902 +Node: Basic Concepts1234084 +Node: Basic High Level1234765 +Ref: figure-general-flow1235047 +Ref: figure-process-flow1235732 +Ref: Basic High Level-Footnote-11239033 +Node: Basic Data Typing1239218 +Node: Glossary1242546 +Node: Copying1274493 +Node: GNU Free Documentation License1312032 +Node: Index1337150  End Tag Table diff --git a/doc/gawk.texi b/doc/gawk.texi index 3fa98afd..e44abad5 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -945,6 +945,8 @@ particular records in a file and perform operations upon them. redirections. * Extension API Variables:: Variables provided by the API. * Extension Versioning:: API Version information. +* Extension GMP/MPFR Versioning:: Version information about GMP and + MPFR. * Extension API Informational Variables:: Variables providing information about @command{gawk}'s invocation. * Extension API Boilerplate:: Boilerplate code for using the API. @@ -32707,6 +32709,11 @@ is necessary in order to keep @file{gawkapi.h} clean, instead of becoming a portability hodge-podge as can be seen in some parts of the @command{gawk} source code. +@item +If your extension uses MPFR facilities, and you wish to receive such +values from @command{gawk} and/or pass such values to it, you must include the +@code{} header before including @code{}. + @item The @file{gawkapi.h} file may be included more than once without ill effect. Doing so, however, is poor coding practice. @@ -32845,7 +32852,7 @@ It is used in the following @code{struct}. @itemx @ @ @ @ awk_valtype_t val_type; @itemx @ @ @ @ union @{ @itemx @ @ @ @ @ @ @ @ awk_string_t@ @ @ @ @ @ @ s; -@itemx @ @ @ @ @ @ @ @ double@ @ @ @ @ @ @ @ @ @ @ @ @ d; +@itemx @ @ @ @ @ @ @ @ awknum_t@ @ @ @ @ @ @ @ @ @ @ n; @itemx @ @ @ @ @ @ @ @ awk_array_t@ @ @ @ @ @ @ @ a; @itemx @ @ @ @ @ @ @ @ awk_scalar_t@ @ @ @ @ @ @ scl; @itemx @ @ @ @ @ @ @ @ awk_value_cookie_t@ vc; @@ -32858,13 +32865,37 @@ The @code{val_type} member indicates what kind of value the @item #define str_value@ @ @ @ @ @ u.s @itemx #define strnum_value@ @ @ str_value @itemx #define regex_value@ @ @ @ str_value -@itemx #define num_value@ @ @ @ @ @ u.d +@itemx #define num_value@ @ @ @ @ @ u.n.d +@itemx #define num_type@ @ @ @ @ @ @ u.n.type +@itemx #define num_ptr@ @ @ @ @ @ @ @ u.n.ptr @itemx #define array_cookie@ @ @ u.a @itemx #define scalar_cookie@ @ u.scl @itemx #define value_cookie@ @ @ u.vc Using these macros makes accessing the fields of the @code{awk_value_t} more readable. +@item typedef struct awk_number @{ +@itemx @ @ @ @ double d; +@itemx @ @ @ @ enum AWK_NUMBER_TYPE @{ +@itemx @ @ @ @ @ @ @ @ AWK_NUMBER_TYPE_DOUBLE, +@itemx @ @ @ @ @ @ @ @ AWK_NUMBER_TYPE_MPFR, +@itemx @ @ @ @ @ @ @ @ AWK_NUMBER_TYPE_MPZ +@itemx @ @ @ @ @} type; +@itemx @ @ @ @ void *ptr; +@itemx @} awk_number_t; +This represents a numeric value. Internally, @command{gawk} stores +every number as either a C @code{double}, a GMP integer, or an MPFR +arbitrary-precision floating-point value. In order to allow extensions +to also support GMP and MPFR values, numeric values are passed in this +structure. + +The double-precision @code{d} element is always populated +in data received from @command{gawk}. In addition, by examining the +@code{type} member, an extension can determine if the @code{ptr} +member is either a GMP integer (type @code{mpz_ptr}), or an MPFR +floating-point value (type @code{mpfr_ptr_t}), and cast it appropriately. + + @item typedef void *awk_scalar_t; Scalars can be represented as an opaque type. These values are obtained from @command{gawk} and then passed back into it. This is discussed @@ -33045,6 +33076,31 @@ instead of @code{gawk_malloc()}. The arguments are the same as for the @code{emalloc()} macro. @end table +Two additional functions allocate MPFR and GMP objects for use +by extension functions that need to create and then return such +values: + +@table @code +@item void *get_mpfr_ptr(); +Allocate and initialize an MPFR object and return a pointer to it. +If the allocation fails, @command{gawk} exits with a fatal +``out of memory'' error. If @command{gawk} was compiled without +MPFR support, calling this function causes a fatal error. + +@item void *get_mpz_ptr(); +Allocate and initialize a GMP object and return a pointer to it. +If the allocation fails, @command{gawk} exits with a fatal +``out of memory'' error. If @command{gawk} was compiled without +MPFR support, calling this function causes a fatal error. +@end table + +Both of these functions return @samp{void *}, since the @file{gawkapi.h} +header file should not have dependency upon @code{} (and @code{}, +which is included from @code{}). The actual return values are of +types @code{mpfr_ptr} and @code{mpz_ptr} respectively, and you should cast +the return values appropriately before assigning the results to variables +of the correct types. + @node Constructor Functions @subsection Constructor Functions @@ -33080,6 +33136,20 @@ It returns @code{result}. This function simply creates a numeric value in the @code{awk_value_t} variable pointed to by @code{result}. +@item static inline awk_value_t * +@itemx make_number_mpz(void *mpz, awk_value_t *result); +This function creates a GMP number value in @code{result}. +The @code{mpz} must be from a call to @code{get_mpz_ptr()} +(and thus be or real underlying type @code{mpz_ptr}). +@command{gawk} takes ownership of this memory. + +@item static inline awk_value_t * +@itemx make_number_mpfr(void *mpfr, awk_value_t *result); +This function creates an MPFR number value in @code{result}. +The @code{mpfr} must be from a call to @code{get_mpfr_ptr()}. +(and thus be or real underlying type @code{mpfr_ptr}) +@command{gawk} takes ownership of this memory. + @item static inline awk_value_t * @itemx make_const_user_input(const char *string, size_t length, awk_value_t *result); This function is identical to @code{make_const_string()}, but the string is @@ -33598,9 +33668,9 @@ the length of the field. The values in @code{fields[0]} provide the information for @code{$1}, and so on through the @code{fields[nf-1]} element containing the information for @code{$NF}. @end table -A convenience macro @code{awk_fieldwidth_info_size(NF)} is provided to +A convenience macro @code{awk_fieldwidth_info_size(numfields)} is provided to calculate the appropriate size of a variable-length -@code{awk_fieldwidth_info_t} structure containing @code{NF} fields. This can +@code{awk_fieldwidth_info_t} structure containing @code{numfields} fields. This can be used as an argument to @code{malloc()} or in a union to allocate space statically. Please refer to the @code{readdir_test} sample extension for an example. @@ -34217,7 +34287,8 @@ However, you can understand the point of cached values if you remember that @code{gawk_calloc()}, or @code{gawk_realloc()}. If you have 20 variables, all of which have the same string value, you must create 20 identical copies of the string.@footnote{Numeric values -are clearly less problematic, requiring only a C @code{double} to store.} +are clearly less problematic, requiring only a C @code{double} to store. +But of course, GMP and MPFR values @emph{do} take up more memory.} It is clearly more efficient, if possible, to create a value once, and then tell @command{gawk} to reuse the value for multiple variables. That @@ -34452,7 +34523,10 @@ The array remains an array, but after calling this function, it has no elements. This is equivalent to using the @code{delete} statement (@pxref{Delete}). -@item awk_bool_t flatten_array_typed(awk_array_t a_cookie, awk_flat_array_t **data, awk_valtype_t index_type, awk_valtype_t value_type); +@item awk_bool_t flatten_array_typed(awk_array_t a_cookie, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_flat_array_t **data, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t index_type, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t value_type); For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t} structure and fill it in with indices and values of the requested types. Set the pointer whose address is passed as @code{data} @@ -34587,7 +34661,8 @@ to double-check that the count in the @code{awk_flat_array_t} is the same as the count just retrieved: @example - if (! flatten_array_typed(value2.array_cookie, & flat_array, AWK_STRING, AWK_UNDEFINED)) @{ + if (! flatten_array_typed(value2.array_cookie, & flat_array, + AWK_STRING, AWK_UNDEFINED)) @{ printf("dump_array_and_delete: could not flatten array\n"); goto out; @} @@ -34922,10 +34997,11 @@ A pipe opened for input. A two-way coprocess. @end table -On error, return an @code{awk_false} value. Otherwise, return +On error, return @code{awk_false}. Otherwise, return @code{awk_true}, and return additional information about the redirection -in the @code{ibufp} and @code{obufp} pointers. For input -redirections, the @code{*ibufp} value should be non-@code{NULL}, +in the @code{ibufp} and @code{obufp} pointers. + +For input redirections, the @code{*ibufp} value should be non-@code{NULL}, and @code{*obufp} should be @code{NULL}. For output redirections, the @code{*obufp} value should be non-@code{NULL}, and @code{*ibufp} should be @code{NULL}. For two-way coprocesses, both values should @@ -34961,9 +35037,10 @@ and with which @command{gawk} was compiled). The second provides information about how @command{gawk} was invoked. @menu -* Extension Versioning:: API Version information. +* Extension Versioning:: API Version information. +* Extension GMP/MPFR Versioning:: Version information about GMP and MPFR. * Extension API Informational Variables:: Variables providing information about - @command{gawk}'s invocation. + @command{gawk}'s invocation. @end menu @node Extension Versioning @@ -35024,6 +35101,49 @@ Such code is included in the boilerplate @code{dl_load_func()} macro provided in @file{gawkapi.h} (discussed in @ref{Extension API Boilerplate}). +@node Extension GMP/MPFR Versioning +@subsubsection GMP and MPFR Version Information + +The API also includes information about the versions of GMP and MPFR +with which the running @command{gawk} was compiled (if any). +They are included in the API @code{struct} as read-only +constant integers: + +@table @code +@item api->gmp_major_version +The major version of the GMP library used to compile @command{gawk}. + +@item api->gmp_minor_version +The minor version of the GMP library used to compile @command{gawk}. + +@item api->mpfr_major_version +The major version of the MPFR library used to compile @command{gawk}. + +@item api->mpfr_minor_version +The minor version of the MPFR library used to compile @command{gawk}. +@end table + +These fields are set to zero if @command{gawk} was compiled without +MPFR support. + +You can check if the versions of MPFR and GMP that you are using match those +of @command{gawk} with the following macro: + +@table @code +@item check_mpfr_version(extension) +The @code{extension} is the extension id passed to all the other macros +and functions defined in @file{gawkapi.h}. If you have not included +the @code{} header file, then this macro will be defined to do nothing. + +If you have included that file, then this macro compares the MPFR +and GMP major and minor versions against those of the library you are +compiling against. If your libraries are newer than @command{gawk}'s, it +produces a fatal error message. + +The @code{dl_load_func()} macro (@pxref{Extension API Boilerplate}) +calls @code{check_mpfr_version()}. +@end table + @node Extension API Informational Variables @subsubsection Informational Variables @cindex API informational variables @@ -35162,6 +35282,10 @@ Check the API versions. If the extension major version does not match @command{gawk}'s, or if the extension minor version is greater than @command{gawk}'s, it prints a fatal error message and exits. +@item +Check the MPFR and GMP versions. If there is a mismatch, it prints +a fatal error message and exits. + @item Load the functions defined in @code{func_table}. If any of them fails to load, it prints a warning message but diff --git a/doc/gawktexi.in b/doc/gawktexi.in index 5b6d56bf..8ad4c72e 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -940,6 +940,8 @@ particular records in a file and perform operations upon them. redirections. * Extension API Variables:: Variables provided by the API. * Extension Versioning:: API Version information. +* Extension GMP/MPFR Versioning:: Version information about GMP and + MPFR. * Extension API Informational Variables:: Variables providing information about @command{gawk}'s invocation. * Extension API Boilerplate:: Boilerplate code for using the API. @@ -31721,6 +31723,11 @@ is necessary in order to keep @file{gawkapi.h} clean, instead of becoming a portability hodge-podge as can be seen in some parts of the @command{gawk} source code. +@item +If your extension uses MPFR facilities, and you wish to receive such +values from @command{gawk} and/or pass such values to it, you must include the +@code{} header before including @code{}. + @item The @file{gawkapi.h} file may be included more than once without ill effect. Doing so, however, is poor coding practice. @@ -31859,7 +31866,7 @@ It is used in the following @code{struct}. @itemx @ @ @ @ awk_valtype_t val_type; @itemx @ @ @ @ union @{ @itemx @ @ @ @ @ @ @ @ awk_string_t@ @ @ @ @ @ @ s; -@itemx @ @ @ @ @ @ @ @ double@ @ @ @ @ @ @ @ @ @ @ @ @ d; +@itemx @ @ @ @ @ @ @ @ awknum_t@ @ @ @ @ @ @ @ @ @ @ n; @itemx @ @ @ @ @ @ @ @ awk_array_t@ @ @ @ @ @ @ @ a; @itemx @ @ @ @ @ @ @ @ awk_scalar_t@ @ @ @ @ @ @ scl; @itemx @ @ @ @ @ @ @ @ awk_value_cookie_t@ vc; @@ -31872,13 +31879,37 @@ The @code{val_type} member indicates what kind of value the @item #define str_value@ @ @ @ @ @ u.s @itemx #define strnum_value@ @ @ str_value @itemx #define regex_value@ @ @ @ str_value -@itemx #define num_value@ @ @ @ @ @ u.d +@itemx #define num_value@ @ @ @ @ @ u.n.d +@itemx #define num_type@ @ @ @ @ @ @ u.n.type +@itemx #define num_ptr@ @ @ @ @ @ @ @ u.n.ptr @itemx #define array_cookie@ @ @ u.a @itemx #define scalar_cookie@ @ u.scl @itemx #define value_cookie@ @ @ u.vc Using these macros makes accessing the fields of the @code{awk_value_t} more readable. +@item typedef struct awk_number @{ +@itemx @ @ @ @ double d; +@itemx @ @ @ @ enum AWK_NUMBER_TYPE @{ +@itemx @ @ @ @ @ @ @ @ AWK_NUMBER_TYPE_DOUBLE, +@itemx @ @ @ @ @ @ @ @ AWK_NUMBER_TYPE_MPFR, +@itemx @ @ @ @ @ @ @ @ AWK_NUMBER_TYPE_MPZ +@itemx @ @ @ @ @} type; +@itemx @ @ @ @ void *ptr; +@itemx @} awk_number_t; +This represents a numeric value. Internally, @command{gawk} stores +every number as either a C @code{double}, a GMP integer, or an MPFR +arbitrary-precision floating-point value. In order to allow extensions +to also support GMP and MPFR values, numeric values are passed in this +structure. + +The double-precision @code{d} element is always populated +in data received from @command{gawk}. In addition, by examining the +@code{type} member, an extension can determine if the @code{ptr} +member is either a GMP integer (type @code{mpz_ptr}), or an MPFR +floating-point value (type @code{mpfr_ptr_t}), and cast it appropriately. + + @item typedef void *awk_scalar_t; Scalars can be represented as an opaque type. These values are obtained from @command{gawk} and then passed back into it. This is discussed @@ -32059,6 +32090,31 @@ instead of @code{gawk_malloc()}. The arguments are the same as for the @code{emalloc()} macro. @end table +Two additional functions allocate MPFR and GMP objects for use +by extension functions that need to create and then return such +values: + +@table @code +@item void *get_mpfr_ptr(); +Allocate and initialize an MPFR object and return a pointer to it. +If the allocation fails, @command{gawk} exits with a fatal +``out of memory'' error. If @command{gawk} was compiled without +MPFR support, calling this function causes a fatal error. + +@item void *get_mpz_ptr(); +Allocate and initialize a GMP object and return a pointer to it. +If the allocation fails, @command{gawk} exits with a fatal +``out of memory'' error. If @command{gawk} was compiled without +MPFR support, calling this function causes a fatal error. +@end table + +Both of these functions return @samp{void *}, since the @file{gawkapi.h} +header file should not have dependency upon @code{} (and @code{}, +which is included from @code{}). The actual return values are of +types @code{mpfr_ptr} and @code{mpz_ptr} respectively, and you should cast +the return values appropriately before assigning the results to variables +of the correct types. + @node Constructor Functions @subsection Constructor Functions @@ -32094,6 +32150,20 @@ It returns @code{result}. This function simply creates a numeric value in the @code{awk_value_t} variable pointed to by @code{result}. +@item static inline awk_value_t * +@itemx make_number_mpz(void *mpz, awk_value_t *result); +This function creates a GMP number value in @code{result}. +The @code{mpz} must be from a call to @code{get_mpz_ptr()} +(and thus be or real underlying type @code{mpz_ptr}). +@command{gawk} takes ownership of this memory. + +@item static inline awk_value_t * +@itemx make_number_mpfr(void *mpfr, awk_value_t *result); +This function creates an MPFR number value in @code{result}. +The @code{mpfr} must be from a call to @code{get_mpfr_ptr()}. +(and thus be or real underlying type @code{mpfr_ptr}) +@command{gawk} takes ownership of this memory. + @item static inline awk_value_t * @itemx make_const_user_input(const char *string, size_t length, awk_value_t *result); This function is identical to @code{make_const_string()}, but the string is @@ -32612,9 +32682,9 @@ the length of the field. The values in @code{fields[0]} provide the information for @code{$1}, and so on through the @code{fields[nf-1]} element containing the information for @code{$NF}. @end table -A convenience macro @code{awk_fieldwidth_info_size(NF)} is provided to +A convenience macro @code{awk_fieldwidth_info_size(numfields)} is provided to calculate the appropriate size of a variable-length -@code{awk_fieldwidth_info_t} structure containing @code{NF} fields. This can +@code{awk_fieldwidth_info_t} structure containing @code{numfields} fields. This can be used as an argument to @code{malloc()} or in a union to allocate space statically. Please refer to the @code{readdir_test} sample extension for an example. @@ -33231,7 +33301,8 @@ However, you can understand the point of cached values if you remember that @code{gawk_calloc()}, or @code{gawk_realloc()}. If you have 20 variables, all of which have the same string value, you must create 20 identical copies of the string.@footnote{Numeric values -are clearly less problematic, requiring only a C @code{double} to store.} +are clearly less problematic, requiring only a C @code{double} to store. +But of course, GMP and MPFR values @emph{do} take up more memory.} It is clearly more efficient, if possible, to create a value once, and then tell @command{gawk} to reuse the value for multiple variables. That @@ -33466,7 +33537,10 @@ The array remains an array, but after calling this function, it has no elements. This is equivalent to using the @code{delete} statement (@pxref{Delete}). -@item awk_bool_t flatten_array_typed(awk_array_t a_cookie, awk_flat_array_t **data, awk_valtype_t index_type, awk_valtype_t value_type); +@item awk_bool_t flatten_array_typed(awk_array_t a_cookie, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_flat_array_t **data, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t index_type, +@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_valtype_t value_type); For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t} structure and fill it in with indices and values of the requested types. Set the pointer whose address is passed as @code{data} @@ -33601,7 +33675,8 @@ to double-check that the count in the @code{awk_flat_array_t} is the same as the count just retrieved: @example - if (! flatten_array_typed(value2.array_cookie, & flat_array, AWK_STRING, AWK_UNDEFINED)) @{ + if (! flatten_array_typed(value2.array_cookie, & flat_array, + AWK_STRING, AWK_UNDEFINED)) @{ printf("dump_array_and_delete: could not flatten array\n"); goto out; @} @@ -33936,10 +34011,11 @@ A pipe opened for input. A two-way coprocess. @end table -On error, return an @code{awk_false} value. Otherwise, return +On error, return @code{awk_false}. Otherwise, return @code{awk_true}, and return additional information about the redirection -in the @code{ibufp} and @code{obufp} pointers. For input -redirections, the @code{*ibufp} value should be non-@code{NULL}, +in the @code{ibufp} and @code{obufp} pointers. + +For input redirections, the @code{*ibufp} value should be non-@code{NULL}, and @code{*obufp} should be @code{NULL}. For output redirections, the @code{*obufp} value should be non-@code{NULL}, and @code{*ibufp} should be @code{NULL}. For two-way coprocesses, both values should @@ -33975,9 +34051,10 @@ and with which @command{gawk} was compiled). The second provides information about how @command{gawk} was invoked. @menu -* Extension Versioning:: API Version information. +* Extension Versioning:: API Version information. +* Extension GMP/MPFR Versioning:: Version information about GMP and MPFR. * Extension API Informational Variables:: Variables providing information about - @command{gawk}'s invocation. + @command{gawk}'s invocation. @end menu @node Extension Versioning @@ -34038,6 +34115,49 @@ Such code is included in the boilerplate @code{dl_load_func()} macro provided in @file{gawkapi.h} (discussed in @ref{Extension API Boilerplate}). +@node Extension GMP/MPFR Versioning +@subsubsection GMP and MPFR Version Information + +The API also includes information about the versions of GMP and MPFR +with which the running @command{gawk} was compiled (if any). +They are included in the API @code{struct} as read-only +constant integers: + +@table @code +@item api->gmp_major_version +The major version of the GMP library used to compile @command{gawk}. + +@item api->gmp_minor_version +The minor version of the GMP library used to compile @command{gawk}. + +@item api->mpfr_major_version +The major version of the MPFR library used to compile @command{gawk}. + +@item api->mpfr_minor_version +The minor version of the MPFR library used to compile @command{gawk}. +@end table + +These fields are set to zero if @command{gawk} was compiled without +MPFR support. + +You can check if the versions of MPFR and GMP that you are using match those +of @command{gawk} with the following macro: + +@table @code +@item check_mpfr_version(extension) +The @code{extension} is the extension id passed to all the other macros +and functions defined in @file{gawkapi.h}. If you have not included +the @code{} header file, then this macro will be defined to do nothing. + +If you have included that file, then this macro compares the MPFR +and GMP major and minor versions against those of the library you are +compiling against. If your libraries are newer than @command{gawk}'s, it +produces a fatal error message. + +The @code{dl_load_func()} macro (@pxref{Extension API Boilerplate}) +calls @code{check_mpfr_version()}. +@end table + @node Extension API Informational Variables @subsubsection Informational Variables @cindex API informational variables @@ -34176,6 +34296,10 @@ Check the API versions. If the extension major version does not match @command{gawk}'s, or if the extension minor version is greater than @command{gawk}'s, it prints a fatal error message and exits. +@item +Check the MPFR and GMP versions. If there is a mismatch, it prints +a fatal error message and exits. + @item Load the functions defined in @code{func_table}. If any of them fails to load, it prints a warning message but -- cgit v1.2.3 From eaac293d06266c89156cc94bc8fd24a4ad7db0e1 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 13 Aug 2017 21:41:14 +0300 Subject: Update version and copyright year in docs. --- doc/ChangeLog | 5 +++++ doc/awkcard.in | 2 +- doc/gawk.1 | 8 ++++---- doc/gawk.info | 28 ++++++++++++++-------------- doc/gawk.texi | 6 +++--- doc/gawktexi.in | 6 +++--- 6 files changed, 30 insertions(+), 25 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 971d0027..86c1d130 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2017-08-13 Arnold D. Robbins + + * gawktexi.in, gawk.1, awkcard.in: Update versions and + copyright years, prepatory to starting a release spiral. + 2017-08-13 Arnold D. Robbins * gawktexi.in: Update API chapter with info about additions diff --git a/doc/awkcard.in b/doc/awkcard.in index 165fca43..fac0e931 100644 --- a/doc/awkcard.in +++ b/doc/awkcard.in @@ -1956,7 +1956,7 @@ to use the current domain.\*(CB .ES .nf \*(CDHost: \*(FCftp.gnu.org\*(FR -File: \*(FC/gnu/gawk/gawk-4.1.4.tar.gz\fP +File: \*(FC/gnu/gawk/gawk-4.2.0.tar.gz\fP .in +.2i .fi GNU \*(AK (\*(GK). There may be a later version. diff --git a/doc/gawk.1 b/doc/gawk.1 index 1b42cc90..d1618884 100644 --- a/doc/gawk.1 +++ b/doc/gawk.1 @@ -13,7 +13,7 @@ . if \w'\(rq' .ds rq "\(rq . \} .\} -.TH GAWK 1 "Jun 30 2016" "Free Software Foundation" "Utility Commands" +.TH GAWK 1 "Aug 13 2017" "Free Software Foundation" "Utility Commands" .SH NAME gawk \- pattern scanning and processing language .SH SYNOPSIS @@ -3955,7 +3955,7 @@ status is 2. On non-POSIX systems, this value may be mapped to .SH VERSION INFORMATION This man page documents .IR gawk , -version 4.1. +version 4.2. .SH AUTHORS The original version of \*(UX .I awk @@ -4054,7 +4054,7 @@ Alfred V. Aho, Brian W. Kernighan, Peter J. Weinberger, Addison-Wesley, 1988. ISBN 0-201-07981-X. .PP \*(EP, -Edition 4.1, shipped with the +Edition 4.2, shipped with the .I gawk source. The current version of this document is available online at @@ -4101,7 +4101,7 @@ We thank him. .SH COPYING PERMISSIONS Copyright \(co 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2007, 2009, -2010, 2011, 2012, 2013, 2014, 2015, 2016 +2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Free Software Foundation, Inc. .PP Permission is granted to make and distribute verbatim copies of diff --git a/doc/gawk.info b/doc/gawk.info index 4faa99c6..9031d5e7 100644 --- a/doc/gawk.info +++ b/doc/gawk.info @@ -5,7 +5,7 @@ Free Software Foundation, Inc. This is Edition 4.1 of 'GAWK: Effective AWK Programming: A User's -Guide for GNU Awk', for the 4.1.4 (or later) version of the GNU +Guide for GNU Awk', for the 4.2.0 (or later) version of the GNU implementation of AWK. Permission is granted to copy, distribute and/or modify this document @@ -42,7 +42,7 @@ Free Software Foundation, Inc. This is Edition 4.1 of 'GAWK: Effective AWK Programming: A User's -Guide for GNU Awk', for the 4.1.4 (or later) version of the GNU +Guide for GNU Awk', for the 4.2.0 (or later) version of the GNU implementation of AWK. Permission is granted to copy, distribute and/or modify this document @@ -28486,7 +28486,7 @@ There are two ways to get GNU software: supported. If you have the 'wget' program, you can use a command like the following: - wget http://ftp.gnu.org/gnu/gawk/gawk-4.1.4.tar.gz + wget http://ftp.gnu.org/gnu/gawk/gawk-4.2.0.tar.gz The GNU software archive is mirrored around the world. The up-to-date list of mirror sites is available from the main FSF website @@ -28508,25 +28508,25 @@ compression programs: 'gzip', 'bzip2', and 'xz'. For simplicity, the rest of these instructions assume you are using the one compressed with the GNU Gzip program ('gzip'). - Once you have the distribution (e.g., 'gawk-4.1.4.tar.gz'), use + Once you have the distribution (e.g., 'gawk-4.2.0.tar.gz'), use 'gzip' to expand the file and then use 'tar' to extract it. You can use the following pipeline to produce the 'gawk' distribution: - gzip -d -c gawk-4.1.4.tar.gz | tar -xvpf - + gzip -d -c gawk-4.2.0.tar.gz | tar -xvpf - On a system with GNU 'tar', you can let 'tar' do the decompression for you: - tar -xvpzf gawk-4.1.4.tar.gz + tar -xvpzf gawk-4.2.0.tar.gz -Extracting the archive creates a directory named 'gawk-4.1.4' in the +Extracting the archive creates a directory named 'gawk-4.2.0' in the current directory. The distribution file name is of the form 'gawk-V.R.P.tar.gz'. The V represents the major version of 'gawk', the R represents the current release of version V, and the P represents a "patch level", meaning that minor bugs have been fixed in the release. The current patch level is -4, but when retrieving distributions, you should get the version with +0, but when retrieving distributions, you should get the version with the highest version, release, and patch level. (Note, however, that patch levels greater than or equal to 70 denote "beta" or nonproduction software; you might not want to retrieve such a version unless you don't @@ -28749,7 +28749,7 @@ Unix-derived systems, GNU/Linux, BSD-based systems, and the Cygwin environment for MS-Windows. After you have extracted the 'gawk' distribution, 'cd' to -'gawk-4.1.4'. As with most GNU software, you configure 'gawk' for your +'gawk-4.2.0'. As with most GNU software, you configure 'gawk' for your system by running the 'configure' program. This program is a Bourne shell script that is generated automatically using GNU Autoconf. (The Autoconf software is described fully starting with *note (Autoconf, @@ -29079,8 +29079,8 @@ environment provides an excellent simulation of GNU/Linux, using Bash, GCC, GNU Make, and other GNU programs. Compilation and installation for Cygwin is the same as for a Unix system: - tar -xvpzf gawk-4.1.4.tar.gz - cd gawk-4.1.4 + tar -xvpzf gawk-4.2.0.tar.gz + cd gawk-4.2.0 ./configure make && make check @@ -29690,9 +29690,9 @@ B.6 Summary * The 'gawk' distribution is available from the GNU Project's main distribution site, 'ftp.gnu.org'. The canonical build recipe is: - wget http://ftp.gnu.org/gnu/gawk/gawk-4.1.4.tar.gz - tar -xvpzf gawk-4.1.4.tar.gz - cd gawk-4.1.4 + wget http://ftp.gnu.org/gnu/gawk/gawk-4.2.0.tar.gz + tar -xvpzf gawk-4.2.0.tar.gz + cd gawk-4.2.0 ./configure && make && make check * 'gawk' may be built on non-POSIX systems as well. The currently diff --git a/doc/gawk.texi b/doc/gawk.texi index e44abad5..9c36c107 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -64,9 +64,9 @@ @c applies to and all the info about who's publishing this edition @c These apply across the board. -@set UPDATE-MONTH July, 2017 -@set VERSION 4.1 -@set PATCHLEVEL 4 +@set UPDATE-MONTH August, 2017 +@set VERSION 4.2 +@set PATCHLEVEL 0 @set GAWKINETTITLE TCP/IP Internetworking with @command{gawk} @ifset FOR_PRINT diff --git a/doc/gawktexi.in b/doc/gawktexi.in index 8ad4c72e..68f0510c 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -59,9 +59,9 @@ @c applies to and all the info about who's publishing this edition @c These apply across the board. -@set UPDATE-MONTH July, 2017 -@set VERSION 4.1 -@set PATCHLEVEL 4 +@set UPDATE-MONTH August, 2017 +@set VERSION 4.2 +@set PATCHLEVEL 0 @set GAWKINETTITLE TCP/IP Internetworking with @command{gawk} @ifset FOR_PRINT -- cgit v1.2.3 From 542d8b1b4ef00298b05b5b1cc19607ac9db6f47f Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 13 Aug 2017 21:41:32 +0300 Subject: Update version in preparation for release. --- configure | 20 ++++++++++---------- configure.ac | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/configure b/configure index 4b1b3209..50c92f8f 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for GNU Awk 4.1.61. +# Generated by GNU Autoconf 2.69 for GNU Awk 4.1.62. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='GNU Awk' PACKAGE_TARNAME='gawk' -PACKAGE_VERSION='4.1.61' -PACKAGE_STRING='GNU Awk 4.1.61' +PACKAGE_VERSION='4.1.62' +PACKAGE_STRING='GNU Awk 4.1.62' PACKAGE_BUGREPORT='bug-gawk@gnu.org' PACKAGE_URL='http://www.gnu.org/software/gawk/' @@ -1331,7 +1331,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures GNU Awk 4.1.61 to adapt to many kinds of systems. +\`configure' configures GNU Awk 4.1.62 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1401,7 +1401,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of GNU Awk 4.1.61:";; + short | recursive ) echo "Configuration of GNU Awk 4.1.62:";; esac cat <<\_ACEOF @@ -1526,7 +1526,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -GNU Awk configure 4.1.61 +GNU Awk configure 4.1.62 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2235,7 +2235,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by GNU Awk $as_me 4.1.61, which was +It was created by GNU Awk $as_me 4.1.62, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3118,7 +3118,7 @@ fi # Define the identity of the package. PACKAGE='gawk' - VERSION='4.1.61' + VERSION='4.1.62' cat >>confdefs.h <<_ACEOF @@ -11562,7 +11562,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by GNU Awk $as_me 4.1.61, which was +This file was extended by GNU Awk $as_me 4.1.62, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -11630,7 +11630,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -GNU Awk config.status 4.1.61 +GNU Awk config.status 4.1.62 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 785f5c5b..872874bf 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ dnl dnl Process this file with autoconf to produce a configure script. -AC_INIT([GNU Awk],[4.1.61],[bug-gawk@gnu.org],[gawk]) +AC_INIT([GNU Awk],[4.1.62],[bug-gawk@gnu.org],[gawk]) # This is a hack. Different versions of install on different systems # are just too different. Chuck it and use install-sh. -- cgit v1.2.3 From f1c5efe6a5ad9692c833ce2124493fb1d3ec6f37 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 13 Aug 2017 21:53:38 +0300 Subject: Sort and prettify the lists of tests. --- test/ChangeLog | 4 ++ test/Makefile.am | 119 +++++++++++++++++++++++++++-------------------------- test/Makefile.in | 122 ++++++++++++++++++++++++++++--------------------------- 3 files changed, 127 insertions(+), 118 deletions(-) diff --git a/test/ChangeLog b/test/ChangeLog index ee361790..b515aa08 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,7 @@ +2017-08-13 Arnold D. Robbins + + * Makefile.am: Sort and prettify the lists of tests. + 2017-08-09 Arnold D. Robbins * badargs.ok: Update after code changes. diff --git a/test/Makefile.am b/test/Makefile.am index f519b0db..c00e64ef 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1196,80 +1196,77 @@ CLEANFILES = core core.* fmtspcl.ok # try to keep these sorted. each letter starts a new line BASIC_TESTS = \ - addcomma anchgsub anchor argarray arrayind1 arrayind2 arrayind3 arrayparm arrayprm2 arrayprm3 \ - arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 arynasty \ - arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \ + addcomma anchgsub anchor argarray arrayind1 arrayind2 arrayind3 arrayparm \ + arrayprm2 arrayprm3 arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 \ + arynasty arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \ aryprm8 aryprm9 arysubnm aryunasgn asgext awkpath \ back89 backgsub badassign1 badbuild \ - callparam childin clobber closebad clsflnam compare compare2 concat1 concat2 \ - concat3 concat4 concat5 convfmt \ + callparam childin clobber closebad clsflnam compare compare2 \ + concat1 concat2 concat3 concat4 concat5 convfmt \ datanonl defref delargv delarpm2 delarprm delfunc dfamb1 dfastress dynlj \ - eofsplit exit2 exitval1 exitval2 exitval3 \ - fcall_exit fcall_exit2 fldchg fldchgnf fldterm fnamedat fnarray fnarray2 \ - fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fsnul1 fsrs fsspcoln \ - fstabplus funsemnl funsmnam funstack \ + eofsplit exit2 exitval1 exitval2 exitval3 fcall_exit fcall_exit2 \ + fldchg fldchgnf fldterm fnamedat fnarray fnarray2 fnaryscl fnasgnm fnmisc \ + fordel forref forsimp fsbs fsnul1 fsrs fsspcoln fstabplus funsemnl \ + funsmnam funstack \ getline getline2 getline3 getline4 getline5 getlnbuf getnr2tb getnr2tm \ - gsubasgn gsubtest gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 \ - gsubtst7 gsubtst8 \ + gsubasgn gsubtest gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 gsubtst7 \ + gsubtst8 \ hex hex2 hsprint \ inpref inputred intest intprec iobug1 \ leaddig leadnl litoct longsub longwrds \ manglprm math membug1 memleak messages minusstr mmap8k mtchi18n \ nasty nasty2 negexp negrange nested nfldstr nfloop nfneg nfset nlfldsep \ - nlinstr nlstrina noeffect nofile nofmtch noloop1 noloop2 nonl \ - noparms nors nulinsrc nulrsend numindex numsubstr \ + nlinstr nlstrina noeffect nofile nofmtch noloop1 noloop2 nonl noparms \ + nors nulinsrc nulrsend numindex numsubstr \ octsub ofmt ofmta ofmtbig ofmtfidl ofmts ofmtstrnum ofs1 onlynl \ opasnidx opasnslf \ - paramasfunc1 paramasfunc2 \ - paramdup paramres paramtyp paramuninitglobal parse1 parsefld parseme \ - pcntplus posix2008sub prdupval prec printf0 printf1 printfchar prmarscl prmreuse \ - prt1eval prtoeval \ - rand randtest range1 readbuf rebrackloc rebt8b1 rebuild redfilnm \ - regeq regexpbrack regexpbrack2 \ - regexprange regrange reindops \ - reparse resplit rri1 rs rscompat rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 \ - rstest3 rstest4 rstest5 rswhite \ - scalar sclforin sclifin sigpipe1 sortempty sortglos splitargv splitarr splitdef \ - splitvar splitwht status-close strcat1 strnum1 strnum2 strtod subamp subback subi18n \ - subsepnm subslash substr swaplns synerr1 synerr2 tradanch tweakfld \ + paramasfunc1 paramasfunc2 paramdup paramres paramtyp paramuninitglobal \ + parse1 parsefld parseme pcntplus posix2008sub prdupval prec printf0 \ + printf1 printfchar prmarscl prmreuse prt1eval prtoeval \ + rand randtest range1 readbuf rebrackloc rebt8b1 rebuild redfilnm regeq \ + regexpbrack regexpbrack2 regexprange regrange reindops reparse resplit \ + rri1 rs rscompat rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 rstest3 \ + rstest4 rstest5 rswhite \ + scalar sclforin sclifin sigpipe1 sortempty sortglos splitargv splitarr \ + splitdef splitvar splitwht status-close strcat1 strnum1 strnum2 strtod \ + subamp subback subi18n subsepnm subslash substr swaplns synerr1 synerr2 \ + tradanch tweakfld \ uninit2 uninit3 uninit4 uninit5 uninitialized unterm uparrfs \ wideidx wideidx2 widesub widesub2 widesub3 widesub4 wjposer1 \ zero2 zeroe0 zeroflag UNIX_TESTS = \ - fflush getlnhd localenl pid pipeio1 pipeio2 poundbang \ - rtlen rtlen01 space strftlng + fflush getlnhd localenl pid pipeio1 pipeio2 poundbang rtlen rtlen01 \ + space strftlng GAWK_EXT_TESTS = \ aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \ - backw badargs beginfile1 beginfile2 binmode1 charasbytes \ - colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 clos1way6 \ - crlf dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \ - devfd devfd1 devfd2 dumpvars errno exit \ - fieldwdth forcenum fpat1 fpat2 fpat3 fpat4 fpat5 fpat6 fpatnull \ - fsfwfs funlen functab1 functab2 functab3 \ - fwtest fwtest2 fwtest3 fwtest4 fwtest5 fwtest6 fwtest7 fwtest8 \ + backw badargs beginfile1 beginfile2 binmode1 \ + charasbytes colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 \ + clos1way6 crlf \ + dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \ + devfd devfd1 devfd2 dumpvars \ + errno exit \ + fieldwdth forcenum fpat1 fpat2 fpat3 fpat4 fpat5 fpat6 fpatnull fsfwfs \ + funlen functab1 functab2 functab3 fwtest fwtest2 fwtest3 fwtest4 \ + fwtest5 fwtest6 fwtest7 fwtest8 \ genpot gensub gensub2 gensub3 getlndir gnuops2 gnuops3 gnureops gsubind \ - icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase \ - incdupe incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 \ - include include2 indirectbuiltin indirectcall indirectcall2 intarray \ + icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase incdupe \ + incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 include include2 \ + indirectbuiltin indirectcall indirectcall2 intarray \ lint lintexp lintindex lintint lintlength lintold lintset lintwarn \ - mixed1 mktime manyfiles match1 match2 match3 mbstr1 mbstr2 \ - muldimposix \ - nastyparm negtime next nondec nondec2 \ - nonfatal1 nonfatal2 nonfatal3 \ - patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \ - profile0 profile1 profile2 profile3 profile4 profile5 profile6 profile7 \ - profile8 profile9 profile10 pty1 \ - rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \ - rsstart2 rsstart3 rstest6 shadow shadowbuiltin \ - sortfor sortfor2 sortu sourcesplit split_after_fpat \ - splitarg4 strftime strftfld \ - strtonum strtonum1 switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \ - symtab7 symtab8 symtab9 symtab10 \ - typedregex1 typedregex2 typedregex3 \ - typeof1 typeof2 typeof3 typeof4 typeof5 \ - timeout \ + mixed1 mktime manyfiles match1 match2 match3 mbstr1 mbstr2 muldimposix \ + nastyparm negtime next nondec nondec2 nonfatal1 nonfatal2 nonfatal3 \ + patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge \ + procinfs profile0 profile1 profile2 profile3 profile4 profile5 profile6 \ + profile7 profile8 profile9 profile10 pty1 \ + rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin \ + rsstart1 rsstart2 rsstart3 rstest6 \ + shadow shadowbuiltin sortfor sortfor2 sortu sourcesplit split_after_fpat \ + splitarg4 strftime strftfld strtonum strtonum1 switch2 symtab1 symtab2 \ + symtab3 symtab4 symtab5 symtab6 symtab7 symtab8 symtab9 symtab10 \ + typedregex1 typedregex2 typedregex3 typeof1 typeof2 typeof3 typeof4 \ + typeof5 timeout \ watchpoint1 ARRAYDEBUG_TESTS = arrdbg @@ -1280,7 +1277,7 @@ INET_TESTS = inetdayu inetdayt inetechu inetecht MACHINE_TESTS = double1 double2 fmtspcl intformat -MPFR_TESTS = mpfrnr mpfrnegzero mpfrmemok1 mpfrrem mpfrrnd mpfrieee \ +MPFR_TESTS = mpfrnr mpfrnegzero mpfrmemok1 mpfrrem mpfrrnd mpfrieee mpfrexprange mpfrsort mpfrsqrt mpfrbigint mpfrstrtonum mpgforcenum LOCALE_CHARSET_TESTS = \ @@ -1290,13 +1287,19 @@ LOCALE_CHARSET_TESTS = \ rebt8b2 rtlenmb sort1 sprintfc SHLIB_TESTS = \ - apiterm fnmatch filefuncs fork fork2 fts functab4 getfile inplace1 inplace2 inplace3 \ - ordchr ordchr2 readdir readdir_test readfile readfile2 revout revtwoway rwarray testext time + apiterm \ + filefuncs fnmatch fork fork2 fts functab4 \ + getfile \ + inplace1 inplace2 inplace3 \ + ordchr ordchr2 \ + readdir readdir_test readfile readfile2 revout \ + revtwoway rwarray \ + testext time # List of the tests which should be run with --lint option: NEED_LINT = \ - defref fmtspcl lintexp lintindex lintint lintlength lintwarn noeffect nofmtch shadow \ - uninit2 uninit3 uninit4 uninit5 uninitialized + defref fmtspcl lintexp lintindex lintint lintlength lintwarn \ + noeffect nofmtch shadow uninit2 uninit3 uninit4 uninit5 uninitialized # List of the tests which should be run with --lint-old option: NEED_LINT_OLD = lintold diff --git a/test/Makefile.in b/test/Makefile.in index a6e4f96e..ea577ce3 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1453,89 +1453,84 @@ CLEANFILES = core core.* fmtspcl.ok # try to keep these sorted. each letter starts a new line BASIC_TESTS = \ - addcomma anchgsub anchor argarray arrayind1 arrayind2 arrayind3 arrayparm arrayprm2 arrayprm3 \ - arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 arynasty \ - arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \ + addcomma anchgsub anchor argarray arrayind1 arrayind2 arrayind3 arrayparm \ + arrayprm2 arrayprm3 arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 \ + arynasty arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \ aryprm8 aryprm9 arysubnm aryunasgn asgext awkpath \ back89 backgsub badassign1 badbuild \ - callparam childin clobber closebad clsflnam compare compare2 concat1 concat2 \ - concat3 concat4 concat5 convfmt \ + callparam childin clobber closebad clsflnam compare compare2 \ + concat1 concat2 concat3 concat4 concat5 convfmt \ datanonl defref delargv delarpm2 delarprm delfunc dfamb1 dfastress dynlj \ - eofsplit exit2 exitval1 exitval2 exitval3 \ - fcall_exit fcall_exit2 fldchg fldchgnf fldterm fnamedat fnarray fnarray2 \ - fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fsnul1 fsrs fsspcoln \ - fstabplus funsemnl funsmnam funstack \ + eofsplit exit2 exitval1 exitval2 exitval3 fcall_exit fcall_exit2 \ + fldchg fldchgnf fldterm fnamedat fnarray fnarray2 fnaryscl fnasgnm fnmisc \ + fordel forref forsimp fsbs fsnul1 fsrs fsspcoln fstabplus funsemnl \ + funsmnam funstack \ getline getline2 getline3 getline4 getline5 getlnbuf getnr2tb getnr2tm \ - gsubasgn gsubtest gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 \ - gsubtst7 gsubtst8 \ + gsubasgn gsubtest gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 gsubtst7 \ + gsubtst8 \ hex hex2 hsprint \ inpref inputred intest intprec iobug1 \ leaddig leadnl litoct longsub longwrds \ manglprm math membug1 memleak messages minusstr mmap8k mtchi18n \ nasty nasty2 negexp negrange nested nfldstr nfloop nfneg nfset nlfldsep \ - nlinstr nlstrina noeffect nofile nofmtch noloop1 noloop2 nonl \ - noparms nors nulinsrc nulrsend numindex numsubstr \ + nlinstr nlstrina noeffect nofile nofmtch noloop1 noloop2 nonl noparms \ + nors nulinsrc nulrsend numindex numsubstr \ octsub ofmt ofmta ofmtbig ofmtfidl ofmts ofmtstrnum ofs1 onlynl \ opasnidx opasnslf \ - paramasfunc1 paramasfunc2 \ - paramdup paramres paramtyp paramuninitglobal parse1 parsefld parseme \ - pcntplus posix2008sub prdupval prec printf0 printf1 printfchar prmarscl prmreuse \ - prt1eval prtoeval \ - rand randtest range1 readbuf rebrackloc rebt8b1 rebuild redfilnm \ - regeq regexpbrack regexpbrack2 \ - regexprange regrange reindops \ - reparse resplit rri1 rs rscompat rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 \ - rstest3 rstest4 rstest5 rswhite \ - scalar sclforin sclifin sigpipe1 sortempty sortglos splitargv splitarr splitdef \ - splitvar splitwht status-close strcat1 strnum1 strnum2 strtod subamp subback subi18n \ - subsepnm subslash substr swaplns synerr1 synerr2 tradanch tweakfld \ + paramasfunc1 paramasfunc2 paramdup paramres paramtyp paramuninitglobal \ + parse1 parsefld parseme pcntplus posix2008sub prdupval prec printf0 \ + printf1 printfchar prmarscl prmreuse prt1eval prtoeval \ + rand randtest range1 readbuf rebrackloc rebt8b1 rebuild redfilnm regeq \ + regexpbrack regexpbrack2 regexprange regrange reindops reparse resplit \ + rri1 rs rscompat rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 rstest3 \ + rstest4 rstest5 rswhite \ + scalar sclforin sclifin sigpipe1 sortempty sortglos splitargv splitarr \ + splitdef splitvar splitwht status-close strcat1 strnum1 strnum2 strtod \ + subamp subback subi18n subsepnm subslash substr swaplns synerr1 synerr2 \ + tradanch tweakfld \ uninit2 uninit3 uninit4 uninit5 uninitialized unterm uparrfs \ wideidx wideidx2 widesub widesub2 widesub3 widesub4 wjposer1 \ zero2 zeroe0 zeroflag UNIX_TESTS = \ - fflush getlnhd localenl pid pipeio1 pipeio2 poundbang \ - rtlen rtlen01 space strftlng + fflush getlnhd localenl pid pipeio1 pipeio2 poundbang rtlen rtlen01 \ + space strftlng GAWK_EXT_TESTS = \ aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \ - backw badargs beginfile1 beginfile2 binmode1 charasbytes \ - colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 clos1way6 \ - crlf dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \ - devfd devfd1 devfd2 dumpvars errno exit \ - fieldwdth forcenum fpat1 fpat2 fpat3 fpat4 fpat5 fpat6 fpatnull \ - fsfwfs funlen functab1 functab2 functab3 \ - fwtest fwtest2 fwtest3 fwtest4 fwtest5 fwtest6 fwtest7 fwtest8 \ + backw badargs beginfile1 beginfile2 binmode1 \ + charasbytes colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 \ + clos1way6 crlf \ + dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \ + devfd devfd1 devfd2 dumpvars \ + errno exit \ + fieldwdth forcenum fpat1 fpat2 fpat3 fpat4 fpat5 fpat6 fpatnull fsfwfs \ + funlen functab1 functab2 functab3 fwtest fwtest2 fwtest3 fwtest4 \ + fwtest5 fwtest6 fwtest7 fwtest8 \ genpot gensub gensub2 gensub3 getlndir gnuops2 gnuops3 gnureops gsubind \ - icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase \ - incdupe incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 \ - include include2 indirectbuiltin indirectcall indirectcall2 intarray \ + icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase incdupe \ + incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 include include2 \ + indirectbuiltin indirectcall indirectcall2 intarray \ lint lintexp lintindex lintint lintlength lintold lintset lintwarn \ - mixed1 mktime manyfiles match1 match2 match3 mbstr1 mbstr2 \ - muldimposix \ - nastyparm negtime next nondec nondec2 \ - nonfatal1 nonfatal2 nonfatal3 \ - patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \ - profile0 profile1 profile2 profile3 profile4 profile5 profile6 profile7 \ - profile8 profile9 profile10 pty1 \ - rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \ - rsstart2 rsstart3 rstest6 shadow shadowbuiltin \ - sortfor sortfor2 sortu sourcesplit split_after_fpat \ - splitarg4 strftime strftfld \ - strtonum strtonum1 switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \ - symtab7 symtab8 symtab9 symtab10 \ - typedregex1 typedregex2 typedregex3 \ - typeof1 typeof2 typeof3 typeof4 typeof5 \ - timeout \ + mixed1 mktime manyfiles match1 match2 match3 mbstr1 mbstr2 muldimposix \ + nastyparm negtime next nondec nondec2 nonfatal1 nonfatal2 nonfatal3 \ + patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge \ + procinfs profile0 profile1 profile2 profile3 profile4 profile5 profile6 \ + profile7 profile8 profile9 profile10 pty1 \ + rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin \ + rsstart1 rsstart2 rsstart3 rstest6 \ + shadow shadowbuiltin sortfor sortfor2 sortu sourcesplit split_after_fpat \ + splitarg4 strftime strftfld strtonum strtonum1 switch2 symtab1 symtab2 \ + symtab3 symtab4 symtab5 symtab6 symtab7 symtab8 symtab9 symtab10 \ + typedregex1 typedregex2 typedregex3 typeof1 typeof2 typeof3 typeof4 \ + typeof5 timeout \ watchpoint1 ARRAYDEBUG_TESTS = arrdbg EXTRA_TESTS = inftest regtest ignrcas3 INET_TESTS = inetdayu inetdayt inetechu inetecht MACHINE_TESTS = double1 double2 fmtspcl intformat -MPFR_TESTS = mpfrnr mpfrnegzero mpfrmemok1 mpfrrem mpfrrnd mpfrieee \ - mpfrexprange mpfrsort mpfrsqrt mpfrbigint mpfrstrtonum mpgforcenum - +MPFR_TESTS = mpfrnr mpfrnegzero mpfrmemok1 mpfrrem mpfrrnd mpfrieee LOCALE_CHARSET_TESTS = \ asort asorti backbigs1 backsmalls1 backsmalls2 \ fmttest fnarydel fnparydl jarebug lc_num1 mbfw1 \ @@ -1543,14 +1538,20 @@ LOCALE_CHARSET_TESTS = \ rebt8b2 rtlenmb sort1 sprintfc SHLIB_TESTS = \ - apiterm fnmatch filefuncs fork fork2 fts functab4 getfile inplace1 inplace2 inplace3 \ - ordchr ordchr2 readdir readdir_test readfile readfile2 revout revtwoway rwarray testext time + apiterm \ + filefuncs fnmatch fork fork2 fts functab4 \ + getfile \ + inplace1 inplace2 inplace3 \ + ordchr ordchr2 \ + readdir readdir_test readfile readfile2 revout \ + revtwoway rwarray \ + testext time # List of the tests which should be run with --lint option: NEED_LINT = \ - defref fmtspcl lintexp lintindex lintint lintlength lintwarn noeffect nofmtch shadow \ - uninit2 uninit3 uninit4 uninit5 uninitialized + defref fmtspcl lintexp lintindex lintint lintlength lintwarn \ + noeffect nofmtch shadow uninit2 uninit3 uninit4 uninit5 uninitialized # List of the tests which should be run with --lint-old option: @@ -1776,6 +1777,7 @@ uninstall-am: .PRECIOUS: Makefile + mpfrexprange mpfrsort mpfrsqrt mpfrbigint mpfrstrtonum mpgforcenum # Message stuff is to make it a little easier to follow. # Make the pass-fail last and dependent on others to avoid -- cgit v1.2.3 From 39c0dd124b19b49e002bc5c79edc703df51ffd3b Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 13 Aug 2017 21:59:05 +0300 Subject: Fix gawk_major_version in gawkapi.h; make NEWS correct (no intdiv). --- ChangeLog | 7 +++++++ NEWS | 58 ++++++++++++++++++++++++++++------------------------------ gawkapi.h | 2 +- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index fa603448..997b9f83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2017-08-13 Arnold D. Robbins + + * gawkapi.h (gawk_api_major_version): Reset to 2 after merging + in feature/api-mpfr branch. + * NEWS: `intdiv' is not built-in; remove the entry for up and update + numbering. Add note about API supporting GMP and MPFR values. + 2017-08-09 Arnold D. Robbins * gawkapi.h (check_mpfr_versions): Define differently based on if diff --git a/NEWS b/NEWS index e4963d4e..a999492c 100644 --- a/NEWS +++ b/NEWS @@ -23,74 +23,70 @@ Changes from 4.1.x to 4.2.0 4. The igawk script and igawk.1 man page are no longer installed by `make install'. They have been obsolete since gawk 4.0.0. -5. Gawk now has a `intdiv()' function to perform integer division; this is - primarily useful for the -M option to avoid MPFR division when all - values involved are integers. - -6. Gawk can now be built with CMake. This is an alternative build +5. Gawk can now be built with CMake. This is an alternative build system for those who may want it; gawk is not going to switch off use of the autotools anytime soon, if ever. -7. Gawk now processes a maximum of two hexadecimal digits in \x +6. Gawk now processes a maximum of two hexadecimal digits in \x escape sequences inside strings. -8. Setting PROCINFO["redirection", "NONFATAL"] to true makes I/O +7. Setting PROCINFO["redirection", "NONFATAL"] to true makes I/O errors for "redirection" not fatal, setting ERRNO. Setting PROCINFO["NONFATAL"] makes all I/O nonfatal. -9. MirBSD is no longer supported. +8. MirBSD is no longer supported. -10. Pretty printing now preserves comments and places them into the +9. Pretty printing now preserves comments and places them into the pretty-printed file. -11. `make install' now installs shell startup files +10. `make install' now installs shell startup files $sysconfdir/profile.d/gawk.{csh,sh} containing shell functions to manipulate the AWKPATH and AWKLIBPATH environment variables. On a Fedora system, these files belong in /etc/profile.d, but the appropriate location may be different on other platforms. -12. Gawk now supports retryable I/O via PROCINFO[input-file, "RETRY"]; see +11. Gawk now supports retryable I/O via PROCINFO[input-file, "RETRY"]; see the manual. -13. The API minor version has been increased to 2; the get_file() +12. The API minor version has been increased to 2; the get_file() API provides access to open redirections. Also see the manual. -14. Revisions in the POSIX standard remove the special case for POSIX +13. Revisions in the POSIX standard remove the special case for POSIX mode when FS = " " where newline was not a field separator. The code and doc have been updated. -15. Gawk now supports strongly typed regexp constants. Such constants +14. Gawk now supports strongly typed regexp constants. Such constants look like @/.../. You can assign them to variables, pass them to functions, use them in ~, !~ and the case part of a switch statement. More details are provided in the manual. -16. The new typeof() function can be used to indicate if a variable or +15. The new typeof() function can be used to indicate if a variable or array element is an array, regexp, string or number. The isarray() function is deprecated in favor of typeof(). -17. As promised when 4.1 was released, the old extension mechanism, +16. As promised when 4.1 was released, the old extension mechanism, using the `extension' function, is now gone. -18. Support for GNU/Linux on Alpha systems has been removed. +17. Support for GNU/Linux on Alpha systems has been removed. -19. Optimizations are now enabled by default. Use the new -s/--no-optimize +18. Optimizations are now enabled by default. Use the new -s/--no-optimize option(s) to disable them. Pretty-printing and profiling automatically disable optimizations so that the output program is the same as the original input program. -20. The extension API now provides a mechanism for generating nonfatal +19. The extension API now provides a mechanism for generating nonfatal error messages. -20. Gawk now uses fwrite_unlocked if it's available. The yields a 7% - 18% +21. Gawk now uses fwrite_unlocked if it's available. The yields a 7% - 18% improvement in raw output speed (gawk '{ print }' on a large file). -21. Pretty-printing now uses the original text of constant numeric values for +22. Pretty-printing now uses the original text of constant numeric values for pretty-printing and profiling. -22. Passing negative operands to any of the bitwise functions now +23. Passing negative operands to any of the bitwise functions now produces a fatal error. -23. The C API has undergone changes that break binary compatibility with +24. The C API has undergone changes that break binary compatibility with the previous version. Thus the API version is now at 2.0. YOU WILL NEED TO RECOMPILE YOUR EXTENSIONS to work with this version of gawk. Source code compatibility remains intact, although you will get @@ -98,31 +94,33 @@ Changes from 4.1.x to 4.2.0 recommend that you do so. Fortunately, the changes are fairly minor and straightforward. -24. Programs that toggle IGNORECASE a lot should now be noticeably faster. +25. Programs that toggle IGNORECASE a lot should now be noticeably faster. -25. The mktime function now accepts an optional second argument. If this +26. The mktime function now accepts an optional second argument. If this argument is present and is non-zero or non-null, the time will be converted from UTC instead of from the local timezone. -26. The FIELDWIDTHS parsing syntax has been enhanced to allow specifying +27. The FIELDWIDTHS parsing syntax has been enhanced to allow specifying how many characters to skip before a field starts. It also allows specifying '*' as the last character to mean "the rest of the record". Field splitting with FIELDWIDTHS now sets NF correctly. The documentation for FIELDWIDTHS in the manual has been considerably reorganized and improved as well. -27. An API input parser now has the ability to override the default field +28. An API input parser now has the ability to override the default field parsing mechanism by specifying the locations of each field in the input record. When this is in effect, PROCINFO["FS"] will be set to "API". -28. The PROCINFO["argv"] array records all of gawk's command line arguments +29. The PROCINFO["argv"] array records all of gawk's command line arguments as gawk received them (the values of the C level argv array). -29. Pretty-printing now preserves parenthesized expressions as they +30. Pretty-printing now preserves parenthesized expressions as they were in the source file. This solves several niggling corner cases with such things. -30. The DJGPP port has been revived and now has an official maintainer. +31. The DJGPP port has been revived and now has an official maintainer. + +32. The API has been extended to give access to GMP and MPFR values. Changes from 4.1.3 to 4.1.4 --------------------------- diff --git a/gawkapi.h b/gawkapi.h index 1c6c74ec..66bd85d3 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -296,7 +296,7 @@ typedef struct awk_two_way_processor { awk_const struct awk_two_way_processor *awk_const next; /* for use by gawk */ } awk_two_way_processor_t; -#define gawk_api_major_version 3 +#define gawk_api_major_version 2 #define gawk_api_minor_version 0 /* Current version of the API. */ -- cgit v1.2.3