[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gawk] Small fixes to gawktexi.in
From: |
Andrew J. Schorr |
Subject: |
Re: [bug-gawk] Small fixes to gawktexi.in |
Date: |
Sat, 12 Nov 2016 14:48:46 -0500 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
Hi,
I defer to Arnold for documentation changes, but I did notice that
you eliminated the hyphen in compound adjectives in several places.
For example, you changed "arbitrary-precision arithmetic" to
"arbitrary precision arithmetic". I don't think you are correct about
that.
http://www.grammarbook.com/punctuation/hyphens.asp
Rule 1. Generally, hyphenate two or more words when they come before a noun
they modify and act as a single idea. This is called a compound adjective.
Examples:
an off-campus apartment
state-of-the-art design
If you're right, then you should also edit Wikipedia.
https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic
Regards,
Andy
On Sun, Nov 13, 2016 at 06:26:38AM +1000, Sergey Tselikh wrote:
> I finished working through the gawk manual, and while reading it I made
> several small changes to gawktexi.in. No harm was done to text of a manual.
>
> Patch (see below) includes the following entry to doc/ChangeLog,
> which explains the changes:
>
> * gawktexi.in: Several small changes to gawktexi.in,
> mainly related to fixing typos, small text polishing
> and adding @group/@end group in @example and @example-like
> constructs to clean PDF version (formatted for Letter paper,
> which is the default) of orphaned single lines of source code
> or example output in higher and lower parts of pages (such
> lines were with just a "}", or with a single line of code or
> a comment).
>
> The following patch is for
> commit dea1c3c59c07731803669ecdc1fbf318b2d88380
> Merge: 8444d69 4c6da6a
> Author: Arnold D. Robbins <address@hidden>
> Date: Tue Nov 8 23:11:41 2016 +0200
> Merge branch 'gawk-4.1-stable'
>
> Patch changes the doc/ChangeLog and doc/gawktexi.in:
>
>
>
> diff --git a/doc/ChangeLog b/doc/ChangeLog
> index 2628687..e3ba624 100644
> --- a/doc/ChangeLog
> +++ b/doc/ChangeLog
> @@ -1,3 +1,14 @@
> +2016-11-13 Sergey Tselikh <address@hidden>
> +
> + * gawktexi.in: Several small changes to gawktexi.in,
> + mainly related to fixing typos, small text polishing
> + and adding @group/@end group in @example and @example-like
> + constructs to clean PDF version (formatted for Letter paper,
> + which is the default) of orphaned single lines of source code
> + or example output in higher and lower parts of pages (such
> + lines were with just a "}", or with a single line of code or
> + a comment).
> +
> 2016-11-08 Arnold D. Robbins <address@hidden>
>
> * gawktexi.in, wordlist: Typo fix. ECBDIC --> EBCDIC.
> diff --git a/doc/gawktexi.in b/doc/gawktexi.in
> index a2f6b3b..320c4b5 100644
> --- a/doc/gawktexi.in
> +++ b/doc/gawktexi.in
> @@ -1472,9 +1472,11 @@ default @command{awk} utility. A more modern
> @command{awk} lives in
> if you try the test program:
>
> @example
> address@hidden
> $ @kbd{awk 1 /dev/null}
> @error{} awk: syntax error near line 1
> @error{} awk: bailing out near line 1
> address@hidden group
> @end example
>
> @noindent
> @@ -2871,10 +2873,12 @@ for the
> single- and double-quote characters, like so:
>
> @example
> address@hidden
> $ @kbd{awk 'BEGIN @{ print "Here is a single quote <\47>" @}'}
> @print{} Here is a single quote <'>
> $ @kbd{awk 'BEGIN @{ print "Here is a double quote <\42>" @}'}
> @print{} Here is a double quote <">
> address@hidden group
> @end example
>
> @noindent
> @@ -3101,8 +3105,10 @@ action---so it uses the default action, printing the
> record.
> Print the length of the longest input line:
>
> @example
> address@hidden
> awk '@{ if (length($0) > max) max = length($0) @}
> END @{ print max @}' data
> address@hidden group
> @end example
>
> The code associated with @code{END} executes after all
> @@ -3419,11 +3425,13 @@ starts a comment, it ignores @emph{everything} on the
> rest of the
> line. For example:
>
> @example
> address@hidden
> $ @kbd{gawk 'BEGIN @{ print "dont panic" # a friendly \}
> > @kbd{ BEGIN rule}
> > @address@hidden'}
> @error{} gawk: cmd. line:2: BEGIN rule
> @error{} gawk: cmd. line:2: ^ syntax error
> address@hidden group
> @end example
>
> @noindent
> @@ -3928,7 +3936,7 @@ care to search for all occurrences of each
> inappropriate construct. As
> @itemx @option{--bignum}
> @cindex @option{-M} option
> @cindex @option{--bignum} option
> -Select arbitrary-precision arithmetic on numbers. This option has no effect
> +Select arbitrary precision arithmetic on numbers. This option has no effect
> if @command{gawk} is not compiled to use the GNU MPFR and MP libraries
> (@pxref{Arbitrary Precision Arithmetic}).
>
> @@ -4601,10 +4609,12 @@ The files to be included may be nested; e.g., given a
> third
> script, namely @file{test3}:
>
> @example
> address@hidden
> @@include "test2"
> BEGIN @{
> print "This is script test3."
> @}
> address@hidden group
> @end example
>
> @noindent
> @@ -4692,8 +4702,10 @@ $ @kbd{gawk '@@load "ordchr"; BEGIN @{print chr(65)@}'}
> This is equivalent to the following example:
>
> @example
> address@hidden
> $ @kbd{gawk -lordchr 'BEGIN @{print chr(65)@}'}
> @print{} A
> address@hidden group
> @end example
>
> @noindent
> @@ -6226,8 +6238,10 @@ with each @samp{u} changed to a newline. Here are the
> results of running
> the program on @file{mail-list}:
>
> @example
> address@hidden
> $ @kbd{awk 'BEGIN @{ RS = "u" @}}
> > @address@hidden print $0 @}' mail-list}
> address@hidden group
> @print{} Amelia 555-5553 amelia.zodiac
> @print{} sq
> @print{} e@@gmail.com F
> @@ -6384,9 +6398,11 @@ matches either a newline or a series of one or more
> uppercase letters
> with optional leading and/or trailing whitespace:
>
> @example
> address@hidden
> $ @kbd{echo record 1 AAAA record 2 BBBB record 3 |}
> > @kbd{gawk 'BEGIN @{ RS = "\n|( *[[:upper:]]+ *)" @}}
> > @address@hidden print "Record =", $0,"and RT = [" RT "]" @}'}
> address@hidden group
> @print{} Record = record 1 and RT = [ AAAA ]
> @print{} Record = record 2 and RT = [ BBBB ]
> @print{} Record = record 3 and RT = [
> @@ -6770,8 +6786,10 @@ values of the fields and @code{OFS}. To do this, use
> the
> seemingly innocuous assignment:
>
> @example
> address@hidden
> $1 = $1 # force record to be reconstituted
> print $0 # or whatever else with $0
> address@hidden group
> @end example
>
> @noindent
> @@ -7467,16 +7485,20 @@ Putting this to use, here is a simple program to
> parse the data:
>
> @example
> @c file eg/misc/simple-csv.awk
> address@hidden
> BEGIN @{
> FPAT = "([^,]+)|(\"[^\"]+\")"
> @}
> address@hidden group
>
> address@hidden
> @{
> print "NF = ", NF
> for (i = 1; i <= NF; i++) @{
> printf("$%d = <%s>\n", i, $i)
> @}
> @}
> address@hidden group
> @c endfile
> @end example
>
> @@ -7886,6 +7908,7 @@ read-a-line-and-check-each-rule loop of @command{awk}
> never sees it.
> The following example swaps every two lines of input:
>
> @example
> address@hidden
> @{
> if ((getline tmp) > 0) @{
> print tmp
> @@ -7893,6 +7916,7 @@ The following example swaps every two lines of input:
> @} else
> print $0
> @}
> address@hidden group
> @end example
>
> @noindent
> @@ -8035,6 +8059,7 @@ lines that begin with @samp{@@execute}, which are
> replaced by the output
> produced by running the rest of the line as a shell command:
>
> @example
> address@hidden
> @{
> if ($1 == "@@execute") @{
> tmp = substr($0, 10) # Remove "@@execute"
> @@ -8044,6 +8069,7 @@ produced by running the rest of the line as a shell
> command:
> @} else
> print
> @}
> address@hidden group
> @end example
>
> @noindent
> @@ -8347,12 +8373,14 @@ For example, a TCP client can decide to give up on
> receiving
> any response from the server after a certain amount of time:
>
> @example
> address@hidden
> Service = "/inet/tcp/0/localhost/daytime"
> PROCINFO[Service, "READ_TIMEOUT"] = 100
> if ((Service |& getline) > 0)
> print $0
> else if (ERRNO != "")
> print ERRNO
> address@hidden group
> @end example
>
> Here is how to read interactively from the address@hidden assumes
> @@ -8694,10 +8722,12 @@ newlines:
> @end ifnotinfo
>
> @example
> address@hidden
> $ @kbd{awk 'BEGIN @{ print "line one\nline two\nline three" @}'}
> @print{} line one
> @print{} line two
> @print{} line three
> address@hidden group
> @end example
>
> @cindex fields, printing
> @@ -8949,12 +8979,14 @@ The output separator variables @code{OFS} and
> @code{ORS} have no effect
> on @code{printf} statements. For example:
>
> @example
> address@hidden
> $ @kbd{awk 'BEGIN @{}
> > @kbd{ORS = "\nOUCH!\n"; OFS = "+"}
> > @kbd{msg = "Don\47t Panic!"}
> > @kbd{printf "%s\n", msg}
> > @address@hidden'}
> @print{} Don't Panic!
> address@hidden group
> @end example
>
> @noindent
> @@ -9476,9 +9508,11 @@ alone for now and let's hope no-one notices.
> @end ignore
>
> @example
> address@hidden
> awk '@{ print $1 > "names.unsorted"
> command = "sort -r > names.sorted"
> print $1 | command @}' mail-list
> address@hidden group
> @end example
>
> The unsorted list is written with an ordinary redirection, while
> @@ -9772,7 +9806,7 @@ The @var{protocol} is one of @samp{tcp} or @samp{udp},
> and the other fields represent the other essential pieces of information
> for making a networking connection.
> These @value{FN}s are used with the @samp{|&} operator for communicating
> -with a coprocess
> +with @w{a coprocess}
> (@pxref{Two-way I/O}).
> This is an advanced feature, mentioned here only for completeness.
> Full discussion is delayed until
> @@ -9871,10 +9905,14 @@ it is good practice to use a variable to store the
> @value{FN} or command.
> The previous example becomes the following:
>
> @example
> address@hidden
> sortcom = "sort -r names"
> sortcom | getline foo
> address@hidden group
> address@hidden
> @dots{}
> close(sortcom)
> address@hidden group
> @end example
>
> @noindent
> @@ -9926,7 +9964,6 @@ you close commands when done. For example, consider
> something like this:
>
> @example
> @{
> - @dots{}
> command = ("grep " $1 " /some/file | my_prog -q " $3)
> while ((command | getline) > 0) @{
> @var{process output of} command
> @@ -10017,7 +10054,7 @@ if it fails.
>
> @float Table,table-close-pipe-return-values
> @caption{Return values from @code{close()} of a pipe}
> address@hidden @columnfractions .40 .60
> address@hidden @columnfractions .50 .50
> @headitem Situation @tab Return value from @code{close()}
> @item Normal exit of command @tab Command's exit status
> @item Death by signal of command @tab 256 + number of murderous signal
> @@ -10046,7 +10083,8 @@ disk) is a fatal error.
>
> @example
> $ @kbd{gawk 'BEGIN @{ print "hi" > "/no/such/file" @}'}
> address@hidden gawk: cmd. line:1: fatal: can't redirect to `/no/such/file'
> (No such file or directory)
> address@hidden gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No
> address@hidden such file or directory)
> @end example
>
> @command{gawk} makes it possible to detect that an error has
> @@ -10237,7 +10275,7 @@ have different forms, but are internally stored in an
> identical manner.
> A @dfn{numeric constant} stands for a number. This number can be an
> integer, a decimal fraction, or a number in scientific (exponential)
> address@hidden internal representation of all numbers,
> -including integers, uses double-precision floating-point numbers.
> +including integers, uses double precision floating-point numbers.
> On most modern systems, these are in IEEE 754 standard format.
> @xref{Arbitrary Precision Arithmetic}, for much more information.}
> Here are some examples of numeric constants that all
> @@ -10463,6 +10501,7 @@ confusion can arise when attempting to use regexp
> constants as arguments
> to user-defined functions (@pxref{User-defined}). For example:
>
> @example
> address@hidden
> function mysub(pat, repl, str, global)
> @{
> if (global)
> @@ -10471,13 +10510,16 @@ function mysub(pat, repl, str, global)
> sub(pat, repl, str)
> return str
> @}
> address@hidden group
>
> address@hidden
> @{
> @dots{}
> text = "hi! hi yourself!"
> mysub(/hi/, "howdy", text, 1)
> @dots{}
> @}
> address@hidden group
> @end example
>
> @c @cindex automatic warnings
> @@ -10641,8 +10683,10 @@ is performed. If numeric values appear in string
> concatenation, they
> are converted to strings. Consider the following:
>
> @example
> address@hidden
> two = 2; three = 3
> print (two three) + 4
> address@hidden group
> @end example
>
> @noindent
> @@ -11115,10 +11159,14 @@ to it. In the following program fragment, the
> variable
> @code{foo} has a numeric value at first, and a string value later on:
>
> @example
> address@hidden
> foo = 1
> print foo
> address@hidden group
> address@hidden
> foo = "bar"
> print foo
> address@hidden group
> @end example
>
> @noindent
> @@ -11190,16 +11238,20 @@ righthand expression. For example:
>
> @cindex Rankin, Pat
> @example
> address@hidden
> # Thanks to Pat Rankin for this example
> BEGIN @{
> foo[rand()] += 5
> for (x in foo)
> print x, foo[x]
> address@hidden group
>
> address@hidden
> bar[rand()] = bar[rand()] + 5
> for (x in bar)
> print x, bar[x]
> @}
> address@hidden group
> @end example
>
> @cindex operators, assignment, evaluation order
> @@ -11784,10 +11836,12 @@ leave off one of the @samp{=} characters. The
> result is still valid
> @command{awk} code, but the program does not do what is intended:
>
> @example
> address@hidden
> if (a = b) # oops! should be a == b
> @dots{}
> else
> @dots{}
> address@hidden group
> @end example
>
> @noindent
> @@ -12734,8 +12788,10 @@ $ @kbd{awk '! /li/' mail-list}
> @print{} Bill 555-1675 bill.drowning@@hotmail.com A
> @print{} Camilla 555-2912 camilla.infusarum@@skynet.be R
> @print{} Fabius 555-1234 fabius.undevicesimus@@ucb.edu F
> address@hidden
> @print{} Martin 555-6480 martin.codicibus@@hotmail.com A
> @print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R
> address@hidden group
> @end example
>
> @cindex @code{BEGIN} pattern, Boolean patterns and
> @@ -13125,10 +13181,12 @@ the variable's value into the program inside the
> script.
> For example, consider the following program:
>
> @example
> address@hidden
> printf "Enter search pattern: "
> read pattern
> awk "/$pattern/ "'@{ nmatches++ @}
> END @{ print nmatches, "found" @}' /path/to/data
> address@hidden group
> @end example
>
> @noindent
> @@ -13317,10 +13375,12 @@ the null string; otherwise, the condition is true.
> Refer to the following:
>
> @example
> address@hidden
> if (x % 2 == 0)
> print "x is even"
> else
> print "x is odd"
> address@hidden group
> @end example
>
> In this example, if the expression @samp{x % 2 == 0} is true (i.e.,
> @@ -13642,6 +13702,7 @@ finds the smallest divisor of any integer, and also
> identifies prime
> numbers:
>
> @example
> address@hidden
> # find smallest divisor of num
> @{
> num = $1
> @@ -13649,11 +13710,14 @@ numbers:
> if (num % divisor == 0)
> break
> @}
> address@hidden group
> address@hidden
> if (num % divisor == 0)
> printf "Smallest divisor of %d is %d\n", num, divisor
> else
> printf "%d is prime\n", num
> @}
> address@hidden group
> @end example
>
> When the remainder is zero in the first @code{if} statement, @command{awk}
> @@ -13961,14 +14025,18 @@ using an @code{exit} statement with a nonzero
> argument, as shown
> in the following example:
>
> @example
> address@hidden
> BEGIN @{
> if (("date" | getline date_now) <= 0) @{
> print "Can't get system date" > "/dev/stderr"
> exit 1
> @}
> address@hidden group
> address@hidden
> print "current date is", date_now
> close("date")
> @}
> address@hidden group
> @end example
>
> @quotation NOTE
> @@ -14183,12 +14251,12 @@ character. (@xref{Output Separators}.)
>
> @cindex @code{PREC} variable
> @item PREC #
> -The working precision of arbitrary-precision floating-point numbers,
> +The working precision of arbitrary precision floating-point numbers,
> 53 bits by default (@pxref{Setting precision}).
>
> @cindex @code{ROUNDMODE} variable
> @item ROUNDMODE #
> -The rounding mode to use for arbitrary-precision arithmetic on
> +The rounding mode to use for arbitrary precision arithmetic on
> numbers, by default @code{"N"} (@code{roundTiesToEven} in
> the IEEE 754 standard; @pxref{Setting the rounding mode}).
>
> @@ -14263,6 +14331,7 @@ Unlike most @command{awk} arrays,
> In the following example:
>
> @example
> address@hidden
> $ @kbd{awk 'BEGIN @{}
> > @kbd{for (i = 0; i < ARGC; i++)}
> > @kbd{print ARGV[i]}
> @@ -14270,6 +14339,7 @@ $ @kbd{awk 'BEGIN @{}
> @print{} awk
> @print{} inventory-shipped
> @print{} mail-list
> address@hidden group
> @end example
>
> @noindent
> @@ -14522,7 +14592,7 @@ The version of @command{gawk}.
>
> The following additional elements in the array
> are available to provide information about the MPFR and GMP libraries
> -if your version of @command{gawk} supports arbitrary-precision arithmetic
> +if your version of @command{gawk} supports arbitrary precision arithmetic
> (@pxref{Arbitrary Precision Arithmetic}):
>
> @table @code
> @@ -14660,12 +14730,14 @@ points out that it effectively gives @command{awk}
> data pointers. Consider his
> example:
>
> @example
> address@hidden
> # Indirect multiply of any variable by amount, return result
>
> function multiply(variable, amount)
> @{
> return SYMTAB[variable] *= amount
> @}
> address@hidden group
> @end example
>
> @noindent
> @@ -14737,6 +14809,7 @@ presented the following program describing the
> information contained in @code{AR
> and @code{ARGV}:
>
> @example
> address@hidden
> $ @kbd{awk 'BEGIN @{}
> > @kbd{for (i = 0; i < ARGC; i++)}
> > @kbd{print ARGV[i]}
> @@ -14744,6 +14817,7 @@ $ @kbd{awk 'BEGIN @{}
> @print{} awk
> @print{} inventory-shipped
> @print{} mail-list
> address@hidden group
> @end example
>
> @noindent
> @@ -15340,8 +15414,10 @@ For example, this statement tests whether the array
> @code{frequencies}
> contains the index @samp{2}:
>
> @example
> address@hidden
> if (2 in frequencies)
> print "Subscript 2 is present."
> address@hidden group
> @end example
>
> Note that this is @emph{not} a test of whether the array
> @@ -15351,8 +15427,10 @@ There is no way to do that except to scan all the
> elements. Also, this
> (incorrect) alternative does:
>
> @example
> address@hidden
> if (frequencies[2] != "")
> print "Subscript 2 is present."
> address@hidden group
> @end example
>
> @node Assigning Elements
> @@ -15409,6 +15487,7 @@ all the lines.
> When this program is run with the following input:
>
> @example
> address@hidden
> @c file eg/misc/arraymax.data
> 5 I am the Five man
> 2 Who are you? The new number two!
> @@ -15416,17 +15495,20 @@ When this program is run with the following input:
> 1 Who is number one?
> 3 I three you.
> @c endfile
> address@hidden group
> @end example
>
> @noindent
> Its output is:
>
> @example
> address@hidden
> 1 Who is number one?
> 2 Who are you? The new number two!
> 3 I three you.
> 4 . . . And four on the floor
> 5 I am the Five man
> address@hidden group
> @end example
>
> If a line number is repeated, the last line with a given number overrides
> @@ -15435,11 +15517,13 @@ Gaps in the line numbers can be handled with an
> easy improvement to the
> program's @code{END} rule, as follows:
>
> @example
> address@hidden
> END @{
> for (x = 1; x <= max; x++)
> if (x in arr)
> print arr[x]
> @}
> address@hidden group
> @end example
>
> @node Scanning an Array
> @@ -15459,8 +15543,10 @@ So @command{awk} has a special kind of @code{for}
> statement for scanning
> an array:
>
> @example
> address@hidden
> for (@var{var} in @var{array})
> @var{body}
> address@hidden group
> @end example
>
> @noindent
> @@ -15481,12 +15567,15 @@ such words.
> for more information on the built-in function @code{length()}.
>
> @example
> address@hidden
> # Record a 1 for each word that is used at least once
> @{
> for (i = 1; i <= NF; i++)
> used[$i] = 1
> @}
> address@hidden group
>
> address@hidden
> # Find number of distinct words more than 10 characters long
> END @{
> for (x in used) @{
> @@ -15497,6 +15586,7 @@ END @{
> @}
> print num_long_words, "words longer than 10 characters"
> @}
> address@hidden group
> @end example
>
> @noindent
> @@ -15884,9 +15974,11 @@ same as assigning it a null value (the empty string,
> @code{""}).
> For example:
>
> @example
> address@hidden
> foo[4] = ""
> if (4 in foo)
> print "This is printed, even though foo[4] is empty"
> address@hidden group
> @end example
>
> @cindex lint checking, array elements
> @@ -16041,22 +16133,26 @@ END @{
> When given the input:
>
> @example
> address@hidden
> 1 2 3 4 5 6
> 2 3 4 5 6 1
> 3 4 5 6 1 2
> 4 5 6 1 2 3
> address@hidden group
> @end example
>
> @noindent
> the program produces the following output:
>
> @example
> address@hidden
> 4 3 2 1
> 5 4 3 2
> 6 5 4 3
> 1 6 5 4
> 2 1 6 5
> 3 2 1 6
> address@hidden group
> @end example
>
> @node Multiscanning
> @@ -16236,15 +16332,19 @@ you can often devise workarounds using control
> statements. For example,
> the following code prints the elements of our main array @code{a}:
>
> @example
> address@hidden
> for (i in a) @{
> for (j in a[i]) @{
> if (j == 3) @{
> for (k in a[i][j])
> print a[i][j][k]
> address@hidden group
> address@hidden
> @} else
> print a[i][j]
> @}
> @}
> address@hidden group
> @end example
>
> @noindent
> @@ -16688,9 +16788,11 @@ asort(a)
> results in the following contents of @code{a}:
>
> @example
> address@hidden
> a[1] = "cul"
> a[2] = "de"
> a[3] = "sac"
> address@hidden group
> @end example
>
> The @code{asorti()} function works similarly to @code{asort()}; however,
> @@ -17744,6 +17846,8 @@ a file or pipe that was opened for reading (such as
> with @code{getline}),
> or if @var{filename} is not an open file, pipe, or coprocess.
> In such a case, @code{fflush()} returns @minus{}1, as well.
>
> address@hidden table
> +
> @sidebar Interactive Versus Noninteractive Buffering
> @cindex buffering, interactive vs.@: noninteractive
>
> @@ -17787,6 +17891,7 @@ Here, no output is printed until after the
> @kbd{Ctrl-d} is typed, because
> it is all buffered and sent down the pipe to @command{cat} in one shot.
> @end sidebar
>
> address@hidden @asis
> @item @code{system(@var{command})}
> @cindexawkfunc{system}
> @cindex invoke shell command
> @@ -18506,7 +18611,7 @@ that illustrates the use of these functions:
> @example
> @group
> @c file eg/lib/bits2str.awk
> -# bits2str --- turn a byte into readable ones and zeros
> +# bits2str --- turn an integer into readable ones and zeros
>
> function bits2str(bits, data, mask)
> @{
> @@ -18528,7 +18633,7 @@ function bits2str(bits, data, mask)
> @c this is a hack to make testbits.awk self-contained
> @ignore
> @c file eg/prog/testbits.awk
> -# bits2str --- turn a byte into readable 1's and 0's
> +# bits2str --- turn an integer into readable ones and zeros
>
> function bits2str(bits, data, mask)
> @{
> @@ -18552,7 +18657,7 @@ BEGIN @{
> printf "0123 = %s\n", bits2str(0123)
> printf "0x99 = %s\n", bits2str(0x99)
> comp = compl(0x99)
> - printf "compl(0x99) = %#x = %s\n", comp, bits2str(comp)
> + printf "compl(0x99) = %#x =\n%s\n", comp, bits2str(comp)
> shift = lshift(0x99, 2)
> printf "lshift(0x99, 2) = %#x = %s\n", shift, bits2str(shift)
> shift = rshift(0x99, 2)
> @@ -18569,7 +18674,8 @@ $ @kbd{gawk -f testbits.awk}
> @print{} 123 = 01111011
> @print{} 0123 = 01010011
> @print{} 0x99 = 10011001
> address@hidden compl(0x99) = 0x3fffffffffff66 =
> 00111111111111111111111111111111111111111111111101100110
> address@hidden compl(0x99) = 0x3fffffffffff66 =
> address@hidden 00111111111111111111111111111111111111111111111101100110
> @print{} lshift(0x99, 2) = 0x264 = 0000001001100100
> @print{} rshift(0x99, 2) = 0x26 = 00100110
> @end example
> @@ -18612,7 +18718,7 @@ as unsigned integers. For this reason, negative
> arguments produce a
> fatal error.
>
> In normal operation, for all of these functions, first the
> -double-precision floating-point value is converted to the widest C
> +double precision floating-point value is converted to the widest C
> unsigned integer type, then the bitwise operation is performed. If the
> result cannot be represented exactly as a C @code{double}, leading
> nonzero bits are removed one by one until it can be represented exactly.
> @@ -18645,7 +18751,7 @@ $ @kbd{gawk -M 'BEGIN @{ printf "%#x\n", compl(42)
> @}'}
> When using the @option{-M} option, under the hood, @command{gawk} uses
> GNU MP arbitrary precision integers which have at least 64 bits of precision.
> When not using @option{-M}, @command{gawk} stores integral values in
> -regular double-precision floating point, which only maintain 53 bits of
> +regular double precision floating point, which only maintain 53 bits of
> precision. Furthermore, the GNU MP library treats (or least seems to treat)
> the leading bit as a sign bit; thus the result with @option{-M} in this case
> is
> a negative number.
> @@ -18832,10 +18938,12 @@ entire program before starting to execute any of it.
> The definition of a function named @var{name} looks like this:
>
> @display
> address@hidden
> @code{function} @address@hidden(address@hidden@code{)}
> @address@hidden
> @var{body-of-function}
> @address@hidden
> address@hidden group
> @end display
>
> @cindex names, functions
> @@ -19003,11 +19111,13 @@ This function deletes all the elements in an array
> (recall that the
> extra whitespace signifies the start of the local variable list):
>
> @example
> address@hidden
> function delarray(a, i)
> @{
> for (i in a)
> delete a[i]
> @}
> address@hidden group
> @end example
>
> When working with arrays, it is often necessary to delete all the elements
> @@ -19214,10 +19324,12 @@ In addition, recursive calls create new arrays.
> Consider this example:
>
> @example
> address@hidden
> function some_func(p1, a)
> @{
> if (p1++ > 3)
> return
> address@hidden group
>
> a[p1] = p1
>
> @@ -19281,12 +19393,14 @@ this has no effect on any other variables. Thus,
> if @code{myfunc()}
> does this:
>
> @example
> address@hidden
> function myfunc(str)
> @{
> print str
> str = "zzz"
> print str
> @}
> address@hidden group
> @end example
>
> @noindent
> @@ -19442,11 +19556,13 @@ function maxelt(vec, i, ret)
> return ret
> @}
>
> address@hidden
> # Load all fields of each record into nums.
> @{
> for(i = 1; i <= NF; i++)
> nums[NR, i] = $i
> @}
> address@hidden group
>
> END @{
> print maxelt(nums)
> @@ -19740,12 +19856,14 @@ first thing to do is write some comparison
> functions:
>
> @example
> @c file eg/prog/indirectcall.awk
> address@hidden
> # num_lt --- do a numeric less than comparison
>
> function num_lt(left, right)
> @{
> return ((left + 0) < (right + 0))
> @}
> address@hidden group
>
> # num_ge --- do a numeric greater than or equal to comparison
>
> @@ -19794,19 +19912,23 @@ names of the two comparison functions:
>
> @example
> @c file eg/prog/indirectcall.awk
> address@hidden
> # sort --- sort the data in ascending order and return it as a string
>
> function sort(first, last)
> @{
> return do_sort(first, last, "num_lt")
> @}
> address@hidden group
>
> address@hidden
> # rsort --- sort the data in descending order and return it as a string
>
> function rsort(first, last)
> @{
> return do_sort(first, last, "num_ge")
> @}
> address@hidden group
> @c endfile
> @end example
>
> @@ -20306,6 +20428,7 @@ been true but was not, and then it kills the program.
> In C, using
> @code{assert()} looks this:
>
> @example
> address@hidden
> #include <assert.h>
>
> int myfunc(int a, double b)
> @@ -20313,6 +20436,7 @@ int myfunc(int a, double b)
> assert(a <= 5 && b >= 17.1);
> @dots{}
> @}
> address@hidden group
> @end example
>
> If the assertion fails, the program prints a message similar to this:
> @@ -20470,9 +20594,10 @@ function round(x, ival, aval, fraction)
> @}
> @c endfile
> @c don't include test harness in the file that gets installed
> -
> address@hidden
> # test harness
> # @{ print $0, round($0) @}
> address@hidden group
> @end example
>
> @node Cliff Random Function
> @@ -20878,7 +21003,7 @@ if (length(contents) == 0)
> @end example
>
> This tests the result to see if it is empty or not. An equivalent
> -test would be @samp{contents == ""}.
> +test would be @address@hidden == ""}}.
>
> @xref{Extension Sample Readfile} for an extension function that
> also reads an entire file into memory.
> @@ -21179,8 +21304,10 @@ $ @kbd{gawk -f rewind.awk -f test.awk data }
> @print{} data 1 a
> @print{} data 2 b
> @print{} data 3 c
> address@hidden
> @print{} data 4 d
> @print{} data 5 e
> address@hidden group
> @end example
>
> @node File Checking
> @@ -22395,8 +22522,10 @@ function getgrent()
> _gr_init()
> if (++_gr_count in _gr_bycount)
> return _gr_bycount[_gr_count]
> address@hidden
> return ""
> @}
> address@hidden group
> @c endfile
> @end example
>
> @@ -22926,10 +23055,12 @@ list of fields or characters:
> if (by_fields == 0 && by_chars == 0)
> by_fields = 1 # default
>
> address@hidden
> if (fieldlist == "") @{
> print "cut: needs list for -c or -f" > "/dev/stderr"
> exit 1
> @}
> address@hidden group
>
> if (by_fields)
> set_fieldlist()
> @@ -23270,8 +23401,10 @@ function endfile(file)
> print fcount
> @}
>
> address@hidden
> total += fcount
> @}
> address@hidden group
> @c endfile
> @end example
>
> @@ -23428,11 +23561,15 @@ BEGIN @{
> pw = getpwuid(uid)
> pr_first_field(pw)
>
> address@hidden
> if (euid != uid) @{
> printf(" euid=%d", euid)
> pw = getpwuid(euid)
> address@hidden group
> address@hidden
> pr_first_field(pw)
> @}
> address@hidden group
>
> printf(" gid=%d", gid)
> pw = getgrgid(gid)
> @@ -23560,14 +23697,17 @@ BEGIN @{
> # test argv in case reading from stdin instead of file
> if (i in ARGV)
> i++ # skip datafile name
> address@hidden
> if (i in ARGV) @{
> outfile = ARGV[i]
> ARGV[i] = ""
> @}
> -
> address@hidden group
> address@hidden
> s1 = s2 = "a"
> out = (outfile s1 s2)
> @}
> address@hidden group
> @c endfile
> @end example
>
> @@ -23723,11 +23863,15 @@ line into each file on the command line, and then
> to the standard output:
> It is also possible to write the loop this way:
>
> @example
> address@hidden
> for (i in copy)
> if (append)
> print >> copy[i]
> address@hidden group
> address@hidden
> else
> print > copy[i]
> address@hidden group
> @end example
>
> @noindent
> @@ -23878,10 +24022,12 @@ BEGIN @{
> usage()
> @}
>
> address@hidden
> if (ARGV[Optind] ~ /^\+[[:digit:]]+$/) @{
> charcount = substr(ARGV[Optind], 2) + 0
> Optind++
> @}
> address@hidden group
>
> for (i = 1; i < Optind; i++)
> ARGV[i] = ""
> @@ -23915,10 +24061,12 @@ strings are then compared and @code{are_equal()}
> returns the result:
>
> @example
> @c file eg/prog/uniq.awk
> address@hidden
> function are_equal( n, m, clast, cline, alast, aline)
> @{
> if (fcount == 0 && charcount == 0)
> return (last == $0)
> address@hidden group
>
> if (fcount > 0) @{
> n = split(last, alast)
> @@ -23933,10 +24081,13 @@ function are_equal( n, m, clast, cline, alast,
> aline)
> clast = substr(clast, charcount + 1)
> cline = substr(cline, charcount + 1)
> @}
> address@hidden
>
> return (clast == cline)
> @}
> address@hidden group
> @c endfile
> +
> @end example
>
> The following two rules are the body of the program. The first one is
> @@ -23994,11 +24145,13 @@ NR == 1 @{
> END @{
> if (do_count)
> printf("%4d %s\n", count, last) > outputfile
> address@hidden
> else if ((repeated_only && count > 1) ||
> (non_repeated_only && count == 1))
> print last > outputfile
> close(outputfile)
> @}
> address@hidden group
> @c endfile
> @end example
>
> @@ -24793,10 +24946,12 @@ At first glance, a program like this would seem to
> do the job:
> freq[$i]++
> @}
>
> address@hidden
> END @{
> for (word in freq)
> printf "%s\t%d\n", word, freq[word]
> @}
> address@hidden group
> @end example
>
> The program relies on @command{awk}'s default field-splitting
> @@ -25186,9 +25341,11 @@ line. That line is then printed to the output file:
> i++
> @}
> @}
> address@hidden
> print join(a, 1, n, SUBSEP) > curfile
> @}
> @}
> address@hidden group
> @c endfile
> @end example
>
> @@ -25274,10 +25431,12 @@ function usage()
> exit 1
> @}
>
> address@hidden
> BEGIN @{
> # validate arguments
> if (ARGC < 3)
> usage()
> address@hidden group
>
> RS = ARGV[1]
> ORS = ARGV[2]
> @@ -25671,13 +25830,11 @@ the program is done:
> continue
> @}
> fpath = pathto($2)
> address@hidden
> if (fpath == "") @{
> printf("igawk: %s:%d: cannot find %s\n",
> input[stackptr], FNR, $2) > "/dev/stderr"
> continue
> @}
> address@hidden group
> if (! (fpath in processed)) @{
> processed[fpath] = input[stackptr]
> input[++stackptr] = fpath # push onto stack
> @@ -25898,7 +26055,6 @@ Here is some partial output when the program is run:
>
> @example
> $ @kbd{gawk -f anagram.awk /usr/share/dict/words | grep '^b'}
> address@hidden
> babbled blabbed
> babbler blabber brabble
> babblers blabbers brabbles
> @@ -25934,10 +26090,12 @@ notice and this notice are preserved.
> Here is the program:
>
> @example
> address@hidden
> awk
> 'address@hidden"~"~"~";o="=="=="==";o+=+o;x=O""O;while(X++<=x+o+o)c=c"%c";
> printf c,(x-O)*(x-O),x*(x-o)-o,x*(x-O)+x-O-o,+x*(x-O)-x+o,X*(o*o+O)+x-O,
> X*(X-x)-o*o,(x+X)*o*o+o,x*(X-x)-O-O,x-O+(O+o+X+x)*(o+O),X*X-X*(x-O)-x+O,
>
> O+X*(o*(o+O)+O),+x+O+X*o,x*(x-o),(o+X+x)*o*o-(x-O-O),O+(X-x)*(X+O),address@hidden'
> address@hidden group
> @end example
>
> @cindex Johansen, Chris
> @@ -26140,7 +26298,6 @@ BEGIN @{
> repl = ARGV[2]
> ARGV[1] = ARGV[2] = ""
> @}
> -
> @{ gsub(pat, repl); print @}
> @end example
>
> @@ -26277,7 +26434,7 @@ debugger for debugging @command{awk} programs.
>
> @item
> @ref{Arbitrary Precision Arithmetic}, describes how you can use
> address@hidden to perform arbitrary-precision arithmetic.
> address@hidden to perform arbitrary precision arithmetic.
>
> @item
> @ref{Dynamic Extensions},
> @@ -26425,11 +26582,13 @@ Our first comparison function can be used to scan
> an array in
> numerical order of the indices:
>
> @example
> address@hidden
> function cmp_num_idx(i1, v1, i2, v2)
> @{
> # numerical index comparison, ascending order
> return (i1 - i2)
> @}
> address@hidden group
> @end example
>
> Our second function traverses an array based on the string order of
> @@ -26534,10 +26693,13 @@ function cmp_field(i1, v1, i2, v2)
> a[NR][i] = $i
> @}
>
> address@hidden
> END @{
> PROCINFO["sorted_in"] = "cmp_field"
> address@hidden group
> if (POS < 1 || POS > NF)
> POS = 1
> +
> for (i in a) @{
> for (j = 1; j <= NF; j++)
> printf("%s%c", a[i][j], j < NF ? ":" : "")
> @@ -26594,6 +26756,7 @@ function cmp_numeric(i1, v1, i2, v2)
> return (v1 != v2) ? (v2 - v1) : (i2 - i1)
> @}
>
> address@hidden
> function cmp_string(i1, v1, i2, v2)
> @{
> # string value (and index) comparison, descending order
> @@ -26601,6 +26764,7 @@ function cmp_string(i1, v1, i2, v2)
> v2 = v2 i2
> return (v1 > v2) ? -1 : (v1 != v2)
> @}
> address@hidden group
> @end example
>
> @c Avoid using the term ``stable'' when describing the unpredictable behavior
> @@ -26754,11 +26918,13 @@ The following example demonstrates the use of a
> comparison function with
> both values to lowercase in order to compare them ignoring case.
>
> @example
> address@hidden
> # case_fold_compare --- compare as strings, ignoring case
>
> function case_fold_compare(i1, v1, i2, v2, l, r)
> @{
> l = tolower(v1)
> address@hidden group
> r = tolower(v2)
>
> if (l < r)
> @@ -27937,10 +28103,14 @@ This example would be better done with
> @code{dcngettext()}:
> @example
> if (groggy)
> message = dcngettext("%d customer disturbing me\n",
> - "%d customers disturbing me\n", "adminprog")
> + "%d customers disturbing me\n",
> + ncustomers,
> + "adminprog")
> else
> message = dcngettext("enjoying %d customer\n",
> - "enjoying %d customers\n", "adminprog")
> + "enjoying %d customers\n",
> + ncustomers,
> + "adminprog")
> printf(message, ncustomers)
> @end example
>
> @@ -28109,8 +28279,10 @@ This is somewhat counterintuitive.
> and those with positional specifiers in the same string:
>
> @example
> address@hidden
> $ @kbd{gawk 'BEGIN @{ printf "%d %3$s\n", 1, 2, "hi" @}'}
> @error{} gawk: cmd. line:1: fatal: must use `count$' on all formats or none
> address@hidden group
> @end example
>
> @quotation NOTE
> @@ -28735,8 +28907,10 @@ be inside this function. To investigate further, we
> must begin
> @samp{n} (for ``next''):
>
> @example
> address@hidden
> gawk> @kbd{n}
> @print{} 66 if (fcount > 0) @{
> address@hidden group
> @end example
>
> This tells us that @command{gawk} is now ready to execute line 66, which
> @@ -29505,10 +29679,12 @@ partial dump of Davide Brini's obfuscated code
>
> @c FIXME: This will need updating if num-handler branch is ever merged in.
> @smallexample
> address@hidden
> gawk> @kbd{dump}
> @print{} # BEGIN
> @print{}
> @print{} [ 1:0xfcd340] Op_rule : [in_rule = BEGIN] [source_file =
> brini.awk]
> address@hidden group
> @print{} [ 1:0xfcc240] Op_push_i : "~" [MALLOC|STRING|STRCUR]
> @print{} [ 1:0xfcc2a0] Op_push_i : "~" [MALLOC|STRING|STRCUR]
> @print{} [ 1:0xfcc280] Op_match :
> @@ -29541,18 +29717,18 @@ gawk> @kbd{dump}
> @print{} [ :0xfcc660] Op_no_op :
> @print{} [ 1:0xfcc520] Op_assign_concat : c
> @print{} [ :0xfcc620] Op_jmp : [target_jmp = 0xfcc440]
> address@hidden
> @dots{}
> address@hidden
> @print{} [ 2:0xfcc5a0] Op_K_printf : [expr_count = 17]
> [redir_type = ""]
> @print{} [ :0xfcc140] Op_no_op :
> @print{} [ :0xfcc1c0] Op_atexit :
> @print{} [ :0xfcc640] Op_stop :
> @print{} [ :0xfcc180] Op_no_op :
> @print{} [ :0xfcd150] Op_after_beginfile :
> address@hidden
> @print{} [ :0xfcc160] Op_no_op :
> @print{} [ :0xfcc1a0] Op_after_endfile :
> gawk>
> address@hidden group
> @end smallexample
>
> @cindex @code{exit} debugger command
> @@ -29821,7 +29997,7 @@ program being debugged, but occasionally it can.
> @end itemize
>
> @node Arbitrary Precision Arithmetic
> address@hidden Arithmetic and Arbitrary-Precision Arithmetic with
> @command{gawk}
> address@hidden Arithmetic and Arbitrary Precision Arithmetic with
> @command{gawk}
> @cindex arbitrary precision
> @cindex multiple precision
> @cindex infinite precision
> @@ -29831,9 +30007,9 @@ This @value{CHAPTER} introduces some basic concepts
> relating to
> how computers do arithmetic and defines some important terms.
> It then proceeds to describe floating-point arithmetic,
> which is what @command{awk} uses for all its computations, including a
> -discussion of arbitrary-precision floating-point arithmetic, which is
> +discussion of arbitrary precision floating-point arithmetic, which is
> a feature available only in @command{gawk}. It continues on to present
> -arbitrary-precision integers, and concludes with a description of some
> +arbitrary precision integers, and concludes with a description of some
> points where @command{gawk} and the POSIX standard are not quite in
> agreement.
>
> @@ -29903,6 +30079,7 @@ In computer systems, integer arithmetic is exact, but
> the possible
> range of values is limited. Integer arithmetic is generally faster than
> floating-point arithmetic.
>
> address@hidden floating-point, numbers
> @item Floating-point arithmetic
> Floating-point numbers represent what were called in school ``real''
> numbers (i.e., those that have a fractional part, such as 3.1415927).
> @@ -29912,40 +30089,61 @@ there are numbers that they cannot represent
> exactly.
>
> Modern systems support floating-point arithmetic in hardware, with a
> limited range of values. There are software libraries that allow
> -the use of arbitrary-precision floating-point calculations.
> +the use of arbitrary precision floating-point calculations.
>
> -POSIX @command{awk} uses @dfn{double-precision} floating-point numbers, which
> -can hold more digits than @dfn{single-precision} floating-point numbers.
> address@hidden has facilities for performing arbitrary-precision
> address@hidden floating-point, address@hidden single precision
> address@hidden floating-point, address@hidden double precision
> address@hidden floating-point, address@hidden arbitrary precision
> address@hidden single precision
> address@hidden double precision
> address@hidden arbitrary precision
> +POSIX @command{awk} uses @dfn{double precision} floating-point numbers, which
> +can hold more digits than @dfn{single precision} floating-point numbers.
> address@hidden has facilities for performing arbitrary precision
> floating-point arithmetic, which we describe in more detail shortly.
> @end table
>
> Computers work with integer and floating-point values of different
> ranges. Integer values are usually either 32 or 64 bits in size.
> -Single-precision floating-point values occupy 32 bits, whereas
> double-precision
> +Single precision floating-point values occupy 32 bits, whereas double
> precision
> floating-point values occupy 64 bits. Floating-point values are always
> -signed. The possible ranges of values are shown in
> @ref{table-numeric-ranges}.
> +signed. The possible ranges of values are shown in @ref{table-numeric-ranges}
> +and @ref{table-floating-point-ranges}.
>
> @float Table,table-numeric-ranges
> address@hidden ranges for different numeric representations}
> address@hidden ranges for integer representations}
> @multitable @columnfractions .34 .33 .33
> address@hidden Numeric representation @tab Minimum value @tab Maximum value
> address@hidden Representation @tab Minimum value @tab Maximum value
> @item 32-bit signed integer @tab @minus{}2,147,483,648 @tab 2,147,483,647
> @item 32-bit unsigned integer @tab 0 @tab 4,294,967,295
> @item 64-bit signed integer @tab @minus{}9,223,372,036,854,775,808 @tab
> 9,223,372,036,854,775,807
> @item 64-bit unsigned integer @tab 0 @tab 18,446,744,073,709,551,615
> address@hidden multitable
> address@hidden float
> +
> address@hidden Table,table-floating-point-ranges
> address@hidden value ranges for floating-point number representations}
> address@hidden @columnfractions .38 .22 .22 .23
> @iftex
> address@hidden Single-precision floating point (approximate) @tab
> @math{1.175494^{-38}} @tab @math{3.402823^{38}}
> address@hidden Double-precision floating point (approximate) @tab
> @math{2.225074^{-308}} @tab @math{1.797693^{308}}
> address@hidden Representation @tab @w{Minimum positive} @w{nonzero value}
> @tab Minimum @w{finite value} @tab Maximum @w{finite value}
> address@hidden iftex
> address@hidden
> address@hidden Representation @tab Minimum positive nonzero value @tab
> Minimum finite value @tab Maximum finite value
> address@hidden ifnottex
> address@hidden @w{Single precision floating-point} @tab @math{1.175494 @cdot
> 10^{-38}} @tab @math{-3.402823 @cdot 10^{38}} @tab @math{3.402823 @cdot
> 10^{38}}
> address@hidden @w{Double precision floating-point} @tab @math{2.225074 @cdot
> 10^{-308}} @tab @math{-1.797693 @cdot 10^{308}} @tab @math{1.797693 @cdot
> 10^{308}}
> address@hidden @w{Quadruple precision floating-point} @tab @math{3.362103
> @cdot 10^{-4932}} @tab @math{-1.189731 @cdot 10^{4932}} @tab @math{1.189731
> @cdot 10^{4932}}
> @end iftex
> @ifinfo
> address@hidden Single-precision floating point (approximate) @tab
> 1.175494e-38 @tab 3.402823e38
> address@hidden Double-precision floating point (approximate) @tab
> 2.225074e-308 @tab 1.797693e308
> address@hidden Single precision floating-point @tab 1.175494e-38 @tab
> -3.402823e+38 @tab 3.402823e+38
> address@hidden Double precision floating-point @tab 2.225074e-308 @tab
> -1.797693e+308 @tab 1.797693e+308
> address@hidden Quadruple precision floating-point @tab 3.362103e-4932 @tab
> -1.189731e+4932 @tab 1.189731e+4932
> @end ifinfo
> @ifnottex
> @ifnotinfo
> address@hidden Single-precision floating point (approximate) @tab
> address@hidden @tab address@hidden
> address@hidden Double-precision floating point (approximate) @tab
> address@hidden @tab address@hidden
> address@hidden Single precision floating-point @tab address@hidden @tab
> address@hidden @tab address@hidden
> address@hidden Double precision floating-point @tab address@hidden @tab
> address@hidden @tab address@hidden
> address@hidden Quadruple precision floating-point @tab address@hidden @tab
> address@hidden @tab address@hidden
> @end ifnotinfo
> @end ifnottex
> @end multitable
> @@ -30050,7 +30248,7 @@ Three of the standard IEEE 754 types are 32-bit
> single precision,
> 64-bit double precision, and 128-bit quadruple precision.
> The standard also specifies extended precision formats
> to allow greater precisions and larger exponent ranges.
> -(@command{awk} uses only the 64-bit double-precision format.)
> +(@command{awk} uses only the 64-bit double precision format.)
>
> @ref{table-ieee-formats} lists the precision and exponent
> field values for the basic IEEE 754 binary formats.
> @@ -30071,14 +30269,14 @@ one extra bit of significand.
> @end quotation
>
> @node MPFR features
> address@hidden Arbitrary-Precision Arithmetic Features in @command{gawk}
> address@hidden Arbitrary Precision Arithmetic Features in @command{gawk}
>
> -By default, @command{gawk} uses the double-precision floating-point values
> +By default, @command{gawk} uses the double precision floating-point values
> supplied by the hardware of the system it runs on. However, if it was
> compiled to do so, and the @option{-M} command-line option is supplied,
> @command{gawk} uses the @uref{http://www.mpfr.org,
> GNU MPFR} and @uref{http://gmplib.org, GNU MP} (GMP) libraries for
> -arbitrary-precision arithmetic on numbers. You can see if MPFR support
> +arbitrary precision arithmetic on numbers. You can see if MPFR support
> is available like so:
>
> @example
> @@ -30126,7 +30324,7 @@ Computer Scientist Should Know About Floating-Point
> Arithmetic,''
> @cite{ACM Computing Surveys} @strong{23}, 1 (1991-03): 5-48. This is
> worth reading if you are interested in the details, but it does require
> a background in computer science.}
> -The discussion applies to both hardware and arbitrary-precision
> +The discussion applies to both hardware and arbitrary precision
> floating-point arithmetic.
>
> @quotation CAUTION
> @@ -30151,7 +30349,7 @@ Simple values like 0.1 cannot be precisely
> represented using
> binary floating-point numbers, and the limited precision of
> floating-point numbers means that slight changes in
> the order of operations or the precision of intermediate storage
> -can change the result. To make matters worse, with arbitrary-precision
> +can change the result. To make matters worse, with arbitrary precision
> floating-point arithmetic, you can set the precision before starting a
> computation, but then you cannot be sure of the number of significant
> decimal places in the final result.
> @@ -30214,12 +30412,14 @@ You have to decide how small a delta is important
> to you. Code to do
> this looks something like the following:
>
> @example
> address@hidden
> delta = 0.00001 # for example
> difference = abs(a) - abs(b) # subtract the two values
> if (difference < delta)
> # all ok
> else
> # not ok
> address@hidden group
> @end example
>
> @noindent
> @@ -30279,7 +30479,7 @@ $ @kbd{gawk 'BEGIN @{}
> @node Getting Accuracy
> @subsection Getting the Accuracy You Need
>
> -Can arbitrary-precision arithmetic give exact results? There are
> +Can arbitrary precision arithmetic give exact results? There are
> no easy answers. The standard rules of algebra often do not apply
> when using floating-point arithmetic.
> Among other things, the distributive and associative laws
> @@ -30288,7 +30488,7 @@ for your computation. Rounding error, cumulative
> precision loss,
> and underflow are often troublesome.
>
> When @command{gawk} tests the expressions @samp{0.1 + 12.2} and
> address@hidden for equality using the machine double-precision arithmetic,
> address@hidden for equality using the machine double precision arithmetic,
> it decides that they are not equal! (@xref{Comparing FP Values}.)
> You can get the result you want by increasing the precision; 56 bits in
> this case does the job:
> @@ -30317,7 +30517,7 @@ a straight test for equality may not work. Instead,
> compare the
> two numbers to see if they are within the desirable delta of each other.
>
> In applications where 15 or fewer decimal places suffice,
> -hardware double-precision arithmetic can be adequate, and is usually much
> faster.
> +hardware double precision arithmetic can be adequate, and is usually much
> faster.
> But you need to keep in mind that every floating-point operation
> can suffer a new rounding error with catastrophic consequences, as
> illustrated
> by our earlier attempt to compute the value of @value{PI}.
> @@ -30346,7 +30546,7 @@ the problem at hand is often the correct approach in
> such situations.
> @node Try To Round
> @subsection Try a Few Extra Bits of Precision and Rounding
>
> -Instead of arbitrary-precision floating-point arithmetic,
> +Instead of arbitrary precision floating-point arithmetic,
> often all you need is an adjustment of your logic
> or a different order for the operations in your calculation.
> The stability and the accuracy of the computation of @value{PI}
> @@ -30389,7 +30589,7 @@ to emulate an IEEE 754 binary format.
> @caption{Predefined precision strings for @code{PREC}}
> @multitable address@hidden"double"}} {12345678901234567890123456789012345}
> @headitem @code{PREC} @tab IEEE 754 binary format
> address@hidden @code{"half"} @tab 16-bit half-precision
> address@hidden @code{"half"} @tab 16-bit half precision
> @item @code{"single"} @tab Basic 32-bit single precision
> @item @code{"double"} @tab Basic 64-bit double precision
> @item @code{"quad"} @tab Basic 128-bit quadruple precision
> @@ -30528,14 +30728,14 @@ accumulation of round-off error, look for a
> significant difference in
> output when you change the rounding mode to be sure.
>
> @node Arbitrary Precision Integers
> address@hidden Arbitrary-Precision Integer Arithmetic with @command{gawk}
> address@hidden Arbitrary Precision Integer Arithmetic with @command{gawk}
> @cindex integers, arbitrary precision
> @cindex arbitrary precision integers
>
> When given the @option{-M} option,
> address@hidden performs all integer arithmetic using GMP arbitrary-precision
> address@hidden performs all integer arithmetic using GMP arbitrary precision
> integers. Any number that looks like an integer in a source
> -or @value{DF} is stored as an arbitrary-precision integer. The size
> +or @value{DF} is stored as an arbitrary precision integer. The size
> of the integer is limited only by the available memory. For example,
> the following computes
> @iftex
> @@ -30550,7 +30750,7 @@ the following computes
> @end ifnotinfo
> @end ifnottex
> the result of which is beyond the
> -limits of ordinary hardware double-precision floating-point values:
> +limits of ordinary hardware double precision floating-point values:
>
> @example
> $ @kbd{gawk -M 'BEGIN @{}
> @@ -30562,7 +30762,7 @@ $ @kbd{gawk -M 'BEGIN @{}
> @print{} 62060698786608744707 ... 92256259918212890625
> @end example
>
> -If instead you were to compute the same value using arbitrary-precision
> +If instead you were to compute the same value using arbitrary precision
> floating-point values, the precision needed for correct output (using
> the formula
> @iftex
> @@ -30607,10 +30807,10 @@ floating-point results exactly. You can either
> increase the precision
> @samp{2.0} with an integer, to perform all computations using integer
> arithmetic to get the correct output.
>
> -Sometimes @command{gawk} must implicitly convert an arbitrary-precision
> -integer into an arbitrary-precision floating-point value. This is
> +Sometimes @command{gawk} must implicitly convert an arbitrary precision
> +integer into an arbitrary precision floating-point value. This is
> primarily because the MPFR library does not always provide the relevant
> -interface to process arbitrary-precision integers or mixed-mode numbers
> +interface to process arbitrary precision integers or mixed-mode numbers
> as needed by an operation or function. In such a case, the precision is
> set to the minimum value necessary for exact conversion, and the working
> precision is not used for this purpose. If this is not what you need or
> @@ -30684,6 +30884,7 @@ choose to set:
>
> @example
> @c file eg/prog/pi.awk
> address@hidden
> # pi.awk --- compute the digits of pi
> @c endfile
> @c endfile
> @@ -30699,6 +30900,7 @@ choose to set:
> BEGIN @{
> digits = 100000
> two = 2 * 10 ^ digits
> address@hidden group
> pi = two
> for (m = digits * 4; m > 0; --m) @{
> d = m * 2 + 1
> @@ -30858,7 +31060,7 @@ Thus, @samp{+nan} and @samp{+NaN} are the same.
> @itemize @value{BULLET}
> @item
> Most computer arithmetic is done using either integers or floating-point
> -values. Standard @command{awk} uses double-precision
> +values. Standard @command{awk} uses double precision
> floating-point values.
>
> @item
> @@ -30896,7 +31098,7 @@ arithmetic. Use @code{PREC} to set the precision in
> bits, and
>
> @item
> With @option{-M}, @command{gawk} performs
> -arbitrary-precision integer arithmetic using the GMP library.
> +arbitrary precision integer arithmetic using the GMP library.
> This is faster and more space-efficient than using MPFR for
> the same calculations.
>
> @@ -31268,7 +31470,7 @@ Doing so, however, is poor coding practice.
> Although the API only uses ISO C 90 features, there is an exception; the
> ``constructor'' functions use the @code{inline} keyword. If your compiler
> does not support this keyword, you should either place
> address@hidden''} on your command line or use the GNU Autotools and include a
> address@hidden''} on your command line or use the
> @uref{http://www.gnu.org/software/autoconf, GNU Autoconf} and include a
> @file{config.h} file in your extensions.
>
> @item
> @@ -31541,6 +31743,7 @@ of the function using the macro.
> For example, you might allocate a string value like so:
>
> @example
> address@hidden
> awk_value_t result;
> char *message;
> const char greet[] = "Don't Panic!";
> @@ -31548,8 +31751,10 @@ const char greet[] = "Don't Panic!";
> emalloc(message, char *, sizeof(greet), "myfunc");
> strcpy(message, greet);
> make_malloced_string(message, strlen(message), & result);
> address@hidden group
> @end example
>
> address@hidden 2
> @item #define erealloc(pointer, type, size, message) @dots{}
> This is like @code{emalloc()}, but it calls @code{gawk_realloc()}
> instead of @code{gawk_malloc()}.
> @@ -31615,11 +31820,13 @@ registering parts of your extension with
> @command{gawk}.
> Extension functions are described by the following record:
>
> @example
> address@hidden
> typedef struct awk_ext_func @{
> @ @ @ @ const char *name;
> @ @ @ @ awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
> @ @ @ @ size_t max_expected_args;
> @} awk_ext_func_t;
> address@hidden group
> @end example
>
> The fields are:
> @@ -31763,12 +31970,14 @@ Your extension should package these functions
> inside an
> @code{awk_input_parser_t}, which looks like this:
>
> @example
> address@hidden
> typedef struct awk_input_parser @{
> const char *name; /* name of parser */
> awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf);
> awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf);
> awk_const struct awk_input_parser *awk_const next; /* for gawk */
> @} awk_input_parser_t;
> address@hidden group
> @end example
>
> The fields are:
> @@ -32427,6 +32636,7 @@ to a global variable or array. It is an optimization
> that
> avoids looking up variables in @command{gawk}'s symbol table every time
> access is needed. This was discussed earlier, in @ref{General Data Types}.
>
> address@hidden 1500
> The following functions let you work with scalar cookies:
>
> @table @code
> @@ -32489,12 +32699,14 @@ your extension's variable in @command{gawk}'s
> symbol table using
> using @code{sym_lookup()}:
>
> @example
> address@hidden
> static awk_scalar_t magic_var_cookie; /* cookie for MAGIC_VAR */
>
> static void
> my_extension_init()
> @{
> awk_value_t value;
> address@hidden group
>
> /* install initial value */
> sym_update("MAGIC_VAR", make_number(42.0, & value));
> @@ -32984,10 +33196,12 @@ Finally, because everything was successful, the
> function sets the
> return value to success, and returns:
>
> @example
> address@hidden
> make_number(1.0, result);
> out:
> return result;
> @}
> address@hidden group
> @end example
>
> Here is the output from running this part of the test:
> @@ -33199,7 +33413,7 @@ BEGIN @{
> Here is the result of running the script:
>
> @example
> -$ @kbd{AWKLIBPATH=$PWD ./gawk -f subarray.awk}
> +$ @kbd{AWKLIBPATH=$PWD gawk -f subarray.awk}
> @print{} new_array["subarray"]["foo"] = bar
> @print{} new_array["hello"] = world
> @print{} new_array["answer"] = 42
> @@ -33306,8 +33520,8 @@ debugging:
> @caption{gawk API version constants}
> @multitable @columnfractions .33 .33 .33
> @headitem API Version @tab C preprocessor define @tab enum constant
> address@hidden Major @tab gawk_api_major_version @tab GAWK_API_MAJOR_VERSION
> address@hidden Minor @tab gawk_api_minor_version @tab GAWK_API_MINOR_VERSION
> address@hidden Major @tab @code{gawk_api_major_version} @tab
> @code{GAWK_API_MAJOR_VERSION}
> address@hidden Minor @tab @code{gawk_api_minor_version} @tab
> @code{GAWK_API_MINOR_VERSION}
> @end multitable
> @end float
>
> @@ -33336,7 +33550,7 @@ It is up to the extension to decide if there are API
> incompatibilities.
> Typically, a check like this is enough:
>
> @example
> -if (api->major_version != GAWK_API_MAJOR_VERSION
> +if ( api->major_version != GAWK_API_MAJOR_VERSION
> || api->minor_version < GAWK_API_MINOR_VERSION) @{
> fprintf(stderr, "foo_extension: version mismatch with gawk!\n");
> fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n",
> @@ -33394,10 +33608,12 @@ as described here. The boilerplate needed is also
> provided in comments
> in the @file{gawkapi.h} header file:
>
> @example
> address@hidden
> /* Boilerplate code: */
> int plugin_is_GPL_compatible;
>
> static gawk_api_t *const api;
> address@hidden group
> static awk_ext_id_t ext_id;
> static const char *ext_version = NULL; /* or @dots{} = "some string" */
>
> @@ -33740,10 +33956,12 @@ The second is a pointer to an @code{awk_value_t}
> structure, usually named
> @code{result}:
>
> @example
> address@hidden
> /* do_chdir --- provide dynamically loaded chdir() function for gawk */
>
> static awk_value_t *
> do_chdir(int nargs, awk_value_t *result)
> address@hidden group
> @{
> awk_value_t newdir;
> int ret = -1;
> @@ -33875,7 +34093,7 @@ fill_stat_array(const char *name, awk_array_t array,
> struct stat *sbuf)
> #endif
> #ifdef S_IFDOOR /* Solaris weirdness */
> @{ S_IFDOOR, "door" @},
> -#endif /* S_IFDOOR */
> +#endif
> @};
> int j, k;
> @end example
> @@ -33918,9 +34136,11 @@ certain members and/or the type of the file. It then
> returns zero,
> for success:
>
> @example
> address@hidden
> #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
> array_set_numeric(array, "blksize", sbuf->st_blksize);
> -#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
> +#endif
> address@hidden group
>
> pmode = format_mode(sbuf->st_mode);
> array_set(array, "pmode", make_const_string(pmode, strlen(pmode),
> @@ -34020,20 +34240,24 @@ Next, it gets the information for the file. If the
> called function
>
> /* stat the file; if error, set ERRNO and return */
> ret = statfunc(name, & sbuf);
> address@hidden
> if (ret < 0) @{
> update_ERRNO_int(errno);
> return make_number(ret, result);
> @}
> address@hidden group
> @end example
>
> The tedious work is done by @code{fill_stat_array()}, shown
> earlier. When done, the function returns the result from
> @code{fill_stat_array()}:
>
> @example
> address@hidden
> ret = fill_stat_array(name, array, & sbuf);
>
> return make_number(ret, result);
> @}
> address@hidden group
> @end example
>
> Finally, it's necessary to provide the ``glue'' that loads the
> @@ -34733,7 +34957,7 @@ order, use the array sorting features in
> @command{gawk} to do so
> (@pxref{Array Sorting}).
>
> The file contains binary data. All integral values are written in network
> -byte order. However, double-precision floating-point values are written
> +byte order. However, double precision floating-point values are written
> as native binary data. Thus, arrays containing only string data can
> theoretically be dumped on systems with one byte order and restored on
> systems with a different one, but this has not been tried.
> @@ -36748,7 +36972,7 @@ into a byte-code interpreter, including the debugger
> The addition of true arrays of arrays
>
> @item
> -The additional modifications for support of arbitrary-precision arithmetic
> +The additional modifications for support of arbitrary precision arithmetic
>
> @item
> The initial text of
> @@ -37478,17 +37702,17 @@ allows control over these translations and is
> interpreted as follows:
>
> @itemize @value{BULLET}
> @item
> -If @code{BINMODE} is @code{"r"} or one,
> +If @code{BINMODE} is @code{"r"} or @code{"1"},
> then
> binary mode is set on read (i.e., no translations on reads).
>
> @item
> -If @code{BINMODE} is @code{"w"} or two,
> +If @code{BINMODE} is @code{"w"} or @code{"2"},
> then
> binary mode is set on write (i.e., no translations on writes).
>
> @item
> -If @code{BINMODE} is @code{"rw"} or @code{"wr"} or three,
> +If @code{BINMODE} is @code{"rw"} or @code{"wr"} or @code{"3"},
> binary mode is set for both read and write.
>
> @item
> @@ -39054,7 +39278,7 @@ different limits.
> @item Number of input records in one file @tab @code{MAX_LONG}
> @item Number of input records total @tab @code{MAX_LONG}
> @item Number of pipe redirections @tab min(number of processes per user,
> number of open files)
> address@hidden Numeric values @tab Double-precision floating point (if not
> using MPFR)
> address@hidden Numeric values @tab Double precision floating point (if not
> using MPFR)
> @item Size of a field @tab @code{MAX_INT}
> @item Size of a literal string @tab @code{MAX_INT}
> @item Size of a printf string @tab @code{MAX_INT}
> @@ -39555,14 +39779,24 @@ like this: @code{""}.
>
> Humans are used to working in decimal; i.e., base 10. In base 10,
> numbers go from 0 to 9, and then ``roll over'' into the next
> address@hidden
> +column. (Remember grade school? @math{42 = 4\times 10 + 2}.)
> address@hidden iftex
> address@hidden
> column. (Remember grade school? 42 = 4 x 10 + 2.)
> address@hidden ifnottex
>
> There are other number bases though. Computers commonly use base 2
> or @dfn{binary}, base 8 or @dfn{octal}, and base 16 or @dfn{hexadecimal}.
> In binary, each column represents two times the value in the column to
> its right. Each column may contain either a 0 or a 1.
> address@hidden
> +Thus, binary 1010 represents @math{(1\times 8) + (0\times 4) + (1\times 2) +
> (0\times 1)}, or decimal 10.
> address@hidden iftex
> address@hidden
> Thus, binary 1010 represents (1 x 8) + (0 x 4) + (1 x 2)
> + (0 x 1), or decimal 10.
> address@hidden ifnottex
> Octal and hexadecimal are discussed more in
> @ref{Nondecimal-numbers}.
>
> @@ -39702,7 +39936,12 @@ electronic circuitry works ``naturally'' in base 2
> (just think of Off/On),
> everything inside a computer is calculated using base 2. Each digit
> represents the presence (or absence) of a power of 2 and is called a
> @dfn{bit}. So, for example, the base-two number @code{10101} is
> address@hidden
> +the same as decimal 21, (@math{(1\times 16) + (1\times 4) + (1\times 1)}).
> address@hidden iftex
> address@hidden
> the same as decimal 21, ((1 x 16) + (1 x 4) + (1 x 1)).
> address@hidden ifnottex
>
> Since base-two numbers quickly become
> very long to read and write, they are usually grouped by 3 (i.e., they are
> @@ -39873,7 +40112,7 @@ See also ``Interpreter.''
> @item Complemented Bracket Expression
> The negation of a @dfn{bracket expression}. All that is @emph{not}
> described by a given bracket expression. The symbol @samp{^} precedes
> -the negated bracket expression. E.g.: @samp{[[^:digit:]}
> +the negated bracket expression. E.g.: @samp{[^[:digit:]]}
> designates whatever character is not a digit. @samp{[^bad]}
> designates whatever character is not one of the letters @samp{b}, @samp{a},
> or @samp{d}.
> @@ -40142,7 +40381,12 @@ Base 16 notation, where the digits are
> @address@hidden and
> @address@hidden, with @samp{A}
> representing 10, @samp{B} representing 11, and so on, up to @samp{F} for 15.
> Hexadecimal numbers are written in C using a leading @samp{0x},
> address@hidden
> +to indicate their base. Thus, @code{0x12} is 18 (@math{(1\times 16) + 2}).
> address@hidden iftex
> address@hidden
> to indicate their base. Thus, @code{0x12} is 18 ((1 x 16) + 2).
> address@hidden ifnottex
> @xref{Nondecimal-numbers}.
>
> @item I/O
> @@ -40206,7 +40450,7 @@ meaning. Keywords are reserved and may not be used
> as variable names.
> @code{break},
> @code{case},
> @code{continue},
> address@hidden
> address@hidden,
> @code{delete},
> @address@hidden,
> @code{else},
> @@ -40292,7 +40536,12 @@ Ancient @command{awk} implementations used single
> precision floating-point.
> @item Octal
> Base-eight notation, where the digits are @address@hidden
> Octal numbers are written in C using a leading @samp{0},
> address@hidden
> +to indicate their base. Thus, @code{013} is 11 (@math{(1\times 8) + 3}).
> address@hidden iftex
> address@hidden
> to indicate their base. Thus, @code{013} is 11 ((1 x 8) + 3).
> address@hidden ifnottex
> @xref{Nondecimal-numbers}.
>
> @item Output Record
> @@ -41802,7 +42051,8 @@ Consistency issues:
> Use @command{ftp} when talking about anonymous ftp
> Use uppercase and lowercase, not "upper-case" and "lower-case"
> or "upper case" and "lower case"
> - Use "single precision" and "double precision", not "single-precision"
> or "double-precision"
> + Use "half precision", "single precision", "double precision" and
> "arbitrary precision",
> + not "half-precision", "single-precision", "double-precision"
> and "arbitrary-precision".
> Use alphanumeric, not alpha-numeric
> Use POSIX-compliant, not POSIX compliant
> Use --foo, not -Wfoo when describing long options
>
>
>
> ~~~
> Sergey Tselikh <address@hidden>
--
Andrew Schorr e-mail: address@hidden
Telemetry Investments, L.L.C. phone: 917-305-1748
545 Fifth Ave, Suite 1108 fax: 212-425-5550
New York, NY 10017-3630