diff options
-rw-r--r-- | ChangeLog | 77 | ||||
-rw-r--r-- | NEWS | 58 | ||||
-rw-r--r-- | awk.h | 15 | ||||
-rw-r--r-- | awkgram.c | 6 | ||||
-rw-r--r-- | awkgram.y | 6 | ||||
-rw-r--r-- | awklib/eg/lib/intdiv.awk | 7 | ||||
-rw-r--r-- | builtin.c | 2 | ||||
-rw-r--r-- | configh.in | 3 | ||||
-rwxr-xr-x | configure | 38 | ||||
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | doc/ChangeLog | 17 | ||||
-rw-r--r-- | doc/awkcard.in | 8 | ||||
-rw-r--r-- | doc/gawk.1 | 10 | ||||
-rw-r--r-- | doc/gawk.info | 1443 | ||||
-rw-r--r-- | doc/gawk.texi | 186 | ||||
-rw-r--r-- | doc/gawktexi.in | 186 | ||||
-rw-r--r-- | extension/ChangeLog | 46 | ||||
-rw-r--r-- | extension/Makefile.am | 8 | ||||
-rw-r--r-- | extension/Makefile.in | 47 | ||||
-rw-r--r-- | extension/aclocal.m4 | 1 | ||||
-rw-r--r-- | extension/configh.in | 6 | ||||
-rwxr-xr-x | extension/configure | 88 | ||||
-rw-r--r-- | extension/configure.ac | 13 | ||||
-rw-r--r-- | extension/intdiv.c | 202 | ||||
-rw-r--r-- | gawkapi.c | 117 | ||||
-rw-r--r-- | gawkapi.h | 97 | ||||
-rw-r--r-- | mpfr.c | 22 | ||||
-rw-r--r-- | node.c | 14 | ||||
-rw-r--r-- | test/ChangeLog | 9 | ||||
-rw-r--r-- | test/Makefile.am | 119 | ||||
-rw-r--r-- | test/Makefile.in | 122 | ||||
-rw-r--r-- | test/dumpvars.ok | 2 | ||||
-rw-r--r-- | test/id.ok | 1 | ||||
-rw-r--r-- | test/mpfrsqrt.awk | 2 | ||||
-rw-r--r-- | test/symtab6.ok | 2 | ||||
-rw-r--r-- | test/symtab8.ok | 2 |
36 files changed, 2012 insertions, 983 deletions
@@ -1,3 +1,16 @@ +2017-08-13 Arnold D. Robbins <arnold@skeeve.com> + + * 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 <arnold@skeeve.com> + + * 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 <arnold@skeeve.com> * main.c (usage): Add URL for Bug reporting info to the help message. @@ -79,6 +92,10 @@ * gawkapi.h, gawkapi.c: Typo fixes in comments. +2017-06-26 Arnold D. Robbins <arnold@skeeve.com> + + * configure.ac: Turn a tab into a space in AC_DEFINE(SUPPLY_INTDIV). + 2017-06-25 Andrew J. Schorr <aschorr@telemetry-investments.com> * gawkmisc.c (xmalloc): Remove function now in support/xalloc.h. @@ -217,11 +234,27 @@ 2017-04-16 Arnold D. Robbins <arnold@skeeve.com> + 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 <arnold@skeeve.com> + * builtin.c (do_intdiv): Use DEREF on the arguments. Thanks to Andrew Schorr for finding the problem. * mpfr.c (do_mpfr_intdiv): Return -1 if numerator or denominator are not valid numbers. Unref various bits first. +2017-04-13 Arnold D. Robbins <arnold@skeeve.com> + + * awk.h (make_number_node): Simplify. + * mpfr.c (mpg_node): Change parameter name to `flags'. + 2017-04-12 Arnold D. Robbins <arnold@skeeve.com> * mpfr.c (mpg_format_val): Set STRCUR flag when we're done. @@ -230,6 +263,9 @@ * builtin.c (do_dcgettext): Move declaration of reslen to outside the ifdefs. Thanks to Hermann Peifer for the report. + * gawkapi.c (awk_value_to_node): Initialize ext_ret_val to NULL + to avoid compiler warnings. + 2017-04-12 Manuel Collado <m-collado@users.sourceforge.net> Fix the FPAT bug reported by Ed Morton in the gawk-bug mailing list. @@ -708,6 +744,47 @@ not updating the node correctly by setting STRING and STRCUR flags and setting stfmt. +2017-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com> + + 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 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 + 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 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 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. + 2017-01-04 Arnold Robbins <arnold@skeeve.com> * config.guess, config.sub, compile, depcomp: Sync from latest @@ -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 --------------------------- @@ -1066,6 +1066,8 @@ struct block_header { enum block_id { BLOCK_NODE = 0, BLOCK_BUCKET, + BLOCK_MPFR, + BLOCK_MPZ, BLOCK_MAX /* count */ }; @@ -1989,6 +1991,19 @@ erealloc_real(void *ptr, size_t count, const char *where, const char *var, const return ret; } +/* make_number_node --- make node with the given flags */ + +static inline NODE * +make_number_node(unsigned int flags) +{ + NODE *r; + getnode(r); + memset(r, 0, sizeof(*r)); + r->type = Node_val; + r->valref = 1; + r->flags = (flags|MALLOC|NUMBER|NUMCUR); + return r; +} /* * str_terminate_f, str_terminate, str_restore: function and macros to @@ -4577,7 +4577,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}, @@ -6892,6 +6894,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) @@ -6901,6 +6904,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; @@ -2149,7 +2149,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}, @@ -4464,6 +4466,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) @@ -4473,6 +4476,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) @@ -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 */ @@ -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 @@ -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 <bug-gawk@gnu.org>. # @@ -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/' @@ -766,6 +766,7 @@ enable_silent_rules with_whiny_user_strftime enable_lint enable_severe_portability_problems +enable_builtin_intdiv0 enable_mpfr enable_dependency_tracking enable_largefile @@ -1330,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]... @@ -1400,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 @@ -1413,6 +1414,8 @@ Optional Features: --disable-lint do not compile in gawk lint checking --enable-severe-portability-problems allow really nasty portability problems + --enable-builtin-intdiv0 + enable built-in intdiv0 function --disable-mpfr do not check for MPFR --enable-dependency-tracking do not reject slow dependency extractors @@ -1523,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. @@ -2232,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 $@ @@ -3115,7 +3118,7 @@ fi # Define the identity of the package. PACKAGE='gawk' - VERSION='4.1.61' + VERSION='4.1.62' cat >>confdefs.h <<_ACEOF @@ -3245,6 +3248,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 + SKIP_MPFR=no # Check whether --enable-mpfr was given. @@ -11544,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 @@ -11612,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 011532f4..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. @@ -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 +) SKIP_MPFR=no AC_ARG_ENABLE([mpfr], diff --git a/doc/ChangeLog b/doc/ChangeLog index 7bb6f916..86c1d130 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,13 @@ +2017-08-13 Arnold D. Robbins <arnold@skeeve.com> + + * gawktexi.in, gawk.1, awkcard.in: Update versions and + copyright years, prepatory to starting a release spiral. + +2017-08-13 Arnold D. Robbins <arnold@skeeve.com> + + * gawktexi.in: Update API chapter with info about additions + for accessing and/or creating MPZ and MPFR values. + 2017-08-04 Arnold D. Robbins <arnold@skeeve.com> * texinfo.tex: Updated. @@ -69,6 +79,13 @@ 2017-04-16 Arnold D. Robbins <arnold@skeeve.com> + * 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 <arnold@skeeve.com> + * gawktexi.in: Improve documentation of the intdiv() function. 2017-04-12 Arnold D. Robbins <arnold@skeeve.com> diff --git a/doc/awkcard.in b/doc/awkcard.in index 86aeee2e..fac0e931 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. @@ -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. @@ -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 @@ -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. @@ -3953,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 @@ -4052,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 @@ -4099,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 10b146d7..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 @@ -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. @@ -12400,24 +12402,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, @@ -23223,59 +23207,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: - <http://mathworld.wolfram.com/PiFormulas.html>. - - 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 - <http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=899>. +(unless the denominator evenly divides into the numerator). ---------- Footnotes ---------- @@ -23759,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 '<mpfr.h>' header before including '<gawkapi.h>'. + * The 'gawkapi.h' file may be included more than once without ill effect. Doing so, however, is poor coding practice. @@ -23878,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;' @@ -23891,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 @@ -24061,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 '<mpfr.h>' (and '<gmp.h>', which is +included from '<mpfr.h>'). 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 @@ -24105,6 +24086,18 @@ code would use them: 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 is flagged as user input that should be treated as a strnum value @@ -24578,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. @@ -25117,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 @@ -25277,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 @@ -25393,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; } @@ -25652,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, @@ -25694,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 ............................................. @@ -25751,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 + '<mpfr.h>' 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 @@ -25877,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'. @@ -27594,9 +27639,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 @@ -28061,8 +28103,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::. @@ -28446,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 @@ -28468,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 @@ -28709,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, @@ -29039,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 @@ -29650,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 @@ -34475,8 +34515,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. @@ -34626,9 +34664,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) @@ -35092,12 +35130,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) @@ -35275,7 +35313,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) @@ -35379,8 +35417,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) @@ -35430,10 +35468,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) @@ -35759,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-1530971 -Ref: Numeric Functions-Footnote-2531328 -Ref: Numeric Functions-Footnote-3531376 -Node: String Functions531648 -Ref: String Functions-Footnote-1555306 -Ref: String Functions-Footnote-2555434 -Ref: String Functions-Footnote-3555682 -Node: Gory Details555769 -Ref: table-sub-escapes557560 -Ref: table-sub-proposed559079 -Ref: table-posix-sub560442 -Ref: table-gensub-escapes561983 -Ref: Gory Details-Footnote-1562806 -Node: I/O Functions562960 -Ref: table-system-return-values569542 -Ref: I/O Functions-Footnote-1571522 -Ref: I/O Functions-Footnote-2571670 -Node: Time Functions571790 -Ref: Time Functions-Footnote-1582457 -Ref: Time Functions-Footnote-2582525 -Ref: Time Functions-Footnote-3582683 -Ref: Time Functions-Footnote-4582794 -Ref: Time Functions-Footnote-5582906 -Ref: Time Functions-Footnote-6583133 -Node: Bitwise Functions583399 -Ref: table-bitwise-ops583993 -Ref: Bitwise Functions-Footnote-1590026 -Ref: Bitwise Functions-Footnote-2590199 -Node: Type Functions590390 -Node: I18N Functions593307 -Node: User-defined594958 -Node: Definition Syntax595763 -Ref: Definition Syntax-Footnote-1601450 -Node: Function Example601521 -Ref: Function Example-Footnote-1604443 -Node: Function Caveats604465 -Node: Calling A Function604983 -Node: Variable Scope605941 -Node: Pass By Value/Reference608935 -Node: Return Statement612434 -Node: Dynamic Typing615413 -Node: Indirect Calls616343 -Ref: Indirect Calls-Footnote-1626594 -Node: Functions Summary626722 -Node: Library Functions629427 -Ref: Library Functions-Footnote-1633034 -Ref: Library Functions-Footnote-2633177 -Node: Library Names633348 -Ref: Library Names-Footnote-1636808 -Ref: Library Names-Footnote-2637031 -Node: General Functions637117 -Node: Strtonum Function638220 -Node: Assert Function641242 -Node: Round Function644568 -Node: Cliff Random Function646109 -Node: Ordinal Functions647125 -Ref: Ordinal Functions-Footnote-1650188 -Ref: Ordinal Functions-Footnote-2650440 -Node: Join Function650650 -Ref: Join Function-Footnote-1652420 -Node: Getlocaltime Function652620 -Node: Readfile Function656362 -Node: Shell Quoting658334 -Node: Data File Management659735 -Node: Filetrans Function660367 -Node: Rewind Function664463 -Node: File Checking666373 -Ref: File Checking-Footnote-1667707 -Node: Empty Files667908 -Node: Ignoring Assigns669887 -Node: Getopt Function671437 -Ref: Getopt Function-Footnote-1682906 -Node: Passwd Functions683106 -Ref: Passwd Functions-Footnote-1691945 -Node: Group Functions692033 -Ref: Group Functions-Footnote-1699931 -Node: Walking Arrays700138 -Node: Library Functions Summary703146 -Node: Library Exercises704552 -Node: Sample Programs705017 -Node: Running Examples705787 -Node: Clones706515 -Node: Cut Program707739 -Node: Egrep Program717668 -Ref: Egrep Program-Footnote-1725180 -Node: Id Program725290 -Node: Split Program728970 -Ref: Split Program-Footnote-1732429 -Node: Tee Program732558 -Node: Uniq Program735348 -Node: Wc Program742774 -Ref: Wc Program-Footnote-1747029 -Node: Miscellaneous Programs747123 -Node: Dupword Program748336 -Node: Alarm Program750366 -Node: Translate Program755221 -Ref: Translate Program-Footnote-1759786 -Node: Labels Program760056 -Ref: Labels Program-Footnote-1763407 -Node: Word Sorting763491 -Node: History Sorting767563 -Node: Extract Program769398 -Node: Simple Sed776927 -Node: Igawk Program780001 -Ref: Igawk Program-Footnote-1794332 -Ref: Igawk Program-Footnote-2794534 -Ref: Igawk Program-Footnote-3794656 -Node: Anagram Program794771 -Node: Signature Program797833 -Node: Programs Summary799080 -Node: Programs Exercises800294 -Ref: Programs Exercises-Footnote-1804423 -Node: Advanced Features804514 -Node: Nondecimal Data806504 -Node: Array Sorting808095 -Node: Controlling Array Traversal808795 -Ref: Controlling Array Traversal-Footnote-1817162 -Node: Array Sorting Functions817280 -Ref: Array Sorting Functions-Footnote-1822371 -Node: Two-way I/O822567 -Ref: Two-way I/O-Footnote-1829118 -Ref: Two-way I/O-Footnote-2829305 -Node: TCP/IP Networking829387 -Node: Profiling832505 -Ref: Profiling-Footnote-1841177 -Node: Advanced Features Summary841500 -Node: Internationalization843344 -Node: I18N and L10N844824 -Node: Explaining gettext845511 -Ref: Explaining gettext-Footnote-1851403 -Ref: Explaining gettext-Footnote-2851588 -Node: Programmer i18n851753 -Ref: Programmer i18n-Footnote-1856702 -Node: Translator i18n856751 -Node: String Extraction857545 -Ref: String Extraction-Footnote-1858677 -Node: Printf Ordering858763 -Ref: Printf Ordering-Footnote-1861549 -Node: I18N Portability861613 -Ref: I18N Portability-Footnote-1864069 -Node: I18N Example864132 -Ref: I18N Example-Footnote-1866938 -Node: Gawk I18N867011 -Node: I18N Summary867656 -Node: Debugger868997 -Node: Debugging870019 -Node: Debugging Concepts870460 -Node: Debugging Terms872269 -Node: Awk Debugging874844 -Node: Sample Debugging Session875750 -Node: Debugger Invocation876284 -Node: Finding The Bug877670 -Node: List of Debugger Commands884148 -Node: Breakpoint Control885481 -Node: Debugger Execution Control889175 -Node: Viewing And Changing Data892537 -Node: Execution Stack895911 -Node: Debugger Info897548 -Node: Miscellaneous Debugger Commands901619 -Node: Readline Support906707 -Node: Limitations907603 -Node: Debugging Summary909712 -Node: Arbitrary Precision Arithmetic910991 -Node: Computer Arithmetic912476 -Ref: table-numeric-ranges916067 -Ref: Computer Arithmetic-Footnote-1916789 -Node: Math Definitions916846 -Ref: table-ieee-formats920160 -Ref: Math Definitions-Footnote-1920763 -Node: MPFR features920868 -Node: FP Math Caution922585 -Ref: FP Math Caution-Footnote-1923657 -Node: Inexactness of computations924026 -Node: Inexact representation924986 -Node: Comparing FP Values926346 -Node: Errors accumulate927428 -Node: Getting Accuracy928861 -Node: Try To Round931571 -Node: Setting precision932470 -Ref: table-predefined-precision-strings933167 -Node: Setting the rounding mode934997 -Ref: table-gawk-rounding-modes935371 -Ref: Setting the rounding mode-Footnote-1938779 -Node: Arbitrary Precision Integers938958 -Ref: Arbitrary Precision Integers-Footnote-1943863 -Node: Checking for MPFR944012 -Node: POSIX Floating Point Problems945309 -Ref: POSIX Floating Point Problems-Footnote-1949180 -Node: Floating point summary949218 -Node: Dynamic Extensions951408 -Node: Extension Intro952961 -Node: Plugin License954227 -Node: Extension Mechanism Outline955024 -Ref: figure-load-extension955463 -Ref: figure-register-new-function957028 -Ref: figure-call-new-function958120 -Node: Extension API Description960182 -Node: Extension API Functions Introduction961824 -Node: General Data Types967158 -Ref: General Data Types-Footnote-1974363 -Node: Memory Allocation Functions974662 -Ref: Memory Allocation Functions-Footnote-1977814 -Node: Constructor Functions977913 -Node: Registration Functions980912 -Node: Extension Functions981597 -Node: Exit Callback Functions986810 -Node: Extension Version String988060 -Node: Input Parsers988723 -Node: Output Wrappers1001430 -Node: Two-way processors1005942 -Node: Printing Messages1008207 -Ref: Printing Messages-Footnote-11009378 -Node: Updating ERRNO1009531 -Node: Requesting Values1010270 -Ref: table-value-types-returned1011007 -Node: Accessing Parameters1011943 -Node: Symbol Table Access1013178 -Node: Symbol table by name1013690 -Node: Symbol table by cookie1015479 -Ref: Symbol table by cookie-Footnote-11019664 -Node: Cached values1019728 -Ref: Cached values-Footnote-11023264 -Node: Array Manipulation1023355 -Ref: Array Manipulation-Footnote-11024446 -Node: Array Data Types1024483 -Ref: Array Data Types-Footnote-11027141 -Node: Array Functions1027233 -Node: Flattening Arrays1031632 -Node: Creating Arrays1038573 -Node: Redirection API1043342 -Node: Extension API Variables1046184 -Node: Extension Versioning1046817 -Ref: gawk-api-version1047254 -Node: Extension API Informational Variables1048982 -Node: Extension API Boilerplate1050046 -Node: Changes from API V11053908 -Node: Finding Extensions1054568 -Node: Extension Example1055127 -Node: Internal File Description1055925 -Node: Internal File Ops1060005 -Ref: Internal File Ops-Footnote-11071405 -Node: Using Internal File Ops1071545 -Ref: Using Internal File Ops-Footnote-11073928 -Node: Extension Samples1074202 -Node: Extension Sample File Functions1075731 -Node: Extension Sample Fnmatch1083380 -Node: Extension Sample Fork1084867 -Node: Extension Sample Inplace1086085 -Node: Extension Sample Ord1089302 -Node: Extension Sample Readdir1090138 -Ref: table-readdir-file-types1091027 -Node: Extension Sample Revout1091832 -Node: Extension Sample Rev2way1092421 -Node: Extension Sample Read write array1093161 -Node: Extension Sample Readfile1095103 -Node: Extension Sample Time1096198 -Node: Extension Sample API Tests1097546 -Node: gawkextlib1098038 -Node: Extension summary1100485 -Node: Extension Exercises1104187 -Node: Language History1105685 -Node: V7/SVR3.11107341 -Node: SVR41109493 -Node: POSIX1110927 -Node: BTL1112306 -Node: POSIX/GNU1113035 -Node: Feature History1118927 -Node: Common Extensions1133351 -Node: Ranges and Locales1134634 -Ref: Ranges and Locales-Footnote-11139250 -Ref: Ranges and Locales-Footnote-21139277 -Ref: Ranges and Locales-Footnote-31139512 -Node: Contributors1139733 -Node: History summary1145361 -Node: Installation1146741 -Node: Gawk Distribution1147685 -Node: Getting1148169 -Node: Extracting1149130 -Node: Distribution contents1150768 -Node: Unix Installation1157110 -Node: Quick Installation1157792 -Node: Shell Startup Files1160206 -Node: Additional Configuration Options1161295 -Node: Configuration Philosophy1163284 -Node: Non-Unix Installation1165653 -Node: PC Installation1166113 -Node: PC Binary Installation1166951 -Node: PC Compiling1167386 -Node: PC Using1168503 -Node: Cygwin1171548 -Node: MSYS1172318 -Node: VMS Installation1172819 -Node: VMS Compilation1173610 -Ref: VMS Compilation-Footnote-11174839 -Node: VMS Dynamic Extensions1174897 -Node: VMS Installation Details1176582 -Node: VMS Running1178835 -Node: VMS GNV1183114 -Node: VMS Old Gawk1183849 -Node: Bugs1184320 -Node: Bug address1184983 -Node: Usenet1187380 -Node: Maintainers1188157 -Node: Other Versions1189418 -Node: Installation summary1196002 -Node: Notes1197037 -Node: Compatibility Mode1197902 -Node: Additions1198684 -Node: Accessing The Source1199609 -Node: Adding Code1201044 -Node: New Ports1207262 -Node: Derived Files1211750 -Ref: Derived Files-Footnote-11217235 -Ref: Derived Files-Footnote-21217270 -Ref: Derived Files-Footnote-31217868 -Node: Future Extensions1217982 -Node: Implementation Limitations1218640 -Node: Extension Design1219823 -Node: Old Extension Problems1220977 -Ref: Old Extension Problems-Footnote-11222495 -Node: Extension New Mechanism Goals1222552 -Ref: Extension New Mechanism Goals-Footnote-11225916 -Node: Extension Other Design Decisions1226105 -Node: Extension Future Growth1228218 -Node: Old Extension Mechanism1229054 -Node: Notes summary1230817 -Node: Basic Concepts1231999 -Node: Basic High Level1232680 -Ref: figure-general-flow1232962 -Ref: figure-process-flow1233647 -Ref: Basic High Level-Footnote-11236948 -Node: Basic Data Typing1237133 -Node: Glossary1240461 -Node: Copying1272408 -Node: GNU Free Documentation License1309947 -Node: Index1335065 +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 c710ea6a..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 @@ -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. @@ -17566,9 +17568,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} @@ -17586,6 +17589,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} @@ -32023,16 +32027,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 @@ -32043,12 +32049,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) @@ -32135,6 +32144,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 Checking for MPFR @section How To Check If MPFR Is Available @@ -32700,6 +32710,11 @@ 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{<mpfr.h>} header before including @code{<gawkapi.h>}. + +@item The @file{gawkapi.h} file may be included more than once without ill effect. Doing so, however, is poor coding practice. @@ -32837,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; @@ -32850,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 @@ -33037,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{<mpfr.h>} (and @code{<gmp.h>}, +which is included from @code{<mpfr.h>}). 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 @@ -33073,6 +33137,20 @@ 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 flagged as user input that should be treated as a strnum value if the contents @@ -33590,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. @@ -34209,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 @@ -34444,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} @@ -34579,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; @} @@ -34914,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 @@ -34953,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 @@ -35016,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{<mpfr.h>} 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 @@ -35155,6 +35283,10 @@ Check the API versions. If the extension major version does not match @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 continues on. @@ -37275,10 +37407,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 @@ -38074,9 +38208,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 5757c857..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 @@ -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. @@ -16839,9 +16841,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} @@ -16859,6 +16862,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} @@ -31037,16 +31041,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 @@ -31057,12 +31063,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) @@ -31149,6 +31158,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 Checking for MPFR @section How To Check If MPFR Is Available @@ -31714,6 +31724,11 @@ 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{<mpfr.h>} header before including @code{<gawkapi.h>}. + +@item The @file{gawkapi.h} file may be included more than once without ill effect. Doing so, however, is poor coding practice. @@ -31851,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; @@ -31864,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 @@ -32051,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{<mpfr.h>} (and @code{<gmp.h>}, +which is included from @code{<mpfr.h>}). 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 @@ -32087,6 +32151,20 @@ 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 flagged as user input that should be treated as a strnum value if the contents @@ -32604,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. @@ -33223,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 @@ -33458,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} @@ -33593,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; @} @@ -33928,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 @@ -33967,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 @@ -34030,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{<mpfr.h>} 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 @@ -34169,6 +34297,10 @@ Check the API versions. If the extension major version does not match @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 continues on. @@ -36289,10 +36421,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 @@ -37088,9 +37222,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 8e6daab6..c6be068a 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,7 +1,23 @@ +2017-08-11 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * intdiv.c: No need to include <gmp.h> explicitly, since <mpfr.h> + does this for us. + +2017-08-10 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * 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 <arnold@skeeve.com> * Makefile.am: Update copyright year. +2017-06-27 Arnold D. Robbins <arnold@skeeve.com> + + * 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 <aschorr@telemetry-investments.com> * rwarray.c (read_value): Use malloc instead of calloc, since @@ -22,6 +38,26 @@ * gawkfts.c (fts_open): Replace malloc+memset with calloc. * rwarray0.c (read_value): Ditto. +2017-04-16 Arnold D. Robbins <arnold@skeeve.com> + + * intdiv.c (func_table): Function is now named intdiv. + +2017-04-14 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * 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 <aschorr@telemetry-investments.com> + + * 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 <arnold@skeeve.com> + + * 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 <arnold@skeeve.com> * inplace.c (inplace_end): Correct the function name in the @@ -88,6 +124,16 @@ system headers assume that if this is defined, it must have a numeric value. +2017-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * 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 <arnold@skeeve.com> * testext.c (valrep2str): Update for new API types. diff --git a/extension/Makefile.am b/extension/Makefile.am index 92787923..147da40a 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 \ @@ -52,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 \ @@ -72,6 +73,11 @@ 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) $(LIBMPFR) + 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 f6e5abd1..917618cb 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__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) @@ -277,17 +283,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) $(readdir_test_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) \ + $(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) $(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) + $(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) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -422,6 +428,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBMPFR = @LIBMPFR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -520,6 +527,7 @@ pkgextension_LTLIBRARIES = \ fnmatch.la \ fork.la \ inplace.la \ + intdiv.la \ ordchr.la \ readdir.la \ readfile.la \ @@ -533,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 @@ -549,6 +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) $(LIBMPFR) ordchr_la_SOURCES = ordchr.c ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS) ordchr_la_LIBADD = $(MY_LIBS) @@ -713,6 +726,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) @@ -751,6 +767,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)/readdir_test.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 <memory.h> 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..7ae66543 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,8 +12862,89 @@ $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi -for ac_func in fdopendir fnmatch gettimeofday \ - getdtablesize nanosleep select statvfs GetSystemTimeAsFileTime +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 <stdio.h> +#include <mpfr.h> +#include <gmp.h> + +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 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 b5b27d03..bde6e3d3 100644 --- a/extension/configure.ac +++ b/extension/configure.ac @@ -69,8 +69,17 @@ AC_HEADER_DIRENT AC_HEADER_MAJOR AC_HEADER_TIME -AC_CHECK_FUNCS(fdopendir fnmatch gettimeofday \ - getdtablesize nanosleep select statvfs GetSystemTimeAsFileTime) +dnl check for mpfr support +case `uname -m` in +*'Power Macintosh'*) + : ;; +*) + GNUPG_CHECK_MPFR + ;; +esac + +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 new file mode 100644 index 00000000..11045858 --- /dev/null +++ b/extension/intdiv.c @@ -0,0 +1,202 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <math.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "gawkapi.h" + +#ifdef HAVE_MPFR +#include <mpfr.h> +#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"; +static awk_bool_t (*init_func)(void) = NULL; + +int plugin_is_GPL_compatible; + +/* double_to_int --- get the integer part of a double */ + +static double +double_to_int(double d) +{ + if (d >= 0) + d = floor(d); + else + d = ceil(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) +{ + awk_value_t index, tmp; + + set_array_element(array, make_const_string(sub, sublen, & index), make_number(num, & tmp)); +} + +#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) +{ + 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; + } +} + +/* 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) +{ + 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) { + warning(ext_id, _("intdiv: division by zero attempted")); + return make_number(-1, result); + } + + 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[] = { + { "intdiv", do_intdiv, 3, 3, awk_false, NULL }, +}; + +/* define the dl_load function using the boilerplate macro */ + +dl_load_func(func_table, intdiv, "") @@ -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; @@ -145,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) @@ -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: @@ -1219,6 +1282,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 @@ -1346,6 +1439,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 */ @@ -1398,6 +1501,8 @@ gawk_api_t api_impl = { calloc, realloc, free, + api_get_mpfr, + api_get_mpz, /* Find/open a file */ api_get_file, @@ -323,6 +323,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; @@ -358,7 +368,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; @@ -366,7 +376,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 @@ -452,6 +464,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 @@ -749,6 +767,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 @@ -794,7 +826,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! */ @@ -884,6 +915,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)) @@ -980,11 +1014,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; } @@ -1053,6 +1115,8 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ exit(1); \ } \ \ + check_mpfr_version(extension); \ +\ /* load functions */ \ for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { \ if (func_table[i].name == NULL) \ @@ -1077,6 +1141,29 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ return (errors == 0); \ } +#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"); \ + 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); \ + } \ +} while (0) +#else +#define check_mpfr_version(extension) /* nothing */ +#endif + #endif /* GAWK */ #ifdef __cplusplus @@ -103,28 +103,16 @@ 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; - getnode(r); - r->type = Node_val; + 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); - 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; } @@ -1181,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 */ /* @@ -1274,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 @@ -333,16 +333,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 @@ void init_btowc_cache() struct block_header nextfree[BLOCK_MAX] = { { NULL, sizeof(NODE) }, { NULL, sizeof(BUCKET) }, +#ifdef HAVE_MPFR + { NULL, sizeof(mpfr_t) }, + { NULL, sizeof(mpz_t) }, +#endif }; diff --git a/test/ChangeLog b/test/ChangeLog index e85aa681..b515aa08 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,7 @@ +2017-08-13 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am: Sort and prettify the lists of tests. + 2017-08-09 Arnold D. Robbins <arnold@skeeve.com> * badargs.ok: Update after code changes. @@ -62,6 +66,11 @@ * Makefile.am (charset-msg-start): Document that having el_GR.iso88597 is helpful. +2017-04-16 Arnold D. Robbins <arnold@skeeve.com> + + * mpfrsqrt.awk: Add `@load intdiv'. + * dumpvars.ok, id.ok, symtab6.ok, symtab8.ok: Updated. + 2017-04-12 Manuel Collado <m-collado@users.sourceforge.net> * Makefile.am (fpat6): New test. 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 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 @@ -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 |