aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--TODO4
-rw-r--r--awk.h2
-rw-r--r--awkgram.c384
-rw-r--r--awkgram.y2
-rw-r--r--doc/gawk.info667
-rw-r--r--doc/gawk.texi10
-rw-r--r--ext.c46
8 files changed, 388 insertions, 737 deletions
diff --git a/ChangeLog b/ChangeLog
index c8753bcf..05cdfed0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,16 @@
* regex.c: Don't include <sys/param.h> on VMS. Thanks to
Anders Wallin.
+ Also unrelated:
+
+ * ext.c (is_letter, is_identifier_char): New functions. Don't use
+ <ctype.h> functions since those could rely on the locale.
+ (make_builtin): Adjust test for valid name to call the new
+ functions and return false instead of throwing a fatal error.
+ * awk.h (is_identchar): Move from here, ...
+ * awkgram.y (is_identchar): ... to here. This is safe, since
+ the locale is C during parsing the program.
+
2012-12-07 Arnold D. Robbins <arnold@skeeve.com>
* awkgram.y (tokentab): `fflush()' is now in POSIX, remove the
diff --git a/TODO b/TODO
index 4179b14d..7f1d82ea 100644
--- a/TODO
+++ b/TODO
@@ -22,7 +22,9 @@ Minor Cleanups and Code Improvements
DONE: awk_true and awk_false
DONE: Update doc to use gcc -o filefuncs.so -shared filefuncs.o
instead of ld ...
- Have check for name not rely on isalpha, isalnum since the locale could botch that up.
+ DONE: Have check for name not rely on isalpha, isalnum since
+ the locale could botch that up. Also make it not
+ fatal.
??? #if !defined(GAWK) && !defined(GAWK_OMIT_CONVENIENCE_MACROS)
DONE: Make fflush() and fflush("") both flush all files, as in BWK awk.
diff --git a/awk.h b/awk.h
index b521b9d2..57bc80d9 100644
--- a/awk.h
+++ b/awk.h
@@ -1214,8 +1214,6 @@ DEREF(NODE *r)
#define iszero(n) ((n)->numbr == 0.0)
#endif
-#define is_identchar(c) (isalnum(c) || (c) == '_')
-
#define var_uninitialized(n) ((n)->var_value == Nnull_string)
#define get_lhs(n, r) (n)->type == Node_var && ! var_uninitialized(n) ? \
diff --git a/awkgram.c b/awkgram.c
index 54680e75..5f2c91c7 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -193,8 +193,10 @@ extern double fmod(double x, double y);
#define YYSTYPE INSTRUCTION *
+#define is_identchar(c) (isalnum(c) || (c) == '_')
+
/* Line 360 of yacc.c */
-#line 198 "awkgram.c"
+#line 200 "awkgram.c"
# ifndef YY_NULL
# if defined __cplusplus && 201103L <= __cplusplus
@@ -363,7 +365,7 @@ int yyparse ();
/* Copy the second part of user declarations. */
/* Line 379 of yacc.c */
-#line 367 "awkgram.c"
+#line 369 "awkgram.c"
#ifdef short
# undef short
@@ -727,25 +729,25 @@ static const yytype_int16 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 195, 195, 197, 202, 203, 209, 221, 225, 236,
- 242, 247, 255, 263, 265, 270, 278, 280, 286, 287,
- 289, 315, 326, 337, 343, 352, 362, 364, 366, 372,
- 377, 378, 382, 401, 400, 434, 436, 441, 442, 455,
- 460, 461, 465, 467, 469, 476, 566, 608, 650, 763,
- 770, 777, 787, 796, 805, 814, 825, 841, 840, 864,
- 876, 876, 974, 974, 1007, 1037, 1043, 1044, 1050, 1051,
- 1058, 1063, 1075, 1089, 1091, 1099, 1104, 1106, 1114, 1116,
- 1125, 1126, 1134, 1139, 1139, 1150, 1154, 1162, 1163, 1166,
- 1168, 1173, 1174, 1183, 1184, 1189, 1194, 1200, 1202, 1204,
- 1211, 1212, 1218, 1219, 1224, 1226, 1231, 1233, 1235, 1237,
- 1243, 1250, 1252, 1254, 1270, 1280, 1287, 1289, 1294, 1296,
- 1298, 1306, 1308, 1313, 1315, 1320, 1322, 1324, 1374, 1376,
- 1378, 1380, 1382, 1384, 1386, 1388, 1411, 1416, 1421, 1446,
- 1452, 1454, 1456, 1458, 1460, 1462, 1467, 1471, 1503, 1505,
- 1511, 1517, 1530, 1531, 1532, 1537, 1542, 1546, 1550, 1565,
- 1578, 1583, 1619, 1637, 1638, 1644, 1645, 1650, 1652, 1659,
- 1676, 1693, 1695, 1702, 1707, 1715, 1725, 1737, 1746, 1750,
- 1754, 1758, 1762, 1766, 1769, 1771, 1775, 1779, 1783
+ 0, 197, 197, 199, 204, 205, 211, 223, 227, 238,
+ 244, 249, 257, 265, 267, 272, 280, 282, 288, 289,
+ 291, 317, 328, 339, 345, 354, 364, 366, 368, 374,
+ 379, 380, 384, 403, 402, 436, 438, 443, 444, 457,
+ 462, 463, 467, 469, 471, 478, 568, 610, 652, 765,
+ 772, 779, 789, 798, 807, 816, 827, 843, 842, 866,
+ 878, 878, 976, 976, 1009, 1039, 1045, 1046, 1052, 1053,
+ 1060, 1065, 1077, 1091, 1093, 1101, 1106, 1108, 1116, 1118,
+ 1127, 1128, 1136, 1141, 1141, 1152, 1156, 1164, 1165, 1168,
+ 1170, 1175, 1176, 1185, 1186, 1191, 1196, 1202, 1204, 1206,
+ 1213, 1214, 1220, 1221, 1226, 1228, 1233, 1235, 1237, 1239,
+ 1245, 1252, 1254, 1256, 1272, 1282, 1289, 1291, 1296, 1298,
+ 1300, 1308, 1310, 1315, 1317, 1322, 1324, 1326, 1376, 1378,
+ 1380, 1382, 1384, 1386, 1388, 1390, 1413, 1418, 1423, 1448,
+ 1454, 1456, 1458, 1460, 1462, 1464, 1469, 1473, 1505, 1507,
+ 1513, 1519, 1532, 1533, 1534, 1539, 1544, 1548, 1552, 1567,
+ 1580, 1585, 1621, 1639, 1640, 1646, 1647, 1652, 1654, 1661,
+ 1678, 1695, 1697, 1704, 1709, 1717, 1727, 1739, 1748, 1752,
+ 1756, 1760, 1764, 1768, 1771, 1773, 1777, 1781, 1785
};
#endif
@@ -2029,7 +2031,7 @@ yyreduce:
{
case 3:
/* Line 1778 of yacc.c */
-#line 198 "awkgram.y"
+#line 200 "awkgram.y"
{
rule = 0;
yyerrok;
@@ -2038,7 +2040,7 @@ yyreduce:
case 5:
/* Line 1778 of yacc.c */
-#line 204 "awkgram.y"
+#line 206 "awkgram.y"
{
next_sourcefile();
if (sourcefile == srcfiles)
@@ -2048,7 +2050,7 @@ yyreduce:
case 6:
/* Line 1778 of yacc.c */
-#line 210 "awkgram.y"
+#line 212 "awkgram.y"
{
rule = 0;
/*
@@ -2061,7 +2063,7 @@ yyreduce:
case 7:
/* Line 1778 of yacc.c */
-#line 222 "awkgram.y"
+#line 224 "awkgram.y"
{
(void) append_rule((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
}
@@ -2069,7 +2071,7 @@ yyreduce:
case 8:
/* Line 1778 of yacc.c */
-#line 226 "awkgram.y"
+#line 228 "awkgram.y"
{
if (rule != Rule) {
msg(_("%s blocks must have an action part"), ruletab[rule]);
@@ -2084,7 +2086,7 @@ yyreduce:
case 9:
/* Line 1778 of yacc.c */
-#line 237 "awkgram.y"
+#line 239 "awkgram.y"
{
in_function = NULL;
(void) mk_function((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
@@ -2094,7 +2096,7 @@ yyreduce:
case 10:
/* Line 1778 of yacc.c */
-#line 243 "awkgram.y"
+#line 245 "awkgram.y"
{
want_source = false;
yyerrok;
@@ -2103,7 +2105,7 @@ yyreduce:
case 11:
/* Line 1778 of yacc.c */
-#line 248 "awkgram.y"
+#line 250 "awkgram.y"
{
want_source = false;
yyerrok;
@@ -2112,7 +2114,7 @@ yyreduce:
case 12:
/* Line 1778 of yacc.c */
-#line 256 "awkgram.y"
+#line 258 "awkgram.y"
{
if (include_source((yyvsp[(1) - (1)])) < 0)
YYABORT;
@@ -2124,19 +2126,19 @@ yyreduce:
case 13:
/* Line 1778 of yacc.c */
-#line 264 "awkgram.y"
+#line 266 "awkgram.y"
{ (yyval) = NULL; }
break;
case 14:
/* Line 1778 of yacc.c */
-#line 266 "awkgram.y"
+#line 268 "awkgram.y"
{ (yyval) = NULL; }
break;
case 15:
/* Line 1778 of yacc.c */
-#line 271 "awkgram.y"
+#line 273 "awkgram.y"
{
if (load_library((yyvsp[(1) - (1)])) < 0)
YYABORT;
@@ -2148,31 +2150,31 @@ yyreduce:
case 16:
/* Line 1778 of yacc.c */
-#line 279 "awkgram.y"
+#line 281 "awkgram.y"
{ (yyval) = NULL; }
break;
case 17:
/* Line 1778 of yacc.c */
-#line 281 "awkgram.y"
+#line 283 "awkgram.y"
{ (yyval) = NULL; }
break;
case 18:
/* Line 1778 of yacc.c */
-#line 286 "awkgram.y"
+#line 288 "awkgram.y"
{ (yyval) = NULL; rule = Rule; }
break;
case 19:
/* Line 1778 of yacc.c */
-#line 288 "awkgram.y"
+#line 290 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); rule = Rule; }
break;
case 20:
/* Line 1778 of yacc.c */
-#line 290 "awkgram.y"
+#line 292 "awkgram.y"
{
INSTRUCTION *tp;
@@ -2202,7 +2204,7 @@ yyreduce:
case 21:
/* Line 1778 of yacc.c */
-#line 316 "awkgram.y"
+#line 318 "awkgram.y"
{
static int begin_seen = 0;
if (do_lint_old && ++begin_seen == 2)
@@ -2217,7 +2219,7 @@ yyreduce:
case 22:
/* Line 1778 of yacc.c */
-#line 327 "awkgram.y"
+#line 329 "awkgram.y"
{
static int end_seen = 0;
if (do_lint_old && ++end_seen == 2)
@@ -2232,7 +2234,7 @@ yyreduce:
case 23:
/* Line 1778 of yacc.c */
-#line 338 "awkgram.y"
+#line 340 "awkgram.y"
{
(yyvsp[(1) - (1)])->in_rule = rule = BEGINFILE;
(yyvsp[(1) - (1)])->source_file = source;
@@ -2242,7 +2244,7 @@ yyreduce:
case 24:
/* Line 1778 of yacc.c */
-#line 344 "awkgram.y"
+#line 346 "awkgram.y"
{
(yyvsp[(1) - (1)])->in_rule = rule = ENDFILE;
(yyvsp[(1) - (1)])->source_file = source;
@@ -2252,7 +2254,7 @@ yyreduce:
case 25:
/* Line 1778 of yacc.c */
-#line 353 "awkgram.y"
+#line 355 "awkgram.y"
{
if ((yyvsp[(2) - (5)]) == NULL)
(yyval) = list_create(instruction(Op_no_op));
@@ -2263,19 +2265,19 @@ yyreduce:
case 26:
/* Line 1778 of yacc.c */
-#line 363 "awkgram.y"
+#line 365 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 27:
/* Line 1778 of yacc.c */
-#line 365 "awkgram.y"
+#line 367 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 28:
/* Line 1778 of yacc.c */
-#line 367 "awkgram.y"
+#line 369 "awkgram.y"
{
yyerror(_("`%s' is a built-in function, it cannot be redefined"),
tokstart);
@@ -2285,13 +2287,13 @@ yyreduce:
case 29:
/* Line 1778 of yacc.c */
-#line 373 "awkgram.y"
+#line 375 "awkgram.y"
{ (yyval) = (yyvsp[(2) - (2)]); }
break;
case 32:
/* Line 1778 of yacc.c */
-#line 383 "awkgram.y"
+#line 385 "awkgram.y"
{
(yyvsp[(1) - (6)])->source_file = source;
if (install_function((yyvsp[(2) - (6)])->lextok, (yyvsp[(1) - (6)]), (yyvsp[(4) - (6)])) < 0)
@@ -2306,13 +2308,13 @@ yyreduce:
case 33:
/* Line 1778 of yacc.c */
-#line 401 "awkgram.y"
+#line 403 "awkgram.y"
{ want_regexp = true; }
break;
case 34:
/* Line 1778 of yacc.c */
-#line 403 "awkgram.y"
+#line 405 "awkgram.y"
{
NODE *n, *exp;
char *re;
@@ -2345,19 +2347,19 @@ yyreduce:
case 35:
/* Line 1778 of yacc.c */
-#line 435 "awkgram.y"
+#line 437 "awkgram.y"
{ bcfree((yyvsp[(1) - (1)])); }
break;
case 37:
/* Line 1778 of yacc.c */
-#line 441 "awkgram.y"
+#line 443 "awkgram.y"
{ (yyval) = NULL; }
break;
case 38:
/* Line 1778 of yacc.c */
-#line 443 "awkgram.y"
+#line 445 "awkgram.y"
{
if ((yyvsp[(2) - (2)]) == NULL)
(yyval) = (yyvsp[(1) - (2)]);
@@ -2374,25 +2376,25 @@ yyreduce:
case 39:
/* Line 1778 of yacc.c */
-#line 456 "awkgram.y"
+#line 458 "awkgram.y"
{ (yyval) = NULL; }
break;
case 42:
/* Line 1778 of yacc.c */
-#line 466 "awkgram.y"
+#line 468 "awkgram.y"
{ (yyval) = NULL; }
break;
case 43:
/* Line 1778 of yacc.c */
-#line 468 "awkgram.y"
+#line 470 "awkgram.y"
{ (yyval) = (yyvsp[(2) - (3)]); }
break;
case 44:
/* Line 1778 of yacc.c */
-#line 470 "awkgram.y"
+#line 472 "awkgram.y"
{
if (do_pretty_print)
(yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count));
@@ -2403,7 +2405,7 @@ yyreduce:
case 45:
/* Line 1778 of yacc.c */
-#line 477 "awkgram.y"
+#line 479 "awkgram.y"
{
INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt;
INSTRUCTION *ip, *nextc, *tbreak;
@@ -2497,7 +2499,7 @@ yyreduce:
case 46:
/* Line 1778 of yacc.c */
-#line 567 "awkgram.y"
+#line 569 "awkgram.y"
{
/*
* -----------------
@@ -2543,7 +2545,7 @@ yyreduce:
case 47:
/* Line 1778 of yacc.c */
-#line 609 "awkgram.y"
+#line 611 "awkgram.y"
{
/*
* -----------------
@@ -2589,7 +2591,7 @@ yyreduce:
case 48:
/* Line 1778 of yacc.c */
-#line 651 "awkgram.y"
+#line 653 "awkgram.y"
{
INSTRUCTION *ip;
char *var_name = (yyvsp[(3) - (8)])->lextok;
@@ -2706,7 +2708,7 @@ regular_loop:
case 49:
/* Line 1778 of yacc.c */
-#line 764 "awkgram.y"
+#line 766 "awkgram.y"
{
(yyval) = mk_for_loop((yyvsp[(1) - (12)]), (yyvsp[(3) - (12)]), (yyvsp[(6) - (12)]), (yyvsp[(9) - (12)]), (yyvsp[(12) - (12)]));
@@ -2717,7 +2719,7 @@ regular_loop:
case 50:
/* Line 1778 of yacc.c */
-#line 771 "awkgram.y"
+#line 773 "awkgram.y"
{
(yyval) = mk_for_loop((yyvsp[(1) - (11)]), (yyvsp[(3) - (11)]), (INSTRUCTION *) NULL, (yyvsp[(8) - (11)]), (yyvsp[(11) - (11)]));
@@ -2728,7 +2730,7 @@ regular_loop:
case 51:
/* Line 1778 of yacc.c */
-#line 778 "awkgram.y"
+#line 780 "awkgram.y"
{
if (do_pretty_print)
(yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count));
@@ -2739,7 +2741,7 @@ regular_loop:
case 52:
/* Line 1778 of yacc.c */
-#line 788 "awkgram.y"
+#line 790 "awkgram.y"
{
if (! break_allowed)
error_ln((yyvsp[(1) - (2)])->source_line,
@@ -2752,7 +2754,7 @@ regular_loop:
case 53:
/* Line 1778 of yacc.c */
-#line 797 "awkgram.y"
+#line 799 "awkgram.y"
{
if (! continue_allowed)
error_ln((yyvsp[(1) - (2)])->source_line,
@@ -2765,7 +2767,7 @@ regular_loop:
case 54:
/* Line 1778 of yacc.c */
-#line 806 "awkgram.y"
+#line 808 "awkgram.y"
{
/* if inside function (rule = 0), resolve context at run-time */
if (rule && rule != Rule)
@@ -2778,7 +2780,7 @@ regular_loop:
case 55:
/* Line 1778 of yacc.c */
-#line 815 "awkgram.y"
+#line 817 "awkgram.y"
{
/* if inside function (rule = 0), resolve context at run-time */
if (rule == BEGIN || rule == END || rule == ENDFILE)
@@ -2793,7 +2795,7 @@ regular_loop:
case 56:
/* Line 1778 of yacc.c */
-#line 826 "awkgram.y"
+#line 828 "awkgram.y"
{
/* Initialize the two possible jump targets, the actual target
* is resolved at run-time.
@@ -2812,7 +2814,7 @@ regular_loop:
case 57:
/* Line 1778 of yacc.c */
-#line 841 "awkgram.y"
+#line 843 "awkgram.y"
{
if (! in_function)
yyerror(_("`return' used outside function context"));
@@ -2821,7 +2823,7 @@ regular_loop:
case 58:
/* Line 1778 of yacc.c */
-#line 844 "awkgram.y"
+#line 846 "awkgram.y"
{
if ((yyvsp[(3) - (4)]) == NULL) {
(yyval) = list_create((yyvsp[(1) - (4)]));
@@ -2846,13 +2848,13 @@ regular_loop:
case 60:
/* Line 1778 of yacc.c */
-#line 876 "awkgram.y"
+#line 878 "awkgram.y"
{ in_print = true; in_parens = 0; }
break;
case 61:
/* Line 1778 of yacc.c */
-#line 877 "awkgram.y"
+#line 879 "awkgram.y"
{
/*
* Optimization: plain `print' has no expression list, so $3 is null.
@@ -2953,13 +2955,13 @@ regular_print:
case 62:
/* Line 1778 of yacc.c */
-#line 974 "awkgram.y"
+#line 976 "awkgram.y"
{ sub_counter = 0; }
break;
case 63:
/* Line 1778 of yacc.c */
-#line 975 "awkgram.y"
+#line 977 "awkgram.y"
{
char *arr = (yyvsp[(2) - (4)])->lextok;
@@ -2996,7 +2998,7 @@ regular_print:
case 64:
/* Line 1778 of yacc.c */
-#line 1012 "awkgram.y"
+#line 1014 "awkgram.y"
{
static bool warned = false;
char *arr = (yyvsp[(3) - (4)])->lextok;
@@ -3026,31 +3028,31 @@ regular_print:
case 65:
/* Line 1778 of yacc.c */
-#line 1038 "awkgram.y"
+#line 1040 "awkgram.y"
{ (yyval) = optimize_assignment((yyvsp[(1) - (1)])); }
break;
case 66:
/* Line 1778 of yacc.c */
-#line 1043 "awkgram.y"
+#line 1045 "awkgram.y"
{ (yyval) = NULL; }
break;
case 67:
/* Line 1778 of yacc.c */
-#line 1045 "awkgram.y"
+#line 1047 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 68:
/* Line 1778 of yacc.c */
-#line 1050 "awkgram.y"
+#line 1052 "awkgram.y"
{ (yyval) = NULL; }
break;
case 69:
/* Line 1778 of yacc.c */
-#line 1052 "awkgram.y"
+#line 1054 "awkgram.y"
{
if ((yyvsp[(1) - (2)]) == NULL)
(yyval) = list_create((yyvsp[(2) - (2)]));
@@ -3061,13 +3063,13 @@ regular_print:
case 70:
/* Line 1778 of yacc.c */
-#line 1059 "awkgram.y"
+#line 1061 "awkgram.y"
{ (yyval) = NULL; }
break;
case 71:
/* Line 1778 of yacc.c */
-#line 1064 "awkgram.y"
+#line 1066 "awkgram.y"
{
INSTRUCTION *casestmt = (yyvsp[(5) - (5)]);
if ((yyvsp[(5) - (5)]) == NULL)
@@ -3083,7 +3085,7 @@ regular_print:
case 72:
/* Line 1778 of yacc.c */
-#line 1076 "awkgram.y"
+#line 1078 "awkgram.y"
{
INSTRUCTION *casestmt = (yyvsp[(4) - (4)]);
if ((yyvsp[(4) - (4)]) == NULL)
@@ -3098,13 +3100,13 @@ regular_print:
case 73:
/* Line 1778 of yacc.c */
-#line 1090 "awkgram.y"
+#line 1092 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 74:
/* Line 1778 of yacc.c */
-#line 1092 "awkgram.y"
+#line 1094 "awkgram.y"
{
NODE *n = (yyvsp[(2) - (2)])->memory;
(void) force_number(n);
@@ -3116,7 +3118,7 @@ regular_print:
case 75:
/* Line 1778 of yacc.c */
-#line 1100 "awkgram.y"
+#line 1102 "awkgram.y"
{
bcfree((yyvsp[(1) - (2)]));
(yyval) = (yyvsp[(2) - (2)]);
@@ -3125,13 +3127,13 @@ regular_print:
case 76:
/* Line 1778 of yacc.c */
-#line 1105 "awkgram.y"
+#line 1107 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 77:
/* Line 1778 of yacc.c */
-#line 1107 "awkgram.y"
+#line 1109 "awkgram.y"
{
(yyvsp[(1) - (1)])->opcode = Op_push_re;
(yyval) = (yyvsp[(1) - (1)]);
@@ -3140,19 +3142,19 @@ regular_print:
case 78:
/* Line 1778 of yacc.c */
-#line 1115 "awkgram.y"
+#line 1117 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 79:
/* Line 1778 of yacc.c */
-#line 1117 "awkgram.y"
+#line 1119 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 81:
/* Line 1778 of yacc.c */
-#line 1127 "awkgram.y"
+#line 1129 "awkgram.y"
{
(yyval) = (yyvsp[(2) - (3)]);
}
@@ -3160,7 +3162,7 @@ regular_print:
case 82:
/* Line 1778 of yacc.c */
-#line 1134 "awkgram.y"
+#line 1136 "awkgram.y"
{
in_print = false;
in_parens = 0;
@@ -3170,13 +3172,13 @@ regular_print:
case 83:
/* Line 1778 of yacc.c */
-#line 1139 "awkgram.y"
+#line 1141 "awkgram.y"
{ in_print = false; in_parens = 0; }
break;
case 84:
/* Line 1778 of yacc.c */
-#line 1140 "awkgram.y"
+#line 1142 "awkgram.y"
{
if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway
&& (yyvsp[(3) - (3)])->lasti->opcode == Op_K_getline_redir
@@ -3188,7 +3190,7 @@ regular_print:
case 85:
/* Line 1778 of yacc.c */
-#line 1151 "awkgram.y"
+#line 1153 "awkgram.y"
{
(yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]), (yyvsp[(6) - (6)]), NULL, NULL);
}
@@ -3196,7 +3198,7 @@ regular_print:
case 86:
/* Line 1778 of yacc.c */
-#line 1156 "awkgram.y"
+#line 1158 "awkgram.y"
{
(yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]), (yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)]));
}
@@ -3204,13 +3206,13 @@ regular_print:
case 91:
/* Line 1778 of yacc.c */
-#line 1173 "awkgram.y"
+#line 1175 "awkgram.y"
{ (yyval) = NULL; }
break;
case 92:
/* Line 1778 of yacc.c */
-#line 1175 "awkgram.y"
+#line 1177 "awkgram.y"
{
bcfree((yyvsp[(1) - (2)]));
(yyval) = (yyvsp[(2) - (2)]);
@@ -3219,19 +3221,19 @@ regular_print:
case 93:
/* Line 1778 of yacc.c */
-#line 1183 "awkgram.y"
+#line 1185 "awkgram.y"
{ (yyval) = NULL; }
break;
case 94:
/* Line 1778 of yacc.c */
-#line 1185 "awkgram.y"
+#line 1187 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]) ; }
break;
case 95:
/* Line 1778 of yacc.c */
-#line 1190 "awkgram.y"
+#line 1192 "awkgram.y"
{
(yyvsp[(1) - (1)])->param_count = 0;
(yyval) = list_create((yyvsp[(1) - (1)]));
@@ -3240,7 +3242,7 @@ regular_print:
case 96:
/* Line 1778 of yacc.c */
-#line 1195 "awkgram.y"
+#line 1197 "awkgram.y"
{
(yyvsp[(3) - (3)])->param_count = (yyvsp[(1) - (3)])->lasti->param_count + 1;
(yyval) = list_append((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]));
@@ -3250,55 +3252,55 @@ regular_print:
case 97:
/* Line 1778 of yacc.c */
-#line 1201 "awkgram.y"
+#line 1203 "awkgram.y"
{ (yyval) = NULL; }
break;
case 98:
/* Line 1778 of yacc.c */
-#line 1203 "awkgram.y"
+#line 1205 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (2)]); }
break;
case 99:
/* Line 1778 of yacc.c */
-#line 1205 "awkgram.y"
+#line 1207 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (3)]); }
break;
case 100:
/* Line 1778 of yacc.c */
-#line 1211 "awkgram.y"
+#line 1213 "awkgram.y"
{ (yyval) = NULL; }
break;
case 101:
/* Line 1778 of yacc.c */
-#line 1213 "awkgram.y"
+#line 1215 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 102:
/* Line 1778 of yacc.c */
-#line 1218 "awkgram.y"
+#line 1220 "awkgram.y"
{ (yyval) = NULL; }
break;
case 103:
/* Line 1778 of yacc.c */
-#line 1220 "awkgram.y"
+#line 1222 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 104:
/* Line 1778 of yacc.c */
-#line 1225 "awkgram.y"
+#line 1227 "awkgram.y"
{ (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); }
break;
case 105:
/* Line 1778 of yacc.c */
-#line 1227 "awkgram.y"
+#line 1229 "awkgram.y"
{
(yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]));
yyerrok;
@@ -3307,31 +3309,31 @@ regular_print:
case 106:
/* Line 1778 of yacc.c */
-#line 1232 "awkgram.y"
+#line 1234 "awkgram.y"
{ (yyval) = NULL; }
break;
case 107:
/* Line 1778 of yacc.c */
-#line 1234 "awkgram.y"
+#line 1236 "awkgram.y"
{ (yyval) = NULL; }
break;
case 108:
/* Line 1778 of yacc.c */
-#line 1236 "awkgram.y"
+#line 1238 "awkgram.y"
{ (yyval) = NULL; }
break;
case 109:
/* Line 1778 of yacc.c */
-#line 1238 "awkgram.y"
+#line 1240 "awkgram.y"
{ (yyval) = NULL; }
break;
case 110:
/* Line 1778 of yacc.c */
-#line 1244 "awkgram.y"
+#line 1246 "awkgram.y"
{
if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec)
lintwarn_ln((yyvsp[(2) - (3)])->source_line,
@@ -3342,19 +3344,19 @@ regular_print:
case 111:
/* Line 1778 of yacc.c */
-#line 1251 "awkgram.y"
+#line 1253 "awkgram.y"
{ (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 112:
/* Line 1778 of yacc.c */
-#line 1253 "awkgram.y"
+#line 1255 "awkgram.y"
{ (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 113:
/* Line 1778 of yacc.c */
-#line 1255 "awkgram.y"
+#line 1257 "awkgram.y"
{
if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec)
warning_ln((yyvsp[(2) - (3)])->source_line,
@@ -3374,7 +3376,7 @@ regular_print:
case 114:
/* Line 1778 of yacc.c */
-#line 1271 "awkgram.y"
+#line 1273 "awkgram.y"
{
if (do_lint_old)
warning_ln((yyvsp[(2) - (3)])->source_line,
@@ -3388,7 +3390,7 @@ regular_print:
case 115:
/* Line 1778 of yacc.c */
-#line 1281 "awkgram.y"
+#line 1283 "awkgram.y"
{
if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec)
lintwarn_ln((yyvsp[(2) - (3)])->source_line,
@@ -3399,31 +3401,31 @@ regular_print:
case 116:
/* Line 1778 of yacc.c */
-#line 1288 "awkgram.y"
+#line 1290 "awkgram.y"
{ (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]), (yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); }
break;
case 117:
/* Line 1778 of yacc.c */
-#line 1290 "awkgram.y"
+#line 1292 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 118:
/* Line 1778 of yacc.c */
-#line 1295 "awkgram.y"
+#line 1297 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 119:
/* Line 1778 of yacc.c */
-#line 1297 "awkgram.y"
+#line 1299 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 120:
/* Line 1778 of yacc.c */
-#line 1299 "awkgram.y"
+#line 1301 "awkgram.y"
{
(yyvsp[(2) - (2)])->opcode = Op_assign_quotient;
(yyval) = (yyvsp[(2) - (2)]);
@@ -3432,43 +3434,43 @@ regular_print:
case 121:
/* Line 1778 of yacc.c */
-#line 1307 "awkgram.y"
+#line 1309 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 122:
/* Line 1778 of yacc.c */
-#line 1309 "awkgram.y"
+#line 1311 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 123:
/* Line 1778 of yacc.c */
-#line 1314 "awkgram.y"
+#line 1316 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 124:
/* Line 1778 of yacc.c */
-#line 1316 "awkgram.y"
+#line 1318 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 125:
/* Line 1778 of yacc.c */
-#line 1321 "awkgram.y"
+#line 1323 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 126:
/* Line 1778 of yacc.c */
-#line 1323 "awkgram.y"
+#line 1325 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 127:
/* Line 1778 of yacc.c */
-#line 1325 "awkgram.y"
+#line 1327 "awkgram.y"
{
int count = 2;
bool is_simple_var = false;
@@ -3519,43 +3521,43 @@ regular_print:
case 129:
/* Line 1778 of yacc.c */
-#line 1377 "awkgram.y"
+#line 1379 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 130:
/* Line 1778 of yacc.c */
-#line 1379 "awkgram.y"
+#line 1381 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 131:
/* Line 1778 of yacc.c */
-#line 1381 "awkgram.y"
+#line 1383 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 132:
/* Line 1778 of yacc.c */
-#line 1383 "awkgram.y"
+#line 1385 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 133:
/* Line 1778 of yacc.c */
-#line 1385 "awkgram.y"
+#line 1387 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 134:
/* Line 1778 of yacc.c */
-#line 1387 "awkgram.y"
+#line 1389 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 135:
/* Line 1778 of yacc.c */
-#line 1389 "awkgram.y"
+#line 1391 "awkgram.y"
{
/*
* In BEGINFILE/ENDFILE, allow `getline var < file'
@@ -3582,7 +3584,7 @@ regular_print:
case 136:
/* Line 1778 of yacc.c */
-#line 1412 "awkgram.y"
+#line 1414 "awkgram.y"
{
(yyvsp[(2) - (2)])->opcode = Op_postincrement;
(yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)]));
@@ -3591,7 +3593,7 @@ regular_print:
case 137:
/* Line 1778 of yacc.c */
-#line 1417 "awkgram.y"
+#line 1419 "awkgram.y"
{
(yyvsp[(2) - (2)])->opcode = Op_postdecrement;
(yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)]));
@@ -3600,7 +3602,7 @@ regular_print:
case 138:
/* Line 1778 of yacc.c */
-#line 1422 "awkgram.y"
+#line 1424 "awkgram.y"
{
if (do_lint_old) {
warning_ln((yyvsp[(4) - (5)])->source_line,
@@ -3624,7 +3626,7 @@ regular_print:
case 139:
/* Line 1778 of yacc.c */
-#line 1447 "awkgram.y"
+#line 1449 "awkgram.y"
{
(yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type);
bcfree((yyvsp[(2) - (4)]));
@@ -3633,43 +3635,43 @@ regular_print:
case 140:
/* Line 1778 of yacc.c */
-#line 1453 "awkgram.y"
+#line 1455 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 141:
/* Line 1778 of yacc.c */
-#line 1455 "awkgram.y"
+#line 1457 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 142:
/* Line 1778 of yacc.c */
-#line 1457 "awkgram.y"
+#line 1459 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 143:
/* Line 1778 of yacc.c */
-#line 1459 "awkgram.y"
+#line 1461 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 144:
/* Line 1778 of yacc.c */
-#line 1461 "awkgram.y"
+#line 1463 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 145:
/* Line 1778 of yacc.c */
-#line 1463 "awkgram.y"
+#line 1465 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
break;
case 146:
/* Line 1778 of yacc.c */
-#line 1468 "awkgram.y"
+#line 1470 "awkgram.y"
{
(yyval) = list_create((yyvsp[(1) - (1)]));
}
@@ -3677,7 +3679,7 @@ regular_print:
case 147:
/* Line 1778 of yacc.c */
-#line 1472 "awkgram.y"
+#line 1474 "awkgram.y"
{
if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) {
(yyvsp[(2) - (2)])->opcode = Op_nomatch;
@@ -3713,13 +3715,13 @@ regular_print:
case 148:
/* Line 1778 of yacc.c */
-#line 1504 "awkgram.y"
+#line 1506 "awkgram.y"
{ (yyval) = (yyvsp[(2) - (3)]); }
break;
case 149:
/* Line 1778 of yacc.c */
-#line 1506 "awkgram.y"
+#line 1508 "awkgram.y"
{
(yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
if ((yyval) == NULL)
@@ -3729,7 +3731,7 @@ regular_print:
case 150:
/* Line 1778 of yacc.c */
-#line 1512 "awkgram.y"
+#line 1514 "awkgram.y"
{
(yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
if ((yyval) == NULL)
@@ -3739,7 +3741,7 @@ regular_print:
case 151:
/* Line 1778 of yacc.c */
-#line 1518 "awkgram.y"
+#line 1520 "awkgram.y"
{
static bool warned = false;
@@ -3756,7 +3758,7 @@ regular_print:
case 154:
/* Line 1778 of yacc.c */
-#line 1533 "awkgram.y"
+#line 1535 "awkgram.y"
{
(yyvsp[(1) - (2)])->opcode = Op_preincrement;
(yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)]));
@@ -3765,7 +3767,7 @@ regular_print:
case 155:
/* Line 1778 of yacc.c */
-#line 1538 "awkgram.y"
+#line 1540 "awkgram.y"
{
(yyvsp[(1) - (2)])->opcode = Op_predecrement;
(yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)]));
@@ -3774,7 +3776,7 @@ regular_print:
case 156:
/* Line 1778 of yacc.c */
-#line 1543 "awkgram.y"
+#line 1545 "awkgram.y"
{
(yyval) = list_create((yyvsp[(1) - (1)]));
}
@@ -3782,7 +3784,7 @@ regular_print:
case 157:
/* Line 1778 of yacc.c */
-#line 1547 "awkgram.y"
+#line 1549 "awkgram.y"
{
(yyval) = list_create((yyvsp[(1) - (1)]));
}
@@ -3790,7 +3792,7 @@ regular_print:
case 158:
/* Line 1778 of yacc.c */
-#line 1551 "awkgram.y"
+#line 1553 "awkgram.y"
{
if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i
&& ((yyvsp[(2) - (2)])->lasti->memory->flags & (STRCUR|STRING)) == 0
@@ -3809,7 +3811,7 @@ regular_print:
case 159:
/* Line 1778 of yacc.c */
-#line 1566 "awkgram.y"
+#line 1568 "awkgram.y"
{
/*
* was: $$ = $2
@@ -3823,7 +3825,7 @@ regular_print:
case 160:
/* Line 1778 of yacc.c */
-#line 1579 "awkgram.y"
+#line 1581 "awkgram.y"
{
func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE);
(yyval) = (yyvsp[(1) - (1)]);
@@ -3832,7 +3834,7 @@ regular_print:
case 161:
/* Line 1778 of yacc.c */
-#line 1584 "awkgram.y"
+#line 1586 "awkgram.y"
{
/* indirect function call */
INSTRUCTION *f, *t;
@@ -3869,7 +3871,7 @@ regular_print:
case 162:
/* Line 1778 of yacc.c */
-#line 1620 "awkgram.y"
+#line 1622 "awkgram.y"
{
param_sanity((yyvsp[(3) - (4)]));
(yyvsp[(1) - (4)])->opcode = Op_func_call;
@@ -3887,37 +3889,37 @@ regular_print:
case 163:
/* Line 1778 of yacc.c */
-#line 1637 "awkgram.y"
+#line 1639 "awkgram.y"
{ (yyval) = NULL; }
break;
case 164:
/* Line 1778 of yacc.c */
-#line 1639 "awkgram.y"
+#line 1641 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 165:
/* Line 1778 of yacc.c */
-#line 1644 "awkgram.y"
+#line 1646 "awkgram.y"
{ (yyval) = NULL; }
break;
case 166:
/* Line 1778 of yacc.c */
-#line 1646 "awkgram.y"
+#line 1648 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (2)]); }
break;
case 167:
/* Line 1778 of yacc.c */
-#line 1651 "awkgram.y"
+#line 1653 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 168:
/* Line 1778 of yacc.c */
-#line 1653 "awkgram.y"
+#line 1655 "awkgram.y"
{
(yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
}
@@ -3925,7 +3927,7 @@ regular_print:
case 169:
/* Line 1778 of yacc.c */
-#line 1660 "awkgram.y"
+#line 1662 "awkgram.y"
{
INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti;
int count = ip->sub_count; /* # of SUBSEP-seperated expressions */
@@ -3943,7 +3945,7 @@ regular_print:
case 170:
/* Line 1778 of yacc.c */
-#line 1677 "awkgram.y"
+#line 1679 "awkgram.y"
{
INSTRUCTION *t = (yyvsp[(2) - (3)]);
if ((yyvsp[(2) - (3)]) == NULL) {
@@ -3961,13 +3963,13 @@ regular_print:
case 171:
/* Line 1778 of yacc.c */
-#line 1694 "awkgram.y"
+#line 1696 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 172:
/* Line 1778 of yacc.c */
-#line 1696 "awkgram.y"
+#line 1698 "awkgram.y"
{
(yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
}
@@ -3975,13 +3977,13 @@ regular_print:
case 173:
/* Line 1778 of yacc.c */
-#line 1703 "awkgram.y"
+#line 1705 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (2)]); }
break;
case 174:
/* Line 1778 of yacc.c */
-#line 1708 "awkgram.y"
+#line 1710 "awkgram.y"
{
char *var_name = (yyvsp[(1) - (1)])->lextok;
@@ -3993,7 +3995,7 @@ regular_print:
case 175:
/* Line 1778 of yacc.c */
-#line 1716 "awkgram.y"
+#line 1718 "awkgram.y"
{
char *arr = (yyvsp[(1) - (2)])->lextok;
(yyvsp[(1) - (2)])->memory = variable((yyvsp[(1) - (2)])->source_line, arr, Node_var_new);
@@ -4004,7 +4006,7 @@ regular_print:
case 176:
/* Line 1778 of yacc.c */
-#line 1726 "awkgram.y"
+#line 1728 "awkgram.y"
{
INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti;
if (ip->opcode == Op_push
@@ -4020,7 +4022,7 @@ regular_print:
case 177:
/* Line 1778 of yacc.c */
-#line 1738 "awkgram.y"
+#line 1740 "awkgram.y"
{
(yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
if ((yyvsp[(3) - (3)]) != NULL)
@@ -4030,7 +4032,7 @@ regular_print:
case 178:
/* Line 1778 of yacc.c */
-#line 1747 "awkgram.y"
+#line 1749 "awkgram.y"
{
(yyvsp[(1) - (1)])->opcode = Op_postincrement;
}
@@ -4038,7 +4040,7 @@ regular_print:
case 179:
/* Line 1778 of yacc.c */
-#line 1751 "awkgram.y"
+#line 1753 "awkgram.y"
{
(yyvsp[(1) - (1)])->opcode = Op_postdecrement;
}
@@ -4046,43 +4048,43 @@ regular_print:
case 180:
/* Line 1778 of yacc.c */
-#line 1754 "awkgram.y"
+#line 1756 "awkgram.y"
{ (yyval) = NULL; }
break;
case 182:
/* Line 1778 of yacc.c */
-#line 1762 "awkgram.y"
+#line 1764 "awkgram.y"
{ yyerrok; }
break;
case 183:
/* Line 1778 of yacc.c */
-#line 1766 "awkgram.y"
+#line 1768 "awkgram.y"
{ yyerrok; }
break;
case 186:
/* Line 1778 of yacc.c */
-#line 1775 "awkgram.y"
+#line 1777 "awkgram.y"
{ yyerrok; }
break;
case 187:
/* Line 1778 of yacc.c */
-#line 1779 "awkgram.y"
+#line 1781 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); yyerrok; }
break;
case 188:
/* Line 1778 of yacc.c */
-#line 1783 "awkgram.y"
+#line 1785 "awkgram.y"
{ yyerrok; }
break;
/* Line 1778 of yacc.c */
-#line 4098 "awkgram.c"
+#line 4100 "awkgram.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -4314,7 +4316,7 @@ yyreturn:
/* Line 2041 of yacc.c */
-#line 1785 "awkgram.y"
+#line 1787 "awkgram.y"
struct token {
diff --git a/awkgram.y b/awkgram.y
index 3048cc80..fef5baa2 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -151,6 +151,8 @@ static inline INSTRUCTION *list_merge(INSTRUCTION *l1, INSTRUCTION *l2);
extern double fmod(double x, double y);
#define YYSTYPE INSTRUCTION *
+
+#define is_identchar(c) (isalnum(c) || (c) == '_')
%}
%token FUNC_CALL NAME REGEXP FILENAME
diff --git a/doc/gawk.info b/doc/gawk.info
index 8378fd94..6843effe 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -21828,16 +21828,14 @@ operations:
in `gawkapi.h'. For correct use, you must therefore include the
corresponding standard header file _before_ including `gawkapi.h':
- C Entity Header File
- -----------------------------
- `FILE' `<stdio.h>'
- `NULL' `<stddef.h>'
- `malloc()' `<stdlib.h>'
- `memset()',`<string.h>'
- `memcpy()'
- `size_t' `<sys/types.h>'
- `struct `<sys/stat.h>'
- stat'
+ C Entity Header File
+ -------------------------------------------
+ `FILE' `<stdio.h>'
+ `NULL' `<stddef.h>'
+ `malloc()' `<stdlib.h>'
+ `memset()', `memcpy()' `<string.h>'
+ `size_t' `<sys/types.h>'
+ `struct stat' `<sys/stat.h>'
Due to portability concerns, especially to systems that are not
fully standards-compliant, it is your responsibility to include
@@ -22184,12 +22182,19 @@ Extension functions are described by the following record:
The name of the new function. `awk' level code calls the function
by this name. This is a regular C string.
+ Function names must obey the rules for `awk' identifiers. That is,
+ they must begin with either a letter or an underscore, which may
+ be followed by any number of letters, digits, and underscores.
+
`awk_value_t *(*function)(int num_actual_args, awk_value_t *result);'
This is a pointer to the C function that provides the desired
functionality. The function must fill in the result with either a
number or a string. `awk' takes ownership of any string memory.
As mentioned earlier, string memory *must* come from `malloc()'.
+ The `num_actual_args' argument tells the C function how many
+ actual parameters were passed from the calling `awk' code.
+
The function must return the value of `result'. This is for the
convenience of the calling code inside `gawk'.
@@ -31774,7 +31779,6 @@ Index

Tag Table:
Node: Top1352
-<<<<<<< HEAD
Node: Foreword40138
Node: Preface44483
Ref: Preface-Footnote-147536
@@ -32173,533 +32177,118 @@ Ref: call-new-function876677
Node: Extension Future Growth878671
Node: Extension API Description879489
Node: Extension API Functions Introduction880817
-Node: General Data Types885517
-Ref: General Data Types-Footnote-1891119
-Node: Requesting Values891418
-Ref: table-value-types-returned892149
-Node: Constructor Functions893103
-Node: Registration Functions896099
-Node: Extension Functions896784
-Node: Exit Callback Functions898616
-Node: Extension Version String899859
-Node: Input Parsers900509
-Node: Output Wrappers909096
-Node: Two-way processors913512
-Node: Printing Messages915642
-Ref: Printing Messages-Footnote-1916719
-Node: Updating `ERRNO'916871
-Node: Accessing Parameters917610
-Node: Symbol Table Access918840
-Node: Symbol table by name919352
-Ref: Symbol table by name-Footnote-1921522
-Node: Symbol table by cookie921602
-Ref: Symbol table by cookie-Footnote-1925731
-Node: Cached values925794
-Ref: Cached values-Footnote-1929237
-Node: Array Manipulation929328
-Ref: Array Manipulation-Footnote-1930426
-Node: Array Data Types930465
-Ref: Array Data Types-Footnote-1933168
-Node: Array Functions933260
-Node: Flattening Arrays937026
-Node: Creating Arrays943859
-Node: Extension API Variables948654
-Node: Extension Versioning949290
-Node: Extension API Informational Variables951191
-Node: Extension API Boilerplate952277
-Node: Finding Extensions956108
-Node: Extension Example956655
-Node: Internal File Description957393
-Node: Internal File Ops961081
-Ref: Internal File Ops-Footnote-1972528
-Node: Using Internal File Ops972668
-Ref: Using Internal File Ops-Footnote-1975021
-Node: Extension Samples975287
-Node: Extension Sample File Functions976730
-Node: Extension Sample Fnmatch985203
-Node: Extension Sample Fork986929
-Node: Extension Sample Ord988143
-Node: Extension Sample Readdir988919
-Node: Extension Sample Revout990423
-Node: Extension Sample Rev2way991016
-Node: Extension Sample Read write array991706
-Node: Extension Sample Readfile993589
-Node: Extension Sample API Tests994344
-Node: Extension Sample Time994869
-Node: gawkextlib996176
-Node: Language History998557
-Node: V7/SVR3.11000079
-Node: SVR41002400
-Node: POSIX1003842
-Node: BTL1004850
-Node: POSIX/GNU1005655
-Node: Common Extensions1011190
-Node: Ranges and Locales1012249
-Ref: Ranges and Locales-Footnote-11016867
-Ref: Ranges and Locales-Footnote-21016894
-Ref: Ranges and Locales-Footnote-31017154
-Node: Contributors1017375
-Node: Installation1021671
-Node: Gawk Distribution1022565
-Node: Getting1023049
-Node: Extracting1023875
-Node: Distribution contents1025567
-Node: Unix Installation1030789
-Node: Quick Installation1031406
-Node: Additional Configuration Options1033368
-Node: Configuration Philosophy1034845
-Node: Non-Unix Installation1037187
-Node: PC Installation1037645
-Node: PC Binary Installation1038944
-Node: PC Compiling1040792
-Node: PC Testing1043736
-Node: PC Using1044912
-Node: Cygwin1049097
-Node: MSYS1050097
-Node: VMS Installation1050611
-Node: VMS Compilation1051214
-Ref: VMS Compilation-Footnote-11052221
-Node: VMS Installation Details1052279
-Node: VMS Running1053914
-Node: VMS Old Gawk1055521
-Node: Bugs1055995
-Node: Other Versions1059847
-Node: Notes1065162
-Node: Compatibility Mode1065821
-Node: Additions1066604
-Node: Accessing The Source1067531
-Node: Adding Code1069134
-Node: New Ports1075176
-Node: Derived Files1079311
-Ref: Derived Files-Footnote-11084619
-Ref: Derived Files-Footnote-21084653
-Ref: Derived Files-Footnote-31085253
-Node: Future Extensions1085351
-Node: Implementation Limitations1085932
-Node: Basic Concepts1087159
-Node: Basic High Level1087840
-Ref: figure-general-flow1088111
-Ref: figure-process-flow1088710
-Ref: Basic High Level-Footnote-11091939
-Node: Basic Data Typing1092124
-Node: Glossary1095479
-Node: Copying1120790
-Node: GNU Free Documentation License1158347
-Node: Index1183484
-=======
-Node: Foreword30282
-Node: Preface34627
-Ref: Preface-Footnote-137680
-Ref: Preface-Footnote-237786
-Node: History38018
-Node: Names40409
-Ref: Names-Footnote-141886
-Node: This Manual41958
-Ref: This Manual-Footnote-146905
-Node: Conventions47005
-Node: Manual History49139
-Ref: Manual History-Footnote-152409
-Ref: Manual History-Footnote-252450
-Node: How To Contribute52524
-Node: Acknowledgments53668
-Node: Getting Started57999
-Node: Running gawk60378
-Node: One-shot61564
-Node: Read Terminal62789
-Ref: Read Terminal-Footnote-164439
-Ref: Read Terminal-Footnote-264715
-Node: Long64886
-Node: Executable Scripts66262
-Ref: Executable Scripts-Footnote-168131
-Ref: Executable Scripts-Footnote-268233
-Node: Comments68780
-Node: Quoting71247
-Node: DOS Quoting75870
-Node: Sample Data Files76545
-Node: Very Simple79577
-Node: Two Rules84176
-Node: More Complex86323
-Ref: More Complex-Footnote-189253
-Node: Statements/Lines89338
-Ref: Statements/Lines-Footnote-193800
-Node: Other Features94065
-Node: When94993
-Node: Invoking Gawk97140
-Node: Command Line98525
-Node: Options99308
-Ref: Options-Footnote-1112852
-Node: Other Arguments112877
-Node: Naming Standard Input115535
-Node: Environment Variables116629
-Node: AWKPATH Variable117073
-Ref: AWKPATH Variable-Footnote-1119670
-Node: Other Environment Variables119930
-Node: Exit Status122270
-Node: Include Files122945
-Node: Obsolete126430
-Node: Undocumented127116
-Node: Regexp127357
-Node: Regexp Usage128746
-Node: Escape Sequences130772
-Node: Regexp Operators136535
-Ref: Regexp Operators-Footnote-1143915
-Ref: Regexp Operators-Footnote-2144062
-Node: Bracket Expressions144160
-Ref: table-char-classes146050
-Node: GNU Regexp Operators148573
-Node: Case-sensitivity152296
-Ref: Case-sensitivity-Footnote-1155264
-Ref: Case-sensitivity-Footnote-2155499
-Node: Leftmost Longest155607
-Node: Computed Regexps156808
-Node: Reading Files160218
-Node: Records162159
-Ref: Records-Footnote-1171083
-Node: Fields171120
-Ref: Fields-Footnote-1174153
-Node: Nonconstant Fields174239
-Node: Changing Fields176441
-Node: Field Separators182422
-Node: Default Field Splitting185051
-Node: Regexp Field Splitting186168
-Node: Single Character Fields189510
-Node: Command Line Field Separator190569
-Node: Field Splitting Summary194010
-Ref: Field Splitting Summary-Footnote-1197202
-Node: Constant Size197303
-Node: Splitting By Content201887
-Ref: Splitting By Content-Footnote-1205613
-Node: Multiple Line205653
-Ref: Multiple Line-Footnote-1211500
-Node: Getline211679
-Node: Plain Getline213907
-Node: Getline/Variable215996
-Node: Getline/File217137
-Node: Getline/Variable/File218459
-Ref: Getline/Variable/File-Footnote-1220058
-Node: Getline/Pipe220145
-Node: Getline/Variable/Pipe222705
-Node: Getline/Coprocess223812
-Node: Getline/Variable/Coprocess225055
-Node: Getline Notes225769
-Node: Getline Summary228556
-Ref: table-getline-variants228899
-Node: Command line directories229755
-Node: Printing230380
-Node: Print232011
-Node: Print Examples233348
-Node: Output Separators236132
-Node: OFMT237892
-Node: Printf239250
-Node: Basic Printf240156
-Node: Control Letters241695
-Node: Format Modifiers245507
-Node: Printf Examples251516
-Node: Redirection254231
-Node: Special Files261215
-Node: Special FD261748
-Ref: Special FD-Footnote-1265373
-Node: Special Network265447
-Node: Special Caveats266297
-Node: Close Files And Pipes267093
-Ref: Close Files And Pipes-Footnote-1274116
-Ref: Close Files And Pipes-Footnote-2274264
-Node: Expressions274414
-Node: Values275546
-Node: Constants276222
-Node: Scalar Constants276902
-Ref: Scalar Constants-Footnote-1277761
-Node: Nondecimal-numbers277943
-Node: Regexp Constants281002
-Node: Using Constant Regexps281477
-Node: Variables284532
-Node: Using Variables285187
-Node: Assignment Options286911
-Node: Conversion288783
-Ref: table-locale-affects294159
-Ref: Conversion-Footnote-1294783
-Node: All Operators294892
-Node: Arithmetic Ops295522
-Node: Concatenation298027
-Ref: Concatenation-Footnote-1300820
-Node: Assignment Ops300940
-Ref: table-assign-ops305928
-Node: Increment Ops307336
-Node: Truth Values and Conditions310806
-Node: Truth Values311889
-Node: Typing and Comparison312938
-Node: Variable Typing313727
-Ref: Variable Typing-Footnote-1317624
-Node: Comparison Operators317746
-Ref: table-relational-ops318156
-Node: POSIX String Comparison321705
-Ref: POSIX String Comparison-Footnote-1322661
-Node: Boolean Ops322799
-Ref: Boolean Ops-Footnote-1326877
-Node: Conditional Exp326968
-Node: Function Calls328700
-Node: Precedence332294
-Node: Locales335963
-Node: Patterns and Actions337052
-Node: Pattern Overview338106
-Node: Regexp Patterns339775
-Node: Expression Patterns340318
-Node: Ranges344003
-Node: BEGIN/END346969
-Node: Using BEGIN/END347731
-Ref: Using BEGIN/END-Footnote-1350462
-Node: I/O And BEGIN/END350568
-Node: BEGINFILE/ENDFILE352850
-Node: Empty355743
-Node: Using Shell Variables356059
-Node: Action Overview358344
-Node: Statements360701
-Node: If Statement362555
-Node: While Statement364054
-Node: Do Statement366098
-Node: For Statement367254
-Node: Switch Statement370406
-Node: Break Statement372503
-Node: Continue Statement374493
-Node: Next Statement376286
-Node: Nextfile Statement378676
-Node: Exit Statement381317
-Node: Built-in Variables383733
-Node: User-modified384828
-Ref: User-modified-Footnote-1392854
-Node: Auto-set392916
-Ref: Auto-set-Footnote-1402207
-Node: ARGC and ARGV402412
-Node: Arrays406263
-Node: Array Basics407768
-Node: Array Intro408594
-Node: Reference to Elements412912
-Node: Assigning Elements415182
-Node: Array Example415673
-Node: Scanning an Array417405
-Node: Controlling Scanning419719
-Ref: Controlling Scanning-Footnote-1424652
-Node: Delete424968
-Ref: Delete-Footnote-1427733
-Node: Numeric Array Subscripts427790
-Node: Uninitialized Subscripts429973
-Node: Multi-dimensional431601
-Node: Multi-scanning434695
-Node: Arrays of Arrays436286
-Node: Functions440931
-Node: Built-in441753
-Node: Calling Built-in442831
-Node: Numeric Functions444819
-Ref: Numeric Functions-Footnote-1448651
-Ref: Numeric Functions-Footnote-2449008
-Ref: Numeric Functions-Footnote-3449056
-Node: String Functions449325
-Ref: String Functions-Footnote-1472822
-Ref: String Functions-Footnote-2472951
-Ref: String Functions-Footnote-3473199
-Node: Gory Details473286
-Ref: table-sub-escapes474965
-Ref: table-sub-posix-92476319
-Ref: table-sub-proposed477662
-Ref: table-posix-sub479012
-Ref: table-gensub-escapes480558
-Ref: Gory Details-Footnote-1481765
-Ref: Gory Details-Footnote-2481816
-Node: I/O Functions481967
-Ref: I/O Functions-Footnote-1489072
-Node: Time Functions489219
-Ref: Time Functions-Footnote-1500111
-Ref: Time Functions-Footnote-2500179
-Ref: Time Functions-Footnote-3500337
-Ref: Time Functions-Footnote-4500448
-Ref: Time Functions-Footnote-5500560
-Ref: Time Functions-Footnote-6500787
-Node: Bitwise Functions501053
-Ref: table-bitwise-ops501611
-Ref: Bitwise Functions-Footnote-1505771
-Node: Type Functions505955
-Node: I18N Functions506425
-Node: User-defined508052
-Node: Definition Syntax508856
-Ref: Definition Syntax-Footnote-1513766
-Node: Function Example513835
-Node: Function Caveats516429
-Node: Calling A Function516850
-Node: Variable Scope517965
-Node: Pass By Value/Reference519940
-Node: Return Statement523380
-Node: Dynamic Typing526361
-Node: Indirect Calls527096
-Node: Internationalization536781
-Node: I18N and L10N538207
-Node: Explaining gettext538893
-Ref: Explaining gettext-Footnote-1543959
-Ref: Explaining gettext-Footnote-2544143
-Node: Programmer i18n544308
-Node: Translator i18n548508
-Node: String Extraction549301
-Ref: String Extraction-Footnote-1550262
-Node: Printf Ordering550348
-Ref: Printf Ordering-Footnote-1553132
-Node: I18N Portability553196
-Ref: I18N Portability-Footnote-1555645
-Node: I18N Example555708
-Ref: I18N Example-Footnote-1558343
-Node: Gawk I18N558415
-Node: Advanced Features559032
-Node: Nondecimal Data560545
-Node: Array Sorting562128
-Node: Controlling Array Traversal562825
-Node: Array Sorting Functions571062
-Ref: Array Sorting Functions-Footnote-1574736
-Ref: Array Sorting Functions-Footnote-2574829
-Node: Two-way I/O575023
-Ref: Two-way I/O-Footnote-1580455
-Node: TCP/IP Networking580525
-Node: Profiling583369
-Node: Library Functions590843
-Ref: Library Functions-Footnote-1593850
-Node: Library Names594021
-Ref: Library Names-Footnote-1597492
-Ref: Library Names-Footnote-2597712
-Node: General Functions597798
-Node: Strtonum Function598751
-Node: Assert Function601681
-Node: Round Function605007
-Node: Cliff Random Function606550
-Node: Ordinal Functions607566
-Ref: Ordinal Functions-Footnote-1610636
-Ref: Ordinal Functions-Footnote-2610888
-Node: Join Function611097
-Ref: Join Function-Footnote-1612868
-Node: Gettimeofday Function613068
-Node: Data File Management616783
-Node: Filetrans Function617415
-Node: Rewind Function621554
-Node: File Checking622941
-Node: Empty Files624035
-Node: Ignoring Assigns626265
-Node: Getopt Function627818
-Ref: Getopt Function-Footnote-1639122
-Node: Passwd Functions639325
-Ref: Passwd Functions-Footnote-1648300
-Node: Group Functions648388
-Node: Walking Arrays656472
-Node: Sample Programs658041
-Node: Running Examples658706
-Node: Clones659434
-Node: Cut Program660658
-Node: Egrep Program670503
-Ref: Egrep Program-Footnote-1678276
-Node: Id Program678386
-Node: Split Program682002
-Ref: Split Program-Footnote-1685521
-Node: Tee Program685649
-Node: Uniq Program688452
-Node: Wc Program695881
-Ref: Wc Program-Footnote-1700147
-Ref: Wc Program-Footnote-2700347
-Node: Miscellaneous Programs700439
-Node: Dupword Program701627
-Node: Alarm Program703658
-Node: Translate Program708407
-Ref: Translate Program-Footnote-1712794
-Ref: Translate Program-Footnote-2713022
-Node: Labels Program713156
-Ref: Labels Program-Footnote-1716527
-Node: Word Sorting716611
-Node: History Sorting720495
-Node: Extract Program722334
-Ref: Extract Program-Footnote-1729817
-Node: Simple Sed729945
-Node: Igawk Program733007
-Ref: Igawk Program-Footnote-1748164
-Ref: Igawk Program-Footnote-2748365
-Node: Anagram Program748503
-Node: Signature Program751571
-Node: Debugger752671
-Node: Debugging753582
-Node: Debugging Concepts753995
-Node: Debugging Terms755851
-Node: Awk Debugging758474
-Node: Sample dgawk session759366
-Node: dgawk invocation759858
-Node: Finding The Bug761040
-Node: List of Debugger Commands767526
-Node: Breakpoint Control768837
-Node: Dgawk Execution Control772473
-Node: Viewing And Changing Data775824
-Node: Dgawk Stack779161
-Node: Dgawk Info780621
-Node: Miscellaneous Dgawk Commands784569
-Node: Readline Support789997
-Node: Dgawk Limitations790835
-Node: Language History793024
-Node: V7/SVR3.1794536
-Node: SVR4796857
-Node: POSIX798299
-Node: BTL799307
-Node: POSIX/GNU800112
-Node: Common Extensions805263
-Node: Ranges and Locales806322
-Ref: Ranges and Locales-Footnote-1810940
-Ref: Ranges and Locales-Footnote-2810967
-Ref: Ranges and Locales-Footnote-3811227
-Node: Contributors811448
-Node: Installation815710
-Node: Gawk Distribution816604
-Node: Getting817088
-Node: Extracting817914
-Node: Distribution contents819606
-Node: Unix Installation824867
-Node: Quick Installation825484
-Node: Additional Configuration Options827446
-Node: Configuration Philosophy828923
-Node: Non-Unix Installation831265
-Node: PC Installation831723
-Node: PC Binary Installation833022
-Node: PC Compiling835037
-Node: PC Testing837981
-Node: PC Using839157
-Node: Cygwin843342
-Node: MSYS844342
-Node: VMS Installation844856
-Node: VMS Compilation845459
-Ref: VMS Compilation-Footnote-1846466
-Node: VMS Installation Details846524
-Node: VMS Running848159
-Node: VMS Old Gawk849766
-Node: Bugs850240
-Node: Other Versions854092
-Node: Notes859373
-Node: Compatibility Mode860065
-Node: Additions860848
-Node: Accessing The Source861660
-Node: Adding Code863085
-Node: New Ports869052
-Node: Dynamic Extensions873165
-Node: Internals874541
-Node: Plugin License883644
-Node: Sample Library884278
-Node: Internal File Description884964
-Node: Internal File Ops888679
-Ref: Internal File Ops-Footnote-1893460
-Node: Using Internal File Ops893600
-Node: Future Extensions895977
-Node: Basic Concepts898481
-Node: Basic High Level899238
-Ref: Basic High Level-Footnote-1903273
-Node: Basic Data Typing903458
-Node: Floating Point Issues907983
-Node: String Conversion Precision909066
-Ref: String Conversion Precision-Footnote-1910766
-Node: Unexpected Results910875
-Node: POSIX Floating Point Problems912701
-Ref: POSIX Floating Point Problems-Footnote-1916406
-Node: Glossary916444
-Node: Copying941619
-Node: GNU Free Documentation License979176
-Node: Index1004313
->>>>>>> gawk-4.0-stable
+Node: General Data Types885595
+Ref: General Data Types-Footnote-1891197
+Node: Requesting Values891496
+Ref: table-value-types-returned892227
+Node: Constructor Functions893181
+Node: Registration Functions896177
+Node: Extension Functions896862
+Node: Exit Callback Functions899036
+Node: Extension Version String900279
+Node: Input Parsers900929
+Node: Output Wrappers909516
+Node: Two-way processors913932
+Node: Printing Messages916062
+Ref: Printing Messages-Footnote-1917139
+Node: Updating `ERRNO'917291
+Node: Accessing Parameters918030
+Node: Symbol Table Access919260
+Node: Symbol table by name919772
+Ref: Symbol table by name-Footnote-1921942
+Node: Symbol table by cookie922022
+Ref: Symbol table by cookie-Footnote-1926151
+Node: Cached values926214
+Ref: Cached values-Footnote-1929657
+Node: Array Manipulation929748
+Ref: Array Manipulation-Footnote-1930846
+Node: Array Data Types930885
+Ref: Array Data Types-Footnote-1933588
+Node: Array Functions933680
+Node: Flattening Arrays937446
+Node: Creating Arrays944279
+Node: Extension API Variables949074
+Node: Extension Versioning949710
+Node: Extension API Informational Variables951611
+Node: Extension API Boilerplate952697
+Node: Finding Extensions956528
+Node: Extension Example957075
+Node: Internal File Description957813
+Node: Internal File Ops961501
+Ref: Internal File Ops-Footnote-1972948
+Node: Using Internal File Ops973088
+Ref: Using Internal File Ops-Footnote-1975441
+Node: Extension Samples975707
+Node: Extension Sample File Functions977150
+Node: Extension Sample Fnmatch985623
+Node: Extension Sample Fork987349
+Node: Extension Sample Ord988563
+Node: Extension Sample Readdir989339
+Node: Extension Sample Revout990843
+Node: Extension Sample Rev2way991436
+Node: Extension Sample Read write array992126
+Node: Extension Sample Readfile994009
+Node: Extension Sample API Tests994764
+Node: Extension Sample Time995289
+Node: gawkextlib996596
+Node: Language History998977
+Node: V7/SVR3.11000499
+Node: SVR41002820
+Node: POSIX1004262
+Node: BTL1005270
+Node: POSIX/GNU1006075
+Node: Common Extensions1011610
+Node: Ranges and Locales1012669
+Ref: Ranges and Locales-Footnote-11017287
+Ref: Ranges and Locales-Footnote-21017314
+Ref: Ranges and Locales-Footnote-31017574
+Node: Contributors1017795
+Node: Installation1022091
+Node: Gawk Distribution1022985
+Node: Getting1023469
+Node: Extracting1024295
+Node: Distribution contents1025987
+Node: Unix Installation1031248
+Node: Quick Installation1031865
+Node: Additional Configuration Options1033827
+Node: Configuration Philosophy1035304
+Node: Non-Unix Installation1037646
+Node: PC Installation1038104
+Node: PC Binary Installation1039403
+Node: PC Compiling1041251
+Node: PC Testing1044195
+Node: PC Using1045371
+Node: Cygwin1049556
+Node: MSYS1050556
+Node: VMS Installation1051070
+Node: VMS Compilation1051673
+Ref: VMS Compilation-Footnote-11052680
+Node: VMS Installation Details1052738
+Node: VMS Running1054373
+Node: VMS Old Gawk1055980
+Node: Bugs1056454
+Node: Other Versions1060306
+Node: Notes1065621
+Node: Compatibility Mode1066280
+Node: Additions1067063
+Node: Accessing The Source1067990
+Node: Adding Code1069593
+Node: New Ports1075635
+Node: Derived Files1079770
+Ref: Derived Files-Footnote-11085078
+Ref: Derived Files-Footnote-21085112
+Ref: Derived Files-Footnote-31085712
+Node: Future Extensions1085810
+Node: Implementation Limitations1086391
+Node: Basic Concepts1087618
+Node: Basic High Level1088299
+Ref: figure-general-flow1088570
+Ref: figure-process-flow1089169
+Ref: Basic High Level-Footnote-11092398
+Node: Basic Data Typing1092583
+Node: Glossary1095938
+Node: Copying1121249
+Node: GNU Free Documentation License1158806
+Node: Index1183943

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index ab26df28..77f8b527 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -28721,7 +28721,7 @@ The following types and/or macros and/or functions are referenced
in @file{gawkapi.h}. For correct use, you must therefore include the
corresponding standard header file @emph{before} including @file{gawkapi.h}:
-@multitable {C Entity} {@code{<sys/types.h>}}
+@multitable {@code{memset()}, @code{memcpy()}} {@code{<sys/types.h>}}
@headitem C Entity @tab Header File
@item @code{FILE} @tab @code{<stdio.h>}
@item @code{NULL} @tab @code{<stddef.h>}
@@ -29109,6 +29109,11 @@ The name of the new function.
@command{awk} level code calls the function by this name.
This is a regular C string.
+Function names must obey the rules for @command{awk}
+identifiers. That is, they must begin with either a letter
+or an underscore, which may be followed by any number of
+letters, digits, and underscores.
+
@item awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
This is a pointer to the C function that provides the desired
functionality.
@@ -29116,6 +29121,9 @@ The function must fill in the result with either a number
or a string. @command{awk} takes ownership of any string memory.
As mentioned earlier, string memory @strong{must} come from @code{malloc()}.
+The @code{num_actual_args} argument tells the C function how many
+actual parameters were passed from the calling @command{awk} code.
+
The function must return the value of @code{result}.
This is for the convenience of the calling code inside @command{gawk}.
diff --git a/ext.c b/ext.c
index 5fc16afe..24a0b27d 100644
--- a/ext.c
+++ b/ext.c
@@ -33,6 +33,42 @@
#include <dlfcn.h>
+/*
+ * is_letter --- function to check letters
+ * isalpha() isn't good enough since it can look at the locale.
+ * Underscore counts as a letter in awk identifiers
+ */
+
+static bool
+is_letter(unsigned char c)
+{
+ switch (c) {
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+ case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z':
+ case '_':
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* is_identifier_char --- return true if a character can be used in an identifier */
+
+static bool
+is_identifier_char(unsigned char c)
+{
+ return (is_letter(c) || isdigit(c));
+}
+
+
#define INIT_FUNC "dl_load"
/* load_ext --- load an external library */
@@ -92,10 +128,14 @@ make_builtin(const awk_ext_func_t *funcinfo)
if (sp == NULL || *sp == '\0')
fatal(_("make_builtin: missing function name"));
+ if (! is_letter(*sp))
+ return false;
+
+ sp++;
+
while ((c = *sp++) != '\0') {
- if ((sp == &name[1] && c != '_' && ! isalpha((unsigned char) c))
- || (sp > &name[1] && ! is_identchar((unsigned char) c)))
- fatal(_("make_builtin: illegal character `%c' in function name `%s'"), c, name);
+ if (! is_identifier_char(c))
+ return false;
}
f = lookup(name);