[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gawk] Small fixes to gawktexi.in
From: |
Sergey Tselikh |
Subject: |
Re: [bug-gawk] Small fixes to gawktexi.in |
Date: |
Sun, 13 Nov 2016 07:26:55 +1000 |
On Sat, 12 Nov 2016 14:48:46 -0500
"Andrew J. Schorr" <address@hidden> wrote:
> 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
Well, in the end of doc/gawktexi.in, after the @bye command, there is
a section with list of consistency tips, one of which is:
Use "single precision" and "double precision", not "single-precision"
or "double-precision"
As I understood, this recommendation should apply to any text in gawktexi.in.
If hyphens in "*-precision" are important, in this e-mail I'm sending
another patch (see below) with no "*-precision" edits and following ChangeLog
entry:
* 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). Hyphenated words "single-precision",
"double-precision" and alike left untouched.
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..470d319 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,15 @@
+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). Hyphenated words "single-precision",
+ "double-precision" and alike left untouched.
+
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..70424c6 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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).
@@ -29914,6 +30091,12 @@ 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.
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.
@command{gawk} has facilities for performing arbitrary-precision
@@ -29924,28 +30107,43 @@ 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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
~~~
Sergey Tselikh <address@hidden>