diff options
-rw-r--r-- | ChangeLog | 29 | ||||
-rw-r--r-- | awk.h | 1 | ||||
-rw-r--r-- | awkgram.c | 666 | ||||
-rw-r--r-- | awkgram.y | 16 | ||||
-rw-r--r-- | doc/ChangeLog | 5 | ||||
-rw-r--r-- | doc/gawk.info | 302 | ||||
-rw-r--r-- | doc/gawk.texi | 69 | ||||
-rw-r--r-- | doc/gawktexi.in | 69 | ||||
-rw-r--r-- | extension/ChangeLog | 9 | ||||
-rw-r--r-- | extension/rwarray.c | 12 | ||||
-rw-r--r-- | gawkapi.c | 32 | ||||
-rw-r--r-- | gawkapi.h | 80 | ||||
-rw-r--r-- | node.c | 21 | ||||
-rw-r--r-- | test/ChangeLog | 10 | ||||
-rw-r--r-- | test/rwarray.awk | 8 |
15 files changed, 741 insertions, 588 deletions
@@ -87,10 +87,39 @@ 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: @@ -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); @@ -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, 622, 624, 631, 721, 763, - 805, 918, 925, 932, 943, 953, 963, 973, 985, 1002, - 1001, 1026, 1038, 1038, 1137, 1137, 1171, 1202, 1211, 1212, - 1218, 1219, 1226, 1231, 1243, 1257, 1259, 1267, 1274, 1276, - 1284, 1293, 1295, 1304, 1305, 1313, 1318, 1318, 1329, 1333, - 1341, 1342, 1345, 1347, 1352, 1353, 1362, 1363, 1368, 1373, - 1382, 1384, 1386, 1393, 1394, 1400, 1401, 1406, 1408, 1413, - 1415, 1423, 1428, 1437, 1438, 1443, 1445, 1450, 1452, 1460, - 1465, 1473, 1474, 1479, 1486, 1490, 1492, 1494, 1507, 1524, - 1534, 1541, 1543, 1548, 1550, 1552, 1560, 1562, 1567, 1569, - 1574, 1576, 1578, 1634, 1636, 1638, 1640, 1642, 1644, 1646, - 1648, 1662, 1667, 1672, 1697, 1703, 1705, 1707, 1709, 1711, - 1713, 1718, 1722, 1754, 1756, 1762, 1768, 1781, 1782, 1783, - 1788, 1793, 1797, 1801, 1816, 1837, 1842, 1879, 1908, 1909, - 1915, 1916, 1921, 1923, 1930, 1947, 1964, 1966, 1973, 1978, - 1986, 1996, 2008, 2017, 2021, 2025, 2029, 2033, 2037, 2040, - 2042, 2046, 2050, 2054 + 433, 434, 438, 438, 484, 483, 517, 532, 534, 539, + 549, 596, 601, 602, 606, 608, 610, 617, 707, 749, + 791, 904, 911, 918, 929, 939, 949, 959, 971, 988, + 987, 1012, 1024, 1024, 1123, 1123, 1157, 1188, 1197, 1198, + 1204, 1205, 1212, 1217, 1229, 1243, 1245, 1253, 1260, 1262, + 1270, 1279, 1281, 1290, 1291, 1299, 1304, 1304, 1315, 1319, + 1327, 1328, 1331, 1333, 1338, 1339, 1348, 1349, 1354, 1359, + 1368, 1370, 1372, 1379, 1380, 1386, 1387, 1392, 1394, 1399, + 1401, 1409, 1414, 1423, 1424, 1429, 1431, 1436, 1438, 1446, + 1451, 1459, 1460, 1465, 1472, 1476, 1478, 1480, 1493, 1510, + 1520, 1527, 1529, 1534, 1536, 1538, 1546, 1548, 1553, 1555, + 1560, 1562, 1564, 1620, 1622, 1624, 1626, 1628, 1630, 1632, + 1634, 1648, 1653, 1658, 1683, 1689, 1691, 1693, 1695, 1697, + 1699, 1704, 1708, 1740, 1742, 1748, 1754, 1767, 1768, 1769, + 1774, 1779, 1783, 1787, 1802, 1823, 1828, 1865, 1894, 1895, + 1901, 1902, 1907, 1909, 1916, 1933, 1950, 1952, 1959, 1964, + 1972, 1982, 1994, 2003, 2007, 2011, 2015, 2019, 2023, 2026, + 2028, 2032, 2036, 2040 }; #endif @@ -2274,7 +2274,6 @@ yyreduce: case 36: #line 518 "awkgram.y" /* yacc.c:1646 */ { - NODE *n, *exp, *n2; char *re; size_t len; @@ -2282,34 +2281,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 2303 "awkgram.c" /* yacc.c:1646 */ +#line 2289 "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 2309 "awkgram.c" /* yacc.c:1646 */ +#line 2295 "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); @@ -2320,11 +2306,11 @@ yyreduce: } else (yyval) = NULL; } -#line 2324 "awkgram.c" /* yacc.c:1646 */ +#line 2310 "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) { @@ -2371,40 +2357,40 @@ yyreduce: } yyerrok; } -#line 2375 "awkgram.c" /* yacc.c:1646 */ +#line 2361 "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 2381 "awkgram.c" /* yacc.c:1646 */ +#line 2367 "awkgram.c" /* yacc.c:1646 */ break; case 44: -#line 621 "awkgram.y" /* yacc.c:1646 */ +#line 607 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2387 "awkgram.c" /* yacc.c:1646 */ +#line 2373 "awkgram.c" /* yacc.c:1646 */ break; case 45: -#line 623 "awkgram.y" /* yacc.c:1646 */ +#line 609 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 2393 "awkgram.c" /* yacc.c:1646 */ +#line 2379 "awkgram.c" /* yacc.c:1646 */ break; case 46: -#line 625 "awkgram.y" /* yacc.c:1646 */ +#line 611 "awkgram.y" /* yacc.c:1646 */ { if (do_pretty_print) (yyval) = list_prepend((yyvsp[0]), instruction(Op_exec_count)); else (yyval) = (yyvsp[0]); } -#line 2404 "awkgram.c" /* yacc.c:1646 */ +#line 2390 "awkgram.c" /* yacc.c:1646 */ break; case 47: -#line 632 "awkgram.y" /* yacc.c:1646 */ +#line 618 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt; INSTRUCTION *ip, *nextc, *tbreak; @@ -2494,11 +2480,11 @@ yyreduce: break_allowed--; fix_break_continue(ip, tbreak, NULL); } -#line 2498 "awkgram.c" /* yacc.c:1646 */ +#line 2484 "awkgram.c" /* yacc.c:1646 */ break; case 48: -#line 722 "awkgram.y" /* yacc.c:1646 */ +#line 708 "awkgram.y" /* yacc.c:1646 */ { /* * ----------------- @@ -2540,11 +2526,11 @@ yyreduce: continue_allowed--; fix_break_continue(ip, tbreak, tcont); } -#line 2544 "awkgram.c" /* yacc.c:1646 */ +#line 2530 "awkgram.c" /* yacc.c:1646 */ break; case 49: -#line 764 "awkgram.y" /* yacc.c:1646 */ +#line 750 "awkgram.y" /* yacc.c:1646 */ { /* * ----------------- @@ -2586,11 +2572,11 @@ yyreduce: } /* else $1 and $4 are NULLs */ } -#line 2590 "awkgram.c" /* yacc.c:1646 */ +#line 2576 "awkgram.c" /* yacc.c:1646 */ break; case 50: -#line 806 "awkgram.y" /* yacc.c:1646 */ +#line 792 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *ip; char *var_name = (yyvsp[-5])->lextok; @@ -2703,33 +2689,33 @@ regular_loop: break_allowed--; continue_allowed--; } -#line 2707 "awkgram.c" /* yacc.c:1646 */ +#line 2693 "awkgram.c" /* yacc.c:1646 */ break; case 51: -#line 919 "awkgram.y" /* yacc.c:1646 */ +#line 905 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_for_loop((yyvsp[-11]), (yyvsp[-9]), (yyvsp[-6]), (yyvsp[-3]), (yyvsp[0])); break_allowed--; continue_allowed--; } -#line 2718 "awkgram.c" /* yacc.c:1646 */ +#line 2704 "awkgram.c" /* yacc.c:1646 */ break; case 52: -#line 926 "awkgram.y" /* yacc.c:1646 */ +#line 912 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_for_loop((yyvsp[-10]), (yyvsp[-8]), (INSTRUCTION *) NULL, (yyvsp[-3]), (yyvsp[0])); break_allowed--; continue_allowed--; } -#line 2729 "awkgram.c" /* yacc.c:1646 */ +#line 2715 "awkgram.c" /* yacc.c:1646 */ break; case 53: -#line 933 "awkgram.y" /* yacc.c:1646 */ +#line 919 "awkgram.y" /* yacc.c:1646 */ { if (do_pretty_print) (yyval) = list_prepend((yyvsp[0]), instruction(Op_exec_count)); @@ -2737,11 +2723,11 @@ regular_loop: (yyval) = (yyvsp[0]); (yyval) = add_pending_comment((yyval)); } -#line 2741 "awkgram.c" /* yacc.c:1646 */ +#line 2727 "awkgram.c" /* yacc.c:1646 */ break; case 54: -#line 944 "awkgram.y" /* yacc.c:1646 */ +#line 930 "awkgram.y" /* yacc.c:1646 */ { if (! break_allowed) error_ln((yyvsp[-1])->source_line, @@ -2751,11 +2737,11 @@ regular_loop: (yyval) = add_pending_comment((yyval)); } -#line 2755 "awkgram.c" /* yacc.c:1646 */ +#line 2741 "awkgram.c" /* yacc.c:1646 */ break; case 55: -#line 954 "awkgram.y" /* yacc.c:1646 */ +#line 940 "awkgram.y" /* yacc.c:1646 */ { if (! continue_allowed) error_ln((yyvsp[-1])->source_line, @@ -2765,11 +2751,11 @@ regular_loop: (yyval) = add_pending_comment((yyval)); } -#line 2769 "awkgram.c" /* yacc.c:1646 */ +#line 2755 "awkgram.c" /* yacc.c:1646 */ break; case 56: -#line 964 "awkgram.y" /* yacc.c:1646 */ +#line 950 "awkgram.y" /* yacc.c:1646 */ { /* if inside function (rule = 0), resolve context at run-time */ if (rule && rule != Rule) @@ -2779,11 +2765,11 @@ regular_loop: (yyval) = list_create((yyvsp[-1])); (yyval) = add_pending_comment((yyval)); } -#line 2783 "awkgram.c" /* yacc.c:1646 */ +#line 2769 "awkgram.c" /* yacc.c:1646 */ break; case 57: -#line 974 "awkgram.y" /* yacc.c:1646 */ +#line 960 "awkgram.y" /* yacc.c:1646 */ { /* if inside function (rule = 0), resolve context at run-time */ if (rule == BEGIN || rule == END || rule == ENDFILE) @@ -2795,11 +2781,11 @@ regular_loop: (yyval) = list_create((yyvsp[-1])); (yyval) = add_pending_comment((yyval)); } -#line 2799 "awkgram.c" /* yacc.c:1646 */ +#line 2785 "awkgram.c" /* yacc.c:1646 */ break; case 58: -#line 986 "awkgram.y" /* yacc.c:1646 */ +#line 972 "awkgram.y" /* yacc.c:1646 */ { /* Initialize the two possible jump targets, the actual target * is resolved at run-time. @@ -2815,20 +2801,20 @@ regular_loop: (yyval) = list_append((yyvsp[-1]), (yyvsp[-2])); (yyval) = add_pending_comment((yyval)); } -#line 2819 "awkgram.c" /* yacc.c:1646 */ +#line 2805 "awkgram.c" /* yacc.c:1646 */ break; case 59: -#line 1002 "awkgram.y" /* yacc.c:1646 */ +#line 988 "awkgram.y" /* yacc.c:1646 */ { if (! in_function) yyerror(_("`return' used outside function context")); } -#line 2828 "awkgram.c" /* yacc.c:1646 */ +#line 2814 "awkgram.c" /* yacc.c:1646 */ break; case 60: -#line 1005 "awkgram.y" /* yacc.c:1646 */ +#line 991 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[-1]) == NULL) { (yyval) = list_create((yyvsp[-3])); @@ -2850,17 +2836,17 @@ regular_loop: } (yyval) = add_pending_comment((yyval)); } -#line 2854 "awkgram.c" /* yacc.c:1646 */ +#line 2840 "awkgram.c" /* yacc.c:1646 */ break; case 62: -#line 1038 "awkgram.y" /* yacc.c:1646 */ +#line 1024 "awkgram.y" /* yacc.c:1646 */ { in_print = true; in_parens = 0; } -#line 2860 "awkgram.c" /* yacc.c:1646 */ +#line 2846 "awkgram.c" /* yacc.c:1646 */ break; case 63: -#line 1039 "awkgram.y" /* yacc.c:1646 */ +#line 1025 "awkgram.y" /* yacc.c:1646 */ { /* * Optimization: plain `print' has no expression list, so $3 is null. @@ -2958,17 +2944,17 @@ regular_print: } (yyval) = add_pending_comment((yyval)); } -#line 2962 "awkgram.c" /* yacc.c:1646 */ +#line 2948 "awkgram.c" /* yacc.c:1646 */ break; case 64: -#line 1137 "awkgram.y" /* yacc.c:1646 */ +#line 1123 "awkgram.y" /* yacc.c:1646 */ { sub_counter = 0; } -#line 2968 "awkgram.c" /* yacc.c:1646 */ +#line 2954 "awkgram.c" /* yacc.c:1646 */ break; case 65: -#line 1138 "awkgram.y" /* yacc.c:1646 */ +#line 1124 "awkgram.y" /* yacc.c:1646 */ { char *arr = (yyvsp[-2])->lextok; @@ -3002,11 +2988,11 @@ regular_print: } (yyval) = add_pending_comment((yyval)); } -#line 3006 "awkgram.c" /* yacc.c:1646 */ +#line 2992 "awkgram.c" /* yacc.c:1646 */ break; case 66: -#line 1176 "awkgram.y" /* yacc.c:1646 */ +#line 1162 "awkgram.y" /* yacc.c:1646 */ { static bool warned = false; char *arr = (yyvsp[-1])->lextok; @@ -3033,55 +3019,55 @@ regular_print: } (yyval) = add_pending_comment((yyval)); } -#line 3037 "awkgram.c" /* yacc.c:1646 */ +#line 3023 "awkgram.c" /* yacc.c:1646 */ break; case 67: -#line 1203 "awkgram.y" /* yacc.c:1646 */ +#line 1189 "awkgram.y" /* yacc.c:1646 */ { (yyval) = optimize_assignment((yyvsp[0])); (yyval) = add_pending_comment((yyval)); } -#line 3046 "awkgram.c" /* yacc.c:1646 */ +#line 3032 "awkgram.c" /* yacc.c:1646 */ break; case 68: -#line 1211 "awkgram.y" /* yacc.c:1646 */ +#line 1197 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3052 "awkgram.c" /* yacc.c:1646 */ +#line 3038 "awkgram.c" /* yacc.c:1646 */ break; case 69: -#line 1213 "awkgram.y" /* yacc.c:1646 */ +#line 1199 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3058 "awkgram.c" /* yacc.c:1646 */ +#line 3044 "awkgram.c" /* yacc.c:1646 */ break; case 70: -#line 1218 "awkgram.y" /* yacc.c:1646 */ +#line 1204 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3064 "awkgram.c" /* yacc.c:1646 */ +#line 3050 "awkgram.c" /* yacc.c:1646 */ break; case 71: -#line 1220 "awkgram.y" /* yacc.c:1646 */ +#line 1206 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[-1]) == NULL) (yyval) = list_create((yyvsp[0])); else (yyval) = list_prepend((yyvsp[-1]), (yyvsp[0])); } -#line 3075 "awkgram.c" /* yacc.c:1646 */ +#line 3061 "awkgram.c" /* yacc.c:1646 */ break; case 72: -#line 1227 "awkgram.y" /* yacc.c:1646 */ +#line 1213 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3081 "awkgram.c" /* yacc.c:1646 */ +#line 3067 "awkgram.c" /* yacc.c:1646 */ break; case 73: -#line 1232 "awkgram.y" /* yacc.c:1646 */ +#line 1218 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *casestmt = (yyvsp[0]); if ((yyvsp[0]) == NULL) @@ -3093,11 +3079,11 @@ regular_print: bcfree((yyvsp[-2])); (yyval) = (yyvsp[-4]); } -#line 3097 "awkgram.c" /* yacc.c:1646 */ +#line 3083 "awkgram.c" /* yacc.c:1646 */ break; case 74: -#line 1244 "awkgram.y" /* yacc.c:1646 */ +#line 1230 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *casestmt = (yyvsp[0]); if ((yyvsp[0]) == NULL) @@ -3108,17 +3094,17 @@ regular_print: (yyvsp[-3])->case_stmt = casestmt; (yyval) = (yyvsp[-3]); } -#line 3112 "awkgram.c" /* yacc.c:1646 */ +#line 3098 "awkgram.c" /* yacc.c:1646 */ break; case 75: -#line 1258 "awkgram.y" /* yacc.c:1646 */ +#line 1244 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3118 "awkgram.c" /* yacc.c:1646 */ +#line 3104 "awkgram.c" /* yacc.c:1646 */ break; case 76: -#line 1260 "awkgram.y" /* yacc.c:1646 */ +#line 1246 "awkgram.y" /* yacc.c:1646 */ { NODE *n = (yyvsp[0])->memory; (void) force_number(n); @@ -3126,28 +3112,28 @@ regular_print: bcfree((yyvsp[-1])); (yyval) = (yyvsp[0]); } -#line 3130 "awkgram.c" /* yacc.c:1646 */ +#line 3116 "awkgram.c" /* yacc.c:1646 */ break; case 77: -#line 1268 "awkgram.y" /* yacc.c:1646 */ +#line 1254 "awkgram.y" /* yacc.c:1646 */ { NODE *n = (yyvsp[0])->lasti->memory; bcfree((yyvsp[-1])); add_sign_to_num(n, '+'); (yyval) = (yyvsp[0]); } -#line 3141 "awkgram.c" /* yacc.c:1646 */ +#line 3127 "awkgram.c" /* yacc.c:1646 */ break; case 78: -#line 1275 "awkgram.y" /* yacc.c:1646 */ +#line 1261 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3147 "awkgram.c" /* yacc.c:1646 */ +#line 3133 "awkgram.c" /* yacc.c:1646 */ break; case 79: -#line 1277 "awkgram.y" /* yacc.c:1646 */ +#line 1263 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[0])->memory->type == Node_regex) (yyvsp[0])->opcode = Op_push_re; @@ -3155,57 +3141,57 @@ regular_print: (yyvsp[0])->opcode = Op_push; (yyval) = (yyvsp[0]); } -#line 3159 "awkgram.c" /* yacc.c:1646 */ +#line 3145 "awkgram.c" /* yacc.c:1646 */ break; case 80: -#line 1285 "awkgram.y" /* yacc.c:1646 */ +#line 1271 "awkgram.y" /* yacc.c:1646 */ { assert(((yyvsp[0])->memory->flags & REGEX) == REGEX); (yyvsp[0])->opcode = Op_push_re; (yyval) = (yyvsp[0]); } -#line 3169 "awkgram.c" /* yacc.c:1646 */ +#line 3155 "awkgram.c" /* yacc.c:1646 */ break; case 81: -#line 1294 "awkgram.y" /* yacc.c:1646 */ +#line 1280 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3175 "awkgram.c" /* yacc.c:1646 */ +#line 3161 "awkgram.c" /* yacc.c:1646 */ break; case 82: -#line 1296 "awkgram.y" /* yacc.c:1646 */ +#line 1282 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3181 "awkgram.c" /* yacc.c:1646 */ +#line 3167 "awkgram.c" /* yacc.c:1646 */ break; case 84: -#line 1306 "awkgram.y" /* yacc.c:1646 */ +#line 1292 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 3189 "awkgram.c" /* yacc.c:1646 */ +#line 3175 "awkgram.c" /* yacc.c:1646 */ break; case 85: -#line 1313 "awkgram.y" /* yacc.c:1646 */ +#line 1299 "awkgram.y" /* yacc.c:1646 */ { in_print = false; in_parens = 0; (yyval) = NULL; } -#line 3199 "awkgram.c" /* yacc.c:1646 */ +#line 3185 "awkgram.c" /* yacc.c:1646 */ break; case 86: -#line 1318 "awkgram.y" /* yacc.c:1646 */ +#line 1304 "awkgram.y" /* yacc.c:1646 */ { in_print = false; in_parens = 0; } -#line 3205 "awkgram.c" /* yacc.c:1646 */ +#line 3191 "awkgram.c" /* yacc.c:1646 */ break; case 87: -#line 1319 "awkgram.y" /* yacc.c:1646 */ +#line 1305 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[-2])->redir_type == redirect_twoway && (yyvsp[0])->lasti->opcode == Op_K_getline_redir @@ -3213,63 +3199,63 @@ regular_print: yyerror(_("multistage two-way pipelines don't work")); (yyval) = list_prepend((yyvsp[0]), (yyvsp[-2])); } -#line 3217 "awkgram.c" /* yacc.c:1646 */ +#line 3203 "awkgram.c" /* yacc.c:1646 */ break; case 88: -#line 1330 "awkgram.y" /* yacc.c:1646 */ +#line 1316 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_condition((yyvsp[-3]), (yyvsp[-5]), (yyvsp[0]), NULL, NULL); } -#line 3225 "awkgram.c" /* yacc.c:1646 */ +#line 3211 "awkgram.c" /* yacc.c:1646 */ break; case 89: -#line 1335 "awkgram.y" /* yacc.c:1646 */ +#line 1321 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_condition((yyvsp[-6]), (yyvsp[-8]), (yyvsp[-3]), (yyvsp[-2]), (yyvsp[0])); } -#line 3233 "awkgram.c" /* yacc.c:1646 */ +#line 3219 "awkgram.c" /* yacc.c:1646 */ break; case 94: -#line 1352 "awkgram.y" /* yacc.c:1646 */ +#line 1338 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3239 "awkgram.c" /* yacc.c:1646 */ +#line 3225 "awkgram.c" /* yacc.c:1646 */ break; case 95: -#line 1354 "awkgram.y" /* yacc.c:1646 */ +#line 1340 "awkgram.y" /* yacc.c:1646 */ { bcfree((yyvsp[-1])); (yyval) = (yyvsp[0]); } -#line 3248 "awkgram.c" /* yacc.c:1646 */ +#line 3234 "awkgram.c" /* yacc.c:1646 */ break; case 96: -#line 1362 "awkgram.y" /* yacc.c:1646 */ +#line 1348 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3254 "awkgram.c" /* yacc.c:1646 */ +#line 3240 "awkgram.c" /* yacc.c:1646 */ break; case 97: -#line 1364 "awkgram.y" /* yacc.c:1646 */ +#line 1350 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3260 "awkgram.c" /* yacc.c:1646 */ +#line 3246 "awkgram.c" /* yacc.c:1646 */ break; case 98: -#line 1369 "awkgram.y" /* yacc.c:1646 */ +#line 1355 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->param_count = 0; (yyval) = list_create((yyvsp[0])); } -#line 3269 "awkgram.c" /* yacc.c:1646 */ +#line 3255 "awkgram.c" /* yacc.c:1646 */ break; case 99: -#line 1374 "awkgram.y" /* yacc.c:1646 */ +#line 1360 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[-2]) != NULL && (yyvsp[0]) != NULL) { (yyvsp[0])->param_count = (yyvsp[-2])->lasti->param_count + 1; @@ -3278,74 +3264,74 @@ regular_print: } else (yyval) = NULL; } -#line 3282 "awkgram.c" /* yacc.c:1646 */ +#line 3268 "awkgram.c" /* yacc.c:1646 */ break; case 100: -#line 1383 "awkgram.y" /* yacc.c:1646 */ +#line 1369 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3288 "awkgram.c" /* yacc.c:1646 */ +#line 3274 "awkgram.c" /* yacc.c:1646 */ break; case 101: -#line 1385 "awkgram.y" /* yacc.c:1646 */ +#line 1371 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 3294 "awkgram.c" /* yacc.c:1646 */ +#line 3280 "awkgram.c" /* yacc.c:1646 */ break; case 102: -#line 1387 "awkgram.y" /* yacc.c:1646 */ +#line 1373 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-2]); } -#line 3300 "awkgram.c" /* yacc.c:1646 */ +#line 3286 "awkgram.c" /* yacc.c:1646 */ break; case 103: -#line 1393 "awkgram.y" /* yacc.c:1646 */ +#line 1379 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3306 "awkgram.c" /* yacc.c:1646 */ +#line 3292 "awkgram.c" /* yacc.c:1646 */ break; case 104: -#line 1395 "awkgram.y" /* yacc.c:1646 */ +#line 1381 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3312 "awkgram.c" /* yacc.c:1646 */ +#line 3298 "awkgram.c" /* yacc.c:1646 */ break; case 105: -#line 1400 "awkgram.y" /* yacc.c:1646 */ +#line 1386 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3318 "awkgram.c" /* yacc.c:1646 */ +#line 3304 "awkgram.c" /* yacc.c:1646 */ break; case 106: -#line 1402 "awkgram.y" /* yacc.c:1646 */ +#line 1388 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3324 "awkgram.c" /* yacc.c:1646 */ +#line 3310 "awkgram.c" /* yacc.c:1646 */ break; case 107: -#line 1407 "awkgram.y" /* yacc.c:1646 */ +#line 1393 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_expression_list(NULL, (yyvsp[0])); } -#line 3330 "awkgram.c" /* yacc.c:1646 */ +#line 3316 "awkgram.c" /* yacc.c:1646 */ break; case 108: -#line 1409 "awkgram.y" /* yacc.c:1646 */ +#line 1395 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0])); yyerrok; } -#line 3339 "awkgram.c" /* yacc.c:1646 */ +#line 3325 "awkgram.c" /* yacc.c:1646 */ break; case 109: -#line 1414 "awkgram.y" /* yacc.c:1646 */ +#line 1400 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3345 "awkgram.c" /* yacc.c:1646 */ +#line 3331 "awkgram.c" /* yacc.c:1646 */ break; case 110: -#line 1416 "awkgram.y" /* yacc.c:1646 */ +#line 1402 "awkgram.y" /* yacc.c:1646 */ { /* * Returning the expression list instead of NULL lets @@ -3353,62 +3339,62 @@ regular_print: */ (yyval) = (yyvsp[-1]); } -#line 3357 "awkgram.c" /* yacc.c:1646 */ +#line 3343 "awkgram.c" /* yacc.c:1646 */ break; case 111: -#line 1424 "awkgram.y" /* yacc.c:1646 */ +#line 1410 "awkgram.y" /* yacc.c:1646 */ { /* Ditto */ (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0])); } -#line 3366 "awkgram.c" /* yacc.c:1646 */ +#line 3352 "awkgram.c" /* yacc.c:1646 */ break; case 112: -#line 1429 "awkgram.y" /* yacc.c:1646 */ +#line 1415 "awkgram.y" /* yacc.c:1646 */ { /* Ditto */ (yyval) = (yyvsp[-2]); } -#line 3375 "awkgram.c" /* yacc.c:1646 */ +#line 3361 "awkgram.c" /* yacc.c:1646 */ break; case 113: -#line 1437 "awkgram.y" /* yacc.c:1646 */ +#line 1423 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3381 "awkgram.c" /* yacc.c:1646 */ +#line 3367 "awkgram.c" /* yacc.c:1646 */ break; case 114: -#line 1439 "awkgram.y" /* yacc.c:1646 */ +#line 1425 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3387 "awkgram.c" /* yacc.c:1646 */ +#line 3373 "awkgram.c" /* yacc.c:1646 */ break; case 115: -#line 1444 "awkgram.y" /* yacc.c:1646 */ +#line 1430 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_expression_list(NULL, (yyvsp[0])); } -#line 3393 "awkgram.c" /* yacc.c:1646 */ +#line 3379 "awkgram.c" /* yacc.c:1646 */ break; case 116: -#line 1446 "awkgram.y" /* yacc.c:1646 */ +#line 1432 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0])); yyerrok; } -#line 3402 "awkgram.c" /* yacc.c:1646 */ +#line 3388 "awkgram.c" /* yacc.c:1646 */ break; case 117: -#line 1451 "awkgram.y" /* yacc.c:1646 */ +#line 1437 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3408 "awkgram.c" /* yacc.c:1646 */ +#line 3394 "awkgram.c" /* yacc.c:1646 */ break; case 118: -#line 1453 "awkgram.y" /* yacc.c:1646 */ +#line 1439 "awkgram.y" /* yacc.c:1646 */ { /* * Returning the expression list instead of NULL lets @@ -3416,72 +3402,72 @@ regular_print: */ (yyval) = (yyvsp[-1]); } -#line 3420 "awkgram.c" /* yacc.c:1646 */ +#line 3406 "awkgram.c" /* yacc.c:1646 */ break; case 119: -#line 1461 "awkgram.y" /* yacc.c:1646 */ +#line 1447 "awkgram.y" /* yacc.c:1646 */ { /* Ditto */ (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0])); } -#line 3429 "awkgram.c" /* yacc.c:1646 */ +#line 3415 "awkgram.c" /* yacc.c:1646 */ break; case 120: -#line 1466 "awkgram.y" /* yacc.c:1646 */ +#line 1452 "awkgram.y" /* yacc.c:1646 */ { /* Ditto */ (yyval) = (yyvsp[-2]); } -#line 3438 "awkgram.c" /* yacc.c:1646 */ +#line 3424 "awkgram.c" /* yacc.c:1646 */ break; case 121: -#line 1473 "awkgram.y" /* yacc.c:1646 */ +#line 1459 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3444 "awkgram.c" /* yacc.c:1646 */ +#line 3430 "awkgram.c" /* yacc.c:1646 */ break; case 122: -#line 1474 "awkgram.y" /* yacc.c:1646 */ +#line 1460 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_create((yyvsp[0])); } -#line 3450 "awkgram.c" /* yacc.c:1646 */ +#line 3436 "awkgram.c" /* yacc.c:1646 */ break; case 123: -#line 1480 "awkgram.y" /* yacc.c:1646 */ +#line 1466 "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 3461 "awkgram.c" /* yacc.c:1646 */ +#line 3447 "awkgram.c" /* yacc.c:1646 */ break; case 124: -#line 1487 "awkgram.y" /* yacc.c:1646 */ +#line 1473 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_assignment((yyvsp[-2]), list_create((yyvsp[0])), (yyvsp[-1])); } -#line 3469 "awkgram.c" /* yacc.c:1646 */ +#line 3455 "awkgram.c" /* yacc.c:1646 */ break; case 125: -#line 1491 "awkgram.y" /* yacc.c:1646 */ +#line 1477 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3475 "awkgram.c" /* yacc.c:1646 */ +#line 3461 "awkgram.c" /* yacc.c:1646 */ break; case 126: -#line 1493 "awkgram.y" /* yacc.c:1646 */ +#line 1479 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3481 "awkgram.c" /* yacc.c:1646 */ +#line 3467 "awkgram.c" /* yacc.c:1646 */ break; case 127: -#line 1495 "awkgram.y" /* yacc.c:1646 */ +#line 1481 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[-2])->lasti->opcode == Op_match_rec) warning_ln((yyvsp[-1])->source_line, @@ -3494,11 +3480,11 @@ regular_print: bcfree((yyvsp[0])); (yyval) = list_append((yyvsp[-2]), (yyvsp[-1])); } -#line 3498 "awkgram.c" /* yacc.c:1646 */ +#line 3484 "awkgram.c" /* yacc.c:1646 */ break; case 128: -#line 1508 "awkgram.y" /* yacc.c:1646 */ +#line 1494 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[-2])->lasti->opcode == Op_match_rec) warning_ln((yyvsp[-1])->source_line, @@ -3515,11 +3501,11 @@ regular_print: (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1])); } } -#line 3519 "awkgram.c" /* yacc.c:1646 */ +#line 3505 "awkgram.c" /* yacc.c:1646 */ break; case 129: -#line 1525 "awkgram.y" /* yacc.c:1646 */ +#line 1511 "awkgram.y" /* yacc.c:1646 */ { if (do_lint_old) warning_ln((yyvsp[-1])->source_line, @@ -3529,91 +3515,91 @@ regular_print: (yyvsp[-1])->expr_count = 1; (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1])); } -#line 3533 "awkgram.c" /* yacc.c:1646 */ +#line 3519 "awkgram.c" /* yacc.c:1646 */ break; case 130: -#line 1535 "awkgram.y" /* yacc.c:1646 */ +#line 1521 "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 3544 "awkgram.c" /* yacc.c:1646 */ +#line 3530 "awkgram.c" /* yacc.c:1646 */ break; case 131: -#line 1542 "awkgram.y" /* yacc.c:1646 */ +#line 1528 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_condition((yyvsp[-4]), (yyvsp[-3]), (yyvsp[-2]), (yyvsp[-1]), (yyvsp[0])); } -#line 3550 "awkgram.c" /* yacc.c:1646 */ +#line 3536 "awkgram.c" /* yacc.c:1646 */ break; case 132: -#line 1544 "awkgram.y" /* yacc.c:1646 */ +#line 1530 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3556 "awkgram.c" /* yacc.c:1646 */ +#line 3542 "awkgram.c" /* yacc.c:1646 */ break; case 133: -#line 1549 "awkgram.y" /* yacc.c:1646 */ +#line 1535 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3562 "awkgram.c" /* yacc.c:1646 */ +#line 3548 "awkgram.c" /* yacc.c:1646 */ break; case 134: -#line 1551 "awkgram.y" /* yacc.c:1646 */ +#line 1537 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3568 "awkgram.c" /* yacc.c:1646 */ +#line 3554 "awkgram.c" /* yacc.c:1646 */ break; case 135: -#line 1553 "awkgram.y" /* yacc.c:1646 */ +#line 1539 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_assign_quotient; (yyval) = (yyvsp[0]); } -#line 3577 "awkgram.c" /* yacc.c:1646 */ +#line 3563 "awkgram.c" /* yacc.c:1646 */ break; case 136: -#line 1561 "awkgram.y" /* yacc.c:1646 */ +#line 1547 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3583 "awkgram.c" /* yacc.c:1646 */ +#line 3569 "awkgram.c" /* yacc.c:1646 */ break; case 137: -#line 1563 "awkgram.y" /* yacc.c:1646 */ +#line 1549 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3589 "awkgram.c" /* yacc.c:1646 */ +#line 3575 "awkgram.c" /* yacc.c:1646 */ break; case 138: -#line 1568 "awkgram.y" /* yacc.c:1646 */ +#line 1554 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3595 "awkgram.c" /* yacc.c:1646 */ +#line 3581 "awkgram.c" /* yacc.c:1646 */ break; case 139: -#line 1570 "awkgram.y" /* yacc.c:1646 */ +#line 1556 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3601 "awkgram.c" /* yacc.c:1646 */ +#line 3587 "awkgram.c" /* yacc.c:1646 */ break; case 140: -#line 1575 "awkgram.y" /* yacc.c:1646 */ +#line 1561 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3607 "awkgram.c" /* yacc.c:1646 */ +#line 3593 "awkgram.c" /* yacc.c:1646 */ break; case 141: -#line 1577 "awkgram.y" /* yacc.c:1646 */ +#line 1563 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3613 "awkgram.c" /* yacc.c:1646 */ +#line 3599 "awkgram.c" /* yacc.c:1646 */ break; case 142: -#line 1579 "awkgram.y" /* yacc.c:1646 */ +#line 1565 "awkgram.y" /* yacc.c:1646 */ { int count = 2; bool is_simple_var = false; @@ -3666,47 +3652,47 @@ regular_print: max_args = count; } } -#line 3670 "awkgram.c" /* yacc.c:1646 */ +#line 3656 "awkgram.c" /* yacc.c:1646 */ break; case 144: -#line 1637 "awkgram.y" /* yacc.c:1646 */ +#line 1623 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3676 "awkgram.c" /* yacc.c:1646 */ +#line 3662 "awkgram.c" /* yacc.c:1646 */ break; case 145: -#line 1639 "awkgram.y" /* yacc.c:1646 */ +#line 1625 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3682 "awkgram.c" /* yacc.c:1646 */ +#line 3668 "awkgram.c" /* yacc.c:1646 */ break; case 146: -#line 1641 "awkgram.y" /* yacc.c:1646 */ +#line 1627 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3688 "awkgram.c" /* yacc.c:1646 */ +#line 3674 "awkgram.c" /* yacc.c:1646 */ break; case 147: -#line 1643 "awkgram.y" /* yacc.c:1646 */ +#line 1629 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3694 "awkgram.c" /* yacc.c:1646 */ +#line 3680 "awkgram.c" /* yacc.c:1646 */ break; case 148: -#line 1645 "awkgram.y" /* yacc.c:1646 */ +#line 1631 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3700 "awkgram.c" /* yacc.c:1646 */ +#line 3686 "awkgram.c" /* yacc.c:1646 */ break; case 149: -#line 1647 "awkgram.y" /* yacc.c:1646 */ +#line 1633 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3706 "awkgram.c" /* yacc.c:1646 */ +#line 3692 "awkgram.c" /* yacc.c:1646 */ break; case 150: -#line 1649 "awkgram.y" /* yacc.c:1646 */ +#line 1635 "awkgram.y" /* yacc.c:1646 */ { /* * In BEGINFILE/ENDFILE, allow `getline [var] < file' @@ -3720,29 +3706,29 @@ regular_print: _("non-redirected `getline' undefined inside END action")); (yyval) = mk_getline((yyvsp[-2]), (yyvsp[-1]), (yyvsp[0]), redirect_input); } -#line 3724 "awkgram.c" /* yacc.c:1646 */ +#line 3710 "awkgram.c" /* yacc.c:1646 */ break; case 151: -#line 1663 "awkgram.y" /* yacc.c:1646 */ +#line 1649 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_postincrement; (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0])); } -#line 3733 "awkgram.c" /* yacc.c:1646 */ +#line 3719 "awkgram.c" /* yacc.c:1646 */ break; case 152: -#line 1668 "awkgram.y" /* yacc.c:1646 */ +#line 1654 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_postdecrement; (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0])); } -#line 3742 "awkgram.c" /* yacc.c:1646 */ +#line 3728 "awkgram.c" /* yacc.c:1646 */ break; case 153: -#line 1673 "awkgram.y" /* yacc.c:1646 */ +#line 1659 "awkgram.y" /* yacc.c:1646 */ { if (do_lint_old) { warning_ln((yyvsp[-1])->source_line, @@ -3762,64 +3748,64 @@ regular_print: (yyval) = list_append(list_merge(t, (yyvsp[0])), (yyvsp[-1])); } } -#line 3766 "awkgram.c" /* yacc.c:1646 */ +#line 3752 "awkgram.c" /* yacc.c:1646 */ break; case 154: -#line 1698 "awkgram.y" /* yacc.c:1646 */ +#line 1684 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_getline((yyvsp[-1]), (yyvsp[0]), (yyvsp[-3]), (yyvsp[-2])->redir_type); bcfree((yyvsp[-2])); } -#line 3775 "awkgram.c" /* yacc.c:1646 */ +#line 3761 "awkgram.c" /* yacc.c:1646 */ break; case 155: -#line 1704 "awkgram.y" /* yacc.c:1646 */ +#line 1690 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3781 "awkgram.c" /* yacc.c:1646 */ +#line 3767 "awkgram.c" /* yacc.c:1646 */ break; case 156: -#line 1706 "awkgram.y" /* yacc.c:1646 */ +#line 1692 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3787 "awkgram.c" /* yacc.c:1646 */ +#line 3773 "awkgram.c" /* yacc.c:1646 */ break; case 157: -#line 1708 "awkgram.y" /* yacc.c:1646 */ +#line 1694 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3793 "awkgram.c" /* yacc.c:1646 */ +#line 3779 "awkgram.c" /* yacc.c:1646 */ break; case 158: -#line 1710 "awkgram.y" /* yacc.c:1646 */ +#line 1696 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3799 "awkgram.c" /* yacc.c:1646 */ +#line 3785 "awkgram.c" /* yacc.c:1646 */ break; case 159: -#line 1712 "awkgram.y" /* yacc.c:1646 */ +#line 1698 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3805 "awkgram.c" /* yacc.c:1646 */ +#line 3791 "awkgram.c" /* yacc.c:1646 */ break; case 160: -#line 1714 "awkgram.y" /* yacc.c:1646 */ +#line 1700 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3811 "awkgram.c" /* yacc.c:1646 */ +#line 3797 "awkgram.c" /* yacc.c:1646 */ break; case 161: -#line 1719 "awkgram.y" /* yacc.c:1646 */ +#line 1705 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_create((yyvsp[0])); } -#line 3819 "awkgram.c" /* yacc.c:1646 */ +#line 3805 "awkgram.c" /* yacc.c:1646 */ break; case 162: -#line 1723 "awkgram.y" /* yacc.c:1646 */ +#line 1709 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[0])->opcode == Op_match_rec) { (yyvsp[0])->opcode = Op_nomatch; @@ -3851,37 +3837,37 @@ regular_print: } } } -#line 3855 "awkgram.c" /* yacc.c:1646 */ +#line 3841 "awkgram.c" /* yacc.c:1646 */ break; case 163: -#line 1755 "awkgram.y" /* yacc.c:1646 */ +#line 1741 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 3861 "awkgram.c" /* yacc.c:1646 */ +#line 3847 "awkgram.c" /* yacc.c:1646 */ break; case 164: -#line 1757 "awkgram.y" /* yacc.c:1646 */ +#line 1743 "awkgram.y" /* yacc.c:1646 */ { (yyval) = snode((yyvsp[-1]), (yyvsp[-3])); if ((yyval) == NULL) YYABORT; } -#line 3871 "awkgram.c" /* yacc.c:1646 */ +#line 3857 "awkgram.c" /* yacc.c:1646 */ break; case 165: -#line 1763 "awkgram.y" /* yacc.c:1646 */ +#line 1749 "awkgram.y" /* yacc.c:1646 */ { (yyval) = snode((yyvsp[-1]), (yyvsp[-3])); if ((yyval) == NULL) YYABORT; } -#line 3881 "awkgram.c" /* yacc.c:1646 */ +#line 3867 "awkgram.c" /* yacc.c:1646 */ break; case 166: -#line 1769 "awkgram.y" /* yacc.c:1646 */ +#line 1755 "awkgram.y" /* yacc.c:1646 */ { static bool warned = false; @@ -3894,45 +3880,45 @@ regular_print: if ((yyval) == NULL) YYABORT; } -#line 3898 "awkgram.c" /* yacc.c:1646 */ +#line 3884 "awkgram.c" /* yacc.c:1646 */ break; case 169: -#line 1784 "awkgram.y" /* yacc.c:1646 */ +#line 1770 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[-1])->opcode = Op_preincrement; (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1])); } -#line 3907 "awkgram.c" /* yacc.c:1646 */ +#line 3893 "awkgram.c" /* yacc.c:1646 */ break; case 170: -#line 1789 "awkgram.y" /* yacc.c:1646 */ +#line 1775 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[-1])->opcode = Op_predecrement; (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1])); } -#line 3916 "awkgram.c" /* yacc.c:1646 */ +#line 3902 "awkgram.c" /* yacc.c:1646 */ break; case 171: -#line 1794 "awkgram.y" /* yacc.c:1646 */ +#line 1780 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_create((yyvsp[0])); } -#line 3924 "awkgram.c" /* yacc.c:1646 */ +#line 3910 "awkgram.c" /* yacc.c:1646 */ break; case 172: -#line 1798 "awkgram.y" /* yacc.c:1646 */ +#line 1784 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_create((yyvsp[0])); } -#line 3932 "awkgram.c" /* yacc.c:1646 */ +#line 3918 "awkgram.c" /* yacc.c:1646 */ break; case 173: -#line 1802 "awkgram.y" /* yacc.c:1646 */ +#line 1788 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[0])->lasti->opcode == Op_push_i && ((yyvsp[0])->lasti->memory->flags & STRING) == 0 @@ -3947,11 +3933,11 @@ regular_print: (yyval) = list_append((yyvsp[0]), (yyvsp[-1])); } } -#line 3951 "awkgram.c" /* yacc.c:1646 */ +#line 3937 "awkgram.c" /* yacc.c:1646 */ break; case 174: -#line 1817 "awkgram.y" /* yacc.c:1646 */ +#line 1803 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[0])->lasti->opcode == Op_push_i && ((yyvsp[0])->lasti->memory->flags & STRING) == 0 @@ -3969,20 +3955,20 @@ regular_print: (yyval) = list_append((yyvsp[0]), (yyvsp[-1])); } } -#line 3973 "awkgram.c" /* yacc.c:1646 */ +#line 3959 "awkgram.c" /* yacc.c:1646 */ break; case 175: -#line 1838 "awkgram.y" /* yacc.c:1646 */ +#line 1824 "awkgram.y" /* yacc.c:1646 */ { func_use((yyvsp[0])->lasti->func_name, FUNC_USE); (yyval) = (yyvsp[0]); } -#line 3982 "awkgram.c" /* yacc.c:1646 */ +#line 3968 "awkgram.c" /* yacc.c:1646 */ break; case 176: -#line 1843 "awkgram.y" /* yacc.c:1646 */ +#line 1829 "awkgram.y" /* yacc.c:1646 */ { /* indirect function call */ INSTRUCTION *f, *t; @@ -4016,11 +4002,11 @@ regular_print: (yyval) = list_prepend((yyvsp[0]), t); at_seen = false; } -#line 4020 "awkgram.c" /* yacc.c:1646 */ +#line 4006 "awkgram.c" /* yacc.c:1646 */ break; case 177: -#line 1880 "awkgram.y" /* yacc.c:1646 */ +#line 1866 "awkgram.y" /* yacc.c:1646 */ { NODE *n; @@ -4045,49 +4031,49 @@ regular_print: (yyval) = list_append(t, (yyvsp[-3])); } } -#line 4049 "awkgram.c" /* yacc.c:1646 */ +#line 4035 "awkgram.c" /* yacc.c:1646 */ break; case 178: -#line 1908 "awkgram.y" /* yacc.c:1646 */ +#line 1894 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 4055 "awkgram.c" /* yacc.c:1646 */ +#line 4041 "awkgram.c" /* yacc.c:1646 */ break; case 179: -#line 1910 "awkgram.y" /* yacc.c:1646 */ +#line 1896 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 4061 "awkgram.c" /* yacc.c:1646 */ +#line 4047 "awkgram.c" /* yacc.c:1646 */ break; case 180: -#line 1915 "awkgram.y" /* yacc.c:1646 */ +#line 1901 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 4067 "awkgram.c" /* yacc.c:1646 */ +#line 4053 "awkgram.c" /* yacc.c:1646 */ break; case 181: -#line 1917 "awkgram.y" /* yacc.c:1646 */ +#line 1903 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 4073 "awkgram.c" /* yacc.c:1646 */ +#line 4059 "awkgram.c" /* yacc.c:1646 */ break; case 182: -#line 1922 "awkgram.y" /* yacc.c:1646 */ +#line 1908 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 4079 "awkgram.c" /* yacc.c:1646 */ +#line 4065 "awkgram.c" /* yacc.c:1646 */ break; case 183: -#line 1924 "awkgram.y" /* yacc.c:1646 */ +#line 1910 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_merge((yyvsp[-1]), (yyvsp[0])); } -#line 4087 "awkgram.c" /* yacc.c:1646 */ +#line 4073 "awkgram.c" /* yacc.c:1646 */ break; case 184: -#line 1931 "awkgram.y" /* yacc.c:1646 */ +#line 1917 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *ip = (yyvsp[0])->lasti; int count = ip->sub_count; /* # of SUBSEP-seperated expressions */ @@ -4101,11 +4087,11 @@ regular_print: sub_counter++; /* count # of dimensions */ (yyval) = (yyvsp[0]); } -#line 4105 "awkgram.c" /* yacc.c:1646 */ +#line 4091 "awkgram.c" /* yacc.c:1646 */ break; case 185: -#line 1948 "awkgram.y" /* yacc.c:1646 */ +#line 1934 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *t = (yyvsp[-1]); if ((yyvsp[-1]) == NULL) { @@ -4119,31 +4105,31 @@ regular_print: (yyvsp[0])->sub_count = count_expressions(&t, false); (yyval) = list_append(t, (yyvsp[0])); } -#line 4123 "awkgram.c" /* yacc.c:1646 */ +#line 4109 "awkgram.c" /* yacc.c:1646 */ break; case 186: -#line 1965 "awkgram.y" /* yacc.c:1646 */ +#line 1951 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 4129 "awkgram.c" /* yacc.c:1646 */ +#line 4115 "awkgram.c" /* yacc.c:1646 */ break; case 187: -#line 1967 "awkgram.y" /* yacc.c:1646 */ +#line 1953 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_merge((yyvsp[-1]), (yyvsp[0])); } -#line 4137 "awkgram.c" /* yacc.c:1646 */ +#line 4123 "awkgram.c" /* yacc.c:1646 */ break; case 188: -#line 1974 "awkgram.y" /* yacc.c:1646 */ +#line 1960 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 4143 "awkgram.c" /* yacc.c:1646 */ +#line 4129 "awkgram.c" /* yacc.c:1646 */ break; case 189: -#line 1979 "awkgram.y" /* yacc.c:1646 */ +#line 1965 "awkgram.y" /* yacc.c:1646 */ { char *var_name = (yyvsp[0])->lextok; @@ -4151,22 +4137,22 @@ regular_print: (yyvsp[0])->memory = variable((yyvsp[0])->source_line, var_name, Node_var_new); (yyval) = list_create((yyvsp[0])); } -#line 4155 "awkgram.c" /* yacc.c:1646 */ +#line 4141 "awkgram.c" /* yacc.c:1646 */ break; case 190: -#line 1987 "awkgram.y" /* yacc.c:1646 */ +#line 1973 "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 4166 "awkgram.c" /* yacc.c:1646 */ +#line 4152 "awkgram.c" /* yacc.c:1646 */ break; case 191: -#line 1997 "awkgram.y" /* yacc.c:1646 */ +#line 1983 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *ip = (yyvsp[0])->nexti; if (ip->opcode == Op_push @@ -4178,73 +4164,73 @@ regular_print: } else (yyval) = (yyvsp[0]); } -#line 4182 "awkgram.c" /* yacc.c:1646 */ +#line 4168 "awkgram.c" /* yacc.c:1646 */ break; case 192: -#line 2009 "awkgram.y" /* yacc.c:1646 */ +#line 1995 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_append((yyvsp[-1]), (yyvsp[-2])); if ((yyvsp[0]) != NULL) mk_assignment((yyvsp[-1]), NULL, (yyvsp[0])); } -#line 4192 "awkgram.c" /* yacc.c:1646 */ +#line 4178 "awkgram.c" /* yacc.c:1646 */ break; case 193: -#line 2018 "awkgram.y" /* yacc.c:1646 */ +#line 2004 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_postincrement; } -#line 4200 "awkgram.c" /* yacc.c:1646 */ +#line 4186 "awkgram.c" /* yacc.c:1646 */ break; case 194: -#line 2022 "awkgram.y" /* yacc.c:1646 */ +#line 2008 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_postdecrement; } -#line 4208 "awkgram.c" /* yacc.c:1646 */ +#line 4194 "awkgram.c" /* yacc.c:1646 */ break; case 195: -#line 2025 "awkgram.y" /* yacc.c:1646 */ +#line 2011 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 4214 "awkgram.c" /* yacc.c:1646 */ +#line 4200 "awkgram.c" /* yacc.c:1646 */ break; case 197: -#line 2033 "awkgram.y" /* yacc.c:1646 */ +#line 2019 "awkgram.y" /* yacc.c:1646 */ { yyerrok; } -#line 4220 "awkgram.c" /* yacc.c:1646 */ +#line 4206 "awkgram.c" /* yacc.c:1646 */ break; case 198: -#line 2037 "awkgram.y" /* yacc.c:1646 */ +#line 2023 "awkgram.y" /* yacc.c:1646 */ { yyerrok; } -#line 4226 "awkgram.c" /* yacc.c:1646 */ +#line 4212 "awkgram.c" /* yacc.c:1646 */ break; case 201: -#line 2046 "awkgram.y" /* yacc.c:1646 */ +#line 2032 "awkgram.y" /* yacc.c:1646 */ { yyerrok; } -#line 4232 "awkgram.c" /* yacc.c:1646 */ +#line 4218 "awkgram.c" /* yacc.c:1646 */ break; case 202: -#line 2050 "awkgram.y" /* yacc.c:1646 */ +#line 2036 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); yyerrok; } -#line 4238 "awkgram.c" /* yacc.c:1646 */ +#line 4224 "awkgram.c" /* yacc.c:1646 */ break; case 203: -#line 2054 "awkgram.y" /* yacc.c:1646 */ +#line 2040 "awkgram.y" /* yacc.c:1646 */ { yyerrok; } -#line 4244 "awkgram.c" /* yacc.c:1646 */ +#line 4230 "awkgram.c" /* yacc.c:1646 */ break; -#line 4248 "awkgram.c" /* yacc.c:1646 */ +#line 4234 "awkgram.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -4472,7 +4458,7 @@ yyreturn: #endif return yyresult; } -#line 2056 "awkgram.y" /* yacc.c:1906 */ +#line 2042 "awkgram.y" /* yacc.c:1906 */ struct token { @@ -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/doc/ChangeLog b/doc/ChangeLog index c9c618d2..68c139a9 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -12,6 +12,11 @@ * gawktexi.in: Update description of awk_ext_func_t structure. +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..67b52f5e 100644 --- a/doc/gawk.info +++ b/doc/gawk.info @@ -23627,7 +23627,8 @@ use them. ' AWK_STRING,' ' AWK_ARRAY,' ' AWK_SCALAR, /* opaque access to a variable */' -' AWK_VALUE_COOKIE /* for updating a previously created value */' +' AWK_VALUE_COOKIE, /* for updating a previously created value */' +' AWK_REGEX' '} awk_valtype_t;' This 'enum' indicates the type of a value. It is used in the following 'struct'. @@ -23647,6 +23648,7 @@ use them. type. '#define str_value u.s' +'#define regex_value str_value' '#define num_value u.d' '#define array_cookie u.a' '#define scalar_cookie u.scl' @@ -23665,7 +23667,7 @@ 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 + Scalar values in 'awk' are numbers, strings, or typed regexps. The 'awk_value_t' struct represents values. The 'val_type' member indicates what is in the 'union'. @@ -23674,6 +23676,12 @@ 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. + 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 +23841,11 @@ 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_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'. + File: gawk.info, Node: Registration Functions, Next: Printing Messages, Prev: Constructor Functions, Up: Extension API Description @@ -24580,8 +24593,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_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,8 +24709,8 @@ 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. + later assignment. Only values of type 'AWK_NUMBER', 'AWK_REGEX', + and 'AWK_STRING' are allowed. Any other type is rejected. 'AWK_UNDEFINED' could be allowed, but doing so would result in inferior performance. @@ -25348,7 +25362,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' @@ -35806,142 +35820,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-1963823 +Node: Memory Allocation Functions964122 +Ref: Memory Allocation Functions-Footnote-1966967 +Node: Constructor Functions967066 +Node: Registration Functions969028 +Node: Extension Functions969713 +Node: Exit Callback Functions974911 +Node: Extension Version String976161 +Node: Input Parsers976824 +Node: Output Wrappers986706 +Node: Two-way processors991218 +Node: Printing Messages993483 +Ref: Printing Messages-Footnote-1994654 +Node: Updating ERRNO994807 +Node: Requesting Values995546 +Ref: table-value-types-returned996283 +Node: Accessing Parameters997166 +Node: Symbol Table Access998401 +Node: Symbol table by name998913 +Node: Symbol table by cookie1000702 +Ref: Symbol table by cookie-Footnote-11004873 +Node: Cached values1004937 +Ref: Cached values-Footnote-11008458 +Node: Array Manipulation1008549 +Ref: Array Manipulation-Footnote-11009640 +Node: Array Data Types1009677 +Ref: Array Data Types-Footnote-11012335 +Node: Array Functions1012427 +Node: Flattening Arrays1016285 +Node: Creating Arrays1023193 +Node: Redirection API1027962 +Node: Extension API Variables1030793 +Node: Extension Versioning1031426 +Ref: gawk-api-version1031863 +Node: Extension API Informational Variables1033591 +Node: Extension API Boilerplate1034655 +Node: Changes from API V11038517 +Node: Finding Extensions1039177 +Node: Extension Example1039736 +Node: Internal File Description1040534 +Node: Internal File Ops1044614 +Ref: Internal File Ops-Footnote-11056014 +Node: Using Internal File Ops1056154 +Ref: Using Internal File Ops-Footnote-11058537 +Node: Extension Samples1058811 +Node: Extension Sample File Functions1060340 +Node: Extension Sample Fnmatch1067989 +Node: Extension Sample Fork1069476 +Node: Extension Sample Inplace1070694 +Node: Extension Sample Ord1073904 +Node: Extension Sample Readdir1074740 +Ref: table-readdir-file-types1075629 +Node: Extension Sample Revout1076434 +Node: Extension Sample Rev2way1077023 +Node: Extension Sample Read write array1077763 +Node: Extension Sample Readfile1079705 +Node: Extension Sample Time1080800 +Node: Extension Sample API Tests1082148 +Node: gawkextlib1082640 +Node: Extension summary1085087 +Node: Extension Exercises1088789 +Node: Language History1090287 +Node: V7/SVR3.11091943 +Node: SVR41094095 +Node: POSIX1095529 +Node: BTL1096908 +Node: POSIX/GNU1097637 +Node: Feature History1103499 +Node: Common Extensions1117869 +Node: Ranges and Locales1119152 +Ref: Ranges and Locales-Footnote-11123768 +Ref: Ranges and Locales-Footnote-21123795 +Ref: Ranges and Locales-Footnote-31124030 +Node: Contributors1124251 +Node: History summary1129811 +Node: Installation1131191 +Node: Gawk Distribution1132135 +Node: Getting1132619 +Node: Extracting1133580 +Node: Distribution contents1135218 +Node: Unix Installation1141303 +Node: Quick Installation1141985 +Node: Shell Startup Files1144399 +Node: Additional Configuration Options1145477 +Node: Configuration Philosophy1147282 +Node: Non-Unix Installation1149651 +Node: PC Installation1150111 +Node: PC Binary Installation1150949 +Node: PC Compiling1151384 +Node: PC Using1152501 +Node: Cygwin1155546 +Node: MSYS1156316 +Node: VMS Installation1156817 +Node: VMS Compilation1157608 +Ref: VMS Compilation-Footnote-11158837 +Node: VMS Dynamic Extensions1158895 +Node: VMS Installation Details1160580 +Node: VMS Running1162833 +Node: VMS GNV1167112 +Node: VMS Old Gawk1167847 +Node: Bugs1168318 +Node: Bug address1168981 +Node: Usenet1171378 +Node: Maintainers1172153 +Node: Other Versions1173529 +Node: Installation summary1180113 +Node: Notes1181148 +Node: Compatibility Mode1182013 +Node: Additions1182795 +Node: Accessing The Source1183720 +Node: Adding Code1185155 +Node: New Ports1191374 +Node: Derived Files1195862 +Ref: Derived Files-Footnote-11201347 +Ref: Derived Files-Footnote-21201382 +Ref: Derived Files-Footnote-31201980 +Node: Future Extensions1202094 +Node: Implementation Limitations1202752 +Node: Extension Design1203935 +Node: Old Extension Problems1205089 +Ref: Old Extension Problems-Footnote-11206607 +Node: Extension New Mechanism Goals1206664 +Ref: Extension New Mechanism Goals-Footnote-11210028 +Node: Extension Other Design Decisions1210217 +Node: Extension Future Growth1212330 +Node: Old Extension Mechanism1213166 +Node: Notes summary1214929 +Node: Basic Concepts1216111 +Node: Basic High Level1216792 +Ref: figure-general-flow1217074 +Ref: figure-process-flow1217759 +Ref: Basic High Level-Footnote-11221060 +Node: Basic Data Typing1221245 +Node: Glossary1224573 +Node: Copying1256520 +Node: GNU Free Documentation License1294059 +Node: Index1319177 End Tag Table diff --git a/doc/gawk.texi b/doc/gawk.texi index 4998f81e..35db3479 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -32559,7 +32559,8 @@ multibyte encoding. @itemx @ @ @ @ AWK_STRING, @itemx @ @ @ @ AWK_ARRAY, @itemx @ @ @ @ AWK_SCALAR,@ @ @ @ @ @ @ @ @ /* opaque access to a variable */ -@itemx @ @ @ @ AWK_VALUE_COOKIE@ @ @ @ /* for updating a previously created value */ +@itemx @ @ @ @ AWK_VALUE_COOKIE,@ @ @ /* for updating a previously created value */ +@itemx @ @ @ @ AWK_REGEX @itemx @} awk_valtype_t; This @code{enum} indicates the type of a value. It is used in the following @code{struct}. @@ -32579,6 +32580,7 @@ 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 regex_value@ @ @ @ str_value @itemx #define num_value@ @ @ @ @ @ u.d @itemx #define array_cookie@ @ @ u.a @itemx #define scalar_cookie@ @ u.scl @@ -32599,7 +32601,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, 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 +32610,12 @@ 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. +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 +32782,11 @@ 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_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}. @end table @node Registration Functions @@ -33458,6 +33471,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 +33547,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 +33570,29 @@ 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 | Number | Regex | Array | Undefined | ++-----------+-----------+------------+------------+-----------+-----------+-----------+ +| | String | String | String | String | false | false | +| +-----------+------------+------------+-----------+-----------+-----------+ +| | Number | Number if | Number | false | false | false | +| | | can be | | | | | +| | | converted, | | | | | +| | | else false | | | | | +| +-----------+------------+------------+-----------+-----------+-----------+ +| | Regex | false | false | Regex | false | false | +| +-----------+------------+------------+-----------+-----------+-----------+ +| Type | Array | false | false | false | Array | false | +| Requested +-----------+------------+------------+-----------+-----------+-----------+ +| | Scalar | Scalar | Scalar | Scalar | false | false | +| +-----------+------------+------------+-----------+-----------+-----------+ +| | Undefined | String | Number | Regex | Array | Undefined | +| +-----------+------------+------------+-----------+-----------+-----------+ +| | Value | false | false | false | false | false | +| | Cookie | | | | | | ++-----------+-----------+------------+------------+-----------+-----------+-----------+ @end example @end ifplaintext @end float @@ -33675,7 +33692,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_REGEX}, or @code{AWK_NUMBER}. Here too, the predefined variables may not be updated. @end table @@ -33796,7 +33813,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}, 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. @@ -34540,7 +34557,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 diff --git a/doc/gawktexi.in b/doc/gawktexi.in index ca571514..f7f232a9 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -31573,7 +31573,8 @@ multibyte encoding. @itemx @ @ @ @ AWK_STRING, @itemx @ @ @ @ AWK_ARRAY, @itemx @ @ @ @ AWK_SCALAR,@ @ @ @ @ @ @ @ @ /* opaque access to a variable */ -@itemx @ @ @ @ AWK_VALUE_COOKIE@ @ @ @ /* for updating a previously created value */ +@itemx @ @ @ @ AWK_VALUE_COOKIE,@ @ @ /* for updating a previously created value */ +@itemx @ @ @ @ AWK_REGEX @itemx @} awk_valtype_t; This @code{enum} indicates the type of a value. It is used in the following @code{struct}. @@ -31593,6 +31594,7 @@ 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 regex_value@ @ @ @ str_value @itemx #define num_value@ @ @ @ @ @ u.d @itemx #define array_cookie@ @ @ u.a @itemx #define scalar_cookie@ @ u.scl @@ -31613,7 +31615,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, 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 +31624,12 @@ 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. +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 +31796,11 @@ 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_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}. @end table @node Registration Functions @@ -32472,6 +32485,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 +32561,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 +32584,29 @@ 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 | Number | Regex | Array | Undefined | ++-----------+-----------+------------+------------+-----------+-----------+-----------+ +| | String | String | String | String | false | false | +| +-----------+------------+------------+-----------+-----------+-----------+ +| | Number | Number if | Number | false | false | false | +| | | can be | | | | | +| | | converted, | | | | | +| | | else false | | | | | +| +-----------+------------+------------+-----------+-----------+-----------+ +| | Regex | false | false | Regex | false | false | +| +-----------+------------+------------+-----------+-----------+-----------+ +| Type | Array | false | false | false | Array | false | +| Requested +-----------+------------+------------+-----------+-----------+-----------+ +| | Scalar | Scalar | Scalar | Scalar | false | false | +| +-----------+------------+------------+-----------+-----------+-----------+ +| | Undefined | String | Number | Regex | Array | Undefined | +| +-----------+------------+------------+-----------+-----------+-----------+ +| | Value | false | false | false | false | false | +| | Cookie | | | | | | ++-----------+-----------+------------+------------+-----------+-----------+-----------+ @end example @end ifplaintext @end float @@ -32689,7 +32706,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_REGEX}, or @code{AWK_NUMBER}. Here too, the predefined variables may not be updated. @end table @@ -32810,7 +32827,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}, 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. @@ -33554,7 +33571,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 diff --git a/extension/ChangeLog b/extension/ChangeLog index 0642a955..bf7d3fa4 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -41,6 +41,15 @@ * testext.c: Ditto. * time.c: Ditto. +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..b62b6de0 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) * 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 regex or an array */ static awk_bool_t write_value(FILE *fp, awk_value_t *val) @@ -232,7 +232,7 @@ 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; + code = (val->val_type == AWK_STRING ? 0 : 3); if (fwrite(& code, 1, sizeof(code), fp) != sizeof(code)) return awk_false; @@ -449,7 +449,7 @@ read_value(FILE *fp, awk_value_t *value) return awk_false; } len = ntohl(len); - value->val_type = AWK_STRING; + value->val_type = (code == 0 ? AWK_STRING : AWK_REGEX); value->str_value.len = len; value->str_value.str = gawk_malloc(len + 1); memset(value->str_value.str, '\0', len + 1); @@ -164,6 +164,10 @@ 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_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) @@ -440,6 +444,15 @@ 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) +{ + assign_string(node, val); + val->val_type = AWK_REGEX; +} + /* node_to_awk_value --- convert a node into a value for an extension */ static awk_bool_t @@ -489,12 +502,19 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) ret = awk_true; break; + case AWK_REGEX: + assign_regex(node, val); + ret = awk_true; + break; + case AWK_SCALAR: fixtype(node); if ((node->flags & NUMBER) != 0) { val->val_type = AWK_NUMBER; } else if ((node->flags & STRING) != 0) { val->val_type = AWK_STRING; + } else if ((node->flags & REGEX) != 0) { + val->val_type = AWK_REGEX; } else val->val_type = AWK_UNDEFINED; ret = awk_false; @@ -513,6 +533,9 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) } else if ((node->flags & STRING) != 0) { assign_string(node, val); ret = awk_true; + } else if ((node->flags & REGEX) != 0) { + assign_regex(node, val); + ret = awk_true; } else val->val_type = AWK_UNDEFINED; break; @@ -618,6 +641,7 @@ api_sym_update(awk_ext_id_t id, switch (value->val_type) { case AWK_NUMBER: case AWK_STRING: + case AWK_REGEX: case AWK_UNDEFINED: case AWK_ARRAY: case AWK_SCALAR: @@ -715,6 +739,7 @@ api_sym_update_scalar(awk_ext_id_t id, return awk_true; } break; + case AWK_STRING: if (node->var_value->valref == 1) { NODE *r = node->var_value; @@ -735,11 +760,14 @@ api_sym_update_scalar(awk_ext_id_t id, 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; } @@ -763,6 +791,7 @@ valid_subscript_type(awk_valtype_t valtype) case AWK_UNDEFINED: case AWK_NUMBER: case AWK_STRING: + case AWK_REGEX: case AWK_SCALAR: case AWK_VALUE_COOKIE: return true; @@ -1005,6 +1034,8 @@ api_flatten_array(awk_ext_id_t id, * index to be a string, since indices are always * conceptually strings, regardless of internal optimizations * to treat them as integers in some cases. + * + * Regexes are forced to string too. */ if (! node_to_awk_value(index, & (*data)->elements[j].index, AWK_STRING)) { @@ -1073,6 +1104,7 @@ api_create_value(awk_ext_id_t id, awk_value_t *value, switch (value->val_type) { case AWK_NUMBER: case AWK_STRING: + case AWK_REGEX: break; default: /* reject anything other than a simple scalar */ @@ -308,7 +308,8 @@ typedef enum { AWK_STRING, AWK_ARRAY, AWK_SCALAR, /* opaque access to a variable */ - AWK_VALUE_COOKIE /* for updating a previously created value */ + AWK_VALUE_COOKIE, /* for updating a previously created value */ + AWK_REGEX /* last for binary compatibility */ } awk_valtype_t; /* @@ -325,6 +326,7 @@ typedef struct awk_value { awk_value_cookie_t vc; } u; #define str_value u.s +#define regex_value str_value #define num_value u.d #define array_cookie u.a #define scalar_cookie u.scl @@ -493,27 +495,29 @@ 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 | Number | Regex | Array | Undefined | + +-----------+-----------+------------+------------+-----------+-----------+-----------+ + | | String | String | String | String | false | false | + | +-----------+------------+------------+-----------+-----------+-----------+ + | | Number | Number if | Number | false | false | false | + | | | can be | | | | | + | | | converted, | | | | | + | | | else false | | | | | + | +-----------+------------+------------+-----------+-----------+-----------+ + | | Regex | false | false | Regex | false | false | + | +-----------+------------+------------+-----------+-----------+-----------+ + | Type | Array | false | false | false | Array | false | + | Requested +-----------+------------+------------+-----------+-----------+-----------+ + | | Scalar | Scalar | Scalar | Scalar | false | false | + | +-----------+------------+------------+-----------+-----------+-----------+ + | | Undefined | String | Number | Regex | Array | Undefined | + | +-----------+------------+------------+-----------+-----------+-----------+ + | | Value | false | false | false | false | false | + | | Cookie | | | | | | + +-----------+-----------+------------+------------+-----------+-----------+-----------+ */ /* Functions to handle parameters passed to the extension. */ @@ -839,21 +843,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 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,8 +873,22 @@ 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_regex(str, len, result) r_make_string_type(api, ext_id, str, len, 1, result, AWK_REGEX) /* make_null_string --- make a null string value */ @@ -895,6 +914,7 @@ make_number(double num, awk_value_t *result) return result; } + /* * Each extension must define a function with this prototype: * @@ -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..a2dbdc5a 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,13 @@ +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..70809b64 100644 --- a/test/rwarray.awk +++ b/test/rwarray.awk @@ -4,6 +4,9 @@ BEGIN { while ((getline word) > 0) dict[word] = word word + re_sub = "/typed-regex/" + dict[re_sub] = @/search me/ + n = asorti(dict, dictindices) for (i = 1; i <= n; i++) printf("dict[%s] = %s\n", dictindices[i], dict[dictindices[i]]) > "orig.out" @@ -12,7 +15,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 +39,8 @@ 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])); } |