diff options
-rw-r--r-- | ChangeLog | 39 | ||||
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | awk.h | 4 | ||||
-rw-r--r-- | builtin.c | 37 | ||||
-rw-r--r-- | doc/ChangeLog | 10 | ||||
-rw-r--r-- | doc/gawk.info | 1183 | ||||
-rw-r--r-- | doc/gawk.texi | 73 | ||||
-rw-r--r-- | doc/gawktexi.in | 73 | ||||
-rw-r--r-- | io.c | 73 | ||||
-rw-r--r-- | test/ChangeLog | 10 | ||||
-rw-r--r-- | test/Makefile.am | 5 | ||||
-rw-r--r-- | test/Makefile.in | 15 | ||||
-rw-r--r-- | test/Maketests | 10 | ||||
-rw-r--r-- | test/nonfatal1.awk | 5 | ||||
-rw-r--r-- | test/nonfatal1.ok | 2 | ||||
-rw-r--r-- | test/nonfatal2.awk | 5 | ||||
-rw-r--r-- | test/nonfatal2.ok | 1 |
17 files changed, 965 insertions, 585 deletions
@@ -20,6 +20,29 @@ * profile.c (pprint): Restore printing of count for rules. Bug report by Hermann Peifer. +2015-02-08 Arnold D. Robbins <arnold@skeeve.com> + + * io.c: Make it "NONFATAL" everywhere. + +2015-02-08 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * awk.h (RED_NON_FATAL): Removed. + (redirect): Add new failure_fatal parameter. + (is_non_fatal_redirect): Add declaration. + * builtin.c (efwrite): Rework check for non-fatal. + (do_printf): Adjust calls to redirect. + (do_print_rec): Ditto. Move check for redirection error up. + * io.c (redflags2str): Remove RED_NON_FATAL. + (redirect): Add new failure_fatal parameter. Simplify the code. + (is_non_fatal_redirect): New function. + (do_getline_redir): Adjust calls to redirect. + +2014-12-27 Arnold D. Robbins <arnold@skeeve.com> + + * awk.h (is_non_fatal_std): Declare new function. + * io.c (is_non_fatal_std): New function. + * builtin.c (efwrite): Call it. + 2015-02-07 Arnold D. Robbins <arnold@skeeve.com> * regcomp.c, regex.c, regex.h, regex_internal.c, regex_internal.h, @@ -127,6 +150,22 @@ * profile.c (pprint): Be sure to set ip2 in all paths through the code. Thanks to GCC 4.9 for the warning. +2014-12-20 Arnold D. Robbins <arnold@skeeve.com> + + Enable non-fatal output on per-file or global basis, + via PROCINFO. + + * awk.h (RED_NON_FATAL): New redirection flag. + * builtin.c (efwrite): If RED_NON_FATAL set, just set ERRNO and return. + (do_printf): Check errflg and if set, set ERRNO and return. + (do_print): Ditto. + (do_print_rec): Ditto. + * io.c (redflags2str): Update table. + (redirect): Check for global PROCINFO["nonfatal"] or for + PROCINFO[file, "nonfatal"] and don't fail on open if set. + Add RED_NON_FATAL to flags. + (in_PROCINFO): Make smarter and more general. + 2014-12-12 Stephen Davies <sdavies@sdc.com.au> Improve comment handling in pretty printing. @@ -1,4 +1,4 @@ -Sun Sep 28 22:19:10 IDT 2014 +Wed Dec 24 20:41:38 IST 2014 ============================ There were too many files tracking different thoughts and ideas for @@ -44,9 +44,6 @@ Minor New Features Consider relaxing the strictness of --posix. - Make it possible to put print/printf + redirections into - an expression. - ? Add an optional base to strtonum, allowing 2-36. ? Optional third argument for index indicating where to start the @@ -1482,7 +1482,7 @@ extern void register_two_way_processor(awk_two_way_processor_t *processor); extern void set_FNR(void); extern void set_NR(void); -extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg); +extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal); extern NODE *do_close(int nargs); extern int flush_io(void); extern int close_io(bool *stdio_problem); @@ -1494,6 +1494,8 @@ extern NODE *do_getline(int intovar, IOBUF *iop); extern struct redirect *getredirect(const char *str, int len); extern bool inrec(IOBUF *iop, int *errcode); extern int nextfile(IOBUF **curfile, bool skipping); +extern bool is_non_fatal_std(FILE *fp); +extern bool is_non_fatal_redirect(const char *str); /* main.c */ extern int arg_assign(char *arg, bool initing); extern int is_std_var(const char *var); @@ -129,10 +129,14 @@ wrerror: if (fp == stdout && errno == EPIPE) gawk_exit(EXIT_FATAL); + /* otherwise die verbosely */ - fatal(_("%s to \"%s\" failed (%s)"), from, - rp ? rp->value : _("standard output"), - errno ? strerror(errno) : _("reason unknown")); + if ((rp != NULL) ? is_non_fatal_redirect(rp->value) : is_non_fatal_std(fp)) + update_ERRNO_int(errno); + else + fatal(_("%s to \"%s\" failed (%s)"), from, + rp ? rp->value : _("standard output"), + errno ? strerror(errno) : _("reason unknown")); } /* do_exp --- exponential function */ @@ -1639,7 +1643,7 @@ do_printf(int nargs, int redirtype) FILE *fp = NULL; NODE *tmp; struct redirect *rp = NULL; - int errflg; /* not used, sigh */ + int errflg = 0; NODE *redir_exp = NULL; if (nargs == 0) { @@ -1650,7 +1654,7 @@ do_printf(int nargs, int redirtype) redir_exp = TOP(); if (redir_exp->type != Node_val) fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp)); - rp = redirect(redir_exp, redirtype, & errflg); + rp = redirect(redir_exp, redirtype, & errflg, true); DEREF(redir_exp); decr_sp(); } @@ -1663,9 +1667,13 @@ do_printf(int nargs, int redirtype) redir_exp = PEEK(nargs); if (redir_exp->type != Node_val) fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp)); - rp = redirect(redir_exp, redirtype, & errflg); + rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) fp = rp->output.fp; + else if (errflg) { + update_ERRNO_int(errflg); + return; + } } else if (do_debug) /* only the debugger can change the default output */ fp = output_fp; else @@ -2078,7 +2086,7 @@ void do_print(int nargs, int redirtype) { struct redirect *rp = NULL; - int errflg; /* not used, sigh */ + int errflg = 0; FILE *fp = NULL; int i; NODE *redir_exp = NULL; @@ -2090,9 +2098,13 @@ do_print(int nargs, int redirtype) redir_exp = PEEK(nargs); if (redir_exp->type != Node_val) fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp)); - rp = redirect(redir_exp, redirtype, & errflg); + rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) fp = rp->output.fp; + else if (errflg) { + update_ERRNO_int(errflg); + return; + } } else if (do_debug) /* only the debugger can change the default output */ fp = output_fp; else @@ -2148,13 +2160,13 @@ do_print_rec(int nargs, int redirtype) FILE *fp = NULL; NODE *f0; struct redirect *rp = NULL; - int errflg; /* not used, sigh */ + int errflg = 0; NODE *redir_exp = NULL; assert(nargs == 0); if (redirtype != 0) { redir_exp = TOP(); - rp = redirect(redir_exp, redirtype, & errflg); + rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) fp = rp->output.fp; DEREF(redir_exp); @@ -2162,6 +2174,11 @@ do_print_rec(int nargs, int redirtype) } else fp = output_fp; + if (errflg) { + update_ERRNO_int(errflg); + return; + } + if (fp == NULL) return; diff --git a/doc/ChangeLog b/doc/ChangeLog index 093b25bb..5420ce97 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -17,6 +17,7 @@ 2015-02-08 Arnold D. Robbins <arnold@skeeve.com> * gawktexi.in: O'Reilly fixes. + Make non-fatal i/o use "NONFATAL". 2015-02-06 Arnold D. Robbins <arnold@skeeve.com> @@ -77,12 +78,21 @@ * gawkinet.texi: Fix capitalization in document title. * gawktexi.in: Here we go again: Starting on more O'Reilly fixes. +2014-12-27 Arnold D. Robbins <arnold@skeeve.com> + + * gawktexi.in: Add info that nonfatal I/O works with stdout and + stderr. Revise version info and what was added when. + 2014-12-26 Antonio Giovanni Colombo <azc100@gmail.com> * gawktexi.in (Glossary): Really sort the items. 2014-12-24 Arnold D. Robbins <arnold@skeeve.com> + * gawktexi.in: Start documenting nonfatal output. + +2014-12-24 Arnold D. Robbins <arnold@skeeve.com> + * gawktexi.in: Add one more paragraph to new foreword. * gawktexi.in: Fix exponentiation in TeX mode. Thanks to Marco Curreli by way of Antonio Giovanni Columbo. diff --git a/doc/gawk.info b/doc/gawk.info index afdc99b9..2537830e 100644 --- a/doc/gawk.info +++ b/doc/gawk.info @@ -246,6 +246,7 @@ entitled "GNU Free Documentation License". * Special Caveats:: Things to watch out for. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. * Values:: Constants, Variables, and Regular @@ -6128,6 +6129,7 @@ function. `gawk' allows access to inherited file descriptors. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. @@ -7041,7 +7043,7 @@ that `gawk' provides: behavior. -File: gawk.info, Node: Close Files And Pipes, Next: Output Summary, Prev: Special Files, Up: Printing +File: gawk.info, Node: Close Files And Pipes, Next: Nonfatal, Prev: Special Files, Up: Printing 5.9 Closing Input and Output Redirections ========================================= @@ -7210,9 +7212,61 @@ call. See the system manual pages for information on how to decode this value. -File: gawk.info, Node: Output Summary, Next: Output Exercises, Prev: Close Files And Pipes, Up: Printing +File: gawk.info, Node: Nonfatal, Next: Output Summary, Prev: Close Files And Pipes, Up: Printing -5.10 Summary +5.10 Enabling Nonfatal Output +============================= + +This minor node describes a `gawk'-specific feature. + + In standard `awk', output with `print' or `printf' to a nonexistent +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) + + `gawk' makes it possible to detect that an error has occurred, +allowing you to possibly recover from the error, or at least print an +error message of your choosing before exiting. You can do this in one +of two ways: + + * For all output files, by assigning any value to + `PROCINFO["NONFATAL"]'. + + * On a per-file basis, by assigning any value to `PROCINFO[FILENAME, + "NONFATAL"]'. Here, FILENAME is the name of the file to which you + wish output to be nonfatal. + + Once you have enabled nonfatal output, you must check `ERRNO' after +every relevant `print' or `printf' statement to see if something went +wrong. It is also a good idea to initialize `ERRNO' to zero before +attempting the output. For example: + + $ gawk ' + > BEGIN { + > PROCINFO["NONFATAL"] = 1 + > ERRNO = 0 + > print "hi" > "/no/such/file" + > if (ERRNO) { + > print("Output failed:", ERRNO) > "/dev/stderr" + > exit 1 + > } + > }' + error--> Output failed: No such file or directory + + Here, `gawk' did not produce a fatal error; instead it let the `awk' +program code detect the problem and handle it. + + This mechanism works also for standard output and standard error. +For standard output, you may use `PROCINFO["-", "NONFATAL"]' or +`PROCINFO["/dev/stdout", "NONFATAL"]'. For standard error, use +`PROCINFO["/dev/stderr", "NONFATAL"]'. + + +File: gawk.info, Node: Output Summary, Next: Output Exercises, Prev: Nonfatal, Up: Printing + +5.11 Summary ============ * The `print' statement prints comma-separated expressions. Each @@ -7234,11 +7288,16 @@ File: gawk.info, Node: Output Summary, Next: Output Exercises, Prev: Close Fi For coprocesses, it is possible to close only one direction of the communications. + * Normally errors with `print' or `printf' are fatal. `gawk' lets + you make output errors be nonfatal either for all files or on a + per-file basis. You must then check for errors after every + relevant output statement. + File: gawk.info, Node: Output Exercises, Prev: Output Summary, Up: Printing -5.11 Exercises +5.12 Exercises ============== 1. Rewrite the program: @@ -26479,6 +26538,9 @@ the current version of `gawk'. - Directories on the command line produce a warning and are skipped (*note Command-line directories::) + - Output with `print' and `printf' need not be fatal (*note + Nonfatal::) + * New keywords: - The `BEGINFILE' and `ENDFILE' special patterns (*note @@ -26994,6 +27056,8 @@ in POSIX `awk', in the order they were added to `gawk'. * The maximum number of hexdecimal digits in `\x' escapes is now two. *Note Escape Sequences::. + * Nonfatal output with `print' and `printf'. *Note Nonfatal::. + * Support for MirBSD was removed. @@ -34667,560 +34731,561 @@ Index Tag Table: Node: Top1204 -Node: Foreword342225 -Node: Foreword446669 -Node: Preface48200 -Ref: Preface-Footnote-151071 -Ref: Preface-Footnote-251178 -Ref: Preface-Footnote-351411 -Node: History51553 -Node: Names53904 -Ref: Names-Footnote-154997 -Node: This Manual55143 -Ref: This Manual-Footnote-161643 -Node: Conventions61743 -Node: Manual History64080 -Ref: Manual History-Footnote-167073 -Ref: Manual History-Footnote-267114 -Node: How To Contribute67188 -Node: Acknowledgments68317 -Node: Getting Started73183 -Node: Running gawk75622 -Node: One-shot76812 -Node: Read Terminal78076 -Node: Long80107 -Node: Executable Scripts81620 -Ref: Executable Scripts-Footnote-184409 -Node: Comments84512 -Node: Quoting86994 -Node: DOS Quoting92512 -Node: Sample Data Files93187 -Node: Very Simple95782 -Node: Two Rules100681 -Node: More Complex102567 -Node: Statements/Lines105429 -Ref: Statements/Lines-Footnote-1109884 -Node: Other Features110149 -Node: When111085 -Ref: When-Footnote-1112839 -Node: Intro Summary112904 -Node: Invoking Gawk113788 -Node: Command Line115302 -Node: Options116100 -Ref: Options-Footnote-1131895 -Ref: Options-Footnote-2132124 -Node: Other Arguments132149 -Node: Naming Standard Input135097 -Node: Environment Variables136190 -Node: AWKPATH Variable136748 -Ref: AWKPATH Variable-Footnote-1140155 -Ref: AWKPATH Variable-Footnote-2140200 -Node: AWKLIBPATH Variable140460 -Node: Other Environment Variables141716 -Node: Exit Status145234 -Node: Include Files145910 -Node: Loading Shared Libraries149499 -Node: Obsolete150926 -Node: Undocumented151618 -Node: Invoking Summary151885 -Node: Regexp153548 -Node: Regexp Usage155002 -Node: Escape Sequences157039 -Node: Regexp Operators163268 -Ref: Regexp Operators-Footnote-1170678 -Ref: Regexp Operators-Footnote-2170825 -Node: Bracket Expressions170923 -Ref: table-char-classes172938 -Node: Leftmost Longest175880 -Node: Computed Regexps177182 -Node: GNU Regexp Operators180611 -Node: Case-sensitivity184283 -Ref: Case-sensitivity-Footnote-1187168 -Ref: Case-sensitivity-Footnote-2187403 -Node: Regexp Summary187511 -Node: Reading Files188978 -Node: Records191071 -Node: awk split records191804 -Node: gawk split records196733 -Ref: gawk split records-Footnote-1201272 -Node: Fields201309 -Ref: Fields-Footnote-1204087 -Node: Nonconstant Fields204173 -Ref: Nonconstant Fields-Footnote-1206411 -Node: Changing Fields206614 -Node: Field Separators212545 -Node: Default Field Splitting215249 -Node: Regexp Field Splitting216366 -Node: Single Character Fields219716 -Node: Command Line Field Separator220775 -Node: Full Line Fields223992 -Ref: Full Line Fields-Footnote-1225513 -Ref: Full Line Fields-Footnote-2225559 -Node: Field Splitting Summary225660 -Node: Constant Size227734 -Node: Splitting By Content232317 -Ref: Splitting By Content-Footnote-1236282 -Node: Multiple Line236445 -Ref: Multiple Line-Footnote-1242326 -Node: Getline242505 -Node: Plain Getline244712 -Node: Getline/Variable247352 -Node: Getline/File248501 -Node: Getline/Variable/File249886 -Ref: Getline/Variable/File-Footnote-1251489 -Node: Getline/Pipe251576 -Node: Getline/Variable/Pipe254254 -Node: Getline/Coprocess255385 -Node: Getline/Variable/Coprocess256649 -Node: Getline Notes257388 -Node: Getline Summary260182 -Ref: table-getline-variants260594 -Node: Read Timeout261423 -Ref: Read Timeout-Footnote-1265260 -Node: Command-line directories265318 -Node: Input Summary266223 -Node: Input Exercises269608 -Node: Printing270336 -Node: Print272113 -Node: Print Examples273570 -Node: Output Separators276349 -Node: OFMT278367 -Node: Printf279722 -Node: Basic Printf280507 -Node: Control Letters282079 -Node: Format Modifiers286064 -Node: Printf Examples292074 -Node: Redirection294560 -Node: Special FD301398 -Ref: Special FD-Footnote-1304564 -Node: Special Files304638 -Node: Other Inherited Files305255 -Node: Special Network306255 -Node: Special Caveats307117 -Node: Close Files And Pipes308066 -Ref: Close Files And Pipes-Footnote-1315257 -Ref: Close Files And Pipes-Footnote-2315405 -Node: Output Summary315555 -Node: Output Exercises316553 -Node: Expressions317233 -Node: Values318422 -Node: Constants319099 -Node: Scalar Constants319790 -Ref: Scalar Constants-Footnote-1320652 -Node: Nondecimal-numbers320902 -Node: Regexp Constants323912 -Node: Using Constant Regexps324438 -Node: Variables327601 -Node: Using Variables328258 -Node: Assignment Options330169 -Node: Conversion332044 -Node: Strings And Numbers332568 -Ref: Strings And Numbers-Footnote-1335633 -Node: Locale influences conversions335742 -Ref: table-locale-affects338488 -Node: All Operators339080 -Node: Arithmetic Ops339709 -Node: Concatenation342214 -Ref: Concatenation-Footnote-1345033 -Node: Assignment Ops345140 -Ref: table-assign-ops350119 -Node: Increment Ops351429 -Node: Truth Values and Conditions354860 -Node: Truth Values355943 -Node: Typing and Comparison356992 -Node: Variable Typing357808 -Node: Comparison Operators361475 -Ref: table-relational-ops361885 -Node: POSIX String Comparison365380 -Ref: POSIX String Comparison-Footnote-1366452 -Node: Boolean Ops366591 -Ref: Boolean Ops-Footnote-1371069 -Node: Conditional Exp371160 -Node: Function Calls372898 -Node: Precedence376778 -Node: Locales380438 -Node: Expressions Summary382070 -Node: Patterns and Actions384641 -Node: Pattern Overview385761 -Node: Regexp Patterns387440 -Node: Expression Patterns387983 -Node: Ranges391763 -Node: BEGIN/END394870 -Node: Using BEGIN/END395631 -Ref: Using BEGIN/END-Footnote-1398367 -Node: I/O And BEGIN/END398473 -Node: BEGINFILE/ENDFILE400788 -Node: Empty403685 -Node: Using Shell Variables404002 -Node: Action Overview406275 -Node: Statements408601 -Node: If Statement410449 -Node: While Statement411944 -Node: Do Statement413972 -Node: For Statement415120 -Node: Switch Statement418278 -Node: Break Statement420660 -Node: Continue Statement422701 -Node: Next Statement424528 -Node: Nextfile Statement426909 -Node: Exit Statement429537 -Node: Built-in Variables431948 -Node: User-modified433081 -Ref: User-modified-Footnote-1440784 -Node: Auto-set440846 -Ref: Auto-set-Footnote-1454555 -Ref: Auto-set-Footnote-2454760 -Node: ARGC and ARGV454816 -Node: Pattern Action Summary459034 -Node: Arrays461467 -Node: Array Basics462796 -Node: Array Intro463640 -Ref: figure-array-elements465574 -Ref: Array Intro-Footnote-1468194 -Node: Reference to Elements468322 -Node: Assigning Elements470784 -Node: Array Example471275 -Node: Scanning an Array473034 -Node: Controlling Scanning476054 -Ref: Controlling Scanning-Footnote-1481448 -Node: Numeric Array Subscripts481764 -Node: Uninitialized Subscripts483949 -Node: Delete485566 -Ref: Delete-Footnote-1488315 -Node: Multidimensional488372 -Node: Multiscanning491469 -Node: Arrays of Arrays493058 -Node: Arrays Summary497812 -Node: Functions499903 -Node: Built-in500942 -Node: Calling Built-in502020 -Node: Numeric Functions504015 -Ref: Numeric Functions-Footnote-1508833 -Ref: Numeric Functions-Footnote-2509190 -Ref: Numeric Functions-Footnote-3509238 -Node: String Functions509510 -Ref: String Functions-Footnote-1533011 -Ref: String Functions-Footnote-2533140 -Ref: String Functions-Footnote-3533388 -Node: Gory Details533475 -Ref: table-sub-escapes535256 -Ref: table-sub-proposed536771 -Ref: table-posix-sub538133 -Ref: table-gensub-escapes539670 -Ref: Gory Details-Footnote-1540503 -Node: I/O Functions540654 -Ref: I/O Functions-Footnote-1547890 -Node: Time Functions548037 -Ref: Time Functions-Footnote-1558546 -Ref: Time Functions-Footnote-2558614 -Ref: Time Functions-Footnote-3558772 -Ref: Time Functions-Footnote-4558883 -Ref: Time Functions-Footnote-5558995 -Ref: Time Functions-Footnote-6559222 -Node: Bitwise Functions559488 -Ref: table-bitwise-ops560050 -Ref: Bitwise Functions-Footnote-1564378 -Node: Type Functions564550 -Node: I18N Functions565702 -Node: User-defined567349 -Node: Definition Syntax568154 -Ref: Definition Syntax-Footnote-1573813 -Node: Function Example573884 -Ref: Function Example-Footnote-1576805 -Node: Function Caveats576827 -Node: Calling A Function577345 -Node: Variable Scope578303 -Node: Pass By Value/Reference581296 -Node: Return Statement584793 -Node: Dynamic Typing587772 -Node: Indirect Calls588701 -Ref: Indirect Calls-Footnote-1600007 -Node: Functions Summary600135 -Node: Library Functions602837 -Ref: Library Functions-Footnote-1606445 -Ref: Library Functions-Footnote-2606588 -Node: Library Names606759 -Ref: Library Names-Footnote-1610217 -Ref: Library Names-Footnote-2610440 -Node: General Functions610526 -Node: Strtonum Function611629 -Node: Assert Function614651 -Node: Round Function617975 -Node: Cliff Random Function619516 -Node: Ordinal Functions620532 -Ref: Ordinal Functions-Footnote-1623595 -Ref: Ordinal Functions-Footnote-2623847 -Node: Join Function624058 -Ref: Join Function-Footnote-1625828 -Node: Getlocaltime Function626028 -Node: Readfile Function629772 -Node: Shell Quoting631744 -Node: Data File Management633145 -Node: Filetrans Function633777 -Node: Rewind Function637873 -Node: File Checking639259 -Ref: File Checking-Footnote-1640592 -Node: Empty Files640793 -Node: Ignoring Assigns642772 -Node: Getopt Function644322 -Ref: Getopt Function-Footnote-1655786 -Node: Passwd Functions655986 -Ref: Passwd Functions-Footnote-1664826 -Node: Group Functions664914 -Ref: Group Functions-Footnote-1672811 -Node: Walking Arrays673016 -Node: Library Functions Summary674616 -Node: Library Exercises676020 -Node: Sample Programs677300 -Node: Running Examples678070 -Node: Clones678798 -Node: Cut Program680022 -Node: Egrep Program689742 -Ref: Egrep Program-Footnote-1697245 -Node: Id Program697355 -Node: Split Program701031 -Ref: Split Program-Footnote-1704485 -Node: Tee Program704613 -Node: Uniq Program707402 -Node: Wc Program714821 -Ref: Wc Program-Footnote-1719071 -Node: Miscellaneous Programs719165 -Node: Dupword Program720378 -Node: Alarm Program722409 -Node: Translate Program727214 -Ref: Translate Program-Footnote-1731777 -Node: Labels Program732047 -Ref: Labels Program-Footnote-1735398 -Node: Word Sorting735482 -Node: History Sorting739552 -Node: Extract Program741387 -Node: Simple Sed748911 -Node: Igawk Program751981 -Ref: Igawk Program-Footnote-1766307 -Ref: Igawk Program-Footnote-2766508 -Ref: Igawk Program-Footnote-3766630 -Node: Anagram Program766745 -Node: Signature Program769806 -Node: Programs Summary771053 -Node: Programs Exercises772274 -Ref: Programs Exercises-Footnote-1776405 -Node: Advanced Features776496 -Node: Nondecimal Data778478 -Node: Array Sorting780068 -Node: Controlling Array Traversal780768 -Ref: Controlling Array Traversal-Footnote-1789134 -Node: Array Sorting Functions789252 -Ref: Array Sorting Functions-Footnote-1793138 -Node: Two-way I/O793334 -Ref: Two-way I/O-Footnote-1798279 -Ref: Two-way I/O-Footnote-2798465 -Node: TCP/IP Networking798547 -Node: Profiling801419 -Node: Advanced Features Summary809690 -Node: Internationalization811623 -Node: I18N and L10N813103 -Node: Explaining gettext813789 -Ref: Explaining gettext-Footnote-1818814 -Ref: Explaining gettext-Footnote-2818998 -Node: Programmer i18n819163 -Ref: Programmer i18n-Footnote-1824039 -Node: Translator i18n824088 -Node: String Extraction824882 -Ref: String Extraction-Footnote-1826013 -Node: Printf Ordering826099 -Ref: Printf Ordering-Footnote-1828885 -Node: I18N Portability828949 -Ref: I18N Portability-Footnote-1831405 -Node: I18N Example831468 -Ref: I18N Example-Footnote-1834271 -Node: Gawk I18N834343 -Node: I18N Summary834987 -Node: Debugger836327 -Node: Debugging837349 -Node: Debugging Concepts837790 -Node: Debugging Terms839600 -Node: Awk Debugging842172 -Node: Sample Debugging Session843078 -Node: Debugger Invocation843612 -Node: Finding The Bug844997 -Node: List of Debugger Commands851476 -Node: Breakpoint Control852808 -Node: Debugger Execution Control856485 -Node: Viewing And Changing Data859844 -Node: Execution Stack863220 -Node: Debugger Info864855 -Node: Miscellaneous Debugger Commands868900 -Node: Readline Support873901 -Node: Limitations874795 -Node: Debugging Summary876910 -Node: Arbitrary Precision Arithmetic878084 -Node: Computer Arithmetic879500 -Ref: table-numeric-ranges883099 -Ref: Computer Arithmetic-Footnote-1883623 -Node: Math Definitions883680 -Ref: table-ieee-formats886975 -Ref: Math Definitions-Footnote-1887579 -Node: MPFR features887684 -Node: FP Math Caution889355 -Ref: FP Math Caution-Footnote-1890405 -Node: Inexactness of computations890774 -Node: Inexact representation891733 -Node: Comparing FP Values893091 -Node: Errors accumulate894173 -Node: Getting Accuracy895605 -Node: Try To Round898309 -Node: Setting precision899208 -Ref: table-predefined-precision-strings899892 -Node: Setting the rounding mode901721 -Ref: table-gawk-rounding-modes902085 -Ref: Setting the rounding mode-Footnote-1905537 -Node: Arbitrary Precision Integers905716 -Ref: Arbitrary Precision Integers-Footnote-1910614 -Node: POSIX Floating Point Problems910763 -Ref: POSIX Floating Point Problems-Footnote-1914642 -Node: Floating point summary914680 -Node: Dynamic Extensions916876 -Node: Extension Intro918428 -Node: Plugin License919693 -Node: Extension Mechanism Outline920490 -Ref: figure-load-extension920918 -Ref: figure-register-new-function922398 -Ref: figure-call-new-function923402 -Node: Extension API Description925389 -Node: Extension API Functions Introduction926839 -Node: General Data Types931660 -Ref: General Data Types-Footnote-1937560 -Node: Memory Allocation Functions937859 -Ref: Memory Allocation Functions-Footnote-1940698 -Node: Constructor Functions940797 -Node: Registration Functions942532 -Node: Extension Functions943217 -Node: Exit Callback Functions945514 -Node: Extension Version String946762 -Node: Input Parsers947425 -Node: Output Wrappers957300 -Node: Two-way processors961813 -Node: Printing Messages964076 -Ref: Printing Messages-Footnote-1965152 -Node: Updating `ERRNO'965304 -Node: Requesting Values966044 -Ref: table-value-types-returned966771 -Node: Accessing Parameters967728 -Node: Symbol Table Access968962 -Node: Symbol table by name969476 -Node: Symbol table by cookie971496 -Ref: Symbol table by cookie-Footnote-1975641 -Node: Cached values975704 -Ref: Cached values-Footnote-1979200 -Node: Array Manipulation979291 -Ref: Array Manipulation-Footnote-1980389 -Node: Array Data Types980426 -Ref: Array Data Types-Footnote-1983081 -Node: Array Functions983173 -Node: Flattening Arrays987032 -Node: Creating Arrays993934 -Node: Extension API Variables998705 -Node: Extension Versioning999341 -Node: Extension API Informational Variables1001232 -Node: Extension API Boilerplate1002297 -Node: Finding Extensions1006106 -Node: Extension Example1006666 -Node: Internal File Description1007438 -Node: Internal File Ops1011505 -Ref: Internal File Ops-Footnote-11023256 -Node: Using Internal File Ops1023396 -Ref: Using Internal File Ops-Footnote-11025779 -Node: Extension Samples1026052 -Node: Extension Sample File Functions1027580 -Node: Extension Sample Fnmatch1035261 -Node: Extension Sample Fork1036749 -Node: Extension Sample Inplace1037964 -Node: Extension Sample Ord1039640 -Node: Extension Sample Readdir1040476 -Ref: table-readdir-file-types1041353 -Node: Extension Sample Revout1042164 -Node: Extension Sample Rev2way1042753 -Node: Extension Sample Read write array1043493 -Node: Extension Sample Readfile1045433 -Node: Extension Sample Time1046528 -Node: Extension Sample API Tests1047876 -Node: gawkextlib1048367 -Node: Extension summary1051045 -Node: Extension Exercises1054734 -Node: Language History1055456 -Node: V7/SVR3.11057112 -Node: SVR41059265 -Node: POSIX1060699 -Node: BTL1062080 -Node: POSIX/GNU1062811 -Node: Feature History1068556 -Node: Common Extensions1082282 -Node: Ranges and Locales1083654 -Ref: Ranges and Locales-Footnote-11088273 -Ref: Ranges and Locales-Footnote-21088300 -Ref: Ranges and Locales-Footnote-31088535 -Node: Contributors1088756 -Node: History summary1094296 -Node: Installation1095675 -Node: Gawk Distribution1096621 -Node: Getting1097105 -Node: Extracting1097928 -Node: Distribution contents1099565 -Node: Unix Installation1105667 -Node: Quick Installation1106350 -Node: Shell Startup Files1108761 -Node: Additional Configuration Options1109840 -Node: Configuration Philosophy1111644 -Node: Non-Unix Installation1114013 -Node: PC Installation1114471 -Node: PC Binary Installation1115791 -Node: PC Compiling1117639 -Ref: PC Compiling-Footnote-11120660 -Node: PC Testing1120769 -Node: PC Using1121945 -Node: Cygwin1126060 -Node: MSYS1126830 -Node: VMS Installation1127331 -Node: VMS Compilation1128123 -Ref: VMS Compilation-Footnote-11129352 -Node: VMS Dynamic Extensions1129410 -Node: VMS Installation Details1131094 -Node: VMS Running1133345 -Node: VMS GNV1136185 -Node: VMS Old Gawk1136920 -Node: Bugs1137390 -Node: Other Versions1141279 -Node: Installation summary1147713 -Node: Notes1148772 -Node: Compatibility Mode1149637 -Node: Additions1150419 -Node: Accessing The Source1151344 -Node: Adding Code1152779 -Node: New Ports1158936 -Node: Derived Files1163418 -Ref: Derived Files-Footnote-11168893 -Ref: Derived Files-Footnote-21168927 -Ref: Derived Files-Footnote-31169523 -Node: Future Extensions1169637 -Node: Implementation Limitations1170243 -Node: Extension Design1171491 -Node: Old Extension Problems1172645 -Ref: Old Extension Problems-Footnote-11174162 -Node: Extension New Mechanism Goals1174219 -Ref: Extension New Mechanism Goals-Footnote-11177579 -Node: Extension Other Design Decisions1177768 -Node: Extension Future Growth1179876 -Node: Old Extension Mechanism1180712 -Node: Notes summary1182474 -Node: Basic Concepts1183660 -Node: Basic High Level1184341 -Ref: figure-general-flow1184613 -Ref: figure-process-flow1185212 -Ref: Basic High Level-Footnote-11188441 -Node: Basic Data Typing1188626 -Node: Glossary1191954 -Node: Copying1223883 -Node: GNU Free Documentation License1261439 -Node: Index1286575 +Node: Foreword342291 +Node: Foreword446735 +Node: Preface48266 +Ref: Preface-Footnote-151137 +Ref: Preface-Footnote-251244 +Ref: Preface-Footnote-351477 +Node: History51619 +Node: Names53970 +Ref: Names-Footnote-155063 +Node: This Manual55209 +Ref: This Manual-Footnote-161709 +Node: Conventions61809 +Node: Manual History64146 +Ref: Manual History-Footnote-167139 +Ref: Manual History-Footnote-267180 +Node: How To Contribute67254 +Node: Acknowledgments68383 +Node: Getting Started73249 +Node: Running gawk75688 +Node: One-shot76878 +Node: Read Terminal78142 +Node: Long80173 +Node: Executable Scripts81686 +Ref: Executable Scripts-Footnote-184475 +Node: Comments84578 +Node: Quoting87060 +Node: DOS Quoting92578 +Node: Sample Data Files93253 +Node: Very Simple95848 +Node: Two Rules100747 +Node: More Complex102633 +Node: Statements/Lines105495 +Ref: Statements/Lines-Footnote-1109950 +Node: Other Features110215 +Node: When111151 +Ref: When-Footnote-1112905 +Node: Intro Summary112970 +Node: Invoking Gawk113854 +Node: Command Line115368 +Node: Options116166 +Ref: Options-Footnote-1131961 +Ref: Options-Footnote-2132190 +Node: Other Arguments132215 +Node: Naming Standard Input135163 +Node: Environment Variables136256 +Node: AWKPATH Variable136814 +Ref: AWKPATH Variable-Footnote-1140221 +Ref: AWKPATH Variable-Footnote-2140266 +Node: AWKLIBPATH Variable140526 +Node: Other Environment Variables141782 +Node: Exit Status145300 +Node: Include Files145976 +Node: Loading Shared Libraries149565 +Node: Obsolete150992 +Node: Undocumented151684 +Node: Invoking Summary151951 +Node: Regexp153614 +Node: Regexp Usage155068 +Node: Escape Sequences157105 +Node: Regexp Operators163334 +Ref: Regexp Operators-Footnote-1170744 +Ref: Regexp Operators-Footnote-2170891 +Node: Bracket Expressions170989 +Ref: table-char-classes173004 +Node: Leftmost Longest175946 +Node: Computed Regexps177248 +Node: GNU Regexp Operators180677 +Node: Case-sensitivity184349 +Ref: Case-sensitivity-Footnote-1187234 +Ref: Case-sensitivity-Footnote-2187469 +Node: Regexp Summary187577 +Node: Reading Files189044 +Node: Records191137 +Node: awk split records191870 +Node: gawk split records196799 +Ref: gawk split records-Footnote-1201338 +Node: Fields201375 +Ref: Fields-Footnote-1204153 +Node: Nonconstant Fields204239 +Ref: Nonconstant Fields-Footnote-1206477 +Node: Changing Fields206680 +Node: Field Separators212611 +Node: Default Field Splitting215315 +Node: Regexp Field Splitting216432 +Node: Single Character Fields219782 +Node: Command Line Field Separator220841 +Node: Full Line Fields224058 +Ref: Full Line Fields-Footnote-1225579 +Ref: Full Line Fields-Footnote-2225625 +Node: Field Splitting Summary225726 +Node: Constant Size227800 +Node: Splitting By Content232383 +Ref: Splitting By Content-Footnote-1236348 +Node: Multiple Line236511 +Ref: Multiple Line-Footnote-1242392 +Node: Getline242571 +Node: Plain Getline244778 +Node: Getline/Variable247418 +Node: Getline/File248567 +Node: Getline/Variable/File249952 +Ref: Getline/Variable/File-Footnote-1251555 +Node: Getline/Pipe251642 +Node: Getline/Variable/Pipe254320 +Node: Getline/Coprocess255451 +Node: Getline/Variable/Coprocess256715 +Node: Getline Notes257454 +Node: Getline Summary260248 +Ref: table-getline-variants260660 +Node: Read Timeout261489 +Ref: Read Timeout-Footnote-1265326 +Node: Command-line directories265384 +Node: Input Summary266289 +Node: Input Exercises269674 +Node: Printing270402 +Node: Print272237 +Node: Print Examples273694 +Node: Output Separators276473 +Node: OFMT278491 +Node: Printf279846 +Node: Basic Printf280631 +Node: Control Letters282203 +Node: Format Modifiers286188 +Node: Printf Examples292198 +Node: Redirection294684 +Node: Special FD301522 +Ref: Special FD-Footnote-1304688 +Node: Special Files304762 +Node: Other Inherited Files305379 +Node: Special Network306379 +Node: Special Caveats307241 +Node: Close Files And Pipes308190 +Ref: Close Files And Pipes-Footnote-1315375 +Ref: Close Files And Pipes-Footnote-2315523 +Node: Nonfatal315673 +Node: Output Summary317596 +Node: Output Exercises318817 +Node: Expressions319497 +Node: Values320686 +Node: Constants321363 +Node: Scalar Constants322054 +Ref: Scalar Constants-Footnote-1322916 +Node: Nondecimal-numbers323166 +Node: Regexp Constants326176 +Node: Using Constant Regexps326702 +Node: Variables329865 +Node: Using Variables330522 +Node: Assignment Options332433 +Node: Conversion334308 +Node: Strings And Numbers334832 +Ref: Strings And Numbers-Footnote-1337897 +Node: Locale influences conversions338006 +Ref: table-locale-affects340752 +Node: All Operators341344 +Node: Arithmetic Ops341973 +Node: Concatenation344478 +Ref: Concatenation-Footnote-1347297 +Node: Assignment Ops347404 +Ref: table-assign-ops352383 +Node: Increment Ops353693 +Node: Truth Values and Conditions357124 +Node: Truth Values358207 +Node: Typing and Comparison359256 +Node: Variable Typing360072 +Node: Comparison Operators363739 +Ref: table-relational-ops364149 +Node: POSIX String Comparison367644 +Ref: POSIX String Comparison-Footnote-1368716 +Node: Boolean Ops368855 +Ref: Boolean Ops-Footnote-1373333 +Node: Conditional Exp373424 +Node: Function Calls375162 +Node: Precedence379042 +Node: Locales382702 +Node: Expressions Summary384334 +Node: Patterns and Actions386905 +Node: Pattern Overview388025 +Node: Regexp Patterns389704 +Node: Expression Patterns390247 +Node: Ranges394027 +Node: BEGIN/END397134 +Node: Using BEGIN/END397895 +Ref: Using BEGIN/END-Footnote-1400631 +Node: I/O And BEGIN/END400737 +Node: BEGINFILE/ENDFILE403052 +Node: Empty405949 +Node: Using Shell Variables406266 +Node: Action Overview408539 +Node: Statements410865 +Node: If Statement412713 +Node: While Statement414208 +Node: Do Statement416236 +Node: For Statement417384 +Node: Switch Statement420542 +Node: Break Statement422924 +Node: Continue Statement424965 +Node: Next Statement426792 +Node: Nextfile Statement429173 +Node: Exit Statement431801 +Node: Built-in Variables434212 +Node: User-modified435345 +Ref: User-modified-Footnote-1443048 +Node: Auto-set443110 +Ref: Auto-set-Footnote-1456819 +Ref: Auto-set-Footnote-2457024 +Node: ARGC and ARGV457080 +Node: Pattern Action Summary461298 +Node: Arrays463731 +Node: Array Basics465060 +Node: Array Intro465904 +Ref: figure-array-elements467838 +Ref: Array Intro-Footnote-1470458 +Node: Reference to Elements470586 +Node: Assigning Elements473048 +Node: Array Example473539 +Node: Scanning an Array475298 +Node: Controlling Scanning478318 +Ref: Controlling Scanning-Footnote-1483712 +Node: Numeric Array Subscripts484028 +Node: Uninitialized Subscripts486213 +Node: Delete487830 +Ref: Delete-Footnote-1490579 +Node: Multidimensional490636 +Node: Multiscanning493733 +Node: Arrays of Arrays495322 +Node: Arrays Summary500076 +Node: Functions502167 +Node: Built-in503206 +Node: Calling Built-in504284 +Node: Numeric Functions506279 +Ref: Numeric Functions-Footnote-1511097 +Ref: Numeric Functions-Footnote-2511454 +Ref: Numeric Functions-Footnote-3511502 +Node: String Functions511774 +Ref: String Functions-Footnote-1535275 +Ref: String Functions-Footnote-2535404 +Ref: String Functions-Footnote-3535652 +Node: Gory Details535739 +Ref: table-sub-escapes537520 +Ref: table-sub-proposed539035 +Ref: table-posix-sub540397 +Ref: table-gensub-escapes541934 +Ref: Gory Details-Footnote-1542767 +Node: I/O Functions542918 +Ref: I/O Functions-Footnote-1550154 +Node: Time Functions550301 +Ref: Time Functions-Footnote-1560810 +Ref: Time Functions-Footnote-2560878 +Ref: Time Functions-Footnote-3561036 +Ref: Time Functions-Footnote-4561147 +Ref: Time Functions-Footnote-5561259 +Ref: Time Functions-Footnote-6561486 +Node: Bitwise Functions561752 +Ref: table-bitwise-ops562314 +Ref: Bitwise Functions-Footnote-1566642 +Node: Type Functions566814 +Node: I18N Functions567966 +Node: User-defined569613 +Node: Definition Syntax570418 +Ref: Definition Syntax-Footnote-1576077 +Node: Function Example576148 +Ref: Function Example-Footnote-1579069 +Node: Function Caveats579091 +Node: Calling A Function579609 +Node: Variable Scope580567 +Node: Pass By Value/Reference583560 +Node: Return Statement587057 +Node: Dynamic Typing590036 +Node: Indirect Calls590965 +Ref: Indirect Calls-Footnote-1602271 +Node: Functions Summary602399 +Node: Library Functions605101 +Ref: Library Functions-Footnote-1608709 +Ref: Library Functions-Footnote-2608852 +Node: Library Names609023 +Ref: Library Names-Footnote-1612481 +Ref: Library Names-Footnote-2612704 +Node: General Functions612790 +Node: Strtonum Function613893 +Node: Assert Function616915 +Node: Round Function620239 +Node: Cliff Random Function621780 +Node: Ordinal Functions622796 +Ref: Ordinal Functions-Footnote-1625859 +Ref: Ordinal Functions-Footnote-2626111 +Node: Join Function626322 +Ref: Join Function-Footnote-1628092 +Node: Getlocaltime Function628292 +Node: Readfile Function632036 +Node: Shell Quoting634008 +Node: Data File Management635409 +Node: Filetrans Function636041 +Node: Rewind Function640137 +Node: File Checking641523 +Ref: File Checking-Footnote-1642856 +Node: Empty Files643057 +Node: Ignoring Assigns645036 +Node: Getopt Function646586 +Ref: Getopt Function-Footnote-1658050 +Node: Passwd Functions658250 +Ref: Passwd Functions-Footnote-1667090 +Node: Group Functions667178 +Ref: Group Functions-Footnote-1675075 +Node: Walking Arrays675280 +Node: Library Functions Summary676880 +Node: Library Exercises678284 +Node: Sample Programs679564 +Node: Running Examples680334 +Node: Clones681062 +Node: Cut Program682286 +Node: Egrep Program692006 +Ref: Egrep Program-Footnote-1699509 +Node: Id Program699619 +Node: Split Program703295 +Ref: Split Program-Footnote-1706749 +Node: Tee Program706877 +Node: Uniq Program709666 +Node: Wc Program717085 +Ref: Wc Program-Footnote-1721335 +Node: Miscellaneous Programs721429 +Node: Dupword Program722642 +Node: Alarm Program724673 +Node: Translate Program729478 +Ref: Translate Program-Footnote-1734041 +Node: Labels Program734311 +Ref: Labels Program-Footnote-1737662 +Node: Word Sorting737746 +Node: History Sorting741816 +Node: Extract Program743651 +Node: Simple Sed751175 +Node: Igawk Program754245 +Ref: Igawk Program-Footnote-1768571 +Ref: Igawk Program-Footnote-2768772 +Ref: Igawk Program-Footnote-3768894 +Node: Anagram Program769009 +Node: Signature Program772070 +Node: Programs Summary773317 +Node: Programs Exercises774538 +Ref: Programs Exercises-Footnote-1778669 +Node: Advanced Features778760 +Node: Nondecimal Data780742 +Node: Array Sorting782332 +Node: Controlling Array Traversal783032 +Ref: Controlling Array Traversal-Footnote-1791398 +Node: Array Sorting Functions791516 +Ref: Array Sorting Functions-Footnote-1795402 +Node: Two-way I/O795598 +Ref: Two-way I/O-Footnote-1800543 +Ref: Two-way I/O-Footnote-2800729 +Node: TCP/IP Networking800811 +Node: Profiling803683 +Node: Advanced Features Summary811954 +Node: Internationalization813887 +Node: I18N and L10N815367 +Node: Explaining gettext816053 +Ref: Explaining gettext-Footnote-1821078 +Ref: Explaining gettext-Footnote-2821262 +Node: Programmer i18n821427 +Ref: Programmer i18n-Footnote-1826303 +Node: Translator i18n826352 +Node: String Extraction827146 +Ref: String Extraction-Footnote-1828277 +Node: Printf Ordering828363 +Ref: Printf Ordering-Footnote-1831149 +Node: I18N Portability831213 +Ref: I18N Portability-Footnote-1833669 +Node: I18N Example833732 +Ref: I18N Example-Footnote-1836535 +Node: Gawk I18N836607 +Node: I18N Summary837251 +Node: Debugger838591 +Node: Debugging839613 +Node: Debugging Concepts840054 +Node: Debugging Terms841864 +Node: Awk Debugging844436 +Node: Sample Debugging Session845342 +Node: Debugger Invocation845876 +Node: Finding The Bug847261 +Node: List of Debugger Commands853740 +Node: Breakpoint Control855072 +Node: Debugger Execution Control858749 +Node: Viewing And Changing Data862108 +Node: Execution Stack865484 +Node: Debugger Info867119 +Node: Miscellaneous Debugger Commands871164 +Node: Readline Support876165 +Node: Limitations877059 +Node: Debugging Summary879174 +Node: Arbitrary Precision Arithmetic880348 +Node: Computer Arithmetic881764 +Ref: table-numeric-ranges885363 +Ref: Computer Arithmetic-Footnote-1885887 +Node: Math Definitions885944 +Ref: table-ieee-formats889239 +Ref: Math Definitions-Footnote-1889843 +Node: MPFR features889948 +Node: FP Math Caution891619 +Ref: FP Math Caution-Footnote-1892669 +Node: Inexactness of computations893038 +Node: Inexact representation893997 +Node: Comparing FP Values895355 +Node: Errors accumulate896437 +Node: Getting Accuracy897869 +Node: Try To Round900573 +Node: Setting precision901472 +Ref: table-predefined-precision-strings902156 +Node: Setting the rounding mode903985 +Ref: table-gawk-rounding-modes904349 +Ref: Setting the rounding mode-Footnote-1907801 +Node: Arbitrary Precision Integers907980 +Ref: Arbitrary Precision Integers-Footnote-1912878 +Node: POSIX Floating Point Problems913027 +Ref: POSIX Floating Point Problems-Footnote-1916906 +Node: Floating point summary916944 +Node: Dynamic Extensions919140 +Node: Extension Intro920692 +Node: Plugin License921957 +Node: Extension Mechanism Outline922754 +Ref: figure-load-extension923182 +Ref: figure-register-new-function924662 +Ref: figure-call-new-function925666 +Node: Extension API Description927653 +Node: Extension API Functions Introduction929103 +Node: General Data Types933924 +Ref: General Data Types-Footnote-1939824 +Node: Memory Allocation Functions940123 +Ref: Memory Allocation Functions-Footnote-1942962 +Node: Constructor Functions943061 +Node: Registration Functions944796 +Node: Extension Functions945481 +Node: Exit Callback Functions947778 +Node: Extension Version String949026 +Node: Input Parsers949689 +Node: Output Wrappers959564 +Node: Two-way processors964077 +Node: Printing Messages966340 +Ref: Printing Messages-Footnote-1967416 +Node: Updating `ERRNO'967568 +Node: Requesting Values968308 +Ref: table-value-types-returned969035 +Node: Accessing Parameters969992 +Node: Symbol Table Access971226 +Node: Symbol table by name971740 +Node: Symbol table by cookie973760 +Ref: Symbol table by cookie-Footnote-1977905 +Node: Cached values977968 +Ref: Cached values-Footnote-1981464 +Node: Array Manipulation981555 +Ref: Array Manipulation-Footnote-1982653 +Node: Array Data Types982690 +Ref: Array Data Types-Footnote-1985345 +Node: Array Functions985437 +Node: Flattening Arrays989296 +Node: Creating Arrays996198 +Node: Extension API Variables1000969 +Node: Extension Versioning1001605 +Node: Extension API Informational Variables1003496 +Node: Extension API Boilerplate1004561 +Node: Finding Extensions1008370 +Node: Extension Example1008930 +Node: Internal File Description1009702 +Node: Internal File Ops1013769 +Ref: Internal File Ops-Footnote-11025520 +Node: Using Internal File Ops1025660 +Ref: Using Internal File Ops-Footnote-11028043 +Node: Extension Samples1028316 +Node: Extension Sample File Functions1029844 +Node: Extension Sample Fnmatch1037525 +Node: Extension Sample Fork1039013 +Node: Extension Sample Inplace1040228 +Node: Extension Sample Ord1041904 +Node: Extension Sample Readdir1042740 +Ref: table-readdir-file-types1043617 +Node: Extension Sample Revout1044428 +Node: Extension Sample Rev2way1045017 +Node: Extension Sample Read write array1045757 +Node: Extension Sample Readfile1047697 +Node: Extension Sample Time1048792 +Node: Extension Sample API Tests1050140 +Node: gawkextlib1050631 +Node: Extension summary1053309 +Node: Extension Exercises1056998 +Node: Language History1057720 +Node: V7/SVR3.11059376 +Node: SVR41061529 +Node: POSIX1062963 +Node: BTL1064344 +Node: POSIX/GNU1065075 +Node: Feature History1070911 +Node: Common Extensions1084705 +Node: Ranges and Locales1086077 +Ref: Ranges and Locales-Footnote-11090696 +Ref: Ranges and Locales-Footnote-21090723 +Ref: Ranges and Locales-Footnote-31090958 +Node: Contributors1091179 +Node: History summary1096719 +Node: Installation1098098 +Node: Gawk Distribution1099044 +Node: Getting1099528 +Node: Extracting1100351 +Node: Distribution contents1101988 +Node: Unix Installation1108090 +Node: Quick Installation1108773 +Node: Shell Startup Files1111184 +Node: Additional Configuration Options1112263 +Node: Configuration Philosophy1114067 +Node: Non-Unix Installation1116436 +Node: PC Installation1116894 +Node: PC Binary Installation1118214 +Node: PC Compiling1120062 +Ref: PC Compiling-Footnote-11123083 +Node: PC Testing1123192 +Node: PC Using1124368 +Node: Cygwin1128483 +Node: MSYS1129253 +Node: VMS Installation1129754 +Node: VMS Compilation1130546 +Ref: VMS Compilation-Footnote-11131775 +Node: VMS Dynamic Extensions1131833 +Node: VMS Installation Details1133517 +Node: VMS Running1135768 +Node: VMS GNV1138608 +Node: VMS Old Gawk1139343 +Node: Bugs1139813 +Node: Other Versions1143702 +Node: Installation summary1150136 +Node: Notes1151195 +Node: Compatibility Mode1152060 +Node: Additions1152842 +Node: Accessing The Source1153767 +Node: Adding Code1155202 +Node: New Ports1161359 +Node: Derived Files1165841 +Ref: Derived Files-Footnote-11171316 +Ref: Derived Files-Footnote-21171350 +Ref: Derived Files-Footnote-31171946 +Node: Future Extensions1172060 +Node: Implementation Limitations1172666 +Node: Extension Design1173914 +Node: Old Extension Problems1175068 +Ref: Old Extension Problems-Footnote-11176585 +Node: Extension New Mechanism Goals1176642 +Ref: Extension New Mechanism Goals-Footnote-11180002 +Node: Extension Other Design Decisions1180191 +Node: Extension Future Growth1182299 +Node: Old Extension Mechanism1183135 +Node: Notes summary1184897 +Node: Basic Concepts1186083 +Node: Basic High Level1186764 +Ref: figure-general-flow1187036 +Ref: figure-process-flow1187635 +Ref: Basic High Level-Footnote-11190864 +Node: Basic Data Typing1191049 +Node: Glossary1194377 +Node: Copying1226306 +Node: GNU Free Documentation License1263862 +Node: Index1288998 End Tag Table diff --git a/doc/gawk.texi b/doc/gawk.texi index 7136a7de..c1fb6f10 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -633,6 +633,7 @@ particular records in a file and perform operations upon them. * Special Caveats:: Things to watch out for. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. * Values:: Constants, Variables, and Regular @@ -8929,6 +8930,7 @@ and discusses the @code{close()} built-in function. @command{gawk} allows access to inherited file descriptors. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. @end menu @@ -10435,6 +10437,63 @@ when closing a pipe. @end ifnotdocbook +@node Nonfatal +@section Enabling Nonfatal Output + +This @value{SECTION} describes a @command{gawk}-specific feature. + +In standard @command{awk}, output with @code{print} or @code{printf} +to a nonexistent file, or some other I/O error (such as filling up the +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) +@end example + +@command{gawk} makes it possible to detect that an error has +occurred, allowing you to possibly recover from the error, or +at least print an error message of your choosing before exiting. +You can do this in one of two ways: + +@itemize @bullet +@item +For all output files, by assigning any value to @code{PROCINFO["NONFATAL"]}. + +@item +On a per-file basis, by assigning any value to +@code{PROCINFO[@var{filename}, "NONFATAL"]}. +Here, @var{filename} is the name of the file to which +you wish output to be nonfatal. +@end itemize + +Once you have enabled nonfatal output, you must check @code{ERRNO} +after every relevant @code{print} or @code{printf} statement to +see if something went wrong. It is also a good idea to initialize +@code{ERRNO} to zero before attempting the output. For example: + +@example +$ @kbd{gawk '} +> @kbd{BEGIN @{} +> @kbd{ PROCINFO["NONFATAL"] = 1} +> @kbd{ ERRNO = 0} +> @kbd{ print "hi" > "/no/such/file"} +> @kbd{ if (ERRNO) @{} +> @kbd{ print("Output failed:", ERRNO) > "/dev/stderr"} +> @kbd{ exit 1} +> @kbd{ @}} +> @kbd{@}'} +@error{} Output failed: No such file or directory +@end example + +Here, @command{gawk} did not produce a fatal error; instead +it let the @command{awk} program code detect the problem and handle it. + +This mechanism works also for standard output and standard error. +For standard output, you may use @code{PROCINFO["-", "NONFATAL"]} +or @code{PROCINFO["/dev/stdout", "NONFATAL"]}. For standard error, use +@code{PROCINFO["/dev/stderr", "NONFATAL"]}. + @node Output Summary @section Summary @@ -10463,6 +10522,12 @@ Use @code{close()} to close open file, pipe, and coprocess redirections. For coprocesses, it is possible to close only one direction of the communications. +@item +Normally errors with @code{print} or @code{printf} are fatal. +@command{gawk} lets you make output errors be nonfatal either for +all files or on a per-file basis. You must then check for errors +after every relevant output statement. + @end itemize @c EXCLUDE START @@ -35689,6 +35754,10 @@ Indirect function calls @item Directories on the command line produce a warning and are skipped (@pxref{Command-line directories}) + +@item +Output with @code{print} and @code{printf} need not be fatal +(@pxref{Nonfatal}) @end itemize @item @@ -36568,6 +36637,10 @@ is now two. @xref{Escape Sequences}. @item +Nonfatal output with @code{print} and @code{printf}. +@xref{Nonfatal}. + +@item Support for MirBSD was removed. @end itemize diff --git a/doc/gawktexi.in b/doc/gawktexi.in index 1e3a7c83..21f579d8 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -628,6 +628,7 @@ particular records in a file and perform operations upon them. * Special Caveats:: Things to watch out for. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. * Values:: Constants, Variables, and Regular @@ -8529,6 +8530,7 @@ and discusses the @code{close()} built-in function. @command{gawk} allows access to inherited file descriptors. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. @end menu @@ -9931,6 +9933,63 @@ when closing a pipe. @end sidebar +@node Nonfatal +@section Enabling Nonfatal Output + +This @value{SECTION} describes a @command{gawk}-specific feature. + +In standard @command{awk}, output with @code{print} or @code{printf} +to a nonexistent file, or some other I/O error (such as filling up the +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) +@end example + +@command{gawk} makes it possible to detect that an error has +occurred, allowing you to possibly recover from the error, or +at least print an error message of your choosing before exiting. +You can do this in one of two ways: + +@itemize @bullet +@item +For all output files, by assigning any value to @code{PROCINFO["NONFATAL"]}. + +@item +On a per-file basis, by assigning any value to +@code{PROCINFO[@var{filename}, "NONFATAL"]}. +Here, @var{filename} is the name of the file to which +you wish output to be nonfatal. +@end itemize + +Once you have enabled nonfatal output, you must check @code{ERRNO} +after every relevant @code{print} or @code{printf} statement to +see if something went wrong. It is also a good idea to initialize +@code{ERRNO} to zero before attempting the output. For example: + +@example +$ @kbd{gawk '} +> @kbd{BEGIN @{} +> @kbd{ PROCINFO["NONFATAL"] = 1} +> @kbd{ ERRNO = 0} +> @kbd{ print "hi" > "/no/such/file"} +> @kbd{ if (ERRNO) @{} +> @kbd{ print("Output failed:", ERRNO) > "/dev/stderr"} +> @kbd{ exit 1} +> @kbd{ @}} +> @kbd{@}'} +@error{} Output failed: No such file or directory +@end example + +Here, @command{gawk} did not produce a fatal error; instead +it let the @command{awk} program code detect the problem and handle it. + +This mechanism works also for standard output and standard error. +For standard output, you may use @code{PROCINFO["-", "NONFATAL"]} +or @code{PROCINFO["/dev/stdout", "NONFATAL"]}. For standard error, use +@code{PROCINFO["/dev/stderr", "NONFATAL"]}. + @node Output Summary @section Summary @@ -9959,6 +10018,12 @@ Use @code{close()} to close open file, pipe, and coprocess redirections. For coprocesses, it is possible to close only one direction of the communications. +@item +Normally errors with @code{print} or @code{printf} are fatal. +@command{gawk} lets you make output errors be nonfatal either for +all files or on a per-file basis. You must then check for errors +after every relevant output statement. + @end itemize @c EXCLUDE START @@ -34780,6 +34845,10 @@ Indirect function calls @item Directories on the command line produce a warning and are skipped (@pxref{Command-line directories}) + +@item +Output with @code{print} and @code{printf} need not be fatal +(@pxref{Nonfatal}) @end itemize @item @@ -35659,6 +35728,10 @@ is now two. @xref{Escape Sequences}. @item +Nonfatal output with @code{print} and @code{printf}. +@xref{Nonfatal}. + +@item Support for MirBSD was removed. @end itemize @@ -261,7 +261,6 @@ struct recmatch { static int iop_close(IOBUF *iop); -struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg); static void close_one(void); static int close_redir(struct redirect *rp, bool exitwarn, two_way_close_type how); #ifndef PIPES_SIMULATED @@ -727,7 +726,7 @@ redflags2str(int flags) /* redirect --- Redirection for printf and print commands */ struct redirect * -redirect(NODE *redir_exp, int redirtype, int *errflg) +redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal) { struct redirect *rp; char *str; @@ -892,6 +891,12 @@ redirect(NODE *redir_exp, int redirtype, int *errflg) (void) flush_io(); os_restore_mode(fileno(stdin)); + /* + * Don't check failure_fatal; see input pipe below. + * Note that the failure happens upon failure to fork, + * using a non-existant program will still succeed the + * popen(). + */ if ((rp->output.fp = popen(str, binmode("w"))) == NULL) fatal(_("can't open pipe `%s' for output (%s)"), str, strerror(errno)); @@ -927,13 +932,11 @@ redirect(NODE *redir_exp, int redirtype, int *errflg) case redirect_twoway: direction = "to/from"; if (! two_way_open(str, rp)) { -#ifdef HAVE_SOCKETS - if (inetfile(str, NULL)) { + if (! failure_fatal || is_non_fatal_redirect(str)) { *errflg = errno; /* do not free rp, saving it for reuse (save_rp = rp) */ return NULL; } else -#endif fatal(_("can't open two way pipe `%s' for input/output (%s)"), str, strerror(errno)); } @@ -1009,11 +1012,14 @@ redirect(NODE *redir_exp, int redirtype, int *errflg) * can return -1. For output to file, * complain. The shell will complain on * a bad command to a pipe. + * + * 12/2014: Take nonfatal settings in PROCINFO into account. */ if (errflg != NULL) *errflg = errno; - if ( redirtype == redirect_output - || redirtype == redirect_append) { + if (failure_fatal && ! is_non_fatal_redirect(str) && + (redirtype == redirect_output + || redirtype == redirect_append)) { /* multiple messages make life easier for translators */ if (*direction == 'f') fatal(_("can't redirect from `%s' (%s)"), @@ -1058,6 +1064,36 @@ getredirect(const char *str, int len) return NULL; } +/* is_non_fatal_std --- return true if fp is stdout/stderr and nonfatal */ + +bool +is_non_fatal_std(FILE *fp) +{ + static const char nonfatal[] = "NONFATAL"; + + if (in_PROCINFO(nonfatal, NULL, NULL)) + return true; + + /* yucky logic. sigh. */ + if (fp == stdout) { + return ( in_PROCINFO("-", nonfatal, NULL) != NULL + || in_PROCINFO("/dev/stdout", nonfatal, NULL) != NULL); + } else if (fp == stderr) { + return (in_PROCINFO("/dev/stderr", nonfatal, NULL) != NULL); + } + + return false; +} + +/* is_non_fatal_redirect --- return true if redirected I/O should be nonfatal */ + +bool +is_non_fatal_redirect(const char *str) +{ + return in_PROCINFO("NONFATAL", NULL, NULL) != NULL + || in_PROCINFO(str, "NONFATAL", NULL) != NULL; +} + /* close_one --- temporarily close an open file to re-use the fd */ static void @@ -2421,7 +2457,7 @@ do_getline_redir(int into_variable, enum redirval redirtype) assert(redirtype != redirect_none); redir_exp = TOP(); - rp = redirect(redir_exp, redirtype, & redir_error); + rp = redirect(redir_exp, redirtype, & redir_error, false); DEREF(redir_exp); decr_sp(); if (rp == NULL) { @@ -3799,12 +3835,21 @@ in_PROCINFO(const char *pidx1, const char *pidx2, NODE **full_idx) NODE *r, *sub = NULL; NODE *subsep = SUBSEP_node->var_value; + if (PROCINFO_node == NULL || (pidx1 == NULL && pidx2 == NULL)) + return NULL; + /* full_idx is in+out parameter */ if (full_idx) sub = *full_idx; - str_len = strlen(pidx1) + subsep->stlen + strlen(pidx2); + if (pidx1 != NULL && pidx2 == NULL) + str_len = strlen(pidx1); + else if (pidx1 == NULL && pidx2 != NULL) + str_len = strlen(pidx2); + else + str_len = strlen(pidx1) + subsep->stlen + strlen(pidx2); + if (sub == NULL) { emalloc(str, char *, str_len + 1, "in_PROCINFO"); sub = make_str_node(str, str_len, ALREADY_MALLOCED); @@ -3818,8 +3863,14 @@ in_PROCINFO(const char *pidx1, const char *pidx2, NODE **full_idx) sub->stlen = str_len; } - sprintf(sub->stptr, "%s%.*s%s", pidx1, (int)subsep->stlen, - subsep->stptr, pidx2); + if (pidx1 != NULL && pidx2 == NULL) + strcpy(sub->stptr, pidx1); + else if (pidx1 == NULL && pidx2 != NULL) + strcpy(sub->stptr, pidx2); + else + sprintf(sub->stptr, "%s%.*s%s", pidx1, (int)subsep->stlen, + subsep->stptr, pidx2); + r = in_array(PROCINFO_node, sub); if (! full_idx) unref(sub); diff --git a/test/ChangeLog b/test/ChangeLog index ecbfaf0d..d047ae0a 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -3,6 +3,16 @@ * Makefile.am (profile0): New test. * profile0.awk, profile0.in, profile0.ok: New files. +2015-02-08 Arnold D. Robbins <arnold@skeeve.com> + + * nonfatal1.awk, nonfatal2.awk: String is now "NONFATAL". + +2015-02-06 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (nonfatal1, nonfatal2): New tests. + * nonfatal1.awk, nonfatal1.ok: New files. + * nonfatal2.awk, nonfatal2.ok: New files. + 2015-02-01 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (paramasfunc1, paramasfunc2): Now need --posix. diff --git a/test/Makefile.am b/test/Makefile.am index 4f78ddb4..38b0d00b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -597,6 +597,10 @@ EXTRA_DIST = \ nondec.ok \ nondec2.awk \ nondec2.ok \ + nonfatal1.awk \ + nonfatal1.ok \ + nonfatal2.awk \ + nonfatal2.ok \ nonl.awk \ nonl.ok \ noparms.awk \ @@ -1044,6 +1048,7 @@ GAWK_EXT_TESTS = \ lint lintold lintwarn \ manyfiles match1 match2 match3 mbstr1 \ nastyparm next nondec nondec2 \ + nonfatal1 nonfatal2 \ patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \ profile0 profile1 profile2 profile3 profile4 profile5 profile6 profile7 \ profile8 pty1 \ diff --git a/test/Makefile.in b/test/Makefile.in index 30c77b97..9b235e46 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -854,6 +854,10 @@ EXTRA_DIST = \ nondec.ok \ nondec2.awk \ nondec2.ok \ + nonfatal1.awk \ + nonfatal1.ok \ + nonfatal2.awk \ + nonfatal2.ok \ nonl.awk \ nonl.ok \ noparms.awk \ @@ -1300,6 +1304,7 @@ GAWK_EXT_TESTS = \ lint lintold lintwarn \ manyfiles match1 match2 match3 mbstr1 \ nastyparm next nondec nondec2 \ + nonfatal1 nonfatal2 \ patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \ profile0 profile1 profile2 profile3 profile4 profile5 profile6 profile7 \ profile8 pty1 \ @@ -3628,6 +3633,16 @@ nondec: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +nonfatal1: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +nonfatal2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + patsplit: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index f3639b0f..9e19a2d5 100644 --- a/test/Maketests +++ b/test/Maketests @@ -1147,6 +1147,16 @@ nondec: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +nonfatal1: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +nonfatal2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + patsplit: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/nonfatal1.awk b/test/nonfatal1.awk new file mode 100644 index 00000000..bf821d49 --- /dev/null +++ b/test/nonfatal1.awk @@ -0,0 +1,5 @@ +BEGIN { + PROCINFO["NONFATAL"] + print |& "/inet/tcp/0/ti10/357" + print ERRNO +} diff --git a/test/nonfatal1.ok b/test/nonfatal1.ok new file mode 100644 index 00000000..b96b8e27 --- /dev/null +++ b/test/nonfatal1.ok @@ -0,0 +1,2 @@ +gawk: nonfatal1.awk:3: fatal: remote host and port information (ti10, 357) invalid +EXIT CODE: 2 diff --git a/test/nonfatal2.awk b/test/nonfatal2.awk new file mode 100644 index 00000000..fedbba43 --- /dev/null +++ b/test/nonfatal2.awk @@ -0,0 +1,5 @@ +BEGIN { + PROCINFO["NONFATAL"] = 1 + print > "/dev/no/such/file" + print ERRNO +} diff --git a/test/nonfatal2.ok b/test/nonfatal2.ok new file mode 100644 index 00000000..ddc88691 --- /dev/null +++ b/test/nonfatal2.ok @@ -0,0 +1 @@ +No such file or directory |