[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug-gawk] Small fixes to gawktexi.in
From: |
Sergey Tselikh |
Subject: |
[bug-gawk] Small fixes to gawktexi.in |
Date: |
Sun, 13 Nov 2016 06:26:38 +1000 |
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>
- [bug-gawk] Small fixes to gawktexi.in,
Sergey Tselikh <=