diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/ChangeLog | 12 | ||||
-rw-r--r-- | doc/gawk.info | 1084 | ||||
-rw-r--r-- | doc/gawk.texi | 312 | ||||
-rw-r--r-- | doc/gawktexi.in | 310 |
4 files changed, 1128 insertions, 590 deletions
diff --git a/doc/ChangeLog b/doc/ChangeLog index 7c4b66db..02cc0dd4 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,15 @@ +2017-12-01 Sergey Tselikh <stselikh@gmail.com> + + * 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. + 2017-12-14 Arnold D. Robbins <arnold@skeeve.com> * gawktexi.in: Add a note to add a section on recursion. diff --git a/doc/gawk.info b/doc/gawk.info index 5dc9f7b0..a60904e7 100644 --- a/doc/gawk.info +++ b/doc/gawk.info @@ -7383,13 +7383,13 @@ from the system's 'close()' or 'fclose()' C functions when closing input or output files, respectively. This value is zero if the close succeeds, or -1 if it fails. -Situation Return value from 'close()' +Situation Return value from 'close()' -------------------------------------------------------------------------- -Normal exit of command Command's exit status -Death by signal of command 256 + number of murderous signal -Death by signal of command 512 + number of murderous signal -with core dump -Some kind of error -1 +Normal exit of command Command's exit status +Death by signal of command 256 + number of murderous signal +Death by signal of command with 512 + number of murderous signal +core dump +Some kind of error -1 Table 5.1: Return values from 'close()' of a pipe @@ -7422,7 +7422,8 @@ file, or some other I/O error (such as filling up the disk) is a fatal error. $ gawk 'BEGIN { print "hi" > "/no/such/file" }' - error-> gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No such file or directory) + error-> gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No + error-> such file or directory) 'gawk' makes it possible to detect that an error has occurred, allowing you to possibly recover from the error, or at least print an @@ -13288,35 +13289,34 @@ parameters are enclosed in square brackets ([ ]): Interactive Versus Noninteractive Buffering - As a side point, buffering issues can be even more confusing if - your program is "interactive" (i.e., communicating with a user - sitting at a keyboard).(1) + As a side point, buffering issues can be even more confusing if your +program is "interactive" (i.e., communicating with a user sitting at a +keyboard).(1) - Interactive programs generally "line buffer" their output (i.e., - they write out every line). Noninteractive programs wait until - they have a full buffer, which may be many lines of output. Here - is an example of the difference: + Interactive programs generally "line buffer" their output (i.e., they +write out every line). Noninteractive programs wait until they have a +full buffer, which may be many lines of output. Here is an example of +the difference: - $ awk '{ print $1 + $2 }' - 1 1 - -| 2 - 2 3 - -| 5 - Ctrl-d + $ awk '{ print $1 + $2 }' + 1 1 + -| 2 + 2 3 + -| 5 + Ctrl-d - Each line of output is printed immediately. Compare that behavior - with this example: +Each line of output is printed immediately. Compare that behavior with +this example: - $ awk '{ print $1 + $2 }' | cat - 1 1 - 2 3 - Ctrl-d - -| 2 - -| 5 + $ awk '{ print $1 + $2 }' | cat + 1 1 + 2 3 + Ctrl-d + -| 2 + -| 5 - Here, no output is printed until after the 'Ctrl-d' is typed, - because it is all buffered and sent down the pipe to 'cat' in one - shot. +Here, no output is printed until after the 'Ctrl-d' is typed, because it +is all buffered and sent down the pipe to 'cat' in one shot. 'system(COMMAND)' Execute the operating system command COMMAND and then return to the @@ -13814,7 +13814,7 @@ are enclosed in square brackets ([ ]): Here is a user-defined function (*note User-defined::) that illustrates the use of these functions: - # bits2str --- turn a byte into readable ones and zeros + # bits2str --- turn an integer into readable ones and zeros function bits2str(bits, data, mask) { @@ -13849,7 +13849,8 @@ This program produces the following output when run: -| 123 = 01111011 -| 0123 = 01010011 -| 0x99 = 10011001 - -| compl(0x99) = 0x3fffffffffff66 = 00111111111111111111111111111111111111111111111101100110 + -| compl(0x99) = 0x3fffffffffff66 = + -| 00111111111111111111111111111111111111111111111101100110 -| lshift(0x99, 2) = 0x264 = 0000001001100100 -| rshift(0x99, 2) = 0x26 = 00100110 @@ -15417,7 +15418,6 @@ following function does traditional rounding; it might be useful if your return ival } } - # test harness # { print $0, round($0) } @@ -17743,7 +17743,6 @@ names: outfile = ARGV[i] ARGV[i] = "" } - s1 = s2 = "a" out = (outfile s1 s2) } @@ -19994,6 +19993,7 @@ specific field position and can be used for this purpose: PROCINFO["sorted_in"] = "cmp_field" 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 ? ":" : "") @@ -22313,9 +22313,7 @@ categories, as follows: -| [ :0xfcc660] Op_no_op : -| [ 1:0xfcc520] Op_assign_concat : c -| [ :0xfcc620] Op_jmp : [target_jmp = 0xfcc440] - -| ... - -| -| [ 2:0xfcc5a0] Op_K_printf : [expr_count = 17] [redir_type = ""] -| [ :0xfcc140] Op_no_op : -| [ :0xfcc1c0] Op_atexit : @@ -22581,11 +22579,14 @@ Floating-point arithmetic 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 +double-precision floating-point values occupy 64 bits. +(Quadruple-precision floating point values also exist. They occupy 128 +bits, but such numbers are not available in 'awk'.) Floating-point values are always signed. The possible ranges of values are shown in -*note Table 15.1: table-numeric-ranges. +*note Table 15.1: table-numeric-ranges. and *note Table 15.2: +table-floating-point-ranges. -Numeric representation Minimum value Maximum value +Representation Minimum value Maximum value --------------------------------------------------------------------------- 32-bit signed integer -2,147,483,648 2,147,483,647 32-bit unsigned 0 4,294,967,295 @@ -22593,14 +22594,22 @@ integer 64-bit signed integer -9,223,372,036,854,775,8089,223,372,036,854,775,807 64-bit unsigned 0 18,446,744,073,709,551,615 integer -Single-precision 1.175494e-38 3.402823e38 -floating point -(approximate) -Double-precision 2.225074e-308 1.797693e308 -floating point -(approximate) -Table 15.1: Value ranges for different numeric representations +Table 15.1: Value ranges for integer representations + +Representation Minimum Minimum finite Maximum finite + positive value value + nonzero value +-------------------------------------------------------------------------------- +Single-precision 1.175494e-38 -3.402823e+38 3.402823e+38 +floating-point +Double-precision 2.225074e-308 -1.797693e+308 1.797693e+308 +floating-point +Quadruple-precision 3.362103e-4932 -1.189731e+4932 1.189731e+4932 +floating-point + +Table 15.2: Approximate value ranges for floating-point number +representations ---------- Footnotes ---------- @@ -22689,7 +22698,7 @@ IEEE 754 types are 32-bit single precision, 64-bit double precision, and precision formats to allow greater precisions and larger exponent ranges. ('awk' uses only the 64-bit double-precision format.) - *note Table 15.2: table-ieee-formats. lists the precision and + *note Table 15.3: table-ieee-formats. lists the precision and exponent field values for the basic IEEE 754 binary formats. Name Total bits Precision Minimum Maximum @@ -22699,7 +22708,7 @@ Single 32 24 -126 +127 Double 64 53 -1022 +1023 Quadruple 128 113 -16382 +16383 -Table 15.2: Basic IEEE format values +Table 15.3: Basic IEEE format values NOTE: The precision numbers include the implied leading one that gives them one extra bit of significand. @@ -23010,7 +23019,7 @@ operation or calling a built-in function rounds the result to the current working precision. The default working precision is 53 bits, which you can modify using the predefined variable 'PREC'. You can also set the value to one of the predefined case-insensitive strings shown in -*note Table 15.3: table-predefined-precision-strings, to emulate an IEEE +*note Table 15.4: table-predefined-precision-strings, to emulate an IEEE 754 binary format. 'PREC' IEEE 754 binary format @@ -23021,7 +23030,7 @@ set the value to one of the predefined case-insensitive strings shown in '"quad"' Basic 128-bit quadruple precision '"oct"' 256-bit octuple precision -Table 15.3: Predefined precision strings for 'PREC' +Table 15.4: Predefined precision strings for 'PREC' The following example illustrates the effects of changing precision on arithmetic operations: @@ -23063,7 +23072,7 @@ File: gawk.info, Node: Setting the rounding mode, Prev: Setting precision, Up The 'ROUNDMODE' variable provides program-level control over the rounding mode. The correspondence between 'ROUNDMODE' and the IEEE -rounding modes is shown in *note Table 15.4: table-gawk-rounding-modes. +rounding modes is shown in *note Table 15.5: table-gawk-rounding-modes. Rounding mode IEEE name 'ROUNDMODE' --------------------------------------------------------------------------- @@ -23073,10 +23082,10 @@ Round toward negative infinity 'roundTowardNegative' '"D"' or '"d"' Round toward zero 'roundTowardZero' '"Z"' or '"z"' Round away from zero '"A"' or '"a"' -Table 15.4: 'gawk' rounding modes +Table 15.5: 'gawk' rounding modes 'ROUNDMODE' has the default value '"N"', which selects the IEEE 754 -rounding mode 'roundTiesToEven'. In *note Table 15.4: +rounding mode 'roundTiesToEven'. In *note Table 15.5: table-gawk-rounding-modes, the value '"A"' selects rounding away from zero. This is only available if your version of the MPFR library supports it; otherwise, setting 'ROUNDMODE' to '"A"' has no effect. @@ -24023,6 +24032,8 @@ value: strcpy(message, greet); make_malloced_string(message, strlen(message), & result); + + '#define ezalloc(pointer, type, size, message) ...' This is like 'emalloc()', but it calls 'gawk_calloc()' instead of 'gawk_malloc()'. The arguments are the same as for the 'emalloc()' @@ -25616,7 +25627,7 @@ array: Here is the result of running the script: - $ AWKLIBPATH=$PWD ./gawk -f subarray.awk + $ AWKLIBPATH=$PWD gawk -f subarray.awk -| new_array["subarray"]["foo"] = bar -| new_array["hello"] = world -| new_array["answer"] = 42 @@ -25751,7 +25762,7 @@ are included in the API 'struct' as read-only constant integers: It is up to the extension to decide if there are API incompatibilities. Typically, a check like this is enough: - 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", @@ -26317,7 +26328,7 @@ table to map file types to strings: #endif #ifdef S_IFDOOR /* Solaris weirdness */ { S_IFDOOR, "door" }, - #endif /* S_IFDOOR */ + #endif }; int j, k; @@ -26356,7 +26367,7 @@ and/or the type of the file. It then returns zero, for success: #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE array_set_numeric(array, "blksize", sbuf->st_blksize); - #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ + #endif pmode = format_mode(sbuf->st_mode); array_set(array, "pmode", make_const_string(pmode, strlen(pmode), @@ -31023,7 +31034,7 @@ Compiler Complemented Bracket Expression The negation of a "bracket expression". All that is _not_ described by a given bracket expression. The symbol '^' precedes - the negated bracket expression. E.g.: '[[^:digit:]' designates + the negated bracket expression. E.g.: '[^[:digit:]]' designates whatever character is not a digit. '[^bad]' designates whatever character is not one of the letters 'b', 'a', or 'd'. See "Bracket Expression." @@ -31278,7 +31289,7 @@ Keyword names. 'gawk''s keywords are: 'BEGIN', 'BEGINFILE', 'END', 'ENDFILE', - 'break', 'case', 'continue', 'default' 'delete', 'do...while', + 'break', 'case', 'continue', 'default', 'delete', 'do...while', 'else', 'exit', 'for...in', 'for', 'function', 'func', 'if', 'next', 'nextfile', 'switch', and 'while'. @@ -32889,7 +32900,7 @@ Index * --re-interval option: Options. (line 292) * --sandbox option: Options. (line 304) * --sandbox option, disabling system() function: I/O Functions. - (line 129) + (line 128) * --sandbox option, input redirection with getline: Getline. (line 19) * --sandbox option, output redirection with print, printf: Redirection. (line 6) @@ -33130,6 +33141,7 @@ Index (line 6) * arbitrary precision integers: Arbitrary Precision Integers. (line 6) +* arbitrary-precision: Computer Arithmetic. (line 61) * archaeologists: Bugs. (line 6) * arctangent: Numeric Functions. (line 12) * ARGC/ARGV variables: Auto-set. (line 15) @@ -33454,11 +33466,11 @@ Index * Buening, Andreas: Acknowledgments. (line 60) * Buening, Andreas <1>: Contributors. (line 95) * Buening, Andreas <2>: Maintainers. (line 14) -* buffering, input/output: I/O Functions. (line 166) +* buffering, input/output: I/O Functions. (line 165) * buffering, input/output <1>: Two-way I/O. (line 53) * buffering, interactive vs. noninteractive: I/O Functions. (line 76) * buffers, flushing: I/O Functions. (line 32) -* buffers, flushing <1>: I/O Functions. (line 166) +* buffers, flushing <1>: I/O Functions. (line 165) * buffers, operators for: GNU Regexp Operators. (line 51) * bug reports, email address, bug-gawk@gnu.org: Bug address. (line 31) @@ -33620,9 +33632,9 @@ Index (line 31) * converting, dates to timestamps: Time Functions. (line 78) * converting, numbers to strings: Strings And Numbers. (line 6) -* converting, numbers to strings <1>: Bitwise Functions. (line 108) +* converting, numbers to strings <1>: Bitwise Functions. (line 109) * converting, strings to numbers: Strings And Numbers. (line 6) -* converting, strings to numbers <1>: Bitwise Functions. (line 108) +* converting, strings to numbers <1>: Bitwise Functions. (line 109) * CONVFMT variable: Strings And Numbers. (line 29) * CONVFMT variable <1>: User-modified. (line 30) * CONVFMT variable, and array subscripts: Numeric Array Subscripts. @@ -33755,16 +33767,16 @@ Index (line 39) * debugger commands, frame: Execution Stack. (line 27) * debugger commands, h (help): Miscellaneous Debugger Commands. - (line 69) + (line 67) * debugger commands, help: Miscellaneous Debugger Commands. - (line 69) + (line 67) * debugger commands, i (info): Debugger Info. (line 13) * debugger commands, ignore: Breakpoint Control. (line 87) * debugger commands, info: Debugger Info. (line 13) * debugger commands, l (list): Miscellaneous Debugger Commands. - (line 75) + (line 73) * debugger commands, list: Miscellaneous Debugger Commands. - (line 75) + (line 73) * debugger commands, n (next): Debugger Execution Control. (line 43) * debugger commands, next: Debugger Execution Control. @@ -33782,9 +33794,9 @@ Index * debugger commands, printf: Viewing And Changing Data. (line 53) * debugger commands, q (quit): Miscellaneous Debugger Commands. - (line 102) + (line 100) * debugger commands, quit: Miscellaneous Debugger Commands. - (line 102) + (line 100) * debugger commands, r (run): Debugger Execution Control. (line 62) * debugger commands, return: Debugger Execution Control. @@ -33806,7 +33818,7 @@ Index * debugger commands, t (tbreak): Breakpoint Control. (line 90) * debugger commands, tbreak: Breakpoint Control. (line 90) * debugger commands, trace: Miscellaneous Debugger Commands. - (line 110) + (line 108) * debugger commands, u (until): Debugger Execution Control. (line 82) * debugger commands, undisplay: Viewing And Changing Data. @@ -33947,6 +33959,7 @@ Index * dollar sign ($), regexp operator: Regexp Operators. (line 35) * double quote ("), in regexp constants: Computed Regexps. (line 30) * double quote ("), in shell commands: Quoting. (line 54) +* double-precision: Computer Arithmetic. (line 61) * down debugger command: Execution Stack. (line 23) * Drepper, Ulrich: Acknowledgments. (line 52) * Duman, Patrice: Acknowledgments. (line 75) @@ -34052,14 +34065,14 @@ Index * exclamation point (!), !~ operator <7>: Expression Patterns. (line 24) * exit debugger command: Miscellaneous Debugger Commands. - (line 66) + (line 64) * exit statement: Exit Statement. (line 6) * exit status, of gawk: Exit Status. (line 6) * exit status, of VMS: VMS Running. (line 28) * exit the debugger: Miscellaneous Debugger Commands. - (line 66) + (line 64) * exit the debugger <1>: Miscellaneous Debugger Commands. - (line 102) + (line 100) * exp: Numeric Functions. (line 19) * expand utility: Very Simple. (line 73) * Expat XML parser library: gawkextlib. (line 37) @@ -34225,8 +34238,15 @@ Index * fixed-width data: Constant Size. (line 6) * flag variables: Boolean Ops. (line 69) * flag variables <1>: Tee Program. (line 20) +* floating-point, numbers: Computer Arithmetic. (line 49) * floating-point, numbers, arbitrary precision: Arbitrary Precision Arithmetic. (line 6) +* floating-point, numbers, arbitrary-precision: Computer Arithmetic. + (line 61) +* floating-point, numbers, double-precision: Computer Arithmetic. + (line 61) +* floating-point, numbers, single-precision: Computer Arithmetic. + (line 61) * floating-point, VAX/VMS: VMS Running. (line 50) * flush buffered output: I/O Functions. (line 28) * fnmatch() extension function: Extension Sample Fnmatch. @@ -34527,7 +34547,7 @@ Index * Guerrero, Juan Manuel <1>: Contributors. (line 150) * Guerrero, Juan Manuel <2>: Maintainers. (line 14) * h debugger command (alias for help): Miscellaneous Debugger Commands. - (line 69) + (line 67) * Hankerson, Darrel: Acknowledgments. (line 60) * Hankerson, Darrel <1>: Contributors. (line 61) * Haque, John: Contributors. (line 111) @@ -34535,7 +34555,7 @@ Index * Hartholz, Marshall: Acknowledgments. (line 38) * Hasegawa, Isamu: Contributors. (line 97) * help debugger command: Miscellaneous Debugger Commands. - (line 69) + (line 67) * hexadecimal numbers: Nondecimal-numbers. (line 6) * hexadecimal values, enabling interpretation of: Options. (line 223) * history expansion, in debugger: Readline Support. (line 6) @@ -34629,7 +34649,7 @@ Index * integers, arbitrary precision: Arbitrary Precision Integers. (line 6) * integers, unsigned: Computer Arithmetic. (line 41) -* interacting with other programs: I/O Functions. (line 107) +* interacting with other programs: I/O Functions. (line 106) * internationalization: I18N Functions. (line 6) * internationalization <1>: I18N and L10N. (line 6) * internationalization, localization: User-modified. (line 155) @@ -34650,7 +34670,7 @@ Index * interpreted programs <1>: Glossary. (line 443) * interval expressions, regexp operator: Regexp Operators. (line 116) * inventory-shipped file: Sample Data Files. (line 32) -* invoke shell command: I/O Functions. (line 107) +* invoke shell command: I/O Functions. (line 106) * isarray: Type Functions. (line 11) * ISO: Glossary. (line 454) * ISO 8859-1: Glossary. (line 194) @@ -34683,7 +34703,7 @@ Index * Knights, jedi: Undocumented. (line 6) * Kwok, Conrad: Contributors. (line 35) * l debugger command (alias for list): Miscellaneous Debugger Commands. - (line 75) + (line 73) * labels.awk program: Labels Program. (line 51) * Langston, Peter: Advanced Features. (line 6) * LANGUAGE environment variable: Explaining gettext. (line 120) @@ -34761,7 +34781,7 @@ Index * Linux <2>: Glossary. (line 746) * list all global variables, in debugger: Debugger Info. (line 48) * list debugger command: Miscellaneous Debugger Commands. - (line 75) + (line 73) * list function definitions, in debugger: Debugger Info. (line 30) * loading extensions, @load directive: Loading Shared Libraries. (line 8) @@ -34902,7 +34922,7 @@ Index * null strings, converting numbers to strings: Strings And Numbers. (line 21) * null strings, matching: String Functions. (line 539) -* number as string of bits: Bitwise Functions. (line 108) +* number as string of bits: Bitwise Functions. (line 109) * number of array elements: String Functions. (line 200) * number sign (#), #! (executable scripts): Executable Scripts. (line 6) @@ -34913,7 +34933,7 @@ Index * numbers, Cliff random: Cliff Random Function. (line 6) * numbers, converting: Strings And Numbers. (line 6) -* numbers, converting <1>: Bitwise Functions. (line 108) +* numbers, converting <1>: Bitwise Functions. (line 109) * numbers, converting, to strings: User-modified. (line 30) * numbers, converting, to strings <1>: User-modified. (line 107) * numbers, hexadecimal: Nondecimal-numbers. (line 6) @@ -34996,7 +35016,7 @@ Index * output redirection: Redirection. (line 6) * output wrapper: Output Wrappers. (line 6) * output, buffering: I/O Functions. (line 32) -* output, buffering <1>: I/O Functions. (line 166) +* output, buffering <1>: I/O Functions. (line 165) * output, duplicating into files: Tee Program. (line 6) * output, files, closing: Close Files And Pipes. (line 6) @@ -35220,7 +35240,7 @@ Index * programming, concepts <1>: Basic Concepts. (line 6) * pwcat program: Passwd Functions. (line 23) * q debugger command (alias for quit): Miscellaneous Debugger Commands. - (line 102) + (line 100) * QSE awk: Other Versions. (line 140) * Quanstrom, Erik: Alarm Program. (line 8) * question mark (?), ?: operator: Precedence. (line 91) @@ -35229,7 +35249,7 @@ Index (line 62) * QuikTrim Awk: Other Versions. (line 144) * quit debugger command: Miscellaneous Debugger Commands. - (line 102) + (line 100) * QUIT signal (MS-Windows): Profiling. (line 212) * quoting in gawk command lines: Long. (line 26) * quoting in gawk command lines, tricks for: Quoting. (line 91) @@ -35486,12 +35506,12 @@ Index (line 63) * sidebar, Backslash Before Regular Characters: Escape Sequences. (line 106) -* sidebar, Beware The Smoke and Mirrors!: Bitwise Functions. (line 126) +* sidebar, Beware The Smoke and Mirrors!: Bitwise Functions. (line 127) * sidebar, Changing FS Does Not Affect the Fields: Full Line Fields. (line 14) * sidebar, Changing NR and FNR: Auto-set. (line 388) * sidebar, Controlling Output Buffering with system(): I/O Functions. - (line 164) + (line 163) * sidebar, Escape Sequences for Metacharacters: Escape Sequences. (line 138) * sidebar, FS and IGNORECASE: Field Splitting Summary. @@ -35535,6 +35555,7 @@ Index * single quote ('), with double quotes: Quoting. (line 73) * single-character fields: Single Character Fields. (line 6) +* single-precision: Computer Arithmetic. (line 61) * single-step execution, in the debugger: Debugger Execution Control. (line 43) * Skywalker, Luke: Undocumented. (line 6) @@ -35617,7 +35638,7 @@ Index * string-translation functions: I18N Functions. (line 6) * strings splitting, example: String Functions. (line 336) * strings, converting: Strings And Numbers. (line 6) -* strings, converting <1>: Bitwise Functions. (line 108) +* strings, converting <1>: Bitwise Functions. (line 109) * strings, converting letter case: String Functions. (line 525) * strings, converting, numbers to: User-modified. (line 30) * strings, converting, numbers to <1>: User-modified. (line 107) @@ -35657,7 +35678,7 @@ Index * SYMTAB array: Auto-set. (line 332) * syntactic ambiguity: /= operator vs. /=.../ regexp constant: Assignment Ops. (line 149) -* system: I/O Functions. (line 107) +* system: I/O Functions. (line 106) * systime: Time Functions. (line 68) * t debugger command (alias for tbreak): Breakpoint Control. (line 90) * tbreak debugger command: Breakpoint Control. (line 90) @@ -35714,7 +35735,7 @@ Index * toupper: String Functions. (line 532) * tr utility: Translate Program. (line 6) * trace debugger command: Miscellaneous Debugger Commands. - (line 110) + (line 108) * traceback, display in debugger: Execution Stack. (line 13) * translate string: I18N Functions. (line 21) * translate.awk program: Translate Program. (line 55) @@ -35748,7 +35769,7 @@ Index (line 40) * troubleshooting, string concatenation: Concatenation. (line 27) * troubleshooting, substr() function: String Functions. (line 502) -* troubleshooting, system() function: I/O Functions. (line 129) +* troubleshooting, system() function: I/O Functions. (line 128) * troubleshooting, typographical errors, global variables: Options. (line 99) * true, logical: Truth Values. (line 6) @@ -36043,444 +36064,445 @@ Node: Special Network315828 Node: Special Caveats316688 Node: Close Files And Pipes317637 Ref: table-close-pipe-return-values324544 -Ref: Close Files And Pipes-Footnote-1325327 -Ref: Close Files And Pipes-Footnote-2325475 -Node: Nonfatal325627 -Node: Output Summary327952 -Node: Output Exercises329174 -Node: Expressions329853 -Node: Values331041 -Node: Constants331719 -Node: Scalar Constants332410 -Ref: Scalar Constants-Footnote-1333274 -Node: Nondecimal-numbers333524 -Node: Regexp Constants336525 -Node: Using Constant Regexps337051 -Node: Standard Regexp Constants337673 -Node: Strong Regexp Constants340861 -Node: Variables343819 -Node: Using Variables344476 -Node: Assignment Options346386 -Node: Conversion348259 -Node: Strings And Numbers348783 -Ref: Strings And Numbers-Footnote-1351846 -Node: Locale influences conversions351955 -Ref: table-locale-affects354713 -Node: All Operators355331 -Node: Arithmetic Ops355960 -Node: Concatenation358466 -Ref: Concatenation-Footnote-1361313 -Node: Assignment Ops361420 -Ref: table-assign-ops366411 -Node: Increment Ops367724 -Node: Truth Values and Conditions371184 -Node: Truth Values372258 -Node: Typing and Comparison373306 -Node: Variable Typing374126 -Ref: Variable Typing-Footnote-1380589 -Ref: Variable Typing-Footnote-2380661 -Node: Comparison Operators380738 -Ref: table-relational-ops381157 -Node: POSIX String Comparison384652 -Ref: POSIX String Comparison-Footnote-1386347 -Ref: POSIX String Comparison-Footnote-2386486 -Node: Boolean Ops386570 -Ref: Boolean Ops-Footnote-1391052 -Node: Conditional Exp391144 -Node: Function Calls392880 -Node: Precedence396757 -Node: Locales400416 -Node: Expressions Summary402048 -Node: Patterns and Actions404621 -Node: Pattern Overview405741 -Node: Regexp Patterns407418 -Node: Expression Patterns407960 -Node: Ranges411741 -Node: BEGIN/END414849 -Node: Using BEGIN/END415610 -Ref: Using BEGIN/END-Footnote-1418346 -Node: I/O And BEGIN/END418452 -Node: BEGINFILE/ENDFILE420766 -Node: Empty423679 -Node: Using Shell Variables423996 -Node: Action Overview426270 -Node: Statements428595 -Node: If Statement430443 -Node: While Statement431938 -Node: Do Statement433966 -Node: For Statement435114 -Node: Switch Statement438285 -Node: Break Statement440671 -Node: Continue Statement442763 -Node: Next Statement444590 -Node: Nextfile Statement446973 -Node: Exit Statement449625 -Node: Built-in Variables452028 -Node: User-modified453161 -Node: Auto-set460928 -Ref: Auto-set-Footnote-1477261 -Ref: Auto-set-Footnote-2477467 -Node: ARGC and ARGV477523 -Node: Pattern Action Summary481736 -Node: Arrays484166 -Node: Array Basics485495 -Node: Array Intro486339 -Ref: figure-array-elements488314 -Ref: Array Intro-Footnote-1491018 -Node: Reference to Elements491146 -Node: Assigning Elements493610 -Node: Array Example494101 -Node: Scanning an Array495860 -Node: Controlling Scanning498882 -Ref: Controlling Scanning-Footnote-1504281 -Node: Numeric Array Subscripts504597 -Node: Uninitialized Subscripts506781 -Node: Delete508400 -Ref: Delete-Footnote-1511152 -Node: Multidimensional511209 -Node: Multiscanning514304 -Node: Arrays of Arrays515895 -Node: Arrays Summary520662 -Node: Functions522755 -Node: Built-in523793 -Node: Calling Built-in524874 -Node: Numeric Functions526870 -Ref: Numeric Functions-Footnote-1530898 -Ref: Numeric Functions-Footnote-2531255 -Ref: Numeric Functions-Footnote-3531303 -Node: String Functions531575 -Ref: String Functions-Footnote-1555233 -Ref: String Functions-Footnote-2555361 -Ref: String Functions-Footnote-3555609 -Node: Gory Details555696 -Ref: table-sub-escapes557487 -Ref: table-sub-proposed559006 -Ref: table-posix-sub560369 -Ref: table-gensub-escapes561910 -Ref: Gory Details-Footnote-1562733 -Node: I/O Functions562887 -Ref: table-system-return-values569469 -Ref: I/O Functions-Footnote-1571449 -Ref: I/O Functions-Footnote-2571597 -Node: Time Functions571717 -Ref: Time Functions-Footnote-1582388 -Ref: Time Functions-Footnote-2582456 -Ref: Time Functions-Footnote-3582614 -Ref: Time Functions-Footnote-4582725 -Ref: Time Functions-Footnote-5582837 -Ref: Time Functions-Footnote-6583064 -Node: Bitwise Functions583330 -Ref: table-bitwise-ops583924 -Ref: Bitwise Functions-Footnote-1589957 -Ref: Bitwise Functions-Footnote-2590130 -Node: Type Functions590321 -Node: I18N Functions593072 -Node: User-defined594723 -Node: Definition Syntax595528 -Ref: Definition Syntax-Footnote-1601215 -Node: Function Example601286 -Ref: Function Example-Footnote-1604208 -Node: Function Caveats604230 -Node: Calling A Function604748 -Node: Variable Scope605706 -Node: Pass By Value/Reference608700 -Node: Return Statement612199 -Node: Dynamic Typing615178 -Node: Indirect Calls616108 -Ref: Indirect Calls-Footnote-1626360 -Node: Functions Summary626488 -Node: Library Functions629193 -Ref: Library Functions-Footnote-1632800 -Ref: Library Functions-Footnote-2632943 -Node: Library Names633114 -Ref: Library Names-Footnote-1636574 -Ref: Library Names-Footnote-2636797 -Node: General Functions636883 -Node: Strtonum Function637986 -Node: Assert Function641008 -Node: Round Function644334 -Node: Cliff Random Function645875 -Node: Ordinal Functions646891 -Ref: Ordinal Functions-Footnote-1649954 -Ref: Ordinal Functions-Footnote-2650206 -Node: Join Function650416 -Ref: Join Function-Footnote-1652186 -Node: Getlocaltime Function652386 -Node: Readfile Function656128 -Node: Shell Quoting658105 -Node: Data File Management659506 -Node: Filetrans Function660138 -Node: Rewind Function664234 -Node: File Checking666144 -Ref: File Checking-Footnote-1667478 -Node: Empty Files667679 -Node: Ignoring Assigns669658 -Node: Getopt Function671208 -Ref: Getopt Function-Footnote-1682677 -Node: Passwd Functions682877 -Ref: Passwd Functions-Footnote-1691716 -Node: Group Functions691804 -Ref: Group Functions-Footnote-1699702 -Node: Walking Arrays699909 -Node: Library Functions Summary702917 -Node: Library Exercises704323 -Node: Sample Programs704788 -Node: Running Examples705558 -Node: Clones706286 -Node: Cut Program707510 -Node: Egrep Program717439 -Ref: Egrep Program-Footnote-1724951 -Node: Id Program725061 -Node: Split Program728741 -Ref: Split Program-Footnote-1732200 -Node: Tee Program732329 -Node: Uniq Program735119 -Node: Wc Program742545 -Ref: Wc Program-Footnote-1746800 -Node: Miscellaneous Programs746894 -Node: Dupword Program748107 -Node: Alarm Program750137 -Node: Translate Program754992 -Ref: Translate Program-Footnote-1759557 -Node: Labels Program759827 -Ref: Labels Program-Footnote-1763178 -Node: Word Sorting763262 -Node: History Sorting767334 -Node: Extract Program769169 -Node: Simple Sed776699 -Node: Igawk Program779773 -Ref: Igawk Program-Footnote-1794104 -Ref: Igawk Program-Footnote-2794306 -Ref: Igawk Program-Footnote-3794428 -Node: Anagram Program794543 -Node: Signature Program797605 -Node: Programs Summary798852 -Node: Programs Exercises800066 -Ref: Programs Exercises-Footnote-1804195 -Node: Advanced Features804286 -Node: Nondecimal Data806276 -Node: Array Sorting807867 -Node: Controlling Array Traversal808567 -Ref: Controlling Array Traversal-Footnote-1816934 -Node: Array Sorting Functions817052 -Ref: Array Sorting Functions-Footnote-1822143 -Node: Two-way I/O822339 -Ref: Two-way I/O-Footnote-1828891 -Ref: Two-way I/O-Footnote-2829078 -Node: TCP/IP Networking829160 -Node: Profiling832278 -Ref: Profiling-Footnote-1840950 -Node: Advanced Features Summary841273 -Node: Internationalization843117 -Node: I18N and L10N844597 -Node: Explaining gettext845284 -Ref: Explaining gettext-Footnote-1851176 -Ref: Explaining gettext-Footnote-2851361 -Node: Programmer i18n851526 -Ref: Programmer i18n-Footnote-1856475 -Node: Translator i18n856524 -Node: String Extraction857318 -Ref: String Extraction-Footnote-1858450 -Node: Printf Ordering858536 -Ref: Printf Ordering-Footnote-1861322 -Node: I18N Portability861386 -Ref: I18N Portability-Footnote-1863842 -Node: I18N Example863905 -Ref: I18N Example-Footnote-1866711 -Node: Gawk I18N866784 -Node: I18N Summary867429 -Node: Debugger868770 -Node: Debugging869793 -Node: Debugging Concepts870234 -Node: Debugging Terms872043 -Node: Awk Debugging874618 -Node: Sample Debugging Session875524 -Node: Debugger Invocation876058 -Node: Finding The Bug877444 -Node: List of Debugger Commands883922 -Node: Breakpoint Control885255 -Node: Debugger Execution Control888949 -Node: Viewing And Changing Data892311 -Node: Execution Stack895685 -Node: Debugger Info897322 -Node: Miscellaneous Debugger Commands901393 -Node: Readline Support906481 -Node: Limitations907377 -Node: Debugging Summary909486 -Node: Arbitrary Precision Arithmetic910765 -Node: Computer Arithmetic912250 -Ref: table-numeric-ranges915841 -Ref: Computer Arithmetic-Footnote-1916563 -Node: Math Definitions916620 -Ref: table-ieee-formats919936 -Ref: Math Definitions-Footnote-1920539 -Node: MPFR features920644 -Node: FP Math Caution922362 -Ref: FP Math Caution-Footnote-1923434 -Node: Inexactness of computations923803 -Node: Inexact representation924763 -Node: Comparing FP Values926123 -Node: Errors accumulate927205 -Node: Getting Accuracy928638 -Node: Try To Round931348 -Node: Setting precision932247 -Ref: table-predefined-precision-strings932944 -Node: Setting the rounding mode934774 -Ref: table-gawk-rounding-modes935148 -Ref: Setting the rounding mode-Footnote-1938523 -Node: Arbitrary Precision Integers938702 -Ref: Arbitrary Precision Integers-Footnote-1941877 -Node: Checking for MPFR942026 -Node: POSIX Floating Point Problems943323 -Ref: POSIX Floating Point Problems-Footnote-1947194 -Node: Floating point summary947232 -Node: Dynamic Extensions949422 -Node: Extension Intro950975 -Node: Plugin License952241 -Node: Extension Mechanism Outline953038 -Ref: figure-load-extension953477 -Ref: figure-register-new-function955042 -Ref: figure-call-new-function956134 -Node: Extension API Description958196 -Node: Extension API Functions Introduction959838 -Node: General Data Types965378 -Ref: General Data Types-Footnote-1973739 -Node: Memory Allocation Functions974038 -Ref: Memory Allocation Functions-Footnote-1978246 -Node: Constructor Functions978345 -Node: Registration Functions981931 -Node: Extension Functions982616 -Node: Exit Callback Functions987831 -Node: Extension Version String989081 -Node: Input Parsers989744 -Node: Output Wrappers1002465 -Node: Two-way processors1006977 -Node: Printing Messages1009242 -Ref: Printing Messages-Footnote-11010413 -Node: Updating ERRNO1010566 -Node: Requesting Values1011305 -Ref: table-value-types-returned1012042 -Node: Accessing Parameters1012978 -Node: Symbol Table Access1014213 -Node: Symbol table by name1014725 -Node: Symbol table by cookie1016514 -Ref: Symbol table by cookie-Footnote-11020699 -Node: Cached values1020763 -Ref: Cached values-Footnote-11024299 -Node: Array Manipulation1024452 -Ref: Array Manipulation-Footnote-11025543 -Node: Array Data Types1025580 -Ref: Array Data Types-Footnote-11028238 -Node: Array Functions1028330 -Node: Flattening Arrays1032828 -Node: Creating Arrays1039804 -Node: Redirection API1044573 -Node: Extension API Variables1047406 -Node: Extension Versioning1048117 -Ref: gawk-api-version1048546 -Node: Extension GMP/MPFR Versioning1050274 -Node: Extension API Informational Variables1051902 -Node: Extension API Boilerplate1052975 -Node: Changes from API V11056949 -Node: Finding Extensions1058521 -Node: Extension Example1059080 -Node: Internal File Description1059878 -Node: Internal File Ops1063958 -Ref: Internal File Ops-Footnote-11075358 -Node: Using Internal File Ops1075498 -Ref: Using Internal File Ops-Footnote-11077881 -Node: Extension Samples1078155 -Node: Extension Sample File Functions1079684 -Node: Extension Sample Fnmatch1087333 -Node: Extension Sample Fork1088820 -Node: Extension Sample Inplace1090038 -Node: Extension Sample Ord1093255 -Node: Extension Sample Readdir1094091 -Ref: table-readdir-file-types1094980 -Node: Extension Sample Revout1095785 -Node: Extension Sample Rev2way1096374 -Node: Extension Sample Read write array1097114 -Node: Extension Sample Readfile1099056 -Node: Extension Sample Time1100151 -Node: Extension Sample API Tests1101499 -Node: gawkextlib1101991 -Node: Extension summary1104447 -Node: Extension Exercises1108149 -Node: Language History1109647 -Node: V7/SVR3.11111303 -Node: SVR41113455 -Node: POSIX1114889 -Node: BTL1116269 -Node: POSIX/GNU1116998 -Node: Feature History1122776 -Node: Common Extensions1138635 -Node: Ranges and Locales1139918 -Ref: Ranges and Locales-Footnote-11144534 -Ref: Ranges and Locales-Footnote-21144561 -Ref: Ranges and Locales-Footnote-31144796 -Node: Contributors1145017 -Node: History summary1150962 -Node: Installation1152342 -Node: Gawk Distribution1153286 -Node: Getting1153770 -Node: Extracting1154733 -Node: Distribution contents1156371 -Node: Unix Installation1162851 -Node: Quick Installation1163533 -Node: Shell Startup Files1165947 -Node: Additional Configuration Options1167036 -Node: Configuration Philosophy1168897 -Node: Non-Unix Installation1171266 -Node: PC Installation1171726 -Node: PC Binary Installation1172564 -Node: PC Compiling1172999 -Node: PC Using1174116 -Node: Cygwin1177161 -Node: MSYS1177931 -Node: VMS Installation1178432 -Node: VMS Compilation1179223 -Ref: VMS Compilation-Footnote-11180452 -Node: VMS Dynamic Extensions1180510 -Node: VMS Installation Details1182195 -Node: VMS Running1184448 -Node: VMS GNV1188727 -Node: VMS Old Gawk1189462 -Node: Bugs1189933 -Node: Bug address1190596 -Node: Usenet1193388 -Node: Maintainers1194165 -Node: Other Versions1195426 -Node: Installation summary1202188 -Node: Notes1203390 -Node: Compatibility Mode1204255 -Node: Additions1205037 -Node: Accessing The Source1205962 -Node: Adding Code1207399 -Node: New Ports1213618 -Node: Derived Files1218106 -Ref: Derived Files-Footnote-11223752 -Ref: Derived Files-Footnote-21223787 -Ref: Derived Files-Footnote-31224385 -Node: Future Extensions1224499 -Node: Implementation Limitations1225157 -Node: Extension Design1226340 -Node: Old Extension Problems1227494 -Ref: Old Extension Problems-Footnote-11229012 -Node: Extension New Mechanism Goals1229069 -Ref: Extension New Mechanism Goals-Footnote-11232433 -Node: Extension Other Design Decisions1232622 -Node: Extension Future Growth1234735 -Node: Old Extension Mechanism1235571 -Node: Notes summary1237334 -Node: Basic Concepts1238516 -Node: Basic High Level1239197 -Ref: figure-general-flow1239479 -Ref: figure-process-flow1240164 -Ref: Basic High Level-Footnote-11243465 -Node: Basic Data Typing1243650 -Node: Glossary1246978 -Node: Copying1278814 -Node: GNU Free Documentation License1316353 -Node: Index1341471 +Ref: Close Files And Pipes-Footnote-1325357 +Ref: Close Files And Pipes-Footnote-2325505 +Node: Nonfatal325657 +Node: Output Summary327995 +Node: Output Exercises329217 +Node: Expressions329896 +Node: Values331084 +Node: Constants331762 +Node: Scalar Constants332453 +Ref: Scalar Constants-Footnote-1333317 +Node: Nondecimal-numbers333567 +Node: Regexp Constants336568 +Node: Using Constant Regexps337094 +Node: Standard Regexp Constants337716 +Node: Strong Regexp Constants340904 +Node: Variables343862 +Node: Using Variables344519 +Node: Assignment Options346429 +Node: Conversion348302 +Node: Strings And Numbers348826 +Ref: Strings And Numbers-Footnote-1351889 +Node: Locale influences conversions351998 +Ref: table-locale-affects354756 +Node: All Operators355374 +Node: Arithmetic Ops356003 +Node: Concatenation358509 +Ref: Concatenation-Footnote-1361356 +Node: Assignment Ops361463 +Ref: table-assign-ops366454 +Node: Increment Ops367767 +Node: Truth Values and Conditions371227 +Node: Truth Values372301 +Node: Typing and Comparison373349 +Node: Variable Typing374169 +Ref: Variable Typing-Footnote-1380632 +Ref: Variable Typing-Footnote-2380704 +Node: Comparison Operators380781 +Ref: table-relational-ops381200 +Node: POSIX String Comparison384695 +Ref: POSIX String Comparison-Footnote-1386390 +Ref: POSIX String Comparison-Footnote-2386529 +Node: Boolean Ops386613 +Ref: Boolean Ops-Footnote-1391095 +Node: Conditional Exp391187 +Node: Function Calls392923 +Node: Precedence396800 +Node: Locales400459 +Node: Expressions Summary402091 +Node: Patterns and Actions404664 +Node: Pattern Overview405784 +Node: Regexp Patterns407461 +Node: Expression Patterns408003 +Node: Ranges411784 +Node: BEGIN/END414892 +Node: Using BEGIN/END415653 +Ref: Using BEGIN/END-Footnote-1418389 +Node: I/O And BEGIN/END418495 +Node: BEGINFILE/ENDFILE420809 +Node: Empty423722 +Node: Using Shell Variables424039 +Node: Action Overview426313 +Node: Statements428638 +Node: If Statement430486 +Node: While Statement431981 +Node: Do Statement434009 +Node: For Statement435157 +Node: Switch Statement438328 +Node: Break Statement440714 +Node: Continue Statement442806 +Node: Next Statement444633 +Node: Nextfile Statement447016 +Node: Exit Statement449668 +Node: Built-in Variables452071 +Node: User-modified453204 +Node: Auto-set460971 +Ref: Auto-set-Footnote-1477304 +Ref: Auto-set-Footnote-2477510 +Node: ARGC and ARGV477566 +Node: Pattern Action Summary481779 +Node: Arrays484209 +Node: Array Basics485538 +Node: Array Intro486382 +Ref: figure-array-elements488357 +Ref: Array Intro-Footnote-1491061 +Node: Reference to Elements491189 +Node: Assigning Elements493653 +Node: Array Example494144 +Node: Scanning an Array495903 +Node: Controlling Scanning498925 +Ref: Controlling Scanning-Footnote-1504324 +Node: Numeric Array Subscripts504640 +Node: Uninitialized Subscripts506824 +Node: Delete508443 +Ref: Delete-Footnote-1511195 +Node: Multidimensional511252 +Node: Multiscanning514347 +Node: Arrays of Arrays515938 +Node: Arrays Summary520705 +Node: Functions522798 +Node: Built-in523836 +Node: Calling Built-in524917 +Node: Numeric Functions526913 +Ref: Numeric Functions-Footnote-1530941 +Ref: Numeric Functions-Footnote-2531298 +Ref: Numeric Functions-Footnote-3531346 +Node: String Functions531618 +Ref: String Functions-Footnote-1555276 +Ref: String Functions-Footnote-2555404 +Ref: String Functions-Footnote-3555652 +Node: Gory Details555739 +Ref: table-sub-escapes557530 +Ref: table-sub-proposed559049 +Ref: table-posix-sub560412 +Ref: table-gensub-escapes561953 +Ref: Gory Details-Footnote-1562776 +Node: I/O Functions562930 +Ref: table-system-return-values569398 +Ref: I/O Functions-Footnote-1571378 +Ref: I/O Functions-Footnote-2571526 +Node: Time Functions571646 +Ref: Time Functions-Footnote-1582317 +Ref: Time Functions-Footnote-2582385 +Ref: Time Functions-Footnote-3582543 +Ref: Time Functions-Footnote-4582654 +Ref: Time Functions-Footnote-5582766 +Ref: Time Functions-Footnote-6582993 +Node: Bitwise Functions583259 +Ref: table-bitwise-ops583853 +Ref: Bitwise Functions-Footnote-1589898 +Ref: Bitwise Functions-Footnote-2590071 +Node: Type Functions590262 +Node: I18N Functions593013 +Node: User-defined594664 +Node: Definition Syntax595469 +Ref: Definition Syntax-Footnote-1601156 +Node: Function Example601227 +Ref: Function Example-Footnote-1604149 +Node: Function Caveats604171 +Node: Calling A Function604689 +Node: Variable Scope605647 +Node: Pass By Value/Reference608641 +Node: Return Statement612140 +Node: Dynamic Typing615119 +Node: Indirect Calls616049 +Ref: Indirect Calls-Footnote-1626301 +Node: Functions Summary626429 +Node: Library Functions629134 +Ref: Library Functions-Footnote-1632741 +Ref: Library Functions-Footnote-2632884 +Node: Library Names633055 +Ref: Library Names-Footnote-1636515 +Ref: Library Names-Footnote-2636738 +Node: General Functions636824 +Node: Strtonum Function637927 +Node: Assert Function640949 +Node: Round Function644275 +Node: Cliff Random Function645815 +Node: Ordinal Functions646831 +Ref: Ordinal Functions-Footnote-1649894 +Ref: Ordinal Functions-Footnote-2650146 +Node: Join Function650356 +Ref: Join Function-Footnote-1652126 +Node: Getlocaltime Function652326 +Node: Readfile Function656068 +Node: Shell Quoting658045 +Node: Data File Management659446 +Node: Filetrans Function660078 +Node: Rewind Function664174 +Node: File Checking666084 +Ref: File Checking-Footnote-1667418 +Node: Empty Files667619 +Node: Ignoring Assigns669598 +Node: Getopt Function671148 +Ref: Getopt Function-Footnote-1682617 +Node: Passwd Functions682817 +Ref: Passwd Functions-Footnote-1691656 +Node: Group Functions691744 +Ref: Group Functions-Footnote-1699642 +Node: Walking Arrays699849 +Node: Library Functions Summary702857 +Node: Library Exercises704263 +Node: Sample Programs704728 +Node: Running Examples705498 +Node: Clones706226 +Node: Cut Program707450 +Node: Egrep Program717379 +Ref: Egrep Program-Footnote-1724891 +Node: Id Program725001 +Node: Split Program728681 +Ref: Split Program-Footnote-1732139 +Node: Tee Program732268 +Node: Uniq Program735058 +Node: Wc Program742484 +Ref: Wc Program-Footnote-1746739 +Node: Miscellaneous Programs746833 +Node: Dupword Program748046 +Node: Alarm Program750076 +Node: Translate Program754931 +Ref: Translate Program-Footnote-1759496 +Node: Labels Program759766 +Ref: Labels Program-Footnote-1763117 +Node: Word Sorting763201 +Node: History Sorting767273 +Node: Extract Program769108 +Node: Simple Sed776638 +Node: Igawk Program779712 +Ref: Igawk Program-Footnote-1794043 +Ref: Igawk Program-Footnote-2794245 +Ref: Igawk Program-Footnote-3794367 +Node: Anagram Program794482 +Node: Signature Program797544 +Node: Programs Summary798791 +Node: Programs Exercises800005 +Ref: Programs Exercises-Footnote-1804134 +Node: Advanced Features804225 +Node: Nondecimal Data806215 +Node: Array Sorting807806 +Node: Controlling Array Traversal808506 +Ref: Controlling Array Traversal-Footnote-1816874 +Node: Array Sorting Functions816992 +Ref: Array Sorting Functions-Footnote-1822083 +Node: Two-way I/O822279 +Ref: Two-way I/O-Footnote-1828831 +Ref: Two-way I/O-Footnote-2829018 +Node: TCP/IP Networking829100 +Node: Profiling832218 +Ref: Profiling-Footnote-1840890 +Node: Advanced Features Summary841213 +Node: Internationalization843057 +Node: I18N and L10N844537 +Node: Explaining gettext845224 +Ref: Explaining gettext-Footnote-1851116 +Ref: Explaining gettext-Footnote-2851301 +Node: Programmer i18n851466 +Ref: Programmer i18n-Footnote-1856415 +Node: Translator i18n856464 +Node: String Extraction857258 +Ref: String Extraction-Footnote-1858390 +Node: Printf Ordering858476 +Ref: Printf Ordering-Footnote-1861262 +Node: I18N Portability861326 +Ref: I18N Portability-Footnote-1863782 +Node: I18N Example863845 +Ref: I18N Example-Footnote-1866651 +Node: Gawk I18N866724 +Node: I18N Summary867369 +Node: Debugger868710 +Node: Debugging869733 +Node: Debugging Concepts870174 +Node: Debugging Terms871983 +Node: Awk Debugging874558 +Node: Sample Debugging Session875464 +Node: Debugger Invocation875998 +Node: Finding The Bug877384 +Node: List of Debugger Commands883862 +Node: Breakpoint Control885195 +Node: Debugger Execution Control888889 +Node: Viewing And Changing Data892251 +Node: Execution Stack895625 +Node: Debugger Info897262 +Node: Miscellaneous Debugger Commands901333 +Node: Readline Support906395 +Node: Limitations907291 +Node: Debugging Summary909400 +Node: Arbitrary Precision Arithmetic910679 +Node: Computer Arithmetic912164 +Ref: table-numeric-ranges915930 +Ref: table-floating-point-ranges916423 +Ref: Computer Arithmetic-Footnote-1917081 +Node: Math Definitions917138 +Ref: table-ieee-formats920454 +Ref: Math Definitions-Footnote-1921057 +Node: MPFR features921162 +Node: FP Math Caution922880 +Ref: FP Math Caution-Footnote-1923952 +Node: Inexactness of computations924321 +Node: Inexact representation925281 +Node: Comparing FP Values926641 +Node: Errors accumulate927723 +Node: Getting Accuracy929156 +Node: Try To Round931866 +Node: Setting precision932765 +Ref: table-predefined-precision-strings933462 +Node: Setting the rounding mode935292 +Ref: table-gawk-rounding-modes935666 +Ref: Setting the rounding mode-Footnote-1939041 +Node: Arbitrary Precision Integers939220 +Ref: Arbitrary Precision Integers-Footnote-1942395 +Node: Checking for MPFR942544 +Node: POSIX Floating Point Problems943841 +Ref: POSIX Floating Point Problems-Footnote-1947712 +Node: Floating point summary947750 +Node: Dynamic Extensions949940 +Node: Extension Intro951493 +Node: Plugin License952759 +Node: Extension Mechanism Outline953556 +Ref: figure-load-extension953995 +Ref: figure-register-new-function955560 +Ref: figure-call-new-function956652 +Node: Extension API Description958714 +Node: Extension API Functions Introduction960356 +Node: General Data Types965896 +Ref: General Data Types-Footnote-1974257 +Node: Memory Allocation Functions974556 +Ref: Memory Allocation Functions-Footnote-1978766 +Node: Constructor Functions978865 +Node: Registration Functions982451 +Node: Extension Functions983136 +Node: Exit Callback Functions988351 +Node: Extension Version String989601 +Node: Input Parsers990264 +Node: Output Wrappers1002985 +Node: Two-way processors1007497 +Node: Printing Messages1009762 +Ref: Printing Messages-Footnote-11010933 +Node: Updating ERRNO1011086 +Node: Requesting Values1011825 +Ref: table-value-types-returned1012562 +Node: Accessing Parameters1013498 +Node: Symbol Table Access1014733 +Node: Symbol table by name1015245 +Node: Symbol table by cookie1017034 +Ref: Symbol table by cookie-Footnote-11021219 +Node: Cached values1021283 +Ref: Cached values-Footnote-11024819 +Node: Array Manipulation1024972 +Ref: Array Manipulation-Footnote-11026063 +Node: Array Data Types1026100 +Ref: Array Data Types-Footnote-11028758 +Node: Array Functions1028850 +Node: Flattening Arrays1033348 +Node: Creating Arrays1040324 +Node: Redirection API1045091 +Node: Extension API Variables1047924 +Node: Extension Versioning1048635 +Ref: gawk-api-version1049064 +Node: Extension GMP/MPFR Versioning1050795 +Node: Extension API Informational Variables1052423 +Node: Extension API Boilerplate1053496 +Node: Changes from API V11057470 +Node: Finding Extensions1059042 +Node: Extension Example1059601 +Node: Internal File Description1060399 +Node: Internal File Ops1064479 +Ref: Internal File Ops-Footnote-11075830 +Node: Using Internal File Ops1075970 +Ref: Using Internal File Ops-Footnote-11078353 +Node: Extension Samples1078627 +Node: Extension Sample File Functions1080156 +Node: Extension Sample Fnmatch1087805 +Node: Extension Sample Fork1089292 +Node: Extension Sample Inplace1090510 +Node: Extension Sample Ord1093727 +Node: Extension Sample Readdir1094563 +Ref: table-readdir-file-types1095452 +Node: Extension Sample Revout1096257 +Node: Extension Sample Rev2way1096846 +Node: Extension Sample Read write array1097586 +Node: Extension Sample Readfile1099528 +Node: Extension Sample Time1100623 +Node: Extension Sample API Tests1101971 +Node: gawkextlib1102463 +Node: Extension summary1104919 +Node: Extension Exercises1108621 +Node: Language History1110119 +Node: V7/SVR3.11111775 +Node: SVR41113927 +Node: POSIX1115361 +Node: BTL1116741 +Node: POSIX/GNU1117470 +Node: Feature History1123248 +Node: Common Extensions1139107 +Node: Ranges and Locales1140390 +Ref: Ranges and Locales-Footnote-11145006 +Ref: Ranges and Locales-Footnote-21145033 +Ref: Ranges and Locales-Footnote-31145268 +Node: Contributors1145489 +Node: History summary1151434 +Node: Installation1152814 +Node: Gawk Distribution1153758 +Node: Getting1154242 +Node: Extracting1155205 +Node: Distribution contents1156843 +Node: Unix Installation1163323 +Node: Quick Installation1164005 +Node: Shell Startup Files1166419 +Node: Additional Configuration Options1167508 +Node: Configuration Philosophy1169369 +Node: Non-Unix Installation1171738 +Node: PC Installation1172198 +Node: PC Binary Installation1173036 +Node: PC Compiling1173471 +Node: PC Using1174588 +Node: Cygwin1177633 +Node: MSYS1178403 +Node: VMS Installation1178904 +Node: VMS Compilation1179695 +Ref: VMS Compilation-Footnote-11180924 +Node: VMS Dynamic Extensions1180982 +Node: VMS Installation Details1182667 +Node: VMS Running1184920 +Node: VMS GNV1189199 +Node: VMS Old Gawk1189934 +Node: Bugs1190405 +Node: Bug address1191068 +Node: Usenet1193860 +Node: Maintainers1194637 +Node: Other Versions1195898 +Node: Installation summary1202660 +Node: Notes1203862 +Node: Compatibility Mode1204727 +Node: Additions1205509 +Node: Accessing The Source1206434 +Node: Adding Code1207871 +Node: New Ports1214090 +Node: Derived Files1218578 +Ref: Derived Files-Footnote-11224224 +Ref: Derived Files-Footnote-21224259 +Ref: Derived Files-Footnote-31224857 +Node: Future Extensions1224971 +Node: Implementation Limitations1225629 +Node: Extension Design1226812 +Node: Old Extension Problems1227966 +Ref: Old Extension Problems-Footnote-11229484 +Node: Extension New Mechanism Goals1229541 +Ref: Extension New Mechanism Goals-Footnote-11232905 +Node: Extension Other Design Decisions1233094 +Node: Extension Future Growth1235207 +Node: Old Extension Mechanism1236043 +Node: Notes summary1237806 +Node: Basic Concepts1238988 +Node: Basic High Level1239669 +Ref: figure-general-flow1239951 +Ref: figure-process-flow1240636 +Ref: Basic High Level-Footnote-11243937 +Node: Basic Data Typing1244122 +Node: Glossary1247450 +Node: Copying1279288 +Node: GNU Free Documentation License1316827 +Node: Index1341945 End Tag Table diff --git a/doc/gawk.texi b/doc/gawk.texi index 54c4f913..dec51695 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -1527,9 +1527,11 @@ default @command{awk} utility. A more modern @command{awk} lives in if you try the test program: @example +@group $ @kbd{awk 1 /dev/null} @error{} awk: syntax error near line 1 @error{} awk: bailing out near line 1 +@end group @end example @noindent @@ -2991,10 +2993,12 @@ for the single- and double-quote characters, like so: @example +@group $ @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 <"> +@end group @end example @noindent @@ -3266,8 +3270,10 @@ action---so it uses the default action, printing the record. Print the length of the longest input line: @example +@group awk '@{ if (length($0) > max) max = length($0) @} END @{ print max @}' data +@end group @end example The code associated with @code{END} executes after all @@ -3584,11 +3590,13 @@ starts a comment, it ignores @emph{everything} on the rest of the line. For example: @example +@group $ @kbd{gawk 'BEGIN @{ print "dont panic" # a friendly \} > @kbd{ BEGIN rule} > @kbd{@}'} @error{} gawk: cmd. line:2: BEGIN rule @error{} gawk: cmd. line:2: ^ syntax error +@end group @end example @noindent @@ -4785,10 +4793,12 @@ The files to be included may be nested; e.g., given a third script, namely @file{test3}: @example +@group @@include "test2" BEGIN @{ print "This is script test3." @} +@end group @end example @noindent @@ -4875,8 +4885,10 @@ $ @kbd{gawk '@@load "ordchr"; BEGIN @{print chr(65)@}'} This is equivalent to the following example: @example +@group $ @kbd{gawk -lordchr 'BEGIN @{print chr(65)@}'} @print{} A +@end group @end example @noindent @@ -6499,8 +6511,10 @@ with each @samp{u} changed to a newline. Here are the results of running the program on @file{mail-list}: @example +@group $ @kbd{awk 'BEGIN @{ RS = "u" @}} > @kbd{@{ print $0 @}' mail-list} +@end group @print{} Amelia 555-5553 amelia.zodiac @print{} sq @print{} e@@gmail.com F @@ -6657,9 +6671,11 @@ matches either a newline or a series of one or more uppercase letters with optional leading and/or trailing whitespace: @example +@group $ @kbd{echo record 1 AAAA record 2 BBBB record 3 |} > @kbd{gawk 'BEGIN @{ RS = "\n|( *[[:upper:]]+ *)" @}} > @kbd{@{ print "Record =", $0,"and RT = [" RT "]" @}'} +@end group @print{} Record = record 1 and RT = [ AAAA ] @print{} Record = record 2 and RT = [ BBBB ] @print{} Record = record 3 and RT = [ @@ -7100,8 +7116,10 @@ values of the fields and @code{OFS}. To do this, use the seemingly innocuous assignment: @example +@group $1 = $1 # force record to be reconstituted print $0 # or whatever else with $0 +@end group @end example @noindent @@ -7997,16 +8015,20 @@ Putting this to use, here is a simple program to parse the data: @example @c file eg/misc/simple-csv.awk +@group BEGIN @{ FPAT = "([^,]+)|(\"[^\"]+\")" @} +@end group +@group @{ print "NF = ", NF for (i = 1; i <= NF; i++) @{ printf("$%d = <%s>\n", i, $i) @} @} +@end group @c endfile @end example @@ -8447,6 +8469,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 +@group @{ if ((getline tmp) > 0) @{ print tmp @@ -8454,6 +8477,7 @@ The following example swaps every two lines of input: @} else print $0 @} +@end group @end example @noindent @@ -8596,6 +8620,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 +@group @{ if ($1 == "@@execute") @{ tmp = substr($0, 10) # Remove "@@execute" @@ -8605,6 +8630,7 @@ produced by running the rest of the line as a shell command: @} else print @} +@end group @end example @noindent @@ -8908,12 +8934,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 +@group Service = "/inet/tcp/0/localhost/daytime" PROCINFO[Service, "READ_TIMEOUT"] = 100 if ((Service |& getline) > 0) print $0 else if (ERRNO != "") print ERRNO +@end group @end example Here is how to read interactively from the user@footnote{This assumes @@ -9255,10 +9283,12 @@ newlines: @end ifnotinfo @example +@group $ @kbd{awk 'BEGIN @{ print "line one\nline two\nline three" @}'} @print{} line one @print{} line two @print{} line three +@end group @end example @cindex fields, printing @@ -9510,12 +9540,14 @@ The output separator variables @code{OFS} and @code{ORS} have no effect on @code{printf} statements. For example: @example +@group $ @kbd{awk 'BEGIN @{} > @kbd{ORS = "\nOUCH!\n"; OFS = "+"} > @kbd{msg = "Don\47t Panic!"} > @kbd{printf "%s\n", msg} > @kbd{@}'} @print{} Don't Panic! +@end group @end example @noindent @@ -10038,9 +10070,11 @@ alone for now and let's hope no-one notices. @end ignore @example +@group awk '@{ print $1 > "names.unsorted" command = "sort -r > names.sorted" print $1 | command @}' mail-list +@end group @end example The unsorted list is written with an ordinary redirection, while @@ -10375,7 +10409,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 @@ -10474,10 +10508,14 @@ it is good practice to use a variable to store the @value{FN} or command. The previous example becomes the following: @example +@group sortcom = "sort -r names" sortcom | getline foo +@end group +@group @dots{} close(sortcom) +@end group @end example @noindent @@ -10625,7 +10663,7 @@ if it fails. @float Table,table-close-pipe-return-values @caption{Return values from @code{close()} of a pipe} -@multitable @columnfractions .40 .60 +@multitable @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 @@ -10691,7 +10729,7 @@ if it fails. @float Table,table-close-pipe-return-values @caption{Return values from @code{close()} of a pipe} -@multitable @columnfractions .40 .60 +@multitable @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 @@ -10721,7 +10759,8 @@ disk) is a fatal error. @example $ @kbd{gawk 'BEGIN @{ print "hi" > "/no/such/file" @}'} -@error{} gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No such file or directory) +@error{} gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No +@error{} such file or directory) @end example @command{gawk} makes it possible to detect that an error has @@ -11181,6 +11220,7 @@ confusion can arise when attempting to use regexp constants as arguments to user-defined functions (@pxref{User-defined}). For example: @example +@group function mysub(pat, repl, str, global) @{ if (global) @@ -11189,13 +11229,16 @@ function mysub(pat, repl, str, global) sub(pat, repl, str) return str @} +@end group +@group @{ @dots{} text = "hi! hi yourself!" mysub(/hi/, "howdy", text, 1) @dots{} @} +@end group @end example @c @cindex automatic warnings @@ -11443,8 +11486,10 @@ is performed. If numeric values appear in string concatenation, they are converted to strings. Consider the following: @example +@group two = 2; three = 3 print (two three) + 4 +@end group @end example @noindent @@ -11946,10 +11991,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 +@group foo = 1 print foo +@end group +@group foo = "bar" print foo +@end group @end example @noindent @@ -12021,16 +12070,20 @@ righthand expression. For example: @cindex Rankin, Pat @example +@group # Thanks to Pat Rankin for this example BEGIN @{ foo[rand()] += 5 for (x in foo) print x, foo[x] +@end group +@group bar[rand()] = bar[rand()] + 5 for (x in bar) print x, bar[x] @} +@end group @end example @cindex operators, assignment, evaluation order @@ -12816,10 +12869,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 +@group if (a = b) # oops! should be a == b @dots{} else @dots{} +@end group @end example @noindent @@ -13771,8 +13826,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 +@group @print{} Martin 555-6480 martin.codicibus@@hotmail.com A @print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R +@end group @end example @cindex @code{BEGIN} pattern, Boolean patterns and @@ -14163,10 +14220,12 @@ the variable's value into the program inside the script. For example, consider the following program: @example +@group printf "Enter search pattern: " read pattern awk "/$pattern/ "'@{ nmatches++ @} END @{ print nmatches, "found" @}' /path/to/data +@end group @end example @noindent @@ -14355,10 +14414,12 @@ the null string; otherwise, the condition is true. Refer to the following: @example +@group if (x % 2 == 0) print "x is even" else print "x is odd" +@end group @end example In this example, if the expression @samp{x % 2 == 0} is true (i.e., @@ -14680,6 +14741,7 @@ finds the smallest divisor of any integer, and also identifies prime numbers: @example +@group # find smallest divisor of num @{ num = $1 @@ -14687,11 +14749,14 @@ numbers: if (num % divisor == 0) break @} +@end group +@group if (num % divisor == 0) printf "Smallest divisor of %d is %d\n", num, divisor else printf "%d is prime\n", num @} +@end group @end example When the remainder is zero in the first @code{if} statement, @command{awk} @@ -14999,14 +15064,18 @@ using an @code{exit} statement with a nonzero argument, as shown in the following example: @example +@group BEGIN @{ if (("date" | getline date_now) <= 0) @{ print "Can't get system date" > "/dev/stderr" exit 1 @} +@end group +@group print "current date is", date_now close("date") @} +@end group @end example @quotation NOTE @@ -15304,6 +15373,7 @@ Unlike most @command{awk} arrays, In the following example: @example +@group $ @kbd{awk 'BEGIN @{} > @kbd{for (i = 0; i < ARGC; i++)} > @kbd{print ARGV[i]} @@ -15311,6 +15381,7 @@ $ @kbd{awk 'BEGIN @{} @print{} awk @print{} inventory-shipped @print{} mail-list +@end group @end example @noindent @@ -15735,12 +15806,14 @@ points out that it effectively gives @command{awk} data pointers. Consider his example: @example +@group # Indirect multiply of any variable by amount, return result function multiply(variable, amount) @{ return SYMTAB[variable] *= amount @} +@end group @end example @noindent @@ -15858,6 +15931,7 @@ presented the following program describing the information contained in @code{AR and @code{ARGV}: @example +@group $ @kbd{awk 'BEGIN @{} > @kbd{for (i = 0; i < ARGC; i++)} > @kbd{print ARGV[i]} @@ -15865,6 +15939,7 @@ $ @kbd{awk 'BEGIN @{} @print{} awk @print{} inventory-shipped @print{} mail-list +@end group @end example @noindent @@ -16461,8 +16536,10 @@ For example, this statement tests whether the array @code{frequencies} contains the index @samp{2}: @example +@group if (2 in frequencies) print "Subscript 2 is present." +@end group @end example Note that this is @emph{not} a test of whether the array @@ -16472,8 +16549,10 @@ There is no way to do that except to scan all the elements. Also, this (incorrect) alternative does: @example +@group if (frequencies[2] != "") print "Subscript 2 is present." +@end group @end example @node Assigning Elements @@ -16530,6 +16609,7 @@ all the lines. When this program is run with the following input: @example +@group @c file eg/misc/arraymax.data 5 I am the Five man 2 Who are you? The new number two! @@ -16537,17 +16617,20 @@ When this program is run with the following input: 1 Who is number one? 3 I three you. @c endfile +@end group @end example @noindent Its output is: @example +@group 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 +@end group @end example If a line number is repeated, the last line with a given number overrides @@ -16556,11 +16639,13 @@ Gaps in the line numbers can be handled with an easy improvement to the program's @code{END} rule, as follows: @example +@group END @{ for (x = 1; x <= max; x++) if (x in arr) print arr[x] @} +@end group @end example @node Scanning an Array @@ -16580,8 +16665,10 @@ So @command{awk} has a special kind of @code{for} statement for scanning an array: @example +@group for (@var{var} in @var{array}) @var{body} +@end group @end example @noindent @@ -16602,12 +16689,15 @@ such words. for more information on the built-in function @code{length()}. @example +@group # Record a 1 for each word that is used at least once @{ for (i = 1; i <= NF; i++) used[$i] = 1 @} +@end group +@group # Find number of distinct words more than 10 characters long END @{ for (x in used) @{ @@ -16618,6 +16708,7 @@ END @{ @} print num_long_words, "words longer than 10 characters" @} +@end group @end example @noindent @@ -17005,9 +17096,11 @@ same as assigning it a null value (the empty string, @code{""}). For example: @example +@group foo[4] = "" if (4 in foo) print "This is printed, even though foo[4] is empty" +@end group @end example @cindex lint checking, array elements @@ -17162,22 +17255,26 @@ END @{ When given the input: @example +@group 1 2 3 4 5 6 2 3 4 5 6 1 3 4 5 6 1 2 4 5 6 1 2 3 +@end group @end example @noindent the program produces the following output: @example +@group 4 3 2 1 5 4 3 2 6 5 4 3 1 6 5 4 2 1 6 5 3 2 1 6 +@end group @end example @node Multiscanning @@ -17357,15 +17454,19 @@ you can often devise workarounds using control statements. For example, the following code prints the elements of our main array @code{a}: @example +@group for (i in a) @{ for (j in a[i]) @{ if (j == 3) @{ for (k in a[i][j]) print a[i][j][k] +@end group +@group @} else print a[i][j] @} @} +@end group @end example @noindent @@ -17815,9 +17916,11 @@ asort(a) results in the following contents of @code{a}: @example +@group a[1] = "cul" a[2] = "de" a[3] = "sac" +@end group @end example The @code{asorti()} function works similarly to @code{asort()}; however, @@ -18906,6 +19009,9 @@ 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. +@c end the table to let the sidebar take up the full width of the page. +@end table + @cindex sidebar, Interactive Versus Noninteractive Buffering @ifdocbook @docbook @@ -19006,6 +19112,7 @@ it is all buffered and sent down the pipe to @command{cat} in one shot. @end cartouche @end ifnotdocbook +@table @asis @item @code{system(@var{command})} @cindexawkfunc{system} @cindex invoke shell command @@ -19798,7 +19905,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) @{ @@ -19820,7 +19927,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) @{ @@ -19861,7 +19968,8 @@ $ @kbd{gawk -f testbits.awk} @print{} 123 = 01111011 @print{} 0123 = 01010011 @print{} 0x99 = 10011001 -@print{} compl(0x99) = 0x3fffffffffff66 = 00111111111111111111111111111111111111111111111101100110 +@print{} compl(0x99) = 0x3fffffffffff66 = +@print{} 00111111111111111111111111111111111111111111111101100110 @print{} lshift(0x99, 2) = 0x264 = 0000001001100100 @print{} rshift(0x99, 2) = 0x26 = 00100110 @end example @@ -20200,10 +20308,12 @@ entire program before starting to execute any of it. The definition of a function named @var{name} looks like this: @display +@group @code{function} @var{name}@code{(}[@var{parameter-list}]@code{)} @code{@{} @var{body-of-function} @code{@}} +@end group @end display @cindex names, functions @@ -20371,11 +20481,13 @@ This function deletes all the elements in an array (recall that the extra whitespace signifies the start of the local variable list): @example +@group function delarray(a, i) @{ for (i in a) delete a[i] @} +@end group @end example When working with arrays, it is often necessary to delete all the elements @@ -20582,10 +20694,12 @@ In addition, recursive calls create new arrays. Consider this example: @example +@group function some_func(p1, a) @{ if (p1++ > 3) return +@end group a[p1] = p1 @@ -20649,12 +20763,14 @@ this has no effect on any other variables. Thus, if @code{myfunc()} does this: @example +@group function myfunc(str) @{ print str str = "zzz" print str @} +@end group @end example @noindent @@ -20810,11 +20926,13 @@ function maxelt(vec, i, ret) return ret @} +@group # Load all fields of each record into nums. @{ for(i = 1; i <= NF; i++) nums[NR, i] = $i @} +@end group END @{ print maxelt(nums) @@ -21108,12 +21226,14 @@ first thing to do is write some comparison functions: @example @c file eg/prog/indirectcall.awk +@group # num_lt --- do a numeric less than comparison function num_lt(left, right) @{ return ((left + 0) < (right + 0)) @} +@end group # num_ge --- do a numeric greater than or equal to comparison @@ -21162,19 +21282,23 @@ names of the two comparison functions: @example @c file eg/prog/indirectcall.awk +@group # sort --- sort the data in ascending order and return it as a string function sort(first, last) @{ return do_sort(first, last, "num_lt") @} +@end group +@group # rsort --- sort the data in descending order and return it as a string function rsort(first, last) @{ return do_sort(first, last, "num_ge") @} +@end group @c endfile @end example @@ -21674,6 +21798,7 @@ been true but was not, and then it kills the program. In C, using @code{assert()} looks this: @example +@group #include <assert.h> int myfunc(int a, double b) @@ -21681,6 +21806,7 @@ int myfunc(int a, double b) assert(a <= 5 && b >= 17.1); @dots{} @} +@end group @end example If the assertion fails, the program prints a message similar to this: @@ -21838,9 +21964,10 @@ function round(x, ival, aval, fraction) @} @c endfile @c don't include test harness in the file that gets installed - +@group # test harness # @{ print $0, round($0) @} +@end group @end example @node Cliff Random Function @@ -22246,7 +22373,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 @samp{@w{contents == ""}}. @xref{Extension Sample Readfile} for an extension function that also reads an entire file into memory. @@ -22577,8 +22704,10 @@ $ @kbd{gawk -f rewind.awk -f test.awk data } @print{} data 1 a @print{} data 2 b @print{} data 3 c +@group @print{} data 4 d @print{} data 5 e +@end group @end example @node File Checking @@ -23793,8 +23922,10 @@ function getgrent() _gr_init() if (++_gr_count in _gr_bycount) return _gr_bycount[_gr_count] +@group return "" @} +@end group @c endfile @end example @@ -24324,10 +24455,12 @@ list of fields or characters: if (by_fields == 0 && by_chars == 0) by_fields = 1 # default +@group if (fieldlist == "") @{ print "cut: needs list for -c or -f" > "/dev/stderr" exit 1 @} +@end group if (by_fields) set_fieldlist() @@ -24668,8 +24801,10 @@ function endfile(file) print fcount @} +@group total += fcount @} +@end group @c endfile @end example @@ -24826,11 +24961,15 @@ BEGIN @{ pw = getpwuid(uid) pr_first_field(pw) +@group if (euid != uid) @{ printf(" euid=%d", euid) pw = getpwuid(euid) +@end group +@group pr_first_field(pw) @} +@end group printf(" gid=%d", gid) pw = getgrgid(gid) @@ -24958,14 +25097,17 @@ BEGIN @{ # test argv in case reading from stdin instead of file if (i in ARGV) i++ # skip datafile name +@group if (i in ARGV) @{ outfile = ARGV[i] ARGV[i] = "" @} - +@end group +@group s1 = s2 = "a" out = (outfile s1 s2) @} +@end group @c endfile @end example @@ -25121,11 +25263,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 +@group for (i in copy) if (append) print >> copy[i] +@end group +@group else print > copy[i] +@end group @end example @noindent @@ -25276,10 +25422,12 @@ BEGIN @{ usage() @} +@group if (ARGV[Optind] ~ /^\+[[:digit:]]+$/) @{ charcount = substr(ARGV[Optind], 2) + 0 Optind++ @} +@end group for (i = 1; i < Optind; i++) ARGV[i] = "" @@ -25313,10 +25461,12 @@ strings are then compared and @code{are_equal()} returns the result: @example @c file eg/prog/uniq.awk +@group function are_equal( n, m, clast, cline, alast, aline) @{ if (fcount == 0 && charcount == 0) return (last == $0) +@end group if (fcount > 0) @{ n = split(last, alast) @@ -25331,9 +25481,11 @@ function are_equal( n, m, clast, cline, alast, aline) clast = substr(clast, charcount + 1) cline = substr(cline, charcount + 1) @} +@group return (clast == cline) @} +@end group @c endfile @end example @@ -25392,11 +25544,13 @@ NR == 1 @{ END @{ if (do_count) printf("%4d %s\n", count, last) > outputfile +@group else if ((repeated_only && count > 1) || (non_repeated_only && count == 1)) print last > outputfile close(outputfile) @} +@end group @c endfile @end example @@ -26191,10 +26345,12 @@ At first glance, a program like this would seem to do the job: freq[$i]++ @} +@group END @{ for (word in freq) printf "%s\t%d\n", word, freq[word] @} +@end group @end example The program relies on @command{awk}'s default field-splitting @@ -26584,9 +26740,11 @@ line. That line is then printed to the output file: i++ @} @} +@group print join(a, 1, n, SUBSEP) > curfile @} @} +@end group @c endfile @end example @@ -26672,10 +26830,12 @@ function usage() exit 1 @} +@group BEGIN @{ # validate arguments if (ARGC < 3) usage() +@end group RS = ARGV[1] ORS = ARGV[2] @@ -27069,13 +27229,11 @@ the program is done: continue @} fpath = pathto($2) -@group if (fpath == "") @{ printf("igawk: %s:%d: cannot find %s\n", input[stackptr], FNR, $2) > "/dev/stderr" continue @} -@end group if (! (fpath in processed)) @{ processed[fpath] = input[stackptr] input[++stackptr] = fpath # push onto stack @@ -27332,10 +27490,12 @@ notice and this notice are preserved. Here is the program: @example +@group awk 'BEGIN@{O="~"~"~";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),x-O@}' +@end group @end example @cindex Johansen, Chris @@ -27823,11 +27983,13 @@ Our first comparison function can be used to scan an array in numerical order of the indices: @example +@group function cmp_num_idx(i1, v1, i2, v2) @{ # numerical index comparison, ascending order return (i1 - i2) @} +@end group @end example Our second function traverses an array based on the string order of @@ -27932,10 +28094,13 @@ function cmp_field(i1, v1, i2, v2) a[NR][i] = $i @} +@group END @{ PROCINFO["sorted_in"] = "cmp_field" +@end 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 ? ":" : "") @@ -27992,6 +28157,7 @@ function cmp_numeric(i1, v1, i2, v2) return (v1 != v2) ? (v2 - v1) : (i2 - i1) @} +@group function cmp_string(i1, v1, i2, v2) @{ # string value (and index) comparison, descending order @@ -27999,6 +28165,7 @@ function cmp_string(i1, v1, i2, v2) v2 = v2 i2 return (v1 > v2) ? -1 : (v1 != v2) @} +@end group @end example @c Avoid using the term ``stable'' when describing the unpredictable behavior @@ -28152,11 +28319,13 @@ The following example demonstrates the use of a comparison function with both values to lowercase in order to compare them ignoring case. @example +@group # case_fold_compare --- compare as strings, ignoring case function case_fold_compare(i1, v1, i2, v2, l, r) @{ l = tolower(v1) +@end group r = tolower(v2) if (l < r) @@ -29513,8 +29682,10 @@ This is somewhat counterintuitive. and those with positional specifiers in the same string: @example +@group $ @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 +@end group @end example @quotation NOTE @@ -30139,8 +30310,10 @@ be inside this function. To investigate further, we must begin @samp{n} (for ``next''): @example +@group gawk> @kbd{n} @print{} 66 if (fcount > 0) @{ +@end group @end example This tells us that @command{gawk} is now ready to execute line 66, which @@ -30909,10 +31082,12 @@ partial dump of Davide Brini's obfuscated code @c FIXME: This will need updating if num-handler branch is ever merged in. @smallexample +@group gawk> @kbd{dump} @print{} # BEGIN @print{} @print{} [ 1:0xfcd340] Op_rule : [in_rule = BEGIN] [source_file = brini.awk] +@end group @print{} [ 1:0xfcc240] Op_push_i : "~" [MALLOC|STRING|STRCUR] @print{} [ 1:0xfcc2a0] Op_push_i : "~" [MALLOC|STRING|STRCUR] @print{} [ 1:0xfcc280] Op_match : @@ -30945,18 +31120,18 @@ gawk> @kbd{dump} @print{} [ :0xfcc660] Op_no_op : @print{} [ 1:0xfcc520] Op_assign_concat : c @print{} [ :0xfcc620] Op_jmp : [target_jmp = 0xfcc440] -@print{} @dots{} -@print{} @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 : +@group @print{} [ :0xfcc160] Op_no_op : @print{} [ :0xfcc1a0] Op_after_endfile : gawk> +@end group @end smallexample @cindex @code{exit} debugger command @@ -31311,6 +31486,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. +@cindex 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). @@ -31322,6 +31498,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. +@cindex floating-point, numbers@comma{} single-precision +@cindex floating-point, numbers@comma{} double-precision +@cindex floating-point, numbers@comma{} arbitrary-precision +@cindex single-precision +@cindex double-precision +@cindex 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 @@ -31331,29 +31513,48 @@ floating-point arithmetic, which we describe in more detail shortly. 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}. +floating-point values occupy 64 bits. +(Quadruple-precision floating point values also exist. They occupy 128 bits, +but such numbers are not available in @command{awk}.) +Floating-point values are always +signed. The possible ranges of values are shown in @ref{table-numeric-ranges} +and @ref{table-floating-point-ranges}. @float Table,table-numeric-ranges -@caption{Value ranges for different numeric representations} +@caption{Value ranges for integer representations} @multitable @columnfractions .34 .33 .33 -@headitem Numeric representation @tab Minimum value @tab Maximum value +@headitem 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 +@end multitable +@end float + +@float Table,table-floating-point-ranges +@caption{Approximate value ranges for floating-point number representations} +@multitable @columnfractions .38 .22 .22 .23 @iftex -@item Single-precision floating point (approximate) @tab @math{1.175494^{-38}} @tab @math{3.402823^{38}} -@item Double-precision floating point (approximate) @tab @math{2.225074^{-308}} @tab @math{1.797693^{308}} +@headitem Representation @tab @w{Minimum positive} @w{nonzero value} @tab Minimum @w{finite value} @tab Maximum @w{finite value} +@end iftex +@ifnottex +@headitem Representation @tab Minimum positive nonzero value @tab Minimum finite value @tab Maximum finite value +@end ifnottex +@iftex +@item @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}} +@item @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}} +@item @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 -@item Single-precision floating point (approximate) @tab 1.175494e-38 @tab 3.402823e38 -@item Double-precision floating point (approximate) @tab 2.225074e-308 @tab 1.797693e308 +@item Single-precision floating-point @tab 1.175494e-38 @tab -3.402823e+38 @tab 3.402823e+38 +@item Double-precision floating-point @tab 2.225074e-308 @tab -1.797693e+308 @tab 1.797693e+308 +@item Quadruple-precision floating-point @tab 3.362103e-4932 @tab -1.189731e+4932 @tab 1.189731e+4932 @end ifinfo @ifnottex @ifnotinfo -@item Single-precision floating point (approximate) @tab 1.175494@sup{-38} @tab 3.402823@sup{38} -@item Double-precision floating point (approximate) @tab 2.225074@sup{-308} @tab 1.797693@sup{308} +@item Single-precision floating-point @tab 1.175494*10@sup{-38} @tab -3.402823*10@sup{38} @tab 3.402823*10@sup{38} +@item Double-precision floating-point @tab 2.225074*10@sup{-308} @tab -1.797693*10@sup{308} @tab 1.797693*10@sup{308} +@item Quadruple-precision floating-point @tab 3.362103*10@sup{-4932} @tab -1.189731*10@sup{4932} @tab 1.189731*10@sup{4932} @end ifnotinfo @end ifnottex @end multitable @@ -31622,12 +31823,14 @@ You have to decide how small a delta is important to you. Code to do this looks something like the following: @example +@group delta = 0.00001 # for example difference = abs(a) - abs(b) # subtract the two values if (difference < delta) # all ok else # not ok +@end group @end example @noindent @@ -32097,6 +32300,7 @@ choose to set: @example @c file eg/prog/pi.awk +@group # pi.awk --- compute the digits of pi @c endfile @c endfile @@ -32112,6 +32316,7 @@ choose to set: BEGIN @{ digits = 100000 two = 2 * 10 ^ digits +@end group pi = two for (m = digits * 4; m > 0; --m) @{ d = m * 2 + 1 @@ -33078,6 +33283,7 @@ of the function using the macro. For example, you might allocate a string value like so: @example +@group awk_value_t result; char *message; const char greet[] = "Don't Panic!"; @@ -33085,8 +33291,10 @@ const char greet[] = "Don't Panic!"; emalloc(message, char *, sizeof(greet), "myfunc"); strcpy(message, greet); make_malloced_string(message, strlen(message), & result); +@end group @end example +@sp 2 @item #define ezalloc(pointer, type, size, message) @dots{} This is like @code{emalloc()}, but it calls @code{gawk_calloc()} instead of @code{gawk_malloc()}. @@ -33222,6 +33430,7 @@ registering parts of your extension with @command{gawk}. Extension functions are described by the following record: @example +@group typedef struct awk_ext_func @{ @ @ @ @ const char *name; @ @ @ @ awk_value_t *(*const function)(int num_actual_args, @@ -33232,6 +33441,7 @@ typedef struct awk_ext_func @{ @ @ @ @ awk_bool_t suppress_lint; @ @ @ @ void *data; /* opaque pointer to any extra state */ @} awk_ext_func_t; +@end group @end example The fields are: @@ -33427,12 +33637,14 @@ Your extension should package these functions inside an @code{awk_input_parser_t}, which looks like this: @example +@group 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; +@end group @end example The fields are: @@ -34185,6 +34397,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}. +@need 1500 The following functions let you work with scalar cookies: @table @code @@ -34247,12 +34460,14 @@ your extension's variable in @command{gawk}'s symbol table using using @code{sym_lookup()}: @example +@group static awk_scalar_t magic_var_cookie; /* cookie for MAGIC_VAR */ static void my_extension_init() @{ awk_value_t value; +@end group /* install initial value */ sym_update("MAGIC_VAR", make_number(42.0, & value)); @@ -34756,10 +34971,12 @@ Finally, because everything was successful, the function sets the return value to success, and returns: @example +@group make_number(1.0, result); out: return result; @} +@end group @end example Here is the output from running this part of the test: @@ -34971,7 +35188,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 @@ -35110,7 +35327,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", @@ -35211,10 +35428,12 @@ as described here. The boilerplate needed is also provided in comments in the @file{gawkapi.h} header file: @example +@group /* Boilerplate code: */ int plugin_is_GPL_compatible; static gawk_api_t *const api; +@end group static awk_ext_id_t ext_id; static const char *ext_version = NULL; /* or @dots{} = "some string" */ @@ -35615,10 +35834,12 @@ The second is a pointer to an @code{awk_value_t} structure, usually named @code{result}: @example +@group /* do_chdir --- provide dynamically loaded chdir() function for gawk */ static awk_value_t * do_chdir(int nargs, awk_value_t *result, struct awk_ext_func *unused) +@end group @{ awk_value_t newdir; int ret = -1; @@ -35745,7 +35966,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 @@ -35788,9 +36009,11 @@ certain members and/or the type of the file. It then returns zero, for success: @example +@group #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE array_set_numeric(array, "blksize", sbuf->st_blksize); -#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ +#endif +@end group pmode = format_mode(sbuf->st_mode); array_set(array, "pmode", make_const_string(pmode, strlen(pmode), @@ -35879,20 +36102,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); +@group if (ret < 0) @{ update_ERRNO_int(errno); return make_number(ret, result); @} +@end 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 +@group ret = fill_stat_array(name, array, & sbuf); return make_number(ret, result); @} +@end group @end example Finally, it's necessary to provide the ``glue'' that loads the @@ -41580,14 +41807,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 +@iftex +column. (Remember grade school? @math{42 = 4\times 10 + 2}.) +@end iftex +@ifnottex column. (Remember grade school? 42 = 4 x 10 + 2.) +@end 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. +@iftex +Thus, binary 1010 represents @math{(1\times 8) + (0\times 4) + (1\times 2) + (0\times 1)}, or decimal 10. +@end iftex +@ifnottex Thus, binary 1010 represents (1 x 8) + (0 x 4) + (1 x 2) + (0 x 1), or decimal 10. +@end ifnottex Octal and hexadecimal are discussed more in @ref{Nondecimal-numbers}. @@ -41727,7 +41964,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 +@iftex +the same as decimal 21, (@math{(1\times 16) + (1\times 4) + (1\times 1)}). +@end iftex +@ifnottex the same as decimal 21, ((1 x 16) + (1 x 4) + (1 x 1)). +@end ifnottex Since base-two numbers quickly become very long to read and write, they are usually grouped by 3 (i.e., they are @@ -41898,7 +42140,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}. @@ -42167,7 +42409,12 @@ Base 16 notation, where the digits are @code{0}--@code{9} and @code{A}--@code{F}, 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}, +@iftex +to indicate their base. Thus, @code{0x12} is 18 (@math{(1\times 16) + 2}). +@end iftex +@ifnottex to indicate their base. Thus, @code{0x12} is 18 ((1 x 16) + 2). +@end ifnottex @xref{Nondecimal-numbers}. @item I/O @@ -42231,7 +42478,7 @@ meaning. Keywords are reserved and may not be used as variable names. @code{break}, @code{case}, @code{continue}, -@code{default} +@code{default}, @code{delete}, @code{do@dots{}while}, @code{else}, @@ -42317,7 +42564,12 @@ Ancient @command{awk} implementations used single precision floating-point. @item Octal Base-eight notation, where the digits are @code{0}--@code{7}. Octal numbers are written in C using a leading @samp{0}, +@iftex +to indicate their base. Thus, @code{013} is 11 (@math{(1\times 8) + 3}). +@end iftex +@ifnottex to indicate their base. Thus, @code{013} is 11 ((1 x 8) + 3). +@end ifnottex @xref{Nondecimal-numbers}. @item Output Record diff --git a/doc/gawktexi.in b/doc/gawktexi.in index fccd15f9..654fa3eb 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -1494,9 +1494,11 @@ default @command{awk} utility. A more modern @command{awk} lives in if you try the test program: @example +@group $ @kbd{awk 1 /dev/null} @error{} awk: syntax error near line 1 @error{} awk: bailing out near line 1 +@end group @end example @noindent @@ -2901,10 +2903,12 @@ for the single- and double-quote characters, like so: @example +@group $ @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 <"> +@end group @end example @noindent @@ -3176,8 +3180,10 @@ action---so it uses the default action, printing the record. Print the length of the longest input line: @example +@group awk '@{ if (length($0) > max) max = length($0) @} END @{ print max @}' data +@end group @end example The code associated with @code{END} executes after all @@ -3494,11 +3500,13 @@ starts a comment, it ignores @emph{everything} on the rest of the line. For example: @example +@group $ @kbd{gawk 'BEGIN @{ print "dont panic" # a friendly \} > @kbd{ BEGIN rule} > @kbd{@}'} @error{} gawk: cmd. line:2: BEGIN rule @error{} gawk: cmd. line:2: ^ syntax error +@end group @end example @noindent @@ -4695,10 +4703,12 @@ The files to be included may be nested; e.g., given a third script, namely @file{test3}: @example +@group @@include "test2" BEGIN @{ print "This is script test3." @} +@end group @end example @noindent @@ -4785,8 +4795,10 @@ $ @kbd{gawk '@@load "ordchr"; BEGIN @{print chr(65)@}'} This is equivalent to the following example: @example +@group $ @kbd{gawk -lordchr 'BEGIN @{print chr(65)@}'} @print{} A +@end group @end example @noindent @@ -6282,8 +6294,10 @@ with each @samp{u} changed to a newline. Here are the results of running the program on @file{mail-list}: @example +@group $ @kbd{awk 'BEGIN @{ RS = "u" @}} > @kbd{@{ print $0 @}' mail-list} +@end group @print{} Amelia 555-5553 amelia.zodiac @print{} sq @print{} e@@gmail.com F @@ -6440,9 +6454,11 @@ matches either a newline or a series of one or more uppercase letters with optional leading and/or trailing whitespace: @example +@group $ @kbd{echo record 1 AAAA record 2 BBBB record 3 |} > @kbd{gawk 'BEGIN @{ RS = "\n|( *[[:upper:]]+ *)" @}} > @kbd{@{ print "Record =", $0,"and RT = [" RT "]" @}'} +@end group @print{} Record = record 1 and RT = [ AAAA ] @print{} Record = record 2 and RT = [ BBBB ] @print{} Record = record 3 and RT = [ @@ -6826,8 +6842,10 @@ values of the fields and @code{OFS}. To do this, use the seemingly innocuous assignment: @example +@group $1 = $1 # force record to be reconstituted print $0 # or whatever else with $0 +@end group @end example @noindent @@ -7596,16 +7614,20 @@ Putting this to use, here is a simple program to parse the data: @example @c file eg/misc/simple-csv.awk +@group BEGIN @{ FPAT = "([^,]+)|(\"[^\"]+\")" @} +@end group +@group @{ print "NF = ", NF for (i = 1; i <= NF; i++) @{ printf("$%d = <%s>\n", i, $i) @} @} +@end group @c endfile @end example @@ -8046,6 +8068,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 +@group @{ if ((getline tmp) > 0) @{ print tmp @@ -8053,6 +8076,7 @@ The following example swaps every two lines of input: @} else print $0 @} +@end group @end example @noindent @@ -8195,6 +8219,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 +@group @{ if ($1 == "@@execute") @{ tmp = substr($0, 10) # Remove "@@execute" @@ -8204,6 +8229,7 @@ produced by running the rest of the line as a shell command: @} else print @} +@end group @end example @noindent @@ -8507,12 +8533,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 +@group Service = "/inet/tcp/0/localhost/daytime" PROCINFO[Service, "READ_TIMEOUT"] = 100 if ((Service |& getline) > 0) print $0 else if (ERRNO != "") print ERRNO +@end group @end example Here is how to read interactively from the user@footnote{This assumes @@ -8854,10 +8882,12 @@ newlines: @end ifnotinfo @example +@group $ @kbd{awk 'BEGIN @{ print "line one\nline two\nline three" @}'} @print{} line one @print{} line two @print{} line three +@end group @end example @cindex fields, printing @@ -9109,12 +9139,14 @@ The output separator variables @code{OFS} and @code{ORS} have no effect on @code{printf} statements. For example: @example +@group $ @kbd{awk 'BEGIN @{} > @kbd{ORS = "\nOUCH!\n"; OFS = "+"} > @kbd{msg = "Don\47t Panic!"} > @kbd{printf "%s\n", msg} > @kbd{@}'} @print{} Don't Panic! +@end group @end example @noindent @@ -9637,9 +9669,11 @@ alone for now and let's hope no-one notices. @end ignore @example +@group awk '@{ print $1 > "names.unsorted" command = "sort -r > names.sorted" print $1 | command @}' mail-list +@end group @end example The unsorted list is written with an ordinary redirection, while @@ -9933,7 +9967,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 @@ -10032,10 +10066,14 @@ it is good practice to use a variable to store the @value{FN} or command. The previous example becomes the following: @example +@group sortcom = "sort -r names" sortcom | getline foo +@end group +@group @dots{} close(sortcom) +@end group @end example @noindent @@ -10178,7 +10216,7 @@ if it fails. @float Table,table-close-pipe-return-values @caption{Return values from @code{close()} of a pipe} -@multitable @columnfractions .40 .60 +@multitable @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 @@ -10207,7 +10245,8 @@ disk) is a fatal error. @example $ @kbd{gawk 'BEGIN @{ print "hi" > "/no/such/file" @}'} -@error{} gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No such file or directory) +@error{} gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No +@error{} such file or directory) @end example @command{gawk} makes it possible to detect that an error has @@ -10638,6 +10677,7 @@ confusion can arise when attempting to use regexp constants as arguments to user-defined functions (@pxref{User-defined}). For example: @example +@group function mysub(pat, repl, str, global) @{ if (global) @@ -10646,13 +10686,16 @@ function mysub(pat, repl, str, global) sub(pat, repl, str) return str @} +@end group +@group @{ @dots{} text = "hi! hi yourself!" mysub(/hi/, "howdy", text, 1) @dots{} @} +@end group @end example @c @cindex automatic warnings @@ -10900,8 +10943,10 @@ is performed. If numeric values appear in string concatenation, they are converted to strings. Consider the following: @example +@group two = 2; three = 3 print (two three) + 4 +@end group @end example @noindent @@ -11374,10 +11419,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 +@group foo = 1 print foo +@end group +@group foo = "bar" print foo +@end group @end example @noindent @@ -11449,16 +11498,20 @@ righthand expression. For example: @cindex Rankin, Pat @example +@group # Thanks to Pat Rankin for this example BEGIN @{ foo[rand()] += 5 for (x in foo) print x, foo[x] +@end group +@group bar[rand()] = bar[rand()] + 5 for (x in bar) print x, bar[x] @} +@end group @end example @cindex operators, assignment, evaluation order @@ -12134,10 +12187,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 +@group if (a = b) # oops! should be a == b @dots{} else @dots{} +@end group @end example @noindent @@ -13089,8 +13144,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 +@group @print{} Martin 555-6480 martin.codicibus@@hotmail.com A @print{} Jean-Paul 555-2127 jeanpaul.campanorum@@nyu.edu R +@end group @end example @cindex @code{BEGIN} pattern, Boolean patterns and @@ -13481,10 +13538,12 @@ the variable's value into the program inside the script. For example, consider the following program: @example +@group printf "Enter search pattern: " read pattern awk "/$pattern/ "'@{ nmatches++ @} END @{ print nmatches, "found" @}' /path/to/data +@end group @end example @noindent @@ -13673,10 +13732,12 @@ the null string; otherwise, the condition is true. Refer to the following: @example +@group if (x % 2 == 0) print "x is even" else print "x is odd" +@end group @end example In this example, if the expression @samp{x % 2 == 0} is true (i.e., @@ -13998,6 +14059,7 @@ finds the smallest divisor of any integer, and also identifies prime numbers: @example +@group # find smallest divisor of num @{ num = $1 @@ -14005,11 +14067,14 @@ numbers: if (num % divisor == 0) break @} +@end group +@group if (num % divisor == 0) printf "Smallest divisor of %d is %d\n", num, divisor else printf "%d is prime\n", num @} +@end group @end example When the remainder is zero in the first @code{if} statement, @command{awk} @@ -14317,14 +14382,18 @@ using an @code{exit} statement with a nonzero argument, as shown in the following example: @example +@group BEGIN @{ if (("date" | getline date_now) <= 0) @{ print "Can't get system date" > "/dev/stderr" exit 1 @} +@end group +@group print "current date is", date_now close("date") @} +@end group @end example @quotation NOTE @@ -14622,6 +14691,7 @@ Unlike most @command{awk} arrays, In the following example: @example +@group $ @kbd{awk 'BEGIN @{} > @kbd{for (i = 0; i < ARGC; i++)} > @kbd{print ARGV[i]} @@ -14629,6 +14699,7 @@ $ @kbd{awk 'BEGIN @{} @print{} awk @print{} inventory-shipped @print{} mail-list +@end group @end example @noindent @@ -15053,12 +15124,14 @@ points out that it effectively gives @command{awk} data pointers. Consider his example: @example +@group # Indirect multiply of any variable by amount, return result function multiply(variable, amount) @{ return SYMTAB[variable] *= amount @} +@end group @end example @noindent @@ -15130,6 +15203,7 @@ presented the following program describing the information contained in @code{AR and @code{ARGV}: @example +@group $ @kbd{awk 'BEGIN @{} > @kbd{for (i = 0; i < ARGC; i++)} > @kbd{print ARGV[i]} @@ -15137,6 +15211,7 @@ $ @kbd{awk 'BEGIN @{} @print{} awk @print{} inventory-shipped @print{} mail-list +@end group @end example @noindent @@ -15733,8 +15808,10 @@ For example, this statement tests whether the array @code{frequencies} contains the index @samp{2}: @example +@group if (2 in frequencies) print "Subscript 2 is present." +@end group @end example Note that this is @emph{not} a test of whether the array @@ -15744,8 +15821,10 @@ There is no way to do that except to scan all the elements. Also, this (incorrect) alternative does: @example +@group if (frequencies[2] != "") print "Subscript 2 is present." +@end group @end example @node Assigning Elements @@ -15802,6 +15881,7 @@ all the lines. When this program is run with the following input: @example +@group @c file eg/misc/arraymax.data 5 I am the Five man 2 Who are you? The new number two! @@ -15809,17 +15889,20 @@ When this program is run with the following input: 1 Who is number one? 3 I three you. @c endfile +@end group @end example @noindent Its output is: @example +@group 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 +@end group @end example If a line number is repeated, the last line with a given number overrides @@ -15828,11 +15911,13 @@ Gaps in the line numbers can be handled with an easy improvement to the program's @code{END} rule, as follows: @example +@group END @{ for (x = 1; x <= max; x++) if (x in arr) print arr[x] @} +@end group @end example @node Scanning an Array @@ -15852,8 +15937,10 @@ So @command{awk} has a special kind of @code{for} statement for scanning an array: @example +@group for (@var{var} in @var{array}) @var{body} +@end group @end example @noindent @@ -15874,12 +15961,15 @@ such words. for more information on the built-in function @code{length()}. @example +@group # Record a 1 for each word that is used at least once @{ for (i = 1; i <= NF; i++) used[$i] = 1 @} +@end group +@group # Find number of distinct words more than 10 characters long END @{ for (x in used) @{ @@ -15890,6 +15980,7 @@ END @{ @} print num_long_words, "words longer than 10 characters" @} +@end group @end example @noindent @@ -16277,9 +16368,11 @@ same as assigning it a null value (the empty string, @code{""}). For example: @example +@group foo[4] = "" if (4 in foo) print "This is printed, even though foo[4] is empty" +@end group @end example @cindex lint checking, array elements @@ -16434,22 +16527,26 @@ END @{ When given the input: @example +@group 1 2 3 4 5 6 2 3 4 5 6 1 3 4 5 6 1 2 4 5 6 1 2 3 +@end group @end example @noindent the program produces the following output: @example +@group 4 3 2 1 5 4 3 2 6 5 4 3 1 6 5 4 2 1 6 5 3 2 1 6 +@end group @end example @node Multiscanning @@ -16629,15 +16726,19 @@ you can often devise workarounds using control statements. For example, the following code prints the elements of our main array @code{a}: @example +@group for (i in a) @{ for (j in a[i]) @{ if (j == 3) @{ for (k in a[i][j]) print a[i][j][k] +@end group +@group @} else print a[i][j] @} @} +@end group @end example @noindent @@ -17087,9 +17188,11 @@ asort(a) results in the following contents of @code{a}: @example +@group a[1] = "cul" a[2] = "de" a[3] = "sac" +@end group @end example The @code{asorti()} function works similarly to @code{asort()}; however, @@ -18145,6 +18248,9 @@ 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. +@c end the table to let the sidebar take up the full width of the page. +@end table + @sidebar Interactive Versus Noninteractive Buffering @cindex buffering, interactive vs.@: noninteractive @@ -18188,6 +18294,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 +@table @asis @item @code{system(@var{command})} @cindexawkfunc{system} @cindex invoke shell command @@ -18909,7 +19016,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) @{ @@ -18931,7 +19038,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) @{ @@ -18972,7 +19079,8 @@ $ @kbd{gawk -f testbits.awk} @print{} 123 = 01111011 @print{} 0123 = 01010011 @print{} 0x99 = 10011001 -@print{} compl(0x99) = 0x3fffffffffff66 = 00111111111111111111111111111111111111111111111101100110 +@print{} compl(0x99) = 0x3fffffffffff66 = +@print{} 00111111111111111111111111111111111111111111111101100110 @print{} lshift(0x99, 2) = 0x264 = 0000001001100100 @print{} rshift(0x99, 2) = 0x26 = 00100110 @end example @@ -19243,10 +19351,12 @@ entire program before starting to execute any of it. The definition of a function named @var{name} looks like this: @display +@group @code{function} @var{name}@code{(}[@var{parameter-list}]@code{)} @code{@{} @var{body-of-function} @code{@}} +@end group @end display @cindex names, functions @@ -19414,11 +19524,13 @@ This function deletes all the elements in an array (recall that the extra whitespace signifies the start of the local variable list): @example +@group function delarray(a, i) @{ for (i in a) delete a[i] @} +@end group @end example When working with arrays, it is often necessary to delete all the elements @@ -19625,10 +19737,12 @@ In addition, recursive calls create new arrays. Consider this example: @example +@group function some_func(p1, a) @{ if (p1++ > 3) return +@end group a[p1] = p1 @@ -19692,12 +19806,14 @@ this has no effect on any other variables. Thus, if @code{myfunc()} does this: @example +@group function myfunc(str) @{ print str str = "zzz" print str @} +@end group @end example @noindent @@ -19853,11 +19969,13 @@ function maxelt(vec, i, ret) return ret @} +@group # Load all fields of each record into nums. @{ for(i = 1; i <= NF; i++) nums[NR, i] = $i @} +@end group END @{ print maxelt(nums) @@ -20151,12 +20269,14 @@ first thing to do is write some comparison functions: @example @c file eg/prog/indirectcall.awk +@group # num_lt --- do a numeric less than comparison function num_lt(left, right) @{ return ((left + 0) < (right + 0)) @} +@end group # num_ge --- do a numeric greater than or equal to comparison @@ -20205,19 +20325,23 @@ names of the two comparison functions: @example @c file eg/prog/indirectcall.awk +@group # sort --- sort the data in ascending order and return it as a string function sort(first, last) @{ return do_sort(first, last, "num_lt") @} +@end group +@group # rsort --- sort the data in descending order and return it as a string function rsort(first, last) @{ return do_sort(first, last, "num_ge") @} +@end group @c endfile @end example @@ -20717,6 +20841,7 @@ been true but was not, and then it kills the program. In C, using @code{assert()} looks this: @example +@group #include <assert.h> int myfunc(int a, double b) @@ -20724,6 +20849,7 @@ int myfunc(int a, double b) assert(a <= 5 && b >= 17.1); @dots{} @} +@end group @end example If the assertion fails, the program prints a message similar to this: @@ -20881,9 +21007,10 @@ function round(x, ival, aval, fraction) @} @c endfile @c don't include test harness in the file that gets installed - +@group # test harness # @{ print $0, round($0) @} +@end group @end example @node Cliff Random Function @@ -21289,7 +21416,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 @samp{@w{contents == ""}}. @xref{Extension Sample Readfile} for an extension function that also reads an entire file into memory. @@ -21590,8 +21717,10 @@ $ @kbd{gawk -f rewind.awk -f test.awk data } @print{} data 1 a @print{} data 2 b @print{} data 3 c +@group @print{} data 4 d @print{} data 5 e +@end group @end example @node File Checking @@ -22806,8 +22935,10 @@ function getgrent() _gr_init() if (++_gr_count in _gr_bycount) return _gr_bycount[_gr_count] +@group return "" @} +@end group @c endfile @end example @@ -23337,10 +23468,12 @@ list of fields or characters: if (by_fields == 0 && by_chars == 0) by_fields = 1 # default +@group if (fieldlist == "") @{ print "cut: needs list for -c or -f" > "/dev/stderr" exit 1 @} +@end group if (by_fields) set_fieldlist() @@ -23681,8 +23814,10 @@ function endfile(file) print fcount @} +@group total += fcount @} +@end group @c endfile @end example @@ -23839,11 +23974,15 @@ BEGIN @{ pw = getpwuid(uid) pr_first_field(pw) +@group if (euid != uid) @{ printf(" euid=%d", euid) pw = getpwuid(euid) +@end group +@group pr_first_field(pw) @} +@end group printf(" gid=%d", gid) pw = getgrgid(gid) @@ -23971,14 +24110,17 @@ BEGIN @{ # test argv in case reading from stdin instead of file if (i in ARGV) i++ # skip datafile name +@group if (i in ARGV) @{ outfile = ARGV[i] ARGV[i] = "" @} - +@end group +@group s1 = s2 = "a" out = (outfile s1 s2) @} +@end group @c endfile @end example @@ -24134,11 +24276,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 +@group for (i in copy) if (append) print >> copy[i] +@end group +@group else print > copy[i] +@end group @end example @noindent @@ -24289,10 +24435,12 @@ BEGIN @{ usage() @} +@group if (ARGV[Optind] ~ /^\+[[:digit:]]+$/) @{ charcount = substr(ARGV[Optind], 2) + 0 Optind++ @} +@end group for (i = 1; i < Optind; i++) ARGV[i] = "" @@ -24326,10 +24474,12 @@ strings are then compared and @code{are_equal()} returns the result: @example @c file eg/prog/uniq.awk +@group function are_equal( n, m, clast, cline, alast, aline) @{ if (fcount == 0 && charcount == 0) return (last == $0) +@end group if (fcount > 0) @{ n = split(last, alast) @@ -24344,9 +24494,11 @@ function are_equal( n, m, clast, cline, alast, aline) clast = substr(clast, charcount + 1) cline = substr(cline, charcount + 1) @} +@group return (clast == cline) @} +@end group @c endfile @end example @@ -24405,11 +24557,13 @@ NR == 1 @{ END @{ if (do_count) printf("%4d %s\n", count, last) > outputfile +@group else if ((repeated_only && count > 1) || (non_repeated_only && count == 1)) print last > outputfile close(outputfile) @} +@end group @c endfile @end example @@ -25204,10 +25358,12 @@ At first glance, a program like this would seem to do the job: freq[$i]++ @} +@group END @{ for (word in freq) printf "%s\t%d\n", word, freq[word] @} +@end group @end example The program relies on @command{awk}'s default field-splitting @@ -25597,9 +25753,11 @@ line. That line is then printed to the output file: i++ @} @} +@group print join(a, 1, n, SUBSEP) > curfile @} @} +@end group @c endfile @end example @@ -25685,10 +25843,12 @@ function usage() exit 1 @} +@group BEGIN @{ # validate arguments if (ARGC < 3) usage() +@end group RS = ARGV[1] ORS = ARGV[2] @@ -26082,13 +26242,11 @@ the program is done: continue @} fpath = pathto($2) -@group if (fpath == "") @{ printf("igawk: %s:%d: cannot find %s\n", input[stackptr], FNR, $2) > "/dev/stderr" continue @} -@end group if (! (fpath in processed)) @{ processed[fpath] = input[stackptr] input[++stackptr] = fpath # push onto stack @@ -26345,10 +26503,12 @@ notice and this notice are preserved. Here is the program: @example +@group awk 'BEGIN@{O="~"~"~";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),x-O@}' +@end group @end example @cindex Johansen, Chris @@ -26836,11 +26996,13 @@ Our first comparison function can be used to scan an array in numerical order of the indices: @example +@group function cmp_num_idx(i1, v1, i2, v2) @{ # numerical index comparison, ascending order return (i1 - i2) @} +@end group @end example Our second function traverses an array based on the string order of @@ -26945,10 +27107,13 @@ function cmp_field(i1, v1, i2, v2) a[NR][i] = $i @} +@group END @{ PROCINFO["sorted_in"] = "cmp_field" +@end 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 ? ":" : "") @@ -27005,6 +27170,7 @@ function cmp_numeric(i1, v1, i2, v2) return (v1 != v2) ? (v2 - v1) : (i2 - i1) @} +@group function cmp_string(i1, v1, i2, v2) @{ # string value (and index) comparison, descending order @@ -27012,6 +27178,7 @@ function cmp_string(i1, v1, i2, v2) v2 = v2 i2 return (v1 > v2) ? -1 : (v1 != v2) @} +@end group @end example @c Avoid using the term ``stable'' when describing the unpredictable behavior @@ -27165,11 +27332,13 @@ The following example demonstrates the use of a comparison function with both values to lowercase in order to compare them ignoring case. @example +@group # case_fold_compare --- compare as strings, ignoring case function case_fold_compare(i1, v1, i2, v2, l, r) @{ l = tolower(v1) +@end group r = tolower(v2) if (l < r) @@ -28526,8 +28695,10 @@ This is somewhat counterintuitive. and those with positional specifiers in the same string: @example +@group $ @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 +@end group @end example @quotation NOTE @@ -29152,8 +29323,10 @@ be inside this function. To investigate further, we must begin @samp{n} (for ``next''): @example +@group gawk> @kbd{n} @print{} 66 if (fcount > 0) @{ +@end group @end example This tells us that @command{gawk} is now ready to execute line 66, which @@ -29922,10 +30095,12 @@ partial dump of Davide Brini's obfuscated code @c FIXME: This will need updating if num-handler branch is ever merged in. @smallexample +@group gawk> @kbd{dump} @print{} # BEGIN @print{} @print{} [ 1:0xfcd340] Op_rule : [in_rule = BEGIN] [source_file = brini.awk] +@end group @print{} [ 1:0xfcc240] Op_push_i : "~" [MALLOC|STRING|STRCUR] @print{} [ 1:0xfcc2a0] Op_push_i : "~" [MALLOC|STRING|STRCUR] @print{} [ 1:0xfcc280] Op_match : @@ -29958,18 +30133,18 @@ gawk> @kbd{dump} @print{} [ :0xfcc660] Op_no_op : @print{} [ 1:0xfcc520] Op_assign_concat : c @print{} [ :0xfcc620] Op_jmp : [target_jmp = 0xfcc440] -@print{} @dots{} -@print{} @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 : +@group @print{} [ :0xfcc160] Op_no_op : @print{} [ :0xfcc1a0] Op_after_endfile : gawk> +@end group @end smallexample @cindex @code{exit} debugger command @@ -30324,6 +30499,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. +@cindex 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). @@ -30335,6 +30511,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. +@cindex floating-point, numbers@comma{} single-precision +@cindex floating-point, numbers@comma{} double-precision +@cindex floating-point, numbers@comma{} arbitrary-precision +@cindex single-precision +@cindex double-precision +@cindex 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 @@ -30344,29 +30526,48 @@ floating-point arithmetic, which we describe in more detail shortly. 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}. +floating-point values occupy 64 bits. +(Quadruple-precision floating point values also exist. They occupy 128 bits, +but such numbers are not available in @command{awk}.) +Floating-point values are always +signed. The possible ranges of values are shown in @ref{table-numeric-ranges} +and @ref{table-floating-point-ranges}. @float Table,table-numeric-ranges -@caption{Value ranges for different numeric representations} +@caption{Value ranges for integer representations} @multitable @columnfractions .34 .33 .33 -@headitem Numeric representation @tab Minimum value @tab Maximum value +@headitem 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 +@end multitable +@end float + +@float Table,table-floating-point-ranges +@caption{Approximate value ranges for floating-point number representations} +@multitable @columnfractions .38 .22 .22 .23 @iftex -@item Single-precision floating point (approximate) @tab @math{1.175494^{-38}} @tab @math{3.402823^{38}} -@item Double-precision floating point (approximate) @tab @math{2.225074^{-308}} @tab @math{1.797693^{308}} +@headitem Representation @tab @w{Minimum positive} @w{nonzero value} @tab Minimum @w{finite value} @tab Maximum @w{finite value} +@end iftex +@ifnottex +@headitem Representation @tab Minimum positive nonzero value @tab Minimum finite value @tab Maximum finite value +@end ifnottex +@iftex +@item @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}} +@item @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}} +@item @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 -@item Single-precision floating point (approximate) @tab 1.175494e-38 @tab 3.402823e38 -@item Double-precision floating point (approximate) @tab 2.225074e-308 @tab 1.797693e308 +@item Single-precision floating-point @tab 1.175494e-38 @tab -3.402823e+38 @tab 3.402823e+38 +@item Double-precision floating-point @tab 2.225074e-308 @tab -1.797693e+308 @tab 1.797693e+308 +@item Quadruple-precision floating-point @tab 3.362103e-4932 @tab -1.189731e+4932 @tab 1.189731e+4932 @end ifinfo @ifnottex @ifnotinfo -@item Single-precision floating point (approximate) @tab 1.175494@sup{-38} @tab 3.402823@sup{38} -@item Double-precision floating point (approximate) @tab 2.225074@sup{-308} @tab 1.797693@sup{308} +@item Single-precision floating-point @tab 1.175494*10@sup{-38} @tab -3.402823*10@sup{38} @tab 3.402823*10@sup{38} +@item Double-precision floating-point @tab 2.225074*10@sup{-308} @tab -1.797693*10@sup{308} @tab 1.797693*10@sup{308} +@item Quadruple-precision floating-point @tab 3.362103*10@sup{-4932} @tab -1.189731*10@sup{4932} @tab 1.189731*10@sup{4932} @end ifnotinfo @end ifnottex @end multitable @@ -30635,12 +30836,14 @@ You have to decide how small a delta is important to you. Code to do this looks something like the following: @example +@group delta = 0.00001 # for example difference = abs(a) - abs(b) # subtract the two values if (difference < delta) # all ok else # not ok +@end group @end example @noindent @@ -31110,6 +31313,7 @@ choose to set: @example @c file eg/prog/pi.awk +@group # pi.awk --- compute the digits of pi @c endfile @c endfile @@ -31125,6 +31329,7 @@ choose to set: BEGIN @{ digits = 100000 two = 2 * 10 ^ digits +@end group pi = two for (m = digits * 4; m > 0; --m) @{ d = m * 2 + 1 @@ -32091,6 +32296,7 @@ of the function using the macro. For example, you might allocate a string value like so: @example +@group awk_value_t result; char *message; const char greet[] = "Don't Panic!"; @@ -32098,8 +32304,10 @@ const char greet[] = "Don't Panic!"; emalloc(message, char *, sizeof(greet), "myfunc"); strcpy(message, greet); make_malloced_string(message, strlen(message), & result); +@end group @end example +@sp 2 @item #define ezalloc(pointer, type, size, message) @dots{} This is like @code{emalloc()}, but it calls @code{gawk_calloc()} instead of @code{gawk_malloc()}. @@ -32235,6 +32443,7 @@ registering parts of your extension with @command{gawk}. Extension functions are described by the following record: @example +@group typedef struct awk_ext_func @{ @ @ @ @ const char *name; @ @ @ @ awk_value_t *(*const function)(int num_actual_args, @@ -32245,6 +32454,7 @@ typedef struct awk_ext_func @{ @ @ @ @ awk_bool_t suppress_lint; @ @ @ @ void *data; /* opaque pointer to any extra state */ @} awk_ext_func_t; +@end group @end example The fields are: @@ -32440,12 +32650,14 @@ Your extension should package these functions inside an @code{awk_input_parser_t}, which looks like this: @example +@group 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; +@end group @end example The fields are: @@ -33198,6 +33410,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}. +@need 1500 The following functions let you work with scalar cookies: @table @code @@ -33260,12 +33473,14 @@ your extension's variable in @command{gawk}'s symbol table using using @code{sym_lookup()}: @example +@group static awk_scalar_t magic_var_cookie; /* cookie for MAGIC_VAR */ static void my_extension_init() @{ awk_value_t value; +@end group /* install initial value */ sym_update("MAGIC_VAR", make_number(42.0, & value)); @@ -33769,10 +33984,12 @@ Finally, because everything was successful, the function sets the return value to success, and returns: @example +@group make_number(1.0, result); out: return result; @} +@end group @end example Here is the output from running this part of the test: @@ -33984,7 +34201,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 @@ -34123,7 +34340,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", @@ -34224,10 +34441,12 @@ as described here. The boilerplate needed is also provided in comments in the @file{gawkapi.h} header file: @example +@group /* Boilerplate code: */ int plugin_is_GPL_compatible; static gawk_api_t *const api; +@end group static awk_ext_id_t ext_id; static const char *ext_version = NULL; /* or @dots{} = "some string" */ @@ -34628,10 +34847,12 @@ The second is a pointer to an @code{awk_value_t} structure, usually named @code{result}: @example +@group /* do_chdir --- provide dynamically loaded chdir() function for gawk */ static awk_value_t * do_chdir(int nargs, awk_value_t *result, struct awk_ext_func *unused) +@end group @{ awk_value_t newdir; int ret = -1; @@ -34758,7 +34979,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 @@ -34801,9 +35022,11 @@ certain members and/or the type of the file. It then returns zero, for success: @example +@group #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE array_set_numeric(array, "blksize", sbuf->st_blksize); -#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ +#endif +@end group pmode = format_mode(sbuf->st_mode); array_set(array, "pmode", make_const_string(pmode, strlen(pmode), @@ -34892,20 +35115,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); +@group if (ret < 0) @{ update_ERRNO_int(errno); return make_number(ret, result); @} +@end 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 +@group ret = fill_stat_array(name, array, & sbuf); return make_number(ret, result); @} +@end group @end example Finally, it's necessary to provide the ``glue'' that loads the @@ -40593,14 +40820,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 +@iftex +column. (Remember grade school? @math{42 = 4\times 10 + 2}.) +@end iftex +@ifnottex column. (Remember grade school? 42 = 4 x 10 + 2.) +@end 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. +@iftex +Thus, binary 1010 represents @math{(1\times 8) + (0\times 4) + (1\times 2) + (0\times 1)}, or decimal 10. +@end iftex +@ifnottex Thus, binary 1010 represents (1 x 8) + (0 x 4) + (1 x 2) + (0 x 1), or decimal 10. +@end ifnottex Octal and hexadecimal are discussed more in @ref{Nondecimal-numbers}. @@ -40740,7 +40977,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 +@iftex +the same as decimal 21, (@math{(1\times 16) + (1\times 4) + (1\times 1)}). +@end iftex +@ifnottex the same as decimal 21, ((1 x 16) + (1 x 4) + (1 x 1)). +@end ifnottex Since base-two numbers quickly become very long to read and write, they are usually grouped by 3 (i.e., they are @@ -40911,7 +41153,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}. @@ -41180,7 +41422,12 @@ Base 16 notation, where the digits are @code{0}--@code{9} and @code{A}--@code{F}, 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}, +@iftex +to indicate their base. Thus, @code{0x12} is 18 (@math{(1\times 16) + 2}). +@end iftex +@ifnottex to indicate their base. Thus, @code{0x12} is 18 ((1 x 16) + 2). +@end ifnottex @xref{Nondecimal-numbers}. @item I/O @@ -41244,7 +41491,7 @@ meaning. Keywords are reserved and may not be used as variable names. @code{break}, @code{case}, @code{continue}, -@code{default} +@code{default}, @code{delete}, @code{do@dots{}while}, @code{else}, @@ -41330,7 +41577,12 @@ Ancient @command{awk} implementations used single precision floating-point. @item Octal Base-eight notation, where the digits are @code{0}--@code{7}. Octal numbers are written in C using a leading @samp{0}, +@iftex +to indicate their base. Thus, @code{013} is 11 (@math{(1\times 8) + 3}). +@end iftex +@ifnottex to indicate their base. Thus, @code{013} is 11 ((1 x 8) + 3). +@end ifnottex @xref{Nondecimal-numbers}. @item Output Record |