aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog70
-rw-r--r--awk.h15
-rw-r--r--awkgram.c6
-rw-r--r--awkgram.y6
-rw-r--r--awklib/eg/lib/intdiv.awk7
-rw-r--r--builtin.c2
-rw-r--r--configh.in3
-rwxr-xr-xconfigure18
-rw-r--r--configure.ac11
-rw-r--r--doc/ChangeLog12
-rw-r--r--doc/awkcard.in6
-rw-r--r--doc/gawk.12
-rw-r--r--doc/gawk.info1415
-rw-r--r--doc/gawk.texi180
-rw-r--r--doc/gawktexi.in180
-rw-r--r--extension/ChangeLog46
-rw-r--r--extension/Makefile.am8
-rw-r--r--extension/Makefile.in47
-rw-r--r--extension/aclocal.m41
-rw-r--r--extension/configh.in6
-rwxr-xr-xextension/configure88
-rw-r--r--extension/configure.ac13
-rw-r--r--extension/intdiv.c202
-rw-r--r--gawkapi.c117
-rw-r--r--gawkapi.h99
-rw-r--r--mpfr.c22
-rw-r--r--node.c14
-rw-r--r--test/ChangeLog5
-rw-r--r--test/dumpvars.ok2
-rw-r--r--test/id.ok1
-rw-r--r--test/mpfrsqrt.awk2
-rw-r--r--test/symtab6.ok2
-rw-r--r--test/symtab8.ok2
33 files changed, 1810 insertions, 800 deletions
diff --git a/ChangeLog b/ChangeLog
index d890a281..fa603448 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
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.
Unrelated:
@@ -79,6 +85,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 +227,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 +256,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 +737,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
diff --git a/awk.h b/awk.h
index 74c8ab2f..80e597f1 100644
--- a/awk.h
+++ b/awk.h
@@ -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
diff --git a/awkgram.c b/awkgram.c
index 99387f51..97b59706 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -4552,7 +4552,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},
@@ -6867,6 +6869,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)
@@ -6876,6 +6879,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
ip = arg->lasti;
if (ip->opcode == Op_push)
ip->opcode = Op_push_array;
+#endif /* SUPPLY_INTDIV */
} else if (r->builtin == do_match) {
static bool warned = false;
diff --git a/awkgram.y b/awkgram.y
index 61c00ff2..1a75e641 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -2132,7 +2132,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},
@@ -4447,6 +4449,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)
@@ -4456,6 +4459,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
ip = arg->lasti;
if (ip->opcode == Op_push)
ip->opcode = Op_push_array;
+#endif /* SUPPLY_INTDIV */
} else if (r->builtin == do_match) {
static bool warned = false;
diff --git a/awklib/eg/lib/intdiv.awk b/awklib/eg/lib/intdiv.awk
index dbc553b0..9de5978e 100644
--- a/awklib/eg/lib/intdiv.awk
+++ b/awklib/eg/lib/intdiv.awk
@@ -1,4 +1,4 @@
-# intdiv --- do integer division
+# intdiv0 --- do integer division
#
# Arnold Robbins, arnold@skeeve.com, Public Domain
@@ -6,8 +6,11 @@
#
# Name changed from div() to intdiv()
# April, 2015
+#
+# Changed to intdiv0()
+# April, 2016
-function intdiv(numerator, denominator, result)
+function intdiv0(numerator, denominator, result)
{
split("", result)
diff --git a/builtin.c b/builtin.c
index d354921f..bf838a8a 100644
--- a/builtin.c
+++ b/builtin.c
@@ -3971,6 +3971,7 @@ do_bindtextdomain(int nargs)
return make_string(the_result, strlen(the_result));
}
+#ifdef SUPPLY_INTDIV
/* do_intdiv --- do integer division, return quotient and remainder in dest array */
/*
@@ -4039,6 +4040,7 @@ do_intdiv(int nargs)
return make_number((AWKNUM) 0.0);
}
+#endif /* SUPPLY_INTDIV */
/* do_typeof --- return a string with the type of the arg */
diff --git a/configh.in b/configh.in
index 41f63d4f..4d5ce95e 100644
--- a/configh.in
+++ b/configh.in
@@ -377,6 +377,9 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
+/* enable built-in intdiv0 function */
+#undef SUPPLY_INTDIV
+
/* some systems define this type here */
#undef TIME_T_IN_SYS_TYPES_H
diff --git a/configure b/configure
index c1b5eca4..4b1b3209 100755
--- a/configure
+++ b/configure
@@ -766,6 +766,7 @@ enable_silent_rules
with_whiny_user_strftime
enable_lint
enable_severe_portability_problems
+enable_builtin_intdiv0
enable_mpfr
enable_dependency_tracking
enable_largefile
@@ -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
@@ -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.
diff --git a/configure.ac b/configure.ac
index 011532f4..785f5c5b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -67,6 +67,17 @@ AC_ARG_ENABLE([severe-portability-problems],
AC_DEFINE(I_DONT_KNOW_WHAT_IM_DOING, 1, [enable severe portability problems])
fi
)
+AC_ARG_ENABLE([builtin-intdiv0],
+ [AS_HELP_STRING([--enable-builtin-intdiv0],[enable built-in intdiv0 function])],
+ if test "$enableval" = yes
+ then
+ AC_DEFINE(SUPPLY_INTDIV, 1, [enable built-in intdiv0 function])
+ sed '/^@set PATCHLEVEL/a\
+@set INTDIV' < "$srcdir"/doc/gawktexi.in > foo
+ cp foo "$srcdir"/doc/gawktexi.in
+ rm foo
+ fi
+)
SKIP_MPFR=no
AC_ARG_ENABLE([mpfr],
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 7bb6f916..971d0027 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,8 @@
+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 +74,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..165fca43 100644
--- a/doc/awkcard.in
+++ b/doc/awkcard.in
@@ -1617,9 +1617,9 @@ l lw(1.9i).
\*(FCcos(\*(FIexpr\*(FC)\*(FR The cosine of \*(FIexpr\fP, which is in radians.
\*(FCexp(\*(FIexpr\*(FC)\*(FR The exponential function (\*(FIe \*(FC^ \*(FIx\*(FR).
\*(FCint(\*(FIexpr\*(FC)\*(FR Truncate to integer.
-\*(CB\*(FCintdiv(\*(FIn\*(FR\*(FC,\*(FI d\*(FR\*(FC,\*(FI r\*(FR\*(FC)\*(FR T{
-Return result of integer division in \*(FIr\*(FR.\*(CD
-T}
+.\" \*(CB\*(FCintdiv(\*(FIn\*(FR\*(FC,\*(FI d\*(FR\*(FC,\*(FI r\*(FR\*(FC)\*(FR T{
+.\" Return result of integer division in \*(FIr\*(FR.\*(CD
+.\" T}
\*(FClog(\*(FIexpr\*(FC)\*(FR The natural logarithm function (base \*(FIe\^\*(FR).
\*(FCrand()\fP A random number \*(FIN\fP such that 0 \(<= \*(FIN\fP < 1.
\*(FCsin(\*(FIexpr\*(FC)\*(FR The sine of \*(FIexpr\fP, which is in radians.
diff --git a/doc/gawk.1 b/doc/gawk.1
index b04cb013..1b42cc90 100644
--- a/doc/gawk.1
+++ b/doc/gawk.1
@@ -2711,6 +2711,7 @@ The exponential function.
.TP
.BI int( expr )
Truncate to integer.
+.ig
.TP
.BI intdiv( num ", " denom ", " result )
Truncate
@@ -2728,6 +2729,7 @@ This is a
.I gawk
extension, primarily of value when working with
arbitrarily large integers.
+..
.TP
.BI log( expr )
The natural logarithm function.
diff --git a/doc/gawk.info b/doc/gawk.info
index 10b146d7..4faa99c6 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -573,6 +573,8 @@ in (a) below. A copy of the license is included in the section entitled
redirections.
* Extension API Variables:: Variables provided by the API.
* Extension Versioning:: API Version information.
+* Extension GMP/MPFR Versioning:: Version information about GMP and
+ MPFR.
* Extension API Informational Variables:: Variables providing information about
'gawk''s invocation.
* Extension API Boilerplate:: Boilerplate code for using the API.
@@ -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::.
@@ -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..e44abad5 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -945,6 +945,8 @@ particular records in a file and perform operations upon them.
redirections.
* Extension API Variables:: Variables provided by the API.
* Extension Versioning:: API Version information.
+* Extension GMP/MPFR Versioning:: Version information about GMP and
+ MPFR.
* Extension API Informational Variables:: Variables providing information about
@command{gawk}'s invocation.
* Extension API Boilerplate:: Boilerplate code for using the API.
@@ -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..8ad4c72e 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -940,6 +940,8 @@ particular records in a file and perform operations upon them.
redirections.
* Extension API Variables:: Variables provided by the API.
* Extension Versioning:: API Version information.
+* Extension GMP/MPFR Versioning:: Version information about GMP and
+ MPFR.
* Extension API Informational Variables:: Variables providing information about
@command{gawk}'s invocation.
* Extension API Boilerplate:: Boilerplate code for using the API.
@@ -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, "")
diff --git a/gawkapi.c b/gawkapi.c
index 56a782fe..0abcb885 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -25,6 +25,14 @@
#include "awk.h"
+#ifdef HAVE_MPFR
+#define getmpfr(n) getblock(n, BLOCK_MPFR, mpfr_ptr)
+#define freempfr(n) freeblock(n, BLOCK_MPFR)
+
+#define getmpz(n) getblock(n, BLOCK_MPZ, mpz_ptr)
+#define freempz(n) freeblock(n, BLOCK_MPZ)
+#endif
+
/* Declare some globals used by api_get_file: */
extern IOBUF *curfile;
extern INSTRUCTION *main_beginfile;
@@ -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,
diff --git a/gawkapi.h b/gawkapi.h
index b8e8a26d..1c6c74ec 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -296,7 +296,7 @@ typedef struct awk_two_way_processor {
awk_const struct awk_two_way_processor *awk_const next; /* for use by gawk */
} awk_two_way_processor_t;
-#define gawk_api_major_version 2
+#define gawk_api_major_version 3
#define gawk_api_minor_version 0
/* Current version of the API. */
@@ -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
diff --git a/mpfr.c b/mpfr.c
index f0a410f9..5ac6077b 100644
--- a/mpfr.c
+++ b/mpfr.c
@@ -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
diff --git a/node.c b/node.c
index 7287e8fa..f64bd9eb 100644
--- a/node.c
+++ b/node.c
@@ -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..ee361790 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -62,6 +62,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/dumpvars.ok b/test/dumpvars.ok
index 7caecd35..85d1c859 100644
--- a/test/dumpvars.ok
+++ b/test/dumpvars.ok
@@ -9,7 +9,7 @@ FILENAME: "-"
FNR: 3
FPAT: "[^[:space:]]+"
FS: " "
-FUNCTAB: array, 42 elements
+FUNCTAB: array, 41 elements
IGNORECASE: 0
LINT: 0
NF: 1
diff --git a/test/id.ok b/test/id.ok
index 7454a4fc..79130657 100644
--- a/test/id.ok
+++ b/test/id.ok
@@ -47,7 +47,6 @@ gsub -> builtin
i -> untyped
index -> builtin
int -> builtin
-intdiv -> builtin
isarray -> builtin
length -> builtin
log -> builtin
diff --git a/test/mpfrsqrt.awk b/test/mpfrsqrt.awk
index 3fb1f5f8..8cc416bb 100644
--- a/test/mpfrsqrt.awk
+++ b/test/mpfrsqrt.awk
@@ -9,6 +9,8 @@
#
# Running this program (sqrt-bug.awk):
# --------------------------------------------------------------------
+
+@load "intdiv"
BEGIN {
a=11111111111111111111111111111111111111111111111111111111111
print sqrt(a^2)
diff --git a/test/symtab6.ok b/test/symtab6.ok
index 34c10636..7de717a0 100644
--- a/test/symtab6.ok
+++ b/test/symtab6.ok
@@ -9,7 +9,7 @@ FILENAME: ""
FNR: 0
FPAT: "[^[:space:]]+"
FS: " "
-FUNCTAB: array, 42 elements
+FUNCTAB: array, 41 elements
IGNORECASE: 0
LINT: 0
NF: 0
diff --git a/test/symtab8.ok b/test/symtab8.ok
index 0cf40fe9..da29b585 100644
--- a/test/symtab8.ok
+++ b/test/symtab8.ok
@@ -9,7 +9,7 @@ FIELDWIDTHS: ""
FNR: 1
FPAT: "[^[:space:]]+"
FS: " "
-FUNCTAB: array, 42 elements
+FUNCTAB: array, 41 elements
IGNORECASE: 0
LINT: 0
NF: 1