summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2015-03-27 06:40:45 +0300
committerArnold D. Robbins <arnold@skeeve.com>2015-03-27 06:40:45 +0300
commit3fad6ad12e1637c4e1b72fbeaf0265f44da0cf27 (patch)
tree8e83597d27430370914142150647e11c07410e0b
parent603eb56251817ac19491b7671ed01402b2d7399c (diff)
parent7d3d7d27391db40c0561ea47e6b8a5a1ae24c6fb (diff)
downloadgawk-3fad6ad12e1637c4e1b72fbeaf0265f44da0cf27.tar.gz
Merge branch 'master' into wasted-byte
-rw-r--r--ChangeLog196
-rw-r--r--NEWS11
-rw-r--r--awk.h4
-rw-r--r--awkgram.c721
-rw-r--r--awkgram.y3
-rw-r--r--awklib/eg/lib/inplace.awk9
-rwxr-xr-xconfig.guess6
-rwxr-xr-xconfig.sub8
-rw-r--r--configh.in6
-rwxr-xr-xconfigure5
-rw-r--r--configure.ac5
-rw-r--r--doc/ChangeLog37
-rw-r--r--doc/gawk.147
-rw-r--r--doc/gawk.info1376
-rw-r--r--doc/gawk.texi165
-rw-r--r--doc/gawktexi.in165
-rw-r--r--eval.c4
-rw-r--r--extension/ChangeLog185
-rw-r--r--extension/build-aux/ChangeLog4
-rwxr-xr-xextension/build-aux/config.guess6
-rwxr-xr-xextension/build-aux/config.sub8
-rw-r--r--extension/build-aux/ltmain.sh23
-rwxr-xr-xextension/configure45
-rw-r--r--extension/inplace.3am23
-rw-r--r--extension/m4/ChangeLog4
-rw-r--r--extension/m4/libtool.m427
-rw-r--r--extension/m4/ltversion.m410
-rw-r--r--extension/testext.c205
-rw-r--r--gawkapi.c105
-rw-r--r--gawkapi.h40
-rw-r--r--interpret.h19
-rw-r--r--io.c169
-rw-r--r--test/ChangeLog50
-rw-r--r--test/Makefile.am28
-rw-r--r--test/Makefile.in38
-rw-r--r--test/Maketests10
-rw-r--r--test/errno.awk10
-rw-r--r--test/errno.in3
-rw-r--r--test/errno.ok3
-rw-r--r--test/exitval3.awk2
-rw-r--r--test/exitval3.ok1
-rw-r--r--test/getfile.awk35
-rw-r--r--test/getfile.ok17
-rw-r--r--test/inplace1.ok2
-rw-r--r--test/inplace2.ok2
-rw-r--r--test/inplace3.ok4
-rw-r--r--test/testext.ok12
-rw-r--r--test/timeout.awk26
-rw-r--r--test/timeout.ok12
49 files changed, 2775 insertions, 1121 deletions
diff --git a/ChangeLog b/ChangeLog
index ad14f19a..c123e91e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2015-03-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (redirect): Change not_string from int to bool.
+ * gawkapi.c (api_get_file): Minor stylistic improvements.
+ * NEWS: Updated for retryable I/O and new API function.
+
+2015-03-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * interpret.h (r_interpret): When Op_K_exit has an argument of
+ Nnull_string, do not update exit_val, since no value was supplied.
+
+2015-03-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h, gawkapi.c, io.c: Minor code reformatting.
+
+2015-03-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.guess, config.sub: Updated, from libtool 2.4.6.
+
2015-03-17 Arnold D. Robbins <arnold@skeeve.com>
* profile.c (pp_number): Allocate enough room to print the number
@@ -170,6 +189,22 @@
* builtin.c (do_length): Update comment.
* main.c (init_vars): Just call load_procinfo() and `load_environ()'.
+2015-01-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ Revert changes to API deferred variable creation -- these variables
+ should be created when lookup is called, not when update is called.
+ * awk.h (variable_create): Remove function declaration.
+ * awkgram.y (variable_create): Remove function.
+ (variable): Restore variable_create functionality inline.
+ * gawkapi.c (api_sym_update): Revert to using install_symbol, since the
+ deferred variable check should be done when lookup is called, not here.
+
+2015-01-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (api_set_array_element): Remove stray call to
+ make_aname. I cannot see what purpose this served. Maybe I am
+ missing something.
+
2015-01-07 Arnold D. Robbins <arnold@skeeve.com>
* configure.ac: Update debug flags if developing.
@@ -188,6 +223,59 @@
(do_add_scrfile): Set it on -l.
(process_deferred): Check it also.
+2015-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (api_sym_update): If copying a subarray, must update
+ the parent_array pointer. Also, call the astore hook if non-NULL.
+ (api_set_array_element): Call the astore hook if non-NULL.
+
+2015-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awk.h (variable_create): Now takes a 3rd argument to tell caller
+ whether this is a deferred variable.
+ * awkgram.y (variable_create): Return indicator of whether this is
+ a deferred variable in a newly added 3rd arg.
+ (variable): Pass 3rd arg to variable_create.
+ * gawkapi.c (api_sym_update): If we triggered the creation of a deferred
+ variable, we must merge the extension's array elements into the deffered
+ array, not the other way around. The ENVIRON array has special funcs
+ to call setenv and unsetenv.
+
+2015-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awk.h (variable_create): Declare new function.
+ * awkgram.y (variable_create): New function to create a variable
+ taking the deferred variable list into consideration.
+ (variable): Call new function variable_create if the variable is
+ not found.
+ * gawkapi.c (api_sym_update): If an array is being created, then
+ call new function variable_create instead of install_symbol. If this
+ is the first reference to a deferred variable, than the new array
+ may contain elements that must be merged into the array provided by
+ the extension.
+
+2015-01-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * io.c (wait_any): If the `interesting' argument is non-zero, then we
+ must not return until that child process has exited, since the caller
+ gawk_pclose depends on our returning its exit status. So in that case,
+ do not pass WNOHANG to waitpid.
+
+2015-01-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h: Fix another comment typo.
+
+2015-01-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h: Fix typo in comment.
+
+2015-01-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h (gawk_api): Modify api_get_file to remove the typelen
+ argument.
+ (get_file): Remove typelen argument from the macro.
+ * gawkapi.c (api_get_file): Remove typelen argument.
+
2014-12-24 Arnold D. Robbins <arnold@skeeve.com>
* profile.c (pprint): Be sure to set ip2 in all paths
@@ -357,6 +445,36 @@
and a it's a Node_val set to Nnull_string, return AWK_UNDEFINED instead
of AWK_NUMBER 0.
+2014-11-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awk.h (redirect_string): First argument should be const. Add a new
+ extfd argument to enable extensions to create files with pre-opened
+ file descriptors.
+ (after_beginfile): Declare function used in both eval.c and gawkapi.c.
+ * eval.c (after_beginfile): Remove extern declaration now in awk.h.
+ * gawkapi.c (api_get_file): Implement API changes to return
+ awk_input_buf_t and/or awk_output_buf_t info, as well as accept an
+ fd for inserting an opened file into the table.
+ * gawkapi.h (gawk_api): Modify the api_get_file declaration to
+ return awk_bool_t and add 3 new arguments -- a file descriptor
+ for inserting an already opened file, and awk_input_buf_t and
+ awk_output_buf_t to return info about both input and output.
+ (get_file): Add new arguments to the macro.
+ * io.c (redirect_string): First arg should be const, and add a new
+ extfd arg so extensions can pass in a file that has already been
+ opened by the extension. Use the passed-in fd when appropriate,
+ and pass it into two_way_open.
+ (redirect): Pass new fd -1 arg to redirect_string.
+ (two_way_open): Accept new extension fd parameter and open it
+ as a socket.
+
+2014-11-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * io.c (retryable): New function to indicate whether I/O can be
+ retried for this file instead of throwing a hard error.
+ (get_a_record) Check whether this file is configured for retryable
+ I/O before returning nonstandard -2.
+
2014-11-03 Norihiro Tanaka <noritnk@kcn.ne.jp>
* re.c (research): Use dfa superset to improve matching speed.
@@ -1525,6 +1643,45 @@
* io.c (get_a_record): Change `min' to `MIN' for consistency with
other files and general practice.
+2013-07-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac (AC_CHECK_FUNCS): Check for sigprocmask.
+ * io.c (wait_any): If sigprocmask is available, block signals instead
+ of ignoring them temporarily.
+
+2013-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h (gawk_api): Document that the api_get_file function will not
+ access the file type and length arguments if the file name is empty.
+
+2013-07-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac (AC_CHECK_FUNCS): Add a check for waitpid.
+ * io.c (wait_any): Enhance comment to explain why we loop reaping all
+ exited children when the argument is zero. When available, use waitpid
+ with WNOHANG to avoid blocking. Remove my previous incorrect patch to
+ exit after reaping the first child. The function is intended to
+ wait for all children, since we are not careful about reaping children
+ as soon as they die.
+
+2013-07-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h (gawk_api): Remove unused api_lookup_file hook.
+ (lookup_file): Remove associated macro.
+ * gawkapi.c (api_lookup_file): Remove unused function.
+ (api_impl): Remove unused api_lookup_file hook.
+
+2013-07-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awkgram.y (main_beginfile): Declare new global INSTRUCTION *.
+ (parse_program): Set main_beginfile to point to the BEGINFILE
+ instruction block.
+ * gawkapi.c (api_get_file): After nextfile starts a new file,
+ we need to run the BEGINFILE actions. We retrieve the
+ instruction pointer from main_beginfile and execute it until
+ we reach the Op_after_beginfile opcode. We then run after_beginfile
+ manually and restore the value of currule and source.
+
2013-07-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
* gawkapi.h (awk_element_t): Add comment indicating that the array
@@ -1535,6 +1692,45 @@
force_string redundant, since node_to_awk_value does that internally
when we request a string.
+2013-07-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * eval.c (update_ERRNO_string): Set PROCINFO["errno"] to 0.
+ * io.c (inrec): Since get_a_record may now return -2, be sure
+ to throw an error in that case as well.
+ (wait_any): Fix what appears to be a bug. The old logic repeatedly
+ called wait until it failed. When a process has multiple children,
+ this causes it to stall until all of them have exited. Instead,
+ we now exit the function after the first successful wait call.
+ (do_getline_redir, do_getline): Handle case where get_a_record
+ returns -2.
+ (errno_io_retry): New function to decide whether an I/O operation should
+ be retried.
+ (get_a_record): When read returns an error, call errno_io_retry to
+ decide whether the operation should be retried. If so, return -2
+ instead of setting the IOP_AT_EOF flag.
+
+2013-07-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * eval.c (update_ERRNO_int, unset_ERRNO): Update PROCINFO["errno"].
+
+2013-06-30 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awk.h (redirect_string): Declare new function that provides API access
+ to the redirection mechanism.
+ * gawkapi.h (GAWK_API_MINOR_VERSION): Bump from 0 to 1 since 2 new
+ hooks were added to the api.
+ (gawk_api_t): Add 2 new functions api_lookup_file and api_get_file.
+ (lookup_file, get_file): New macros to wrap the new API functions.
+ * gawkapi.c (curfile): Declare this extern, since it is needed
+ by lookup_file and get_flie.
+ (api_lookup_file): Find an open file using curfile or getredirect().
+ (api_get_file): Find or open a file using curfile or redirect_string().
+ (api_impl): Add api_lookup_file and api_get_file.
+ * io.c (redirect_string): Renamed from redirect and changed arguments
+ to take a string instead of a 'NODE *'. This allows it to be called
+ through the API's new get_file hook.
+ (redirect): Now implemented by calling redirect_string backend function.
+
2013-07-04 Arnold D. Robbins <arnold@skeeve.com>
* builtin.c (format_tree): Fixes for %c with multibyte characters
diff --git a/NEWS b/NEWS
index 0b4a89fe..0c27c2c0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,5 @@
- Copyright (C) 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
+ Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015,
+ Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
@@ -44,6 +45,12 @@ Changes from 4.1.x to 4.2.0
system, these files belong in /etc/profile.d, but the appropriate location
may be different on other platforms.
+11. Gawk now supports retryable I/O via PROCINFO[input-file, "RETRY"]; see
+ the manual.
+
+12. The API minor version has been increased to two; the get_file()
+ API provides access to open redirections. Also see the manual.
+
Changes from 4.1.1 to 4.1.2
---------------------------
@@ -82,7 +89,7 @@ Changes from 4.1.1 to 4.1.2
AWKPATH setting, be sure to put "." in it somewhere. The documentation
has been updated and clarified.
-10. Infrastructure upgrades: Automake 1.15, Gettext 0.19.4, Libtool 2.4.5,
+10. Infrastructure upgrades: Automake 1.15, Gettext 0.19.4, Libtool 2.4.6,
Bison 3.0.4.
11. If a user-defined function has a parameter with the same name as another
diff --git a/awk.h b/awk.h
index 7a44c1d0..6b9ac10b 100644
--- a/awk.h
+++ b/awk.h
@@ -1483,6 +1483,9 @@ extern void set_FNR(void);
extern void set_NR(void);
extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal);
+extern struct redirect *redirect_string(const char *redir_exp_str,
+ size_t redir_exp_len, bool not_string_flag, int redirtype,
+ int *errflg, int extfd, bool failure_fatal);
extern NODE *do_close(int nargs);
extern int flush_io(void);
extern int close_io(bool *stdio_problem);
@@ -1503,6 +1506,7 @@ extern int is_off_limits_var(const char *var);
extern char *estrdup(const char *str, size_t len);
extern void update_global_values();
extern long getenv_long(const char *name);
+extern void after_beginfile(IOBUF **curfile);
/* mpfr.c */
extern void set_PREC(void);
diff --git a/awkgram.c b/awkgram.c
index 0baf5070..ad012b1d 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -184,6 +184,7 @@ static INSTRUCTION *ip_atexit = NULL;
static INSTRUCTION *ip_end;
static INSTRUCTION *ip_endfile;
static INSTRUCTION *ip_beginfile;
+INSTRUCTION *main_beginfile;
static INSTRUCTION *comment = NULL;
static INSTRUCTION *program_comment = NULL;
@@ -202,7 +203,7 @@ extern double fmod(double x, double y);
#define YYSTYPE INSTRUCTION *
-#line 206 "awkgram.c" /* yacc.c:339 */
+#line 207 "awkgram.c" /* yacc.c:339 */
# ifndef YY_NULLPTR
# if defined __cplusplus && 201103L <= __cplusplus
@@ -356,7 +357,7 @@ int yyparse (void);
/* Copy the second part of user declarations. */
-#line 360 "awkgram.c" /* yacc.c:358 */
+#line 361 "awkgram.c" /* yacc.c:358 */
#ifdef short
# undef short
@@ -658,25 +659,25 @@ static const yytype_uint8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 205, 205, 207, 212, 213, 217, 229, 234, 245,
- 251, 257, 266, 274, 276, 281, 289, 291, 297, 305,
- 315, 345, 359, 373, 381, 392, 404, 406, 408, 414,
- 422, 423, 427, 462, 461, 495, 497, 502, 508, 536,
- 541, 542, 546, 548, 550, 557, 647, 689, 731, 844,
- 851, 858, 868, 877, 886, 895, 906, 922, 921, 945,
- 957, 957, 1055, 1055, 1088, 1118, 1124, 1125, 1131, 1132,
- 1139, 1144, 1156, 1170, 1172, 1180, 1185, 1187, 1195, 1197,
- 1206, 1207, 1215, 1220, 1220, 1231, 1235, 1243, 1244, 1247,
- 1249, 1254, 1255, 1264, 1265, 1270, 1275, 1281, 1283, 1285,
- 1292, 1293, 1299, 1300, 1305, 1307, 1312, 1314, 1322, 1327,
- 1336, 1343, 1345, 1347, 1363, 1373, 1380, 1382, 1387, 1389,
- 1391, 1399, 1401, 1406, 1408, 1413, 1415, 1417, 1467, 1469,
- 1471, 1473, 1475, 1477, 1479, 1481, 1495, 1500, 1505, 1530,
- 1536, 1538, 1540, 1542, 1544, 1546, 1551, 1555, 1587, 1589,
- 1595, 1601, 1614, 1615, 1616, 1621, 1626, 1630, 1634, 1649,
- 1662, 1667, 1704, 1733, 1734, 1740, 1741, 1746, 1748, 1755,
- 1772, 1789, 1791, 1798, 1803, 1811, 1821, 1833, 1842, 1846,
- 1850, 1854, 1858, 1862, 1865, 1867, 1871, 1875, 1879
+ 0, 206, 206, 208, 213, 214, 218, 230, 235, 246,
+ 252, 258, 267, 275, 277, 282, 290, 292, 298, 306,
+ 316, 346, 360, 374, 382, 393, 405, 407, 409, 415,
+ 423, 424, 428, 463, 462, 496, 498, 503, 509, 537,
+ 542, 543, 547, 549, 551, 558, 648, 690, 732, 845,
+ 852, 859, 869, 878, 887, 896, 907, 923, 922, 946,
+ 958, 958, 1056, 1056, 1089, 1119, 1125, 1126, 1132, 1133,
+ 1140, 1145, 1157, 1171, 1173, 1181, 1186, 1188, 1196, 1198,
+ 1207, 1208, 1216, 1221, 1221, 1232, 1236, 1244, 1245, 1248,
+ 1250, 1255, 1256, 1265, 1266, 1271, 1276, 1282, 1284, 1286,
+ 1293, 1294, 1300, 1301, 1306, 1308, 1313, 1315, 1323, 1328,
+ 1337, 1344, 1346, 1348, 1364, 1374, 1381, 1383, 1388, 1390,
+ 1392, 1400, 1402, 1407, 1409, 1414, 1416, 1418, 1468, 1470,
+ 1472, 1474, 1476, 1478, 1480, 1482, 1496, 1501, 1506, 1531,
+ 1537, 1539, 1541, 1543, 1545, 1547, 1552, 1556, 1588, 1590,
+ 1596, 1602, 1615, 1616, 1617, 1622, 1627, 1631, 1635, 1650,
+ 1663, 1668, 1705, 1734, 1735, 1741, 1742, 1747, 1749, 1756,
+ 1773, 1790, 1792, 1799, 1804, 1812, 1822, 1834, 1843, 1847,
+ 1851, 1855, 1859, 1863, 1866, 1868, 1872, 1876, 1880
};
#endif
@@ -1849,24 +1850,24 @@ yyreduce:
switch (yyn)
{
case 3:
-#line 208 "awkgram.y" /* yacc.c:1646 */
+#line 209 "awkgram.y" /* yacc.c:1646 */
{
rule = 0;
yyerrok;
}
-#line 1858 "awkgram.c" /* yacc.c:1646 */
+#line 1859 "awkgram.c" /* yacc.c:1646 */
break;
case 5:
-#line 214 "awkgram.y" /* yacc.c:1646 */
+#line 215 "awkgram.y" /* yacc.c:1646 */
{
next_sourcefile();
}
-#line 1866 "awkgram.c" /* yacc.c:1646 */
+#line 1867 "awkgram.c" /* yacc.c:1646 */
break;
case 6:
-#line 218 "awkgram.y" /* yacc.c:1646 */
+#line 219 "awkgram.y" /* yacc.c:1646 */
{
rule = 0;
/*
@@ -1875,20 +1876,20 @@ yyreduce:
*/
/* yyerrok; */
}
-#line 1879 "awkgram.c" /* yacc.c:1646 */
+#line 1880 "awkgram.c" /* yacc.c:1646 */
break;
case 7:
-#line 230 "awkgram.y" /* yacc.c:1646 */
+#line 231 "awkgram.y" /* yacc.c:1646 */
{
(void) append_rule((yyvsp[-1]), (yyvsp[0]));
first_rule = false;
}
-#line 1888 "awkgram.c" /* yacc.c:1646 */
+#line 1889 "awkgram.c" /* yacc.c:1646 */
break;
case 8:
-#line 235 "awkgram.y" /* yacc.c:1646 */
+#line 236 "awkgram.y" /* yacc.c:1646 */
{
if (rule != Rule) {
msg(_("%s blocks must have an action part"), ruletab[rule]);
@@ -1899,41 +1900,41 @@ yyreduce:
} else /* pattern rule with non-empty pattern */
(void) append_rule((yyvsp[-1]), NULL);
}
-#line 1903 "awkgram.c" /* yacc.c:1646 */
+#line 1904 "awkgram.c" /* yacc.c:1646 */
break;
case 9:
-#line 246 "awkgram.y" /* yacc.c:1646 */
+#line 247 "awkgram.y" /* yacc.c:1646 */
{
in_function = NULL;
(void) mk_function((yyvsp[-1]), (yyvsp[0]));
yyerrok;
}
-#line 1913 "awkgram.c" /* yacc.c:1646 */
+#line 1914 "awkgram.c" /* yacc.c:1646 */
break;
case 10:
-#line 252 "awkgram.y" /* yacc.c:1646 */
+#line 253 "awkgram.y" /* yacc.c:1646 */
{
want_source = false;
at_seen = false;
yyerrok;
}
-#line 1923 "awkgram.c" /* yacc.c:1646 */
+#line 1924 "awkgram.c" /* yacc.c:1646 */
break;
case 11:
-#line 258 "awkgram.y" /* yacc.c:1646 */
+#line 259 "awkgram.y" /* yacc.c:1646 */
{
want_source = false;
at_seen = false;
yyerrok;
}
-#line 1933 "awkgram.c" /* yacc.c:1646 */
+#line 1934 "awkgram.c" /* yacc.c:1646 */
break;
case 12:
-#line 267 "awkgram.y" /* yacc.c:1646 */
+#line 268 "awkgram.y" /* yacc.c:1646 */
{
if (include_source((yyvsp[0])) < 0)
YYABORT;
@@ -1941,23 +1942,23 @@ yyreduce:
bcfree((yyvsp[0]));
(yyval) = NULL;
}
-#line 1945 "awkgram.c" /* yacc.c:1646 */
+#line 1946 "awkgram.c" /* yacc.c:1646 */
break;
case 13:
-#line 275 "awkgram.y" /* yacc.c:1646 */
+#line 276 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 1951 "awkgram.c" /* yacc.c:1646 */
+#line 1952 "awkgram.c" /* yacc.c:1646 */
break;
case 14:
-#line 277 "awkgram.y" /* yacc.c:1646 */
+#line 278 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 1957 "awkgram.c" /* yacc.c:1646 */
+#line 1958 "awkgram.c" /* yacc.c:1646 */
break;
case 15:
-#line 282 "awkgram.y" /* yacc.c:1646 */
+#line 283 "awkgram.y" /* yacc.c:1646 */
{
if (load_library((yyvsp[0])) < 0)
YYABORT;
@@ -1965,23 +1966,23 @@ yyreduce:
bcfree((yyvsp[0]));
(yyval) = NULL;
}
-#line 1969 "awkgram.c" /* yacc.c:1646 */
+#line 1970 "awkgram.c" /* yacc.c:1646 */
break;
case 16:
-#line 290 "awkgram.y" /* yacc.c:1646 */
+#line 291 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 1975 "awkgram.c" /* yacc.c:1646 */
+#line 1976 "awkgram.c" /* yacc.c:1646 */
break;
case 17:
-#line 292 "awkgram.y" /* yacc.c:1646 */
+#line 293 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 1981 "awkgram.c" /* yacc.c:1646 */
+#line 1982 "awkgram.c" /* yacc.c:1646 */
break;
case 18:
-#line 297 "awkgram.y" /* yacc.c:1646 */
+#line 298 "awkgram.y" /* yacc.c:1646 */
{
rule = Rule;
if (comment != NULL) {
@@ -1990,11 +1991,11 @@ yyreduce:
} else
(yyval) = NULL;
}
-#line 1994 "awkgram.c" /* yacc.c:1646 */
+#line 1995 "awkgram.c" /* yacc.c:1646 */
break;
case 19:
-#line 306 "awkgram.y" /* yacc.c:1646 */
+#line 307 "awkgram.y" /* yacc.c:1646 */
{
rule = Rule;
if (comment != NULL) {
@@ -2003,11 +2004,11 @@ yyreduce:
} else
(yyval) = (yyvsp[0]);
}
-#line 2007 "awkgram.c" /* yacc.c:1646 */
+#line 2008 "awkgram.c" /* yacc.c:1646 */
break;
case 20:
-#line 316 "awkgram.y" /* yacc.c:1646 */
+#line 317 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *tp;
@@ -2037,11 +2038,11 @@ yyreduce:
(yyval) = list_append(list_merge((yyvsp[-3]), (yyvsp[0])), tp);
rule = Rule;
}
-#line 2041 "awkgram.c" /* yacc.c:1646 */
+#line 2042 "awkgram.c" /* yacc.c:1646 */
break;
case 21:
-#line 346 "awkgram.y" /* yacc.c:1646 */
+#line 347 "awkgram.y" /* yacc.c:1646 */
{
static int begin_seen = 0;
@@ -2055,11 +2056,11 @@ yyreduce:
check_comment();
(yyval) = (yyvsp[0]);
}
-#line 2059 "awkgram.c" /* yacc.c:1646 */
+#line 2060 "awkgram.c" /* yacc.c:1646 */
break;
case 22:
-#line 360 "awkgram.y" /* yacc.c:1646 */
+#line 361 "awkgram.y" /* yacc.c:1646 */
{
static int end_seen = 0;
@@ -2073,11 +2074,11 @@ yyreduce:
check_comment();
(yyval) = (yyvsp[0]);
}
-#line 2077 "awkgram.c" /* yacc.c:1646 */
+#line 2078 "awkgram.c" /* yacc.c:1646 */
break;
case 23:
-#line 374 "awkgram.y" /* yacc.c:1646 */
+#line 375 "awkgram.y" /* yacc.c:1646 */
{
func_first = false;
(yyvsp[0])->in_rule = rule = BEGINFILE;
@@ -2085,11 +2086,11 @@ yyreduce:
check_comment();
(yyval) = (yyvsp[0]);
}
-#line 2089 "awkgram.c" /* yacc.c:1646 */
+#line 2090 "awkgram.c" /* yacc.c:1646 */
break;
case 24:
-#line 382 "awkgram.y" /* yacc.c:1646 */
+#line 383 "awkgram.y" /* yacc.c:1646 */
{
func_first = false;
(yyvsp[0])->in_rule = rule = ENDFILE;
@@ -2097,11 +2098,11 @@ yyreduce:
check_comment();
(yyval) = (yyvsp[0]);
}
-#line 2101 "awkgram.c" /* yacc.c:1646 */
+#line 2102 "awkgram.c" /* yacc.c:1646 */
break;
case 25:
-#line 393 "awkgram.y" /* yacc.c:1646 */
+#line 394 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *ip;
if ((yyvsp[-3]) == NULL)
@@ -2110,42 +2111,42 @@ yyreduce:
ip = (yyvsp[-3]);
(yyval) = ip;
}
-#line 2114 "awkgram.c" /* yacc.c:1646 */
+#line 2115 "awkgram.c" /* yacc.c:1646 */
break;
case 26:
-#line 405 "awkgram.y" /* yacc.c:1646 */
+#line 406 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 2120 "awkgram.c" /* yacc.c:1646 */
+#line 2121 "awkgram.c" /* yacc.c:1646 */
break;
case 27:
-#line 407 "awkgram.y" /* yacc.c:1646 */
+#line 408 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 2126 "awkgram.c" /* yacc.c:1646 */
+#line 2127 "awkgram.c" /* yacc.c:1646 */
break;
case 28:
-#line 409 "awkgram.y" /* yacc.c:1646 */
+#line 410 "awkgram.y" /* yacc.c:1646 */
{
yyerror(_("`%s' is a built-in function, it cannot be redefined"),
tokstart);
YYABORT;
}
-#line 2136 "awkgram.c" /* yacc.c:1646 */
+#line 2137 "awkgram.c" /* yacc.c:1646 */
break;
case 29:
-#line 415 "awkgram.y" /* yacc.c:1646 */
+#line 416 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = (yyvsp[0]);
at_seen = false;
}
-#line 2145 "awkgram.c" /* yacc.c:1646 */
+#line 2146 "awkgram.c" /* yacc.c:1646 */
break;
case 32:
-#line 428 "awkgram.y" /* yacc.c:1646 */
+#line 429 "awkgram.y" /* yacc.c:1646 */
{
/*
* treat any comments between BOF and the first function
@@ -2172,17 +2173,17 @@ yyreduce:
/* $4 already free'd in install_function */
(yyval) = (yyvsp[-5]);
}
-#line 2176 "awkgram.c" /* yacc.c:1646 */
+#line 2177 "awkgram.c" /* yacc.c:1646 */
break;
case 33:
-#line 462 "awkgram.y" /* yacc.c:1646 */
+#line 463 "awkgram.y" /* yacc.c:1646 */
{ want_regexp = true; }
-#line 2182 "awkgram.c" /* yacc.c:1646 */
+#line 2183 "awkgram.c" /* yacc.c:1646 */
break;
case 34:
-#line 464 "awkgram.y" /* yacc.c:1646 */
+#line 465 "awkgram.y" /* yacc.c:1646 */
{
NODE *n, *exp;
char *re;
@@ -2211,28 +2212,28 @@ yyreduce:
(yyval)->opcode = Op_match_rec;
(yyval)->memory = n;
}
-#line 2215 "awkgram.c" /* yacc.c:1646 */
+#line 2216 "awkgram.c" /* yacc.c:1646 */
break;
case 35:
-#line 496 "awkgram.y" /* yacc.c:1646 */
+#line 497 "awkgram.y" /* yacc.c:1646 */
{ bcfree((yyvsp[0])); }
-#line 2221 "awkgram.c" /* yacc.c:1646 */
+#line 2222 "awkgram.c" /* yacc.c:1646 */
break;
case 37:
-#line 502 "awkgram.y" /* yacc.c:1646 */
+#line 503 "awkgram.y" /* yacc.c:1646 */
{
if (comment != NULL) {
(yyval) = list_create(comment);
comment = NULL;
} else (yyval) = NULL;
}
-#line 2232 "awkgram.c" /* yacc.c:1646 */
+#line 2233 "awkgram.c" /* yacc.c:1646 */
break;
case 38:
-#line 509 "awkgram.y" /* yacc.c:1646 */
+#line 510 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[0]) == NULL) {
if (comment == NULL)
@@ -2260,40 +2261,40 @@ yyreduce:
}
yyerrok;
}
-#line 2264 "awkgram.c" /* yacc.c:1646 */
+#line 2265 "awkgram.c" /* yacc.c:1646 */
break;
case 39:
-#line 537 "awkgram.y" /* yacc.c:1646 */
+#line 538 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 2270 "awkgram.c" /* yacc.c:1646 */
+#line 2271 "awkgram.c" /* yacc.c:1646 */
break;
case 42:
-#line 547 "awkgram.y" /* yacc.c:1646 */
+#line 548 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 2276 "awkgram.c" /* yacc.c:1646 */
+#line 2277 "awkgram.c" /* yacc.c:1646 */
break;
case 43:
-#line 549 "awkgram.y" /* yacc.c:1646 */
+#line 550 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 2282 "awkgram.c" /* yacc.c:1646 */
+#line 2283 "awkgram.c" /* yacc.c:1646 */
break;
case 44:
-#line 551 "awkgram.y" /* yacc.c:1646 */
+#line 552 "awkgram.y" /* yacc.c:1646 */
{
if (do_pretty_print)
(yyval) = list_prepend((yyvsp[0]), instruction(Op_exec_count));
else
(yyval) = (yyvsp[0]);
}
-#line 2293 "awkgram.c" /* yacc.c:1646 */
+#line 2294 "awkgram.c" /* yacc.c:1646 */
break;
case 45:
-#line 558 "awkgram.y" /* yacc.c:1646 */
+#line 559 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt;
INSTRUCTION *ip, *nextc, *tbreak;
@@ -2383,11 +2384,11 @@ yyreduce:
break_allowed--;
fix_break_continue(ip, tbreak, NULL);
}
-#line 2387 "awkgram.c" /* yacc.c:1646 */
+#line 2388 "awkgram.c" /* yacc.c:1646 */
break;
case 46:
-#line 648 "awkgram.y" /* yacc.c:1646 */
+#line 649 "awkgram.y" /* yacc.c:1646 */
{
/*
* -----------------
@@ -2429,11 +2430,11 @@ yyreduce:
continue_allowed--;
fix_break_continue(ip, tbreak, tcont);
}
-#line 2433 "awkgram.c" /* yacc.c:1646 */
+#line 2434 "awkgram.c" /* yacc.c:1646 */
break;
case 47:
-#line 690 "awkgram.y" /* yacc.c:1646 */
+#line 691 "awkgram.y" /* yacc.c:1646 */
{
/*
* -----------------
@@ -2475,11 +2476,11 @@ yyreduce:
} /* else
$1 and $4 are NULLs */
}
-#line 2479 "awkgram.c" /* yacc.c:1646 */
+#line 2480 "awkgram.c" /* yacc.c:1646 */
break;
case 48:
-#line 732 "awkgram.y" /* yacc.c:1646 */
+#line 733 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *ip;
char *var_name = (yyvsp[-5])->lextok;
@@ -2592,44 +2593,44 @@ regular_loop:
break_allowed--;
continue_allowed--;
}
-#line 2596 "awkgram.c" /* yacc.c:1646 */
+#line 2597 "awkgram.c" /* yacc.c:1646 */
break;
case 49:
-#line 845 "awkgram.y" /* yacc.c:1646 */
+#line 846 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_for_loop((yyvsp[-11]), (yyvsp[-9]), (yyvsp[-6]), (yyvsp[-3]), (yyvsp[0]));
break_allowed--;
continue_allowed--;
}
-#line 2607 "awkgram.c" /* yacc.c:1646 */
+#line 2608 "awkgram.c" /* yacc.c:1646 */
break;
case 50:
-#line 852 "awkgram.y" /* yacc.c:1646 */
+#line 853 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_for_loop((yyvsp[-10]), (yyvsp[-8]), (INSTRUCTION *) NULL, (yyvsp[-3]), (yyvsp[0]));
break_allowed--;
continue_allowed--;
}
-#line 2618 "awkgram.c" /* yacc.c:1646 */
+#line 2619 "awkgram.c" /* yacc.c:1646 */
break;
case 51:
-#line 859 "awkgram.y" /* yacc.c:1646 */
+#line 860 "awkgram.y" /* yacc.c:1646 */
{
if (do_pretty_print)
(yyval) = list_prepend((yyvsp[0]), instruction(Op_exec_count));
else
(yyval) = (yyvsp[0]);
}
-#line 2629 "awkgram.c" /* yacc.c:1646 */
+#line 2630 "awkgram.c" /* yacc.c:1646 */
break;
case 52:
-#line 869 "awkgram.y" /* yacc.c:1646 */
+#line 870 "awkgram.y" /* yacc.c:1646 */
{
if (! break_allowed)
error_ln((yyvsp[-1])->source_line,
@@ -2638,11 +2639,11 @@ regular_loop:
(yyval) = list_create((yyvsp[-1]));
}
-#line 2642 "awkgram.c" /* yacc.c:1646 */
+#line 2643 "awkgram.c" /* yacc.c:1646 */
break;
case 53:
-#line 878 "awkgram.y" /* yacc.c:1646 */
+#line 879 "awkgram.y" /* yacc.c:1646 */
{
if (! continue_allowed)
error_ln((yyvsp[-1])->source_line,
@@ -2651,11 +2652,11 @@ regular_loop:
(yyval) = list_create((yyvsp[-1]));
}
-#line 2655 "awkgram.c" /* yacc.c:1646 */
+#line 2656 "awkgram.c" /* yacc.c:1646 */
break;
case 54:
-#line 887 "awkgram.y" /* yacc.c:1646 */
+#line 888 "awkgram.y" /* yacc.c:1646 */
{
/* if inside function (rule = 0), resolve context at run-time */
if (rule && rule != Rule)
@@ -2664,11 +2665,11 @@ regular_loop:
(yyvsp[-1])->target_jmp = ip_rec;
(yyval) = list_create((yyvsp[-1]));
}
-#line 2668 "awkgram.c" /* yacc.c:1646 */
+#line 2669 "awkgram.c" /* yacc.c:1646 */
break;
case 55:
-#line 896 "awkgram.y" /* yacc.c:1646 */
+#line 897 "awkgram.y" /* yacc.c:1646 */
{
/* if inside function (rule = 0), resolve context at run-time */
if (rule == BEGIN || rule == END || rule == ENDFILE)
@@ -2679,11 +2680,11 @@ regular_loop:
(yyvsp[-1])->target_endfile = ip_endfile;
(yyval) = list_create((yyvsp[-1]));
}
-#line 2683 "awkgram.c" /* yacc.c:1646 */
+#line 2684 "awkgram.c" /* yacc.c:1646 */
break;
case 56:
-#line 907 "awkgram.y" /* yacc.c:1646 */
+#line 908 "awkgram.y" /* yacc.c:1646 */
{
/* Initialize the two possible jump targets, the actual target
* is resolved at run-time.
@@ -2698,20 +2699,20 @@ regular_loop:
} else
(yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
}
-#line 2702 "awkgram.c" /* yacc.c:1646 */
+#line 2703 "awkgram.c" /* yacc.c:1646 */
break;
case 57:
-#line 922 "awkgram.y" /* yacc.c:1646 */
+#line 923 "awkgram.y" /* yacc.c:1646 */
{
if (! in_function)
yyerror(_("`return' used outside function context"));
}
-#line 2711 "awkgram.c" /* yacc.c:1646 */
+#line 2712 "awkgram.c" /* yacc.c:1646 */
break;
case 58:
-#line 925 "awkgram.y" /* yacc.c:1646 */
+#line 926 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-1]) == NULL) {
(yyval) = list_create((yyvsp[-3]));
@@ -2732,17 +2733,17 @@ regular_loop:
(yyval) = list_append((yyvsp[-1]), (yyvsp[-3]));
}
}
-#line 2736 "awkgram.c" /* yacc.c:1646 */
+#line 2737 "awkgram.c" /* yacc.c:1646 */
break;
case 60:
-#line 957 "awkgram.y" /* yacc.c:1646 */
+#line 958 "awkgram.y" /* yacc.c:1646 */
{ in_print = true; in_parens = 0; }
-#line 2742 "awkgram.c" /* yacc.c:1646 */
+#line 2743 "awkgram.c" /* yacc.c:1646 */
break;
case 61:
-#line 958 "awkgram.y" /* yacc.c:1646 */
+#line 959 "awkgram.y" /* yacc.c:1646 */
{
/*
* Optimization: plain `print' has no expression list, so $3 is null.
@@ -2839,17 +2840,17 @@ regular_print:
}
}
}
-#line 2843 "awkgram.c" /* yacc.c:1646 */
+#line 2844 "awkgram.c" /* yacc.c:1646 */
break;
case 62:
-#line 1055 "awkgram.y" /* yacc.c:1646 */
+#line 1056 "awkgram.y" /* yacc.c:1646 */
{ sub_counter = 0; }
-#line 2849 "awkgram.c" /* yacc.c:1646 */
+#line 2850 "awkgram.c" /* yacc.c:1646 */
break;
case 63:
-#line 1056 "awkgram.y" /* yacc.c:1646 */
+#line 1057 "awkgram.y" /* yacc.c:1646 */
{
char *arr = (yyvsp[-2])->lextok;
@@ -2882,11 +2883,11 @@ regular_print:
(yyval) = list_append(list_append((yyvsp[0]), (yyvsp[-2])), (yyvsp[-3]));
}
}
-#line 2886 "awkgram.c" /* yacc.c:1646 */
+#line 2887 "awkgram.c" /* yacc.c:1646 */
break;
case 64:
-#line 1093 "awkgram.y" /* yacc.c:1646 */
+#line 1094 "awkgram.y" /* yacc.c:1646 */
{
static bool warned = false;
char *arr = (yyvsp[-1])->lextok;
@@ -2912,52 +2913,52 @@ regular_print:
fatal(_("`delete' is not allowed with FUNCTAB"));
}
}
-#line 2916 "awkgram.c" /* yacc.c:1646 */
+#line 2917 "awkgram.c" /* yacc.c:1646 */
break;
case 65:
-#line 1119 "awkgram.y" /* yacc.c:1646 */
+#line 1120 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = optimize_assignment((yyvsp[0])); }
-#line 2922 "awkgram.c" /* yacc.c:1646 */
+#line 2923 "awkgram.c" /* yacc.c:1646 */
break;
case 66:
-#line 1124 "awkgram.y" /* yacc.c:1646 */
+#line 1125 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 2928 "awkgram.c" /* yacc.c:1646 */
+#line 2929 "awkgram.c" /* yacc.c:1646 */
break;
case 67:
-#line 1126 "awkgram.y" /* yacc.c:1646 */
+#line 1127 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 2934 "awkgram.c" /* yacc.c:1646 */
+#line 2935 "awkgram.c" /* yacc.c:1646 */
break;
case 68:
-#line 1131 "awkgram.y" /* yacc.c:1646 */
+#line 1132 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 2940 "awkgram.c" /* yacc.c:1646 */
+#line 2941 "awkgram.c" /* yacc.c:1646 */
break;
case 69:
-#line 1133 "awkgram.y" /* yacc.c:1646 */
+#line 1134 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-1]) == NULL)
(yyval) = list_create((yyvsp[0]));
else
(yyval) = list_prepend((yyvsp[-1]), (yyvsp[0]));
}
-#line 2951 "awkgram.c" /* yacc.c:1646 */
+#line 2952 "awkgram.c" /* yacc.c:1646 */
break;
case 70:
-#line 1140 "awkgram.y" /* yacc.c:1646 */
+#line 1141 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 2957 "awkgram.c" /* yacc.c:1646 */
+#line 2958 "awkgram.c" /* yacc.c:1646 */
break;
case 71:
-#line 1145 "awkgram.y" /* yacc.c:1646 */
+#line 1146 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *casestmt = (yyvsp[0]);
if ((yyvsp[0]) == NULL)
@@ -2969,11 +2970,11 @@ regular_print:
bcfree((yyvsp[-2]));
(yyval) = (yyvsp[-4]);
}
-#line 2973 "awkgram.c" /* yacc.c:1646 */
+#line 2974 "awkgram.c" /* yacc.c:1646 */
break;
case 72:
-#line 1157 "awkgram.y" /* yacc.c:1646 */
+#line 1158 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *casestmt = (yyvsp[0]);
if ((yyvsp[0]) == NULL)
@@ -2984,17 +2985,17 @@ regular_print:
(yyvsp[-3])->case_stmt = casestmt;
(yyval) = (yyvsp[-3]);
}
-#line 2988 "awkgram.c" /* yacc.c:1646 */
+#line 2989 "awkgram.c" /* yacc.c:1646 */
break;
case 73:
-#line 1171 "awkgram.y" /* yacc.c:1646 */
+#line 1172 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 2994 "awkgram.c" /* yacc.c:1646 */
+#line 2995 "awkgram.c" /* yacc.c:1646 */
break;
case 74:
-#line 1173 "awkgram.y" /* yacc.c:1646 */
+#line 1174 "awkgram.y" /* yacc.c:1646 */
{
NODE *n = (yyvsp[0])->memory;
(void) force_number(n);
@@ -3002,71 +3003,71 @@ regular_print:
bcfree((yyvsp[-1]));
(yyval) = (yyvsp[0]);
}
-#line 3006 "awkgram.c" /* yacc.c:1646 */
+#line 3007 "awkgram.c" /* yacc.c:1646 */
break;
case 75:
-#line 1181 "awkgram.y" /* yacc.c:1646 */
+#line 1182 "awkgram.y" /* yacc.c:1646 */
{
bcfree((yyvsp[-1]));
(yyval) = (yyvsp[0]);
}
-#line 3015 "awkgram.c" /* yacc.c:1646 */
+#line 3016 "awkgram.c" /* yacc.c:1646 */
break;
case 76:
-#line 1186 "awkgram.y" /* yacc.c:1646 */
+#line 1187 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3021 "awkgram.c" /* yacc.c:1646 */
+#line 3022 "awkgram.c" /* yacc.c:1646 */
break;
case 77:
-#line 1188 "awkgram.y" /* yacc.c:1646 */
+#line 1189 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_push_re;
(yyval) = (yyvsp[0]);
}
-#line 3030 "awkgram.c" /* yacc.c:1646 */
+#line 3031 "awkgram.c" /* yacc.c:1646 */
break;
case 78:
-#line 1196 "awkgram.y" /* yacc.c:1646 */
+#line 1197 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3036 "awkgram.c" /* yacc.c:1646 */
+#line 3037 "awkgram.c" /* yacc.c:1646 */
break;
case 79:
-#line 1198 "awkgram.y" /* yacc.c:1646 */
+#line 1199 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3042 "awkgram.c" /* yacc.c:1646 */
+#line 3043 "awkgram.c" /* yacc.c:1646 */
break;
case 81:
-#line 1208 "awkgram.y" /* yacc.c:1646 */
+#line 1209 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = (yyvsp[-1]);
}
-#line 3050 "awkgram.c" /* yacc.c:1646 */
+#line 3051 "awkgram.c" /* yacc.c:1646 */
break;
case 82:
-#line 1215 "awkgram.y" /* yacc.c:1646 */
+#line 1216 "awkgram.y" /* yacc.c:1646 */
{
in_print = false;
in_parens = 0;
(yyval) = NULL;
}
-#line 3060 "awkgram.c" /* yacc.c:1646 */
+#line 3061 "awkgram.c" /* yacc.c:1646 */
break;
case 83:
-#line 1220 "awkgram.y" /* yacc.c:1646 */
+#line 1221 "awkgram.y" /* yacc.c:1646 */
{ in_print = false; in_parens = 0; }
-#line 3066 "awkgram.c" /* yacc.c:1646 */
+#line 3067 "awkgram.c" /* yacc.c:1646 */
break;
case 84:
-#line 1221 "awkgram.y" /* yacc.c:1646 */
+#line 1222 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-2])->redir_type == redirect_twoway
&& (yyvsp[0])->lasti->opcode == Op_K_getline_redir
@@ -3074,136 +3075,136 @@ regular_print:
yyerror(_("multistage two-way pipelines don't work"));
(yyval) = list_prepend((yyvsp[0]), (yyvsp[-2]));
}
-#line 3078 "awkgram.c" /* yacc.c:1646 */
+#line 3079 "awkgram.c" /* yacc.c:1646 */
break;
case 85:
-#line 1232 "awkgram.y" /* yacc.c:1646 */
+#line 1233 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_condition((yyvsp[-3]), (yyvsp[-5]), (yyvsp[0]), NULL, NULL);
}
-#line 3086 "awkgram.c" /* yacc.c:1646 */
+#line 3087 "awkgram.c" /* yacc.c:1646 */
break;
case 86:
-#line 1237 "awkgram.y" /* yacc.c:1646 */
+#line 1238 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_condition((yyvsp[-6]), (yyvsp[-8]), (yyvsp[-3]), (yyvsp[-2]), (yyvsp[0]));
}
-#line 3094 "awkgram.c" /* yacc.c:1646 */
+#line 3095 "awkgram.c" /* yacc.c:1646 */
break;
case 91:
-#line 1254 "awkgram.y" /* yacc.c:1646 */
+#line 1255 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3100 "awkgram.c" /* yacc.c:1646 */
+#line 3101 "awkgram.c" /* yacc.c:1646 */
break;
case 92:
-#line 1256 "awkgram.y" /* yacc.c:1646 */
+#line 1257 "awkgram.y" /* yacc.c:1646 */
{
bcfree((yyvsp[-1]));
(yyval) = (yyvsp[0]);
}
-#line 3109 "awkgram.c" /* yacc.c:1646 */
+#line 3110 "awkgram.c" /* yacc.c:1646 */
break;
case 93:
-#line 1264 "awkgram.y" /* yacc.c:1646 */
+#line 1265 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3115 "awkgram.c" /* yacc.c:1646 */
+#line 3116 "awkgram.c" /* yacc.c:1646 */
break;
case 94:
-#line 1266 "awkgram.y" /* yacc.c:1646 */
+#line 1267 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3121 "awkgram.c" /* yacc.c:1646 */
+#line 3122 "awkgram.c" /* yacc.c:1646 */
break;
case 95:
-#line 1271 "awkgram.y" /* yacc.c:1646 */
+#line 1272 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->param_count = 0;
(yyval) = list_create((yyvsp[0]));
}
-#line 3130 "awkgram.c" /* yacc.c:1646 */
+#line 3131 "awkgram.c" /* yacc.c:1646 */
break;
case 96:
-#line 1276 "awkgram.y" /* yacc.c:1646 */
+#line 1277 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->param_count = (yyvsp[-2])->lasti->param_count + 1;
(yyval) = list_append((yyvsp[-2]), (yyvsp[0]));
yyerrok;
}
-#line 3140 "awkgram.c" /* yacc.c:1646 */
+#line 3141 "awkgram.c" /* yacc.c:1646 */
break;
case 97:
-#line 1282 "awkgram.y" /* yacc.c:1646 */
+#line 1283 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3146 "awkgram.c" /* yacc.c:1646 */
+#line 3147 "awkgram.c" /* yacc.c:1646 */
break;
case 98:
-#line 1284 "awkgram.y" /* yacc.c:1646 */
+#line 1285 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 3152 "awkgram.c" /* yacc.c:1646 */
+#line 3153 "awkgram.c" /* yacc.c:1646 */
break;
case 99:
-#line 1286 "awkgram.y" /* yacc.c:1646 */
+#line 1287 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-2]); }
-#line 3158 "awkgram.c" /* yacc.c:1646 */
+#line 3159 "awkgram.c" /* yacc.c:1646 */
break;
case 100:
-#line 1292 "awkgram.y" /* yacc.c:1646 */
+#line 1293 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3164 "awkgram.c" /* yacc.c:1646 */
+#line 3165 "awkgram.c" /* yacc.c:1646 */
break;
case 101:
-#line 1294 "awkgram.y" /* yacc.c:1646 */
+#line 1295 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3170 "awkgram.c" /* yacc.c:1646 */
+#line 3171 "awkgram.c" /* yacc.c:1646 */
break;
case 102:
-#line 1299 "awkgram.y" /* yacc.c:1646 */
+#line 1300 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3176 "awkgram.c" /* yacc.c:1646 */
+#line 3177 "awkgram.c" /* yacc.c:1646 */
break;
case 103:
-#line 1301 "awkgram.y" /* yacc.c:1646 */
+#line 1302 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3182 "awkgram.c" /* yacc.c:1646 */
+#line 3183 "awkgram.c" /* yacc.c:1646 */
break;
case 104:
-#line 1306 "awkgram.y" /* yacc.c:1646 */
+#line 1307 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_expression_list(NULL, (yyvsp[0])); }
-#line 3188 "awkgram.c" /* yacc.c:1646 */
+#line 3189 "awkgram.c" /* yacc.c:1646 */
break;
case 105:
-#line 1308 "awkgram.y" /* yacc.c:1646 */
+#line 1309 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
yyerrok;
}
-#line 3197 "awkgram.c" /* yacc.c:1646 */
+#line 3198 "awkgram.c" /* yacc.c:1646 */
break;
case 106:
-#line 1313 "awkgram.y" /* yacc.c:1646 */
+#line 1314 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3203 "awkgram.c" /* yacc.c:1646 */
+#line 3204 "awkgram.c" /* yacc.c:1646 */
break;
case 107:
-#line 1315 "awkgram.y" /* yacc.c:1646 */
+#line 1316 "awkgram.y" /* yacc.c:1646 */
{
/*
* Returning the expression list instead of NULL lets
@@ -3211,52 +3212,52 @@ regular_print:
*/
(yyval) = (yyvsp[-1]);
}
-#line 3215 "awkgram.c" /* yacc.c:1646 */
+#line 3216 "awkgram.c" /* yacc.c:1646 */
break;
case 108:
-#line 1323 "awkgram.y" /* yacc.c:1646 */
+#line 1324 "awkgram.y" /* yacc.c:1646 */
{
/* Ditto */
(yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
}
-#line 3224 "awkgram.c" /* yacc.c:1646 */
+#line 3225 "awkgram.c" /* yacc.c:1646 */
break;
case 109:
-#line 1328 "awkgram.y" /* yacc.c:1646 */
+#line 1329 "awkgram.y" /* yacc.c:1646 */
{
/* Ditto */
(yyval) = (yyvsp[-2]);
}
-#line 3233 "awkgram.c" /* yacc.c:1646 */
+#line 3234 "awkgram.c" /* yacc.c:1646 */
break;
case 110:
-#line 1337 "awkgram.y" /* yacc.c:1646 */
+#line 1338 "awkgram.y" /* yacc.c:1646 */
{
if (do_lint && (yyvsp[0])->lasti->opcode == Op_match_rec)
lintwarn_ln((yyvsp[-1])->source_line,
_("regular expression on right of assignment"));
(yyval) = mk_assignment((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1]));
}
-#line 3244 "awkgram.c" /* yacc.c:1646 */
+#line 3245 "awkgram.c" /* yacc.c:1646 */
break;
case 111:
-#line 1344 "awkgram.y" /* yacc.c:1646 */
+#line 1345 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3250 "awkgram.c" /* yacc.c:1646 */
+#line 3251 "awkgram.c" /* yacc.c:1646 */
break;
case 112:
-#line 1346 "awkgram.y" /* yacc.c:1646 */
+#line 1347 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3256 "awkgram.c" /* yacc.c:1646 */
+#line 3257 "awkgram.c" /* yacc.c:1646 */
break;
case 113:
-#line 1348 "awkgram.y" /* yacc.c:1646 */
+#line 1349 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-2])->lasti->opcode == Op_match_rec)
warning_ln((yyvsp[-1])->source_line,
@@ -3272,11 +3273,11 @@ regular_print:
(yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1]));
}
}
-#line 3276 "awkgram.c" /* yacc.c:1646 */
+#line 3277 "awkgram.c" /* yacc.c:1646 */
break;
case 114:
-#line 1364 "awkgram.y" /* yacc.c:1646 */
+#line 1365 "awkgram.y" /* yacc.c:1646 */
{
if (do_lint_old)
warning_ln((yyvsp[-1])->source_line,
@@ -3286,91 +3287,91 @@ regular_print:
(yyvsp[-1])->expr_count = 1;
(yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1]));
}
-#line 3290 "awkgram.c" /* yacc.c:1646 */
+#line 3291 "awkgram.c" /* yacc.c:1646 */
break;
case 115:
-#line 1374 "awkgram.y" /* yacc.c:1646 */
+#line 1375 "awkgram.y" /* yacc.c:1646 */
{
if (do_lint && (yyvsp[0])->lasti->opcode == Op_match_rec)
lintwarn_ln((yyvsp[-1])->source_line,
_("regular expression on right of comparison"));
(yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1]));
}
-#line 3301 "awkgram.c" /* yacc.c:1646 */
+#line 3302 "awkgram.c" /* yacc.c:1646 */
break;
case 116:
-#line 1381 "awkgram.y" /* yacc.c:1646 */
+#line 1382 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_condition((yyvsp[-4]), (yyvsp[-3]), (yyvsp[-2]), (yyvsp[-1]), (yyvsp[0])); }
-#line 3307 "awkgram.c" /* yacc.c:1646 */
+#line 3308 "awkgram.c" /* yacc.c:1646 */
break;
case 117:
-#line 1383 "awkgram.y" /* yacc.c:1646 */
+#line 1384 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3313 "awkgram.c" /* yacc.c:1646 */
+#line 3314 "awkgram.c" /* yacc.c:1646 */
break;
case 118:
-#line 1388 "awkgram.y" /* yacc.c:1646 */
+#line 1389 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3319 "awkgram.c" /* yacc.c:1646 */
+#line 3320 "awkgram.c" /* yacc.c:1646 */
break;
case 119:
-#line 1390 "awkgram.y" /* yacc.c:1646 */
+#line 1391 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3325 "awkgram.c" /* yacc.c:1646 */
+#line 3326 "awkgram.c" /* yacc.c:1646 */
break;
case 120:
-#line 1392 "awkgram.y" /* yacc.c:1646 */
+#line 1393 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_assign_quotient;
(yyval) = (yyvsp[0]);
}
-#line 3334 "awkgram.c" /* yacc.c:1646 */
+#line 3335 "awkgram.c" /* yacc.c:1646 */
break;
case 121:
-#line 1400 "awkgram.y" /* yacc.c:1646 */
+#line 1401 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3340 "awkgram.c" /* yacc.c:1646 */
+#line 3341 "awkgram.c" /* yacc.c:1646 */
break;
case 122:
-#line 1402 "awkgram.y" /* yacc.c:1646 */
+#line 1403 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3346 "awkgram.c" /* yacc.c:1646 */
+#line 3347 "awkgram.c" /* yacc.c:1646 */
break;
case 123:
-#line 1407 "awkgram.y" /* yacc.c:1646 */
+#line 1408 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3352 "awkgram.c" /* yacc.c:1646 */
+#line 3353 "awkgram.c" /* yacc.c:1646 */
break;
case 124:
-#line 1409 "awkgram.y" /* yacc.c:1646 */
+#line 1410 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3358 "awkgram.c" /* yacc.c:1646 */
+#line 3359 "awkgram.c" /* yacc.c:1646 */
break;
case 125:
-#line 1414 "awkgram.y" /* yacc.c:1646 */
+#line 1415 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3364 "awkgram.c" /* yacc.c:1646 */
+#line 3365 "awkgram.c" /* yacc.c:1646 */
break;
case 126:
-#line 1416 "awkgram.y" /* yacc.c:1646 */
+#line 1417 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3370 "awkgram.c" /* yacc.c:1646 */
+#line 3371 "awkgram.c" /* yacc.c:1646 */
break;
case 127:
-#line 1418 "awkgram.y" /* yacc.c:1646 */
+#line 1419 "awkgram.y" /* yacc.c:1646 */
{
int count = 2;
bool is_simple_var = false;
@@ -3417,47 +3418,47 @@ regular_print:
max_args = count;
}
}
-#line 3421 "awkgram.c" /* yacc.c:1646 */
+#line 3422 "awkgram.c" /* yacc.c:1646 */
break;
case 129:
-#line 1470 "awkgram.y" /* yacc.c:1646 */
+#line 1471 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3427 "awkgram.c" /* yacc.c:1646 */
+#line 3428 "awkgram.c" /* yacc.c:1646 */
break;
case 130:
-#line 1472 "awkgram.y" /* yacc.c:1646 */
+#line 1473 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3433 "awkgram.c" /* yacc.c:1646 */
+#line 3434 "awkgram.c" /* yacc.c:1646 */
break;
case 131:
-#line 1474 "awkgram.y" /* yacc.c:1646 */
+#line 1475 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3439 "awkgram.c" /* yacc.c:1646 */
+#line 3440 "awkgram.c" /* yacc.c:1646 */
break;
case 132:
-#line 1476 "awkgram.y" /* yacc.c:1646 */
+#line 1477 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3445 "awkgram.c" /* yacc.c:1646 */
+#line 3446 "awkgram.c" /* yacc.c:1646 */
break;
case 133:
-#line 1478 "awkgram.y" /* yacc.c:1646 */
+#line 1479 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3451 "awkgram.c" /* yacc.c:1646 */
+#line 3452 "awkgram.c" /* yacc.c:1646 */
break;
case 134:
-#line 1480 "awkgram.y" /* yacc.c:1646 */
+#line 1481 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3457 "awkgram.c" /* yacc.c:1646 */
+#line 3458 "awkgram.c" /* yacc.c:1646 */
break;
case 135:
-#line 1482 "awkgram.y" /* yacc.c:1646 */
+#line 1483 "awkgram.y" /* yacc.c:1646 */
{
/*
* In BEGINFILE/ENDFILE, allow `getline [var] < file'
@@ -3471,29 +3472,29 @@ regular_print:
_("non-redirected `getline' undefined inside END action"));
(yyval) = mk_getline((yyvsp[-2]), (yyvsp[-1]), (yyvsp[0]), redirect_input);
}
-#line 3475 "awkgram.c" /* yacc.c:1646 */
+#line 3476 "awkgram.c" /* yacc.c:1646 */
break;
case 136:
-#line 1496 "awkgram.y" /* yacc.c:1646 */
+#line 1497 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_postincrement;
(yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
}
-#line 3484 "awkgram.c" /* yacc.c:1646 */
+#line 3485 "awkgram.c" /* yacc.c:1646 */
break;
case 137:
-#line 1501 "awkgram.y" /* yacc.c:1646 */
+#line 1502 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_postdecrement;
(yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
}
-#line 3493 "awkgram.c" /* yacc.c:1646 */
+#line 3494 "awkgram.c" /* yacc.c:1646 */
break;
case 138:
-#line 1506 "awkgram.y" /* yacc.c:1646 */
+#line 1507 "awkgram.y" /* yacc.c:1646 */
{
if (do_lint_old) {
warning_ln((yyvsp[-1])->source_line,
@@ -3513,64 +3514,64 @@ regular_print:
(yyval) = list_append(list_merge(t, (yyvsp[0])), (yyvsp[-1]));
}
}
-#line 3517 "awkgram.c" /* yacc.c:1646 */
+#line 3518 "awkgram.c" /* yacc.c:1646 */
break;
case 139:
-#line 1531 "awkgram.y" /* yacc.c:1646 */
+#line 1532 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_getline((yyvsp[-1]), (yyvsp[0]), (yyvsp[-3]), (yyvsp[-2])->redir_type);
bcfree((yyvsp[-2]));
}
-#line 3526 "awkgram.c" /* yacc.c:1646 */
+#line 3527 "awkgram.c" /* yacc.c:1646 */
break;
case 140:
-#line 1537 "awkgram.y" /* yacc.c:1646 */
+#line 1538 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3532 "awkgram.c" /* yacc.c:1646 */
+#line 3533 "awkgram.c" /* yacc.c:1646 */
break;
case 141:
-#line 1539 "awkgram.y" /* yacc.c:1646 */
+#line 1540 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3538 "awkgram.c" /* yacc.c:1646 */
+#line 3539 "awkgram.c" /* yacc.c:1646 */
break;
case 142:
-#line 1541 "awkgram.y" /* yacc.c:1646 */
+#line 1542 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3544 "awkgram.c" /* yacc.c:1646 */
+#line 3545 "awkgram.c" /* yacc.c:1646 */
break;
case 143:
-#line 1543 "awkgram.y" /* yacc.c:1646 */
+#line 1544 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3550 "awkgram.c" /* yacc.c:1646 */
+#line 3551 "awkgram.c" /* yacc.c:1646 */
break;
case 144:
-#line 1545 "awkgram.y" /* yacc.c:1646 */
+#line 1546 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3556 "awkgram.c" /* yacc.c:1646 */
+#line 3557 "awkgram.c" /* yacc.c:1646 */
break;
case 145:
-#line 1547 "awkgram.y" /* yacc.c:1646 */
+#line 1548 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3562 "awkgram.c" /* yacc.c:1646 */
+#line 3563 "awkgram.c" /* yacc.c:1646 */
break;
case 146:
-#line 1552 "awkgram.y" /* yacc.c:1646 */
+#line 1553 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_create((yyvsp[0]));
}
-#line 3570 "awkgram.c" /* yacc.c:1646 */
+#line 3571 "awkgram.c" /* yacc.c:1646 */
break;
case 147:
-#line 1556 "awkgram.y" /* yacc.c:1646 */
+#line 1557 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[0])->opcode == Op_match_rec) {
(yyvsp[0])->opcode = Op_nomatch;
@@ -3602,37 +3603,37 @@ regular_print:
}
}
}
-#line 3606 "awkgram.c" /* yacc.c:1646 */
+#line 3607 "awkgram.c" /* yacc.c:1646 */
break;
case 148:
-#line 1588 "awkgram.y" /* yacc.c:1646 */
+#line 1589 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 3612 "awkgram.c" /* yacc.c:1646 */
+#line 3613 "awkgram.c" /* yacc.c:1646 */
break;
case 149:
-#line 1590 "awkgram.y" /* yacc.c:1646 */
+#line 1591 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
if ((yyval) == NULL)
YYABORT;
}
-#line 3622 "awkgram.c" /* yacc.c:1646 */
+#line 3623 "awkgram.c" /* yacc.c:1646 */
break;
case 150:
-#line 1596 "awkgram.y" /* yacc.c:1646 */
+#line 1597 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
if ((yyval) == NULL)
YYABORT;
}
-#line 3632 "awkgram.c" /* yacc.c:1646 */
+#line 3633 "awkgram.c" /* yacc.c:1646 */
break;
case 151:
-#line 1602 "awkgram.y" /* yacc.c:1646 */
+#line 1603 "awkgram.y" /* yacc.c:1646 */
{
static bool warned = false;
@@ -3645,45 +3646,45 @@ regular_print:
if ((yyval) == NULL)
YYABORT;
}
-#line 3649 "awkgram.c" /* yacc.c:1646 */
+#line 3650 "awkgram.c" /* yacc.c:1646 */
break;
case 154:
-#line 1617 "awkgram.y" /* yacc.c:1646 */
+#line 1618 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[-1])->opcode = Op_preincrement;
(yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
}
-#line 3658 "awkgram.c" /* yacc.c:1646 */
+#line 3659 "awkgram.c" /* yacc.c:1646 */
break;
case 155:
-#line 1622 "awkgram.y" /* yacc.c:1646 */
+#line 1623 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[-1])->opcode = Op_predecrement;
(yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
}
-#line 3667 "awkgram.c" /* yacc.c:1646 */
+#line 3668 "awkgram.c" /* yacc.c:1646 */
break;
case 156:
-#line 1627 "awkgram.y" /* yacc.c:1646 */
+#line 1628 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_create((yyvsp[0]));
}
-#line 3675 "awkgram.c" /* yacc.c:1646 */
+#line 3676 "awkgram.c" /* yacc.c:1646 */
break;
case 157:
-#line 1631 "awkgram.y" /* yacc.c:1646 */
+#line 1632 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_create((yyvsp[0]));
}
-#line 3683 "awkgram.c" /* yacc.c:1646 */
+#line 3684 "awkgram.c" /* yacc.c:1646 */
break;
case 158:
-#line 1635 "awkgram.y" /* yacc.c:1646 */
+#line 1636 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[0])->lasti->opcode == Op_push_i
&& ((yyvsp[0])->lasti->memory->flags & (STRCUR|STRING)) == 0
@@ -3698,11 +3699,11 @@ regular_print:
(yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
}
}
-#line 3702 "awkgram.c" /* yacc.c:1646 */
+#line 3703 "awkgram.c" /* yacc.c:1646 */
break;
case 159:
-#line 1650 "awkgram.y" /* yacc.c:1646 */
+#line 1651 "awkgram.y" /* yacc.c:1646 */
{
/*
* was: $$ = $2
@@ -3712,20 +3713,20 @@ regular_print:
(yyvsp[-1])->memory = make_number(0.0);
(yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
}
-#line 3716 "awkgram.c" /* yacc.c:1646 */
+#line 3717 "awkgram.c" /* yacc.c:1646 */
break;
case 160:
-#line 1663 "awkgram.y" /* yacc.c:1646 */
+#line 1664 "awkgram.y" /* yacc.c:1646 */
{
func_use((yyvsp[0])->lasti->func_name, FUNC_USE);
(yyval) = (yyvsp[0]);
}
-#line 3725 "awkgram.c" /* yacc.c:1646 */
+#line 3726 "awkgram.c" /* yacc.c:1646 */
break;
case 161:
-#line 1668 "awkgram.y" /* yacc.c:1646 */
+#line 1669 "awkgram.y" /* yacc.c:1646 */
{
/* indirect function call */
INSTRUCTION *f, *t;
@@ -3759,11 +3760,11 @@ regular_print:
(yyval) = list_prepend((yyvsp[0]), t);
at_seen = false;
}
-#line 3763 "awkgram.c" /* yacc.c:1646 */
+#line 3764 "awkgram.c" /* yacc.c:1646 */
break;
case 162:
-#line 1705 "awkgram.y" /* yacc.c:1646 */
+#line 1706 "awkgram.y" /* yacc.c:1646 */
{
NODE *n;
@@ -3788,49 +3789,49 @@ regular_print:
(yyval) = list_append(t, (yyvsp[-3]));
}
}
-#line 3792 "awkgram.c" /* yacc.c:1646 */
+#line 3793 "awkgram.c" /* yacc.c:1646 */
break;
case 163:
-#line 1733 "awkgram.y" /* yacc.c:1646 */
+#line 1734 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3798 "awkgram.c" /* yacc.c:1646 */
+#line 3799 "awkgram.c" /* yacc.c:1646 */
break;
case 164:
-#line 1735 "awkgram.y" /* yacc.c:1646 */
+#line 1736 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3804 "awkgram.c" /* yacc.c:1646 */
+#line 3805 "awkgram.c" /* yacc.c:1646 */
break;
case 165:
-#line 1740 "awkgram.y" /* yacc.c:1646 */
+#line 1741 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3810 "awkgram.c" /* yacc.c:1646 */
+#line 3811 "awkgram.c" /* yacc.c:1646 */
break;
case 166:
-#line 1742 "awkgram.y" /* yacc.c:1646 */
+#line 1743 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 3816 "awkgram.c" /* yacc.c:1646 */
+#line 3817 "awkgram.c" /* yacc.c:1646 */
break;
case 167:
-#line 1747 "awkgram.y" /* yacc.c:1646 */
+#line 1748 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3822 "awkgram.c" /* yacc.c:1646 */
+#line 3823 "awkgram.c" /* yacc.c:1646 */
break;
case 168:
-#line 1749 "awkgram.y" /* yacc.c:1646 */
+#line 1750 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
}
-#line 3830 "awkgram.c" /* yacc.c:1646 */
+#line 3831 "awkgram.c" /* yacc.c:1646 */
break;
case 169:
-#line 1756 "awkgram.y" /* yacc.c:1646 */
+#line 1757 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *ip = (yyvsp[0])->lasti;
int count = ip->sub_count; /* # of SUBSEP-seperated expressions */
@@ -3844,11 +3845,11 @@ regular_print:
sub_counter++; /* count # of dimensions */
(yyval) = (yyvsp[0]);
}
-#line 3848 "awkgram.c" /* yacc.c:1646 */
+#line 3849 "awkgram.c" /* yacc.c:1646 */
break;
case 170:
-#line 1773 "awkgram.y" /* yacc.c:1646 */
+#line 1774 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *t = (yyvsp[-1]);
if ((yyvsp[-1]) == NULL) {
@@ -3862,31 +3863,31 @@ regular_print:
(yyvsp[0])->sub_count = count_expressions(&t, false);
(yyval) = list_append(t, (yyvsp[0]));
}
-#line 3866 "awkgram.c" /* yacc.c:1646 */
+#line 3867 "awkgram.c" /* yacc.c:1646 */
break;
case 171:
-#line 1790 "awkgram.y" /* yacc.c:1646 */
+#line 1791 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3872 "awkgram.c" /* yacc.c:1646 */
+#line 3873 "awkgram.c" /* yacc.c:1646 */
break;
case 172:
-#line 1792 "awkgram.y" /* yacc.c:1646 */
+#line 1793 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
}
-#line 3880 "awkgram.c" /* yacc.c:1646 */
+#line 3881 "awkgram.c" /* yacc.c:1646 */
break;
case 173:
-#line 1799 "awkgram.y" /* yacc.c:1646 */
+#line 1800 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 3886 "awkgram.c" /* yacc.c:1646 */
+#line 3887 "awkgram.c" /* yacc.c:1646 */
break;
case 174:
-#line 1804 "awkgram.y" /* yacc.c:1646 */
+#line 1805 "awkgram.y" /* yacc.c:1646 */
{
char *var_name = (yyvsp[0])->lextok;
@@ -3894,22 +3895,22 @@ regular_print:
(yyvsp[0])->memory = variable((yyvsp[0])->source_line, var_name, Node_var_new);
(yyval) = list_create((yyvsp[0]));
}
-#line 3898 "awkgram.c" /* yacc.c:1646 */
+#line 3899 "awkgram.c" /* yacc.c:1646 */
break;
case 175:
-#line 1812 "awkgram.y" /* yacc.c:1646 */
+#line 1813 "awkgram.y" /* yacc.c:1646 */
{
char *arr = (yyvsp[-1])->lextok;
(yyvsp[-1])->memory = variable((yyvsp[-1])->source_line, arr, Node_var_new);
(yyvsp[-1])->opcode = Op_push_array;
(yyval) = list_prepend((yyvsp[0]), (yyvsp[-1]));
}
-#line 3909 "awkgram.c" /* yacc.c:1646 */
+#line 3910 "awkgram.c" /* yacc.c:1646 */
break;
case 176:
-#line 1822 "awkgram.y" /* yacc.c:1646 */
+#line 1823 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *ip = (yyvsp[0])->nexti;
if (ip->opcode == Op_push
@@ -3921,73 +3922,73 @@ regular_print:
} else
(yyval) = (yyvsp[0]);
}
-#line 3925 "awkgram.c" /* yacc.c:1646 */
+#line 3926 "awkgram.c" /* yacc.c:1646 */
break;
case 177:
-#line 1834 "awkgram.y" /* yacc.c:1646 */
+#line 1835 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
if ((yyvsp[0]) != NULL)
mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
}
-#line 3935 "awkgram.c" /* yacc.c:1646 */
+#line 3936 "awkgram.c" /* yacc.c:1646 */
break;
case 178:
-#line 1843 "awkgram.y" /* yacc.c:1646 */
+#line 1844 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_postincrement;
}
-#line 3943 "awkgram.c" /* yacc.c:1646 */
+#line 3944 "awkgram.c" /* yacc.c:1646 */
break;
case 179:
-#line 1847 "awkgram.y" /* yacc.c:1646 */
+#line 1848 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_postdecrement;
}
-#line 3951 "awkgram.c" /* yacc.c:1646 */
+#line 3952 "awkgram.c" /* yacc.c:1646 */
break;
case 180:
-#line 1850 "awkgram.y" /* yacc.c:1646 */
+#line 1851 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3957 "awkgram.c" /* yacc.c:1646 */
+#line 3958 "awkgram.c" /* yacc.c:1646 */
break;
case 182:
-#line 1858 "awkgram.y" /* yacc.c:1646 */
+#line 1859 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
-#line 3963 "awkgram.c" /* yacc.c:1646 */
+#line 3964 "awkgram.c" /* yacc.c:1646 */
break;
case 183:
-#line 1862 "awkgram.y" /* yacc.c:1646 */
+#line 1863 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
-#line 3969 "awkgram.c" /* yacc.c:1646 */
+#line 3970 "awkgram.c" /* yacc.c:1646 */
break;
case 186:
-#line 1871 "awkgram.y" /* yacc.c:1646 */
+#line 1872 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
-#line 3975 "awkgram.c" /* yacc.c:1646 */
+#line 3976 "awkgram.c" /* yacc.c:1646 */
break;
case 187:
-#line 1875 "awkgram.y" /* yacc.c:1646 */
+#line 1876 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); yyerrok; }
-#line 3981 "awkgram.c" /* yacc.c:1646 */
+#line 3982 "awkgram.c" /* yacc.c:1646 */
break;
case 188:
-#line 1879 "awkgram.y" /* yacc.c:1646 */
+#line 1880 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
-#line 3987 "awkgram.c" /* yacc.c:1646 */
+#line 3988 "awkgram.c" /* yacc.c:1646 */
break;
-#line 3991 "awkgram.c" /* yacc.c:1646 */
+#line 3992 "awkgram.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -4215,7 +4216,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 1881 "awkgram.y" /* yacc.c:1906 */
+#line 1882 "awkgram.y" /* yacc.c:1906 */
struct token {
@@ -4724,7 +4725,7 @@ parse_program(INSTRUCTION **pcode)
ip_newfile = ip_rec = ip_atexit = ip_beginfile = ip_endfile = NULL;
else {
ip_endfile = instruction(Op_no_op);
- ip_beginfile = instruction(Op_no_op);
+ main_beginfile = ip_beginfile = instruction(Op_no_op);
ip_rec = instruction(Op_get_record); /* target for `next', also ip_newfile */
ip_newfile = bcalloc(Op_newfile, 2, 0); /* target for `nextfile' */
ip_newfile->target_jmp = ip_end;
diff --git a/awkgram.y b/awkgram.y
index 28dc8567..067a933f 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -144,6 +144,7 @@ static INSTRUCTION *ip_atexit = NULL;
static INSTRUCTION *ip_end;
static INSTRUCTION *ip_endfile;
static INSTRUCTION *ip_beginfile;
+INSTRUCTION *main_beginfile;
static INSTRUCTION *comment = NULL;
static INSTRUCTION *program_comment = NULL;
@@ -2386,7 +2387,7 @@ parse_program(INSTRUCTION **pcode)
ip_newfile = ip_rec = ip_atexit = ip_beginfile = ip_endfile = NULL;
else {
ip_endfile = instruction(Op_no_op);
- ip_beginfile = instruction(Op_no_op);
+ main_beginfile = ip_beginfile = instruction(Op_no_op);
ip_rec = instruction(Op_get_record); /* target for `next', also ip_newfile */
ip_newfile = bcalloc(Op_newfile, 2, 0); /* target for `nextfile' */
ip_newfile->target_jmp = ip_end;
diff --git a/awklib/eg/lib/inplace.awk b/awklib/eg/lib/inplace.awk
index 6403a228..d1574654 100644
--- a/awklib/eg/lib/inplace.awk
+++ b/awklib/eg/lib/inplace.awk
@@ -5,10 +5,15 @@
# Please set INPLACE_SUFFIX to make a backup copy. For example, you may
# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
+# N.B. We call inplace_end() in the BEGINFILE and END rules so that any
+# actions in an ENDFILE rule will be redirected as expected.
+
BEGINFILE {
- inplace_begin(FILENAME, INPLACE_SUFFIX)
+ if (_inplace_filename != "")
+ inplace_end(_inplace_filename, INPLACE_SUFFIX)
+ inplace_begin(_inplace_filename = FILENAME, INPLACE_SUFFIX)
}
-ENDFILE {
+END {
inplace_end(FILENAME, INPLACE_SUFFIX)
}
diff --git a/config.guess b/config.guess
index 6c32c864..dbfb9786 100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2014-11-04'
+timestamp='2015-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
diff --git a/config.sub b/config.sub
index 7ffe3737..6d2e94c8 100755
--- a/config.sub
+++ b/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2014-12-03'
+timestamp='2015-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -260,7 +260,7 @@ case $basic_machine in
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
- | fido | fr30 | frv \
+ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
diff --git a/configh.in b/configh.in
index a3c411bb..f4309812 100644
--- a/configh.in
+++ b/configh.in
@@ -168,6 +168,9 @@
/* Define to 1 if you have the `setsid' function. */
#undef HAVE_SETSID
+/* Define to 1 if you have the `sigprocmask' function. */
+#undef HAVE_SIGPROCMASK
+
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
@@ -293,6 +296,9 @@
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
diff --git a/configure b/configure
index e425f55a..def8a041 100755
--- a/configure
+++ b/configure
@@ -10323,9 +10323,10 @@ esac
for ac_func in atexit btowc fmod getgrent getgroups grantpt \
isascii iswctype iswlower iswupper mbrlen \
memcmp memcpy memcpy_ulong memmove memset \
- memset_ulong mkstemp posix_openpt setenv setlocale setsid snprintf strchr \
+ memset_ulong mkstemp posix_openpt setenv setlocale setsid sigprocmask \
+ snprintf strchr \
strerror strftime strcasecmp strncasecmp strcoll strtod strtoul \
- system tmpfile towlower towupper tzset usleep wcrtomb \
+ system tmpfile towlower towupper tzset usleep waitpid wcrtomb \
wcscoll wctype
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
diff --git a/configure.ac b/configure.ac
index 7c922ccf..a6972ab2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -269,9 +269,10 @@ esac
AC_CHECK_FUNCS(atexit btowc fmod getgrent getgroups grantpt \
isascii iswctype iswlower iswupper mbrlen \
memcmp memcpy memcpy_ulong memmove memset \
- memset_ulong mkstemp posix_openpt setenv setlocale setsid snprintf strchr \
+ memset_ulong mkstemp posix_openpt setenv setlocale setsid sigprocmask \
+ snprintf strchr \
strerror strftime strcasecmp strncasecmp strcoll strtod strtoul \
- system tmpfile towlower towupper tzset usleep wcrtomb \
+ system tmpfile towlower towupper tzset usleep waitpid wcrtomb \
wcscoll wctype)
dnl this check is for both mbrtowc and the mbstate_t type, which is good
AC_FUNC_MBRTOWC
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 4fb63919..f4a6f19b 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,21 @@
+2015-03-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor edits.
+
+2015-03-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor fixes from Antonio Colombo and new exercise
+ in chapter 16.
+ * gawk.1: Minor edits.
+ * gawktexi.in: Edits in material on errno and retryable and get_file
+ API.
+
+2015-03-17 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in: Modify inplace.awk to call inplace_end in BEGINFILE
+ and END instead of in ENDFILE. This way, actions in ENDFILE rules
+ will be redirected as expected.
+
2015-03-17 Arnold D. Robbins <arnold@skeeve.com>
* gawktexi.in: Turn "positive" into non-negative as appropriate.
@@ -132,6 +150,25 @@
* gawktexi.in: Add info that nonfatal I/O works with stdout and
stderr. Revise version info and what was added when.
+2015-01-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in: Improve get_file documentation.
+
+2015-01-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in: Replace "Retrying I/O" with "Retrying Input", since this
+ feature pertains to input, not output.
+
+2015-01-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in: Document the get_file API function.
+
+2015-01-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.1: Document new features PROCINFO["errno"] and
+ PROCINFO["input", "RETRY"], and new getline return value of -2.
+ * gawktexi.in: Ditto.
+
2014-12-26 Antonio Giovanni Colombo <azc100@gmail.com>
* gawktexi.in (Glossary): Really sort the items.
diff --git a/doc/gawk.1 b/doc/gawk.1
index 3d5d1812..45a4c9f2 100644
--- a/doc/gawk.1
+++ b/doc/gawk.1
@@ -13,7 +13,7 @@
. if \w'\(rq' .ds rq "\(rq
. \}
.\}
-.TH GAWK 1 "Aug 03 2014" "Free Software Foundation" "Utility Commands"
+.TH GAWK 1 "Mar 24 2015" "Free Software Foundation" "Utility Commands"
.SH NAME
gawk \- pattern scanning and processing language
.SH SYNOPSIS
@@ -942,6 +942,15 @@ then
will contain
a string describing the error.
The value is subject to translation in non-English locales.
+If the string in
+.B ERRNO
+corresponds to a system error in the
+.IR errno (3)
+variable, then the numeric value can be found in
+.B PROCINFO["errno"].
+For non-system errors,
+.B PROCINFO["errno"]
+will be zero.
.TP
.B FIELDWIDTHS
A whitespace separated list of field widths. When set,
@@ -1103,6 +1112,13 @@ system call.
The default time format string for
.BR strftime() .
.TP
+\fBPROCINFO["errno"]\fP
+The value of
+.IR errno (3)
+when
+.BR ERRNO
+is set to the associated error message.
+.TP
\fBPROCINFO["euid"]\fP
The value of the
.IR geteuid (2)
@@ -1221,6 +1237,28 @@ where
is a redirection string or a filename. A value of zero or
less than zero means no timeout.
.TP
+\fBPROCINFO["input", "RETRY"]\fP
+If an I/O error that may be retried occurs when reading data from
+.IR input ,
+and this array entry exists, then
+.B getline
+will return \-2 instead of following the default behavior of returning \-1
+and configuring
+.IR input
+to return no further data.
+An I/O error that may be retried is one where
+.IR errno (3)
+has the value
+.IR EAGAIN ,
+.IR EWOULDBLOCK ,
+.IR EINTR ,
+or
+.IR ETIMEDOUT .
+This may be useful in conjunction with
+\fBPROCINFO["input", "READ_TIMEOUT"]\fP
+or situations where a file descriptor has been configured to behave in a
+non-blocking fashion.
+.TP
\fBPROCINFO["mpfr_version"]\fP
The version of the GNU MPFR library used for arbitrary precision
number support in
@@ -2289,6 +2327,13 @@ below.)
The
.B getline
command returns 1 on success, 0 on end of file, and \-1 on an error.
+If the
+.IR errno (3)
+value indicates that the I/O operation may be retried,
+and \fBPROCINFO["input", "RETRY"]\fP
+is set, then \-2 will be returned instead of \-1, and further calls to
+.B getline
+may be attempted.
Upon an error,
.B ERRNO
is set to a string describing the problem.
diff --git a/doc/gawk.info b/doc/gawk.info
index 90ae5848..d0312ec6 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -217,6 +217,7 @@ entitled "GNU Free Documentation License".
`getline'.
* Getline Summary:: Summary of `getline' Variants.
* Read Timeout:: Reading input with a timeout.
+* Retrying Input:: Retrying input after certain errors.
* Command-line directories:: What happens if you put a directory on
the command line.
* Input Summary:: Input summary.
@@ -558,6 +559,7 @@ entitled "GNU Free Documentation License".
* Array Functions:: Functions for working with arrays.
* Flattening Arrays:: How to flatten arrays.
* Creating Arrays:: How to create and populate arrays.
+* Redirection API:: How to access and manipulate redirections.
* Extension API Variables:: Variables provided by the API.
* Extension Versioning:: API Version information.
* Extension API Informational Variables:: Variables providing information about
@@ -4178,6 +4180,7 @@ have to be named on the `awk' command line (*note Getline::).
* Getline:: Reading files under explicit program control
using the `getline' function.
* Read Timeout:: Reading input with a timeout.
+* Retrying Input:: Retrying input after certain errors.
* Command-line directories:: What happens if you put a directory on the
command line.
* Input Summary:: Input summary.
@@ -5450,6 +5453,11 @@ record, such as a file that cannot be opened, then `getline' returns
-1. In this case, `gawk' sets the variable `ERRNO' to a string
describing the error that occurred.
+ If `ERRNO' indicates that the I/O operation may be retried, and
+`PROCINFO["INPUT", "RETRY"]' is set, then `getline' returns -2 instead
+of -1, and further calls to `getline' may be attemped. *Note Retrying
+Input::, for further information about this feature.
+
In the following examples, COMMAND stands for a string value that
represents a shell command.
@@ -5886,7 +5894,7 @@ VAR
Table 4.1: `getline' variants and what they set

-File: gawk.info, Node: Read Timeout, Next: Command-line directories, Prev: Getline, Up: Reading Files
+File: gawk.info, Node: Read Timeout, Next: Retrying Input, Prev: Getline, Up: Reading Files
4.10 Reading Input with a Timeout
=================================
@@ -5965,7 +5973,8 @@ a per-command or per-connection basis.
`gawk' considers a timeout event to be an error even though the
attempt to read from the underlying device may succeed in a later
attempt. This is a limitation, and it also means that you cannot use
-this to multiplex input from two or more sources.
+this to multiplex input from two or more sources. *Note Retrying
+Input::, for a way to enable later I/O attempts to succeed.
Assigning a timeout value prevents read operations from blocking
indefinitely. But bear in mind that there are other ways `gawk' can
@@ -5980,9 +5989,36 @@ writing.
(1) This assumes that standard input is the keyboard.

-File: gawk.info, Node: Command-line directories, Next: Input Summary, Prev: Read Timeout, Up: Reading Files
+File: gawk.info, Node: Retrying Input, Next: Command-line directories, Prev: Read Timeout, Up: Reading Files
+
+4.11 Retrying Reads After Certain Input Errors
+==============================================
+
+This minor node describes a feature that is specific to `gawk'.
+
+ When `gawk' encounters an error while reading input, by default
+`getline' returns -1, and subsequent attempts to read from that file
+result in an end-of-file indication. However, you may optionally
+instruct `gawk' to allow I/O to be retried when certain errors are
+encountered by setting a special element in the `PROCINFO' array (*note
+Auto-set::):
+
+ PROCINFO["INPUT_NAME", "RETRY"] = 1
+
+ When this element exists, `gawk' checks the value of the system
+`errno' variable when an I/O error occurs. If `errno' indicates a
+subsequent I/O attempt may succeed, `getline' instead returns -2 and
+further calls to `getline' may succeed. This applies to the `errno'
+values `EAGAIN', `EWOULDBLOCK', `EINTR', or `ETIMEDOUT'.
+
+ This feature is useful in conjunction with `PROCINFO["INPUT_NAME",
+"READ_TIMEOUT"]' or situations where a file descriptor has been
+configured to behave in a non-blocking fashion.
+
+
+File: gawk.info, Node: Command-line directories, Next: Input Summary, Prev: Retrying Input, Up: Reading Files
-4.11 Directories on the Command Line
+4.12 Directories on the Command Line
====================================
According to the POSIX standard, files named on the `awk' command line
@@ -6005,7 +6041,7 @@ usable data from an `awk' program.

File: gawk.info, Node: Input Summary, Next: Input Exercises, Prev: Command-line directories, Up: Reading Files
-4.12 Summary
+4.13 Summary
============
* Input is split into records based on the value of `RS'. The
@@ -6079,7 +6115,7 @@ File: gawk.info, Node: Input Summary, Next: Input Exercises, Prev: Command-li

File: gawk.info, Node: Input Exercises, Prev: Input Summary, Up: Reading Files
-4.13 Exercises
+4.14 Exercises
==============
1. Using the `FIELDWIDTHS' variable (*note Constant Size::), write a
@@ -10440,6 +10476,11 @@ Options::), they are not special:
`getline' returning -1. You are, of course, free to clear it
yourself before doing an I/O operation.
+ If the value of `ERRNO' corresponds to a system error in the C
+ `errno' variable, then `PROCINFO["errno"]' will be set to the value
+ of `errno'. For non-system errors, `PROCINFO["errno"]' will be
+ zero.
+
`FILENAME'
The name of the current input file. When no data files are listed
on the command line, `awk' reads from the standard input and
@@ -10488,6 +10529,10 @@ Options::), they are not special:
`PROCINFO["egid"]'
The value of the `getegid()' system call.
+ `PROCINFO["errno"]'
+ The value of the C `errno' variable when `ERRNO' is set to
+ the associated error message.
+
`PROCINFO["euid"]'
The value of the `geteuid()' system call.
@@ -10598,6 +10643,10 @@ Options::), they are not special:
open input file, pipe, or coprocess. *Note Read Timeout::,
for more information.
+ * It may be used to indicate that input may be retried when it
+ fails due to certain errors. *Note Retrying Input::, for
+ more information.
+
* It may be used to cause coprocesses to communicate over
pseudo-ttys instead of through two-way pipes; this is
discussed further in *note Two-way I/O::.
@@ -22973,6 +23022,7 @@ describes the API in detail.
* Symbol Table Access:: Functions for accessing global
variables.
* Array Manipulation:: Functions for working with arrays.
+* Redirection API:: How to access and manipulate redirections.
* Extension API Variables:: Variables provided by the API.
* Extension API Boilerplate:: Boilerplate code for using the API.
@@ -23033,6 +23083,9 @@ operations:
- Flattening an array for easy C-style looping over all its
indices and elements
+ * Accessing and manipulating redirections.
+
+
Some points about using the API:
* The following types, macros, and/or functions are referenced in
@@ -24244,7 +24297,7 @@ using `release_value()'.
`double' to store.

-File: gawk.info, Node: Array Manipulation, Next: Extension API Variables, Prev: Symbol Table Access, Up: Extension API Description
+File: gawk.info, Node: Array Manipulation, Next: Redirection API, Prev: Symbol Table Access, Up: Extension API Description
16.4.11 Array Manipulation
--------------------------
@@ -24729,9 +24782,78 @@ array:
environment variable.)

-File: gawk.info, Node: Extension API Variables, Next: Extension API Boilerplate, Prev: Array Manipulation, Up: Extension API Description
+File: gawk.info, Node: Redirection API, Next: Extension API Variables, Prev: Array Manipulation, Up: Extension API Description
+
+16.4.12 Accessing and Manipulating Redirections
+-----------------------------------------------
+
+The following function allows extensions to access and manipulate
+redirections.
-16.4.12 API Variables
+`awk_bool_t get_file(const char *name,'
+` size_t name_len,'
+` const char *filetype,'
+` int fd,'
+` const awk_input_buf_t **ibufp,'
+` const awk_output_buf_t **obufp);'
+ Look up a file in `gawk''s internal redirection table. If `name'
+ is `NULL' or `name_len' is zero, return data for the currently
+ open input file corresponding to `FILENAME'. (This does not
+ access the `filetype' argument, so that may be undefined). If the
+ file is not already open, attempt to open it. The `filetype'
+ argument must be zero-terminated and should be one of:
+
+ `">"'
+ A file opened for output.
+
+ `">>"'
+ A file opened for append.
+
+ `"<"'
+ A file opened for input.
+
+ `"|>"'
+ A pipe opened for output.
+
+ `"|<"'
+ A pipe opened for input.
+
+ `"|&"'
+ A two-way coprocess.
+
+ On error, return a `false' value. Otherwise, return `true', and
+ return additional information about the redirection in the `ibufp'
+ and `obufp' pointers. For input redirections, the `*ibufp' value
+ should be non-`NULL', and `*obufp' should be `NULL'. For output
+ redirections, the `*obufp' value should be non-`NULL', and `*ibufp'
+ should be `NULL'. For two-way coprocesses, both values should be
+ non-`NULL'.
+
+ In the usual case, the extension is interested in `(*ibufp)->fd'
+ and/or `fileno((*obufp)->fp)'. If the file is not already open,
+ and the `fd' argument is non-negative, `gawk' will use that file
+ descriptor instead of opening the file in the usual way. If `fd'
+ is non-negative, but the file exists already, `gawk' ignores `fd'
+ and returns the existing file. It is the caller's responsibility
+ to notice that neither the `fd' in the returned `awk_input_buf_t'
+ nor the `fd' in the returned `awk_output_buf_t' matches the
+ requested value.
+
+ Note that supplying a file descriptor is currently _not_ supported
+ for pipes. However, supplying a file descriptor should work for
+ input, output, append, and two-way (coprocess) sockets. If
+ `filetype' is two-way, `gawk' assumes that it is a socket! Note
+ that in the two-way case, the input and output file descriptors
+ may differ. To check for success, you must check whether either
+ matches.
+
+ It is anticipated that this API function will be used to implement
+I/O multiplexing and a socket library.
+
+
+File: gawk.info, Node: Extension API Variables, Next: Extension API Boilerplate, Prev: Redirection API, Up: Extension API Description
+
+16.4.13 API Variables
---------------------
The API provides two sets of variables. The first provides information
@@ -24748,7 +24870,7 @@ information about how `gawk' was invoked.

File: gawk.info, Node: Extension Versioning, Next: Extension API Informational Variables, Up: Extension API Variables
-16.4.12.1 API Version Constants and Variables
+16.4.13.1 API Version Constants and Variables
.............................................
The API provides both a "major" and a "minor" version number. The API
@@ -24797,7 +24919,7 @@ Boilerplate::).

File: gawk.info, Node: Extension API Informational Variables, Prev: Extension Versioning, Up: Extension API Variables
-16.4.12.2 Informational Variables
+16.4.13.2 Informational Variables
.................................
The API provides access to several variables that describe whether the
@@ -24832,7 +24954,7 @@ not change during execution.

File: gawk.info, Node: Extension API Boilerplate, Prev: Extension API Variables, Up: Extension API Description
-16.4.13 Boilerplate Code
+16.4.14 Boilerplate Code
------------------------
As mentioned earlier (*note Extension Mechanism Outline::), the function
@@ -25838,11 +25960,16 @@ performs "in-place" editing of each input file. It uses the bundled
# Please set INPLACE_SUFFIX to make a backup copy. For example, you may
# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
+ # N.B. We call inplace_end() in the BEGINFILE and END rules so that any
+ # actions in an ENDFILE rule will be redirected as expected.
+
BEGINFILE {
- inplace_begin(FILENAME, INPLACE_SUFFIX)
+ if (_inplace_filename != "")
+ inplace_end(_inplace_filename, INPLACE_SUFFIX)
+ inplace_begin(_inplace_filename = FILENAME, INPLACE_SUFFIX)
}
- ENDFILE {
+ END {
inplace_end(FILENAME, INPLACE_SUFFIX)
}
@@ -25854,6 +25981,10 @@ the extension restores standard output to its original destination. If
a backup file name created by appending that suffix. Finally, the
temporary file is renamed to the original file name.
+ The `_inplace_filename' variable serves to keep track of the current
+filename so as to not invoke `inplace_end()' before processing the
+first file.
+
If any error occurs, the extension issues a fatal error to terminate
processing immediately without damaging the original file.
@@ -26280,12 +26411,26 @@ File: gawk.info, Node: Extension Exercises, Prev: Extension summary, Up: Dyna
`chmod()', and `umask()' to the file operations extension
presented in *note Internal File Ops::.
- 2. (Hard.) How would you provide namespaces in `gawk', so that the
+ 2. Write an input parser that prints a prompt if the input is a from
+ a "terminal" device. You can use the `isatty()' function to tell
+ if the input file is a terminal. (Hint: this function is usually
+ expensive to call; try to call it just once.) The content of the
+ prompt should come from a variable settable by `awk'-level code.
+ You can write the prompt to stanard error. However, for best
+ results, open a new file descriptor (or file pointer) on
+ `/dev/tty' and print the prompt there, in case standard error has
+ been redirected.
+
+ Why is standard error a better choice than standard output for
+ writing the prompt? Which reading mechanism should you replace,
+ the one to get a record, or the one to read raw bytes?
+
+ 3. (Hard.) How would you provide namespaces in `gawk', so that the
names of functions in different extensions don't conflict with
each other? If you come up with a really good scheme, contact the
`gawk' maintainer to tell him about it.
- 3. Write a wrapper script that provides an interface similar to `sed
+ 4. Write a wrapper script that provides an interface similar to `sed
-i' for the "inplace" extension presented in *note Extension
Sample Inplace::.
@@ -32531,9 +32676,9 @@ Index
(line 143)
* dark corner, exit statement: Exit Statement. (line 30)
* dark corner, field separators: Full Line Fields. (line 22)
-* dark corner, FILENAME variable <1>: Auto-set. (line 104)
+* dark corner, FILENAME variable <1>: Auto-set. (line 109)
* dark corner, FILENAME variable: Getline Notes. (line 19)
-* dark corner, FNR/NR variables: Auto-set. (line 328)
+* dark corner, FNR/NR variables: Auto-set. (line 341)
* dark corner, format-control characters: Control Letters. (line 18)
* dark corner, FS as null string: Single Character Fields.
(line 20)
@@ -32727,7 +32872,7 @@ Index
* differences in awk and gawk, FIELDWIDTHS variable: User-modified.
(line 37)
* differences in awk and gawk, FPAT variable: User-modified. (line 43)
-* differences in awk and gawk, FUNCTAB variable: Auto-set. (line 130)
+* differences in awk and gawk, FUNCTAB variable: Auto-set. (line 135)
* differences in awk and gawk, function arguments (gawk): Calling Built-in.
(line 16)
* differences in awk and gawk, getline command: Getline. (line 19)
@@ -32750,7 +32895,7 @@ Index
(line 263)
* differences in awk and gawk, print/printf statements: Format Modifiers.
(line 13)
-* differences in awk and gawk, PROCINFO array: Auto-set. (line 144)
+* differences in awk and gawk, PROCINFO array: Auto-set. (line 149)
* differences in awk and gawk, read timeouts: Read Timeout. (line 6)
* differences in awk and gawk, record separators: awk split records.
(line 125)
@@ -32758,9 +32903,11 @@ Index
(line 43)
* differences in awk and gawk, regular expressions: Case-sensitivity.
(line 26)
+* differences in awk and gawk, retrying input: Retrying Input.
+ (line 6)
* differences in awk and gawk, RS/RT variables: gawk split records.
(line 58)
-* differences in awk and gawk, RT variable: Auto-set. (line 279)
+* differences in awk and gawk, RT variable: Auto-set. (line 292)
* differences in awk and gawk, single-character fields: Single Character Fields.
(line 6)
* differences in awk and gawk, split() function: String Functions.
@@ -32768,7 +32915,7 @@ Index
* differences in awk and gawk, strings: Scalar Constants. (line 20)
* differences in awk and gawk, strings, storing: gawk split records.
(line 77)
-* differences in awk and gawk, SYMTAB variable: Auto-set. (line 283)
+* differences in awk and gawk, SYMTAB variable: Auto-set. (line 296)
* differences in awk and gawk, TEXTDOMAIN variable: User-modified.
(line 151)
* differences in awk and gawk, trunc-mod operation: Arithmetic Ops.
@@ -32809,8 +32956,8 @@ Index
* dynamically loaded extensions: Dynamic Extensions. (line 6)
* e debugger command (alias for enable): Breakpoint Control. (line 73)
* EBCDIC: Ordinal Functions. (line 45)
-* effective group ID of gawk user: Auto-set. (line 149)
-* effective user ID of gawk user: Auto-set. (line 153)
+* effective group ID of gawk user: Auto-set. (line 154)
+* effective user ID of gawk user: Auto-set. (line 162)
* egrep utility <1>: Egrep Program. (line 6)
* egrep utility: Bracket Expressions. (line 26)
* egrep.awk program: Egrep Program. (line 54)
@@ -32925,7 +33072,7 @@ Index
(line 6)
* extension API version: Extension Versioning.
(line 6)
-* extension API, version number: Auto-set. (line 246)
+* extension API, version number: Auto-set. (line 255)
* extension example: Extension Example. (line 6)
* extension registration: Registration Functions.
(line 6)
@@ -33006,7 +33153,7 @@ Index
* file names, distinguishing: Auto-set. (line 56)
* file names, in compatibility mode: Special Caveats. (line 9)
* file names, standard streams in gawk: Special FD. (line 48)
-* FILENAME variable <1>: Auto-set. (line 104)
+* FILENAME variable <1>: Auto-set. (line 109)
* FILENAME variable: Reading Files. (line 6)
* FILENAME variable, getline, setting with: Getline Notes. (line 19)
* filenames, assignments as: Ignoring Assigns. (line 6)
@@ -33074,9 +33221,9 @@ Index
* flush buffered output: I/O Functions. (line 28)
* fnmatch() extension function: Extension Sample Fnmatch.
(line 12)
-* FNR variable <1>: Auto-set. (line 114)
+* FNR variable <1>: Auto-set. (line 119)
* FNR variable: Records. (line 6)
-* FNR variable, changing: Auto-set. (line 328)
+* FNR variable, changing: Auto-set. (line 341)
* for statement: For Statement. (line 6)
* for statement, looping over arrays: Scanning an Array. (line 20)
* fork() extension function: Extension Sample Fork.
@@ -33126,7 +33273,7 @@ Index
* FSF (Free Software Foundation): Manual History. (line 6)
* fts() extension function: Extension Sample File Functions.
(line 61)
-* FUNCTAB array: Auto-set. (line 130)
+* FUNCTAB array: Auto-set. (line 135)
* function calls: Function Calls. (line 6)
* function calls, indirect: Indirect Calls. (line 6)
* function calls, indirect, @-notation for: Indirect Calls. (line 47)
@@ -33176,7 +33323,7 @@ Index
* G-d: Acknowledgments. (line 94)
* Garfinkle, Scott: Contributors. (line 34)
* gawk program, dynamic profiling: Profiling. (line 178)
-* gawk version: Auto-set. (line 221)
+* gawk version: Auto-set. (line 230)
* gawk, ARGIND variable in: Other Arguments. (line 15)
* gawk, awk and <1>: This Manual. (line 14)
* gawk, awk and: Preface. (line 21)
@@ -33211,7 +33358,7 @@ Index
* gawk, FPAT variable in <1>: User-modified. (line 43)
* gawk, FPAT variable in: Splitting By Content.
(line 25)
-* gawk, FUNCTAB array in: Auto-set. (line 130)
+* gawk, FUNCTAB array in: Auto-set. (line 135)
* gawk, function arguments and: Calling Built-in. (line 16)
* gawk, hexadecimal numbers and: Nondecimal-numbers. (line 42)
* gawk, IGNORECASE variable in <1>: Array Sorting Functions.
@@ -33243,7 +33390,7 @@ Index
* gawk, predefined variables and: Built-in Variables. (line 14)
* gawk, PROCINFO array in <1>: Two-way I/O. (line 99)
* gawk, PROCINFO array in <2>: Time Functions. (line 47)
-* gawk, PROCINFO array in: Auto-set. (line 144)
+* gawk, PROCINFO array in: Auto-set. (line 149)
* gawk, regexp constants and: Using Constant Regexps.
(line 28)
* gawk, regular expressions, case sensitivity: Case-sensitivity.
@@ -33251,14 +33398,14 @@ Index
* gawk, regular expressions, operators: GNU Regexp Operators.
(line 6)
* gawk, regular expressions, precedence: Regexp Operators. (line 161)
-* gawk, RT variable in <1>: Auto-set. (line 279)
+* gawk, RT variable in <1>: Auto-set. (line 292)
* gawk, RT variable in <2>: Multiple Line. (line 129)
* gawk, RT variable in: awk split records. (line 125)
* gawk, See Also awk: Preface. (line 34)
* gawk, source code, obtaining: Getting. (line 6)
* gawk, splitting fields and: Constant Size. (line 87)
* gawk, string-translation functions: I18N Functions. (line 6)
-* gawk, SYMTAB array in: Auto-set. (line 283)
+* gawk, SYMTAB array in: Auto-set. (line 296)
* gawk, TEXTDOMAIN variable in: User-modified. (line 151)
* gawk, timestamps: Time Functions. (line 6)
* gawk, uses for: Preface. (line 34)
@@ -33350,7 +33497,7 @@ Index
* Grigera, Juan: Contributors. (line 57)
* group database, reading: Group Functions. (line 6)
* group file: Group Functions. (line 6)
-* group ID of gawk user: Auto-set. (line 194)
+* group ID of gawk user: Auto-set. (line 203)
* groups, information about: Group Functions. (line 6)
* gsub <1>: String Functions. (line 140)
* gsub: Using Constant Regexps.
@@ -33645,7 +33792,7 @@ Index
* mawk utility <3>: Concatenation. (line 36)
* mawk utility <4>: Getline/Pipe. (line 62)
* mawk utility: Escape Sequences. (line 120)
-* maximum precision supported by MPFR library: Auto-set. (line 235)
+* maximum precision supported by MPFR library: Auto-set. (line 244)
* McIlroy, Doug: Glossary. (line 258)
* McPhee, Patrick: Contributors. (line 100)
* message object files: Explaining gettext. (line 42)
@@ -33658,7 +33805,7 @@ Index
* messages from extensions: Printing Messages. (line 6)
* metacharacters in regular expressions: Regexp Operators. (line 6)
* metacharacters, escape sequences for: Escape Sequences. (line 139)
-* minimum precision supported by MPFR library: Auto-set. (line 238)
+* minimum precision required by MPFR library: Auto-set. (line 247)
* mktime: Time Functions. (line 25)
* modifiers, in format specifiers: Format Modifiers. (line 6)
* monetary information, localization: Explaining gettext. (line 104)
@@ -33707,7 +33854,7 @@ Index
(line 47)
* nexti debugger command: Debugger Execution Control.
(line 49)
-* NF variable <1>: Auto-set. (line 119)
+* NF variable <1>: Auto-set. (line 124)
* NF variable: Fields. (line 33)
* NF variable, decrementing: Changing Fields. (line 107)
* ni debugger command (alias for nexti): Debugger Execution Control.
@@ -33716,9 +33863,9 @@ Index
* non-existent array elements: Reference to Elements.
(line 23)
* not Boolean-logic operator: Boolean Ops. (line 6)
-* NR variable <1>: Auto-set. (line 139)
+* NR variable <1>: Auto-set. (line 144)
* NR variable: Records. (line 6)
-* NR variable, changing: Auto-set. (line 328)
+* NR variable, changing: Auto-set. (line 341)
* null strings <1>: Basic Data Typing. (line 26)
* null strings <2>: Truth Values. (line 6)
* null strings <3>: Regexp Field Splitting.
@@ -33832,7 +33979,7 @@ Index
* p debugger command (alias for print): Viewing And Changing Data.
(line 36)
* Papadopoulos, Panos: Contributors. (line 128)
-* parent process ID of gawk process: Auto-set. (line 203)
+* parent process ID of gawk process: Auto-set. (line 212)
* parentheses (), in a profile: Profiling. (line 146)
* parentheses (), regexp operator: Regexp Operators. (line 81)
* password file: Passwd Functions. (line 16)
@@ -33998,24 +34145,24 @@ Index
* printing, unduplicated lines of text: Uniq Program. (line 6)
* printing, user information: Id Program. (line 6)
* private variables: Library Names. (line 11)
-* process group idIDof gawk process: Auto-set. (line 197)
-* process ID of gawk process: Auto-set. (line 200)
+* process group ID of gawk process: Auto-set. (line 206)
+* process ID of gawk process: Auto-set. (line 209)
* processes, two-way communications with: Two-way I/O. (line 6)
* processing data: Basic High Level. (line 6)
* PROCINFO array <1>: Passwd Functions. (line 6)
* PROCINFO array <2>: Time Functions. (line 47)
-* PROCINFO array: Auto-set. (line 144)
+* PROCINFO array: Auto-set. (line 149)
* PROCINFO array, and communications via ptys: Two-way I/O. (line 99)
* PROCINFO array, and group membership: Group Functions. (line 6)
* PROCINFO array, and user and group ID numbers: Id Program. (line 15)
* PROCINFO array, testing the field splitting: Passwd Functions.
(line 154)
-* PROCINFO array, uses: Auto-set. (line 256)
+* PROCINFO array, uses: Auto-set. (line 265)
* PROCINFO, values of sorted_in: Controlling Scanning.
(line 26)
* profiling awk programs: Profiling. (line 6)
* profiling awk programs, dynamically: Profiling. (line 178)
-* program identifiers: Auto-set. (line 162)
+* program identifiers: Auto-set. (line 171)
* program, definition of: Getting Started. (line 21)
* programming conventions, --non-decimal-data option: Nondecimal Data.
(line 35)
@@ -34150,6 +34297,7 @@ Index
* relational operators, See comparison operators: Typing and Comparison.
(line 9)
* replace in string: String Functions. (line 409)
+* retrying input: Retrying Input. (line 6)
* return debugger command: Debugger Execution Control.
(line 54)
* return statement, user-defined functions: Return Statement. (line 6)
@@ -34173,7 +34321,7 @@ Index
* right shift: Bitwise Functions. (line 53)
* right shift, bitwise: Bitwise Functions. (line 32)
* Ritchie, Dennis: Basic Data Typing. (line 54)
-* RLENGTH variable: Auto-set. (line 266)
+* RLENGTH variable: Auto-set. (line 279)
* RLENGTH variable, match() function and: String Functions. (line 228)
* Robbins, Arnold <1>: Future Extensions. (line 6)
* Robbins, Arnold <2>: Bugs. (line 71)
@@ -34199,9 +34347,9 @@ Index
* RS variable: awk split records. (line 12)
* RS variable, multiline records and: Multiple Line. (line 17)
* rshift: Bitwise Functions. (line 53)
-* RSTART variable: Auto-set. (line 272)
+* RSTART variable: Auto-set. (line 285)
* RSTART variable, match() function and: String Functions. (line 228)
-* RT variable <1>: Auto-set. (line 279)
+* RT variable <1>: Auto-set. (line 292)
* RT variable <2>: Multiple Line. (line 129)
* RT variable: awk split records. (line 125)
* Rubin, Paul <1>: Contributors. (line 15)
@@ -34221,7 +34369,7 @@ Index
* scanning arrays: Scanning an Array. (line 6)
* scanning multidimensional arrays: Multiscanning. (line 11)
* Schorr, Andrew <1>: Contributors. (line 133)
-* Schorr, Andrew <2>: Auto-set. (line 311)
+* Schorr, Andrew <2>: Auto-set. (line 324)
* Schorr, Andrew: Acknowledgments. (line 60)
* Schreiber, Bert: Acknowledgments. (line 38)
* Schreiber, Rita: Acknowledgments. (line 38)
@@ -34304,7 +34452,7 @@ Index
(line 106)
* sidebar, Changing FS Does Not Affect the Fields: Full Line Fields.
(line 14)
-* sidebar, Changing NR and FNR: Auto-set. (line 326)
+* sidebar, Changing NR and FNR: Auto-set. (line 339)
* sidebar, Controlling Output Buffering with system(): I/O Functions.
(line 139)
* sidebar, Escape Sequences for Metacharacters: Escape Sequences.
@@ -34466,9 +34614,9 @@ Index
* substr: String Functions. (line 482)
* substring: String Functions. (line 482)
* Sumner, Andrew: Other Versions. (line 68)
-* supplementary groups of gawk process: Auto-set. (line 251)
+* supplementary groups of gawk process: Auto-set. (line 260)
* switch statement: Switch Statement. (line 6)
-* SYMTAB array: Auto-set. (line 283)
+* SYMTAB array: Auto-set. (line 296)
* syntactic ambiguity: /= operator vs. /=.../ regexp constant: Assignment Ops.
(line 148)
* system: I/O Functions. (line 107)
@@ -34645,10 +34793,10 @@ Index
* variables, uninitialized, as array subscripts: Uninitialized Subscripts.
(line 6)
* variables, user-defined: Variables. (line 6)
-* version of gawk: Auto-set. (line 221)
-* version of gawk extension API: Auto-set. (line 246)
-* version of GNU MP library: Auto-set. (line 232)
-* version of GNU MPFR library: Auto-set. (line 228)
+* version of gawk: Auto-set. (line 230)
+* version of gawk extension API: Auto-set. (line 255)
+* version of GNU MP library: Auto-set. (line 241)
+* version of GNU MPFR library: Auto-set. (line 237)
* vertical bar (|): Regexp Operators. (line 70)
* vertical bar (|), | operator (I/O) <1>: Precedence. (line 65)
* vertical bar (|), | operator (I/O): Getline/Pipe. (line 9)
@@ -34738,561 +34886,563 @@ Index

Tag Table:
Node: Top1204
-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-155064
-Node: This Manual55210
-Ref: This Manual-Footnote-161710
-Node: Conventions61810
-Node: Manual History64147
-Ref: Manual History-Footnote-167140
-Ref: Manual History-Footnote-267181
-Node: How To Contribute67255
-Node: Acknowledgments68384
-Node: Getting Started73250
-Node: Running gawk75689
-Node: One-shot76879
-Node: Read Terminal78143
-Node: Long80174
-Node: Executable Scripts81687
-Ref: Executable Scripts-Footnote-184476
-Node: Comments84579
-Node: Quoting87061
-Node: DOS Quoting92579
-Node: Sample Data Files93254
-Node: Very Simple95849
-Node: Two Rules100748
-Node: More Complex102634
-Node: Statements/Lines105496
-Ref: Statements/Lines-Footnote-1109951
-Node: Other Features110216
-Node: When111152
-Ref: When-Footnote-1112906
-Node: Intro Summary112971
-Node: Invoking Gawk113855
-Node: Command Line115369
-Node: Options116167
-Ref: Options-Footnote-1131962
-Ref: Options-Footnote-2132191
-Node: Other Arguments132216
-Node: Naming Standard Input135164
-Node: Environment Variables136257
-Node: AWKPATH Variable136815
-Ref: AWKPATH Variable-Footnote-1140222
-Ref: AWKPATH Variable-Footnote-2140267
-Node: AWKLIBPATH Variable140527
-Node: Other Environment Variables141783
-Node: Exit Status145414
-Node: Include Files146090
-Node: Loading Shared Libraries149679
-Node: Obsolete151106
-Node: Undocumented151798
-Node: Invoking Summary152065
-Node: Regexp153728
-Node: Regexp Usage155182
-Node: Escape Sequences157219
-Node: Regexp Operators163448
-Ref: Regexp Operators-Footnote-1170858
-Ref: Regexp Operators-Footnote-2171005
-Node: Bracket Expressions171103
-Ref: table-char-classes173118
-Node: Leftmost Longest176060
-Node: Computed Regexps177362
-Node: GNU Regexp Operators180791
-Node: Case-sensitivity184463
-Ref: Case-sensitivity-Footnote-1187348
-Ref: Case-sensitivity-Footnote-2187583
-Node: Regexp Summary187691
-Node: Reading Files189158
-Node: Records191251
-Node: awk split records191984
-Node: gawk split records196913
-Ref: gawk split records-Footnote-1201452
-Node: Fields201489
-Ref: Fields-Footnote-1204267
-Node: Nonconstant Fields204353
-Ref: Nonconstant Fields-Footnote-1206591
-Node: Changing Fields206794
-Node: Field Separators212725
-Node: Default Field Splitting215429
-Node: Regexp Field Splitting216546
-Node: Single Character Fields219896
-Node: Command Line Field Separator220955
-Node: Full Line Fields224172
-Ref: Full Line Fields-Footnote-1225693
-Ref: Full Line Fields-Footnote-2225739
-Node: Field Splitting Summary225840
-Node: Constant Size227914
-Node: Splitting By Content232493
-Ref: Splitting By Content-Footnote-1236458
-Node: Multiple Line236621
-Ref: Multiple Line-Footnote-1242502
-Node: Getline242681
-Node: Plain Getline244888
-Node: Getline/Variable247528
-Node: Getline/File248677
-Node: Getline/Variable/File250062
-Ref: Getline/Variable/File-Footnote-1251665
-Node: Getline/Pipe251752
-Node: Getline/Variable/Pipe254430
-Node: Getline/Coprocess255561
-Node: Getline/Variable/Coprocess256825
-Node: Getline Notes257564
-Node: Getline Summary260358
-Ref: table-getline-variants260770
-Node: Read Timeout261599
-Ref: Read Timeout-Footnote-1265436
-Node: Command-line directories265494
-Node: Input Summary266399
-Node: Input Exercises269784
-Node: Printing270512
-Node: Print272347
-Node: Print Examples273804
-Node: Output Separators276583
-Node: OFMT278601
-Node: Printf279956
-Node: Basic Printf280741
-Node: Control Letters282313
-Node: Format Modifiers286298
-Node: Printf Examples292304
-Node: Redirection294790
-Node: Special FD301628
-Ref: Special FD-Footnote-1304794
-Node: Special Files304868
-Node: Other Inherited Files305485
-Node: Special Network306485
-Node: Special Caveats307347
-Node: Close Files And Pipes308296
-Ref: Close Files And Pipes-Footnote-1315481
-Ref: Close Files And Pipes-Footnote-2315629
-Node: Nonfatal315779
-Node: Output Summary318104
-Node: Output Exercises319325
-Node: Expressions320005
-Node: Values321194
-Node: Constants321871
-Node: Scalar Constants322562
-Ref: Scalar Constants-Footnote-1323424
-Node: Nondecimal-numbers323674
-Node: Regexp Constants326684
-Node: Using Constant Regexps327210
-Node: Variables330373
-Node: Using Variables331030
-Node: Assignment Options332941
-Node: Conversion334816
-Node: Strings And Numbers335340
-Ref: Strings And Numbers-Footnote-1338405
-Node: Locale influences conversions338514
-Ref: table-locale-affects341260
-Node: All Operators341852
-Node: Arithmetic Ops342481
-Node: Concatenation344986
-Ref: Concatenation-Footnote-1347805
-Node: Assignment Ops347912
-Ref: table-assign-ops352891
-Node: Increment Ops354201
-Node: Truth Values and Conditions357632
-Node: Truth Values358715
-Node: Typing and Comparison359764
-Node: Variable Typing360580
-Node: Comparison Operators364247
-Ref: table-relational-ops364657
-Node: POSIX String Comparison368152
-Ref: POSIX String Comparison-Footnote-1369224
-Node: Boolean Ops369363
-Ref: Boolean Ops-Footnote-1373841
-Node: Conditional Exp373932
-Node: Function Calls375670
-Node: Precedence379550
-Node: Locales383210
-Node: Expressions Summary384842
-Node: Patterns and Actions387413
-Node: Pattern Overview388533
-Node: Regexp Patterns390212
-Node: Expression Patterns390755
-Node: Ranges394535
-Node: BEGIN/END397642
-Node: Using BEGIN/END398403
-Ref: Using BEGIN/END-Footnote-1401139
-Node: I/O And BEGIN/END401245
-Node: BEGINFILE/ENDFILE403560
-Node: Empty406457
-Node: Using Shell Variables406774
-Node: Action Overview409047
-Node: Statements411373
-Node: If Statement413221
-Node: While Statement414716
-Node: Do Statement416744
-Node: For Statement417892
-Node: Switch Statement421050
-Node: Break Statement423432
-Node: Continue Statement425525
-Node: Next Statement427352
-Node: Nextfile Statement429733
-Node: Exit Statement432361
-Node: Built-in Variables434772
-Node: User-modified435905
-Ref: User-modified-Footnote-1443539
-Node: Auto-set443601
-Ref: Auto-set-Footnote-1457310
-Ref: Auto-set-Footnote-2457515
-Node: ARGC and ARGV457571
-Node: Pattern Action Summary461789
-Node: Arrays464222
-Node: Array Basics465551
-Node: Array Intro466395
-Ref: figure-array-elements468332
-Ref: Array Intro-Footnote-1470955
-Node: Reference to Elements471083
-Node: Assigning Elements473545
-Node: Array Example474036
-Node: Scanning an Array475795
-Node: Controlling Scanning478818
-Ref: Controlling Scanning-Footnote-1484212
-Node: Numeric Array Subscripts484528
-Node: Uninitialized Subscripts486713
-Node: Delete488330
-Ref: Delete-Footnote-1491079
-Node: Multidimensional491136
-Node: Multiscanning494233
-Node: Arrays of Arrays495822
-Node: Arrays Summary500576
-Node: Functions502667
-Node: Built-in503706
-Node: Calling Built-in504784
-Node: Numeric Functions506779
-Ref: Numeric Functions-Footnote-1511597
-Ref: Numeric Functions-Footnote-2511954
-Ref: Numeric Functions-Footnote-3512002
-Node: String Functions512274
-Ref: String Functions-Footnote-1535775
-Ref: String Functions-Footnote-2535904
-Ref: String Functions-Footnote-3536152
-Node: Gory Details536239
-Ref: table-sub-escapes538020
-Ref: table-sub-proposed539535
-Ref: table-posix-sub540897
-Ref: table-gensub-escapes542434
-Ref: Gory Details-Footnote-1543267
-Node: I/O Functions543418
-Ref: I/O Functions-Footnote-1550654
-Node: Time Functions550801
-Ref: Time Functions-Footnote-1561310
-Ref: Time Functions-Footnote-2561378
-Ref: Time Functions-Footnote-3561536
-Ref: Time Functions-Footnote-4561647
-Ref: Time Functions-Footnote-5561759
-Ref: Time Functions-Footnote-6561986
-Node: Bitwise Functions562252
-Ref: table-bitwise-ops562814
-Ref: Bitwise Functions-Footnote-1567142
-Node: Type Functions567314
-Node: I18N Functions568466
-Node: User-defined570113
-Node: Definition Syntax570918
-Ref: Definition Syntax-Footnote-1576577
-Node: Function Example576648
-Ref: Function Example-Footnote-1579569
-Node: Function Caveats579591
-Node: Calling A Function580109
-Node: Variable Scope581067
-Node: Pass By Value/Reference584060
-Node: Return Statement587557
-Node: Dynamic Typing590536
-Node: Indirect Calls591465
-Ref: Indirect Calls-Footnote-1601330
-Node: Functions Summary601458
-Node: Library Functions604160
-Ref: Library Functions-Footnote-1607768
-Ref: Library Functions-Footnote-2607911
-Node: Library Names608082
-Ref: Library Names-Footnote-1611540
-Ref: Library Names-Footnote-2611763
-Node: General Functions611849
-Node: Strtonum Function612952
-Node: Assert Function615974
-Node: Round Function619298
-Node: Cliff Random Function620839
-Node: Ordinal Functions621855
-Ref: Ordinal Functions-Footnote-1624918
-Ref: Ordinal Functions-Footnote-2625170
-Node: Join Function625381
-Ref: Join Function-Footnote-1627151
-Node: Getlocaltime Function627351
-Node: Readfile Function631095
-Node: Shell Quoting633067
-Node: Data File Management634468
-Node: Filetrans Function635100
-Node: Rewind Function639196
-Node: File Checking640582
-Ref: File Checking-Footnote-1641915
-Node: Empty Files642116
-Node: Ignoring Assigns644095
-Node: Getopt Function645645
-Ref: Getopt Function-Footnote-1657109
-Node: Passwd Functions657309
-Ref: Passwd Functions-Footnote-1666149
-Node: Group Functions666237
-Ref: Group Functions-Footnote-1674134
-Node: Walking Arrays674339
-Node: Library Functions Summary677345
-Node: Library Exercises678747
-Node: Sample Programs680027
-Node: Running Examples680797
-Node: Clones681525
-Node: Cut Program682749
-Node: Egrep Program692469
-Ref: Egrep Program-Footnote-1699972
-Node: Id Program700082
-Node: Split Program703758
-Ref: Split Program-Footnote-1707212
-Node: Tee Program707340
-Node: Uniq Program710129
-Node: Wc Program717548
-Ref: Wc Program-Footnote-1721798
-Node: Miscellaneous Programs721892
-Node: Dupword Program723105
-Node: Alarm Program725136
-Node: Translate Program729941
-Ref: Translate Program-Footnote-1734504
-Node: Labels Program734774
-Ref: Labels Program-Footnote-1738125
-Node: Word Sorting738209
-Node: History Sorting742279
-Node: Extract Program744114
-Node: Simple Sed751638
-Node: Igawk Program754708
-Ref: Igawk Program-Footnote-1769034
-Ref: Igawk Program-Footnote-2769235
-Ref: Igawk Program-Footnote-3769357
-Node: Anagram Program769472
-Node: Signature Program772533
-Node: Programs Summary773780
-Node: Programs Exercises775001
-Ref: Programs Exercises-Footnote-1779132
-Node: Advanced Features779223
-Node: Nondecimal Data781205
-Node: Array Sorting782795
-Node: Controlling Array Traversal783495
-Ref: Controlling Array Traversal-Footnote-1791861
-Node: Array Sorting Functions791979
-Ref: Array Sorting Functions-Footnote-1795865
-Node: Two-way I/O796061
-Ref: Two-way I/O-Footnote-1801006
-Ref: Two-way I/O-Footnote-2801192
-Node: TCP/IP Networking801274
-Node: Profiling804146
-Node: Advanced Features Summary812417
-Node: Internationalization814350
-Node: I18N and L10N815830
-Node: Explaining gettext816516
-Ref: Explaining gettext-Footnote-1821541
-Ref: Explaining gettext-Footnote-2821725
-Node: Programmer i18n821890
-Ref: Programmer i18n-Footnote-1826766
-Node: Translator i18n826815
-Node: String Extraction827609
-Ref: String Extraction-Footnote-1828740
-Node: Printf Ordering828826
-Ref: Printf Ordering-Footnote-1831612
-Node: I18N Portability831676
-Ref: I18N Portability-Footnote-1834132
-Node: I18N Example834195
-Ref: I18N Example-Footnote-1836998
-Node: Gawk I18N837070
-Node: I18N Summary837714
-Node: Debugger839054
-Node: Debugging840076
-Node: Debugging Concepts840517
-Node: Debugging Terms842327
-Node: Awk Debugging844899
-Node: Sample Debugging Session845805
-Node: Debugger Invocation846339
-Node: Finding The Bug847724
-Node: List of Debugger Commands854203
-Node: Breakpoint Control855535
-Node: Debugger Execution Control859212
-Node: Viewing And Changing Data862571
-Node: Execution Stack865947
-Node: Debugger Info867582
-Node: Miscellaneous Debugger Commands871627
-Node: Readline Support876628
-Node: Limitations877522
-Node: Debugging Summary879637
-Node: Arbitrary Precision Arithmetic880811
-Node: Computer Arithmetic882227
-Ref: table-numeric-ranges885804
-Ref: Computer Arithmetic-Footnote-1886328
-Node: Math Definitions886385
-Ref: table-ieee-formats889680
-Ref: Math Definitions-Footnote-1890284
-Node: MPFR features890389
-Node: FP Math Caution892060
-Ref: FP Math Caution-Footnote-1893110
-Node: Inexactness of computations893479
-Node: Inexact representation894438
-Node: Comparing FP Values895796
-Node: Errors accumulate896878
-Node: Getting Accuracy898310
-Node: Try To Round901014
-Node: Setting precision901913
-Ref: table-predefined-precision-strings902597
-Node: Setting the rounding mode904426
-Ref: table-gawk-rounding-modes904790
-Ref: Setting the rounding mode-Footnote-1908242
-Node: Arbitrary Precision Integers908421
-Ref: Arbitrary Precision Integers-Footnote-1913319
-Node: POSIX Floating Point Problems913468
-Ref: POSIX Floating Point Problems-Footnote-1917347
-Node: Floating point summary917385
-Node: Dynamic Extensions919572
-Node: Extension Intro921124
-Node: Plugin License922389
-Node: Extension Mechanism Outline923186
-Ref: figure-load-extension923614
-Ref: figure-register-new-function925094
-Ref: figure-call-new-function926098
-Node: Extension API Description928085
-Node: Extension API Functions Introduction929535
-Node: General Data Types934356
-Ref: General Data Types-Footnote-1940256
-Node: Memory Allocation Functions940555
-Ref: Memory Allocation Functions-Footnote-1943394
-Node: Constructor Functions943493
-Node: Registration Functions945232
-Node: Extension Functions945917
-Node: Exit Callback Functions948214
-Node: Extension Version String949462
-Node: Input Parsers950125
-Node: Output Wrappers960000
-Node: Two-way processors964513
-Node: Printing Messages966776
-Ref: Printing Messages-Footnote-1967852
-Node: Updating `ERRNO'968004
-Node: Requesting Values968744
-Ref: table-value-types-returned969471
-Node: Accessing Parameters970428
-Node: Symbol Table Access971662
-Node: Symbol table by name972176
-Node: Symbol table by cookie974196
-Ref: Symbol table by cookie-Footnote-1978341
-Node: Cached values978404
-Ref: Cached values-Footnote-1981900
-Node: Array Manipulation981991
-Ref: Array Manipulation-Footnote-1983089
-Node: Array Data Types983126
-Ref: Array Data Types-Footnote-1985781
-Node: Array Functions985873
-Node: Flattening Arrays989732
-Node: Creating Arrays996634
-Node: Extension API Variables1001405
-Node: Extension Versioning1002041
-Node: Extension API Informational Variables1003932
-Node: Extension API Boilerplate1004997
-Node: Finding Extensions1008806
-Node: Extension Example1009366
-Node: Internal File Description1010138
-Node: Internal File Ops1014205
-Ref: Internal File Ops-Footnote-11025956
-Node: Using Internal File Ops1026096
-Ref: Using Internal File Ops-Footnote-11028479
-Node: Extension Samples1028752
-Node: Extension Sample File Functions1030280
-Node: Extension Sample Fnmatch1037961
-Node: Extension Sample Fork1039449
-Node: Extension Sample Inplace1040664
-Node: Extension Sample Ord1042340
-Node: Extension Sample Readdir1043176
-Ref: table-readdir-file-types1044053
-Node: Extension Sample Revout1044864
-Node: Extension Sample Rev2way1045453
-Node: Extension Sample Read write array1046193
-Node: Extension Sample Readfile1048133
-Node: Extension Sample Time1049228
-Node: Extension Sample API Tests1050576
-Node: gawkextlib1051067
-Node: Extension summary1053745
-Node: Extension Exercises1057434
-Node: Language History1058156
-Node: V7/SVR3.11059812
-Node: SVR41061965
-Node: POSIX1063399
-Node: BTL1064780
-Node: POSIX/GNU1065511
-Node: Feature History1071347
-Node: Common Extensions1085141
-Node: Ranges and Locales1086513
-Ref: Ranges and Locales-Footnote-11091132
-Ref: Ranges and Locales-Footnote-21091159
-Ref: Ranges and Locales-Footnote-31091394
-Node: Contributors1091615
-Node: History summary1097155
-Node: Installation1098534
-Node: Gawk Distribution1099480
-Node: Getting1099964
-Node: Extracting1100787
-Node: Distribution contents1102424
-Node: Unix Installation1108526
-Node: Quick Installation1109209
-Node: Shell Startup Files1111620
-Node: Additional Configuration Options1112699
-Node: Configuration Philosophy1114503
-Node: Non-Unix Installation1116872
-Node: PC Installation1117330
-Node: PC Binary Installation1118650
-Node: PC Compiling1120498
-Ref: PC Compiling-Footnote-11123519
-Node: PC Testing1123628
-Node: PC Using1124804
-Node: Cygwin1128919
-Node: MSYS1129689
-Node: VMS Installation1130190
-Node: VMS Compilation1130982
-Ref: VMS Compilation-Footnote-11132211
-Node: VMS Dynamic Extensions1132269
-Node: VMS Installation Details1133953
-Node: VMS Running1136204
-Node: VMS GNV1139044
-Node: VMS Old Gawk1139779
-Node: Bugs1140249
-Node: Other Versions1144138
-Node: Installation summary1150572
-Node: Notes1151631
-Node: Compatibility Mode1152496
-Node: Additions1153278
-Node: Accessing The Source1154203
-Node: Adding Code1155638
-Node: New Ports1161795
-Node: Derived Files1166277
-Ref: Derived Files-Footnote-11171752
-Ref: Derived Files-Footnote-21171786
-Ref: Derived Files-Footnote-31172382
-Node: Future Extensions1172496
-Node: Implementation Limitations1173102
-Node: Extension Design1174350
-Node: Old Extension Problems1175504
-Ref: Old Extension Problems-Footnote-11177021
-Node: Extension New Mechanism Goals1177078
-Ref: Extension New Mechanism Goals-Footnote-11180438
-Node: Extension Other Design Decisions1180627
-Node: Extension Future Growth1182735
-Node: Old Extension Mechanism1183571
-Node: Notes summary1185333
-Node: Basic Concepts1186519
-Node: Basic High Level1187200
-Ref: figure-general-flow1187472
-Ref: figure-process-flow1188071
-Ref: Basic High Level-Footnote-11191300
-Node: Basic Data Typing1191485
-Node: Glossary1194813
-Node: Copying1226742
-Node: GNU Free Documentation License1264298
-Node: Index1289434
+Node: Foreword342451
+Node: Foreword446895
+Node: Preface48426
+Ref: Preface-Footnote-151297
+Ref: Preface-Footnote-251404
+Ref: Preface-Footnote-351637
+Node: History51779
+Node: Names54130
+Ref: Names-Footnote-155224
+Node: This Manual55370
+Ref: This Manual-Footnote-161870
+Node: Conventions61970
+Node: Manual History64307
+Ref: Manual History-Footnote-167300
+Ref: Manual History-Footnote-267341
+Node: How To Contribute67415
+Node: Acknowledgments68544
+Node: Getting Started73410
+Node: Running gawk75849
+Node: One-shot77039
+Node: Read Terminal78303
+Node: Long80334
+Node: Executable Scripts81847
+Ref: Executable Scripts-Footnote-184636
+Node: Comments84739
+Node: Quoting87221
+Node: DOS Quoting92739
+Node: Sample Data Files93414
+Node: Very Simple96009
+Node: Two Rules100908
+Node: More Complex102794
+Node: Statements/Lines105656
+Ref: Statements/Lines-Footnote-1110111
+Node: Other Features110376
+Node: When111312
+Ref: When-Footnote-1113066
+Node: Intro Summary113131
+Node: Invoking Gawk114015
+Node: Command Line115529
+Node: Options116327
+Ref: Options-Footnote-1132122
+Ref: Options-Footnote-2132351
+Node: Other Arguments132376
+Node: Naming Standard Input135324
+Node: Environment Variables136417
+Node: AWKPATH Variable136975
+Ref: AWKPATH Variable-Footnote-1140382
+Ref: AWKPATH Variable-Footnote-2140427
+Node: AWKLIBPATH Variable140687
+Node: Other Environment Variables141943
+Node: Exit Status145574
+Node: Include Files146250
+Node: Loading Shared Libraries149839
+Node: Obsolete151266
+Node: Undocumented151958
+Node: Invoking Summary152225
+Node: Regexp153888
+Node: Regexp Usage155342
+Node: Escape Sequences157379
+Node: Regexp Operators163608
+Ref: Regexp Operators-Footnote-1171018
+Ref: Regexp Operators-Footnote-2171165
+Node: Bracket Expressions171263
+Ref: table-char-classes173278
+Node: Leftmost Longest176220
+Node: Computed Regexps177522
+Node: GNU Regexp Operators180951
+Node: Case-sensitivity184623
+Ref: Case-sensitivity-Footnote-1187508
+Ref: Case-sensitivity-Footnote-2187743
+Node: Regexp Summary187851
+Node: Reading Files189318
+Node: Records191480
+Node: awk split records192213
+Node: gawk split records197142
+Ref: gawk split records-Footnote-1201681
+Node: Fields201718
+Ref: Fields-Footnote-1204496
+Node: Nonconstant Fields204582
+Ref: Nonconstant Fields-Footnote-1206820
+Node: Changing Fields207023
+Node: Field Separators212954
+Node: Default Field Splitting215658
+Node: Regexp Field Splitting216775
+Node: Single Character Fields220125
+Node: Command Line Field Separator221184
+Node: Full Line Fields224401
+Ref: Full Line Fields-Footnote-1225922
+Ref: Full Line Fields-Footnote-2225968
+Node: Field Splitting Summary226069
+Node: Constant Size228143
+Node: Splitting By Content232722
+Ref: Splitting By Content-Footnote-1236687
+Node: Multiple Line236850
+Ref: Multiple Line-Footnote-1242731
+Node: Getline242910
+Node: Plain Getline245380
+Node: Getline/Variable248020
+Node: Getline/File249169
+Node: Getline/Variable/File250554
+Ref: Getline/Variable/File-Footnote-1252157
+Node: Getline/Pipe252244
+Node: Getline/Variable/Pipe254922
+Node: Getline/Coprocess256053
+Node: Getline/Variable/Coprocess257317
+Node: Getline Notes258056
+Node: Getline Summary260850
+Ref: table-getline-variants261262
+Node: Read Timeout262091
+Ref: Read Timeout-Footnote-1265994
+Node: Retrying Input266052
+Node: Command-line directories267238
+Node: Input Summary268145
+Node: Input Exercises271530
+Node: Printing272258
+Node: Print274093
+Node: Print Examples275550
+Node: Output Separators278329
+Node: OFMT280347
+Node: Printf281702
+Node: Basic Printf282487
+Node: Control Letters284059
+Node: Format Modifiers288044
+Node: Printf Examples294050
+Node: Redirection296536
+Node: Special FD303374
+Ref: Special FD-Footnote-1306540
+Node: Special Files306614
+Node: Other Inherited Files307231
+Node: Special Network308231
+Node: Special Caveats309093
+Node: Close Files And Pipes310042
+Ref: Close Files And Pipes-Footnote-1317227
+Ref: Close Files And Pipes-Footnote-2317375
+Node: Nonfatal317525
+Node: Output Summary319850
+Node: Output Exercises321071
+Node: Expressions321751
+Node: Values322940
+Node: Constants323617
+Node: Scalar Constants324308
+Ref: Scalar Constants-Footnote-1325170
+Node: Nondecimal-numbers325420
+Node: Regexp Constants328430
+Node: Using Constant Regexps328956
+Node: Variables332119
+Node: Using Variables332776
+Node: Assignment Options334687
+Node: Conversion336562
+Node: Strings And Numbers337086
+Ref: Strings And Numbers-Footnote-1340151
+Node: Locale influences conversions340260
+Ref: table-locale-affects343006
+Node: All Operators343598
+Node: Arithmetic Ops344227
+Node: Concatenation346732
+Ref: Concatenation-Footnote-1349551
+Node: Assignment Ops349658
+Ref: table-assign-ops354637
+Node: Increment Ops355947
+Node: Truth Values and Conditions359378
+Node: Truth Values360461
+Node: Typing and Comparison361510
+Node: Variable Typing362326
+Node: Comparison Operators365993
+Ref: table-relational-ops366403
+Node: POSIX String Comparison369898
+Ref: POSIX String Comparison-Footnote-1370970
+Node: Boolean Ops371109
+Ref: Boolean Ops-Footnote-1375587
+Node: Conditional Exp375678
+Node: Function Calls377416
+Node: Precedence381296
+Node: Locales384956
+Node: Expressions Summary386588
+Node: Patterns and Actions389159
+Node: Pattern Overview390279
+Node: Regexp Patterns391958
+Node: Expression Patterns392501
+Node: Ranges396281
+Node: BEGIN/END399388
+Node: Using BEGIN/END400149
+Ref: Using BEGIN/END-Footnote-1402885
+Node: I/O And BEGIN/END402991
+Node: BEGINFILE/ENDFILE405306
+Node: Empty408203
+Node: Using Shell Variables408520
+Node: Action Overview410793
+Node: Statements413119
+Node: If Statement414967
+Node: While Statement416462
+Node: Do Statement418490
+Node: For Statement419638
+Node: Switch Statement422796
+Node: Break Statement425178
+Node: Continue Statement427271
+Node: Next Statement429098
+Node: Nextfile Statement431479
+Node: Exit Statement434107
+Node: Built-in Variables436518
+Node: User-modified437651
+Ref: User-modified-Footnote-1445285
+Node: Auto-set445347
+Ref: Auto-set-Footnote-1459580
+Ref: Auto-set-Footnote-2459785
+Node: ARGC and ARGV459841
+Node: Pattern Action Summary464059
+Node: Arrays466492
+Node: Array Basics467821
+Node: Array Intro468665
+Ref: figure-array-elements470602
+Ref: Array Intro-Footnote-1473225
+Node: Reference to Elements473353
+Node: Assigning Elements475815
+Node: Array Example476306
+Node: Scanning an Array478065
+Node: Controlling Scanning481088
+Ref: Controlling Scanning-Footnote-1486482
+Node: Numeric Array Subscripts486798
+Node: Uninitialized Subscripts488983
+Node: Delete490600
+Ref: Delete-Footnote-1493349
+Node: Multidimensional493406
+Node: Multiscanning496503
+Node: Arrays of Arrays498092
+Node: Arrays Summary502846
+Node: Functions504937
+Node: Built-in505976
+Node: Calling Built-in507054
+Node: Numeric Functions509049
+Ref: Numeric Functions-Footnote-1513867
+Ref: Numeric Functions-Footnote-2514224
+Ref: Numeric Functions-Footnote-3514272
+Node: String Functions514544
+Ref: String Functions-Footnote-1538045
+Ref: String Functions-Footnote-2538174
+Ref: String Functions-Footnote-3538422
+Node: Gory Details538509
+Ref: table-sub-escapes540290
+Ref: table-sub-proposed541805
+Ref: table-posix-sub543167
+Ref: table-gensub-escapes544704
+Ref: Gory Details-Footnote-1545537
+Node: I/O Functions545688
+Ref: I/O Functions-Footnote-1552924
+Node: Time Functions553071
+Ref: Time Functions-Footnote-1563580
+Ref: Time Functions-Footnote-2563648
+Ref: Time Functions-Footnote-3563806
+Ref: Time Functions-Footnote-4563917
+Ref: Time Functions-Footnote-5564029
+Ref: Time Functions-Footnote-6564256
+Node: Bitwise Functions564522
+Ref: table-bitwise-ops565084
+Ref: Bitwise Functions-Footnote-1569412
+Node: Type Functions569584
+Node: I18N Functions570736
+Node: User-defined572383
+Node: Definition Syntax573188
+Ref: Definition Syntax-Footnote-1578847
+Node: Function Example578918
+Ref: Function Example-Footnote-1581839
+Node: Function Caveats581861
+Node: Calling A Function582379
+Node: Variable Scope583337
+Node: Pass By Value/Reference586330
+Node: Return Statement589827
+Node: Dynamic Typing592806
+Node: Indirect Calls593735
+Ref: Indirect Calls-Footnote-1603600
+Node: Functions Summary603728
+Node: Library Functions606430
+Ref: Library Functions-Footnote-1610038
+Ref: Library Functions-Footnote-2610181
+Node: Library Names610352
+Ref: Library Names-Footnote-1613810
+Ref: Library Names-Footnote-2614033
+Node: General Functions614119
+Node: Strtonum Function615222
+Node: Assert Function618244
+Node: Round Function621568
+Node: Cliff Random Function623109
+Node: Ordinal Functions624125
+Ref: Ordinal Functions-Footnote-1627188
+Ref: Ordinal Functions-Footnote-2627440
+Node: Join Function627651
+Ref: Join Function-Footnote-1629421
+Node: Getlocaltime Function629621
+Node: Readfile Function633365
+Node: Shell Quoting635337
+Node: Data File Management636738
+Node: Filetrans Function637370
+Node: Rewind Function641466
+Node: File Checking642852
+Ref: File Checking-Footnote-1644185
+Node: Empty Files644386
+Node: Ignoring Assigns646365
+Node: Getopt Function647915
+Ref: Getopt Function-Footnote-1659379
+Node: Passwd Functions659579
+Ref: Passwd Functions-Footnote-1668419
+Node: Group Functions668507
+Ref: Group Functions-Footnote-1676404
+Node: Walking Arrays676609
+Node: Library Functions Summary679615
+Node: Library Exercises681017
+Node: Sample Programs682297
+Node: Running Examples683067
+Node: Clones683795
+Node: Cut Program685019
+Node: Egrep Program694739
+Ref: Egrep Program-Footnote-1702242
+Node: Id Program702352
+Node: Split Program706028
+Ref: Split Program-Footnote-1709482
+Node: Tee Program709610
+Node: Uniq Program712399
+Node: Wc Program719818
+Ref: Wc Program-Footnote-1724068
+Node: Miscellaneous Programs724162
+Node: Dupword Program725375
+Node: Alarm Program727406
+Node: Translate Program732211
+Ref: Translate Program-Footnote-1736774
+Node: Labels Program737044
+Ref: Labels Program-Footnote-1740395
+Node: Word Sorting740479
+Node: History Sorting744549
+Node: Extract Program746384
+Node: Simple Sed753908
+Node: Igawk Program756978
+Ref: Igawk Program-Footnote-1771304
+Ref: Igawk Program-Footnote-2771505
+Ref: Igawk Program-Footnote-3771627
+Node: Anagram Program771742
+Node: Signature Program774803
+Node: Programs Summary776050
+Node: Programs Exercises777271
+Ref: Programs Exercises-Footnote-1781402
+Node: Advanced Features781493
+Node: Nondecimal Data783475
+Node: Array Sorting785065
+Node: Controlling Array Traversal785765
+Ref: Controlling Array Traversal-Footnote-1794131
+Node: Array Sorting Functions794249
+Ref: Array Sorting Functions-Footnote-1798135
+Node: Two-way I/O798331
+Ref: Two-way I/O-Footnote-1803276
+Ref: Two-way I/O-Footnote-2803462
+Node: TCP/IP Networking803544
+Node: Profiling806416
+Node: Advanced Features Summary814687
+Node: Internationalization816620
+Node: I18N and L10N818100
+Node: Explaining gettext818786
+Ref: Explaining gettext-Footnote-1823811
+Ref: Explaining gettext-Footnote-2823995
+Node: Programmer i18n824160
+Ref: Programmer i18n-Footnote-1829036
+Node: Translator i18n829085
+Node: String Extraction829879
+Ref: String Extraction-Footnote-1831010
+Node: Printf Ordering831096
+Ref: Printf Ordering-Footnote-1833882
+Node: I18N Portability833946
+Ref: I18N Portability-Footnote-1836402
+Node: I18N Example836465
+Ref: I18N Example-Footnote-1839268
+Node: Gawk I18N839340
+Node: I18N Summary839984
+Node: Debugger841324
+Node: Debugging842346
+Node: Debugging Concepts842787
+Node: Debugging Terms844597
+Node: Awk Debugging847169
+Node: Sample Debugging Session848075
+Node: Debugger Invocation848609
+Node: Finding The Bug849994
+Node: List of Debugger Commands856473
+Node: Breakpoint Control857805
+Node: Debugger Execution Control861482
+Node: Viewing And Changing Data864841
+Node: Execution Stack868217
+Node: Debugger Info869852
+Node: Miscellaneous Debugger Commands873897
+Node: Readline Support878898
+Node: Limitations879792
+Node: Debugging Summary881907
+Node: Arbitrary Precision Arithmetic883081
+Node: Computer Arithmetic884497
+Ref: table-numeric-ranges888074
+Ref: Computer Arithmetic-Footnote-1888598
+Node: Math Definitions888655
+Ref: table-ieee-formats891950
+Ref: Math Definitions-Footnote-1892554
+Node: MPFR features892659
+Node: FP Math Caution894330
+Ref: FP Math Caution-Footnote-1895380
+Node: Inexactness of computations895749
+Node: Inexact representation896708
+Node: Comparing FP Values898066
+Node: Errors accumulate899148
+Node: Getting Accuracy900580
+Node: Try To Round903284
+Node: Setting precision904183
+Ref: table-predefined-precision-strings904867
+Node: Setting the rounding mode906696
+Ref: table-gawk-rounding-modes907060
+Ref: Setting the rounding mode-Footnote-1910512
+Node: Arbitrary Precision Integers910691
+Ref: Arbitrary Precision Integers-Footnote-1915589
+Node: POSIX Floating Point Problems915738
+Ref: POSIX Floating Point Problems-Footnote-1919617
+Node: Floating point summary919655
+Node: Dynamic Extensions921842
+Node: Extension Intro923394
+Node: Plugin License924659
+Node: Extension Mechanism Outline925456
+Ref: figure-load-extension925884
+Ref: figure-register-new-function927364
+Ref: figure-call-new-function928368
+Node: Extension API Description930355
+Node: Extension API Functions Introduction931889
+Node: General Data Types936758
+Ref: General Data Types-Footnote-1942658
+Node: Memory Allocation Functions942957
+Ref: Memory Allocation Functions-Footnote-1945796
+Node: Constructor Functions945895
+Node: Registration Functions947634
+Node: Extension Functions948319
+Node: Exit Callback Functions950616
+Node: Extension Version String951864
+Node: Input Parsers952527
+Node: Output Wrappers962402
+Node: Two-way processors966915
+Node: Printing Messages969178
+Ref: Printing Messages-Footnote-1970254
+Node: Updating `ERRNO'970406
+Node: Requesting Values971146
+Ref: table-value-types-returned971873
+Node: Accessing Parameters972830
+Node: Symbol Table Access974064
+Node: Symbol table by name974578
+Node: Symbol table by cookie976598
+Ref: Symbol table by cookie-Footnote-1980743
+Node: Cached values980806
+Ref: Cached values-Footnote-1984302
+Node: Array Manipulation984393
+Ref: Array Manipulation-Footnote-1985483
+Node: Array Data Types985520
+Ref: Array Data Types-Footnote-1988175
+Node: Array Functions988267
+Node: Flattening Arrays992126
+Node: Creating Arrays999028
+Node: Redirection API1003799
+Node: Extension API Variables1006624
+Node: Extension Versioning1007257
+Node: Extension API Informational Variables1009148
+Node: Extension API Boilerplate1010213
+Node: Finding Extensions1014022
+Node: Extension Example1014582
+Node: Internal File Description1015354
+Node: Internal File Ops1019421
+Ref: Internal File Ops-Footnote-11031172
+Node: Using Internal File Ops1031312
+Ref: Using Internal File Ops-Footnote-11033695
+Node: Extension Samples1033968
+Node: Extension Sample File Functions1035496
+Node: Extension Sample Fnmatch1043177
+Node: Extension Sample Fork1044665
+Node: Extension Sample Inplace1045880
+Node: Extension Sample Ord1047966
+Node: Extension Sample Readdir1048802
+Ref: table-readdir-file-types1049679
+Node: Extension Sample Revout1050490
+Node: Extension Sample Rev2way1051079
+Node: Extension Sample Read write array1051819
+Node: Extension Sample Readfile1053759
+Node: Extension Sample Time1054854
+Node: Extension Sample API Tests1056202
+Node: gawkextlib1056693
+Node: Extension summary1059371
+Node: Extension Exercises1063060
+Node: Language History1064556
+Node: V7/SVR3.11066212
+Node: SVR41068365
+Node: POSIX1069799
+Node: BTL1071180
+Node: POSIX/GNU1071911
+Node: Feature History1077747
+Node: Common Extensions1091541
+Node: Ranges and Locales1092913
+Ref: Ranges and Locales-Footnote-11097532
+Ref: Ranges and Locales-Footnote-21097559
+Ref: Ranges and Locales-Footnote-31097794
+Node: Contributors1098015
+Node: History summary1103555
+Node: Installation1104934
+Node: Gawk Distribution1105880
+Node: Getting1106364
+Node: Extracting1107187
+Node: Distribution contents1108824
+Node: Unix Installation1114926
+Node: Quick Installation1115609
+Node: Shell Startup Files1118020
+Node: Additional Configuration Options1119099
+Node: Configuration Philosophy1120903
+Node: Non-Unix Installation1123272
+Node: PC Installation1123730
+Node: PC Binary Installation1125050
+Node: PC Compiling1126898
+Ref: PC Compiling-Footnote-11129919
+Node: PC Testing1130028
+Node: PC Using1131204
+Node: Cygwin1135319
+Node: MSYS1136089
+Node: VMS Installation1136590
+Node: VMS Compilation1137382
+Ref: VMS Compilation-Footnote-11138611
+Node: VMS Dynamic Extensions1138669
+Node: VMS Installation Details1140353
+Node: VMS Running1142604
+Node: VMS GNV1145444
+Node: VMS Old Gawk1146179
+Node: Bugs1146649
+Node: Other Versions1150538
+Node: Installation summary1156972
+Node: Notes1158031
+Node: Compatibility Mode1158896
+Node: Additions1159678
+Node: Accessing The Source1160603
+Node: Adding Code1162038
+Node: New Ports1168195
+Node: Derived Files1172677
+Ref: Derived Files-Footnote-11178152
+Ref: Derived Files-Footnote-21178186
+Ref: Derived Files-Footnote-31178782
+Node: Future Extensions1178896
+Node: Implementation Limitations1179502
+Node: Extension Design1180750
+Node: Old Extension Problems1181904
+Ref: Old Extension Problems-Footnote-11183421
+Node: Extension New Mechanism Goals1183478
+Ref: Extension New Mechanism Goals-Footnote-11186838
+Node: Extension Other Design Decisions1187027
+Node: Extension Future Growth1189135
+Node: Old Extension Mechanism1189971
+Node: Notes summary1191733
+Node: Basic Concepts1192919
+Node: Basic High Level1193600
+Ref: figure-general-flow1193872
+Ref: figure-process-flow1194471
+Ref: Basic High Level-Footnote-11197700
+Node: Basic Data Typing1197885
+Node: Glossary1201213
+Node: Copying1233142
+Node: GNU Free Documentation License1270698
+Node: Index1295834

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 27cbcab2..e9d987f0 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -604,6 +604,7 @@ particular records in a file and perform operations upon them.
@code{getline}.
* Getline Summary:: Summary of @code{getline} Variants.
* Read Timeout:: Reading input with a timeout.
+* Retrying Input:: Retrying input after certain errors.
* Command-line directories:: What happens if you put a directory on
the command line.
* Input Summary:: Input summary.
@@ -945,6 +946,7 @@ particular records in a file and perform operations upon them.
* Array Functions:: Functions for working with arrays.
* Flattening Arrays:: How to flatten arrays.
* Creating Arrays:: How to create and populate arrays.
+* Redirection API:: How to access and manipulate redirections.
* Extension API Variables:: Variables provided by the API.
* Extension Versioning:: API Version information.
* Extension API Informational Variables:: Variables providing information about
@@ -6327,6 +6329,7 @@ used with it do not have to be named on the @command{awk} command line
* Getline:: Reading files under explicit program control
using the @code{getline} function.
* Read Timeout:: Reading input with a timeout.
+* Retrying Input:: Retrying input after certain errors.
* Command-line directories:: What happens if you put a directory on the
command line.
* Input Summary:: Input summary.
@@ -8113,6 +8116,13 @@ a record, such as a file that cannot be opened, then @code{getline}
returns @minus{}1. In this case, @command{gawk} sets the variable
@code{ERRNO} to a string describing the error that occurred.
+If @code{ERRNO} indicates that the I/O operation may be
+retried, and @code{PROCINFO["@var{input}", "RETRY"]} is set,
+then @code{getline} returns @minus{}2
+instead of @minus{}1, and further calls to @code{getline}
+may be attemped. @DBXREF{Retrying Input} for further information about
+this feature.
+
In the following examples, @var{command} stands for a string value that
represents a shell command.
@@ -8767,7 +8777,8 @@ on a per-command or per-connection basis.
the attempt to read from the underlying device may
succeed in a later attempt. This is a limitation, and it also
means that you cannot use this to multiplex input from
-two or more sources.
+two or more sources. @DBXREF{Retrying Input} for a way to enable
+later I/O attempts to succeed.
Assigning a timeout value prevents read operations from
blocking indefinitely. But bear in mind that there are other ways
@@ -8777,6 +8788,35 @@ a connection before it can start reading any data,
or the attempt to open a FIFO special file for reading can block
indefinitely until some other process opens it for writing.
+@node Retrying Input
+@section Retrying Reads After Certain Input Errors
+@cindex retrying input
+
+@cindex differences in @command{awk} and @command{gawk}, retrying input
+This @value{SECTION} describes a feature that is specific to @command{gawk}.
+
+When @command{gawk} encounters an error while reading input, by
+default @code{getline} returns @minus{}1, and subsequent attempts to
+read from that file result in an end-of-file indication. However, you
+may optionally instruct @command{gawk} to allow I/O to be retried when
+certain errors are encountered by setting a special element in
+the @code{PROCINFO} array (@pxref{Auto-set}):
+
+@example
+PROCINFO["@var{input_name}", "RETRY"] = 1
+@end example
+
+When this element exists, @command{gawk} checks the value of the system
+@code{errno} variable when an I/O error occurs. If @code{errno} indicates
+a subsequent I/O attempt may succeed, @code{getline} instead returns
+@minus{}2 and
+further calls to @code{getline} may succeed. This applies to the @code{errno}
+values @code{EAGAIN}, @code{EWOULDBLOCK}, @code{EINTR}, or @code{ETIMEDOUT}.
+
+This feature is useful in conjunction with
+@code{PROCINFO["@var{input_name}", "READ_TIMEOUT"]} or situations where a file
+descriptor has been configured to behave in a non-blocking fashion.
+
@node Command-line directories
@section Directories on the Command Line
@cindex differences in @command{awk} and @command{gawk}, command-line directories
@@ -14928,6 +14968,11 @@ value to be meaningful when an I/O operation returns a failure value,
such as @code{getline} returning @minus{}1. You are, of course, free
to clear it yourself before doing an I/O operation.
+If the value of @code{ERRNO} corresponds to a system error in the C
+@code{errno} variable, then @code{PROCINFO["errno"]} will be set to the value
+of @code{errno}. For non-system errors, @code{PROCINFO["errno"]} will
+be zero.
+
@cindex @code{FILENAME} variable
@cindex dark corner, @code{FILENAME} variable
@item @code{FILENAME}
@@ -14996,6 +15041,10 @@ are guaranteed to be available:
@item PROCINFO["egid"]
The value of the @code{getegid()} system call.
+@item PROCINFO["errno"]
+The value of the C @code{errno} variable when @code{ERRNO} is set to
+the associated error message.
+
@item PROCINFO["euid"]
@cindex effective user ID of @command{gawk} user
The value of the @code{geteuid()} system call.
@@ -15046,7 +15095,7 @@ while the program runs.
The value of the @code{getgid()} system call.
@item PROCINFO["pgrpid"]
-@cindex process group idIDof @command{gawk} process
+@cindex process group ID of @command{gawk} process
The process group ID of the current process.
@item PROCINFO["pid"]
@@ -15098,7 +15147,7 @@ The version of the GNU MP library.
The maximum precision supported by MPFR.
@item PROCINFO["prec_min"]
-@cindex minimum precision supported by MPFR library
+@cindex minimum precision required by MPFR library
The minimum precision required by MPFR.
@end table
@@ -15135,6 +15184,11 @@ open input file, pipe, or coprocess.
@DBXREF{Read Timeout} for more information.
@item
+It may be used to indicate that input may be retried when it fails due to
+certain errors.
+@DBXREF{Retrying Input} for more information.
+
+@item
It may be used to cause coprocesses to communicate over pseudo-ttys
instead of through two-way pipes; this is discussed further in
@ref{Two-way I/O}.
@@ -31571,6 +31625,7 @@ This (rather large) @value{SECTION} describes the API in detail.
* Symbol Table Access:: Functions for accessing global
variables.
* Array Manipulation:: Functions for working with arrays.
+* Redirection API:: How to access and manipulate redirections.
* Extension API Variables:: Variables provided by the API.
* Extension API Boilerplate:: Boilerplate code for using the API.
@end menu
@@ -31646,6 +31701,10 @@ Clearing an array
@item
Flattening an array for easy C-style looping over all its indices and elements
@end itemize
+
+@item
+Accessing and manipulating redirections.
+
@end itemize
Some points about using the API:
@@ -33616,6 +33675,75 @@ $ @kbd{AWKLIBPATH=$PWD ./gawk -f subarray.awk}
(@DBXREF{Finding Extensions} for more information on the
@env{AWKLIBPATH} environment variable.)
+@node Redirection API
+@subsection Accessing and Manipulating Redirections
+
+The following function allows extensions to access and manipulate redirections.
+
+@table @code
+@item awk_bool_t get_file(const char *name,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ size_t name_len,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const char *filetype,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ int fd,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_input_buf_t **ibufp,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_output_buf_t **obufp);
+Look up a file in @command{gawk}'s internal redirection table.
+If @code{name} is @code{NULL} or @code{name_len} is zero, return
+data for the currently open input file corresponding to @code{FILENAME}.
+(This does not access the @code{filetype} argument, so that may be undefined).
+If the file is not already open, attempt to open it.
+The @code{filetype} argument must be zero-terminated and should be one of:
+
+@table @code
+@item ">"
+A file opened for output.
+
+@item ">>"
+A file opened for append.
+
+@item "<"
+A file opened for input.
+
+@item "|>"
+A pipe opened for output.
+
+@item "|<"
+A pipe opened for input.
+
+@item "|&"
+A two-way coprocess.
+@end table
+
+On error, return a @code{false} value. Otherwise, return
+@code{true}, and return additional information about the redirection
+in the @code{ibufp} and @code{obufp} pointers. For input
+redirections, the @code{*ibufp} value should be non-@code{NULL},
+and @code{*obufp} should be @code{NULL}. For output redirections,
+the @code{*obufp} value should be non-@code{NULL}, and @code{*ibufp}
+should be @code{NULL}. For two-way coprocesses, both values should
+be non-@code{NULL}.
+
+In the usual case, the extension is interested in @code{(*ibufp)->fd}
+and/or @code{fileno((*obufp)->fp)}. If the file is not already
+open, and the @code{fd} argument is non-negative, @command{gawk}
+will use that file descriptor instead of opening the file in the
+usual way. If @code{fd} is non-negative, but the file exists already,
+@command{gawk} ignores @code{fd} and returns the existing file. It is
+the caller's responsibility to notice that neither the @code{fd} in
+the returned @code{awk_input_buf_t} nor the @code{fd} in the returned
+@code{awk_output_buf_t} matches the requested value.
+
+Note that supplying a file descriptor is currently @emph{not} supported
+for pipes. However, supplying a file descriptor should work for input,
+output, append, and two-way (coprocess) sockets. If @code{filetype}
+is two-way, @command{gawk} assumes that it is a socket! Note that in
+the two-way case, the input and output file descriptors may differ.
+To check for success, you must check whether either matches.
+@end table
+
+It is anticipated that this API function will be used to implement I/O
+multiplexing and a socket library.
+
@node Extension API Variables
@subsection API Variables
@@ -34830,11 +34958,16 @@ properly:
# Please set INPLACE_SUFFIX to make a backup copy. For example, you may
# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
+# N.B. We call inplace_end() in the BEGINFILE and END rules so that any
+# actions in an ENDFILE rule will be redirected as expected.
+
BEGINFILE @{
- inplace_begin(FILENAME, INPLACE_SUFFIX)
+ if (_inplace_filename != "")
+ inplace_end(_inplace_filename, INPLACE_SUFFIX)
+ inplace_begin(_inplace_filename = FILENAME, INPLACE_SUFFIX)
@}
-ENDFILE @{
+END @{
inplace_end(FILENAME, INPLACE_SUFFIX)
@}
@end group
@@ -34849,6 +34982,10 @@ If @code{INPLACE_SUFFIX} is not an empty string, the original file is
linked to a backup @value{FN} created by appending that suffix. Finally,
the temporary file is renamed to the original @value{FN}.
+The @code{_inplace_filename} variable serves to keep track of the
+current filename so as to not invoke @code{inplace_end()} before
+processing the first file.
+
If any error occurs, the extension issues a fatal error to terminate
processing immediately without damaging the original file.
@@ -35343,6 +35480,24 @@ Add functions to implement system calls such as @code{chown()},
@code{chmod()}, and @code{umask()} to the file operations extension
presented in @ref{Internal File Ops}.
+@c Idea from comp.lang.awk, February 2015
+@item
+Write an input parser that prints a prompt if the input is
+a from a ``terminal'' device. You can use the @code{isatty()}
+function to tell if the input file is a terminal. (Hint: this function
+is usually expensive to call; try to call it just once.)
+The content of the prompt should come from a variable settable
+by @command{awk}-level code.
+You can write the prompt to stanard error. However,
+for best results, open a new file descriptor (or file pointer)
+on @file{/dev/tty} and print the prompt there, in case standard
+error has been redirected.
+
+Why is standard error a better
+choice than standard output for writing the prompt?
+Which reading mechanism should you replace, the one to get
+a record, or the one to read raw bytes?
+
@item
(Hard.)
How would you provide namespaces in @command{gawk}, so that the
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index 121a066e..178444a4 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -599,6 +599,7 @@ particular records in a file and perform operations upon them.
@code{getline}.
* Getline Summary:: Summary of @code{getline} Variants.
* Read Timeout:: Reading input with a timeout.
+* Retrying Input:: Retrying input after certain errors.
* Command-line directories:: What happens if you put a directory on
the command line.
* Input Summary:: Input summary.
@@ -940,6 +941,7 @@ particular records in a file and perform operations upon them.
* Array Functions:: Functions for working with arrays.
* Flattening Arrays:: How to flatten arrays.
* Creating Arrays:: How to create and populate arrays.
+* Redirection API:: How to access and manipulate redirections.
* Extension API Variables:: Variables provided by the API.
* Extension Versioning:: API Version information.
* Extension API Informational Variables:: Variables providing information about
@@ -6111,6 +6113,7 @@ used with it do not have to be named on the @command{awk} command line
* Getline:: Reading files under explicit program control
using the @code{getline} function.
* Read Timeout:: Reading input with a timeout.
+* Retrying Input:: Retrying input after certain errors.
* Command-line directories:: What happens if you put a directory on the
command line.
* Input Summary:: Input summary.
@@ -7713,6 +7716,13 @@ a record, such as a file that cannot be opened, then @code{getline}
returns @minus{}1. In this case, @command{gawk} sets the variable
@code{ERRNO} to a string describing the error that occurred.
+If @code{ERRNO} indicates that the I/O operation may be
+retried, and @code{PROCINFO["@var{input}", "RETRY"]} is set,
+then @code{getline} returns @minus{}2
+instead of @minus{}1, and further calls to @code{getline}
+may be attemped. @DBXREF{Retrying Input} for further information about
+this feature.
+
In the following examples, @var{command} stands for a string value that
represents a shell command.
@@ -8367,7 +8377,8 @@ on a per-command or per-connection basis.
the attempt to read from the underlying device may
succeed in a later attempt. This is a limitation, and it also
means that you cannot use this to multiplex input from
-two or more sources.
+two or more sources. @DBXREF{Retrying Input} for a way to enable
+later I/O attempts to succeed.
Assigning a timeout value prevents read operations from
blocking indefinitely. But bear in mind that there are other ways
@@ -8377,6 +8388,35 @@ a connection before it can start reading any data,
or the attempt to open a FIFO special file for reading can block
indefinitely until some other process opens it for writing.
+@node Retrying Input
+@section Retrying Reads After Certain Input Errors
+@cindex retrying input
+
+@cindex differences in @command{awk} and @command{gawk}, retrying input
+This @value{SECTION} describes a feature that is specific to @command{gawk}.
+
+When @command{gawk} encounters an error while reading input, by
+default @code{getline} returns @minus{}1, and subsequent attempts to
+read from that file result in an end-of-file indication. However, you
+may optionally instruct @command{gawk} to allow I/O to be retried when
+certain errors are encountered by setting a special element in
+the @code{PROCINFO} array (@pxref{Auto-set}):
+
+@example
+PROCINFO["@var{input_name}", "RETRY"] = 1
+@end example
+
+When this element exists, @command{gawk} checks the value of the system
+@code{errno} variable when an I/O error occurs. If @code{errno} indicates
+a subsequent I/O attempt may succeed, @code{getline} instead returns
+@minus{}2 and
+further calls to @code{getline} may succeed. This applies to the @code{errno}
+values @code{EAGAIN}, @code{EWOULDBLOCK}, @code{EINTR}, or @code{ETIMEDOUT}.
+
+This feature is useful in conjunction with
+@code{PROCINFO["@var{input_name}", "READ_TIMEOUT"]} or situations where a file
+descriptor has been configured to behave in a non-blocking fashion.
+
@node Command-line directories
@section Directories on the Command Line
@cindex differences in @command{awk} and @command{gawk}, command-line directories
@@ -14256,6 +14296,11 @@ value to be meaningful when an I/O operation returns a failure value,
such as @code{getline} returning @minus{}1. You are, of course, free
to clear it yourself before doing an I/O operation.
+If the value of @code{ERRNO} corresponds to a system error in the C
+@code{errno} variable, then @code{PROCINFO["errno"]} will be set to the value
+of @code{errno}. For non-system errors, @code{PROCINFO["errno"]} will
+be zero.
+
@cindex @code{FILENAME} variable
@cindex dark corner, @code{FILENAME} variable
@item @code{FILENAME}
@@ -14324,6 +14369,10 @@ are guaranteed to be available:
@item PROCINFO["egid"]
The value of the @code{getegid()} system call.
+@item PROCINFO["errno"]
+The value of the C @code{errno} variable when @code{ERRNO} is set to
+the associated error message.
+
@item PROCINFO["euid"]
@cindex effective user ID of @command{gawk} user
The value of the @code{geteuid()} system call.
@@ -14374,7 +14423,7 @@ while the program runs.
The value of the @code{getgid()} system call.
@item PROCINFO["pgrpid"]
-@cindex process group idIDof @command{gawk} process
+@cindex process group ID of @command{gawk} process
The process group ID of the current process.
@item PROCINFO["pid"]
@@ -14426,7 +14475,7 @@ The version of the GNU MP library.
The maximum precision supported by MPFR.
@item PROCINFO["prec_min"]
-@cindex minimum precision supported by MPFR library
+@cindex minimum precision required by MPFR library
The minimum precision required by MPFR.
@end table
@@ -14463,6 +14512,11 @@ open input file, pipe, or coprocess.
@DBXREF{Read Timeout} for more information.
@item
+It may be used to indicate that input may be retried when it fails due to
+certain errors.
+@DBXREF{Retrying Input} for more information.
+
+@item
It may be used to cause coprocesses to communicate over pseudo-ttys
instead of through two-way pipes; this is discussed further in
@ref{Two-way I/O}.
@@ -30662,6 +30716,7 @@ This (rather large) @value{SECTION} describes the API in detail.
* Symbol Table Access:: Functions for accessing global
variables.
* Array Manipulation:: Functions for working with arrays.
+* Redirection API:: How to access and manipulate redirections.
* Extension API Variables:: Variables provided by the API.
* Extension API Boilerplate:: Boilerplate code for using the API.
@end menu
@@ -30737,6 +30792,10 @@ Clearing an array
@item
Flattening an array for easy C-style looping over all its indices and elements
@end itemize
+
+@item
+Accessing and manipulating redirections.
+
@end itemize
Some points about using the API:
@@ -32707,6 +32766,75 @@ $ @kbd{AWKLIBPATH=$PWD ./gawk -f subarray.awk}
(@DBXREF{Finding Extensions} for more information on the
@env{AWKLIBPATH} environment variable.)
+@node Redirection API
+@subsection Accessing and Manipulating Redirections
+
+The following function allows extensions to access and manipulate redirections.
+
+@table @code
+@item awk_bool_t get_file(const char *name,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ size_t name_len,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const char *filetype,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ int fd,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_input_buf_t **ibufp,
+@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const awk_output_buf_t **obufp);
+Look up a file in @command{gawk}'s internal redirection table.
+If @code{name} is @code{NULL} or @code{name_len} is zero, return
+data for the currently open input file corresponding to @code{FILENAME}.
+(This does not access the @code{filetype} argument, so that may be undefined).
+If the file is not already open, attempt to open it.
+The @code{filetype} argument must be zero-terminated and should be one of:
+
+@table @code
+@item ">"
+A file opened for output.
+
+@item ">>"
+A file opened for append.
+
+@item "<"
+A file opened for input.
+
+@item "|>"
+A pipe opened for output.
+
+@item "|<"
+A pipe opened for input.
+
+@item "|&"
+A two-way coprocess.
+@end table
+
+On error, return a @code{false} value. Otherwise, return
+@code{true}, and return additional information about the redirection
+in the @code{ibufp} and @code{obufp} pointers. For input
+redirections, the @code{*ibufp} value should be non-@code{NULL},
+and @code{*obufp} should be @code{NULL}. For output redirections,
+the @code{*obufp} value should be non-@code{NULL}, and @code{*ibufp}
+should be @code{NULL}. For two-way coprocesses, both values should
+be non-@code{NULL}.
+
+In the usual case, the extension is interested in @code{(*ibufp)->fd}
+and/or @code{fileno((*obufp)->fp)}. If the file is not already
+open, and the @code{fd} argument is non-negative, @command{gawk}
+will use that file descriptor instead of opening the file in the
+usual way. If @code{fd} is non-negative, but the file exists already,
+@command{gawk} ignores @code{fd} and returns the existing file. It is
+the caller's responsibility to notice that neither the @code{fd} in
+the returned @code{awk_input_buf_t} nor the @code{fd} in the returned
+@code{awk_output_buf_t} matches the requested value.
+
+Note that supplying a file descriptor is currently @emph{not} supported
+for pipes. However, supplying a file descriptor should work for input,
+output, append, and two-way (coprocess) sockets. If @code{filetype}
+is two-way, @command{gawk} assumes that it is a socket! Note that in
+the two-way case, the input and output file descriptors may differ.
+To check for success, you must check whether either matches.
+@end table
+
+It is anticipated that this API function will be used to implement I/O
+multiplexing and a socket library.
+
@node Extension API Variables
@subsection API Variables
@@ -33921,11 +34049,16 @@ properly:
# Please set INPLACE_SUFFIX to make a backup copy. For example, you may
# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
+# N.B. We call inplace_end() in the BEGINFILE and END rules so that any
+# actions in an ENDFILE rule will be redirected as expected.
+
BEGINFILE @{
- inplace_begin(FILENAME, INPLACE_SUFFIX)
+ if (_inplace_filename != "")
+ inplace_end(_inplace_filename, INPLACE_SUFFIX)
+ inplace_begin(_inplace_filename = FILENAME, INPLACE_SUFFIX)
@}
-ENDFILE @{
+END @{
inplace_end(FILENAME, INPLACE_SUFFIX)
@}
@end group
@@ -33940,6 +34073,10 @@ If @code{INPLACE_SUFFIX} is not an empty string, the original file is
linked to a backup @value{FN} created by appending that suffix. Finally,
the temporary file is renamed to the original @value{FN}.
+The @code{_inplace_filename} variable serves to keep track of the
+current filename so as to not invoke @code{inplace_end()} before
+processing the first file.
+
If any error occurs, the extension issues a fatal error to terminate
processing immediately without damaging the original file.
@@ -34434,6 +34571,24 @@ Add functions to implement system calls such as @code{chown()},
@code{chmod()}, and @code{umask()} to the file operations extension
presented in @ref{Internal File Ops}.
+@c Idea from comp.lang.awk, February 2015
+@item
+Write an input parser that prints a prompt if the input is
+a from a ``terminal'' device. You can use the @code{isatty()}
+function to tell if the input file is a terminal. (Hint: this function
+is usually expensive to call; try to call it just once.)
+The content of the prompt should come from a variable settable
+by @command{awk}-level code.
+You can write the prompt to stanard error. However,
+for best results, open a new file descriptor (or file pointer)
+on @file{/dev/tty} and print the prompt there, in case standard
+error has been redirected.
+
+Why is standard error a better
+choice than standard output for writing the prompt?
+Which reading mechanism should you replace, the one to get
+a record, or the one to read raw bytes?
+
@item
(Hard.)
How would you provide namespaces in @command{gawk}, so that the
diff --git a/eval.c b/eval.c
index 95ce758c..8ee17615 100644
--- a/eval.c
+++ b/eval.c
@@ -25,7 +25,6 @@
#include "awk.h"
-extern void after_beginfile(IOBUF **curfile);
extern double pow(double x, double y);
extern double modf(double x, double *yp);
extern double fmod(double x, double y);
@@ -1026,6 +1025,7 @@ update_ERRNO_int(int errcode)
{
char *cp;
+ update_PROCINFO_num("errno", errcode);
if (errcode) {
cp = strerror(errcode);
cp = gettext(cp);
@@ -1040,6 +1040,7 @@ update_ERRNO_int(int errcode)
void
update_ERRNO_string(const char *string)
{
+ update_PROCINFO_num("errno", 0);
unref(ERRNO_node->var_value);
ERRNO_node->var_value = make_string(string, strlen(string));
}
@@ -1049,6 +1050,7 @@ update_ERRNO_string(const char *string)
void
unset_ERRNO(void)
{
+ update_PROCINFO_num("errno", 0);
unref(ERRNO_node->var_value);
ERRNO_node->var_value = dupnode(Nnull_string);
}
diff --git a/extension/ChangeLog b/extension/ChangeLog
index b43d6746..9348d745 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,17 @@
+2015-03-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c: Move test for deferred variables here.
+
+2015-03-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * configure: Updated to libtool 2.4.6.
+
+2015-03-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * inplace.3am (SYNOPSIS): Updated to not show the contents
+ of the extension.
+ (BUGS): Removed.
+
2015-03-17 Arnold D. Robbins <arnold@skeeve.com>
* inplace.c (do_inplace_begin): Jump through more hoops to satisfy
@@ -24,6 +38,46 @@
* testext.c (var_test): Adjust for PROCINFO now being there.
+
+2015-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * testext.c (test_deferred): New function to help with testing
+ of deferred variable instantiation.
+ (do_get_file): Remove unused variable array.
+ (func_table): Add test_deferred.
+
+2015-01-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * testext.c (test_get_file): Fix error message.
+ (do_get_file): Implement new function providing low-level access
+ to the get_file API.
+ (func_table): Add "get_file" -> do_get_file.
+ (init_testext): If TESTEXT_QUIET has been set to a numeric value,
+ return quietly.
+
+2015-01-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * testext.c (test_get_file): The get_file hook no longer takes a
+ typelen argument.
+
+2015-01-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ Remove the select extension, since it will be part of gawkextlib.
+ * select.c, siglist.h: Deleted.
+ * Makefile.am (pkgextension_LTLIBRARIES): Remove select.la.
+ (select_la_SOURCES, select_la_LDFLAGS, select_la_LIBADD): Remove.
+ (EXTRA_DIST): Remove siglist.h.
+ * configure.ac (AC_CHECK_HEADERS): Remove signal.h.
+ (AC_CHECK_FUNCS): Remove fcntl, kill, sigaction, and sigprocmask.
+
+2014-12-14 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ Remove the errno extension, since it is now part of gawkextlib.
+ * errno.c, errlist.h: Deleted.
+ * Makefile.am (pkgextension_LTLIBRARIES): Remove errno.la.
+ (errno_la_SOURCES, errno_la_LDFLAGS, errno_la_LIBADD): Remove.
+ (EXTRA_DIST): Remove errlist.h.
+
2014-12-14 Andrew J. Schorr <aschorr@telemetry-investments.com>
* readfile.c (read_file_to_buffer): Do not waste a byte at the end of
@@ -36,6 +90,35 @@
* inplace.c (do_inplace_begin): Jump through hoops to silence
GCC warnings about return value of chown.
+2014-11-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (do_input_fd): New function to return the input file
+ descriptor associated with a file/command.
+ (do_output_fd): New function to return the output file descriptor
+ associated with a file/command.
+ (func_table): Add new functions "input_fd" and "output_fd".
+ * testext.c (test_get_file): Do not use __func__, since it is a C99
+ feature, and gawk does not assume C99.
+
+2014-11-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * errno.c (do_errno2name, do_name2errno): Remove unused variable 'str'.
+ * select.c (do_signal): Remove unused variable 'override'.
+ (grabfd): New helper function to map a gawk file to the appropriate
+ fd for use in the arguments to selectd.
+ (do_select): get_file has 3 new arguments and returns info about both
+ the input and output buf.
+ (do_set_non_blocking): Support changes to get_file API.
+ * testext.c (test_get_file): New test function to check that extension
+ file creation via the get_file API is working.
+
+2014-11-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (set_retry): New function to set PROCINFO[<name>, "RETRY"].
+ (do_set_non_blocking): If called with a file name as opposed to a file
+ descriptor, call the set_retry function to configure PROCINFO to tell
+ io.c to retry I/O for temporary failures.
+
2014-10-12 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (uninstall-so): Remove *.lib too, per suggestion
@@ -207,6 +290,108 @@
* gawkdirfd.h (FAKE_FD_VALUE): Move definition up in the file to give
clean compile on MinGW.
+2013-07-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac (AC_CHECK_FUNCS): Check for fcntl.
+ * select.c (set_non_blocking): Check that fcntl and O_NONBLOCK are
+ available.
+
+2013-07-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (signal_handler): On platforms lacking sigaction, reset
+ the signal handler each time a signal is trapped to protect in case
+ the system resets it to default.
+
+2013-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (signal_result): New function to set result string from
+ signal function and detect when we need to roll back.
+ (do_signal): Now takes an optional 3rd override argument. Instead
+ of returning -1 or 0, we now return information about the previously
+ installed signal handler: default, ignore, trap, or unknown. An
+ empty string is returned on error. If it is an unknown handler,
+ and override is not non-zero, we roll back the handler and return "".
+
+2013-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (set_non_blocking): Do not attempt F_SETFL if F_GETFL fails.
+ (do_set_non_blocking): Add support for case when called with a single
+ "" argument.
+
+2013-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (do_signal): If sigaction is unavailable, fall back to
+ signal and hope that it does the right thing.
+
+2013-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac (AC_CHECK_FUNCS): Add kill and sigprocmask.
+ * select.c (get_signal_number): Change error messages since now may
+ be called by "kill" as well as "select_signal".
+ (do_signal): Add a lint warning if there are more than 2 args.
+ (do_kill): Add new function to send a signal.
+ (do_select): Support platforms where sigprocmask is not available.
+ There will be a race condition on such platforms, but that is not
+ easily avoided.
+
+2013-07-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (do_select): Now that the API flatten_array call has been
+ patched to ensure that the index values are strings, we can remove
+ the code to check for the AWK_NUMBER case.
+
+2013-07-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (do_select): Do not treat a numeric command value as a
+ file descriptor unless the command type is empty.
+
+2013-07-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add errlist.h and siglist.h.
+
+2013-07-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (set_non_blocking): New helper function to call fcntl.
+ (do_set_non_blocking): Add support for the case where there's a single
+ integer fd argument.
+
+2013-07-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * select.c (do_set_non_blocking): Implement new set_non_blocking
+ function.
+ (func_table): Add set_non_blocking.
+
+2013-07-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * errlist.h: New file containing a list of all the errno values I could
+ find.
+ * errno.c: Implement a new errno extension providing strerror,
+ errno2name, and name2errno.
+ * Makefile.am (pkgextension_LTLIBRARIES): Add errno.la.
+ (errno_la_SOURCES, errno_la_LDFLAGS, errno_la_LIBADD): Build new errno
+ extension.
+ * select.c (ext_version): Fix version string.
+ * siglist.h: Update to newest glibc version.
+
+2013-07-01 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * siglist.h: New file copied from glibc to provide a mapping between
+ signal number and name.
+ * select.c: Add a new "select_signal" function and provide support
+ for trapping signals.
+ (do_select): Add support for a 5th argument to contain an array
+ of returned signals. Improve the argument processing, and add
+ better warning messages.
+
+2013-06-30 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (pkgextension_LTLIBRARIES): Add select.la.
+ (select_la_SOURCES, select_la_LDFLAGS, select_la_LIBADD): Build new
+ select extension.
+ * configure.ac (AC_CHECK_HEADERS): Add signal.h.
+ (AC_CHECK_FUNCS): Add sigaction.
+ * select.c: Implement the new select extension.
+
2013-06-10 Arnold D. Robbins <arnold@skeeve.com>
* configure.ac (AC_HEADER_MAJOR): New macro added.
diff --git a/extension/build-aux/ChangeLog b/extension/build-aux/ChangeLog
index 697db607..589d20cc 100644
--- a/extension/build-aux/ChangeLog
+++ b/extension/build-aux/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * config.guess, config.sub, ltmain.sh: Updated, from libtool 2.4.6.
+
2014-04-08 Arnold D. Robbins <arnold@skeeve.com>
* 4.1.1: Release tar ball made.
diff --git a/extension/build-aux/config.guess b/extension/build-aux/config.guess
index 6c32c864..dbfb9786 100755
--- a/extension/build-aux/config.guess
+++ b/extension/build-aux/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2014-11-04'
+timestamp='2015-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
diff --git a/extension/build-aux/config.sub b/extension/build-aux/config.sub
index 7ffe3737..6d2e94c8 100755
--- a/extension/build-aux/config.sub
+++ b/extension/build-aux/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2014-12-03'
+timestamp='2015-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -260,7 +260,7 @@ case $basic_machine in
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
- | fido | fr30 | frv \
+ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
diff --git a/extension/build-aux/ltmain.sh b/extension/build-aux/ltmain.sh
index b8915268..0f0a2da3 100644
--- a/extension/build-aux/ltmain.sh
+++ b/extension/build-aux/ltmain.sh
@@ -2,7 +2,7 @@
## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
## by inline-source v2014-01-03.01
-# libtool (GNU libtool) 2.4.5
+# libtool (GNU libtool) 2.4.6
# Provide generalized library-building support services.
# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
@@ -31,8 +31,8 @@
PROGRAM=libtool
PACKAGE=libtool
-VERSION=2.4.5
-package_revision=2.4.5
+VERSION=2.4.6
+package_revision=2.4.6
## ------ ##
@@ -64,7 +64,7 @@ package_revision=2.4.5
# libraries, which are installed to $pkgauxdir.
# Set a version string for this script.
-scriptversion=2014-01-03.01; # UTC
+scriptversion=2015-01-20.17; # UTC
# General shell script boiler plate, and helper functions.
# Written by Gary V. Vaughan, 2004
@@ -192,7 +192,7 @@ func_path_progs ()
_G_path_prog_max=0
_G_path_prog_found=false
- _G_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
for _G_dir in $_G_PATH; do
IFS=$_G_save_IFS
test -z "$_G_dir" && _G_dir=.
@@ -1977,7 +1977,7 @@ func_version ()
# End:
# Set a version string.
-scriptversion='(GNU libtool) 2.4.5'
+scriptversion='(GNU libtool) 2.4.6'
# func_echo ARG...
@@ -2039,7 +2039,12 @@ usage_message="Options:
"
# Additional text appended to 'usage_message' in response to '--help'.
-long_help_message=$long_help_message"
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message
MODE must be one of the following:
@@ -2063,13 +2068,15 @@ include the following information:
compiler: $LTCC
compiler flags: $LTCFLAGS
linker: $LD (gnu? $with_gnu_ld)
- version: $progname (GNU libtool) 2.4.5
+ version: $progname (GNU libtool) 2.4.6
automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
Report bugs to <bug-libtool@gnu.org>.
GNU libtool home page: <http://www.gnu.org/software/libtool/>.
General help using GNU software: <http://www.gnu.org/gethelp/>."
+ exit 0
+}
# func_lo2o OBJECT-NAME
diff --git a/extension/configure b/extension/configure
index 6818958b..199833f7 100755
--- a/extension/configure
+++ b/extension/configure
@@ -4852,8 +4852,8 @@ esac
-macro_version='2.4.5'
-macro_revision='2.4.5'
+macro_version='2.4.6'
+macro_revision='2.4.6'
@@ -8187,7 +8187,7 @@ func_munge_path_list ()
x)
;;
*:)
- eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \S|@1\"
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
;;
x:*)
eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
@@ -11693,13 +11693,20 @@ if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
fi
-# lt_cv_sys_lib... is unaugmented for libtool script decls...
-lt_cv_sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-# ..but sys_lib_... needs LT_SYS_LIBRARY_PATH munging for
-# LT_SYS_DLSEARCH_PATH macro in ltdl.m4 to work with the correct paths:
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
@@ -13791,7 +13798,8 @@ finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
-lt_cv_sys_lib_dlsearch_path_spec='`$ECHO "$lt_cv_sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
@@ -13909,7 +13917,8 @@ postinstall_cmds \
postuninstall_cmds \
finish_cmds \
sys_lib_search_path_spec \
-lt_cv_sys_lib_dlsearch_path_spec; do
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path; do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[\\\\\\\`\\"\\\$]*)
eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
@@ -14685,7 +14694,7 @@ $as_echo X"$file" |
available_tags=''
# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$LT_SYS_LIBRARY_PATH"}
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
# ### BEGIN LIBTOOL CONFIG
@@ -14936,8 +14945,11 @@ hardcode_into_libs=$hardcode_into_libs
# Compile-time system search path for libraries.
sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-# Run-time system search path for libraries.
-sys_lib_dlsearch_path_spec=$lt_lt_cv_sys_lib_dlsearch_path_spec
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
# Whether dlopen is supported.
dlopen_support=$enable_dlopen
@@ -15089,9 +15101,8 @@ hardcode_action=$hardcode_action
_LT_EOF
cat <<'_LT_EOF' >> "$cfgfile"
-## -------------------------------------- ##
-## Shell functions shared with configure. ##
-## -------------------------------------- ##
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
# func_munge_path_list VARIABLE PATH
# -----------------------------------
@@ -15113,7 +15124,7 @@ func_munge_path_list ()
x)
;;
*:)
- eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \S|@1\"
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
;;
x:*)
eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
@@ -15144,6 +15155,8 @@ func_cc_basename ()
}
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
_LT_EOF
case $host_os in
diff --git a/extension/inplace.3am b/extension/inplace.3am
index d6339c4a..f8fc098f 100644
--- a/extension/inplace.3am
+++ b/extension/inplace.3am
@@ -1,21 +1,10 @@
-.TH INPLACE 3am "Mar 16 2015" "Free Software Foundation" "GNU Awk Extension Modules"
+.TH INPLACE 3am "Mar 18 2015" "Free Software Foundation" "GNU Awk Extension Modules"
.SH NAME
inplace \- emulate sed/perl/ruby in-place editing
.SH SYNOPSIS
.ft CW
.nf
-@load "inplace"
-
-# Please set INPLACE_SUFFIX to make a backup copy. For example, you may
-# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule.
-
-BEGINFILE {
- inplace_begin(FILENAME, INPLACE_SUFFIX)
-}
-
-ENDFILE {
- inplace_end(FILENAME, INPLACE_SUFFIX)
-}
+gawk -i inplace ...
.fi
.ft R
.SH DESCRIPTION
@@ -27,8 +16,7 @@ and
.BR inplace_end() .
These functions are meant to be invoked from the
.I inplace.awk
-wrapper (whose contents are displayed above)
-which is installed when
+wrapper which is installed when
.I gawk
is.
.PP
@@ -45,10 +33,7 @@ extension concatenates that suffix onto the original
filename and uses the result as a filename for renaming
the original.
... .SH NOTES
-.SH BUGS
-As currently written, output from an \f(CWENDFILE\fP
-rule does not get redirected into the replacement file.
-Neither does output from an \f(CWEND\fP rule.
+... .SH BUGS
.SH EXAMPLE
.ft CW
.nf
diff --git a/extension/m4/ChangeLog b/extension/m4/ChangeLog
index f991eac3..6895c6b6 100644
--- a/extension/m4/ChangeLog
+++ b/extension/m4/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * libtoolm4, ltversion.m4: Updated to libtool 2.4.6.
+
2015-01-24 Arnold D. Robbins <arnold@skeeve.com>
* gettext.m4, iconv.m4, intlmacosx.m4, po.m4: Removed.
diff --git a/extension/m4/libtool.m4 b/extension/m4/libtool.m4
index f796d7bc..a3bc337b 100644
--- a/extension/m4/libtool.m4
+++ b/extension/m4/libtool.m4
@@ -738,7 +738,7 @@ _LT_COPYING
_LT_LIBTOOL_TAGS
# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$LT_SYS_LIBRARY_PATH"}
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
# ### BEGIN LIBTOOL CONFIG
_LT_LIBTOOL_CONFIG_VARS
@@ -748,13 +748,14 @@ _LT_LIBTOOL_TAG_VARS
_LT_EOF
cat <<'_LT_EOF' >> "$cfgfile"
-## -------------------------------------- ##
-## Shell functions shared with configure. ##
-## -------------------------------------- ##
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
_LT_PREPARE_MUNGE_PATH_LIST
_LT_PREPARE_CC_BASENAME
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
_LT_EOF
case $host_os in
@@ -2256,7 +2257,7 @@ func_munge_path_list ()
x)
;;
*:)
- eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \$@S|@1\"
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
;;
x:*)
eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
@@ -3100,13 +3101,15 @@ if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
fi
-# lt_cv_sys_lib... is unaugmented for libtool script decls...
-lt_cv_sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-# ..but sys_lib_... needs LT_SYS_LIBRARY_PATH munging for
-# LT_SYS_DLSEARCH_PATH macro in ltdl.m4 to work with the correct paths:
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
_LT_DECL([], [variables_saved_for_relink], [1],
[Variables whose values should be saved in libtool wrapper scripts and
restored at link time])
@@ -3139,8 +3142,10 @@ _LT_DECL([], [hardcode_into_libs], [0],
[Whether we should hardcode library paths into libraries])
_LT_DECL([], [sys_lib_search_path_spec], [2],
[Compile-time system search path for libraries])
-_LT_DECL([sys_lib_dlsearch_path_spec], [lt_cv_sys_lib_dlsearch_path_spec], [2],
- [Run-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+ [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+ [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
])# _LT_SYS_DYNAMIC_LINKER
diff --git a/extension/m4/ltversion.m4 b/extension/m4/ltversion.m4
index a4c5ed43..fa04b52a 100644
--- a/extension/m4/ltversion.m4
+++ b/extension/m4/ltversion.m4
@@ -9,15 +9,15 @@
# @configure_input@
-# serial 4171 ltversion.m4
+# serial 4179 ltversion.m4
# This file is part of GNU Libtool
-m4_define([LT_PACKAGE_VERSION], [2.4.5])
-m4_define([LT_PACKAGE_REVISION], [2.4.5])
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.5'
-macro_revision='2.4.5'
+[macro_version='2.4.6'
+macro_revision='2.4.6'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
diff --git a/extension/testext.c b/extension/testext.c
index 4a1e7032..e2ddbe87 100644
--- a/extension/testext.c
+++ b/extension/testext.c
@@ -37,6 +37,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <fcntl.h>
#include "gawkapi.h"
@@ -374,6 +375,84 @@ out:
}
/*
+ * 3/2015: This test is no longer strictly necessary,
+ * since PROCINFO is no longer a deferred variable.
+ * But we leave it in for safety, anyway.
+ */
+/*
+BEGIN {
+ print "test_deferred returns", test_deferred()
+ print ""
+}
+*/
+static awk_value_t *
+test_deferred(int nargs, awk_value_t *result)
+{
+ awk_value_t arr;
+ awk_value_t index, value;
+ const struct nval {
+ const char *name;
+ double val;
+ } seed[] = {
+ { "fubar", 9.0, },
+ { "rumpus", -5.0, },
+ };
+ struct nval sysval[] = {
+ { "uid", getuid(), },
+ { "api_major", GAWK_API_MAJOR_VERSION, },
+ };
+ size_t i;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 0) {
+ printf("test_deferred: nargs not right (%d should be 0)\n", nargs);
+ goto out;
+ }
+
+ if (! sym_lookup("PROCINFO", AWK_ARRAY, & arr)) {
+ printf("test_deferred: %d: sym_lookup failed\n", __LINE__);
+ goto out;
+ }
+
+ for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) {
+ make_const_string(seed[i].name, strlen(seed[i].name), & index);
+ make_number(seed[i].val, & value);
+ if (! set_array_element(arr.array_cookie, & index, & value)) {
+ printf("test_deferred: %d: set_array_element(%s) failed\n", __LINE__, seed[i].name);
+ goto out;
+ }
+ }
+
+ /* test that it still contains the values we loaded */
+ for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) {
+ make_const_string(seed[i].name, strlen(seed[i].name), & index);
+ make_null_string(& value);
+ if (! get_array_element(arr.array_cookie, &index, AWK_NUMBER, & value)) {
+ printf("test_deferred: %d: get_array_element(%s) failed\n", __LINE__, seed[i].name);
+ goto out;
+ }
+ printf("%s = %g\n", seed[i].name, value.num_value);
+ }
+
+ /* check a few automatically-supplied values */
+ for (i = 0; i < sizeof(sysval)/sizeof(sysval[0]); i++) {
+ make_const_string(sysval[i].name, strlen(sysval[i].name), & index);
+ make_null_string(& value);
+ if (! get_array_element(arr.array_cookie, &index, AWK_NUMBER, & value)) {
+ printf("test_deferred: %d: get_array_element(%s) failed\n", __LINE__, sysval[i].name);
+ goto out;
+ }
+ printf("%s matches %d\n", sysval[i].name, (value.num_value == sysval[i].val));
+ }
+
+ make_number(1.0, result);
+out:
+ return result;
+}
+
+/*
BEGIN {
for (i = 1; i <= 10; i++)
test_array[i] = i + 2
@@ -710,6 +789,7 @@ BEGIN {
ret = test_indirect_vars() # should get correct value of NR
printf("test_indirect_var() return %d\n", ret)
delete ARGV[1]
+ print ""
}
*/
@@ -742,6 +822,124 @@ out:
return result;
}
+/*
+BEGIN {
+ outfile = "testexttmp.txt"
+ alias = ".test.alias"
+ print "line 1" > outfile
+ print "line 2" > outfile
+ print "line 3" > outfile
+ close(outfile)
+ ret = test_get_file(outfile, alias)
+ printf "test_get_file returned %d\n", ret
+ nr = 0
+ while ((getline < alias) > 0)
+ printf "File [%s] nr [%s]: %s\n", alias, ++nr, $0
+ close(alias)
+ system("rm " outfile)
+ print ""
+}
+*/
+
+/* test_get_file --- test that we can create a file */
+
+static awk_value_t *
+test_get_file(int nargs, awk_value_t *result)
+{
+ awk_value_t filename, alias;
+ int fd;
+ const awk_input_buf_t *ibuf;
+ const awk_output_buf_t *obuf;
+
+ if (nargs != 2) {
+ printf("%s: nargs not right (%d should be 2)\n", "test_get_file", nargs);
+ return make_number(-1.0, result);
+ }
+
+ if (! get_argument(0, AWK_STRING, & filename)) {
+ printf("%s: cannot get first arg\n", "test_get_file");
+ return make_number(-1.0, result);
+ }
+ if (! get_argument(1, AWK_STRING, & alias)) {
+ printf("%s: cannot get second arg\n", "test_get_file");
+ return make_number(-1.0, result);
+ }
+ if ((fd = open(filename.str_value.str, O_RDONLY)) < 0) {
+ printf("%s: open(%s) failed\n", "test_get_file", filename.str_value.str);
+ return make_number(-1.0, result);
+ }
+ if (! get_file(alias.str_value.str, strlen(alias.str_value.str), "<", fd, &ibuf, &obuf)) {
+ printf("%s: get_file(%s) failed\n", "test_get_file", alias.str_value.str);
+ return make_number(-1.0, result);
+ }
+ if (! ibuf || ibuf->fd != fd) {
+ printf("%s: get_file(%s) returned fd %d instead of %d\n", "test_get_file", alias.str_value.str, ibuf ? ibuf->fd : -1, fd);
+ return make_number(-1.0, result);
+ }
+ return make_number(0.0, result);
+}
+
+/* do_get_file --- provide access to get_file API */
+
+static awk_value_t *
+do_get_file(int nargs, awk_value_t *result)
+{
+ awk_value_t filename, filetype, fd, res;
+ const awk_input_buf_t *ibuf;
+ const awk_output_buf_t *obuf;
+
+ if (nargs != 4) {
+ printf("%s: nargs not right (%d should be 4)\n", "get_file", nargs);
+ return make_number(-1.0, result);
+ }
+
+ if (! get_argument(0, AWK_STRING, & filename)) {
+ printf("%s: cannot get first arg\n", "get_file");
+ return make_number(-1.0, result);
+ }
+ if (! get_argument(1, AWK_STRING, & filetype)) {
+ printf("%s: cannot get second arg\n", "get_file");
+ return make_number(-1.0, result);
+ }
+ if (! get_argument(2, AWK_NUMBER, & fd)) {
+ printf("%s: cannot get third arg\n", "get_file");
+ return make_number(-1.0, result);
+ }
+ if (! get_argument(3, AWK_ARRAY, & res)) {
+ printf("%s: cannot get fourth arg\n", "get_file");
+ return make_number(-1.0, result);
+ }
+ clear_array(res.array_cookie);
+
+ if (! get_file(filename.str_value.str, strlen(filename.str_value.str), filetype.str_value.str, fd.num_value, &ibuf, &obuf)) {
+ printf("%s: get_file(%s, %s, %d) failed\n", "get_file", filename.str_value.str, filetype.str_value.str, (int)(fd.num_value));
+ return make_number(0.0, result);
+ }
+
+ if (ibuf) {
+ awk_value_t idx, val;
+ set_array_element(res.array_cookie,
+ make_const_string("input", 5, & idx),
+ make_number(ibuf->fd, & val));
+ if (ibuf->name)
+ set_array_element(res.array_cookie,
+ make_const_string("input_name", 10, & idx),
+ make_const_string(ibuf->name, strlen(ibuf->name), & val));
+ }
+ if (obuf) {
+ awk_value_t idx, val;
+ set_array_element(res.array_cookie,
+ make_const_string("output", 6, & idx),
+ make_number(obuf->fp ? fileno(obuf->fp) : -1,
+ & val));
+ if (obuf->name)
+ set_array_element(res.array_cookie,
+ make_const_string("output_name", 11, & idx),
+ make_const_string(obuf->name, strlen(obuf->name), & val));
+ }
+ return make_number(1.0, result);
+}
+
/* fill_in_array --- fill in a new array */
static void
@@ -829,6 +1027,7 @@ static awk_ext_func_t func_table[] = {
{ "dump_array_and_delete", dump_array_and_delete, 2 },
{ "try_modify_environ", try_modify_environ, 0 },
{ "var_test", var_test, 1 },
+ { "test_deferred", test_deferred, 0 },
{ "test_errno", test_errno, 0 },
{ "test_array_size", test_array_size, 1 },
{ "test_array_elem", test_array_elem, 2 },
@@ -837,6 +1036,8 @@ static awk_ext_func_t func_table[] = {
{ "test_scalar", test_scalar, 1 },
{ "test_scalar_reserved", test_scalar_reserved, 0 },
{ "test_indirect_vars", test_indirect_vars, 0 },
+ { "test_get_file", test_get_file, 2 },
+ { "get_file", do_get_file, 4 },
};
/* init_testext --- additional initialization function */
@@ -847,6 +1048,10 @@ static awk_bool_t init_testext(void)
static const char message[] = "hello, world"; /* of course */
static const char message2[] = "i am a scalar";
+ /* This is used by the getfile test */
+ if (sym_lookup("TESTEXT_QUIET", AWK_NUMBER, & value))
+ return awk_true;
+
/* add at_exit functions */
awk_atexit(at_exit0, NULL);
awk_atexit(at_exit1, & data_for_1);
diff --git a/gawkapi.c b/gawkapi.c
index 3b495452..9d8c6f36 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -25,6 +25,11 @@
#include "awk.h"
+/* Declare some globals used by api_get_file: */
+extern IOBUF *curfile;
+extern INSTRUCTION *main_beginfile;
+extern int currule;
+
static awk_bool_t node_to_awk_value(NODE *node, awk_value_t *result, awk_valtype_t wanted);
/*
@@ -783,7 +788,6 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie,
tmp = awk_value_to_node(index);
aptr = assoc_lookup(array, tmp);
- unref(tmp);
unref(*aptr);
elem = *aptr = awk_value_to_node(value);
if (elem->type == Node_var_array) {
@@ -791,6 +795,9 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie,
elem->vname = estrdup(index->str_value.str,
index->str_value.len);
}
+ if (array->astore != NULL)
+ (*array->astore)(array, tmp);
+ unref(tmp);
return awk_true;
}
@@ -1034,6 +1041,99 @@ api_release_value(awk_ext_id_t id, awk_value_cookie_t value)
return awk_true;
}
+/* api_get_file --- return a handle to an existing or newly opened file */
+
+static awk_bool_t
+api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype,
+ int fd, const awk_input_buf_t **ibufp, const awk_output_buf_t **obufp)
+{
+ const struct redirect *f;
+ int flag; /* not used, sigh */
+ enum redirval redirtype;
+
+ if (name == NULL || namelen == 0) {
+ if (curfile == NULL) {
+ INSTRUCTION *pc;
+ int save_rule;
+ char *save_source;
+
+ if (nextfile(& curfile, false) <= 0)
+ return awk_false;
+
+ pc = main_beginfile;
+ /* save execution state */
+ save_rule = currule;
+ save_source = source;
+
+ for (;;) {
+ if (pc == NULL)
+ fatal(_("cannot find end of BEGINFILE rule"));
+ if (pc->opcode == Op_after_beginfile)
+ break;
+ pc = pc->nexti;
+ }
+ pc->opcode = Op_stop;
+ (void) (*interpret)(main_beginfile);
+ pc->opcode = Op_after_beginfile;
+ after_beginfile(& curfile);
+ /* restore execution state */
+ currule = save_rule;
+ source = save_source;
+ }
+ *ibufp = &curfile->public;
+ *obufp = NULL;
+
+ return awk_true;
+ }
+
+ redirtype = redirect_none;
+ switch (filetype[0]) {
+ case '<':
+ if (filetype[1] == '\0')
+ redirtype = redirect_input;
+ break;
+ case '>':
+ switch (filetype[1]) {
+ case '\0':
+ redirtype = redirect_output;
+ break;
+ case '>':
+ if (filetype[2] == '\0')
+ redirtype = redirect_append;
+ break;
+ }
+ break;
+ case '|':
+ if (filetype[2] == '\0') {
+ switch (filetype[1]) {
+ case '>':
+ redirtype = redirect_pipe;
+ break;
+ case '<':
+ redirtype = redirect_pipein;
+ break;
+ case '&':
+ redirtype = redirect_twoway;
+ break;
+ }
+ }
+ break;
+ }
+
+ if (redirtype == redirect_none) {
+ warning(_("cannot open unrecognized file type `%s' for `%s'"),
+ filetype, name);
+ return awk_false;
+ }
+
+ if ((f = redirect_string(name, namelen, 0, redirtype, &flag, fd, false)) == NULL)
+ return awk_false;
+
+ *ibufp = f->iop ? & f->iop->public : NULL;
+ *obufp = f->output.fp ? & f->output : NULL;
+ return awk_true;
+}
+
/*
* Register a version string for this extension with gawk.
*/
@@ -1119,6 +1219,9 @@ gawk_api_t api_impl = {
calloc,
realloc,
free,
+
+ /* Find/open a file */
+ api_get_file,
};
/* init_ext_api --- init the extension API */
diff --git a/gawkapi.h b/gawkapi.h
index aa283c18..c5bb1ea9 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -263,7 +263,7 @@ typedef struct awk_two_way_processor {
/* Current version of the API. */
enum {
GAWK_API_MAJOR_VERSION = 1,
- GAWK_API_MINOR_VERSION = 1
+ GAWK_API_MINOR_VERSION = 2
};
/* A number of typedefs related to different types of values. */
@@ -504,7 +504,7 @@ typedef struct gawk_api {
awk_value_t *result);
/*
- * Convert a paramter that was undefined into an array
+ * Convert a parameter that was undefined into an array
* (provide call-by-reference for arrays). Returns false
* if count is too big, or if the argument's type is
* not undefined.
@@ -674,6 +674,39 @@ typedef struct gawk_api {
void *(*api_calloc)(size_t nmemb, size_t size);
void *(*api_realloc)(void *ptr, size_t size);
void (*api_free)(void *ptr);
+
+ /*
+ * Look up a file. If the name is NULL or name_len is 0, it returns
+ * data for the currently open input file corresponding to FILENAME
+ * (and it will not access the filetype argument, so that may be
+ * undefined).
+ * If the file is not already open, it tries to open it.
+ * The "filetype" argument should be one of:
+ * ">", ">>", "<", "|>", "|<", and "|&"
+ * If the file is not already open, and the fd argument is non-negative,
+ * gawk will use that file descriptor instead of opening the file
+ * in the usual way. If the fd is non-negative, but the file exists
+ * already, gawk ignores the fd and returns the existing file. It is
+ * the caller's responsibility to notice that the fd in the returned
+ * awk_input_buf_t does not match the requested value. Note that
+ * supplying a file descriptor is currently NOT supported for pipes.
+ * It should work for input, output, append, and two-way (coprocess)
+ * sockets. If the filetype is two-way, we assume that it is a socket!
+ * Note that in the two-way case, the input and output file descriptors
+ * may differ. To check for success, one must check that either of
+ * them matches.
+ */
+ awk_bool_t (*api_get_file)(awk_ext_id_t id,
+ const char *name,
+ size_t name_len,
+ const char *filetype,
+ int fd,
+ /*
+ * Return values (on success, one or both should
+ * be non-NULL):
+ */
+ const awk_input_buf_t **ibufp,
+ const awk_output_buf_t **obufp);
} gawk_api_t;
#ifndef GAWK /* these are not for the gawk code itself! */
@@ -756,6 +789,9 @@ typedef struct gawk_api {
#define release_value(value) \
(api->api_release_value(ext_id, value))
+#define get_file(name, namelen, filetype, fd, ibuf, obuf) \
+ (api->api_get_file(ext_id, name, namelen, filetype, fd, ibuf, obuf))
+
#define register_ext_version(version) \
(api->api_register_ext_version(ext_id, version))
diff --git a/interpret.h b/interpret.h
index 665f6faa..cf158ca6 100644
--- a/interpret.h
+++ b/interpret.h
@@ -1314,17 +1314,18 @@ match_re:
fatal(_("`exit' cannot be called in the current context"));
exiting = true;
- t1 = POP_NUMBER();
- exit_val = (int) get_number_si(t1);
- DEREF(t1);
+ if ((t1 = POP_NUMBER()) != Nnull_string) {
+ exit_val = (int) get_number_si(t1);
#ifdef VMS
- if (exit_val == 0)
- exit_val = EXIT_SUCCESS;
- else if (exit_val == 1)
- exit_val = EXIT_FAILURE;
- /* else
- just pass anything else on through */
+ if (exit_val == 0)
+ exit_val = EXIT_SUCCESS;
+ else if (exit_val == 1)
+ exit_val = EXIT_FAILURE;
+ /* else
+ just pass anything else on through */
#endif
+ }
+ DEREF(t1);
if (currule == BEGINFILE || currule == ENDFILE) {
diff --git a/io.c b/io.c
index c3b27f8e..835030c1 100644
--- a/io.c
+++ b/io.c
@@ -271,7 +271,7 @@ static IOBUF *iop_alloc(int fd, const char *name, int errno_val);
static IOBUF *iop_finish(IOBUF *iop);
static int gawk_pclose(struct redirect *rp);
static int str2mode(const char *mode);
-static int two_way_open(const char *str, struct redirect *rp);
+static int two_way_open(const char *str, struct redirect *rp, int extfd);
static int pty_vs_pipe(const char *command);
static void find_input_parser(IOBUF *iop);
static bool find_output_wrapper(awk_output_buf_t *outbuf);
@@ -595,7 +595,8 @@ inrec(IOBUF *iop, int *errcode)
else
cnt = get_a_record(& begin, iop, errcode);
- if (cnt == EOF) {
+ /* Note that get_a_record may return -2 when I/O would block */
+ if (cnt < 0) {
retval = false;
} else {
INCREMENT_REC(NR);
@@ -723,13 +724,13 @@ redflags2str(int flags)
return genflags2str(flags, redtab);
}
-/* redirect --- Redirection for printf and print commands */
+/* redirect_string --- Redirection for printf and print commands, use string info */
struct redirect *
-redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
+redirect_string(const char *str, size_t explen, bool not_string,
+ int redirtype, int *errflg, int extfd, bool failure_fatal)
{
struct redirect *rp;
- char *str;
int tflag = 0;
int outflag = 0;
const char *direction = "to";
@@ -778,18 +779,16 @@ redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
default:
cant_happen();
}
- if (do_lint && (redir_exp->flags & STRCUR) == 0)
+ if (do_lint && not_string)
lintwarn(_("expression in `%s' redirection only has numeric value"),
what);
- redir_exp = force_string(redir_exp);
- str = redir_exp->stptr;
if (str == NULL || *str == '\0')
fatal(_("expression for `%s' redirection has null string value"),
what);
- if (do_lint && (strncmp(str, "0", redir_exp->stlen) == 0
- || strncmp(str, "1", redir_exp->stlen) == 0))
+ if (do_lint && (strncmp(str, "0", explen) == 0
+ || strncmp(str, "1", explen) == 0))
lintwarn(_("filename `%s' for `%s' redirection may be result of logical expression"),
str, what);
@@ -827,8 +826,8 @@ redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
#endif /* PIPES_SIMULATED */
/* now check for a match */
- if (strlen(rp->value) == redir_exp->stlen
- && memcmp(rp->value, str, redir_exp->stlen) == 0
+ if (strlen(rp->value) == explen
+ && memcmp(rp->value, str, explen) == 0
&& ((rp->flag & ~(RED_NOBUF|RED_EOF|RED_PTY)) == tflag
|| (outflag != 0
&& (rp->flag & (RED_FILE|RED_WRITE)) == outflag))) {
@@ -839,23 +838,25 @@ redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
if (do_lint && rpflag != newflag)
lintwarn(
_("unnecessary mixing of `>' and `>>' for file `%.*s'"),
- (int) redir_exp->stlen, rp->value);
+ (int) explen, rp->value);
break;
}
}
if (rp == NULL) {
+ char *newstr;
new_rp = true;
if (save_rp != NULL) {
rp = save_rp;
efree(rp->value);
} else
emalloc(rp, struct redirect *, sizeof(struct redirect), "redirect");
- emalloc(str, char *, redir_exp->stlen + 1, "redirect");
- memcpy(str, redir_exp->stptr, redir_exp->stlen);
- str[redir_exp->stlen] = '\0';
- rp->value = str;
+ emalloc(newstr, char *, explen + 1, "redirect");
+ memcpy(newstr, str, explen);
+ newstr[explen] = '\0';
+ str = newstr;
+ rp->value = newstr;
rp->flag = tflag;
init_output_wrapper(& rp->output);
rp->output.name = str;
@@ -887,6 +888,10 @@ redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
mode = binmode("a");
break;
case redirect_pipe:
+ if (extfd >= 0) {
+ warning(_("get_file cannot create pipe `%s' with fd %d"), str, extfd);
+ return NULL;
+ }
/* synchronize output before new pipe */
(void) flush_io();
@@ -906,6 +911,10 @@ redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
rp->flag |= RED_NOBUF;
break;
case redirect_pipein:
+ if (extfd >= 0) {
+ warning(_("get_file cannot create pipe `%s' with fd %d"), str, extfd);
+ return NULL;
+ }
direction = "from";
if (gawk_popen(str, rp) == NULL)
fatal(_("can't open pipe `%s' for input (%s)"),
@@ -913,7 +922,7 @@ redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
break;
case redirect_input:
direction = "from";
- fd = devopen(str, binmode("r"));
+ fd = (extfd >= 0) ? extfd : devopen(str, binmode("r"));
if (fd == INVALID_HANDLE && errno == EISDIR) {
*errflg = EISDIR;
/* do not free rp, saving it for reuse (save_rp = rp) */
@@ -930,8 +939,14 @@ redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
}
break;
case redirect_twoway:
+#ifndef HAVE_SOCKETS
+ if (extfd >= 0) {
+ warning(_("get_file socket creation not supported on this platform for `%s' with fd %d"), str, extfd);
+ return NULL;
+ }
+#endif
direction = "to/from";
- if (! two_way_open(str, rp)) {
+ if (! two_way_open(str, rp, extfd)) {
if (! failure_fatal || is_non_fatal_redirect(str)) {
*errflg = errno;
/* do not free rp, saving it for reuse (save_rp = rp) */
@@ -948,7 +963,7 @@ redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
if (mode != NULL) {
errno = 0;
rp->output.mode = mode;
- fd = devopen(str, mode);
+ fd = (extfd >= 0) ? extfd : devopen(str, mode);
if (fd > INVALID_HANDLE) {
if (fd == fileno(stdin))
@@ -1050,6 +1065,18 @@ redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
return rp;
}
+/* redirect --- Redirection for printf and print commands */
+
+struct redirect *
+redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal)
+{
+ bool not_string = ((redir_exp->flags & STRCUR) == 0);
+
+ redir_exp = force_string(redir_exp);
+ return redirect_string(redir_exp->stptr, redir_exp->stlen, not_string,
+ redirtype, errflg, -1, failure_fatal);
+}
+
/* getredirect --- find the struct redirect for this file or pipe */
struct redirect *
@@ -1758,16 +1785,16 @@ strictopen:
/* two_way_open --- open a two way communications channel */
static int
-two_way_open(const char *str, struct redirect *rp)
+two_way_open(const char *str, struct redirect *rp, int extfd)
{
static bool no_ptys = false;
#ifdef HAVE_SOCKETS
/* case 1: socket */
- if (inetfile(str, NULL)) {
+ if (extfd >= 0 || inetfile(str, NULL)) {
int fd, newfd;
- fd = devopen(str, "rw");
+ fd = (extfd >= 0) ? extfd : devopen(str, "rw");
if (fd == INVALID_HANDLE)
return false;
if ((BINMODE & BINMODE_OUTPUT) != 0)
@@ -2227,17 +2254,43 @@ use_pipes:
#ifndef PIPES_SIMULATED /* real pipes */
-/* wait_any --- wait for a child process, close associated pipe */
+/*
+ * wait_any --- if the argument pid is 0, wait for all child processes that
+ * have exited. We loop to make sure to reap all children that have exited to
+ * minimize the risk of running out of process slots. Since we don't process
+ * SIGCHLD, we do not immediately reap exited children. So when we get here,
+ * we want to reap any that have piled up.
+ *
+ * Note: on platforms that do not support waitpid with WNOHANG, when called with
+ * a zero argument, this function will hang until all children have exited.
+ *
+ * AJS, 2013-07-07: I do not see why we need to ignore signals during this
+ * function. This function just waits and updates the pid and status fields.
+ * I don't see why that should interfere with any signal handlers. But I am
+ * reluctant to remove this protection. So I changed to use sigprocmask to
+ * block signals instead to avoid interfering with installed signal handlers.
+ */
static int
wait_any(int interesting) /* pid of interest, if any */
{
- RETSIGTYPE (*hstat)(int), (*istat)(int), (*qstat)(int);
int pid;
int status = 0;
struct redirect *redp;
+#ifdef HAVE_SIGPROCMASK
+ sigset_t set, oldset;
+
+ /* I have no idea why we are blocking signals during this function... */
+ sigemptyset(& set);
+ sigaddset(& set, SIGINT);
+ sigaddset(& set, SIGHUP);
+ sigaddset(& set, SIGQUIT);
+ sigprocmask(SIG_BLOCK, & set, & oldset);
+#else
+ RETSIGTYPE (*hstat)(int), (*istat)(int), (*qstat)(int);
istat = signal(SIGINT, SIG_IGN);
+#endif
#ifdef __MINGW32__
if (interesting < 0) {
status = -1;
@@ -2253,11 +2306,22 @@ wait_any(int interesting) /* pid of interest, if any */
break;
}
}
-#else
+#else /* ! __MINGW32__ */
+#ifndef HAVE_SIGPROCMASK
hstat = signal(SIGHUP, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
+#endif
for (;;) {
-# ifdef HAVE_SYS_WAIT_H /* POSIX compatible sys/wait.h */
+# if defined(HAVE_WAITPID) && defined(WNOHANG)
+ /*
+ * N.B. If the caller wants status for a specific child process
+ * (i.e. interesting is non-zero), then we must hang until we
+ * get exit status for that child.
+ */
+ if ((pid = waitpid(-1, & status, (interesting ? 0 : WNOHANG))) == 0)
+ /* No children have exited */
+ break;
+# elif defined(HAVE_SYS_WAIT_H) /* POSIX compatible sys/wait.h */
pid = wait(& status);
# else
pid = wait((union wait *) & status);
@@ -2275,10 +2339,16 @@ wait_any(int interesting) /* pid of interest, if any */
if (pid == -1 && errno == ECHILD)
break;
}
+#ifndef HAVE_SIGPROCMASK
signal(SIGHUP, hstat);
signal(SIGQUIT, qstat);
#endif
+#endif /* ! __MINGW32__ */
+#ifndef HAVE_SIGPROCMASK
signal(SIGINT, istat);
+#else
+ sigprocmask(SIG_SETMASK, & oldset, NULL);
+#endif
return status;
}
@@ -2499,7 +2569,7 @@ do_getline_redir(int into_variable, enum redirval redirtype)
if (errcode != 0) {
if (! do_traditional && (errcode != -1))
update_ERRNO_int(errcode);
- return make_number((AWKNUM) -1.0);
+ return make_number((AWKNUM) cnt);
}
if (cnt == EOF) {
@@ -2549,7 +2619,7 @@ do_getline(int into_variable, IOBUF *iop)
update_ERRNO_int(errcode);
if (into_variable)
(void) POP_ADDRESS();
- return make_number((AWKNUM) -1.0);
+ return make_number((AWKNUM) cnt);
}
if (cnt == EOF)
@@ -3443,10 +3513,45 @@ find_longest_terminator:
return REC_OK;
}
+/* retryable --- return true if PROCINFO[<filename>, "RETRY"] exists */
+
+static inline int
+retryable(IOBUF *iop)
+{
+ return PROCINFO_node && in_PROCINFO(iop->public.name, "RETRY", NULL);
+}
+
+/* errno_io_retry --- Does the I/O error indicate that the operation should be retried later? */
+
+static inline int
+errno_io_retry(void)
+{
+ switch (errno) {
+#ifdef EAGAIN
+ case EAGAIN:
+#endif
+#ifdef EWOULDBLOCK
+#if !defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)
+ case EWOULDBLOCK:
+#endif
+#endif
+#ifdef EINTR
+ case EINTR:
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT:
+#endif
+ return 1;
+ default:
+ return 0;
+ }
+}
+
/*
* get_a_record --- read a record from IOP into out,
* return length of EOF, set RT.
* Note that errcode is never NULL, and the caller initializes *errcode to 0.
+ * If I/O would block, return -2.
*/
static int
@@ -3490,8 +3595,10 @@ get_a_record(char **out, /* pointer to pointer to data */
iop->flag |= IOP_AT_EOF;
return EOF;
} else if (iop->count == -1) {
- iop->flag |= IOP_AT_EOF;
*errcode = errno;
+ if (errno_io_retry() && retryable(iop))
+ return -2;
+ iop->flag |= IOP_AT_EOF;
return EOF;
} else {
iop->dataend = iop->buf + iop->count;
@@ -3565,6 +3672,8 @@ get_a_record(char **out, /* pointer to pointer to data */
iop->count = iop->public.read_func(iop->public.fd, iop->dataend, amt_to_read);
if (iop->count == -1) {
*errcode = errno;
+ if (errno_io_retry() && retryable(iop))
+ return -2;
iop->flag |= IOP_AT_EOF;
break;
} else if (iop->count == 0) {
diff --git a/test/ChangeLog b/test/ChangeLog
index e9848c4b..8aedf6f2 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,21 @@
+2015-03-27 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am: Remove defvar test and reference to files; test
+ code moved into extension/testext.c.
+ * defvar.awk, defvar.ok: Removed.
+ * testext.ok: Updated.
+
+2015-03-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add exitval3.awk and exitval3.ok.
+ (BASIC_TESTS): Add new test exitval3.
+ * exitval3.awk, exitval3.ok: New files.
+
+2015-03-17 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * inplace1.ok, inplace2.ok, inplace3.ok: Update error message line
+ numbers to reflect changes to inplace.awk.
+
2015-03-17 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (mpfrmemok1): New test.
@@ -107,6 +125,34 @@
* testext.ok: Adjust for code changes.
+2015-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add defvar.awk and defvar.ok.
+ (SHLIB_TESTS): Add defvar.
+ (defvar): New test.
+ * defvar.awk, defvar.ok: New files.
+
+2015-01-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add getfile.awk and getfile.ok.
+ (SHLIB_TESTS): Add getfile.
+ (getfile): New test.
+ * getfile.awk, getfile.ok: New files.
+
+2015-01-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add timeout.awk and timeout.ok.
+ (BASIC_TESTS): Remove errno.
+ (GAWK_EXT_TESTS): Add errno and timeout.
+ * timeout.awk, timeout.ok: New files.
+
+2015-01-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * Makefile.am (EXTRA_DIST): Add errno.awk, errno.in, and errno.ok.
+ (BASIC_TESTS): Add errno.
+ (errno): New test.
+ * errno.awk, errno.in, errno.ok: New files.
+
2014-12-24 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (badbuild): New test.
@@ -141,6 +187,10 @@
* mbprintf4.awk: Add record and line number for debugging.
* mpprint4.ok: Adjust.
+2014-11-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * testext.ok: Add results from new test_get_file test.
+
2014-11-02 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (profile7): New test.
diff --git a/test/Makefile.am b/test/Makefile.am
index d2cd0ddd..788fff5e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -212,6 +212,9 @@ EXTRA_DIST = \
dynlj.ok \
eofsplit.awk \
eofsplit.ok \
+ errno.awk \
+ errno.in \
+ errno.ok \
exit.ok \
exit.sh \
exit2.awk \
@@ -221,6 +224,8 @@ EXTRA_DIST = \
exitval2.awk \
exitval2.ok \
exitval2.w32 \
+ exitval3.awk \
+ exitval3.ok \
fcall_exit.awk \
fcall_exit.ok \
fcall_exit2.awk \
@@ -340,6 +345,8 @@ EXTRA_DIST = \
gensub.ok \
gensub2.awk \
gensub2.ok \
+ getfile.awk \
+ getfile.ok \
getline.awk \
getline.in \
getline.ok \
@@ -948,6 +955,8 @@ EXTRA_DIST = \
testext.ok \
time.awk \
time.ok \
+ timeout.awk \
+ timeout.ok \
tradanch.awk \
tradanch.in \
tradanch.ok \
@@ -1011,7 +1020,7 @@ BASIC_TESTS = \
callparam childin clobber closebad clsflnam compare compare2 concat1 concat2 \
concat3 concat4 convfmt \
datanonl defref delargv delarpm2 delarprm delfunc dfamb1 dfastress dynlj \
- eofsplit exit2 exitval1 exitval2 \
+ eofsplit exit2 exitval1 exitval2 exitval3 \
fcall_exit fcall_exit2 fldchg fldchgnf fnamedat fnarray fnarray2 \
fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fsrs fsspcoln \
fstabplus funsemnl funsmnam funstack \
@@ -1047,7 +1056,7 @@ UNIX_TESTS = \
GAWK_EXT_TESTS = \
aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \
backw badargs beginfile1 beginfile2 binmode1 charasbytes \
- colonwarn clos1way crlf dbugeval delsub devfd devfd1 devfd2 dumpvars exit \
+ colonwarn clos1way crlf dbugeval delsub devfd devfd1 devfd2 dumpvars errno exit \
fieldwdth fpat1 fpat2 fpat3 fpat4 fpatnull fsfwfs funlen \
functab1 functab2 functab3 fwtest fwtest2 fwtest3 \
genpot gensub gensub2 getlndir gnuops2 gnuops3 gnureops \
@@ -1065,7 +1074,8 @@ GAWK_EXT_TESTS = \
rsstart2 rsstart3 rstest6 shadow sortfor sortu split_after_fpat \
splitarg4 strftime \
strtonum switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \
- symtab7 symtab8 symtab9
+ symtab7 symtab8 symtab9 \
+ timeout
EXTRA_TESTS = inftest regtest
@@ -1082,7 +1092,7 @@ LOCALE_CHARSET_TESTS = \
mbprintf1 mbprintf2 mbprintf3 mbprintf4 rebt8b2 rtlenmb sort1 sprintfc
SHLIB_TESTS = \
- fnmatch filefuncs fork fork2 fts functab4 inplace1 inplace2 inplace3 \
+ fnmatch filefuncs fork fork2 fts functab4 getfile inplace1 inplace2 inplace3 \
ordchr ordchr2 readdir readfile readfile2 revout revtwoway rwarray testext time
# List of the tests which should be run with --lint option:
@@ -1341,6 +1351,11 @@ devfd::
@$(AWK) 1 /dev/fd/4 /dev/fd/5 4<"$(srcdir)"/devfd.in4 5<"$(srcdir)"/devfd.in5 >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+errno:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
fflush::
@echo $@
@"$(srcdir)"/fflush.sh >_$@
@@ -1934,6 +1949,11 @@ testext::
@$(AWK) -f ./testext.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ testext.awk
+getfile:
+ @echo $@
+ @$(AWK) -v TESTEXT_QUIET=1 -ltestext -f $(srcdir)/$@.awk $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
readdir:
@if [ "`uname`" = Linux ] && [ "`stat -f . 2>/dev/null | awk 'NR == 2 { print $$NF }'`" = nfs ]; then \
echo This test may fail on GNU/Linux systems when run on an NFS filesystem.; \
diff --git a/test/Makefile.in b/test/Makefile.in
index cf8093b8..ad27412a 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -469,6 +469,9 @@ EXTRA_DIST = \
dynlj.ok \
eofsplit.awk \
eofsplit.ok \
+ errno.awk \
+ errno.in \
+ errno.ok \
exit.ok \
exit.sh \
exit2.awk \
@@ -478,6 +481,8 @@ EXTRA_DIST = \
exitval2.awk \
exitval2.ok \
exitval2.w32 \
+ exitval3.awk \
+ exitval3.ok \
fcall_exit.awk \
fcall_exit.ok \
fcall_exit2.awk \
@@ -597,6 +602,8 @@ EXTRA_DIST = \
gensub.ok \
gensub2.awk \
gensub2.ok \
+ getfile.awk \
+ getfile.ok \
getline.awk \
getline.in \
getline.ok \
@@ -1205,6 +1212,8 @@ EXTRA_DIST = \
testext.ok \
time.awk \
time.ok \
+ timeout.awk \
+ timeout.ok \
tradanch.awk \
tradanch.in \
tradanch.ok \
@@ -1267,7 +1276,7 @@ BASIC_TESTS = \
callparam childin clobber closebad clsflnam compare compare2 concat1 concat2 \
concat3 concat4 convfmt \
datanonl defref delargv delarpm2 delarprm delfunc dfamb1 dfastress dynlj \
- eofsplit exit2 exitval1 exitval2 \
+ eofsplit exit2 exitval1 exitval2 exitval3 \
fcall_exit fcall_exit2 fldchg fldchgnf fnamedat fnarray fnarray2 \
fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fsrs fsspcoln \
fstabplus funsemnl funsmnam funstack \
@@ -1303,7 +1312,7 @@ UNIX_TESTS = \
GAWK_EXT_TESTS = \
aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \
backw badargs beginfile1 beginfile2 binmode1 charasbytes \
- colonwarn clos1way crlf dbugeval delsub devfd devfd1 devfd2 dumpvars exit \
+ colonwarn clos1way crlf dbugeval delsub devfd devfd1 devfd2 dumpvars errno exit \
fieldwdth fpat1 fpat2 fpat3 fpat4 fpatnull fsfwfs funlen \
functab1 functab2 functab3 fwtest fwtest2 fwtest3 \
genpot gensub gensub2 getlndir gnuops2 gnuops3 gnureops \
@@ -1321,7 +1330,8 @@ GAWK_EXT_TESTS = \
rsstart2 rsstart3 rstest6 shadow sortfor sortu split_after_fpat \
splitarg4 strftime \
strtonum switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \
- symtab7 symtab8 symtab9
+ symtab7 symtab8 symtab9 \
+ timeout
EXTRA_TESTS = inftest regtest
INET_TESTS = inetdayu inetdayt inetechu inetecht
@@ -1335,7 +1345,7 @@ LOCALE_CHARSET_TESTS = \
mbprintf1 mbprintf2 mbprintf3 mbprintf4 rebt8b2 rtlenmb sort1 sprintfc
SHLIB_TESTS = \
- fnmatch filefuncs fork fork2 fts functab4 inplace1 inplace2 inplace3 \
+ fnmatch filefuncs fork fork2 fts functab4 getfile inplace1 inplace2 inplace3 \
ordchr ordchr2 readdir readfile readfile2 revout revtwoway rwarray testext time
@@ -1779,6 +1789,11 @@ devfd::
@$(AWK) 1 /dev/fd/4 /dev/fd/5 4<"$(srcdir)"/devfd.in4 5<"$(srcdir)"/devfd.in5 >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+errno:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
fflush::
@echo $@
@"$(srcdir)"/fflush.sh >_$@
@@ -2371,6 +2386,11 @@ testext::
@$(AWK) -f ./testext.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ testext.awk
+getfile:
+ @echo $@
+ @$(AWK) -v TESTEXT_QUIET=1 -ltestext -f $(srcdir)/$@.awk $(srcdir)/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
readdir:
@if [ "`uname`" = Linux ] && [ "`stat -f . 2>/dev/null | awk 'NR == 2 { print $$NF }'`" = nfs ]; then \
echo This test may fail on GNU/Linux systems when run on an NFS filesystem.; \
@@ -2730,6 +2750,11 @@ exitval2:
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+exitval3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
fcall_exit:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@@ -3797,6 +3822,11 @@ symtab7:
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+timeout:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
double1:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/Maketests b/test/Maketests
index 5011fb1f..f3d048ed 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -230,6 +230,11 @@ exitval2:
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+exitval3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
fcall_exit:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@@ -1297,6 +1302,11 @@ symtab7:
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+timeout:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
double1:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/errno.awk b/test/errno.awk
new file mode 100644
index 00000000..bcb77614
--- /dev/null
+++ b/test/errno.awk
@@ -0,0 +1,10 @@
+BEGIN {
+ # check that PROCINFO["errno"] is working properly
+ getline
+ if (close(FILENAME)) {
+ print "Error `" ERRNO "' closing input file"
+ print "errno =", PROCINFO["errno"]
+ }
+ getline < (FILENAME "/bogus")
+ print (PROCINFO["errno"] > 0), ERRNO
+}
diff --git a/test/errno.in b/test/errno.in
new file mode 100644
index 00000000..a92d664b
--- /dev/null
+++ b/test/errno.in
@@ -0,0 +1,3 @@
+line 1
+line 2
+line 3
diff --git a/test/errno.ok b/test/errno.ok
new file mode 100644
index 00000000..181afdaf
--- /dev/null
+++ b/test/errno.ok
@@ -0,0 +1,3 @@
+Error `close of redirection that was never opened' closing input file
+errno = 0
+1 Not a directory
diff --git a/test/exitval3.awk b/test/exitval3.awk
new file mode 100644
index 00000000..33e8c433
--- /dev/null
+++ b/test/exitval3.awk
@@ -0,0 +1,2 @@
+BEGIN { exit 42 }
+END { exit }
diff --git a/test/exitval3.ok b/test/exitval3.ok
new file mode 100644
index 00000000..20f64b8c
--- /dev/null
+++ b/test/exitval3.ok
@@ -0,0 +1 @@
+EXIT CODE: 42
diff --git a/test/getfile.awk b/test/getfile.awk
new file mode 100644
index 00000000..6ee783f6
--- /dev/null
+++ b/test/getfile.awk
@@ -0,0 +1,35 @@
+function basename(x) {
+ return gensub(/^.*\//, "", 1, x)
+}
+
+BEGIN {
+ print "BEGIN"
+
+ cmd = "echo hello; echo goodbye"
+ rc = get_file(cmd, "<<", -1, res)
+ print "expected error result", rc, ERRNO
+ print "get_file returned", get_file(cmd, "|<", -1, res)
+ print "input_name", basename(res["input_name"])
+ print (cmd | getline x)
+ print x
+
+ # check that calling get_file on "" triggers the BEGINFILE rule
+ print "get_file returned", get_file("", "", -1, res)
+ print "input_name", basename(res["input_name"])
+ print "end BEGIN"
+}
+
+BEGINFILE {
+ printf "BEGINFILE (%s) ERRNO (%s)\n", basename(FILENAME), ERRNO
+}
+
+ENDFILE {
+ printf "ENDFILE (%s) ERRNO (%s)\n", basename(FILENAME), ERRNO
+}
+
+END {
+ print "END"
+ print (cmd | getline x)
+ print x
+ print close(cmd)
+}
diff --git a/test/getfile.ok b/test/getfile.ok
new file mode 100644
index 00000000..92c915f2
--- /dev/null
+++ b/test/getfile.ok
@@ -0,0 +1,17 @@
+BEGIN
+gawk: ./getfile.awk:9: warning: cannot open unrecognized file type `<<' for `echo hello; echo goodbye'
+get_file: get_file(echo hello; echo goodbye, <<, -1) failed
+expected error result 0
+get_file returned 1
+input_name echo hello; echo goodbye
+1
+hello
+BEGINFILE (getfile.awk) ERRNO ()
+get_file returned 1
+input_name getfile.awk
+end BEGIN
+ENDFILE (getfile.awk) ERRNO ()
+END
+1
+goodbye
+0
diff --git a/test/inplace1.ok b/test/inplace1.ok
index ffcb768d..82562235 100644
--- a/test/inplace1.ok
+++ b/test/inplace1.ok
@@ -1,5 +1,5 @@
before
-gawk: inplace:9: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
+gawk: inplace:14: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
stdin start
is bar replaced?
stdin end
diff --git a/test/inplace2.ok b/test/inplace2.ok
index ffcb768d..82562235 100644
--- a/test/inplace2.ok
+++ b/test/inplace2.ok
@@ -1,5 +1,5 @@
before
-gawk: inplace:9: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
+gawk: inplace:14: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
stdin start
is bar replaced?
stdin end
diff --git a/test/inplace3.ok b/test/inplace3.ok
index 7cd960bc..a7b7254f 100644
--- a/test/inplace3.ok
+++ b/test/inplace3.ok
@@ -1,11 +1,11 @@
before
-gawk: inplace:9: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
+gawk: inplace:14: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
stdin start
is bar replaced?
stdin end
after
Before
-gawk: inplace:9: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
+gawk: inplace:14: warning: inplace_begin: disabling in-place editing for invalid FILENAME `-'
stdin start
is foo replaced?
stdin end
diff --git a/test/testext.ok b/test/testext.ok
index a828ecb2..897a7336 100644
--- a/test/testext.ok
+++ b/test/testext.ok
@@ -23,6 +23,12 @@ var_test() returned 1, test_var = 42
test_errno() returned 1, ERRNO = No child processes
+fubar = 9
+rumpus = -5
+uid matches 1
+api_major matches 1
+test_deferred returns 1
+
length of test_array is 10, should be 10
test_array_size: incoming size is 10
test_array_size() returned 1, length is now 0
@@ -69,6 +75,12 @@ test_scalar_reserved: could not update new_value2 for ARGC - pass
test_indirect_var: sym_lookup of NR passed
test_indirect_var: value of NR is 3
test_indirect_var() return 1
+
+test_get_file returned 0
+File [.test.alias] nr [1]: line 1
+File [.test.alias] nr [2]: line 2
+File [.test.alias] nr [3]: line 3
+
answer_num = 42
message_string = hello, world
new_array["hello"] = "world"
diff --git a/test/timeout.awk b/test/timeout.awk
new file mode 100644
index 00000000..ccf4537d
--- /dev/null
+++ b/test/timeout.awk
@@ -0,0 +1,26 @@
+BEGIN {
+ cmd = "echo hello; sleep 1; echo goodbye"
+
+ print "With timeouts"
+ PROCINFO[cmd, "READ_TIMEOUT"] = 300
+ while ((rc = (cmd | getline x)) > 0)
+ print x
+ if (rc < 0)
+ print rc, (PROCINFO["errno"] != 0), (ERRNO != "")
+ print (close(cmd) != 0)
+
+ PROCINFO[cmd, "RETRY"]
+ print ""
+ print "With timeouts and retries"
+ while (((rc = (cmd | getline x)) > 0) || (rc == -2)) {
+ if (rc > 0) {
+ print x
+ n = 0
+ }
+ else
+ print ++n, "timed out; trying again"
+ }
+ if (rc < 0)
+ print rc, (PROCINFO["errno"] != 0), (ERRNO != "")
+ print (close(cmd) != 0)
+}
diff --git a/test/timeout.ok b/test/timeout.ok
new file mode 100644
index 00000000..a388747b
--- /dev/null
+++ b/test/timeout.ok
@@ -0,0 +1,12 @@
+With timeouts
+hello
+-1 1 1
+1
+
+With timeouts and retries
+hello
+1 timed out; trying again
+2 timed out; trying again
+3 timed out; trying again
+goodbye
+0