aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog94
-rw-r--r--awk.h11
-rw-r--r--awkgram.c670
-rw-r--r--awkgram.y16
-rw-r--r--builtin.c9
-rw-r--r--doc/ChangeLog26
-rw-r--r--doc/gawk.info365
-rw-r--r--doc/gawk.texi115
-rw-r--r--doc/gawktexi.in115
-rw-r--r--extension/ChangeLog20
-rw-r--r--extension/rwarray.c42
-rw-r--r--extension/testext.c2
-rw-r--r--gawkapi.c229
-rw-r--r--gawkapi.h111
-rw-r--r--node.c21
-rw-r--r--test/ChangeLog14
-rw-r--r--test/rwarray.awk16
17 files changed, 1218 insertions, 658 deletions
diff --git a/ChangeLog b/ChangeLog
index 277e467f..b1aa2d30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -26,6 +26,19 @@
regcomp.c, regex.c, regex.h, regex_internal.c, regex_internal.h,
regexec.c, verify.h, xalloc.h: Moved to support.
+ Unrelated: Totally break binary compatibility in the API
+ after merging in API min/max changes and REGEX and STRNUM
+ support in the API:
+
+ * gawkapi.c (valtype2str): New function.
+ (node_to_awk_value): Minor simplification in a switch.
+ (api_flatten_array): Removed.
+ (api_flatten_array_typed): Use valtype2str in error message.
+ (api_impl): Reorder functions to group related ones together again.
+ * gawkapi.h (awk_valtype_t): Reorder enum values.
+ (struct gawk_api): Remove api_flatten_array field. Reorder
+ functions to group related ones together again.
+
2016-12-17 Arnold D. Robbins <arnold@skeeve.com>
* gawkapi.h (api_add_ext_func): Add comment about point to
@@ -73,6 +86,57 @@
* dfa.c: Sync with GNULIB.
+2016-12-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ Add API support for strnum values.
+ * gawkapi.c (awk_value_to_node): Add AWK_STRNUM.
+ (assign_string): Add a type argument so we can use this for AWK_STRING
+ or AWK_STRNUM.
+ (node_to_awk_value): When AWK_NUMBER is requested, a regex value
+ should return false, as per the header file documentation.
+ Add support for AWK_STRNUM requests. When AWK_REGEX is requested,
+ implement the cases properly instead of always returning true.
+ Fix AWK_SCALAR logic. For AWK_UNDEFINED, rewrite using a switch
+ and support AWK_STRNUM.
+ (api_sym_update): Add AWK_STRNUM.
+ (api_sym_update_scalar): Add optimized support for updating AWK_STRNUM.
+ (valid_subscript_type): Add AWK_STRNUM.
+ (api_create_value): Add AWK_STRNUM.
+ * gawkapi.h (awk_valtype_t): Add AWK_STRNUM.
+ (strnum_value): New macro.
+ (Value fetching table): Updated.
+
+2016-12-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.c (assign_regex): Do not call assign_string, since we
+ know that a REGEX value is not an unterminated field string.
+ * gawkapi.h (make_regex): Delete macro.
+ (make_const_regex, make_malloced_regex): Add new macros to replace
+ make_regex with necessary memory management support.
+
+2016-12-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awk.h (fixtype): Remove conditional checking if the node type
+ is Node_val. This is already covered by the assert, and if it's not
+ true, we have serious bugs.
+ * builtin.c (do_typeof): Do not treat Node_var the same way as
+ Node_val, since they are different beasts. In reality, the argument
+ to this function will never have type Node_var.
+
+2016-12-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h (awk_element_t): Remove obsolete comment claiming that
+ the index will always be a string.
+ (gawk_api_t): Add new api_flatten_array_typed function and indicate
+ that api_flatten_array has been superseded.
+ (flatten_array_typed): New macro to call api_flatten_array_typed.
+ (flatten_array): Redefine using the new flatten_array_typed macro.
+ * gawkapi.c (api_flatten_array_typed): New function renamed from
+ api_flatten_array to flatten an array with the types requested by the
+ caller. Also update the comments and error messages.
+ (api_flatten_array): Now a wrapper around api_flatten_array_typed.
+ (api_impl): Add new api_flatten_array_typed hook.
+
2016-12-06 Arnold D. Robbins <arnold@skeeve.com>
Add minimum required and maximum expected number of arguments
@@ -87,10 +151,40 @@
in instructions. Add checking code and lint checks.
(Op_ext_func): Copy min_required and max_expected from function info.
+
+2016-12-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h (r_make_string_type): New inline function to create strings
+ of any type, currently AWK_STRING or AWK_REGEX.
+ (r_make_string): Now a wrapper around r_make_string_type.
+ (make_regex): Convert from an inline function to a macro that
+ calls r_make_string_type.
+
2016-11-30 Arnold D. Robbins <arnold@skeeve.com>
* dfa.c: Sync with fixes in GNULIB.
+ Unrelated:
+
+ * gawkapi.h (make_regex): New function.
+
+2016-11-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ Add support for typed regex variables to the API.
+
+ * awk.h (make_typed_regex): Declare function.
+ * awkgram.y (typed_regexp): Call make_typed_regex instead of
+ using inline code.
+ * gawkapi.h (AWK_REGEX): New value type.
+ (regex_value): New macro.
+ (Value fetching table): Updated.
+ * gawkapi.c (awk_value_to_node, node_to_awk_value, api_sym_update,
+ api_sym_update_scalar, valid_subscript_type, api_create_value):
+ Add support for AWK_REGEX.
+ (assign_regex): New function.
+ (api_flatten_array): Adjust comment.
+ * node.c (make_typed_regex): New function; moved code from grammar.
+
2016-11-29 Arnold D. Robbins <arnold@skeeve.com>
Remove redundant flag from dfa:
diff --git a/awk.h b/awk.h
index 854eceaf..278f54c5 100644
--- a/awk.h
+++ b/awk.h
@@ -1641,6 +1641,7 @@ extern NODE *r_force_number(NODE *n);
extern NODE *r_format_val(const char *format, int index, NODE *s);
extern NODE *r_dupnode(NODE *n);
extern NODE *make_str_node(const char *s, size_t len, int flags);
+extern NODE *make_typed_regex(const char *re, size_t len);
extern void *more_blocks(int id);
extern int parse_escape(const char **string_ptr);
extern NODE *str2wstr(NODE *n, size_t **ptr);
@@ -1886,12 +1887,10 @@ static inline NODE *
fixtype(NODE *n)
{
assert(n->type == Node_val);
- if (n->type == Node_val) {
- if ((n->flags & (NUMCUR|USER_INPUT)) == USER_INPUT)
- return force_number(n);
- if ((n->flags & INTIND) != 0)
- return force_string(n);
- }
+ if ((n->flags & (NUMCUR|USER_INPUT)) == USER_INPUT)
+ return force_number(n);
+ if ((n->flags & INTIND) != 0)
+ return force_string(n);
return n;
}
diff --git a/awkgram.c b/awkgram.c
index 0554dc22..2f0f7283 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -673,24 +673,24 @@ static const yytype_uint16 yyrline[] =
0, 215, 215, 217, 222, 223, 227, 239, 244, 255,
262, 268, 277, 285, 287, 292, 300, 302, 308, 316,
326, 356, 370, 384, 392, 403, 415, 417, 419, 425,
- 433, 434, 438, 438, 484, 483, 517, 546, 548, 553,
- 563, 610, 615, 616, 620, 636, 638, 640, 647, 738,
- 780, 822, 935, 942, 949, 960, 970, 980, 990, 1002,
- 1019, 1018, 1043, 1055, 1055, 1154, 1154, 1188, 1219, 1228,
- 1229, 1235, 1236, 1243, 1248, 1260, 1274, 1276, 1284, 1291,
- 1293, 1301, 1310, 1312, 1321, 1322, 1330, 1335, 1335, 1346,
- 1350, 1358, 1359, 1362, 1364, 1369, 1370, 1379, 1380, 1385,
- 1390, 1399, 1401, 1403, 1410, 1411, 1417, 1418, 1423, 1425,
- 1430, 1432, 1440, 1445, 1454, 1455, 1460, 1462, 1467, 1469,
- 1477, 1482, 1490, 1491, 1496, 1503, 1507, 1509, 1511, 1524,
- 1541, 1551, 1558, 1560, 1565, 1567, 1569, 1577, 1579, 1584,
- 1586, 1591, 1593, 1595, 1651, 1653, 1655, 1657, 1659, 1661,
- 1663, 1665, 1679, 1684, 1689, 1714, 1720, 1722, 1724, 1726,
- 1728, 1730, 1735, 1739, 1771, 1773, 1779, 1785, 1798, 1799,
- 1800, 1805, 1810, 1814, 1818, 1833, 1854, 1859, 1896, 1925,
- 1926, 1932, 1933, 1938, 1940, 1947, 1964, 1981, 1983, 1990,
- 1995, 2003, 2013, 2025, 2034, 2038, 2042, 2046, 2050, 2054,
- 2057, 2059, 2063, 2067, 2071
+ 433, 434, 438, 438, 484, 483, 517, 532, 534, 539,
+ 549, 596, 601, 602, 606, 622, 624, 626, 633, 724,
+ 766, 808, 921, 928, 935, 946, 956, 966, 976, 988,
+ 1005, 1004, 1029, 1041, 1041, 1140, 1140, 1174, 1205, 1214,
+ 1215, 1221, 1222, 1229, 1234, 1246, 1260, 1262, 1270, 1277,
+ 1279, 1287, 1296, 1298, 1307, 1308, 1316, 1321, 1321, 1332,
+ 1336, 1344, 1345, 1348, 1350, 1355, 1356, 1365, 1366, 1371,
+ 1376, 1385, 1387, 1389, 1396, 1397, 1403, 1404, 1409, 1411,
+ 1416, 1418, 1426, 1431, 1440, 1441, 1446, 1448, 1453, 1455,
+ 1463, 1468, 1476, 1477, 1482, 1489, 1493, 1495, 1497, 1510,
+ 1527, 1537, 1544, 1546, 1551, 1553, 1555, 1563, 1565, 1570,
+ 1572, 1577, 1579, 1581, 1637, 1639, 1641, 1643, 1645, 1647,
+ 1649, 1651, 1665, 1670, 1675, 1700, 1706, 1708, 1710, 1712,
+ 1714, 1716, 1721, 1725, 1757, 1759, 1765, 1771, 1784, 1785,
+ 1786, 1791, 1796, 1800, 1804, 1819, 1840, 1845, 1882, 1911,
+ 1912, 1918, 1919, 1924, 1926, 1933, 1950, 1967, 1969, 1976,
+ 1981, 1989, 1999, 2011, 2020, 2024, 2028, 2032, 2036, 2040,
+ 2043, 2045, 2049, 2053, 2057
};
#endif
@@ -2281,7 +2281,6 @@ yyreduce:
case 36:
#line 518 "awkgram.y" /* yacc.c:1646 */
{
- NODE *n, *exp, *n2;
char *re;
size_t len;
@@ -2289,34 +2288,21 @@ yyreduce:
(yyvsp[0])->lextok = NULL;
len = strlen(re);
- exp = make_str_node(re, len, ALREADY_MALLOCED);
- n = make_regnode(Node_regex, exp);
- if (n == NULL) {
- unref(exp);
- YYABORT;
- }
-
- n2 = make_string(re, len);
- n2->typed_re = n;
- n2->numbr = 0;
- n2->flags |= NUMCUR|STRCUR|REGEX;
- n2->flags &= ~(STRING|NUMBER);
-
(yyval) = (yyvsp[0]);
(yyval)->opcode = Op_push_re;
- (yyval)->memory = n2;
+ (yyval)->memory = make_typed_regex(re, len);
}
-#line 2310 "awkgram.c" /* yacc.c:1646 */
+#line 2296 "awkgram.c" /* yacc.c:1646 */
break;
case 37:
-#line 547 "awkgram.y" /* yacc.c:1646 */
+#line 533 "awkgram.y" /* yacc.c:1646 */
{ bcfree((yyvsp[0])); }
-#line 2316 "awkgram.c" /* yacc.c:1646 */
+#line 2302 "awkgram.c" /* yacc.c:1646 */
break;
case 39:
-#line 553 "awkgram.y" /* yacc.c:1646 */
+#line 539 "awkgram.y" /* yacc.c:1646 */
{
if (prior_comment != NULL) {
(yyval) = list_create(prior_comment);
@@ -2327,11 +2313,11 @@ yyreduce:
} else
(yyval) = NULL;
}
-#line 2331 "awkgram.c" /* yacc.c:1646 */
+#line 2317 "awkgram.c" /* yacc.c:1646 */
break;
case 40:
-#line 564 "awkgram.y" /* yacc.c:1646 */
+#line 550 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[0]) == NULL) {
if (prior_comment != NULL) {
@@ -2378,17 +2364,17 @@ yyreduce:
}
yyerrok;
}
-#line 2382 "awkgram.c" /* yacc.c:1646 */
+#line 2368 "awkgram.c" /* yacc.c:1646 */
break;
case 41:
-#line 611 "awkgram.y" /* yacc.c:1646 */
+#line 597 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 2388 "awkgram.c" /* yacc.c:1646 */
+#line 2374 "awkgram.c" /* yacc.c:1646 */
break;
case 44:
-#line 621 "awkgram.y" /* yacc.c:1646 */
+#line 607 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *ip;
@@ -2401,34 +2387,34 @@ yyreduce:
$1 is NULL */
(yyval) = ip;
}
-#line 2405 "awkgram.c" /* yacc.c:1646 */
+#line 2391 "awkgram.c" /* yacc.c:1646 */
break;
case 45:
-#line 637 "awkgram.y" /* yacc.c:1646 */
+#line 623 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 2411 "awkgram.c" /* yacc.c:1646 */
+#line 2397 "awkgram.c" /* yacc.c:1646 */
break;
case 46:
-#line 639 "awkgram.y" /* yacc.c:1646 */
+#line 625 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 2417 "awkgram.c" /* yacc.c:1646 */
+#line 2403 "awkgram.c" /* yacc.c:1646 */
break;
case 47:
-#line 641 "awkgram.y" /* yacc.c:1646 */
+#line 627 "awkgram.y" /* yacc.c:1646 */
{
if (do_pretty_print)
(yyval) = list_prepend((yyvsp[0]), instruction(Op_exec_count));
else
(yyval) = (yyvsp[0]);
}
-#line 2428 "awkgram.c" /* yacc.c:1646 */
+#line 2414 "awkgram.c" /* yacc.c:1646 */
break;
case 48:
-#line 648 "awkgram.y" /* yacc.c:1646 */
+#line 634 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt;
INSTRUCTION *ip, *nextc, *tbreak;
@@ -2519,11 +2505,11 @@ yyreduce:
break_allowed--;
fix_break_continue(ip, tbreak, NULL);
}
-#line 2523 "awkgram.c" /* yacc.c:1646 */
+#line 2509 "awkgram.c" /* yacc.c:1646 */
break;
case 49:
-#line 739 "awkgram.y" /* yacc.c:1646 */
+#line 725 "awkgram.y" /* yacc.c:1646 */
{
/*
* -----------------
@@ -2565,11 +2551,11 @@ yyreduce:
continue_allowed--;
fix_break_continue(ip, tbreak, tcont);
}
-#line 2569 "awkgram.c" /* yacc.c:1646 */
+#line 2555 "awkgram.c" /* yacc.c:1646 */
break;
case 50:
-#line 781 "awkgram.y" /* yacc.c:1646 */
+#line 767 "awkgram.y" /* yacc.c:1646 */
{
/*
* -----------------
@@ -2611,11 +2597,11 @@ yyreduce:
} /* else
$1 and $4 are NULLs */
}
-#line 2615 "awkgram.c" /* yacc.c:1646 */
+#line 2601 "awkgram.c" /* yacc.c:1646 */
break;
case 51:
-#line 823 "awkgram.y" /* yacc.c:1646 */
+#line 809 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *ip;
char *var_name = (yyvsp[-5])->lextok;
@@ -2728,33 +2714,33 @@ regular_loop:
break_allowed--;
continue_allowed--;
}
-#line 2732 "awkgram.c" /* yacc.c:1646 */
+#line 2718 "awkgram.c" /* yacc.c:1646 */
break;
case 52:
-#line 936 "awkgram.y" /* yacc.c:1646 */
+#line 922 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_for_loop((yyvsp[-11]), (yyvsp[-9]), (yyvsp[-6]), (yyvsp[-3]), (yyvsp[0]));
break_allowed--;
continue_allowed--;
}
-#line 2743 "awkgram.c" /* yacc.c:1646 */
+#line 2729 "awkgram.c" /* yacc.c:1646 */
break;
case 53:
-#line 943 "awkgram.y" /* yacc.c:1646 */
+#line 929 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_for_loop((yyvsp[-10]), (yyvsp[-8]), (INSTRUCTION *) NULL, (yyvsp[-3]), (yyvsp[0]));
break_allowed--;
continue_allowed--;
}
-#line 2754 "awkgram.c" /* yacc.c:1646 */
+#line 2740 "awkgram.c" /* yacc.c:1646 */
break;
case 54:
-#line 950 "awkgram.y" /* yacc.c:1646 */
+#line 936 "awkgram.y" /* yacc.c:1646 */
{
if (do_pretty_print)
(yyval) = list_prepend((yyvsp[0]), instruction(Op_exec_count));
@@ -2762,11 +2748,11 @@ regular_loop:
(yyval) = (yyvsp[0]);
(yyval) = add_pending_comment((yyval));
}
-#line 2766 "awkgram.c" /* yacc.c:1646 */
+#line 2752 "awkgram.c" /* yacc.c:1646 */
break;
case 55:
-#line 961 "awkgram.y" /* yacc.c:1646 */
+#line 947 "awkgram.y" /* yacc.c:1646 */
{
if (! break_allowed)
error_ln((yyvsp[-1])->source_line,
@@ -2776,11 +2762,11 @@ regular_loop:
(yyval) = add_pending_comment((yyval));
}
-#line 2780 "awkgram.c" /* yacc.c:1646 */
+#line 2766 "awkgram.c" /* yacc.c:1646 */
break;
case 56:
-#line 971 "awkgram.y" /* yacc.c:1646 */
+#line 957 "awkgram.y" /* yacc.c:1646 */
{
if (! continue_allowed)
error_ln((yyvsp[-1])->source_line,
@@ -2790,11 +2776,11 @@ regular_loop:
(yyval) = add_pending_comment((yyval));
}
-#line 2794 "awkgram.c" /* yacc.c:1646 */
+#line 2780 "awkgram.c" /* yacc.c:1646 */
break;
case 57:
-#line 981 "awkgram.y" /* yacc.c:1646 */
+#line 967 "awkgram.y" /* yacc.c:1646 */
{
/* if inside function (rule = 0), resolve context at run-time */
if (rule && rule != Rule)
@@ -2804,11 +2790,11 @@ regular_loop:
(yyval) = list_create((yyvsp[-1]));
(yyval) = add_pending_comment((yyval));
}
-#line 2808 "awkgram.c" /* yacc.c:1646 */
+#line 2794 "awkgram.c" /* yacc.c:1646 */
break;
case 58:
-#line 991 "awkgram.y" /* yacc.c:1646 */
+#line 977 "awkgram.y" /* yacc.c:1646 */
{
/* if inside function (rule = 0), resolve context at run-time */
if (rule == BEGIN || rule == END || rule == ENDFILE)
@@ -2820,11 +2806,11 @@ regular_loop:
(yyval) = list_create((yyvsp[-1]));
(yyval) = add_pending_comment((yyval));
}
-#line 2824 "awkgram.c" /* yacc.c:1646 */
+#line 2810 "awkgram.c" /* yacc.c:1646 */
break;
case 59:
-#line 1003 "awkgram.y" /* yacc.c:1646 */
+#line 989 "awkgram.y" /* yacc.c:1646 */
{
/* Initialize the two possible jump targets, the actual target
* is resolved at run-time.
@@ -2840,20 +2826,20 @@ regular_loop:
(yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
(yyval) = add_pending_comment((yyval));
}
-#line 2844 "awkgram.c" /* yacc.c:1646 */
+#line 2830 "awkgram.c" /* yacc.c:1646 */
break;
case 60:
-#line 1019 "awkgram.y" /* yacc.c:1646 */
+#line 1005 "awkgram.y" /* yacc.c:1646 */
{
if (! in_function)
yyerror(_("`return' used outside function context"));
}
-#line 2853 "awkgram.c" /* yacc.c:1646 */
+#line 2839 "awkgram.c" /* yacc.c:1646 */
break;
case 61:
-#line 1022 "awkgram.y" /* yacc.c:1646 */
+#line 1008 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-1]) == NULL) {
(yyval) = list_create((yyvsp[-3]));
@@ -2875,17 +2861,17 @@ regular_loop:
}
(yyval) = add_pending_comment((yyval));
}
-#line 2879 "awkgram.c" /* yacc.c:1646 */
+#line 2865 "awkgram.c" /* yacc.c:1646 */
break;
case 63:
-#line 1055 "awkgram.y" /* yacc.c:1646 */
+#line 1041 "awkgram.y" /* yacc.c:1646 */
{ in_print = true; in_parens = 0; }
-#line 2885 "awkgram.c" /* yacc.c:1646 */
+#line 2871 "awkgram.c" /* yacc.c:1646 */
break;
case 64:
-#line 1056 "awkgram.y" /* yacc.c:1646 */
+#line 1042 "awkgram.y" /* yacc.c:1646 */
{
/*
* Optimization: plain `print' has no expression list, so $3 is null.
@@ -2983,17 +2969,17 @@ regular_print:
}
(yyval) = add_pending_comment((yyval));
}
-#line 2987 "awkgram.c" /* yacc.c:1646 */
+#line 2973 "awkgram.c" /* yacc.c:1646 */
break;
case 65:
-#line 1154 "awkgram.y" /* yacc.c:1646 */
+#line 1140 "awkgram.y" /* yacc.c:1646 */
{ sub_counter = 0; }
-#line 2993 "awkgram.c" /* yacc.c:1646 */
+#line 2979 "awkgram.c" /* yacc.c:1646 */
break;
case 66:
-#line 1155 "awkgram.y" /* yacc.c:1646 */
+#line 1141 "awkgram.y" /* yacc.c:1646 */
{
char *arr = (yyvsp[-2])->lextok;
@@ -3027,11 +3013,11 @@ regular_print:
}
(yyval) = add_pending_comment((yyval));
}
-#line 3031 "awkgram.c" /* yacc.c:1646 */
+#line 3017 "awkgram.c" /* yacc.c:1646 */
break;
case 67:
-#line 1193 "awkgram.y" /* yacc.c:1646 */
+#line 1179 "awkgram.y" /* yacc.c:1646 */
{
static bool warned = false;
char *arr = (yyvsp[-1])->lextok;
@@ -3058,55 +3044,55 @@ regular_print:
}
(yyval) = add_pending_comment((yyval));
}
-#line 3062 "awkgram.c" /* yacc.c:1646 */
+#line 3048 "awkgram.c" /* yacc.c:1646 */
break;
case 68:
-#line 1220 "awkgram.y" /* yacc.c:1646 */
+#line 1206 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = optimize_assignment((yyvsp[0]));
(yyval) = add_pending_comment((yyval));
}
-#line 3071 "awkgram.c" /* yacc.c:1646 */
+#line 3057 "awkgram.c" /* yacc.c:1646 */
break;
case 69:
-#line 1228 "awkgram.y" /* yacc.c:1646 */
+#line 1214 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3077 "awkgram.c" /* yacc.c:1646 */
+#line 3063 "awkgram.c" /* yacc.c:1646 */
break;
case 70:
-#line 1230 "awkgram.y" /* yacc.c:1646 */
+#line 1216 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3083 "awkgram.c" /* yacc.c:1646 */
+#line 3069 "awkgram.c" /* yacc.c:1646 */
break;
case 71:
-#line 1235 "awkgram.y" /* yacc.c:1646 */
+#line 1221 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3089 "awkgram.c" /* yacc.c:1646 */
+#line 3075 "awkgram.c" /* yacc.c:1646 */
break;
case 72:
-#line 1237 "awkgram.y" /* yacc.c:1646 */
+#line 1223 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-1]) == NULL)
(yyval) = list_create((yyvsp[0]));
else
(yyval) = list_prepend((yyvsp[-1]), (yyvsp[0]));
}
-#line 3100 "awkgram.c" /* yacc.c:1646 */
+#line 3086 "awkgram.c" /* yacc.c:1646 */
break;
case 73:
-#line 1244 "awkgram.y" /* yacc.c:1646 */
+#line 1230 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3106 "awkgram.c" /* yacc.c:1646 */
+#line 3092 "awkgram.c" /* yacc.c:1646 */
break;
case 74:
-#line 1249 "awkgram.y" /* yacc.c:1646 */
+#line 1235 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *casestmt = (yyvsp[0]);
if ((yyvsp[0]) == NULL)
@@ -3118,11 +3104,11 @@ regular_print:
bcfree((yyvsp[-2]));
(yyval) = (yyvsp[-4]);
}
-#line 3122 "awkgram.c" /* yacc.c:1646 */
+#line 3108 "awkgram.c" /* yacc.c:1646 */
break;
case 75:
-#line 1261 "awkgram.y" /* yacc.c:1646 */
+#line 1247 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *casestmt = (yyvsp[0]);
if ((yyvsp[0]) == NULL)
@@ -3133,17 +3119,17 @@ regular_print:
(yyvsp[-3])->case_stmt = casestmt;
(yyval) = (yyvsp[-3]);
}
-#line 3137 "awkgram.c" /* yacc.c:1646 */
+#line 3123 "awkgram.c" /* yacc.c:1646 */
break;
case 76:
-#line 1275 "awkgram.y" /* yacc.c:1646 */
+#line 1261 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3143 "awkgram.c" /* yacc.c:1646 */
+#line 3129 "awkgram.c" /* yacc.c:1646 */
break;
case 77:
-#line 1277 "awkgram.y" /* yacc.c:1646 */
+#line 1263 "awkgram.y" /* yacc.c:1646 */
{
NODE *n = (yyvsp[0])->memory;
(void) force_number(n);
@@ -3151,28 +3137,28 @@ regular_print:
bcfree((yyvsp[-1]));
(yyval) = (yyvsp[0]);
}
-#line 3155 "awkgram.c" /* yacc.c:1646 */
+#line 3141 "awkgram.c" /* yacc.c:1646 */
break;
case 78:
-#line 1285 "awkgram.y" /* yacc.c:1646 */
+#line 1271 "awkgram.y" /* yacc.c:1646 */
{
NODE *n = (yyvsp[0])->lasti->memory;
bcfree((yyvsp[-1]));
add_sign_to_num(n, '+');
(yyval) = (yyvsp[0]);
}
-#line 3166 "awkgram.c" /* yacc.c:1646 */
+#line 3152 "awkgram.c" /* yacc.c:1646 */
break;
case 79:
-#line 1292 "awkgram.y" /* yacc.c:1646 */
+#line 1278 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3172 "awkgram.c" /* yacc.c:1646 */
+#line 3158 "awkgram.c" /* yacc.c:1646 */
break;
case 80:
-#line 1294 "awkgram.y" /* yacc.c:1646 */
+#line 1280 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[0])->memory->type == Node_regex)
(yyvsp[0])->opcode = Op_push_re;
@@ -3180,57 +3166,57 @@ regular_print:
(yyvsp[0])->opcode = Op_push;
(yyval) = (yyvsp[0]);
}
-#line 3184 "awkgram.c" /* yacc.c:1646 */
+#line 3170 "awkgram.c" /* yacc.c:1646 */
break;
case 81:
-#line 1302 "awkgram.y" /* yacc.c:1646 */
+#line 1288 "awkgram.y" /* yacc.c:1646 */
{
assert(((yyvsp[0])->memory->flags & REGEX) == REGEX);
(yyvsp[0])->opcode = Op_push_re;
(yyval) = (yyvsp[0]);
}
-#line 3194 "awkgram.c" /* yacc.c:1646 */
+#line 3180 "awkgram.c" /* yacc.c:1646 */
break;
case 82:
-#line 1311 "awkgram.y" /* yacc.c:1646 */
+#line 1297 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3200 "awkgram.c" /* yacc.c:1646 */
+#line 3186 "awkgram.c" /* yacc.c:1646 */
break;
case 83:
-#line 1313 "awkgram.y" /* yacc.c:1646 */
+#line 1299 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3206 "awkgram.c" /* yacc.c:1646 */
+#line 3192 "awkgram.c" /* yacc.c:1646 */
break;
case 85:
-#line 1323 "awkgram.y" /* yacc.c:1646 */
+#line 1309 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = (yyvsp[-1]);
}
-#line 3214 "awkgram.c" /* yacc.c:1646 */
+#line 3200 "awkgram.c" /* yacc.c:1646 */
break;
case 86:
-#line 1330 "awkgram.y" /* yacc.c:1646 */
+#line 1316 "awkgram.y" /* yacc.c:1646 */
{
in_print = false;
in_parens = 0;
(yyval) = NULL;
}
-#line 3224 "awkgram.c" /* yacc.c:1646 */
+#line 3210 "awkgram.c" /* yacc.c:1646 */
break;
case 87:
-#line 1335 "awkgram.y" /* yacc.c:1646 */
+#line 1321 "awkgram.y" /* yacc.c:1646 */
{ in_print = false; in_parens = 0; }
-#line 3230 "awkgram.c" /* yacc.c:1646 */
+#line 3216 "awkgram.c" /* yacc.c:1646 */
break;
case 88:
-#line 1336 "awkgram.y" /* yacc.c:1646 */
+#line 1322 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-2])->redir_type == redirect_twoway
&& (yyvsp[0])->lasti->opcode == Op_K_getline_redir
@@ -3238,63 +3224,63 @@ regular_print:
yyerror(_("multistage two-way pipelines don't work"));
(yyval) = list_prepend((yyvsp[0]), (yyvsp[-2]));
}
-#line 3242 "awkgram.c" /* yacc.c:1646 */
+#line 3228 "awkgram.c" /* yacc.c:1646 */
break;
case 89:
-#line 1347 "awkgram.y" /* yacc.c:1646 */
+#line 1333 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_condition((yyvsp[-3]), (yyvsp[-5]), (yyvsp[0]), NULL, NULL);
}
-#line 3250 "awkgram.c" /* yacc.c:1646 */
+#line 3236 "awkgram.c" /* yacc.c:1646 */
break;
case 90:
-#line 1352 "awkgram.y" /* yacc.c:1646 */
+#line 1338 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_condition((yyvsp[-6]), (yyvsp[-8]), (yyvsp[-3]), (yyvsp[-2]), (yyvsp[0]));
}
-#line 3258 "awkgram.c" /* yacc.c:1646 */
+#line 3244 "awkgram.c" /* yacc.c:1646 */
break;
case 95:
-#line 1369 "awkgram.y" /* yacc.c:1646 */
+#line 1355 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3264 "awkgram.c" /* yacc.c:1646 */
+#line 3250 "awkgram.c" /* yacc.c:1646 */
break;
case 96:
-#line 1371 "awkgram.y" /* yacc.c:1646 */
+#line 1357 "awkgram.y" /* yacc.c:1646 */
{
bcfree((yyvsp[-1]));
(yyval) = (yyvsp[0]);
}
-#line 3273 "awkgram.c" /* yacc.c:1646 */
+#line 3259 "awkgram.c" /* yacc.c:1646 */
break;
case 97:
-#line 1379 "awkgram.y" /* yacc.c:1646 */
+#line 1365 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3279 "awkgram.c" /* yacc.c:1646 */
+#line 3265 "awkgram.c" /* yacc.c:1646 */
break;
case 98:
-#line 1381 "awkgram.y" /* yacc.c:1646 */
+#line 1367 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3285 "awkgram.c" /* yacc.c:1646 */
+#line 3271 "awkgram.c" /* yacc.c:1646 */
break;
case 99:
-#line 1386 "awkgram.y" /* yacc.c:1646 */
+#line 1372 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->param_count = 0;
(yyval) = list_create((yyvsp[0]));
}
-#line 3294 "awkgram.c" /* yacc.c:1646 */
+#line 3280 "awkgram.c" /* yacc.c:1646 */
break;
case 100:
-#line 1391 "awkgram.y" /* yacc.c:1646 */
+#line 1377 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-2]) != NULL && (yyvsp[0]) != NULL) {
(yyvsp[0])->param_count = (yyvsp[-2])->lasti->param_count + 1;
@@ -3303,74 +3289,74 @@ regular_print:
} else
(yyval) = NULL;
}
-#line 3307 "awkgram.c" /* yacc.c:1646 */
+#line 3293 "awkgram.c" /* yacc.c:1646 */
break;
case 101:
-#line 1400 "awkgram.y" /* yacc.c:1646 */
+#line 1386 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3313 "awkgram.c" /* yacc.c:1646 */
+#line 3299 "awkgram.c" /* yacc.c:1646 */
break;
case 102:
-#line 1402 "awkgram.y" /* yacc.c:1646 */
+#line 1388 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 3319 "awkgram.c" /* yacc.c:1646 */
+#line 3305 "awkgram.c" /* yacc.c:1646 */
break;
case 103:
-#line 1404 "awkgram.y" /* yacc.c:1646 */
+#line 1390 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-2]); }
-#line 3325 "awkgram.c" /* yacc.c:1646 */
+#line 3311 "awkgram.c" /* yacc.c:1646 */
break;
case 104:
-#line 1410 "awkgram.y" /* yacc.c:1646 */
+#line 1396 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3331 "awkgram.c" /* yacc.c:1646 */
+#line 3317 "awkgram.c" /* yacc.c:1646 */
break;
case 105:
-#line 1412 "awkgram.y" /* yacc.c:1646 */
+#line 1398 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3337 "awkgram.c" /* yacc.c:1646 */
+#line 3323 "awkgram.c" /* yacc.c:1646 */
break;
case 106:
-#line 1417 "awkgram.y" /* yacc.c:1646 */
+#line 1403 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3343 "awkgram.c" /* yacc.c:1646 */
+#line 3329 "awkgram.c" /* yacc.c:1646 */
break;
case 107:
-#line 1419 "awkgram.y" /* yacc.c:1646 */
+#line 1405 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3349 "awkgram.c" /* yacc.c:1646 */
+#line 3335 "awkgram.c" /* yacc.c:1646 */
break;
case 108:
-#line 1424 "awkgram.y" /* yacc.c:1646 */
+#line 1410 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_expression_list(NULL, (yyvsp[0])); }
-#line 3355 "awkgram.c" /* yacc.c:1646 */
+#line 3341 "awkgram.c" /* yacc.c:1646 */
break;
case 109:
-#line 1426 "awkgram.y" /* yacc.c:1646 */
+#line 1412 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
yyerrok;
}
-#line 3364 "awkgram.c" /* yacc.c:1646 */
+#line 3350 "awkgram.c" /* yacc.c:1646 */
break;
case 110:
-#line 1431 "awkgram.y" /* yacc.c:1646 */
+#line 1417 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3370 "awkgram.c" /* yacc.c:1646 */
+#line 3356 "awkgram.c" /* yacc.c:1646 */
break;
case 111:
-#line 1433 "awkgram.y" /* yacc.c:1646 */
+#line 1419 "awkgram.y" /* yacc.c:1646 */
{
/*
* Returning the expression list instead of NULL lets
@@ -3378,62 +3364,62 @@ regular_print:
*/
(yyval) = (yyvsp[-1]);
}
-#line 3382 "awkgram.c" /* yacc.c:1646 */
+#line 3368 "awkgram.c" /* yacc.c:1646 */
break;
case 112:
-#line 1441 "awkgram.y" /* yacc.c:1646 */
+#line 1427 "awkgram.y" /* yacc.c:1646 */
{
/* Ditto */
(yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
}
-#line 3391 "awkgram.c" /* yacc.c:1646 */
+#line 3377 "awkgram.c" /* yacc.c:1646 */
break;
case 113:
-#line 1446 "awkgram.y" /* yacc.c:1646 */
+#line 1432 "awkgram.y" /* yacc.c:1646 */
{
/* Ditto */
(yyval) = (yyvsp[-2]);
}
-#line 3400 "awkgram.c" /* yacc.c:1646 */
+#line 3386 "awkgram.c" /* yacc.c:1646 */
break;
case 114:
-#line 1454 "awkgram.y" /* yacc.c:1646 */
+#line 1440 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3406 "awkgram.c" /* yacc.c:1646 */
+#line 3392 "awkgram.c" /* yacc.c:1646 */
break;
case 115:
-#line 1456 "awkgram.y" /* yacc.c:1646 */
+#line 1442 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3412 "awkgram.c" /* yacc.c:1646 */
+#line 3398 "awkgram.c" /* yacc.c:1646 */
break;
case 116:
-#line 1461 "awkgram.y" /* yacc.c:1646 */
+#line 1447 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_expression_list(NULL, (yyvsp[0])); }
-#line 3418 "awkgram.c" /* yacc.c:1646 */
+#line 3404 "awkgram.c" /* yacc.c:1646 */
break;
case 117:
-#line 1463 "awkgram.y" /* yacc.c:1646 */
+#line 1449 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
yyerrok;
}
-#line 3427 "awkgram.c" /* yacc.c:1646 */
+#line 3413 "awkgram.c" /* yacc.c:1646 */
break;
case 118:
-#line 1468 "awkgram.y" /* yacc.c:1646 */
+#line 1454 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 3433 "awkgram.c" /* yacc.c:1646 */
+#line 3419 "awkgram.c" /* yacc.c:1646 */
break;
case 119:
-#line 1470 "awkgram.y" /* yacc.c:1646 */
+#line 1456 "awkgram.y" /* yacc.c:1646 */
{
/*
* Returning the expression list instead of NULL lets
@@ -3441,72 +3427,72 @@ regular_print:
*/
(yyval) = (yyvsp[-1]);
}
-#line 3445 "awkgram.c" /* yacc.c:1646 */
+#line 3431 "awkgram.c" /* yacc.c:1646 */
break;
case 120:
-#line 1478 "awkgram.y" /* yacc.c:1646 */
+#line 1464 "awkgram.y" /* yacc.c:1646 */
{
/* Ditto */
(yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
}
-#line 3454 "awkgram.c" /* yacc.c:1646 */
+#line 3440 "awkgram.c" /* yacc.c:1646 */
break;
case 121:
-#line 1483 "awkgram.y" /* yacc.c:1646 */
+#line 1469 "awkgram.y" /* yacc.c:1646 */
{
/* Ditto */
(yyval) = (yyvsp[-2]);
}
-#line 3463 "awkgram.c" /* yacc.c:1646 */
+#line 3449 "awkgram.c" /* yacc.c:1646 */
break;
case 122:
-#line 1490 "awkgram.y" /* yacc.c:1646 */
+#line 1476 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3469 "awkgram.c" /* yacc.c:1646 */
+#line 3455 "awkgram.c" /* yacc.c:1646 */
break;
case 123:
-#line 1491 "awkgram.y" /* yacc.c:1646 */
+#line 1477 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = list_create((yyvsp[0])); }
-#line 3475 "awkgram.c" /* yacc.c:1646 */
+#line 3461 "awkgram.c" /* yacc.c:1646 */
break;
case 124:
-#line 1497 "awkgram.y" /* yacc.c:1646 */
+#line 1483 "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 3486 "awkgram.c" /* yacc.c:1646 */
+#line 3472 "awkgram.c" /* yacc.c:1646 */
break;
case 125:
-#line 1504 "awkgram.y" /* yacc.c:1646 */
+#line 1490 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_assignment((yyvsp[-2]), list_create((yyvsp[0])), (yyvsp[-1]));
}
-#line 3494 "awkgram.c" /* yacc.c:1646 */
+#line 3480 "awkgram.c" /* yacc.c:1646 */
break;
case 126:
-#line 1508 "awkgram.y" /* yacc.c:1646 */
+#line 1494 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3500 "awkgram.c" /* yacc.c:1646 */
+#line 3486 "awkgram.c" /* yacc.c:1646 */
break;
case 127:
-#line 1510 "awkgram.y" /* yacc.c:1646 */
+#line 1496 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3506 "awkgram.c" /* yacc.c:1646 */
+#line 3492 "awkgram.c" /* yacc.c:1646 */
break;
case 128:
-#line 1512 "awkgram.y" /* yacc.c:1646 */
+#line 1498 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-2])->lasti->opcode == Op_match_rec)
warning_ln((yyvsp[-1])->source_line,
@@ -3519,11 +3505,11 @@ regular_print:
bcfree((yyvsp[0]));
(yyval) = list_append((yyvsp[-2]), (yyvsp[-1]));
}
-#line 3523 "awkgram.c" /* yacc.c:1646 */
+#line 3509 "awkgram.c" /* yacc.c:1646 */
break;
case 129:
-#line 1525 "awkgram.y" /* yacc.c:1646 */
+#line 1511 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[-2])->lasti->opcode == Op_match_rec)
warning_ln((yyvsp[-1])->source_line,
@@ -3540,11 +3526,11 @@ regular_print:
(yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1]));
}
}
-#line 3544 "awkgram.c" /* yacc.c:1646 */
+#line 3530 "awkgram.c" /* yacc.c:1646 */
break;
case 130:
-#line 1542 "awkgram.y" /* yacc.c:1646 */
+#line 1528 "awkgram.y" /* yacc.c:1646 */
{
if (do_lint_old)
warning_ln((yyvsp[-1])->source_line,
@@ -3554,91 +3540,91 @@ regular_print:
(yyvsp[-1])->expr_count = 1;
(yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1]));
}
-#line 3558 "awkgram.c" /* yacc.c:1646 */
+#line 3544 "awkgram.c" /* yacc.c:1646 */
break;
case 131:
-#line 1552 "awkgram.y" /* yacc.c:1646 */
+#line 1538 "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 3569 "awkgram.c" /* yacc.c:1646 */
+#line 3555 "awkgram.c" /* yacc.c:1646 */
break;
case 132:
-#line 1559 "awkgram.y" /* yacc.c:1646 */
+#line 1545 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_condition((yyvsp[-4]), (yyvsp[-3]), (yyvsp[-2]), (yyvsp[-1]), (yyvsp[0])); }
-#line 3575 "awkgram.c" /* yacc.c:1646 */
+#line 3561 "awkgram.c" /* yacc.c:1646 */
break;
case 133:
-#line 1561 "awkgram.y" /* yacc.c:1646 */
+#line 1547 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3581 "awkgram.c" /* yacc.c:1646 */
+#line 3567 "awkgram.c" /* yacc.c:1646 */
break;
case 134:
-#line 1566 "awkgram.y" /* yacc.c:1646 */
+#line 1552 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3587 "awkgram.c" /* yacc.c:1646 */
+#line 3573 "awkgram.c" /* yacc.c:1646 */
break;
case 135:
-#line 1568 "awkgram.y" /* yacc.c:1646 */
+#line 1554 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3593 "awkgram.c" /* yacc.c:1646 */
+#line 3579 "awkgram.c" /* yacc.c:1646 */
break;
case 136:
-#line 1570 "awkgram.y" /* yacc.c:1646 */
+#line 1556 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_assign_quotient;
(yyval) = (yyvsp[0]);
}
-#line 3602 "awkgram.c" /* yacc.c:1646 */
+#line 3588 "awkgram.c" /* yacc.c:1646 */
break;
case 137:
-#line 1578 "awkgram.y" /* yacc.c:1646 */
+#line 1564 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3608 "awkgram.c" /* yacc.c:1646 */
+#line 3594 "awkgram.c" /* yacc.c:1646 */
break;
case 138:
-#line 1580 "awkgram.y" /* yacc.c:1646 */
+#line 1566 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3614 "awkgram.c" /* yacc.c:1646 */
+#line 3600 "awkgram.c" /* yacc.c:1646 */
break;
case 139:
-#line 1585 "awkgram.y" /* yacc.c:1646 */
+#line 1571 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3620 "awkgram.c" /* yacc.c:1646 */
+#line 3606 "awkgram.c" /* yacc.c:1646 */
break;
case 140:
-#line 1587 "awkgram.y" /* yacc.c:1646 */
+#line 1573 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3626 "awkgram.c" /* yacc.c:1646 */
+#line 3612 "awkgram.c" /* yacc.c:1646 */
break;
case 141:
-#line 1592 "awkgram.y" /* yacc.c:1646 */
+#line 1578 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3632 "awkgram.c" /* yacc.c:1646 */
+#line 3618 "awkgram.c" /* yacc.c:1646 */
break;
case 142:
-#line 1594 "awkgram.y" /* yacc.c:1646 */
+#line 1580 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 3638 "awkgram.c" /* yacc.c:1646 */
+#line 3624 "awkgram.c" /* yacc.c:1646 */
break;
case 143:
-#line 1596 "awkgram.y" /* yacc.c:1646 */
+#line 1582 "awkgram.y" /* yacc.c:1646 */
{
int count = 2;
bool is_simple_var = false;
@@ -3691,47 +3677,47 @@ regular_print:
max_args = count;
}
}
-#line 3695 "awkgram.c" /* yacc.c:1646 */
+#line 3681 "awkgram.c" /* yacc.c:1646 */
break;
case 145:
-#line 1654 "awkgram.y" /* yacc.c:1646 */
+#line 1640 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3701 "awkgram.c" /* yacc.c:1646 */
+#line 3687 "awkgram.c" /* yacc.c:1646 */
break;
case 146:
-#line 1656 "awkgram.y" /* yacc.c:1646 */
+#line 1642 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3707 "awkgram.c" /* yacc.c:1646 */
+#line 3693 "awkgram.c" /* yacc.c:1646 */
break;
case 147:
-#line 1658 "awkgram.y" /* yacc.c:1646 */
+#line 1644 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3713 "awkgram.c" /* yacc.c:1646 */
+#line 3699 "awkgram.c" /* yacc.c:1646 */
break;
case 148:
-#line 1660 "awkgram.y" /* yacc.c:1646 */
+#line 1646 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3719 "awkgram.c" /* yacc.c:1646 */
+#line 3705 "awkgram.c" /* yacc.c:1646 */
break;
case 149:
-#line 1662 "awkgram.y" /* yacc.c:1646 */
+#line 1648 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3725 "awkgram.c" /* yacc.c:1646 */
+#line 3711 "awkgram.c" /* yacc.c:1646 */
break;
case 150:
-#line 1664 "awkgram.y" /* yacc.c:1646 */
+#line 1650 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3731 "awkgram.c" /* yacc.c:1646 */
+#line 3717 "awkgram.c" /* yacc.c:1646 */
break;
case 151:
-#line 1666 "awkgram.y" /* yacc.c:1646 */
+#line 1652 "awkgram.y" /* yacc.c:1646 */
{
/*
* In BEGINFILE/ENDFILE, allow `getline [var] < file'
@@ -3745,29 +3731,29 @@ regular_print:
_("non-redirected `getline' undefined inside END action"));
(yyval) = mk_getline((yyvsp[-2]), (yyvsp[-1]), (yyvsp[0]), redirect_input);
}
-#line 3749 "awkgram.c" /* yacc.c:1646 */
+#line 3735 "awkgram.c" /* yacc.c:1646 */
break;
case 152:
-#line 1680 "awkgram.y" /* yacc.c:1646 */
+#line 1666 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_postincrement;
(yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
}
-#line 3758 "awkgram.c" /* yacc.c:1646 */
+#line 3744 "awkgram.c" /* yacc.c:1646 */
break;
case 153:
-#line 1685 "awkgram.y" /* yacc.c:1646 */
+#line 1671 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_postdecrement;
(yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
}
-#line 3767 "awkgram.c" /* yacc.c:1646 */
+#line 3753 "awkgram.c" /* yacc.c:1646 */
break;
case 154:
-#line 1690 "awkgram.y" /* yacc.c:1646 */
+#line 1676 "awkgram.y" /* yacc.c:1646 */
{
if (do_lint_old) {
warning_ln((yyvsp[-1])->source_line,
@@ -3787,64 +3773,64 @@ regular_print:
(yyval) = list_append(list_merge(t, (yyvsp[0])), (yyvsp[-1]));
}
}
-#line 3791 "awkgram.c" /* yacc.c:1646 */
+#line 3777 "awkgram.c" /* yacc.c:1646 */
break;
case 155:
-#line 1715 "awkgram.y" /* yacc.c:1646 */
+#line 1701 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = mk_getline((yyvsp[-1]), (yyvsp[0]), (yyvsp[-3]), (yyvsp[-2])->redir_type);
bcfree((yyvsp[-2]));
}
-#line 3800 "awkgram.c" /* yacc.c:1646 */
+#line 3786 "awkgram.c" /* yacc.c:1646 */
break;
case 156:
-#line 1721 "awkgram.y" /* yacc.c:1646 */
+#line 1707 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3806 "awkgram.c" /* yacc.c:1646 */
+#line 3792 "awkgram.c" /* yacc.c:1646 */
break;
case 157:
-#line 1723 "awkgram.y" /* yacc.c:1646 */
+#line 1709 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3812 "awkgram.c" /* yacc.c:1646 */
+#line 3798 "awkgram.c" /* yacc.c:1646 */
break;
case 158:
-#line 1725 "awkgram.y" /* yacc.c:1646 */
+#line 1711 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3818 "awkgram.c" /* yacc.c:1646 */
+#line 3804 "awkgram.c" /* yacc.c:1646 */
break;
case 159:
-#line 1727 "awkgram.y" /* yacc.c:1646 */
+#line 1713 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3824 "awkgram.c" /* yacc.c:1646 */
+#line 3810 "awkgram.c" /* yacc.c:1646 */
break;
case 160:
-#line 1729 "awkgram.y" /* yacc.c:1646 */
+#line 1715 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3830 "awkgram.c" /* yacc.c:1646 */
+#line 3816 "awkgram.c" /* yacc.c:1646 */
break;
case 161:
-#line 1731 "awkgram.y" /* yacc.c:1646 */
+#line 1717 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3836 "awkgram.c" /* yacc.c:1646 */
+#line 3822 "awkgram.c" /* yacc.c:1646 */
break;
case 162:
-#line 1736 "awkgram.y" /* yacc.c:1646 */
+#line 1722 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_create((yyvsp[0]));
}
-#line 3844 "awkgram.c" /* yacc.c:1646 */
+#line 3830 "awkgram.c" /* yacc.c:1646 */
break;
case 163:
-#line 1740 "awkgram.y" /* yacc.c:1646 */
+#line 1726 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[0])->opcode == Op_match_rec) {
(yyvsp[0])->opcode = Op_nomatch;
@@ -3876,37 +3862,37 @@ regular_print:
}
}
}
-#line 3880 "awkgram.c" /* yacc.c:1646 */
+#line 3866 "awkgram.c" /* yacc.c:1646 */
break;
case 164:
-#line 1772 "awkgram.y" /* yacc.c:1646 */
+#line 1758 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 3886 "awkgram.c" /* yacc.c:1646 */
+#line 3872 "awkgram.c" /* yacc.c:1646 */
break;
case 165:
-#line 1774 "awkgram.y" /* yacc.c:1646 */
+#line 1760 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
if ((yyval) == NULL)
YYABORT;
}
-#line 3896 "awkgram.c" /* yacc.c:1646 */
+#line 3882 "awkgram.c" /* yacc.c:1646 */
break;
case 166:
-#line 1780 "awkgram.y" /* yacc.c:1646 */
+#line 1766 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
if ((yyval) == NULL)
YYABORT;
}
-#line 3906 "awkgram.c" /* yacc.c:1646 */
+#line 3892 "awkgram.c" /* yacc.c:1646 */
break;
case 167:
-#line 1786 "awkgram.y" /* yacc.c:1646 */
+#line 1772 "awkgram.y" /* yacc.c:1646 */
{
static bool warned = false;
@@ -3919,45 +3905,45 @@ regular_print:
if ((yyval) == NULL)
YYABORT;
}
-#line 3923 "awkgram.c" /* yacc.c:1646 */
+#line 3909 "awkgram.c" /* yacc.c:1646 */
break;
case 170:
-#line 1801 "awkgram.y" /* yacc.c:1646 */
+#line 1787 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[-1])->opcode = Op_preincrement;
(yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
}
-#line 3932 "awkgram.c" /* yacc.c:1646 */
+#line 3918 "awkgram.c" /* yacc.c:1646 */
break;
case 171:
-#line 1806 "awkgram.y" /* yacc.c:1646 */
+#line 1792 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[-1])->opcode = Op_predecrement;
(yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
}
-#line 3941 "awkgram.c" /* yacc.c:1646 */
+#line 3927 "awkgram.c" /* yacc.c:1646 */
break;
case 172:
-#line 1811 "awkgram.y" /* yacc.c:1646 */
+#line 1797 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_create((yyvsp[0]));
}
-#line 3949 "awkgram.c" /* yacc.c:1646 */
+#line 3935 "awkgram.c" /* yacc.c:1646 */
break;
case 173:
-#line 1815 "awkgram.y" /* yacc.c:1646 */
+#line 1801 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_create((yyvsp[0]));
}
-#line 3957 "awkgram.c" /* yacc.c:1646 */
+#line 3943 "awkgram.c" /* yacc.c:1646 */
break;
case 174:
-#line 1819 "awkgram.y" /* yacc.c:1646 */
+#line 1805 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[0])->lasti->opcode == Op_push_i
&& ((yyvsp[0])->lasti->memory->flags & STRING) == 0
@@ -3972,11 +3958,11 @@ regular_print:
(yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
}
}
-#line 3976 "awkgram.c" /* yacc.c:1646 */
+#line 3962 "awkgram.c" /* yacc.c:1646 */
break;
case 175:
-#line 1834 "awkgram.y" /* yacc.c:1646 */
+#line 1820 "awkgram.y" /* yacc.c:1646 */
{
if ((yyvsp[0])->lasti->opcode == Op_push_i
&& ((yyvsp[0])->lasti->memory->flags & STRING) == 0
@@ -3994,20 +3980,20 @@ regular_print:
(yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
}
}
-#line 3998 "awkgram.c" /* yacc.c:1646 */
+#line 3984 "awkgram.c" /* yacc.c:1646 */
break;
case 176:
-#line 1855 "awkgram.y" /* yacc.c:1646 */
+#line 1841 "awkgram.y" /* yacc.c:1646 */
{
func_use((yyvsp[0])->lasti->func_name, FUNC_USE);
(yyval) = (yyvsp[0]);
}
-#line 4007 "awkgram.c" /* yacc.c:1646 */
+#line 3993 "awkgram.c" /* yacc.c:1646 */
break;
case 177:
-#line 1860 "awkgram.y" /* yacc.c:1646 */
+#line 1846 "awkgram.y" /* yacc.c:1646 */
{
/* indirect function call */
INSTRUCTION *f, *t;
@@ -4041,11 +4027,11 @@ regular_print:
(yyval) = list_prepend((yyvsp[0]), t);
at_seen = false;
}
-#line 4045 "awkgram.c" /* yacc.c:1646 */
+#line 4031 "awkgram.c" /* yacc.c:1646 */
break;
case 178:
-#line 1897 "awkgram.y" /* yacc.c:1646 */
+#line 1883 "awkgram.y" /* yacc.c:1646 */
{
NODE *n;
@@ -4070,49 +4056,49 @@ regular_print:
(yyval) = list_append(t, (yyvsp[-3]));
}
}
-#line 4074 "awkgram.c" /* yacc.c:1646 */
+#line 4060 "awkgram.c" /* yacc.c:1646 */
break;
case 179:
-#line 1925 "awkgram.y" /* yacc.c:1646 */
+#line 1911 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 4080 "awkgram.c" /* yacc.c:1646 */
+#line 4066 "awkgram.c" /* yacc.c:1646 */
break;
case 180:
-#line 1927 "awkgram.y" /* yacc.c:1646 */
+#line 1913 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 4086 "awkgram.c" /* yacc.c:1646 */
+#line 4072 "awkgram.c" /* yacc.c:1646 */
break;
case 181:
-#line 1932 "awkgram.y" /* yacc.c:1646 */
+#line 1918 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 4092 "awkgram.c" /* yacc.c:1646 */
+#line 4078 "awkgram.c" /* yacc.c:1646 */
break;
case 182:
-#line 1934 "awkgram.y" /* yacc.c:1646 */
+#line 1920 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 4098 "awkgram.c" /* yacc.c:1646 */
+#line 4084 "awkgram.c" /* yacc.c:1646 */
break;
case 183:
-#line 1939 "awkgram.y" /* yacc.c:1646 */
+#line 1925 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 4104 "awkgram.c" /* yacc.c:1646 */
+#line 4090 "awkgram.c" /* yacc.c:1646 */
break;
case 184:
-#line 1941 "awkgram.y" /* yacc.c:1646 */
+#line 1927 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
}
-#line 4112 "awkgram.c" /* yacc.c:1646 */
+#line 4098 "awkgram.c" /* yacc.c:1646 */
break;
case 185:
-#line 1948 "awkgram.y" /* yacc.c:1646 */
+#line 1934 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *ip = (yyvsp[0])->lasti;
int count = ip->sub_count; /* # of SUBSEP-seperated expressions */
@@ -4126,11 +4112,11 @@ regular_print:
sub_counter++; /* count # of dimensions */
(yyval) = (yyvsp[0]);
}
-#line 4130 "awkgram.c" /* yacc.c:1646 */
+#line 4116 "awkgram.c" /* yacc.c:1646 */
break;
case 186:
-#line 1965 "awkgram.y" /* yacc.c:1646 */
+#line 1951 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *t = (yyvsp[-1]);
if ((yyvsp[-1]) == NULL) {
@@ -4144,31 +4130,31 @@ regular_print:
(yyvsp[0])->sub_count = count_expressions(&t, false);
(yyval) = list_append(t, (yyvsp[0]));
}
-#line 4148 "awkgram.c" /* yacc.c:1646 */
+#line 4134 "awkgram.c" /* yacc.c:1646 */
break;
case 187:
-#line 1982 "awkgram.y" /* yacc.c:1646 */
+#line 1968 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
-#line 4154 "awkgram.c" /* yacc.c:1646 */
+#line 4140 "awkgram.c" /* yacc.c:1646 */
break;
case 188:
-#line 1984 "awkgram.y" /* yacc.c:1646 */
+#line 1970 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
}
-#line 4162 "awkgram.c" /* yacc.c:1646 */
+#line 4148 "awkgram.c" /* yacc.c:1646 */
break;
case 189:
-#line 1991 "awkgram.y" /* yacc.c:1646 */
+#line 1977 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
-#line 4168 "awkgram.c" /* yacc.c:1646 */
+#line 4154 "awkgram.c" /* yacc.c:1646 */
break;
case 190:
-#line 1996 "awkgram.y" /* yacc.c:1646 */
+#line 1982 "awkgram.y" /* yacc.c:1646 */
{
char *var_name = (yyvsp[0])->lextok;
@@ -4176,22 +4162,22 @@ regular_print:
(yyvsp[0])->memory = variable((yyvsp[0])->source_line, var_name, Node_var_new);
(yyval) = list_create((yyvsp[0]));
}
-#line 4180 "awkgram.c" /* yacc.c:1646 */
+#line 4166 "awkgram.c" /* yacc.c:1646 */
break;
case 191:
-#line 2004 "awkgram.y" /* yacc.c:1646 */
+#line 1990 "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 4191 "awkgram.c" /* yacc.c:1646 */
+#line 4177 "awkgram.c" /* yacc.c:1646 */
break;
case 192:
-#line 2014 "awkgram.y" /* yacc.c:1646 */
+#line 2000 "awkgram.y" /* yacc.c:1646 */
{
INSTRUCTION *ip = (yyvsp[0])->nexti;
if (ip->opcode == Op_push
@@ -4203,73 +4189,73 @@ regular_print:
} else
(yyval) = (yyvsp[0]);
}
-#line 4207 "awkgram.c" /* yacc.c:1646 */
+#line 4193 "awkgram.c" /* yacc.c:1646 */
break;
case 193:
-#line 2026 "awkgram.y" /* yacc.c:1646 */
+#line 2012 "awkgram.y" /* yacc.c:1646 */
{
(yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
if ((yyvsp[0]) != NULL)
mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
}
-#line 4217 "awkgram.c" /* yacc.c:1646 */
+#line 4203 "awkgram.c" /* yacc.c:1646 */
break;
case 194:
-#line 2035 "awkgram.y" /* yacc.c:1646 */
+#line 2021 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_postincrement;
}
-#line 4225 "awkgram.c" /* yacc.c:1646 */
+#line 4211 "awkgram.c" /* yacc.c:1646 */
break;
case 195:
-#line 2039 "awkgram.y" /* yacc.c:1646 */
+#line 2025 "awkgram.y" /* yacc.c:1646 */
{
(yyvsp[0])->opcode = Op_postdecrement;
}
-#line 4233 "awkgram.c" /* yacc.c:1646 */
+#line 4219 "awkgram.c" /* yacc.c:1646 */
break;
case 196:
-#line 2042 "awkgram.y" /* yacc.c:1646 */
+#line 2028 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
-#line 4239 "awkgram.c" /* yacc.c:1646 */
+#line 4225 "awkgram.c" /* yacc.c:1646 */
break;
case 198:
-#line 2050 "awkgram.y" /* yacc.c:1646 */
+#line 2036 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
-#line 4245 "awkgram.c" /* yacc.c:1646 */
+#line 4231 "awkgram.c" /* yacc.c:1646 */
break;
case 199:
-#line 2054 "awkgram.y" /* yacc.c:1646 */
+#line 2040 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
-#line 4251 "awkgram.c" /* yacc.c:1646 */
+#line 4237 "awkgram.c" /* yacc.c:1646 */
break;
case 202:
-#line 2063 "awkgram.y" /* yacc.c:1646 */
+#line 2049 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
-#line 4257 "awkgram.c" /* yacc.c:1646 */
+#line 4243 "awkgram.c" /* yacc.c:1646 */
break;
case 203:
-#line 2067 "awkgram.y" /* yacc.c:1646 */
+#line 2053 "awkgram.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); yyerrok; }
-#line 4263 "awkgram.c" /* yacc.c:1646 */
+#line 4249 "awkgram.c" /* yacc.c:1646 */
break;
case 204:
-#line 2071 "awkgram.y" /* yacc.c:1646 */
+#line 2057 "awkgram.y" /* yacc.c:1646 */
{ yyerrok; }
-#line 4269 "awkgram.c" /* yacc.c:1646 */
+#line 4255 "awkgram.c" /* yacc.c:1646 */
break;
-#line 4273 "awkgram.c" /* yacc.c:1646 */
+#line 4259 "awkgram.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -4497,7 +4483,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 2073 "awkgram.y" /* yacc.c:1906 */
+#line 2059 "awkgram.y" /* yacc.c:1906 */
struct token {
diff --git a/awkgram.y b/awkgram.y
index 89f1fe1c..62fe8caa 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -516,7 +516,6 @@ regexp
typed_regexp
: TYPED_REGEXP
{
- NODE *n, *exp, *n2;
char *re;
size_t len;
@@ -524,22 +523,9 @@ typed_regexp
$1->lextok = NULL;
len = strlen(re);
- exp = make_str_node(re, len, ALREADY_MALLOCED);
- n = make_regnode(Node_regex, exp);
- if (n == NULL) {
- unref(exp);
- YYABORT;
- }
-
- n2 = make_string(re, len);
- n2->typed_re = n;
- n2->numbr = 0;
- n2->flags |= NUMCUR|STRCUR|REGEX;
- n2->flags &= ~(STRING|NUMBER);
-
$$ = $1;
$$->opcode = Op_push_re;
- $$->memory = n2;
+ $$->memory = make_typed_regex(re, len);
}
a_slash
diff --git a/builtin.c b/builtin.c
index 5d7c3764..f71d71dd 100644
--- a/builtin.c
+++ b/builtin.c
@@ -3988,7 +3988,6 @@ do_typeof(int nargs)
deref = false;
break;
case Node_val:
- case Node_var:
switch (fixtype(arg)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
case STRING:
res = "string";
@@ -4017,6 +4016,14 @@ do_typeof(int nargs)
res = "untyped";
deref = false;
break;
+ case Node_var:
+ /*
+ * Note: this doesn't happen because the function calling code
+ * in interpret.h pushes Node_var->var_value.
+ */
+ fatal(_("typeof: invalid argument type `%s'"),
+ nodetype2str(arg->type));
+ break;
default:
fatal(_("typeof: unknown argument type `%s'"),
nodetype2str(arg->type));
diff --git a/doc/ChangeLog b/doc/ChangeLog
index c9c618d2..3a4978d9 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,8 @@
+2016-12-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Minor edits after merging branches and some
+ additional work in the code.
+
2016-12-17 Arnold D. Robbins <arnold@skeeve.com>
* gawktexi.in: Further API clarifications and edits, add a
@@ -12,6 +17,27 @@
* gawktexi.in: Update description of awk_ext_func_t structure.
+2016-12-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in: Document strnum changes as relates to API.
+ Still stuff left to do -- tables for type conversions need
+ to be updated to show new strnum and regex rows and columns.
+
+2016-12-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in: Remove make_regex and replace it with make_const_regex
+ and make_malloced_regex.
+
+2016-12-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in: Document new flatten_array_typed API function, and
+ indicate that the old flatten_array function has been superseded.
+
+2016-11-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Document typed regex changes as relates to API.
+ Still stuff left to do.
+
2016-11-21 Arnold D. Robbins <arnold@skeeve.com>
* gawktexi.in: Finish off discussion of strongly typed regexp
diff --git a/doc/gawk.info b/doc/gawk.info
index 9033acab..3169ff0c 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -23625,6 +23625,8 @@ use them.
' AWK_UNDEFINED,'
' AWK_NUMBER,'
' AWK_STRING,'
+' AWK_REGEX,'
+' AWK_STRNUM,'
' AWK_ARRAY,'
' AWK_SCALAR, /* opaque access to a variable */'
' AWK_VALUE_COOKIE /* for updating a previously created value */'
@@ -23647,6 +23649,8 @@ use them.
type.
'#define str_value u.s'
+'#define strnum_value str_value'
+'#define regex_value str_value'
'#define num_value u.d'
'#define array_cookie u.a'
'#define scalar_cookie u.scl'
@@ -23665,15 +23669,27 @@ use them.
This is also discussed in a general fashion in the text following
this list, and in more detail in *note Cached values::.
- Scalar values in 'awk' are either numbers or strings. The
-'awk_value_t' struct represents values. The 'val_type' member indicates
-what is in the 'union'.
+ Scalar values in 'awk' are numbers, strings, strnums, or typed
+regexps. The 'awk_value_t' struct represents values. The 'val_type'
+member indicates what is in the 'union'.
Representing numbers is easy--the API uses a C 'double'. Strings
require more work. Because 'gawk' allows embedded NUL bytes in string
values, a string must be represented as a pair containing a data pointer
and length. This is the 'awk_string_t' type.
+ A strnum (numeric string) value is represented as a string and
+consists of user input data that appears to be numeric. When an
+extension creates a strnum value, the result is a string flagged as user
+input. Subsequent parsing by 'gawk' then determines whether it looks
+like a number and should be treated as a strnum, or as a regular string.
+
+ Typed regexp values (*note Strong Regexp Constants::) are not of much
+use to extension functions. Extension functions can tell that they've
+received them, and create them for scalar values. Otherwise, they can
+examine the text of the regexp through 'regex_value.str' and
+'regex_value.len'.
+
Identifiers (i.e., the names of global variables) can be associated
with either scalar values or with arrays. In addition, 'gawk' provides
true arrays of arrays, where any given array element can itself be an
@@ -23833,6 +23849,31 @@ code would use them:
This function simply creates a numeric value in the 'awk_value_t'
variable pointed to by 'result'.
+'static inline awk_value_t *'
+'make_const_user_input(const char *string, size_t length, awk_value_t *result);'
+ This function is identical to 'make_const_string()', but the string
+ is flagged as user input that should be treated as a strnum value
+ if the contents of the string are numeric.
+
+'static inline awk_value_t *'
+'make_malloced_user_input(const char *string, size_t length, awk_value_t *result);'
+ This function is identical to 'make_malloced_string()', but the
+ string is flagged as user input that should be treated as a strnum
+ value if the contents of the string are numeric.
+
+'static inline awk_value_t *'
+'make_const_regex(const char *string, size_t length, awk_value_t *result);'
+ This function creates a strongly typed regexp value by allocating a
+ copy of the string. 'string' is the regular expression of length
+ 'len'.
+
+'static inline awk_value_t *'
+'make_malloced_regex(const char *string, size_t length, awk_value_t *result);'
+ This function creates a strongly typed regexp value. 'string' is
+ the regular expression of length 'len'. It expects 'string' to be
+ a 'char *' value pointing to data previously obtained from
+ 'gawk_malloc()', 'gawk_calloc()', or 'gawk_realloc()'.
+

File: gawk.info, Node: Registration Functions, Next: Printing Messages, Prev: Constructor Functions, Up: Extension API Description
@@ -24580,8 +24621,9 @@ was discussed earlier, in *note General Data Types::.
'awk_bool_t sym_update_scalar(awk_scalar_t cookie, awk_value_t *value);'
Update the value associated with a scalar cookie. Return false if
- the new value is not of type 'AWK_STRING' or 'AWK_NUMBER'. Here
- too, the predefined variables may not be updated.
+ the new value is not of type 'AWK_STRING', 'AWK_STRNUM',
+ 'AWK_REGEX', or 'AWK_NUMBER'. Here too, the predefined variables
+ may not be updated.
It is not obvious at first glance how to work with scalar cookies or
what their raison d'e^tre really is. In theory, the 'sym_lookup()' and
@@ -24695,10 +24737,10 @@ follows:
'awk_bool_t create_value(awk_value_t *value, awk_value_cookie_t *result);'
Create a cached string or numeric value from 'value' for efficient
- later assignment. Only values of type 'AWK_NUMBER' and
- 'AWK_STRING' are allowed. Any other type is rejected.
- 'AWK_UNDEFINED' could be allowed, but doing so would result in
- inferior performance.
+ later assignment. Only values of type 'AWK_NUMBER', 'AWK_REGEX',
+ 'AWK_STRNUM', and 'AWK_STRING' are allowed. Any other type is
+ rejected. 'AWK_UNDEFINED' could be allowed, but doing so would
+ result in inferior performance.
'awk_bool_t release_value(awk_value_cookie_t vc);'
Release the memory associated with a value cookie obtained from
@@ -24925,12 +24967,21 @@ The following functions relate to individual array elements:
array, but after calling this function, it has no elements. This
is equivalent to using the 'delete' statement (*note Delete::).
+'awk_bool_t flatten_array_typed(awk_array_t a_cookie, awk_flat_array_t **data, awk_valtype_t index_type, awk_valtype_t value_type);'
+ For the array represented by 'a_cookie', create an
+ 'awk_flat_array_t' structure and fill it in with indices and values
+ of the requested types. Set the pointer whose address is passed as
+ 'data' to point to this structure. Return true upon success, or
+ false otherwise. *Note Flattening Arrays::, for a discussion of
+ how to flatten an array and work with it.
+
'awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data);'
For the array represented by 'a_cookie', create an
- 'awk_flat_array_t' structure and fill it in. Set the pointer whose
- address is passed as 'data' to point to this structure. Return
- true upon success, or false otherwise. *Note Flattening Arrays::,
- for a discussion of how to flatten an array and work with it.
+ 'awk_flat_array_t' structure and fill it in with 'AWK_STRING'
+ indices and 'AWK_UNDEFINED' values. This is superseded by
+ 'flatten_array_typed()'. It is provided as a macro, and remains
+ convenience and for source code compatibility with the previous
+ version of the API.
'awk_bool_t release_flattened_array(awk_array_t a_cookie,'
' awk_flat_array_t *data);'
@@ -25032,7 +25083,7 @@ count of elements in the array and print it:
double-check that the count in the 'awk_flat_array_t' is the same as the
count just retrieved:
- if (! flatten_array(value2.array_cookie, & flat_array)) {
+ if (! flatten_array_typed(value2.array_cookie, & flat_array, AWK_STRING, AWK_UNDEFINED)) {
printf("dump_array_and_delete: could not flatten array\n");
goto out;
}
@@ -25348,7 +25399,7 @@ versions are available at compile time as C preprocessor defines to
support conditional compilation, and as enum constants to facilitate
debugging:
-API Version C preprocessor define enum constant
+API Version C Preprocessor Define enum constant
--------------------------------------------------------------------
Major 'gawk_api_major_version' 'GAWK_API_MAJOR_VERSION'
Minor 'gawk_api_minor_version' 'GAWK_API_MINOR_VERSION'
@@ -28141,6 +28192,12 @@ to different non-Unix operating systems:
Various '.c', '.y', and '.h' files
These files contain the actual 'gawk' source code.
+'support/*'
+ C header and source files for routines that 'gawk' uses, but that
+ are not part of its core functionality. For example, argument
+ parsing, regular expression matching, and random number generating
+ routines are all kept here.
+
'ABOUT-NLS'
A file containing information about GNU 'gettext' and translations.
@@ -32665,7 +32722,7 @@ Index
* arrays, unassigned elements: Reference to Elements.
(line 18)
* artificial intelligence, gawk and: Distribution contents.
- (line 52)
+ (line 58)
* ASCII: Ordinal Functions. (line 45)
* ASCII <1>: Glossary. (line 196)
* asort: String Functions. (line 42)
@@ -35144,7 +35201,7 @@ Index
* Texinfo <2>: Dupword Program. (line 17)
* Texinfo <3>: Extract Program. (line 12)
* Texinfo <4>: Distribution contents.
- (line 77)
+ (line 83)
* Texinfo <5>: Adding Code. (line 100)
* Texinfo, chapter beginnings in files: Regexp Operators. (line 22)
* Texinfo, extracting programs from source files: Extract Program.
@@ -35806,142 +35863,142 @@ Ref: figure-call-new-function948497
Node: Extension API Description950559
Node: Extension API Functions Introduction952201
Node: General Data Types957512
-Ref: General Data Types-Footnote-1963467
-Node: Memory Allocation Functions963766
-Ref: Memory Allocation Functions-Footnote-1966611
-Node: Constructor Functions966710
-Node: Registration Functions968455
-Node: Extension Functions969140
-Node: Exit Callback Functions974338
-Node: Extension Version String975588
-Node: Input Parsers976251
-Node: Output Wrappers986133
-Node: Two-way processors990645
-Node: Printing Messages992910
-Ref: Printing Messages-Footnote-1994081
-Node: Updating ERRNO994234
-Node: Requesting Values994973
-Ref: table-value-types-returned995710
-Node: Accessing Parameters996593
-Node: Symbol Table Access997828
-Node: Symbol table by name998340
-Node: Symbol table by cookie1000129
-Ref: Symbol table by cookie-Footnote-11004281
-Node: Cached values1004345
-Ref: Cached values-Footnote-11007852
-Node: Array Manipulation1007943
-Ref: Array Manipulation-Footnote-11009034
-Node: Array Data Types1009071
-Ref: Array Data Types-Footnote-11011729
-Node: Array Functions1011821
-Node: Flattening Arrays1015679
-Node: Creating Arrays1022587
-Node: Redirection API1027356
-Node: Extension API Variables1030187
-Node: Extension Versioning1030820
-Ref: gawk-api-version1031257
-Node: Extension API Informational Variables1032985
-Node: Extension API Boilerplate1034049
-Node: Changes from API V11037911
-Node: Finding Extensions1038571
-Node: Extension Example1039130
-Node: Internal File Description1039928
-Node: Internal File Ops1044008
-Ref: Internal File Ops-Footnote-11055408
-Node: Using Internal File Ops1055548
-Ref: Using Internal File Ops-Footnote-11057931
-Node: Extension Samples1058205
-Node: Extension Sample File Functions1059734
-Node: Extension Sample Fnmatch1067383
-Node: Extension Sample Fork1068870
-Node: Extension Sample Inplace1070088
-Node: Extension Sample Ord1073298
-Node: Extension Sample Readdir1074134
-Ref: table-readdir-file-types1075023
-Node: Extension Sample Revout1075828
-Node: Extension Sample Rev2way1076417
-Node: Extension Sample Read write array1077157
-Node: Extension Sample Readfile1079099
-Node: Extension Sample Time1080194
-Node: Extension Sample API Tests1081542
-Node: gawkextlib1082034
-Node: Extension summary1084481
-Node: Extension Exercises1088183
-Node: Language History1089681
-Node: V7/SVR3.11091337
-Node: SVR41093489
-Node: POSIX1094923
-Node: BTL1096302
-Node: POSIX/GNU1097031
-Node: Feature History1102893
-Node: Common Extensions1117263
-Node: Ranges and Locales1118546
-Ref: Ranges and Locales-Footnote-11123162
-Ref: Ranges and Locales-Footnote-21123189
-Ref: Ranges and Locales-Footnote-31123424
-Node: Contributors1123645
-Node: History summary1129205
-Node: Installation1130585
-Node: Gawk Distribution1131529
-Node: Getting1132013
-Node: Extracting1132974
-Node: Distribution contents1134612
-Node: Unix Installation1140697
-Node: Quick Installation1141379
-Node: Shell Startup Files1143793
-Node: Additional Configuration Options1144871
-Node: Configuration Philosophy1146676
-Node: Non-Unix Installation1149045
-Node: PC Installation1149505
-Node: PC Binary Installation1150343
-Node: PC Compiling1150778
-Node: PC Using1151895
-Node: Cygwin1154940
-Node: MSYS1155710
-Node: VMS Installation1156211
-Node: VMS Compilation1157002
-Ref: VMS Compilation-Footnote-11158231
-Node: VMS Dynamic Extensions1158289
-Node: VMS Installation Details1159974
-Node: VMS Running1162227
-Node: VMS GNV1166506
-Node: VMS Old Gawk1167241
-Node: Bugs1167712
-Node: Bug address1168375
-Node: Usenet1170772
-Node: Maintainers1171547
-Node: Other Versions1172923
-Node: Installation summary1179507
-Node: Notes1180542
-Node: Compatibility Mode1181407
-Node: Additions1182189
-Node: Accessing The Source1183114
-Node: Adding Code1184549
-Node: New Ports1190768
-Node: Derived Files1195256
-Ref: Derived Files-Footnote-11200741
-Ref: Derived Files-Footnote-21200776
-Ref: Derived Files-Footnote-31201374
-Node: Future Extensions1201488
-Node: Implementation Limitations1202146
-Node: Extension Design1203329
-Node: Old Extension Problems1204483
-Ref: Old Extension Problems-Footnote-11206001
-Node: Extension New Mechanism Goals1206058
-Ref: Extension New Mechanism Goals-Footnote-11209422
-Node: Extension Other Design Decisions1209611
-Node: Extension Future Growth1211724
-Node: Old Extension Mechanism1212560
-Node: Notes summary1214323
-Node: Basic Concepts1215505
-Node: Basic High Level1216186
-Ref: figure-general-flow1216468
-Ref: figure-process-flow1217153
-Ref: Basic High Level-Footnote-11220454
-Node: Basic Data Typing1220639
-Node: Glossary1223967
-Node: Copying1255914
-Node: GNU Free Documentation License1293453
-Node: Index1318571
+Ref: General Data Types-Footnote-1964235
+Node: Memory Allocation Functions964534
+Ref: Memory Allocation Functions-Footnote-1967379
+Node: Constructor Functions967478
+Node: Registration Functions970477
+Node: Extension Functions971162
+Node: Exit Callback Functions976360
+Node: Extension Version String977610
+Node: Input Parsers978273
+Node: Output Wrappers988155
+Node: Two-way processors992667
+Node: Printing Messages994932
+Ref: Printing Messages-Footnote-1996103
+Node: Updating ERRNO996256
+Node: Requesting Values996995
+Ref: table-value-types-returned997732
+Node: Accessing Parameters998615
+Node: Symbol Table Access999850
+Node: Symbol table by name1000362
+Node: Symbol table by cookie1002151
+Ref: Symbol table by cookie-Footnote-11006336
+Node: Cached values1006400
+Ref: Cached values-Footnote-11009936
+Node: Array Manipulation1010027
+Ref: Array Manipulation-Footnote-11011118
+Node: Array Data Types1011155
+Ref: Array Data Types-Footnote-11013813
+Node: Array Functions1013905
+Node: Flattening Arrays1018300
+Node: Creating Arrays1025241
+Node: Redirection API1030010
+Node: Extension API Variables1032841
+Node: Extension Versioning1033474
+Ref: gawk-api-version1033911
+Node: Extension API Informational Variables1035639
+Node: Extension API Boilerplate1036703
+Node: Changes from API V11040565
+Node: Finding Extensions1041225
+Node: Extension Example1041784
+Node: Internal File Description1042582
+Node: Internal File Ops1046662
+Ref: Internal File Ops-Footnote-11058062
+Node: Using Internal File Ops1058202
+Ref: Using Internal File Ops-Footnote-11060585
+Node: Extension Samples1060859
+Node: Extension Sample File Functions1062388
+Node: Extension Sample Fnmatch1070037
+Node: Extension Sample Fork1071524
+Node: Extension Sample Inplace1072742
+Node: Extension Sample Ord1075952
+Node: Extension Sample Readdir1076788
+Ref: table-readdir-file-types1077677
+Node: Extension Sample Revout1078482
+Node: Extension Sample Rev2way1079071
+Node: Extension Sample Read write array1079811
+Node: Extension Sample Readfile1081753
+Node: Extension Sample Time1082848
+Node: Extension Sample API Tests1084196
+Node: gawkextlib1084688
+Node: Extension summary1087135
+Node: Extension Exercises1090837
+Node: Language History1092335
+Node: V7/SVR3.11093991
+Node: SVR41096143
+Node: POSIX1097577
+Node: BTL1098956
+Node: POSIX/GNU1099685
+Node: Feature History1105547
+Node: Common Extensions1119917
+Node: Ranges and Locales1121200
+Ref: Ranges and Locales-Footnote-11125816
+Ref: Ranges and Locales-Footnote-21125843
+Ref: Ranges and Locales-Footnote-31126078
+Node: Contributors1126299
+Node: History summary1131859
+Node: Installation1133239
+Node: Gawk Distribution1134183
+Node: Getting1134667
+Node: Extracting1135628
+Node: Distribution contents1137266
+Node: Unix Installation1143608
+Node: Quick Installation1144290
+Node: Shell Startup Files1146704
+Node: Additional Configuration Options1147782
+Node: Configuration Philosophy1149587
+Node: Non-Unix Installation1151956
+Node: PC Installation1152416
+Node: PC Binary Installation1153254
+Node: PC Compiling1153689
+Node: PC Using1154806
+Node: Cygwin1157851
+Node: MSYS1158621
+Node: VMS Installation1159122
+Node: VMS Compilation1159913
+Ref: VMS Compilation-Footnote-11161142
+Node: VMS Dynamic Extensions1161200
+Node: VMS Installation Details1162885
+Node: VMS Running1165138
+Node: VMS GNV1169417
+Node: VMS Old Gawk1170152
+Node: Bugs1170623
+Node: Bug address1171286
+Node: Usenet1173683
+Node: Maintainers1174458
+Node: Other Versions1175834
+Node: Installation summary1182418
+Node: Notes1183453
+Node: Compatibility Mode1184318
+Node: Additions1185100
+Node: Accessing The Source1186025
+Node: Adding Code1187460
+Node: New Ports1193679
+Node: Derived Files1198167
+Ref: Derived Files-Footnote-11203652
+Ref: Derived Files-Footnote-21203687
+Ref: Derived Files-Footnote-31204285
+Node: Future Extensions1204399
+Node: Implementation Limitations1205057
+Node: Extension Design1206240
+Node: Old Extension Problems1207394
+Ref: Old Extension Problems-Footnote-11208912
+Node: Extension New Mechanism Goals1208969
+Ref: Extension New Mechanism Goals-Footnote-11212333
+Node: Extension Other Design Decisions1212522
+Node: Extension Future Growth1214635
+Node: Old Extension Mechanism1215471
+Node: Notes summary1217234
+Node: Basic Concepts1218416
+Node: Basic High Level1219097
+Ref: figure-general-flow1219379
+Ref: figure-process-flow1220064
+Ref: Basic High Level-Footnote-11223365
+Node: Basic Data Typing1223550
+Node: Glossary1226878
+Node: Copying1258825
+Node: GNU Free Documentation License1296364
+Node: Index1321482

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 4998f81e..2a7f1c58 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -32557,6 +32557,8 @@ multibyte encoding.
@itemx @ @ @ @ AWK_UNDEFINED,
@itemx @ @ @ @ AWK_NUMBER,
@itemx @ @ @ @ AWK_STRING,
+@itemx @ @ @ @ AWK_REGEX,
+@itemx @ @ @ @ AWK_STRNUM,
@itemx @ @ @ @ AWK_ARRAY,
@itemx @ @ @ @ AWK_SCALAR,@ @ @ @ @ @ @ @ @ /* opaque access to a variable */
@itemx @ @ @ @ AWK_VALUE_COOKIE@ @ @ @ /* for updating a previously created value */
@@ -32579,6 +32581,8 @@ The @code{val_type} member indicates what kind of value the
@code{union} holds, and each member is of the appropriate type.
@item #define str_value@ @ @ @ @ @ u.s
+@itemx #define strnum_value@ @ @ @ str_value
+@itemx #define regex_value@ @ @ @ str_value
@itemx #define num_value@ @ @ @ @ @ u.d
@itemx #define array_cookie@ @ @ u.a
@itemx #define scalar_cookie@ @ u.scl
@@ -32599,7 +32603,7 @@ and in more detail in @ref{Cached values}.
@end table
-Scalar values in @command{awk} are either numbers or strings. The
+Scalar values in @command{awk} are numbers, strings, strnums, or typed regexps. The
@code{awk_value_t} struct represents values. The @code{val_type} member
indicates what is in the @code{union}.
@@ -32608,6 +32612,18 @@ require more work. Because @command{gawk} allows embedded @sc{nul} bytes
in string values, a string must be represented as a pair containing a
data pointer and length. This is the @code{awk_string_t} type.
+A strnum (numeric string) value is represented as a string and consists
+of user input data that appears to be numeric.
+When an extension creates a strnum value, the result is a string flagged
+as user input. Subsequent parsing by @command{gawk} then determines whether it
+looks like a number and should be treated as a strnum, or as a regular string.
+
+Typed regexp values (@pxref{Strong Regexp Constants}) are not of
+much use to extension functions. Extension functions can tell that
+they've received them, and create them for scalar values. Otherwise,
+they can examine the text of the regexp through @code{regex_value.str}
+and @code{regex_value.len}.
+
Identifiers (i.e., the names of global variables) can be associated
with either scalar values or with arrays. In addition, @command{gawk}
provides true arrays of arrays, where any given array element can
@@ -32774,6 +32790,31 @@ It returns @code{result}.
@itemx make_number(double num, awk_value_t *result);
This function simply creates a numeric value in the @code{awk_value_t} variable
pointed to by @code{result}.
+
+@item static inline awk_value_t *
+@itemx make_const_user_input(const char *string, size_t length, awk_value_t *result);
+This function is identical to @code{make_const_string()}, but the string is
+flagged as user input that should be treated as a strnum value if the contents
+of the string are numeric.
+
+@item static inline awk_value_t *
+@itemx make_malloced_user_input(const char *string, size_t length, awk_value_t *result);
+This function is identical to @code{make_malloced_string()}, but the string is
+flagged as user input that should be treated as a strnum value if the contents
+of the string are numeric.
+
+@item static inline awk_value_t *
+@itemx make_const_regex(const char *string, size_t length, awk_value_t *result);
+This function creates a strongly typed regexp value by allocating a copy of the string.
+@code{string} is the regular expression of length @code{len}.
+
+@item static inline awk_value_t *
+@itemx make_malloced_regex(const char *string, size_t length, awk_value_t *result);
+This function creates a strongly typed regexp value.
+@code{string} is the regular expression of length @code{len}.
+It expects @code{string} to be a @samp{char *}
+value pointing to data previously obtained from @code{gawk_malloc()}, @code{gawk_calloc()}, or @code{gawk_realloc()}.
+
@end table
@node Registration Functions
@@ -33458,6 +33499,7 @@ value type, as appropriate. This behavior is summarized in
@float Table,table-value-types-returned
@caption{API value types returned}
+@c FIXME: This needs doing.
@docbook
<informaltable>
<tgroup cols="6">
@@ -33533,6 +33575,7 @@ value type, as appropriate. This behavior is summarized in
</informaltable>
@end docbook
+@c FIXME: This needs doing.
@ifnotplaintext
@ifnotdocbook
@multitable @columnfractions .50 .50
@@ -33555,27 +33598,28 @@ value type, as appropriate. This behavior is summarized in
@end ifnotplaintext
@ifplaintext
@example
- +-------------------------------------------------+
- | Type of Actual Value: |
- +------------+------------+-----------+-----------+
- | String | Number | Array | Undefined |
-+-----------+-----------+------------+------------+-----------+-----------+
-| | String | String | String | False | False |
-| |-----------+------------+------------+-----------+-----------+
-| | Number | Number if | Number | False | False |
-| | | can be | | | |
-| | | converted, | | | |
-| | | else false | | | |
-| |-----------+------------+------------+-----------+-----------+
-| Type | Array | False | False | Array | False |
-| Requested |-----------+------------+------------+-----------+-----------+
-| | Scalar | Scalar | Scalar | False | False |
-| |-----------+------------+------------+-----------+-----------+
-| | Undefined | String | Number | Array | Undefined |
-| |-----------+------------+------------+-----------+-----------+
-| | Value | False | False | False | False |
-| | cookie | | | | |
-+-----------+-----------+------------+------------+-----------+-----------+
+ +-------------------------------------------------------+
+ | Type of Actual Value: |
+ +--------+--------+--------+--------+-------+-----------+
+ | String | Strnum | Number | Regex | Array | Undefined |
++-----------+-----------+--------+--------+--------+--------+-------+-----------+
+| | String | String | String | String | String | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Strnum | false | Strnum | Strnum | false | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Number | Number | Number | Number | false | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Regex | false | false | false | Regex | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| Type | Array | false | false | false | false | Array | false |
+| Requested +-----------+--------+--------+--------+--------+-------+-----------+
+| | Scalar | Scalar | Scalar | Scalar | Scalar | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Undefined | String | Strnum | Number | Regex | Array | Undefined |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Value | false | false | false | false | false | false |
+| | Cookie | | | | | | |
++-----------+-----------+--------+--------+--------+--------+-------+-----------+
@end example
@end ifplaintext
@end float
@@ -33675,7 +33719,7 @@ Return false if the value cannot be retrieved.
@item awk_bool_t sym_update_scalar(awk_scalar_t cookie, awk_value_t *value);
Update the value associated with a scalar cookie. Return false if
-the new value is not of type @code{AWK_STRING} or @code{AWK_NUMBER}.
+the new value is not of type @code{AWK_STRING}, @code{AWK_STRNUM}, @code{AWK_REGEX}, or @code{AWK_NUMBER}.
Here too, the predefined variables may not be updated.
@end table
@@ -33796,7 +33840,7 @@ is what the routines in this @value{SECTION} let you do. The functions are as f
@table @code
@item awk_bool_t create_value(awk_value_t *value, awk_value_cookie_t *result);
Create a cached string or numeric value from @code{value} for
-efficient later assignment. Only values of type @code{AWK_NUMBER}
+efficient later assignment. Only values of type @code{AWK_NUMBER}, @code{AWK_REGEX}, @code{AWK_STRNUM},
and @code{AWK_STRING} are allowed. Any other type is rejected.
@code{AWK_UNDEFINED} could be allowed, but doing so would result in
inferior performance.
@@ -34022,9 +34066,10 @@ The array remains an array, but after calling this function, it
has no elements. This is equivalent to using the @code{delete}
statement (@pxref{Delete}).
-@item awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data);
+@item awk_bool_t flatten_array_typed(awk_array_t a_cookie, awk_flat_array_t **data, awk_valtype_t index_type, awk_valtype_t value_type);
For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t}
-structure and fill it in. Set the pointer whose address is passed as @code{data}
+structure and fill it in with indices and values of the requested types.
+Set the pointer whose address is passed as @code{data}
to point to this structure.
Return true upon success, or false otherwise.
@ifset FOR_PRINT
@@ -34036,6 +34081,14 @@ See the next @value{SECTION}
for a discussion of how to
flatten an array and work with it.
+@item awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data);
+For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t}
+structure and fill it in with @code{AWK_STRING} indices and
+@code{AWK_UNDEFINED} values.
+This is superseded by @code{flatten_array_typed()}.
+It is provided as a macro, and remains convenience and for source code
+compatibility with the previous version of the API.
+
@item awk_bool_t release_flattened_array(awk_array_t a_cookie,
@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_flat_array_t *data);
When done with a flattened array, release the storage using this function.
@@ -34148,7 +34201,7 @@ to double-check that the count in the @code{awk_flat_array_t}
is the same as the count just retrieved:
@example
- if (! flatten_array(value2.array_cookie, & flat_array)) @{
+ if (! flatten_array_typed(value2.array_cookie, & flat_array, AWK_STRING, AWK_UNDEFINED)) @{
printf("dump_array_and_delete: could not flatten array\n");
goto out;
@}
@@ -34540,7 +34593,7 @@ debugging:
@float Table,gawk-api-version
@caption{gawk API version constants}
@multitable {@b{API Version}} {@code{gawk_api_major_version}} {@code{GAWK_API_MAJOR_VERSION}}
-@headitem API Version @tab C preprocessor define @tab enum constant
+@headitem API Version @tab C Preprocessor Define @tab enum constant
@item Major @tab @code{gawk_api_major_version} @tab @code{GAWK_API_MAJOR_VERSION}
@item Minor @tab @code{gawk_api_minor_version} @tab @code{GAWK_API_MINOR_VERSION}
@end multitable
@@ -38196,6 +38249,12 @@ These files contain the actual @command{gawk} source code.
@end table
@table @file
+@item support/*
+C header and source files for routines that @command{gawk}
+uses, but that are not part of its core functionality.
+For example, argument parsing, regular expression matching,
+and random number generating routines are all kept here.
+
@item ABOUT-NLS
A file containing information about GNU @command{gettext} and translations.
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index ca571514..c8c66d2d 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -31571,6 +31571,8 @@ multibyte encoding.
@itemx @ @ @ @ AWK_UNDEFINED,
@itemx @ @ @ @ AWK_NUMBER,
@itemx @ @ @ @ AWK_STRING,
+@itemx @ @ @ @ AWK_REGEX,
+@itemx @ @ @ @ AWK_STRNUM,
@itemx @ @ @ @ AWK_ARRAY,
@itemx @ @ @ @ AWK_SCALAR,@ @ @ @ @ @ @ @ @ /* opaque access to a variable */
@itemx @ @ @ @ AWK_VALUE_COOKIE@ @ @ @ /* for updating a previously created value */
@@ -31593,6 +31595,8 @@ The @code{val_type} member indicates what kind of value the
@code{union} holds, and each member is of the appropriate type.
@item #define str_value@ @ @ @ @ @ u.s
+@itemx #define strnum_value@ @ @ @ str_value
+@itemx #define regex_value@ @ @ @ str_value
@itemx #define num_value@ @ @ @ @ @ u.d
@itemx #define array_cookie@ @ @ u.a
@itemx #define scalar_cookie@ @ u.scl
@@ -31613,7 +31617,7 @@ and in more detail in @ref{Cached values}.
@end table
-Scalar values in @command{awk} are either numbers or strings. The
+Scalar values in @command{awk} are numbers, strings, strnums, or typed regexps. The
@code{awk_value_t} struct represents values. The @code{val_type} member
indicates what is in the @code{union}.
@@ -31622,6 +31626,18 @@ require more work. Because @command{gawk} allows embedded @sc{nul} bytes
in string values, a string must be represented as a pair containing a
data pointer and length. This is the @code{awk_string_t} type.
+A strnum (numeric string) value is represented as a string and consists
+of user input data that appears to be numeric.
+When an extension creates a strnum value, the result is a string flagged
+as user input. Subsequent parsing by @command{gawk} then determines whether it
+looks like a number and should be treated as a strnum, or as a regular string.
+
+Typed regexp values (@pxref{Strong Regexp Constants}) are not of
+much use to extension functions. Extension functions can tell that
+they've received them, and create them for scalar values. Otherwise,
+they can examine the text of the regexp through @code{regex_value.str}
+and @code{regex_value.len}.
+
Identifiers (i.e., the names of global variables) can be associated
with either scalar values or with arrays. In addition, @command{gawk}
provides true arrays of arrays, where any given array element can
@@ -31788,6 +31804,31 @@ It returns @code{result}.
@itemx make_number(double num, awk_value_t *result);
This function simply creates a numeric value in the @code{awk_value_t} variable
pointed to by @code{result}.
+
+@item static inline awk_value_t *
+@itemx make_const_user_input(const char *string, size_t length, awk_value_t *result);
+This function is identical to @code{make_const_string()}, but the string is
+flagged as user input that should be treated as a strnum value if the contents
+of the string are numeric.
+
+@item static inline awk_value_t *
+@itemx make_malloced_user_input(const char *string, size_t length, awk_value_t *result);
+This function is identical to @code{make_malloced_string()}, but the string is
+flagged as user input that should be treated as a strnum value if the contents
+of the string are numeric.
+
+@item static inline awk_value_t *
+@itemx make_const_regex(const char *string, size_t length, awk_value_t *result);
+This function creates a strongly typed regexp value by allocating a copy of the string.
+@code{string} is the regular expression of length @code{len}.
+
+@item static inline awk_value_t *
+@itemx make_malloced_regex(const char *string, size_t length, awk_value_t *result);
+This function creates a strongly typed regexp value.
+@code{string} is the regular expression of length @code{len}.
+It expects @code{string} to be a @samp{char *}
+value pointing to data previously obtained from @code{gawk_malloc()}, @code{gawk_calloc()}, or @code{gawk_realloc()}.
+
@end table
@node Registration Functions
@@ -32472,6 +32513,7 @@ value type, as appropriate. This behavior is summarized in
@float Table,table-value-types-returned
@caption{API value types returned}
+@c FIXME: This needs doing.
@docbook
<informaltable>
<tgroup cols="6">
@@ -32547,6 +32589,7 @@ value type, as appropriate. This behavior is summarized in
</informaltable>
@end docbook
+@c FIXME: This needs doing.
@ifnotplaintext
@ifnotdocbook
@multitable @columnfractions .50 .50
@@ -32569,27 +32612,28 @@ value type, as appropriate. This behavior is summarized in
@end ifnotplaintext
@ifplaintext
@example
- +-------------------------------------------------+
- | Type of Actual Value: |
- +------------+------------+-----------+-----------+
- | String | Number | Array | Undefined |
-+-----------+-----------+------------+------------+-----------+-----------+
-| | String | String | String | False | False |
-| |-----------+------------+------------+-----------+-----------+
-| | Number | Number if | Number | False | False |
-| | | can be | | | |
-| | | converted, | | | |
-| | | else false | | | |
-| |-----------+------------+------------+-----------+-----------+
-| Type | Array | False | False | Array | False |
-| Requested |-----------+------------+------------+-----------+-----------+
-| | Scalar | Scalar | Scalar | False | False |
-| |-----------+------------+------------+-----------+-----------+
-| | Undefined | String | Number | Array | Undefined |
-| |-----------+------------+------------+-----------+-----------+
-| | Value | False | False | False | False |
-| | cookie | | | | |
-+-----------+-----------+------------+------------+-----------+-----------+
+ +-------------------------------------------------------+
+ | Type of Actual Value: |
+ +--------+--------+--------+--------+-------+-----------+
+ | String | Strnum | Number | Regex | Array | Undefined |
++-----------+-----------+--------+--------+--------+--------+-------+-----------+
+| | String | String | String | String | String | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Strnum | false | Strnum | Strnum | false | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Number | Number | Number | Number | false | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Regex | false | false | false | Regex | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| Type | Array | false | false | false | false | Array | false |
+| Requested +-----------+--------+--------+--------+--------+-------+-----------+
+| | Scalar | Scalar | Scalar | Scalar | Scalar | false | false |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Undefined | String | Strnum | Number | Regex | Array | Undefined |
+| +-----------+--------+--------+--------+--------+-------+-----------+
+| | Value | false | false | false | false | false | false |
+| | Cookie | | | | | | |
++-----------+-----------+--------+--------+--------+--------+-------+-----------+
@end example
@end ifplaintext
@end float
@@ -32689,7 +32733,7 @@ Return false if the value cannot be retrieved.
@item awk_bool_t sym_update_scalar(awk_scalar_t cookie, awk_value_t *value);
Update the value associated with a scalar cookie. Return false if
-the new value is not of type @code{AWK_STRING} or @code{AWK_NUMBER}.
+the new value is not of type @code{AWK_STRING}, @code{AWK_STRNUM}, @code{AWK_REGEX}, or @code{AWK_NUMBER}.
Here too, the predefined variables may not be updated.
@end table
@@ -32810,7 +32854,7 @@ is what the routines in this @value{SECTION} let you do. The functions are as f
@table @code
@item awk_bool_t create_value(awk_value_t *value, awk_value_cookie_t *result);
Create a cached string or numeric value from @code{value} for
-efficient later assignment. Only values of type @code{AWK_NUMBER}
+efficient later assignment. Only values of type @code{AWK_NUMBER}, @code{AWK_REGEX}, @code{AWK_STRNUM},
and @code{AWK_STRING} are allowed. Any other type is rejected.
@code{AWK_UNDEFINED} could be allowed, but doing so would result in
inferior performance.
@@ -33036,9 +33080,10 @@ The array remains an array, but after calling this function, it
has no elements. This is equivalent to using the @code{delete}
statement (@pxref{Delete}).
-@item awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data);
+@item awk_bool_t flatten_array_typed(awk_array_t a_cookie, awk_flat_array_t **data, awk_valtype_t index_type, awk_valtype_t value_type);
For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t}
-structure and fill it in. Set the pointer whose address is passed as @code{data}
+structure and fill it in with indices and values of the requested types.
+Set the pointer whose address is passed as @code{data}
to point to this structure.
Return true upon success, or false otherwise.
@ifset FOR_PRINT
@@ -33050,6 +33095,14 @@ See the next @value{SECTION}
for a discussion of how to
flatten an array and work with it.
+@item awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data);
+For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t}
+structure and fill it in with @code{AWK_STRING} indices and
+@code{AWK_UNDEFINED} values.
+This is superseded by @code{flatten_array_typed()}.
+It is provided as a macro, and remains convenience and for source code
+compatibility with the previous version of the API.
+
@item awk_bool_t release_flattened_array(awk_array_t a_cookie,
@itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_flat_array_t *data);
When done with a flattened array, release the storage using this function.
@@ -33162,7 +33215,7 @@ to double-check that the count in the @code{awk_flat_array_t}
is the same as the count just retrieved:
@example
- if (! flatten_array(value2.array_cookie, & flat_array)) @{
+ if (! flatten_array_typed(value2.array_cookie, & flat_array, AWK_STRING, AWK_UNDEFINED)) @{
printf("dump_array_and_delete: could not flatten array\n");
goto out;
@}
@@ -33554,7 +33607,7 @@ debugging:
@float Table,gawk-api-version
@caption{gawk API version constants}
@multitable {@b{API Version}} {@code{gawk_api_major_version}} {@code{GAWK_API_MAJOR_VERSION}}
-@headitem API Version @tab C preprocessor define @tab enum constant
+@headitem API Version @tab C Preprocessor Define @tab enum constant
@item Major @tab @code{gawk_api_major_version} @tab @code{GAWK_API_MAJOR_VERSION}
@item Minor @tab @code{gawk_api_minor_version} @tab @code{GAWK_API_MINOR_VERSION}
@end multitable
@@ -37210,6 +37263,12 @@ These files contain the actual @command{gawk} source code.
@end table
@table @file
+@item support/*
+C header and source files for routines that @command{gawk}
+uses, but that are not part of its core functionality.
+For example, argument parsing, regular expression matching,
+and random number generating routines are all kept here.
+
@item ABOUT-NLS
A file containing information about GNU @command{gettext} and translations.
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 0642a955..20834b01 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,7 @@
+2016-12-22 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c (valrep2str): Update for new API types.
+
2016-12-16 Arnold D. Robbins <arnold@skeeve.com>
* filefuncs.c: Update func_table again.
@@ -41,6 +45,22 @@
* testext.c: Ditto.
* time.c: Ditto.
+2016-12-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * rwarray.c: Adjust to read and write strnum values.
+ (write_value): When writing a string value, code should use htonl.
+ There are now 3 string types: string, strnum, and regex.
+ (read_value): Support 3 string types: string, strnum, and regex.
+
+2016-11-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * rwarray.c: Restore read comparion of major and minor versions
+ to use !=.
+
+2016-11-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * rwarray.c: Adjust to read and write regexes also.
+
2016-10-23 Arnold D. Robbins <arnold@skeeve.com>
* General: Remove trailing whitespace from all relevant files.
diff --git a/extension/rwarray.c b/extension/rwarray.c
index 00ded7bf..186dac0f 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -55,11 +55,11 @@
#define MAGIC "awkrulz\n"
#define MAJOR 3
-#define MINOR 0
+#define MINOR 1
static const gawk_api_t *api; /* for convenience macros to work */
static awk_ext_id_t *ext_id;
-static const char *ext_version = "rwarray extension: version 1.0";
+static const char *ext_version = "rwarray extension: version 1.1";
static awk_bool_t (*init_func)(void) = NULL;
int plugin_is_GPL_compatible;
@@ -84,7 +84,7 @@ static awk_bool_t read_value(FILE *fp, awk_value_t *value);
* For each element:
* Length of index val: 4 bytes - network order
* Index val as characters (N bytes)
- * Value type 4 bytes (0 = string, 1 = number, 2 = array)
+ * Value type 4 bytes (0 = string, 1 = number, 2 = array, 3 = regex, 4 = strnum)
* IF string:
* Length of value 4 bytes
* Value as characters (N bytes)
@@ -210,7 +210,7 @@ write_elem(FILE *fp, awk_element_t *element)
return write_value(fp, & element->value);
}
-/* write_value --- write a number or a string or a array */
+/* write_value --- write a number or a string or a strnum or a regex or an array */
static awk_bool_t
write_value(FILE *fp, awk_value_t *val)
@@ -232,7 +232,22 @@ write_value(FILE *fp, awk_value_t *val)
if (fwrite(& val->num_value, 1, sizeof(val->num_value), fp) != sizeof(val->num_value))
return awk_false;
} else {
- code = 0;
+ switch (val->val_type) {
+ case AWK_STRING:
+ code = htonl(0);
+ break;
+ case AWK_STRNUM:
+ code = htonl(4);
+ break;
+ case AWK_REGEX:
+ code = htonl(3);
+ break;
+ default:
+ /* XXX can this happen? */
+ code = htonl(0);
+ warning(ext_id, _("array value has unknown type %d"), val->val_type);
+ break;
+ }
if (fwrite(& code, 1, sizeof(code), fp) != sizeof(code))
return awk_false;
@@ -449,7 +464,22 @@ read_value(FILE *fp, awk_value_t *value)
return awk_false;
}
len = ntohl(len);
- value->val_type = AWK_STRING;
+ switch (code) {
+ case 0:
+ value->val_type = AWK_STRING;
+ break;
+ case 3:
+ value->val_type = AWK_REGEX;
+ break;
+ case 4:
+ value->val_type = AWK_STRNUM;
+ break;
+ default:
+ /* this cannot happen! */
+ warning(ext_id, _("treating recovered value with unknown type code %d as a string"), code);
+ value->val_type = AWK_STRING;
+ break;
+ }
value->str_value.len = len;
value->str_value.str = gawk_malloc(len + 1);
memset(value->str_value.str, '\0', len + 1);
diff --git a/extension/testext.c b/extension/testext.c
index bf342182..d23ad368 100644
--- a/extension/testext.c
+++ b/extension/testext.c
@@ -70,6 +70,8 @@ valrep2str(const awk_value_t *value)
case AWK_VALUE_COOKIE:
strcpy(buf, "<value-cookie>");
break;
+ case AWK_REGEX:
+ case AWK_STRNUM:
case AWK_STRING:
if (value->str_value.len < size)
size = value->str_value.len;
diff --git a/gawkapi.c b/gawkapi.c
index 0b17dae2..4c6a2f8f 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -31,6 +31,7 @@ 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);
+static char *valtype2str(awk_valtype_t type);
/*
* api_get_argument --- get the count'th paramater, zero-based.
@@ -164,6 +165,15 @@ awk_value_to_node(const awk_value_t *retval)
ext_ret_val = make_str_node(retval->str_value.str,
retval->str_value.len, ALREADY_MALLOCED);
break;
+ case AWK_STRNUM:
+ ext_ret_val = make_str_node(retval->str_value.str,
+ retval->str_value.len, ALREADY_MALLOCED);
+ ext_ret_val->flags |= USER_INPUT;
+ break;
+ case AWK_REGEX:
+ ext_ret_val = make_typed_regex(retval->str_value.str,
+ retval->str_value.len);
+ break;
case AWK_SCALAR:
v = (NODE *) retval->scalar_cookie;
if (v->type != Node_var)
@@ -411,9 +421,9 @@ free_api_string_copies()
/* assign_string --- return a string node with NUL termination */
static inline void
-assign_string(NODE *node, awk_value_t *val)
+assign_string(NODE *node, awk_value_t *val, awk_valtype_t val_type)
{
- val->val_type = AWK_STRING;
+ val->val_type = val_type;
if (node->stptr[node->stlen] != '\0') {
/*
* This is an unterminated field string, so make a copy.
@@ -440,6 +450,19 @@ assign_string(NODE *node, awk_value_t *val)
val->str_value.len = node->stlen;
}
+/* assign_regex --- return a regex node */
+
+static inline void
+assign_regex(NODE *node, awk_value_t *val)
+{
+ /* a REGEX node cannot be an unterminated field string */
+ assert((node->flags & MALLOC) != 0);
+ assert(node->stptr[node->stlen] == '\0');
+ val->str_value.str = node->stptr;
+ val->str_value.len = node->stlen;
+ val->val_type = AWK_REGEX;
+}
+
/* node_to_awk_value --- convert a node into a value for an extension */
static awk_bool_t
@@ -476,45 +499,137 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted)
/* a scalar value */
switch (wanted) {
case AWK_NUMBER:
- val->val_type = AWK_NUMBER;
+ if (node->flags & REGEX)
+ val->val_type = AWK_REGEX;
+ else {
+ val->val_type = AWK_NUMBER;
+ (void) force_number(node);
+ val->num_value = get_number_d(node);
+ ret = awk_true;
+ }
+ break;
- (void) force_number(node);
- val->num_value = get_number_d(node);
- ret = awk_true;
+ case AWK_STRNUM:
+ switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
+ case STRING:
+ val->val_type = AWK_STRING;
+ break;
+ case NUMBER:
+ (void) force_string(node);
+ /* fall through */
+ case NUMBER|USER_INPUT:
+ assign_string(node, val, AWK_STRNUM);
+ ret = awk_true;
+ break;
+ case REGEX:
+ val->val_type = AWK_REGEX;
+ break;
+ case NUMBER|STRING:
+ if (node == Nnull_string) {
+ val->val_type = AWK_UNDEFINED;
+ break;
+ }
+ /* fall through */
+ default:
+ warning(_("node_to_awk_value detected invalid flags combination `%s'; please file a bug report."), flags2str(node->flags));
+ val->val_type = AWK_UNDEFINED;
+ break;
+ }
break;
case AWK_STRING:
(void) force_string(node);
- assign_string(node, val);
+ assign_string(node, val, AWK_STRING);
ret = awk_true;
break;
- case AWK_SCALAR:
- fixtype(node);
- if ((node->flags & NUMBER) != 0) {
+ case AWK_REGEX:
+ switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
+ case STRING:
+ val->val_type = AWK_STRING;
+ break;
+ case NUMBER:
val->val_type = AWK_NUMBER;
- } else if ((node->flags & STRING) != 0) {
+ break;
+ case NUMBER|USER_INPUT:
+ val->val_type = AWK_STRNUM;
+ break;
+ case REGEX:
+ assign_regex(node, val);
+ ret = awk_true;
+ break;
+ case NUMBER|STRING:
+ if (node == Nnull_string) {
+ val->val_type = AWK_UNDEFINED;
+ break;
+ }
+ /* fall through */
+ default:
+ warning(_("node_to_awk_value detected invalid flags combination `%s'; please file a bug report."), flags2str(node->flags));
+ val->val_type = AWK_UNDEFINED;
+ break;
+ }
+ break;
+
+ case AWK_SCALAR:
+ switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
+ case STRING:
val->val_type = AWK_STRING;
- } else
+ break;
+ case NUMBER:
+ val->val_type = AWK_NUMBER;
+ break;
+ case NUMBER|USER_INPUT:
+ val->val_type = AWK_STRNUM;
+ break;
+ case REGEX:
+ val->val_type = AWK_REGEX;
+ break;
+ case NUMBER|STRING:
+ if (node == Nnull_string) {
+ val->val_type = AWK_UNDEFINED;
+ break;
+ }
+ /* fall through */
+ default:
+ warning(_("node_to_awk_value detected invalid flags combination `%s'; please file a bug report."), flags2str(node->flags));
val->val_type = AWK_UNDEFINED;
- ret = awk_false;
+ break;
+ }
break;
case AWK_UNDEFINED:
/* return true and actual type for request of undefined */
- fixtype(node);
- if (node == Nnull_string) {
- val->val_type = AWK_UNDEFINED;
+ switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
+ case STRING:
+ assign_string(node, val, AWK_STRING);
ret = awk_true;
- } else if ((node->flags & NUMBER) != 0) {
+ break;
+ case NUMBER:
val->val_type = AWK_NUMBER;
val->num_value = get_number_d(node);
ret = awk_true;
- } else if ((node->flags & STRING) != 0) {
- assign_string(node, val);
+ break;
+ case NUMBER|USER_INPUT:
+ assign_string(node, val, AWK_STRNUM);
+ ret = awk_true;
+ break;
+ case REGEX:
+ assign_regex(node, val);
ret = awk_true;
- } else
+ break;
+ case NUMBER|STRING:
+ if (node == Nnull_string) {
+ val->val_type = AWK_UNDEFINED;
+ ret = awk_true;
+ break;
+ }
+ /* fall through */
+ default:
+ warning(_("node_to_awk_value detected invalid flags combination `%s'; please file a bug report."), flags2str(node->flags));
val->val_type = AWK_UNDEFINED;
+ break;
+ }
break;
case AWK_ARRAY:
@@ -617,7 +732,9 @@ api_sym_update(awk_ext_id_t id,
switch (value->val_type) {
case AWK_NUMBER:
+ case AWK_STRNUM:
case AWK_STRING:
+ case AWK_REGEX:
case AWK_UNDEFINED:
case AWK_ARRAY:
case AWK_SCALAR:
@@ -715,7 +832,9 @@ api_sym_update_scalar(awk_ext_id_t id,
return awk_true;
}
break;
+
case AWK_STRING:
+ case AWK_STRNUM:
if (node->var_value->valref == 1) {
NODE *r = node->var_value;
@@ -729,17 +848,22 @@ api_sym_update_scalar(awk_ext_id_t id,
/* make_str_node(s, l, ALREADY_MALLOCED): */
r->numbr = 0;
r->flags = (MALLOC|STRING|STRCUR);
+ if (value->val_type == AWK_STRNUM)
+ r->flags |= USER_INPUT;
r->stfmt = STFMT_UNUSED;
r->stptr = value->str_value.str;
r->stlen = value->str_value.len;
return awk_true;
}
break;
+
+ case AWK_REGEX:
case AWK_UNDEFINED:
case AWK_SCALAR:
case AWK_VALUE_COOKIE:
break;
+
default: /* AWK_ARRAY or invalid type */
return awk_false;
}
@@ -762,7 +886,9 @@ valid_subscript_type(awk_valtype_t valtype)
switch (valtype) {
case AWK_UNDEFINED:
case AWK_NUMBER:
+ case AWK_STRNUM:
case AWK_STRING:
+ case AWK_REGEX:
case AWK_SCALAR:
case AWK_VALUE_COOKIE:
return true;
@@ -963,12 +1089,13 @@ api_clear_array(awk_ext_id_t id, awk_array_t a_cookie)
return awk_true;
}
-/* api_flatten_array --- flatten out an array so that it can be looped over easily. */
+/* api_flatten_array_typed --- flatten out an array so that it can be looped over easily. */
static awk_bool_t
-api_flatten_array(awk_ext_id_t id,
+api_flatten_array_typed(awk_ext_id_t id,
awk_array_t a_cookie,
- awk_flat_array_t **data)
+ awk_flat_array_t **data,
+ awk_valtype_t index_type, awk_valtype_t value_type)
{
NODE **list;
size_t i, j;
@@ -985,7 +1112,7 @@ api_flatten_array(awk_ext_id_t id,
(array->table_size - 1) * sizeof(awk_element_t);
emalloc(*data, awk_flat_array_t *, alloc_size,
- "api_flatten_array");
+ "api_flatten_array_typed");
memset(*data, 0, alloc_size);
list = assoc_list(array, "@unsorted", ASORTI);
@@ -1000,21 +1127,16 @@ api_flatten_array(awk_ext_id_t id,
index = list[i];
value = list[i + 1]; /* number or string or subarray */
- /*
- * Convert index and value to ext types. Force the
- * index to be a string, since indices are always
- * conceptually strings, regardless of internal optimizations
- * to treat them as integers in some cases.
- */
+ /* Convert index and value to API types. */
if (! node_to_awk_value(index,
- & (*data)->elements[j].index, AWK_STRING)) {
- fatal(_("api_flatten_array: could not convert index %d\n"),
- (int) i);
+ & (*data)->elements[j].index, index_type)) {
+ fatal(_("api_flatten_array_typed: could not convert index %d to %s\n"),
+ (int) i, valtype2str(index_type));
}
if (! node_to_awk_value(value,
- & (*data)->elements[j].value, AWK_UNDEFINED)) {
- fatal(_("api_flatten_array: could not convert value %d\n"),
- (int) i);
+ & (*data)->elements[j].value, value_type)) {
+ fatal(_("api_flatten_array_typed: could not convert value %d to %s\n"),
+ (int) i, valtype2str(value_type));
}
}
return awk_true;
@@ -1072,7 +1194,9 @@ api_create_value(awk_ext_id_t id, awk_value_t *value,
switch (value->val_type) {
case AWK_NUMBER:
+ case AWK_STRNUM:
case AWK_STRING:
+ case AWK_REGEX:
break;
default:
/* reject anything other than a simple scalar */
@@ -1237,6 +1361,7 @@ gawk_api_t api_impl = {
api_fatal,
api_warning,
api_lintwarn,
+ api_nonfatal,
/* updating ERRNO */
api_update_ERRNO_int,
@@ -1266,7 +1391,7 @@ gawk_api_t api_impl = {
api_del_array_element,
api_create_array,
api_clear_array,
- api_flatten_array,
+ api_flatten_array_typed,
api_release_flattened_array,
/* Memory allocation */
@@ -1277,9 +1402,6 @@ gawk_api_t api_impl = {
/* Find/open a file */
api_get_file,
-
- /* Print nonfatal error message */
- api_nonfatal,
};
/* init_ext_api --- init the extension API */
@@ -1314,3 +1436,30 @@ print_ext_versions(void)
for (p = vi_head; p != NULL; p = p->next)
printf("%s\n", p->version);
}
+
+/* valtype2str --- return a printable representation of a value type */
+
+static char *
+valtype2str(awk_valtype_t type)
+{
+ static char buf[100];
+
+ // Important: keep in same order as in gawkapi.h!
+ static char *values[] = {
+ "AWK_UNDEFINED",
+ "AWK_NUMBER",
+ "AWK_STRING",
+ "AWK_REGEX",
+ "AWK_STRNUM",
+ "AWK_ARRAY",
+ "AWK_SCALAR",
+ "AWK_VALUE_COOKIE",
+ };
+
+ if (AWK_UNDEFINED <= type && type <= AWK_VALUE_COOKIE)
+ return values[(int) type];
+
+ sprintf(buf, "unknown type! (%d)", (int) type);
+
+ return buf;
+}
diff --git a/gawkapi.h b/gawkapi.h
index aae3ac0a..5071adce 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -306,6 +306,8 @@ typedef enum {
AWK_UNDEFINED,
AWK_NUMBER,
AWK_STRING,
+ AWK_REGEX,
+ AWK_STRNUM,
AWK_ARRAY,
AWK_SCALAR, /* opaque access to a variable */
AWK_VALUE_COOKIE /* for updating a previously created value */
@@ -325,6 +327,8 @@ typedef struct awk_value {
awk_value_cookie_t vc;
} u;
#define str_value u.s
+#define strnum_value str_value
+#define regex_value str_value
#define num_value u.d
#define array_cookie u.a
#define scalar_cookie u.scl
@@ -347,7 +351,7 @@ typedef struct awk_element {
AWK_ELEMENT_DELETE = 1 /* set by extension if
should be deleted */
} flags;
- awk_value_t index; /* guaranteed to be a string! */
+ awk_value_t index;
awk_value_t value;
} awk_element_t;
@@ -469,6 +473,7 @@ typedef struct gawk_api {
void (*api_fatal)(awk_ext_id_t id, const char *format, ...);
void (*api_warning)(awk_ext_id_t id, const char *format, ...);
void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...);
+ void (*api_nonfatal)(awk_ext_id_t id, const char *format, ...);
/* Functions to update ERRNO */
void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val);
@@ -493,27 +498,28 @@ typedef struct gawk_api {
Table entry is type returned:
- +-------------------------------------------------+
- | Type of Actual Value: |
- +------------+------------+-----------+-----------+
- | String | Number | Array | Undefined |
- +-----------+-----------+------------+------------+-----------+-----------+
- | | String | String | String | false | false |
- | |-----------+------------+------------+-----------+-----------+
- | | Number | Number if | Number | false | false |
- | | | can be | | | |
- | | | converted, | | | |
- | | | else false | | | |
- | |-----------+------------+------------+-----------+-----------+
- | Type | Array | false | false | Array | false |
- | Requested |-----------+------------+------------+-----------+-----------+
- | | Scalar | Scalar | Scalar | false | false |
- | |-----------+------------+------------+-----------+-----------+
- | | Undefined | String | Number | Array | Undefined |
- | |-----------+------------+------------+-----------+-----------+
- | | Value | false | false | false | false |
- | | Cookie | | | | |
- +-----------+-----------+------------+------------+-----------+-----------+
+ +-------------------------------------------------------+
+ | Type of Actual Value: |
+ +--------+--------+--------+--------+-------+-----------+
+ | String | Strnum | Number | Regex | Array | Undefined |
+ +-----------+-----------+--------+--------+--------+--------+-------+-----------+
+ | | String | String | String | String | String | false | false |
+ | +-----------+--------+--------+--------+--------+-------+-----------+
+ | | Strnum | false | Strnum | Strnum | false | false | false |
+ | +-----------+--------+--------+--------+--------+-------+-----------+
+ | | Number | Number | Number | Number | false | false | false |
+ | +-----------+--------+--------+--------+--------+-------+-----------+
+ | | Regex | false | false | false | Regex | false | false |
+ | +-----------+--------+--------+--------+--------+-------+-----------+
+ | Type | Array | false | false | false | false | Array | false |
+ | Requested +-----------+--------+--------+--------+--------+-------+-----------+
+ | | Scalar | Scalar | Scalar | Scalar | Scalar | false | false |
+ | +-----------+--------+--------+--------+--------+-------+-----------+
+ | | Undefined | String | Strnum | Number | Regex | Array | Undefined |
+ | +-----------+--------+--------+--------+--------+-------+-----------+
+ | | Value | false | false | false | false | false | false |
+ | | Cookie | | | | | | |
+ +-----------+-----------+--------+--------+--------+--------+-------+-----------+
*/
/* Functions to handle parameters passed to the extension. */
@@ -680,10 +686,15 @@ typedef struct gawk_api {
/* Clear out an array */
awk_bool_t (*api_clear_array)(awk_ext_id_t id, awk_array_t a_cookie);
- /* Flatten out an array so that it can be looped over easily. */
- awk_bool_t (*api_flatten_array)(awk_ext_id_t id,
+ /*
+ * Flatten out an array with type conversions as requested.
+ * This supersedes the api_flatten_array function that did not allow
+ * the caller to specify the requested types.
+ */
+ awk_bool_t (*api_flatten_array_typed)(awk_ext_id_t id,
awk_array_t a_cookie,
- awk_flat_array_t **data);
+ awk_flat_array_t **data,
+ awk_valtype_t index_type, awk_valtype_t value_type);
/* When done, delete any marked elements, release the memory. */
awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id,
@@ -733,9 +744,6 @@ typedef struct gawk_api {
const awk_input_buf_t **ibufp,
const awk_output_buf_t **obufp);
- /* Print nonfatal error message */
- void (*api_nonfatal)(awk_ext_id_t id, const char *format, ...);
-
} gawk_api_t;
#ifndef GAWK /* these are not for the gawk code itself! */
@@ -802,8 +810,11 @@ typedef struct gawk_api {
#define clear_array(array) (api->api_clear_array(ext_id, array))
+#define flatten_array_typed(array, data, index_type, value_type) \
+ (api->api_flatten_array_typed(ext_id, array, data, index_type, value_type))
+
#define flatten_array(array, data) \
- (api->api_flatten_array(ext_id, array, data))
+ flatten_array_typed(array, data, AWK_STRING, AWK_UNDEFINED)
#define release_flattened_array(array, data) \
(api->api_release_flattened_array(ext_id, array, data))
@@ -839,21 +850,22 @@ typedef struct gawk_api {
/* Constructor functions */
-/* r_make_string --- make a string value in result from the passed-in string */
+/* r_make_string_type --- make a string or strnum or regexp value in result from the passed-in string */
static inline awk_value_t *
-r_make_string(const gawk_api_t *api, /* needed for emalloc */
- awk_ext_id_t *ext_id, /* ditto */
- const char *string,
- size_t length,
- awk_bool_t duplicate,
- awk_value_t *result)
+r_make_string_type(const gawk_api_t *api, /* needed for emalloc */
+ awk_ext_id_t *ext_id, /* ditto */
+ const char *string,
+ size_t length,
+ awk_bool_t duplicate,
+ awk_value_t *result,
+ awk_valtype_t val_type)
{
char *cp = NULL;
memset(result, 0, sizeof(*result));
- result->val_type = AWK_STRING;
+ result->val_type = val_type;
result->str_value.len = length;
if (duplicate) {
@@ -868,9 +880,33 @@ r_make_string(const gawk_api_t *api, /* needed for emalloc */
return result;
}
+/* r_make_string --- make a string value in result from the passed-in string */
+
+static inline awk_value_t *
+r_make_string(const gawk_api_t *api, /* needed for emalloc */
+ awk_ext_id_t *ext_id, /* ditto */
+ const char *string,
+ size_t length,
+ awk_bool_t duplicate,
+ awk_value_t *result)
+{
+ return r_make_string_type(api, ext_id, string, length, duplicate, result, AWK_STRING);
+}
+
#define make_const_string(str, len, result) r_make_string(api, ext_id, str, len, 1, result)
#define make_malloced_string(str, len, result) r_make_string(api, ext_id, str, len, 0, result)
+#define make_const_regex(str, len, result) r_make_string_type(api, ext_id, str, len, 1, result, AWK_REGEX)
+#define make_malloced_regex(str, len, result) r_make_string_type(api, ext_id, str, len, 0, result, AWK_REGEX)
+
+/*
+ * Note: The caller may not create a Strnum, but it can create a string that is
+ * flagged as user input that MAY be a Strnum. Gawk will decide whether it's a
+ * Strnum or a String by checking whether the string is numeric.
+ */
+#define make_const_user_input(str, len, result) r_make_string_type(api, ext_id, str, len, 1, result, AWK_STRNUM)
+#define make_malloced_user_input(str, len, result) r_make_string_type(api, ext_id, str, len, 0, result, AWK_STRNUM)
+
/* make_null_string --- make a null string value */
static inline awk_value_t *
@@ -895,6 +931,7 @@ make_number(double num, awk_value_t *result)
return result;
}
+
/*
* Each extension must define a function with this prototype:
*
diff --git a/node.c b/node.c
index cef6acbe..97f65fa3 100644
--- a/node.c
+++ b/node.c
@@ -444,6 +444,27 @@ make_str_node(const char *s, size_t len, int flags)
return r;
}
+/* make_typed_regex --- make a typed regex node */
+
+NODE *
+make_typed_regex(const char *re, size_t len)
+{
+ NODE *n, *exp, *n2;
+
+ exp = make_str_node(re, len, ALREADY_MALLOCED);
+ n = make_regnode(Node_regex, exp);
+ if (n == NULL)
+ fatal(_("could not make typed regex"));
+
+ n2 = make_string(re, len);
+ n2->typed_re = n;
+ n2->numbr = 0;
+ n2->flags |= NUMCUR|STRCUR|REGEX;
+ n2->flags &= ~(STRING|NUMBER);
+
+ return n2;
+}
+
/* unref --- remove reference to a particular node */
diff --git a/test/ChangeLog b/test/ChangeLog
index 40988c56..d2b0cf79 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,17 @@
+2016-12-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * rwarray.awk: Check that strnum is recreated correctly.
+
+2016-11-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * rwarray.awk: Use typeof() to verify that typed regex is
+ created correctly upon reading.
+
+2016-11-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * rwarray.awk: Add a typed regex into the array before
+ writing it out and reading it back.
+
2016-11-21 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (EXTRA_DIST): Add valgrind.awk to the list.
diff --git a/test/rwarray.awk b/test/rwarray.awk
index 0cb214ee..86a4b589 100644
--- a/test/rwarray.awk
+++ b/test/rwarray.awk
@@ -4,6 +4,13 @@ BEGIN {
while ((getline word) > 0)
dict[word] = word word
+ re_sub = "/typed-regex/"
+ dict[re_sub] = @/search me/
+
+ strnum_sub = "strnum-sub"
+ split("-2.4", f)
+ dict[strnum_sub] = f[1]
+
n = asorti(dict, dictindices)
for (i = 1; i <= n; i++)
printf("dict[%s] = %s\n", dictindices[i], dict[dictindices[i]]) > "orig.out"
@@ -12,7 +19,6 @@ BEGIN {
ret = writea("orig.bin", dict)
printf "writea() returned %d, expecting 1\n", ret
-
ret = reada("orig.bin", dict)
printf "reada() returned %d, expecting 1\n", ret
@@ -37,4 +43,12 @@ BEGIN {
if (ret == 0 && !("KEEPIT" in ENVIRON))
system("rm -f orig.bin orig.out new.out")
}
+
+ if (typeof(dict[re_sub]) != "regexp")
+ printf("dict[\"%s\"] should be regexp, is %s\n",
+ re_sub, typeof(dict[re_sub]));
+
+ if (typeof(dict[strnum_sub]) != "strnum")
+ printf("dict[\"%s\"] should be strnum, is %s\n",
+ strnum_sub, typeof(dict[strnum_sub]));
}