diff options
-rwxr-xr-x[-rw-r--r--] | ChangeLog | 43 | ||||
-rw-r--r-- | array.c | 9 | ||||
-rw-r--r-- | awk.h | 2 | ||||
-rw-r--r-- | awkgram.c | 471 | ||||
-rw-r--r-- | awkgram.y | 15 | ||||
-rw-r--r-- | custom.h | 8 | ||||
-rw-r--r-- | doc/ChangeLog | 15 | ||||
-rw-r--r-- | doc/gawk.1 | 2 | ||||
-rw-r--r-- | doc/gawk.info | 916 | ||||
-rw-r--r-- | doc/gawk.texi | 69 | ||||
-rw-r--r-- | doc/gawktexi.in | 69 | ||||
-rw-r--r-- | doc/gawkworkflow.texi | 8 | ||||
-rw-r--r-- | interpret.h | 1 | ||||
-rw-r--r-- | main.c | 9 | ||||
-rw-r--r-- | node.c | 4 | ||||
-rw-r--r-- | re.c | 22 | ||||
-rw-r--r-- | test/ChangeLog | 15 | ||||
-rw-r--r-- | test/Makefile.am | 9 | ||||
-rw-r--r-- | test/Makefile.in | 19 | ||||
-rw-r--r-- | test/Maketests | 10 | ||||
-rw-r--r-- | test/arraysort2.awk | 34 | ||||
-rw-r--r-- | test/arraysort2.ok | 26 | ||||
-rw-r--r-- | test/assignnumfield.awk | 1 | ||||
-rw-r--r-- | test/assignnumfield.in | 5 | ||||
-rw-r--r-- | test/assignnumfield.ok | 5 | ||||
-rw-r--r-- | test/back89.ok | 1 | ||||
-rw-r--r-- | test/funstack.ok | 10 | ||||
-rw-r--r-- | test/gsubtst5.ok | 4 | ||||
-rw-r--r-- | test/lintwarn.awk | 5 | ||||
-rw-r--r-- | test/lintwarn.ok | 1 |
30 files changed, 1120 insertions, 688 deletions
diff --git a/ChangeLog b/ChangeLog index 25d4b1a3..20470eb9 100644..100755 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,46 @@ +2018-08-02 Arnold D. Robbins <arnold@skeeve.com> + + * awkgram.y (yylex): Add lint warning upon encountering escaped + physical newlines in a string. + * node.c (make_str_node): Ditto. + +2018-08-01 John E. Malmberg <wb8tyw@qsl.net> + + * custom.h: Include fp.h on OpenVMS. + Workaround for bug in math.h missing some declarations. + +2018-07-31 Arnold D. Robbins <arnold@skeeve.com> + + * interpret.h (unfield): Add a call to force_string() on + new value. See test/assignnumfield.awk. Thanks to + Ralph Corderoy <ralph@inputplus.co.uk> for the bug report. + +2018-07-31 Arnold D. Robbins <arnold@skeeve.com> + + Handle newlines in -v and fix \-<newline>. Thanks to + Samy Mahmoudi <samy.mahmoudi@gmail.com> for the report. + + * awk.h [ELIDE_BACK_NL]: New constant. + * awkgram.y (yylex): Disallow any physical newlines in a string + even if escaped, in POSIX mode. + * main.c (arg_assign): In POSIX mode disallow physical newline + in a -v value. Otherwise call make_str_node() with ELIDE_BACK_NL. + * node.c (make_str_node): Handle ELIDE_BACK_NL. + +2018-07-31 Arnold D. Robbins <arnold@skeeve.com> + + * array.c (cmp_strings): Preserve value of lmin so it can be passed + to memcmp() if IGNORECASE comparison failed. Thanks to + M. Rashid Zamani <rashid.z@gmail.com> for the report. + +2018-07-27 Arnold D. Robbins <arnold@skeeve.com> + + * re.c (make_regexp): Add warnings for unknown escape sequences, + similar to what we already do for strings. + * awkgram.y: Add lint warning about concatenation as target + of `>' redirection. Always use Op_parens so that + print "foo" > ("foo" 1) does not warn. + 2018-07-13 Arnold D. Robbins <arnold@skeeve.com> * builtin.c (format_nan_inf): New function to generate +nan, -nan, @@ -979,7 +979,6 @@ cmp_strings(const NODE *n1, const NODE *n2) char *s1, *s2; size_t len1, len2; int ret; - size_t lmin; s1 = n1->stptr; len1 = n1->stlen; @@ -992,7 +991,9 @@ cmp_strings(const NODE *n1, const NODE *n2) return 1; /* len1 > 0 && len2 > 0 */ - lmin = len1 < len2 ? len1 : len2; + // make const to ensure it doesn't change if we + // need to call memcmp(), below + const size_t lmin = len1 < len2 ? len1 : len2; if (IGNORECASE) { const unsigned char *cp1 = (const unsigned char *) s1; @@ -1002,7 +1003,9 @@ cmp_strings(const NODE *n1, const NODE *n2) ret = strncasecmpmbs((const unsigned char *) cp1, (const unsigned char *) cp2, lmin); } else { - for (ret = 0; lmin-- > 0 && ret == 0; cp1++, cp2++) + size_t count = lmin; + + for (ret = 0; count-- > 0 && ret == 0; cp1++, cp2++) ret = casetable[*cp1] - casetable[*cp2]; } if (ret != 0) @@ -1318,8 +1318,10 @@ DEREF(NODE *r) #define make_string(s, l) make_str_node((s), (l), 0) +// Flags for making string nodes #define SCAN 1 #define ALREADY_MALLOCED 2 +#define ELIDE_BACK_NL 4 #define cant_happen() r_fatal("internal error line %d, file: %s", \ __LINE__, __FILE__) @@ -678,19 +678,19 @@ static const yytype_uint16 yyrline[] = 766, 808, 921, 928, 935, 946, 956, 966, 976, 988, 1005, 1004, 1018, 1030, 1030, 1129, 1129, 1163, 1194, 1203, 1204, 1210, 1211, 1218, 1223, 1235, 1249, 1251, 1259, 1266, - 1268, 1276, 1285, 1287, 1296, 1297, 1305, 1310, 1310, 1321, - 1325, 1333, 1334, 1337, 1339, 1344, 1345, 1354, 1355, 1360, - 1365, 1374, 1376, 1378, 1385, 1386, 1392, 1393, 1398, 1400, - 1405, 1407, 1415, 1420, 1429, 1430, 1435, 1437, 1442, 1444, - 1452, 1457, 1465, 1466, 1471, 1478, 1482, 1484, 1486, 1499, - 1516, 1526, 1533, 1535, 1540, 1542, 1544, 1552, 1554, 1559, - 1561, 1566, 1568, 1570, 1627, 1629, 1631, 1633, 1635, 1637, - 1639, 1641, 1655, 1660, 1665, 1690, 1696, 1698, 1700, 1702, - 1704, 1706, 1711, 1715, 1747, 1754, 1760, 1766, 1779, 1780, - 1781, 1786, 1791, 1795, 1799, 1814, 1835, 1840, 1877, 1906, - 1907, 1913, 1914, 1919, 1921, 1928, 1945, 1962, 1964, 1971, - 1976, 1984, 1994, 2006, 2015, 2019, 2023, 2027, 2031, 2035, - 2038, 2040, 2044, 2048, 2052 + 1268, 1276, 1285, 1287, 1296, 1297, 1305, 1310, 1310, 1323, + 1327, 1335, 1336, 1339, 1341, 1346, 1347, 1356, 1357, 1362, + 1367, 1376, 1378, 1380, 1387, 1388, 1394, 1395, 1400, 1402, + 1407, 1409, 1417, 1422, 1431, 1432, 1437, 1439, 1444, 1446, + 1454, 1459, 1467, 1468, 1473, 1480, 1484, 1486, 1488, 1501, + 1518, 1528, 1535, 1537, 1542, 1544, 1546, 1554, 1556, 1561, + 1563, 1568, 1570, 1572, 1629, 1631, 1633, 1635, 1637, 1639, + 1641, 1643, 1657, 1662, 1667, 1692, 1698, 1700, 1702, 1704, + 1706, 1708, 1713, 1717, 1749, 1757, 1763, 1769, 1782, 1783, + 1784, 1789, 1794, 1798, 1802, 1817, 1838, 1843, 1880, 1909, + 1910, 1916, 1917, 1922, 1924, 1931, 1948, 1965, 1967, 1974, + 1979, 1987, 1997, 2009, 2018, 2022, 2026, 2030, 2034, 2038, + 2041, 2043, 2047, 2051, 2055 }; #endif @@ -3211,65 +3211,67 @@ regular_print: && (yyvsp[0])->lasti->opcode == Op_K_getline_redir && (yyvsp[0])->lasti->redir_type == redirect_twoway) yyerror(_("multistage two-way pipelines don't work")); + if (do_lint && (yyvsp[-2])->redir_type == redirect_output && (yyvsp[0])->lasti->opcode == Op_concat) + lintwarn(_("concatenation as I/O `>' redirection target is ambiguous")); (yyval) = list_prepend((yyvsp[0]), (yyvsp[-2])); } -#line 3217 "awkgram.c" /* yacc.c:1646 */ +#line 3219 "awkgram.c" /* yacc.c:1646 */ break; case 89: -#line 1322 "awkgram.y" /* yacc.c:1646 */ +#line 1324 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_condition((yyvsp[-3]), (yyvsp[-5]), (yyvsp[0]), NULL, NULL); } -#line 3225 "awkgram.c" /* yacc.c:1646 */ +#line 3227 "awkgram.c" /* yacc.c:1646 */ break; case 90: -#line 1327 "awkgram.y" /* yacc.c:1646 */ +#line 1329 "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 3235 "awkgram.c" /* yacc.c:1646 */ break; case 95: -#line 1344 "awkgram.y" /* yacc.c:1646 */ +#line 1346 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3239 "awkgram.c" /* yacc.c:1646 */ +#line 3241 "awkgram.c" /* yacc.c:1646 */ break; case 96: -#line 1346 "awkgram.y" /* yacc.c:1646 */ +#line 1348 "awkgram.y" /* yacc.c:1646 */ { bcfree((yyvsp[-1])); (yyval) = (yyvsp[0]); } -#line 3248 "awkgram.c" /* yacc.c:1646 */ +#line 3250 "awkgram.c" /* yacc.c:1646 */ break; case 97: -#line 1354 "awkgram.y" /* yacc.c:1646 */ +#line 1356 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3254 "awkgram.c" /* yacc.c:1646 */ +#line 3256 "awkgram.c" /* yacc.c:1646 */ break; case 98: -#line 1356 "awkgram.y" /* yacc.c:1646 */ +#line 1358 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3260 "awkgram.c" /* yacc.c:1646 */ +#line 3262 "awkgram.c" /* yacc.c:1646 */ break; case 99: -#line 1361 "awkgram.y" /* yacc.c:1646 */ +#line 1363 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->param_count = 0; (yyval) = list_create((yyvsp[0])); } -#line 3269 "awkgram.c" /* yacc.c:1646 */ +#line 3271 "awkgram.c" /* yacc.c:1646 */ break; case 100: -#line 1366 "awkgram.y" /* yacc.c:1646 */ +#line 1368 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[-2]) != NULL && (yyvsp[0]) != NULL) { (yyvsp[0])->param_count = (yyvsp[-2])->lasti->param_count + 1; @@ -3278,74 +3280,74 @@ regular_print: } else (yyval) = NULL; } -#line 3282 "awkgram.c" /* yacc.c:1646 */ +#line 3284 "awkgram.c" /* yacc.c:1646 */ break; case 101: -#line 1375 "awkgram.y" /* yacc.c:1646 */ +#line 1377 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3288 "awkgram.c" /* yacc.c:1646 */ +#line 3290 "awkgram.c" /* yacc.c:1646 */ break; case 102: -#line 1377 "awkgram.y" /* yacc.c:1646 */ +#line 1379 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 3294 "awkgram.c" /* yacc.c:1646 */ +#line 3296 "awkgram.c" /* yacc.c:1646 */ break; case 103: -#line 1379 "awkgram.y" /* yacc.c:1646 */ +#line 1381 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-2]); } -#line 3300 "awkgram.c" /* yacc.c:1646 */ +#line 3302 "awkgram.c" /* yacc.c:1646 */ break; case 104: -#line 1385 "awkgram.y" /* yacc.c:1646 */ +#line 1387 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3306 "awkgram.c" /* yacc.c:1646 */ +#line 3308 "awkgram.c" /* yacc.c:1646 */ break; case 105: -#line 1387 "awkgram.y" /* yacc.c:1646 */ +#line 1389 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3312 "awkgram.c" /* yacc.c:1646 */ +#line 3314 "awkgram.c" /* yacc.c:1646 */ break; case 106: -#line 1392 "awkgram.y" /* yacc.c:1646 */ +#line 1394 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3318 "awkgram.c" /* yacc.c:1646 */ +#line 3320 "awkgram.c" /* yacc.c:1646 */ break; case 107: -#line 1394 "awkgram.y" /* yacc.c:1646 */ +#line 1396 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3324 "awkgram.c" /* yacc.c:1646 */ +#line 3326 "awkgram.c" /* yacc.c:1646 */ break; case 108: -#line 1399 "awkgram.y" /* yacc.c:1646 */ +#line 1401 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_expression_list(NULL, (yyvsp[0])); } -#line 3330 "awkgram.c" /* yacc.c:1646 */ +#line 3332 "awkgram.c" /* yacc.c:1646 */ break; case 109: -#line 1401 "awkgram.y" /* yacc.c:1646 */ +#line 1403 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0])); yyerrok; } -#line 3339 "awkgram.c" /* yacc.c:1646 */ +#line 3341 "awkgram.c" /* yacc.c:1646 */ break; case 110: -#line 1406 "awkgram.y" /* yacc.c:1646 */ +#line 1408 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3345 "awkgram.c" /* yacc.c:1646 */ +#line 3347 "awkgram.c" /* yacc.c:1646 */ break; case 111: -#line 1408 "awkgram.y" /* yacc.c:1646 */ +#line 1410 "awkgram.y" /* yacc.c:1646 */ { /* * Returning the expression list instead of NULL lets @@ -3353,62 +3355,62 @@ regular_print: */ (yyval) = (yyvsp[-1]); } -#line 3357 "awkgram.c" /* yacc.c:1646 */ +#line 3359 "awkgram.c" /* yacc.c:1646 */ break; case 112: -#line 1416 "awkgram.y" /* yacc.c:1646 */ +#line 1418 "awkgram.y" /* yacc.c:1646 */ { /* Ditto */ (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0])); } -#line 3366 "awkgram.c" /* yacc.c:1646 */ +#line 3368 "awkgram.c" /* yacc.c:1646 */ break; case 113: -#line 1421 "awkgram.y" /* yacc.c:1646 */ +#line 1423 "awkgram.y" /* yacc.c:1646 */ { /* Ditto */ (yyval) = (yyvsp[-2]); } -#line 3375 "awkgram.c" /* yacc.c:1646 */ +#line 3377 "awkgram.c" /* yacc.c:1646 */ break; case 114: -#line 1429 "awkgram.y" /* yacc.c:1646 */ +#line 1431 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3381 "awkgram.c" /* yacc.c:1646 */ +#line 3383 "awkgram.c" /* yacc.c:1646 */ break; case 115: -#line 1431 "awkgram.y" /* yacc.c:1646 */ +#line 1433 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3387 "awkgram.c" /* yacc.c:1646 */ +#line 3389 "awkgram.c" /* yacc.c:1646 */ break; case 116: -#line 1436 "awkgram.y" /* yacc.c:1646 */ +#line 1438 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_expression_list(NULL, (yyvsp[0])); } -#line 3393 "awkgram.c" /* yacc.c:1646 */ +#line 3395 "awkgram.c" /* yacc.c:1646 */ break; case 117: -#line 1438 "awkgram.y" /* yacc.c:1646 */ +#line 1440 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0])); yyerrok; } -#line 3402 "awkgram.c" /* yacc.c:1646 */ +#line 3404 "awkgram.c" /* yacc.c:1646 */ break; case 118: -#line 1443 "awkgram.y" /* yacc.c:1646 */ +#line 1445 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 3408 "awkgram.c" /* yacc.c:1646 */ +#line 3410 "awkgram.c" /* yacc.c:1646 */ break; case 119: -#line 1445 "awkgram.y" /* yacc.c:1646 */ +#line 1447 "awkgram.y" /* yacc.c:1646 */ { /* * Returning the expression list instead of NULL lets @@ -3416,72 +3418,72 @@ regular_print: */ (yyval) = (yyvsp[-1]); } -#line 3420 "awkgram.c" /* yacc.c:1646 */ +#line 3422 "awkgram.c" /* yacc.c:1646 */ break; case 120: -#line 1453 "awkgram.y" /* yacc.c:1646 */ +#line 1455 "awkgram.y" /* yacc.c:1646 */ { /* Ditto */ (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0])); } -#line 3429 "awkgram.c" /* yacc.c:1646 */ +#line 3431 "awkgram.c" /* yacc.c:1646 */ break; case 121: -#line 1458 "awkgram.y" /* yacc.c:1646 */ +#line 1460 "awkgram.y" /* yacc.c:1646 */ { /* Ditto */ (yyval) = (yyvsp[-2]); } -#line 3438 "awkgram.c" /* yacc.c:1646 */ +#line 3440 "awkgram.c" /* yacc.c:1646 */ break; case 122: -#line 1465 "awkgram.y" /* yacc.c:1646 */ +#line 1467 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3444 "awkgram.c" /* yacc.c:1646 */ +#line 3446 "awkgram.c" /* yacc.c:1646 */ break; case 123: -#line 1466 "awkgram.y" /* yacc.c:1646 */ +#line 1468 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_create((yyvsp[0])); } -#line 3450 "awkgram.c" /* yacc.c:1646 */ +#line 3452 "awkgram.c" /* yacc.c:1646 */ break; case 124: -#line 1472 "awkgram.y" /* yacc.c:1646 */ +#line 1474 "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 3463 "awkgram.c" /* yacc.c:1646 */ break; case 125: -#line 1479 "awkgram.y" /* yacc.c:1646 */ +#line 1481 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_assignment((yyvsp[-2]), list_create((yyvsp[0])), (yyvsp[-1])); } -#line 3469 "awkgram.c" /* yacc.c:1646 */ +#line 3471 "awkgram.c" /* yacc.c:1646 */ break; case 126: -#line 1483 "awkgram.y" /* yacc.c:1646 */ +#line 1485 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3475 "awkgram.c" /* yacc.c:1646 */ +#line 3477 "awkgram.c" /* yacc.c:1646 */ break; case 127: -#line 1485 "awkgram.y" /* yacc.c:1646 */ +#line 1487 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3481 "awkgram.c" /* yacc.c:1646 */ +#line 3483 "awkgram.c" /* yacc.c:1646 */ break; case 128: -#line 1487 "awkgram.y" /* yacc.c:1646 */ +#line 1489 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[-2])->lasti->opcode == Op_match_rec) warning_ln((yyvsp[-1])->source_line, @@ -3494,11 +3496,11 @@ regular_print: bcfree((yyvsp[0])); (yyval) = list_append((yyvsp[-2]), (yyvsp[-1])); } -#line 3498 "awkgram.c" /* yacc.c:1646 */ +#line 3500 "awkgram.c" /* yacc.c:1646 */ break; case 129: -#line 1500 "awkgram.y" /* yacc.c:1646 */ +#line 1502 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[-2])->lasti->opcode == Op_match_rec) warning_ln((yyvsp[-1])->source_line, @@ -3515,11 +3517,11 @@ regular_print: (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), (yyvsp[-1])); } } -#line 3519 "awkgram.c" /* yacc.c:1646 */ +#line 3521 "awkgram.c" /* yacc.c:1646 */ break; case 130: -#line 1517 "awkgram.y" /* yacc.c:1646 */ +#line 1519 "awkgram.y" /* yacc.c:1646 */ { if (do_lint_old) warning_ln((yyvsp[-1])->source_line, @@ -3529,91 +3531,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 3535 "awkgram.c" /* yacc.c:1646 */ break; case 131: -#line 1527 "awkgram.y" /* yacc.c:1646 */ +#line 1529 "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 3546 "awkgram.c" /* yacc.c:1646 */ break; case 132: -#line 1534 "awkgram.y" /* yacc.c:1646 */ +#line 1536 "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 3552 "awkgram.c" /* yacc.c:1646 */ break; case 133: -#line 1536 "awkgram.y" /* yacc.c:1646 */ +#line 1538 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3556 "awkgram.c" /* yacc.c:1646 */ +#line 3558 "awkgram.c" /* yacc.c:1646 */ break; case 134: -#line 1541 "awkgram.y" /* yacc.c:1646 */ +#line 1543 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3562 "awkgram.c" /* yacc.c:1646 */ +#line 3564 "awkgram.c" /* yacc.c:1646 */ break; case 135: -#line 1543 "awkgram.y" /* yacc.c:1646 */ +#line 1545 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3568 "awkgram.c" /* yacc.c:1646 */ +#line 3570 "awkgram.c" /* yacc.c:1646 */ break; case 136: -#line 1545 "awkgram.y" /* yacc.c:1646 */ +#line 1547 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_assign_quotient; (yyval) = (yyvsp[0]); } -#line 3577 "awkgram.c" /* yacc.c:1646 */ +#line 3579 "awkgram.c" /* yacc.c:1646 */ break; case 137: -#line 1553 "awkgram.y" /* yacc.c:1646 */ +#line 1555 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3583 "awkgram.c" /* yacc.c:1646 */ +#line 3585 "awkgram.c" /* yacc.c:1646 */ break; case 138: -#line 1555 "awkgram.y" /* yacc.c:1646 */ +#line 1557 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3589 "awkgram.c" /* yacc.c:1646 */ +#line 3591 "awkgram.c" /* yacc.c:1646 */ break; case 139: -#line 1560 "awkgram.y" /* yacc.c:1646 */ +#line 1562 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3595 "awkgram.c" /* yacc.c:1646 */ +#line 3597 "awkgram.c" /* yacc.c:1646 */ break; case 140: -#line 1562 "awkgram.y" /* yacc.c:1646 */ +#line 1564 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3601 "awkgram.c" /* yacc.c:1646 */ +#line 3603 "awkgram.c" /* yacc.c:1646 */ break; case 141: -#line 1567 "awkgram.y" /* yacc.c:1646 */ +#line 1569 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3607 "awkgram.c" /* yacc.c:1646 */ +#line 3609 "awkgram.c" /* yacc.c:1646 */ break; case 142: -#line 1569 "awkgram.y" /* yacc.c:1646 */ +#line 1571 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 3613 "awkgram.c" /* yacc.c:1646 */ +#line 3615 "awkgram.c" /* yacc.c:1646 */ break; case 143: -#line 1571 "awkgram.y" /* yacc.c:1646 */ +#line 1573 "awkgram.y" /* yacc.c:1646 */ { int count = 2; bool is_simple_var = false; @@ -3667,47 +3669,47 @@ regular_print: max_args = count; } } -#line 3671 "awkgram.c" /* yacc.c:1646 */ +#line 3673 "awkgram.c" /* yacc.c:1646 */ break; case 145: -#line 1630 "awkgram.y" /* yacc.c:1646 */ +#line 1632 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3677 "awkgram.c" /* yacc.c:1646 */ +#line 3679 "awkgram.c" /* yacc.c:1646 */ break; case 146: -#line 1632 "awkgram.y" /* yacc.c:1646 */ +#line 1634 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3683 "awkgram.c" /* yacc.c:1646 */ +#line 3685 "awkgram.c" /* yacc.c:1646 */ break; case 147: -#line 1634 "awkgram.y" /* yacc.c:1646 */ +#line 1636 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3689 "awkgram.c" /* yacc.c:1646 */ +#line 3691 "awkgram.c" /* yacc.c:1646 */ break; case 148: -#line 1636 "awkgram.y" /* yacc.c:1646 */ +#line 1638 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3695 "awkgram.c" /* yacc.c:1646 */ +#line 3697 "awkgram.c" /* yacc.c:1646 */ break; case 149: -#line 1638 "awkgram.y" /* yacc.c:1646 */ +#line 1640 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3701 "awkgram.c" /* yacc.c:1646 */ +#line 3703 "awkgram.c" /* yacc.c:1646 */ break; case 150: -#line 1640 "awkgram.y" /* yacc.c:1646 */ +#line 1642 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3707 "awkgram.c" /* yacc.c:1646 */ +#line 3709 "awkgram.c" /* yacc.c:1646 */ break; case 151: -#line 1642 "awkgram.y" /* yacc.c:1646 */ +#line 1644 "awkgram.y" /* yacc.c:1646 */ { /* * In BEGINFILE/ENDFILE, allow `getline [var] < file' @@ -3721,29 +3723,29 @@ regular_print: _("non-redirected `getline' undefined inside END action")); (yyval) = mk_getline((yyvsp[-2]), (yyvsp[-1]), (yyvsp[0]), redirect_input); } -#line 3725 "awkgram.c" /* yacc.c:1646 */ +#line 3727 "awkgram.c" /* yacc.c:1646 */ break; case 152: -#line 1656 "awkgram.y" /* yacc.c:1646 */ +#line 1658 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_postincrement; (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0])); } -#line 3734 "awkgram.c" /* yacc.c:1646 */ +#line 3736 "awkgram.c" /* yacc.c:1646 */ break; case 153: -#line 1661 "awkgram.y" /* yacc.c:1646 */ +#line 1663 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_postdecrement; (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0])); } -#line 3743 "awkgram.c" /* yacc.c:1646 */ +#line 3745 "awkgram.c" /* yacc.c:1646 */ break; case 154: -#line 1666 "awkgram.y" /* yacc.c:1646 */ +#line 1668 "awkgram.y" /* yacc.c:1646 */ { if (do_lint_old) { warning_ln((yyvsp[-1])->source_line, @@ -3763,64 +3765,64 @@ regular_print: (yyval) = list_append(list_merge(t, (yyvsp[0])), (yyvsp[-1])); } } -#line 3767 "awkgram.c" /* yacc.c:1646 */ +#line 3769 "awkgram.c" /* yacc.c:1646 */ break; case 155: -#line 1691 "awkgram.y" /* yacc.c:1646 */ +#line 1693 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_getline((yyvsp[-1]), (yyvsp[0]), (yyvsp[-3]), (yyvsp[-2])->redir_type); bcfree((yyvsp[-2])); } -#line 3776 "awkgram.c" /* yacc.c:1646 */ +#line 3778 "awkgram.c" /* yacc.c:1646 */ break; case 156: -#line 1697 "awkgram.y" /* yacc.c:1646 */ +#line 1699 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3782 "awkgram.c" /* yacc.c:1646 */ +#line 3784 "awkgram.c" /* yacc.c:1646 */ break; case 157: -#line 1699 "awkgram.y" /* yacc.c:1646 */ +#line 1701 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3788 "awkgram.c" /* yacc.c:1646 */ +#line 3790 "awkgram.c" /* yacc.c:1646 */ break; case 158: -#line 1701 "awkgram.y" /* yacc.c:1646 */ +#line 1703 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3794 "awkgram.c" /* yacc.c:1646 */ +#line 3796 "awkgram.c" /* yacc.c:1646 */ break; case 159: -#line 1703 "awkgram.y" /* yacc.c:1646 */ +#line 1705 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3800 "awkgram.c" /* yacc.c:1646 */ +#line 3802 "awkgram.c" /* yacc.c:1646 */ break; case 160: -#line 1705 "awkgram.y" /* yacc.c:1646 */ +#line 1707 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3806 "awkgram.c" /* yacc.c:1646 */ +#line 3808 "awkgram.c" /* yacc.c:1646 */ break; case 161: -#line 1707 "awkgram.y" /* yacc.c:1646 */ +#line 1709 "awkgram.y" /* yacc.c:1646 */ { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); } -#line 3812 "awkgram.c" /* yacc.c:1646 */ +#line 3814 "awkgram.c" /* yacc.c:1646 */ break; case 162: -#line 1712 "awkgram.y" /* yacc.c:1646 */ +#line 1714 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_create((yyvsp[0])); } -#line 3820 "awkgram.c" /* yacc.c:1646 */ +#line 3822 "awkgram.c" /* yacc.c:1646 */ break; case 163: -#line 1716 "awkgram.y" /* yacc.c:1646 */ +#line 1718 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[0])->opcode == Op_match_rec) { (yyvsp[0])->opcode = Op_nomatch; @@ -3852,42 +3854,43 @@ regular_print: } } } -#line 3856 "awkgram.c" /* yacc.c:1646 */ +#line 3858 "awkgram.c" /* yacc.c:1646 */ break; case 164: -#line 1748 "awkgram.y" /* yacc.c:1646 */ +#line 1750 "awkgram.y" /* yacc.c:1646 */ { - if (do_pretty_print) - (yyval) = list_append((yyvsp[-1]), bcalloc(Op_parens, 1, sourceline)); - else - (yyval) = (yyvsp[-1]); + // Always include. Allows us to lint warn on + // print "foo" > "bar" 1 + // but not warn on + // print "foo" > ("bar" 1) + (yyval) = list_append((yyvsp[-1]), bcalloc(Op_parens, 1, sourceline)); } -#line 3867 "awkgram.c" /* yacc.c:1646 */ +#line 3870 "awkgram.c" /* yacc.c:1646 */ break; case 165: -#line 1755 "awkgram.y" /* yacc.c:1646 */ +#line 1758 "awkgram.y" /* yacc.c:1646 */ { (yyval) = snode((yyvsp[-1]), (yyvsp[-3])); if ((yyval) == NULL) YYABORT; } -#line 3877 "awkgram.c" /* yacc.c:1646 */ +#line 3880 "awkgram.c" /* yacc.c:1646 */ break; case 166: -#line 1761 "awkgram.y" /* yacc.c:1646 */ +#line 1764 "awkgram.y" /* yacc.c:1646 */ { (yyval) = snode((yyvsp[-1]), (yyvsp[-3])); if ((yyval) == NULL) YYABORT; } -#line 3887 "awkgram.c" /* yacc.c:1646 */ +#line 3890 "awkgram.c" /* yacc.c:1646 */ break; case 167: -#line 1767 "awkgram.y" /* yacc.c:1646 */ +#line 1770 "awkgram.y" /* yacc.c:1646 */ { static bool warned = false; @@ -3900,45 +3903,45 @@ regular_print: if ((yyval) == NULL) YYABORT; } -#line 3904 "awkgram.c" /* yacc.c:1646 */ +#line 3907 "awkgram.c" /* yacc.c:1646 */ break; case 170: -#line 1782 "awkgram.y" /* yacc.c:1646 */ +#line 1785 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[-1])->opcode = Op_preincrement; (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1])); } -#line 3913 "awkgram.c" /* yacc.c:1646 */ +#line 3916 "awkgram.c" /* yacc.c:1646 */ break; case 171: -#line 1787 "awkgram.y" /* yacc.c:1646 */ +#line 1790 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[-1])->opcode = Op_predecrement; (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1])); } -#line 3922 "awkgram.c" /* yacc.c:1646 */ +#line 3925 "awkgram.c" /* yacc.c:1646 */ break; case 172: -#line 1792 "awkgram.y" /* yacc.c:1646 */ +#line 1795 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_create((yyvsp[0])); } -#line 3930 "awkgram.c" /* yacc.c:1646 */ +#line 3933 "awkgram.c" /* yacc.c:1646 */ break; case 173: -#line 1796 "awkgram.y" /* yacc.c:1646 */ +#line 1799 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_create((yyvsp[0])); } -#line 3938 "awkgram.c" /* yacc.c:1646 */ +#line 3941 "awkgram.c" /* yacc.c:1646 */ break; case 174: -#line 1800 "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 @@ -3953,11 +3956,11 @@ regular_print: (yyval) = list_append((yyvsp[0]), (yyvsp[-1])); } } -#line 3957 "awkgram.c" /* yacc.c:1646 */ +#line 3960 "awkgram.c" /* yacc.c:1646 */ break; case 175: -#line 1815 "awkgram.y" /* yacc.c:1646 */ +#line 1818 "awkgram.y" /* yacc.c:1646 */ { if ((yyvsp[0])->lasti->opcode == Op_push_i && ((yyvsp[0])->lasti->memory->flags & STRING) == 0 @@ -3975,20 +3978,20 @@ regular_print: (yyval) = list_append((yyvsp[0]), (yyvsp[-1])); } } -#line 3979 "awkgram.c" /* yacc.c:1646 */ +#line 3982 "awkgram.c" /* yacc.c:1646 */ break; case 176: -#line 1836 "awkgram.y" /* yacc.c:1646 */ +#line 1839 "awkgram.y" /* yacc.c:1646 */ { func_use((yyvsp[0])->lasti->func_name, FUNC_USE); (yyval) = (yyvsp[0]); } -#line 3988 "awkgram.c" /* yacc.c:1646 */ +#line 3991 "awkgram.c" /* yacc.c:1646 */ break; case 177: -#line 1841 "awkgram.y" /* yacc.c:1646 */ +#line 1844 "awkgram.y" /* yacc.c:1646 */ { /* indirect function call */ INSTRUCTION *f, *t; @@ -4022,11 +4025,11 @@ regular_print: (yyval) = list_prepend((yyvsp[0]), t); at_seen = false; } -#line 4026 "awkgram.c" /* yacc.c:1646 */ +#line 4029 "awkgram.c" /* yacc.c:1646 */ break; case 178: -#line 1878 "awkgram.y" /* yacc.c:1646 */ +#line 1881 "awkgram.y" /* yacc.c:1646 */ { NODE *n; @@ -4051,49 +4054,49 @@ regular_print: (yyval) = list_append(t, (yyvsp[-3])); } } -#line 4055 "awkgram.c" /* yacc.c:1646 */ +#line 4058 "awkgram.c" /* yacc.c:1646 */ break; case 179: -#line 1906 "awkgram.y" /* yacc.c:1646 */ +#line 1909 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 4061 "awkgram.c" /* yacc.c:1646 */ +#line 4064 "awkgram.c" /* yacc.c:1646 */ break; case 180: -#line 1908 "awkgram.y" /* yacc.c:1646 */ +#line 1911 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 4067 "awkgram.c" /* yacc.c:1646 */ +#line 4070 "awkgram.c" /* yacc.c:1646 */ break; case 181: -#line 1913 "awkgram.y" /* yacc.c:1646 */ +#line 1916 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 4073 "awkgram.c" /* yacc.c:1646 */ +#line 4076 "awkgram.c" /* yacc.c:1646 */ break; case 182: -#line 1915 "awkgram.y" /* yacc.c:1646 */ +#line 1918 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 4079 "awkgram.c" /* yacc.c:1646 */ +#line 4082 "awkgram.c" /* yacc.c:1646 */ break; case 183: -#line 1920 "awkgram.y" /* yacc.c:1646 */ +#line 1923 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 4085 "awkgram.c" /* yacc.c:1646 */ +#line 4088 "awkgram.c" /* yacc.c:1646 */ break; case 184: -#line 1922 "awkgram.y" /* yacc.c:1646 */ +#line 1925 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_merge((yyvsp[-1]), (yyvsp[0])); } -#line 4093 "awkgram.c" /* yacc.c:1646 */ +#line 4096 "awkgram.c" /* yacc.c:1646 */ break; case 185: -#line 1929 "awkgram.y" /* yacc.c:1646 */ +#line 1932 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *ip = (yyvsp[0])->lasti; int count = ip->sub_count; /* # of SUBSEP-seperated expressions */ @@ -4107,11 +4110,11 @@ regular_print: sub_counter++; /* count # of dimensions */ (yyval) = (yyvsp[0]); } -#line 4111 "awkgram.c" /* yacc.c:1646 */ +#line 4114 "awkgram.c" /* yacc.c:1646 */ break; case 186: -#line 1946 "awkgram.y" /* yacc.c:1646 */ +#line 1949 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *t = (yyvsp[-1]); if ((yyvsp[-1]) == NULL) { @@ -4125,31 +4128,31 @@ regular_print: (yyvsp[0])->sub_count = count_expressions(&t, false); (yyval) = list_append(t, (yyvsp[0])); } -#line 4129 "awkgram.c" /* yacc.c:1646 */ +#line 4132 "awkgram.c" /* yacc.c:1646 */ break; case 187: -#line 1963 "awkgram.y" /* yacc.c:1646 */ +#line 1966 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 4135 "awkgram.c" /* yacc.c:1646 */ +#line 4138 "awkgram.c" /* yacc.c:1646 */ break; case 188: -#line 1965 "awkgram.y" /* yacc.c:1646 */ +#line 1968 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_merge((yyvsp[-1]), (yyvsp[0])); } -#line 4143 "awkgram.c" /* yacc.c:1646 */ +#line 4146 "awkgram.c" /* yacc.c:1646 */ break; case 189: -#line 1972 "awkgram.y" /* yacc.c:1646 */ +#line 1975 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 4149 "awkgram.c" /* yacc.c:1646 */ +#line 4152 "awkgram.c" /* yacc.c:1646 */ break; case 190: -#line 1977 "awkgram.y" /* yacc.c:1646 */ +#line 1980 "awkgram.y" /* yacc.c:1646 */ { char *var_name = (yyvsp[0])->lextok; @@ -4157,22 +4160,22 @@ regular_print: (yyvsp[0])->memory = variable((yyvsp[0])->source_line, var_name, Node_var_new); (yyval) = list_create((yyvsp[0])); } -#line 4161 "awkgram.c" /* yacc.c:1646 */ +#line 4164 "awkgram.c" /* yacc.c:1646 */ break; case 191: -#line 1985 "awkgram.y" /* yacc.c:1646 */ +#line 1988 "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 4172 "awkgram.c" /* yacc.c:1646 */ +#line 4175 "awkgram.c" /* yacc.c:1646 */ break; case 192: -#line 1995 "awkgram.y" /* yacc.c:1646 */ +#line 1998 "awkgram.y" /* yacc.c:1646 */ { INSTRUCTION *ip = (yyvsp[0])->nexti; if (ip->opcode == Op_push @@ -4184,73 +4187,73 @@ regular_print: } else (yyval) = (yyvsp[0]); } -#line 4188 "awkgram.c" /* yacc.c:1646 */ +#line 4191 "awkgram.c" /* yacc.c:1646 */ break; case 193: -#line 2007 "awkgram.y" /* yacc.c:1646 */ +#line 2010 "awkgram.y" /* yacc.c:1646 */ { (yyval) = list_append((yyvsp[-1]), (yyvsp[-2])); if ((yyvsp[0]) != NULL) mk_assignment((yyvsp[-1]), NULL, (yyvsp[0])); } -#line 4198 "awkgram.c" /* yacc.c:1646 */ +#line 4201 "awkgram.c" /* yacc.c:1646 */ break; case 194: -#line 2016 "awkgram.y" /* yacc.c:1646 */ +#line 2019 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_postincrement; } -#line 4206 "awkgram.c" /* yacc.c:1646 */ +#line 4209 "awkgram.c" /* yacc.c:1646 */ break; case 195: -#line 2020 "awkgram.y" /* yacc.c:1646 */ +#line 2023 "awkgram.y" /* yacc.c:1646 */ { (yyvsp[0])->opcode = Op_postdecrement; } -#line 4214 "awkgram.c" /* yacc.c:1646 */ +#line 4217 "awkgram.c" /* yacc.c:1646 */ break; case 196: -#line 2023 "awkgram.y" /* yacc.c:1646 */ +#line 2026 "awkgram.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 4220 "awkgram.c" /* yacc.c:1646 */ +#line 4223 "awkgram.c" /* yacc.c:1646 */ break; case 198: -#line 2031 "awkgram.y" /* yacc.c:1646 */ +#line 2034 "awkgram.y" /* yacc.c:1646 */ { yyerrok; } -#line 4226 "awkgram.c" /* yacc.c:1646 */ +#line 4229 "awkgram.c" /* yacc.c:1646 */ break; case 199: -#line 2035 "awkgram.y" /* yacc.c:1646 */ +#line 2038 "awkgram.y" /* yacc.c:1646 */ { yyerrok; } -#line 4232 "awkgram.c" /* yacc.c:1646 */ +#line 4235 "awkgram.c" /* yacc.c:1646 */ break; case 202: -#line 2044 "awkgram.y" /* yacc.c:1646 */ +#line 2047 "awkgram.y" /* yacc.c:1646 */ { yyerrok; } -#line 4238 "awkgram.c" /* yacc.c:1646 */ +#line 4241 "awkgram.c" /* yacc.c:1646 */ break; case 203: -#line 2048 "awkgram.y" /* yacc.c:1646 */ +#line 2051 "awkgram.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); yyerrok; } -#line 4244 "awkgram.c" /* yacc.c:1646 */ +#line 4247 "awkgram.c" /* yacc.c:1646 */ break; case 204: -#line 2052 "awkgram.y" /* yacc.c:1646 */ +#line 2055 "awkgram.y" /* yacc.c:1646 */ { yyerrok; } -#line 4250 "awkgram.c" /* yacc.c:1646 */ +#line 4253 "awkgram.c" /* yacc.c:1646 */ break; -#line 4254 "awkgram.c" /* yacc.c:1646 */ +#line 4257 "awkgram.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -4478,7 +4481,7 @@ yyreturn: #endif return yyresult; } -#line 2054 "awkgram.y" /* yacc.c:1906 */ +#line 2057 "awkgram.y" /* yacc.c:1906 */ struct token { @@ -6294,6 +6297,10 @@ retry: if (c == '\r') /* allow MS-DOS files. bleah */ c = nextc(true); if (c == '\n') { + if (do_posix) + fatal(_("POSIX does not allow physical newlines in string values")); + else if (do_lint) + lintwarn(_("backslash string continuation is not portable")); sourceline++; continue; } @@ -1313,6 +1313,8 @@ output_redir && $3->lasti->opcode == Op_K_getline_redir && $3->lasti->redir_type == redirect_twoway) yyerror(_("multistage two-way pipelines don't work")); + if (do_lint && $1->redir_type == redirect_output && $3->lasti->opcode == Op_concat) + lintwarn(_("concatenation as I/O `>' redirection target is ambiguous")); $$ = list_prepend($3, $1); } ; @@ -1746,10 +1748,11 @@ non_post_simp_exp } | '(' exp r_paren { - if (do_pretty_print) - $$ = list_append($2, bcalloc(Op_parens, 1, sourceline)); - else - $$ = $2; + // Always include. Allows us to lint warn on + // print "foo" > "bar" 1 + // but not warn on + // print "foo" > ("bar" 1) + $$ = list_append($2, bcalloc(Op_parens, 1, sourceline)); } | LEX_BUILTIN '(' opt_fcall_expression_list r_paren { @@ -3866,6 +3869,10 @@ retry: if (c == '\r') /* allow MS-DOS files. bleah */ c = nextc(true); if (c == '\n') { + if (do_posix) + fatal(_("POSIX does not allow physical newlines in string values")); + else if (do_lint) + lintwarn(_("backslash string continuation is not portable")); sourceline++; continue; } @@ -38,6 +38,14 @@ #include "vms/redirect.h" #endif +/* OpenVMS has some definitions in fp.h that should be in math.h */ +/* From John Malmberg, wb8tyw@qsl.net */ +#ifdef __VMS +#include <fp.h> +/* isnan () macro is broken */ +#undef isnan +#endif + /* For QNX, based on submission from Michael Hunter, mphunter@qnx.com */ #ifdef __QNX__ #define GETPGRP_VOID 1 diff --git a/doc/ChangeLog b/doc/ChangeLog index 20bb5182..95df0e67 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,18 @@ +2018-07-31 Arnold D. Robbins <arnold@skeeve.com> + + * gawktexi.in (Scalar Constants): Document what happens with + physical newlines in strings, escaped and otherwise. + +2018-07-31 Arnold D. Robbins <arnold@skeeve.com> + + * gawktexi.in (Two-way I/O): Fix some typos. + * gawkworkflow.texi (Configuring git): Correct some + command usages. Thanks to Antonio Columbo for the fix. + +2018-07-31 Ralph Corderoy <ralph@inputplus.co.uk> + + * gawk.1: Avoid hyphenation in gawk email address. + 2018-07-25 Arnold D. Robbins <arnold@skeeve.com> * gawktexi.in (Two-way I/O): Add a nice example on buffering @@ -4050,7 +4050,7 @@ and which ports are currently supported. If you find a bug in .IR gawk , please send electronic mail to -.BR bug-gawk@gnu.org . +.BR \%bug-gawk@gnu.org . Please include your operating system and its revision, the version of .I gawk (from diff --git a/doc/gawk.info b/doc/gawk.info index f4764ac1..99065732 100644 --- a/doc/gawk.info +++ b/doc/gawk.info @@ -7669,6 +7669,55 @@ can be of any length, and they can contain any of the possible eight-bit ASCII characters, including ASCII NUL (character code zero). Other 'awk' implementations may have difficulty with some character codes. + Some languages allow you to continue long strings across multiple +lines by ending the line with a backslash. For example in C: + + #include <stdio.h> + + int main() + { + printf "hello, \ + world\n"); + return 0; + } + +In such a case, the C compiler removes both the backslash and the +newline, producing a string as if it had been typed '"hello, world\n"'. +This is useful when a single string needs to contain a large amount of +text. + + The POSIX standard says explicitly that newlines are not allowed +inside string constants. And indeed, all 'awk' implementations report +an error if you try to do so. For example: + + $ gawk 'BEGIN { print "hello, + > world" }' + -| gawk: cmd. line:1: BEGIN print "hello, + -| gawk: cmd. line:1: ^ unterminated string + -| gawk: cmd. line:1: BEGIN print "hello, + -| gawk: cmd. line:1: ^ syntax error + + Although POSIX doesn't define what happens if you use an escaped +newline, as in the previous C example, all known versions of 'awk' allow +you to do so. Unfortunately, what each one does with such a string +varies. (d.c.) 'gawk', 'mawk', and the OpenSolaris POSIX 'awk' (*note +Other Versions::) elide the backslash and newline, as in C: + + $ gawk 'BEGIN { print "hello, \ + > world" }' + -| hello, world + + Brian Kernighan's 'awk' and Busybox 'awk' remove the backslash but +leave the newline intact, as part of the string: + + $ nawk 'BEGIN { print "hello, \ + > world" }' + -| hello, + -| world + + In POSIX mode (*note Options::), 'gawk' does not allow escaped +newlines. Otherwise, it behaves as just described. + ---------- Footnotes ---------- (1) The internal representation of all numbers, including integers, @@ -23480,7 +23529,7 @@ and infinity values. The solution implemented in 'gawk' is as follows: 'gawk' ignores case in the four special values. Thus, '+nan' and '+NaN' are the same. - Besides handling imput, 'gawk' also needs to print "correct" values + Besides handling input, 'gawk' also needs to print "correct" values on output when a value is either NaN or infinity. Starting with version 4.2.2, for such values 'gawk' prints one of the four strings just described: '+inf', '-inf', '+nan', or '-nan'. Similarly, in POSIX mode, @@ -33871,6 +33920,7 @@ Index * dark corner, regexp constants, as arguments to user-defined functions: Standard Regexp Constants. (line 43) * dark corner, split() function: String Functions. (line 364) +* dark corner, string continuation: Scalar Constants. (line 53) * dark corner, strings, storing: gawk split records. (line 82) * dark corner, value of ARGV[0]: Auto-set. (line 39) * dark corner, ^, in FS: Regexp Field Splitting. @@ -34088,6 +34138,7 @@ Index * differences in awk and gawk, split() function: String Functions. (line 351) * differences in awk and gawk, strings: Scalar Constants. (line 20) +* differences in awk and gawk, strings <1>: Scalar Constants. (line 53) * differences in awk and gawk, strings, storing: gawk split records. (line 76) * differences in awk and gawk, SYMTAB variable: Auto-set. (line 331) @@ -35802,6 +35853,7 @@ Index * string-matching operators: Regexp Usage. (line 19) * string-translation functions: I18N Functions. (line 6) * strings splitting, example: String Functions. (line 337) +* strings, continuation across lines: Scalar Constants. (line 53) * strings, converting: Strings And Numbers. (line 6) * strings, converting <1>: Bitwise Functions. (line 109) * strings, converting letter case: String Functions. (line 526) @@ -36238,436 +36290,436 @@ Node: Expressions332646 Node: Values333834 Node: Constants334512 Node: Scalar Constants335203 -Ref: Scalar Constants-Footnote-1336067 -Node: Nondecimal-numbers336317 -Node: Regexp Constants339318 -Node: Using Constant Regexps339844 -Node: Standard Regexp Constants340466 -Node: Strong Regexp Constants343654 -Node: Variables346612 -Node: Using Variables347269 -Node: Assignment Options349179 -Node: Conversion351052 -Node: Strings And Numbers351576 -Ref: Strings And Numbers-Footnote-1354639 -Node: Locale influences conversions354748 -Ref: table-locale-affects357506 -Node: All Operators358124 -Node: Arithmetic Ops358753 -Node: Concatenation361259 -Ref: Concatenation-Footnote-1364106 -Node: Assignment Ops364213 -Ref: table-assign-ops369204 -Node: Increment Ops370517 -Node: Truth Values and Conditions373977 -Node: Truth Values375051 -Node: Typing and Comparison376099 -Node: Variable Typing376919 -Ref: Variable Typing-Footnote-1383382 -Ref: Variable Typing-Footnote-2383454 -Node: Comparison Operators383531 -Ref: table-relational-ops383950 -Node: POSIX String Comparison387445 -Ref: POSIX String Comparison-Footnote-1389140 -Ref: POSIX String Comparison-Footnote-2389279 -Node: Boolean Ops389363 -Ref: Boolean Ops-Footnote-1393845 -Node: Conditional Exp393937 -Node: Function Calls395673 -Node: Precedence399550 -Node: Locales403209 -Node: Expressions Summary404841 -Node: Patterns and Actions407414 -Node: Pattern Overview408534 -Node: Regexp Patterns410211 -Node: Expression Patterns410753 -Node: Ranges414534 -Node: BEGIN/END417642 -Node: Using BEGIN/END418403 -Ref: Using BEGIN/END-Footnote-1421139 -Node: I/O And BEGIN/END421245 -Node: BEGINFILE/ENDFILE423559 -Node: Empty426472 -Node: Using Shell Variables426789 -Node: Action Overview429063 -Node: Statements431388 -Node: If Statement433236 -Node: While Statement434731 -Node: Do Statement436759 -Node: For Statement437907 -Node: Switch Statement441078 -Node: Break Statement443464 -Node: Continue Statement445556 -Node: Next Statement447383 -Node: Nextfile Statement449766 -Node: Exit Statement452418 -Node: Built-in Variables454821 -Node: User-modified455954 -Node: Auto-set463721 -Ref: Auto-set-Footnote-1480023 -Ref: Auto-set-Footnote-2480229 -Node: ARGC and ARGV480285 -Node: Pattern Action Summary484498 -Node: Arrays486928 -Node: Array Basics488257 -Node: Array Intro489101 -Ref: figure-array-elements491076 -Ref: Array Intro-Footnote-1493780 -Node: Reference to Elements493908 -Node: Assigning Elements496372 -Node: Array Example496863 -Node: Scanning an Array498622 -Node: Controlling Scanning501644 -Ref: Controlling Scanning-Footnote-1507043 -Node: Numeric Array Subscripts507359 -Node: Uninitialized Subscripts509543 -Node: Delete511162 -Ref: Delete-Footnote-1513914 -Node: Multidimensional513971 -Node: Multiscanning517066 -Node: Arrays of Arrays518657 -Node: Arrays Summary523424 -Node: Functions525517 -Node: Built-in526555 -Node: Calling Built-in527636 -Node: Numeric Functions529632 -Ref: Numeric Functions-Footnote-1533660 -Ref: Numeric Functions-Footnote-2534017 -Ref: Numeric Functions-Footnote-3534065 -Node: String Functions534337 -Ref: String Functions-Footnote-1558046 -Ref: String Functions-Footnote-2558174 -Ref: String Functions-Footnote-3558422 -Node: Gory Details558509 -Ref: table-sub-escapes560300 -Ref: table-sub-proposed561819 -Ref: table-posix-sub563182 -Ref: table-gensub-escapes564723 -Ref: Gory Details-Footnote-1565546 -Node: I/O Functions565700 -Ref: table-system-return-values572168 -Ref: I/O Functions-Footnote-1574148 -Ref: I/O Functions-Footnote-2574296 -Node: Time Functions574416 -Ref: Time Functions-Footnote-1585087 -Ref: Time Functions-Footnote-2585155 -Ref: Time Functions-Footnote-3585313 -Ref: Time Functions-Footnote-4585424 -Ref: Time Functions-Footnote-5585536 -Ref: Time Functions-Footnote-6585763 -Node: Bitwise Functions586029 -Ref: table-bitwise-ops586623 -Ref: Bitwise Functions-Footnote-1592686 -Ref: Bitwise Functions-Footnote-2592859 -Node: Type Functions593050 -Node: I18N Functions595801 -Node: User-defined597452 -Node: Definition Syntax598257 -Ref: Definition Syntax-Footnote-1603944 -Node: Function Example604015 -Ref: Function Example-Footnote-1606937 -Node: Function Caveats606959 -Node: Calling A Function607477 -Node: Variable Scope608435 -Node: Pass By Value/Reference611429 -Node: Return Statement614928 -Node: Dynamic Typing617907 -Node: Indirect Calls618837 -Ref: Indirect Calls-Footnote-1629089 -Node: Functions Summary629217 -Node: Library Functions631922 -Ref: Library Functions-Footnote-1635529 -Ref: Library Functions-Footnote-2635672 -Node: Library Names635843 -Ref: Library Names-Footnote-1639303 -Ref: Library Names-Footnote-2639526 -Node: General Functions639612 -Node: Strtonum Function640715 -Node: Assert Function643737 -Node: Round Function647063 -Node: Cliff Random Function648603 -Node: Ordinal Functions649619 -Ref: Ordinal Functions-Footnote-1652682 -Ref: Ordinal Functions-Footnote-2652934 -Node: Join Function653144 -Ref: Join Function-Footnote-1654914 -Node: Getlocaltime Function655114 -Node: Readfile Function658856 -Node: Shell Quoting660833 -Node: Data File Management662234 -Node: Filetrans Function662866 -Node: Rewind Function666962 -Node: File Checking668872 -Ref: File Checking-Footnote-1670206 -Node: Empty Files670407 -Node: Ignoring Assigns672386 -Node: Getopt Function673936 -Ref: Getopt Function-Footnote-1685405 -Node: Passwd Functions685605 -Ref: Passwd Functions-Footnote-1694444 -Node: Group Functions694532 -Ref: Group Functions-Footnote-1702430 -Node: Walking Arrays702637 -Node: Library Functions Summary705645 -Node: Library Exercises707051 -Node: Sample Programs707516 -Node: Running Examples708286 -Node: Clones709014 -Node: Cut Program710238 -Node: Egrep Program720167 -Ref: Egrep Program-Footnote-1727679 -Node: Id Program727789 -Node: Split Program731469 -Ref: Split Program-Footnote-1734927 -Node: Tee Program735056 -Node: Uniq Program737846 -Node: Wc Program745272 -Ref: Wc Program-Footnote-1749527 -Node: Miscellaneous Programs749621 -Node: Dupword Program750834 -Node: Alarm Program752864 -Node: Translate Program757719 -Ref: Translate Program-Footnote-1762284 -Node: Labels Program762554 -Ref: Labels Program-Footnote-1765905 -Node: Word Sorting765989 -Node: History Sorting770061 -Node: Extract Program771896 -Node: Simple Sed779950 -Node: Igawk Program783024 -Ref: Igawk Program-Footnote-1797355 -Ref: Igawk Program-Footnote-2797557 -Ref: Igawk Program-Footnote-3797679 -Node: Anagram Program797794 -Node: Signature Program800856 -Node: Programs Summary802103 -Node: Programs Exercises803317 -Ref: Programs Exercises-Footnote-1807446 -Node: Advanced Features807537 -Node: Nondecimal Data809527 -Node: Array Sorting811118 -Node: Controlling Array Traversal811818 -Ref: Controlling Array Traversal-Footnote-1820186 -Node: Array Sorting Functions820304 -Ref: Array Sorting Functions-Footnote-1825395 -Node: Two-way I/O825591 -Ref: Two-way I/O-Footnote-1833311 -Ref: Two-way I/O-Footnote-2833498 -Node: TCP/IP Networking833580 -Node: Profiling836698 -Ref: Profiling-Footnote-1845370 -Node: Advanced Features Summary845693 -Node: Internationalization847537 -Node: I18N and L10N849017 -Node: Explaining gettext849704 -Ref: Explaining gettext-Footnote-1855596 -Ref: Explaining gettext-Footnote-2855781 -Node: Programmer i18n855946 -Ref: Programmer i18n-Footnote-1860895 -Node: Translator i18n860944 -Node: String Extraction861738 -Ref: String Extraction-Footnote-1862870 -Node: Printf Ordering862956 -Ref: Printf Ordering-Footnote-1865742 -Node: I18N Portability865806 -Ref: I18N Portability-Footnote-1868262 -Node: I18N Example868325 -Ref: I18N Example-Footnote-1871131 -Node: Gawk I18N871204 -Node: I18N Summary871849 -Node: Debugger873190 -Node: Debugging874213 -Node: Debugging Concepts874654 -Node: Debugging Terms876463 -Node: Awk Debugging879038 -Node: Sample Debugging Session879944 -Node: Debugger Invocation880478 -Node: Finding The Bug881864 -Node: List of Debugger Commands888342 -Node: Breakpoint Control889675 -Node: Debugger Execution Control893369 -Node: Viewing And Changing Data896731 -Node: Execution Stack900105 -Node: Debugger Info901742 -Node: Miscellaneous Debugger Commands905813 -Node: Readline Support910875 -Node: Limitations911771 -Node: Debugging Summary913880 -Node: Arbitrary Precision Arithmetic915159 -Node: Computer Arithmetic916644 -Ref: table-numeric-ranges920410 -Ref: table-floating-point-ranges920903 -Ref: Computer Arithmetic-Footnote-1921561 -Node: Math Definitions921618 -Ref: table-ieee-formats924934 -Ref: Math Definitions-Footnote-1925537 -Node: MPFR features925642 -Node: FP Math Caution927360 -Ref: FP Math Caution-Footnote-1928432 -Node: Inexactness of computations928801 -Node: Inexact representation929761 -Node: Comparing FP Values931121 -Node: Errors accumulate932203 -Node: Getting Accuracy933636 -Node: Try To Round936346 -Node: Setting precision937245 -Ref: table-predefined-precision-strings937942 -Node: Setting the rounding mode939772 -Ref: table-gawk-rounding-modes940146 -Ref: Setting the rounding mode-Footnote-1944077 -Node: Arbitrary Precision Integers944256 -Ref: Arbitrary Precision Integers-Footnote-1947431 -Node: Checking for MPFR947580 -Node: POSIX Floating Point Problems949054 -Ref: POSIX Floating Point Problems-Footnote-1953339 -Node: Floating point summary953377 -Node: Dynamic Extensions955567 -Node: Extension Intro957120 -Node: Plugin License958386 -Node: Extension Mechanism Outline959183 -Ref: figure-load-extension959622 -Ref: figure-register-new-function961187 -Ref: figure-call-new-function962279 -Node: Extension API Description964341 -Node: Extension API Functions Introduction965983 -Node: General Data Types971523 -Ref: General Data Types-Footnote-1979884 -Node: Memory Allocation Functions980183 -Ref: Memory Allocation Functions-Footnote-1984393 -Node: Constructor Functions984492 -Node: Registration Functions988078 -Node: Extension Functions988763 -Node: Exit Callback Functions993978 -Node: Extension Version String995228 -Node: Input Parsers995891 -Node: Output Wrappers1008612 -Node: Two-way processors1013124 -Node: Printing Messages1015389 -Ref: Printing Messages-Footnote-11016560 -Node: Updating ERRNO1016713 -Node: Requesting Values1017452 -Ref: table-value-types-returned1018189 -Node: Accessing Parameters1019125 -Node: Symbol Table Access1020360 -Node: Symbol table by name1020872 -Node: Symbol table by cookie1022661 -Ref: Symbol table by cookie-Footnote-11026846 -Node: Cached values1026910 -Ref: Cached values-Footnote-11030446 -Node: Array Manipulation1030599 -Ref: Array Manipulation-Footnote-11031690 -Node: Array Data Types1031727 -Ref: Array Data Types-Footnote-11034385 -Node: Array Functions1034477 -Node: Flattening Arrays1038975 -Node: Creating Arrays1045951 -Node: Redirection API1050718 -Node: Extension API Variables1053551 -Node: Extension Versioning1054262 -Ref: gawk-api-version1054691 -Node: Extension GMP/MPFR Versioning1056422 -Node: Extension API Informational Variables1058050 -Node: Extension API Boilerplate1059123 -Node: Changes from API V11063097 -Node: Finding Extensions1064669 -Node: Extension Example1065228 -Node: Internal File Description1066026 -Node: Internal File Ops1070106 -Ref: Internal File Ops-Footnote-11081456 -Node: Using Internal File Ops1081596 -Ref: Using Internal File Ops-Footnote-11083979 -Node: Extension Samples1084253 -Node: Extension Sample File Functions1085782 -Node: Extension Sample Fnmatch1093431 -Node: Extension Sample Fork1094918 -Node: Extension Sample Inplace1096136 -Node: Extension Sample Ord1099353 -Node: Extension Sample Readdir1100189 -Ref: table-readdir-file-types1101078 -Node: Extension Sample Revout1101883 -Node: Extension Sample Rev2way1102472 -Node: Extension Sample Read write array1103212 -Node: Extension Sample Readfile1105154 -Node: Extension Sample Time1106249 -Node: Extension Sample API Tests1107597 -Node: gawkextlib1108089 -Node: Extension summary1111007 -Node: Extension Exercises1114709 -Node: Language History1116207 -Node: V7/SVR3.11117863 -Node: SVR41120015 -Node: POSIX1121449 -Node: BTL1122829 -Node: POSIX/GNU1123558 -Node: Feature History1129336 -Node: Common Extensions1145195 -Node: Ranges and Locales1146478 -Ref: Ranges and Locales-Footnote-11151094 -Ref: Ranges and Locales-Footnote-21151121 -Ref: Ranges and Locales-Footnote-31151356 -Node: Contributors1151577 -Node: History summary1157522 -Node: Installation1158902 -Node: Gawk Distribution1159846 -Node: Getting1160330 -Node: Extracting1161293 -Node: Distribution contents1162931 -Node: Unix Installation1169411 -Node: Quick Installation1170093 -Node: Shell Startup Files1172507 -Node: Additional Configuration Options1173596 -Node: Configuration Philosophy1175761 -Node: Non-Unix Installation1178130 -Node: PC Installation1178590 -Node: PC Binary Installation1179428 -Node: PC Compiling1179863 -Node: PC Using1180980 -Node: Cygwin1184195 -Node: MSYS1185294 -Node: VMS Installation1185795 -Node: VMS Compilation1186586 -Ref: VMS Compilation-Footnote-11187815 -Node: VMS Dynamic Extensions1187873 -Node: VMS Installation Details1189558 -Node: VMS Running1191811 -Node: VMS GNV1196090 -Node: VMS Old Gawk1196825 -Node: Bugs1197296 -Node: Bug address1197959 -Node: Usenet1200751 -Node: Maintainers1201528 -Node: Other Versions1202789 -Node: Installation summary1209551 -Node: Notes1210753 -Node: Compatibility Mode1211618 -Node: Additions1212400 -Node: Accessing The Source1213325 -Node: Adding Code1214762 -Node: New Ports1220981 -Node: Derived Files1225469 -Ref: Derived Files-Footnote-11231115 -Ref: Derived Files-Footnote-21231150 -Ref: Derived Files-Footnote-31231748 -Node: Future Extensions1231862 -Node: Implementation Limitations1232520 -Node: Extension Design1233703 -Node: Old Extension Problems1234857 -Ref: Old Extension Problems-Footnote-11236375 -Node: Extension New Mechanism Goals1236432 -Ref: Extension New Mechanism Goals-Footnote-11239796 -Node: Extension Other Design Decisions1239985 -Node: Extension Future Growth1242098 -Node: Old Extension Mechanism1242934 -Node: Notes summary1244697 -Node: Basic Concepts1245879 -Node: Basic High Level1246560 -Ref: figure-general-flow1246842 -Ref: figure-process-flow1247527 -Ref: Basic High Level-Footnote-11250828 -Node: Basic Data Typing1251013 -Node: Glossary1254341 -Node: Copying1286179 -Node: GNU Free Documentation License1323722 -Node: Index1348842 +Ref: Scalar Constants-Footnote-1337726 +Node: Nondecimal-numbers337976 +Node: Regexp Constants340977 +Node: Using Constant Regexps341503 +Node: Standard Regexp Constants342125 +Node: Strong Regexp Constants345313 +Node: Variables348271 +Node: Using Variables348928 +Node: Assignment Options350838 +Node: Conversion352711 +Node: Strings And Numbers353235 +Ref: Strings And Numbers-Footnote-1356298 +Node: Locale influences conversions356407 +Ref: table-locale-affects359165 +Node: All Operators359783 +Node: Arithmetic Ops360412 +Node: Concatenation362918 +Ref: Concatenation-Footnote-1365765 +Node: Assignment Ops365872 +Ref: table-assign-ops370863 +Node: Increment Ops372176 +Node: Truth Values and Conditions375636 +Node: Truth Values376710 +Node: Typing and Comparison377758 +Node: Variable Typing378578 +Ref: Variable Typing-Footnote-1385041 +Ref: Variable Typing-Footnote-2385113 +Node: Comparison Operators385190 +Ref: table-relational-ops385609 +Node: POSIX String Comparison389104 +Ref: POSIX String Comparison-Footnote-1390799 +Ref: POSIX String Comparison-Footnote-2390938 +Node: Boolean Ops391022 +Ref: Boolean Ops-Footnote-1395504 +Node: Conditional Exp395596 +Node: Function Calls397332 +Node: Precedence401209 +Node: Locales404868 +Node: Expressions Summary406500 +Node: Patterns and Actions409073 +Node: Pattern Overview410193 +Node: Regexp Patterns411870 +Node: Expression Patterns412412 +Node: Ranges416193 +Node: BEGIN/END419301 +Node: Using BEGIN/END420062 +Ref: Using BEGIN/END-Footnote-1422798 +Node: I/O And BEGIN/END422904 +Node: BEGINFILE/ENDFILE425218 +Node: Empty428131 +Node: Using Shell Variables428448 +Node: Action Overview430722 +Node: Statements433047 +Node: If Statement434895 +Node: While Statement436390 +Node: Do Statement438418 +Node: For Statement439566 +Node: Switch Statement442737 +Node: Break Statement445123 +Node: Continue Statement447215 +Node: Next Statement449042 +Node: Nextfile Statement451425 +Node: Exit Statement454077 +Node: Built-in Variables456480 +Node: User-modified457613 +Node: Auto-set465380 +Ref: Auto-set-Footnote-1481682 +Ref: Auto-set-Footnote-2481888 +Node: ARGC and ARGV481944 +Node: Pattern Action Summary486157 +Node: Arrays488587 +Node: Array Basics489916 +Node: Array Intro490760 +Ref: figure-array-elements492735 +Ref: Array Intro-Footnote-1495439 +Node: Reference to Elements495567 +Node: Assigning Elements498031 +Node: Array Example498522 +Node: Scanning an Array500281 +Node: Controlling Scanning503303 +Ref: Controlling Scanning-Footnote-1508702 +Node: Numeric Array Subscripts509018 +Node: Uninitialized Subscripts511202 +Node: Delete512821 +Ref: Delete-Footnote-1515573 +Node: Multidimensional515630 +Node: Multiscanning518725 +Node: Arrays of Arrays520316 +Node: Arrays Summary525083 +Node: Functions527176 +Node: Built-in528214 +Node: Calling Built-in529295 +Node: Numeric Functions531291 +Ref: Numeric Functions-Footnote-1535319 +Ref: Numeric Functions-Footnote-2535676 +Ref: Numeric Functions-Footnote-3535724 +Node: String Functions535996 +Ref: String Functions-Footnote-1559705 +Ref: String Functions-Footnote-2559833 +Ref: String Functions-Footnote-3560081 +Node: Gory Details560168 +Ref: table-sub-escapes561959 +Ref: table-sub-proposed563478 +Ref: table-posix-sub564841 +Ref: table-gensub-escapes566382 +Ref: Gory Details-Footnote-1567205 +Node: I/O Functions567359 +Ref: table-system-return-values573827 +Ref: I/O Functions-Footnote-1575807 +Ref: I/O Functions-Footnote-2575955 +Node: Time Functions576075 +Ref: Time Functions-Footnote-1586746 +Ref: Time Functions-Footnote-2586814 +Ref: Time Functions-Footnote-3586972 +Ref: Time Functions-Footnote-4587083 +Ref: Time Functions-Footnote-5587195 +Ref: Time Functions-Footnote-6587422 +Node: Bitwise Functions587688 +Ref: table-bitwise-ops588282 +Ref: Bitwise Functions-Footnote-1594345 +Ref: Bitwise Functions-Footnote-2594518 +Node: Type Functions594709 +Node: I18N Functions597460 +Node: User-defined599111 +Node: Definition Syntax599916 +Ref: Definition Syntax-Footnote-1605603 +Node: Function Example605674 +Ref: Function Example-Footnote-1608596 +Node: Function Caveats608618 +Node: Calling A Function609136 +Node: Variable Scope610094 +Node: Pass By Value/Reference613088 +Node: Return Statement616587 +Node: Dynamic Typing619566 +Node: Indirect Calls620496 +Ref: Indirect Calls-Footnote-1630748 +Node: Functions Summary630876 +Node: Library Functions633581 +Ref: Library Functions-Footnote-1637188 +Ref: Library Functions-Footnote-2637331 +Node: Library Names637502 +Ref: Library Names-Footnote-1640962 +Ref: Library Names-Footnote-2641185 +Node: General Functions641271 +Node: Strtonum Function642374 +Node: Assert Function645396 +Node: Round Function648722 +Node: Cliff Random Function650262 +Node: Ordinal Functions651278 +Ref: Ordinal Functions-Footnote-1654341 +Ref: Ordinal Functions-Footnote-2654593 +Node: Join Function654803 +Ref: Join Function-Footnote-1656573 +Node: Getlocaltime Function656773 +Node: Readfile Function660515 +Node: Shell Quoting662492 +Node: Data File Management663893 +Node: Filetrans Function664525 +Node: Rewind Function668621 +Node: File Checking670531 +Ref: File Checking-Footnote-1671865 +Node: Empty Files672066 +Node: Ignoring Assigns674045 +Node: Getopt Function675595 +Ref: Getopt Function-Footnote-1687064 +Node: Passwd Functions687264 +Ref: Passwd Functions-Footnote-1696103 +Node: Group Functions696191 +Ref: Group Functions-Footnote-1704089 +Node: Walking Arrays704296 +Node: Library Functions Summary707304 +Node: Library Exercises708710 +Node: Sample Programs709175 +Node: Running Examples709945 +Node: Clones710673 +Node: Cut Program711897 +Node: Egrep Program721826 +Ref: Egrep Program-Footnote-1729338 +Node: Id Program729448 +Node: Split Program733128 +Ref: Split Program-Footnote-1736586 +Node: Tee Program736715 +Node: Uniq Program739505 +Node: Wc Program746931 +Ref: Wc Program-Footnote-1751186 +Node: Miscellaneous Programs751280 +Node: Dupword Program752493 +Node: Alarm Program754523 +Node: Translate Program759378 +Ref: Translate Program-Footnote-1763943 +Node: Labels Program764213 +Ref: Labels Program-Footnote-1767564 +Node: Word Sorting767648 +Node: History Sorting771720 +Node: Extract Program773555 +Node: Simple Sed781609 +Node: Igawk Program784683 +Ref: Igawk Program-Footnote-1799014 +Ref: Igawk Program-Footnote-2799216 +Ref: Igawk Program-Footnote-3799338 +Node: Anagram Program799453 +Node: Signature Program802515 +Node: Programs Summary803762 +Node: Programs Exercises804976 +Ref: Programs Exercises-Footnote-1809105 +Node: Advanced Features809196 +Node: Nondecimal Data811186 +Node: Array Sorting812777 +Node: Controlling Array Traversal813477 +Ref: Controlling Array Traversal-Footnote-1821845 +Node: Array Sorting Functions821963 +Ref: Array Sorting Functions-Footnote-1827054 +Node: Two-way I/O827250 +Ref: Two-way I/O-Footnote-1834970 +Ref: Two-way I/O-Footnote-2835157 +Node: TCP/IP Networking835239 +Node: Profiling838357 +Ref: Profiling-Footnote-1847029 +Node: Advanced Features Summary847352 +Node: Internationalization849196 +Node: I18N and L10N850676 +Node: Explaining gettext851363 +Ref: Explaining gettext-Footnote-1857255 +Ref: Explaining gettext-Footnote-2857440 +Node: Programmer i18n857605 +Ref: Programmer i18n-Footnote-1862554 +Node: Translator i18n862603 +Node: String Extraction863397 +Ref: String Extraction-Footnote-1864529 +Node: Printf Ordering864615 +Ref: Printf Ordering-Footnote-1867401 +Node: I18N Portability867465 +Ref: I18N Portability-Footnote-1869921 +Node: I18N Example869984 +Ref: I18N Example-Footnote-1872790 +Node: Gawk I18N872863 +Node: I18N Summary873508 +Node: Debugger874849 +Node: Debugging875872 +Node: Debugging Concepts876313 +Node: Debugging Terms878122 +Node: Awk Debugging880697 +Node: Sample Debugging Session881603 +Node: Debugger Invocation882137 +Node: Finding The Bug883523 +Node: List of Debugger Commands890001 +Node: Breakpoint Control891334 +Node: Debugger Execution Control895028 +Node: Viewing And Changing Data898390 +Node: Execution Stack901764 +Node: Debugger Info903401 +Node: Miscellaneous Debugger Commands907472 +Node: Readline Support912534 +Node: Limitations913430 +Node: Debugging Summary915539 +Node: Arbitrary Precision Arithmetic916818 +Node: Computer Arithmetic918303 +Ref: table-numeric-ranges922069 +Ref: table-floating-point-ranges922562 +Ref: Computer Arithmetic-Footnote-1923220 +Node: Math Definitions923277 +Ref: table-ieee-formats926593 +Ref: Math Definitions-Footnote-1927196 +Node: MPFR features927301 +Node: FP Math Caution929019 +Ref: FP Math Caution-Footnote-1930091 +Node: Inexactness of computations930460 +Node: Inexact representation931420 +Node: Comparing FP Values932780 +Node: Errors accumulate933862 +Node: Getting Accuracy935295 +Node: Try To Round938005 +Node: Setting precision938904 +Ref: table-predefined-precision-strings939601 +Node: Setting the rounding mode941431 +Ref: table-gawk-rounding-modes941805 +Ref: Setting the rounding mode-Footnote-1945736 +Node: Arbitrary Precision Integers945915 +Ref: Arbitrary Precision Integers-Footnote-1949090 +Node: Checking for MPFR949239 +Node: POSIX Floating Point Problems950713 +Ref: POSIX Floating Point Problems-Footnote-1954998 +Node: Floating point summary955036 +Node: Dynamic Extensions957226 +Node: Extension Intro958779 +Node: Plugin License960045 +Node: Extension Mechanism Outline960842 +Ref: figure-load-extension961281 +Ref: figure-register-new-function962846 +Ref: figure-call-new-function963938 +Node: Extension API Description966000 +Node: Extension API Functions Introduction967642 +Node: General Data Types973182 +Ref: General Data Types-Footnote-1981543 +Node: Memory Allocation Functions981842 +Ref: Memory Allocation Functions-Footnote-1986052 +Node: Constructor Functions986151 +Node: Registration Functions989737 +Node: Extension Functions990422 +Node: Exit Callback Functions995637 +Node: Extension Version String996887 +Node: Input Parsers997550 +Node: Output Wrappers1010271 +Node: Two-way processors1014783 +Node: Printing Messages1017048 +Ref: Printing Messages-Footnote-11018219 +Node: Updating ERRNO1018372 +Node: Requesting Values1019111 +Ref: table-value-types-returned1019848 +Node: Accessing Parameters1020784 +Node: Symbol Table Access1022019 +Node: Symbol table by name1022531 +Node: Symbol table by cookie1024320 +Ref: Symbol table by cookie-Footnote-11028505 +Node: Cached values1028569 +Ref: Cached values-Footnote-11032105 +Node: Array Manipulation1032258 +Ref: Array Manipulation-Footnote-11033349 +Node: Array Data Types1033386 +Ref: Array Data Types-Footnote-11036044 +Node: Array Functions1036136 +Node: Flattening Arrays1040634 +Node: Creating Arrays1047610 +Node: Redirection API1052377 +Node: Extension API Variables1055210 +Node: Extension Versioning1055921 +Ref: gawk-api-version1056350 +Node: Extension GMP/MPFR Versioning1058081 +Node: Extension API Informational Variables1059709 +Node: Extension API Boilerplate1060782 +Node: Changes from API V11064756 +Node: Finding Extensions1066328 +Node: Extension Example1066887 +Node: Internal File Description1067685 +Node: Internal File Ops1071765 +Ref: Internal File Ops-Footnote-11083115 +Node: Using Internal File Ops1083255 +Ref: Using Internal File Ops-Footnote-11085638 +Node: Extension Samples1085912 +Node: Extension Sample File Functions1087441 +Node: Extension Sample Fnmatch1095090 +Node: Extension Sample Fork1096577 +Node: Extension Sample Inplace1097795 +Node: Extension Sample Ord1101012 +Node: Extension Sample Readdir1101848 +Ref: table-readdir-file-types1102737 +Node: Extension Sample Revout1103542 +Node: Extension Sample Rev2way1104131 +Node: Extension Sample Read write array1104871 +Node: Extension Sample Readfile1106813 +Node: Extension Sample Time1107908 +Node: Extension Sample API Tests1109256 +Node: gawkextlib1109748 +Node: Extension summary1112666 +Node: Extension Exercises1116368 +Node: Language History1117866 +Node: V7/SVR3.11119522 +Node: SVR41121674 +Node: POSIX1123108 +Node: BTL1124488 +Node: POSIX/GNU1125217 +Node: Feature History1130995 +Node: Common Extensions1146854 +Node: Ranges and Locales1148137 +Ref: Ranges and Locales-Footnote-11152753 +Ref: Ranges and Locales-Footnote-21152780 +Ref: Ranges and Locales-Footnote-31153015 +Node: Contributors1153236 +Node: History summary1159181 +Node: Installation1160561 +Node: Gawk Distribution1161505 +Node: Getting1161989 +Node: Extracting1162952 +Node: Distribution contents1164590 +Node: Unix Installation1171070 +Node: Quick Installation1171752 +Node: Shell Startup Files1174166 +Node: Additional Configuration Options1175255 +Node: Configuration Philosophy1177420 +Node: Non-Unix Installation1179789 +Node: PC Installation1180249 +Node: PC Binary Installation1181087 +Node: PC Compiling1181522 +Node: PC Using1182639 +Node: Cygwin1185854 +Node: MSYS1186953 +Node: VMS Installation1187454 +Node: VMS Compilation1188245 +Ref: VMS Compilation-Footnote-11189474 +Node: VMS Dynamic Extensions1189532 +Node: VMS Installation Details1191217 +Node: VMS Running1193470 +Node: VMS GNV1197749 +Node: VMS Old Gawk1198484 +Node: Bugs1198955 +Node: Bug address1199618 +Node: Usenet1202410 +Node: Maintainers1203187 +Node: Other Versions1204448 +Node: Installation summary1211210 +Node: Notes1212412 +Node: Compatibility Mode1213277 +Node: Additions1214059 +Node: Accessing The Source1214984 +Node: Adding Code1216421 +Node: New Ports1222640 +Node: Derived Files1227128 +Ref: Derived Files-Footnote-11232774 +Ref: Derived Files-Footnote-21232809 +Ref: Derived Files-Footnote-31233407 +Node: Future Extensions1233521 +Node: Implementation Limitations1234179 +Node: Extension Design1235362 +Node: Old Extension Problems1236516 +Ref: Old Extension Problems-Footnote-11238034 +Node: Extension New Mechanism Goals1238091 +Ref: Extension New Mechanism Goals-Footnote-11241455 +Node: Extension Other Design Decisions1241644 +Node: Extension Future Growth1243757 +Node: Old Extension Mechanism1244593 +Node: Notes summary1246356 +Node: Basic Concepts1247538 +Node: Basic High Level1248219 +Ref: figure-general-flow1248501 +Ref: figure-process-flow1249186 +Ref: Basic High Level-Footnote-11252487 +Node: Basic Data Typing1252672 +Node: Glossary1256000 +Node: Copying1287838 +Node: GNU Free Documentation License1325381 +Node: Index1350501 End Tag Table diff --git a/doc/gawk.texi b/doc/gawk.texi index 2817777d..97f44bfc 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -11025,6 +11025,69 @@ eight-bit ASCII characters, including ASCII @sc{nul} (character code zero). Other @command{awk} implementations may have difficulty with some character codes. +Some languages allow you to continue long strings across +multiple lines by ending the line with a backslash. For example in C: + +@example +#include <stdio.h> + +int main() +@{ + printf "hello, \ +world\n"); + return 0; +@} +@end example + +@noindent +In such a case, the C compiler removes both the backslash and the newline, +producing a string as if it had been typed @samp{"hello, world\n"}. +This is useful when a single string needs to contain a large amount of text. + +The POSIX standard says explicitly that newlines are not allowed inside string +constants. And indeed, all @command{awk} implementations report an error +if you try to do so. For example: + +@example +$ @kbd{gawk 'BEGIN @{ print "hello, } +> @kbd{world" @}'} +@print{} gawk: cmd. line:1: BEGIN { print "hello, +@print{} gawk: cmd. line:1: ^ unterminated string +@print{} gawk: cmd. line:1: BEGIN { print "hello, +@print{} gawk: cmd. line:1: ^ syntax error +@end example + +@cindex dark corner, string continuation +@cindex strings, continuation across lines +@cindex differences in @command{awk} and @command{gawk}, strings +Although POSIX doesn't define what happens if you use an escaped +newline, as in the previous C example, all known versions of +@command{awk} allow you to do so. Unfortunately, what each one +does with such a string varies. @value{DARKCORNER} @command{gawk}, +@command{mawk}, and the OpenSolaris POSIX @command{awk} +(@pxref{Other Versions}) elide the backslash and newline, as in C: + +@example +$ @kbd{gawk 'BEGIN @{ print "hello, \} +> @kbd{world" @}'} +@print{} hello, world +@end example + +Brian Kernighan's @command{awk} and Busybox @command{awk} +remove the backslash but leave the newline +intact, as part of the string: + +@example +$ @kbd{nawk 'BEGIN @{ print "hello, \} +> @kbd{world" @}'} +@print{} hello, +@print{} world +@end example + +In POSIX mode (@pxref{Options}), @command{gawk} does not +allow escaped newlines. Otherwise, it behaves as +just described. + @node Nondecimal-numbers @subsubsection Octal and Hexadecimal Numbers @cindex octal numbers @@ -32700,9 +32763,9 @@ $ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'} Thus, @samp{+nan} and @samp{+NaN} are the same. @end itemize -Besides handling imput, @command{gawk} also needs to print ``correct'' values on -output when a value is either NaN or infinity. Starting with version 4.2.2, -for such values @command{gawk} prints one of the four strings +Besides handling input, @command{gawk} also needs to print ``correct'' values on +output when a value is either NaN or infinity. Starting with @value{PVERSION} +4.2.2, for such values @command{gawk} prints one of the four strings just described: @samp{+inf}, @samp{-inf}, @samp{+nan}, or @samp{-nan}. Similarly, in POSIX mode, @command{gawk} prints the result of the system's C @code{printf()} function using the @code{%g} format string diff --git a/doc/gawktexi.in b/doc/gawktexi.in index 29befae8..430f8312 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -10511,6 +10511,69 @@ eight-bit ASCII characters, including ASCII @sc{nul} (character code zero). Other @command{awk} implementations may have difficulty with some character codes. +Some languages allow you to continue long strings across +multiple lines by ending the line with a backslash. For example in C: + +@example +#include <stdio.h> + +int main() +@{ + printf "hello, \ +world\n"); + return 0; +@} +@end example + +@noindent +In such a case, the C compiler removes both the backslash and the newline, +producing a string as if it had been typed @samp{"hello, world\n"}. +This is useful when a single string needs to contain a large amount of text. + +The POSIX standard says explicitly that newlines are not allowed inside string +constants. And indeed, all @command{awk} implementations report an error +if you try to do so. For example: + +@example +$ @kbd{gawk 'BEGIN @{ print "hello, } +> @kbd{world" @}'} +@print{} gawk: cmd. line:1: BEGIN { print "hello, +@print{} gawk: cmd. line:1: ^ unterminated string +@print{} gawk: cmd. line:1: BEGIN { print "hello, +@print{} gawk: cmd. line:1: ^ syntax error +@end example + +@cindex dark corner, string continuation +@cindex strings, continuation across lines +@cindex differences in @command{awk} and @command{gawk}, strings +Although POSIX doesn't define what happens if you use an escaped +newline, as in the previous C example, all known versions of +@command{awk} allow you to do so. Unfortunately, what each one +does with such a string varies. @value{DARKCORNER} @command{gawk}, +@command{mawk}, and the OpenSolaris POSIX @command{awk} +(@pxref{Other Versions}) elide the backslash and newline, as in C: + +@example +$ @kbd{gawk 'BEGIN @{ print "hello, \} +> @kbd{world" @}'} +@print{} hello, world +@end example + +Brian Kernighan's @command{awk} and Busybox @command{awk} +remove the backslash but leave the newline +intact, as part of the string: + +@example +$ @kbd{nawk 'BEGIN @{ print "hello, \} +> @kbd{world" @}'} +@print{} hello, +@print{} world +@end example + +In POSIX mode (@pxref{Options}), @command{gawk} does not +allow escaped newlines. Otherwise, it behaves as +just described. + @node Nondecimal-numbers @subsubsection Octal and Hexadecimal Numbers @cindex octal numbers @@ -31674,9 +31737,9 @@ $ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'} Thus, @samp{+nan} and @samp{+NaN} are the same. @end itemize -Besides handling imput, @command{gawk} also needs to print ``correct'' values on -output when a value is either NaN or infinity. Starting with version 4.2.2, -for such values @command{gawk} prints one of the four strings +Besides handling input, @command{gawk} also needs to print ``correct'' values on +output when a value is either NaN or infinity. Starting with @value{PVERSION} +4.2.2, for such values @command{gawk} prints one of the four strings just described: @samp{+inf}, @samp{-inf}, @samp{+nan}, or @samp{-nan}. Similarly, in POSIX mode, @command{gawk} prints the result of the system's C @code{printf()} function using the @code{%g} format string diff --git a/doc/gawkworkflow.texi b/doc/gawkworkflow.texi index 2b971395..90b3c78c 100644 --- a/doc/gawkworkflow.texi +++ b/doc/gawkworkflow.texi @@ -28,10 +28,10 @@ @c applies to and all the info about who's publishing this edition @c These apply across the board. -@set UPDATE-MONTH November, 2017 +@set UPDATE-MONTH July, 2018 @set TITLE Participating in @command{gawk} Development -@set EDITION 0.7 +@set EDITION 0.71 @iftex @set DOCUMENT booklet @@ -903,8 +903,8 @@ the @command{gawk} maintainer recommends that you use are: @cindex configuration setting, @code{push.default} @cindex configuration setting, @code{pager.status} @example -$ @kbd{git config --global push.default=simple} @ii{Only push current branch} -$ @kbd{git config --global pager.status=true} @ii{Use pager for output of} git status +$ @kbd{git config --global push.default simple} @ii{Only push current branch} +$ @kbd{git config --global pager.status true} @ii{Use pager for output of} git status @end example @cindex @file{.gitconfig} file diff --git a/interpret.h b/interpret.h index 8408a532..fed0078c 100644 --- a/interpret.h +++ b/interpret.h @@ -46,6 +46,7 @@ unfield(NODE **l, NODE **r) (*l) = dupnode(*r); DEREF(*r); } + force_string(*l); } #define UNFIELD(l, r) unfield(& (l), & (r)) @@ -1165,11 +1165,18 @@ arg_assign(char *arg, bool initing) fatal(_("cannot use function `%s' as variable name"), arg); } + // POSIX disallows any newlines inside strings + // The scanner handles that for program files. + // We have to check here for strings passed to -v. + if (do_posix && strchr(cp, '\n') != NULL) + fatal(_("POSIX does not allow physical newlines in string values")); + /* * BWK awk expands escapes inside assignments. * This makes sense, so we do it too. + * In addition, remove \-<newline> as in scanning. */ - it = make_str_node(cp, strlen(cp), SCAN); + it = make_str_node(cp, strlen(cp), SCAN | ELIDE_BACK_NL); it->flags |= USER_INPUT; #ifdef LC_NUMERIC /* @@ -450,7 +450,9 @@ make_str_node(const char *s, size_t len, int flags) c = parse_escape(&pf); if (c < 0) { if (do_lint) - lintwarn(_("backslash at end of string")); + lintwarn(_("backslash string continuation is not portable")); + if ((flags & ELIDE_BACK_NL) != 0) + continue; c = '\\'; } *ptm++ = c; @@ -100,6 +100,12 @@ make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal) } } + const char *ok_to_escape; + if (do_traditional) + ok_to_escape = "()|*+?.^$\\[]/-"; + else + ok_to_escape = "<>`'BywWsS{}()|*+?.^$\\[]/-"; + /* We skip multibyte character, since it must not be a special character. */ if ((gawk_mb_cur_max == 1 || ! is_multibyte) && @@ -141,6 +147,14 @@ make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal) case '9': /* a\9b not valid */ *dest++ = c; src++; + { + static bool warned[2]; + + if (! warned[c - '8']) { + warning(_("regexp escape sequence `\\%c' treated as plain `%c'"), c, c); + warned[c - '8'] = true; + } + } break; case 'y': /* normally \b */ /* gnu regex op */ @@ -152,6 +166,14 @@ make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal) } /* else, fall through */ default: + if (strchr(ok_to_escape, c) == NULL) { + static bool warned[256]; + + if (! warned[c & 0xFF]) { + warning(_("regexp escape sequence `\\%c' is not a known regexp operator"), c); + warned[c & 0xFF] = true; + } + } *dest++ = '\\'; *dest++ = (char) c; src++; diff --git a/test/ChangeLog b/test/ChangeLog index 2d85c9a9..2af89e66 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,18 @@ +2018-07-31 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (EXTRA_DIST): Add assignnumfield files. + * assignnumfield.awk, assignnumfield.in, assignnumfield.ok: New files. + +2018-07-31 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (EXTRA_DIST): Add arraysort2 files. + * arraysort2.awk, arraysort2.ok: New files. + +2018-07-27 Arnold D. Robbins <arnold@skeeve.com> + + * back89.ok, funstack.ok, gsubtst5.ok: Update after code changes. + * lintwarn.ok: Ditto. + 2018-07-13 Arnold D. Robbins <arnold@skeeve.com> * fmtspcl.awk, fmtspcl.tok, numrange.ok: Revised after code changes diff --git a/test/Makefile.am b/test/Makefile.am index 4ab96409..774424f7 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -74,6 +74,8 @@ EXTRA_DIST = \ arrayref.ok \ arraysort.awk \ arraysort.ok \ + arraysort2.awk \ + arraysort2.ok \ arrdbg.awk \ arrymem1.awk \ arrymem1.ok \ @@ -119,6 +121,9 @@ EXTRA_DIST = \ asort.ok \ asorti.awk \ asorti.ok \ + assignnumfield.awk \ + assignnumfield.in \ + assignnumfield.ok \ awkpath.ok \ back89.awk \ back89.in \ @@ -1233,7 +1238,7 @@ BASIC_TESTS = \ addcomma anchgsub anchor argarray arrayind1 arrayind2 arrayind3 arrayparm \ arrayprm2 arrayprm3 arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 \ arynasty arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \ - aryprm8 aryprm9 arysubnm aryunasgn asgext awkpath \ + aryprm8 aryprm9 arysubnm aryunasgn asgext awkpath assignnumfield \ back89 backgsub badassign1 badbuild \ callparam childin clobber closebad clsflnam compare compare2 \ concat1 concat2 concat3 concat4 concat5 convfmt \ @@ -1275,7 +1280,7 @@ UNIX_TESTS = \ space strftlng GAWK_EXT_TESTS = \ - aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \ + aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort arraysort2 \ backw badargs beginfile1 beginfile2 binmode1 \ charasbytes colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 \ clos1way6 crlf \ diff --git a/test/Makefile.in b/test/Makefile.in index 5b34a5ad..69b86d07 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -332,6 +332,8 @@ EXTRA_DIST = \ arrayref.ok \ arraysort.awk \ arraysort.ok \ + arraysort2.awk \ + arraysort2.ok \ arrdbg.awk \ arrymem1.awk \ arrymem1.ok \ @@ -377,6 +379,9 @@ EXTRA_DIST = \ asort.ok \ asorti.awk \ asorti.ok \ + assignnumfield.awk \ + assignnumfield.in \ + assignnumfield.ok \ awkpath.ok \ back89.awk \ back89.in \ @@ -1491,7 +1496,7 @@ BASIC_TESTS = \ addcomma anchgsub anchor argarray arrayind1 arrayind2 arrayind3 arrayparm \ arrayprm2 arrayprm3 arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 \ arynasty arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \ - aryprm8 aryprm9 arysubnm aryunasgn asgext awkpath \ + aryprm8 aryprm9 arysubnm aryunasgn asgext awkpath assignnumfield \ back89 backgsub badassign1 badbuild \ callparam childin clobber closebad clsflnam compare compare2 \ concat1 concat2 concat3 concat4 concat5 convfmt \ @@ -1533,7 +1538,7 @@ UNIX_TESTS = \ space strftlng GAWK_EXT_TESTS = \ - aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \ + aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort arraysort2 \ backw badargs beginfile1 beginfile2 binmode1 \ charasbytes colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 \ clos1way6 crlf \ @@ -2785,6 +2790,11 @@ asgext: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +assignnumfield: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + back89: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @@ -3904,6 +3914,11 @@ arraysort: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +arraysort2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + backw: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index 5e5fa5ee..eb7c4651 100644 --- a/test/Maketests +++ b/test/Maketests @@ -140,6 +140,11 @@ asgext: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +assignnumfield: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + back89: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @@ -1259,6 +1264,11 @@ arraysort: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +arraysort2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + backw: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/arraysort2.awk b/test/arraysort2.awk new file mode 100644 index 00000000..e52d2a7c --- /dev/null +++ b/test/arraysort2.awk @@ -0,0 +1,34 @@ +# This should no longer core dump ... 7/31/2018 +function init(b, a, i) +{ + a[1] = "aardvark" + a[2] = "animal" + a[3] = "zebra" + a[4] = "zoo" + a[5] = "Iguana" + a[6] = "Alligator" + a[7] =a[8] = "people" + for (i in a) + b[IGNORECASE][i] = a[i] +} + +BEGIN { + + for (IGNORECASE = 0; IGNORECASE < 2; IGNORECASE++) { + init(b) + + n = asort(b[IGNORECASE]) + + for (i = 1; i <= n; i++) + printf("b[%d][%d] = \"%s\"\n", IGNORECASE, i, b[IGi]) + + print "====" + } + + IGNORECASE = 1 + init(b) + b[2][1] = "" + n = asort(b[1], b[2]) + for (i = 1; i <= n; i++) + printf("b[2][%d] = \"%s\"\n", i, b[2][i]) +} diff --git a/test/arraysort2.ok b/test/arraysort2.ok new file mode 100644 index 00000000..8fda0bfd --- /dev/null +++ b/test/arraysort2.ok @@ -0,0 +1,26 @@ +b[0][1] = "" +b[0][2] = "" +b[0][3] = "" +b[0][4] = "" +b[0][5] = "" +b[0][6] = "" +b[0][7] = "" +b[0][8] = "" +==== +b[1][1] = "" +b[1][2] = "" +b[1][3] = "" +b[1][4] = "" +b[1][5] = "" +b[1][6] = "" +b[1][7] = "" +b[1][8] = "" +==== +b[2][1] = "aardvark" +b[2][2] = "Alligator" +b[2][3] = "animal" +b[2][4] = "Iguana" +b[2][5] = "people" +b[2][6] = "people" +b[2][7] = "zebra" +b[2][8] = "zoo" diff --git a/test/assignnumfield.awk b/test/assignnumfield.awk new file mode 100644 index 00000000..3a056cb0 --- /dev/null +++ b/test/assignnumfield.awk @@ -0,0 +1 @@ +{$0 = ++i} 1 diff --git a/test/assignnumfield.in b/test/assignnumfield.in new file mode 100644 index 00000000..b82c4b2d --- /dev/null +++ b/test/assignnumfield.in @@ -0,0 +1,5 @@ +a b c +a b c +a b c +a b c +a b c diff --git a/test/assignnumfield.ok b/test/assignnumfield.ok new file mode 100644 index 00000000..8a1218a1 --- /dev/null +++ b/test/assignnumfield.ok @@ -0,0 +1,5 @@ +1 +2 +3 +4 +5 diff --git a/test/back89.ok b/test/back89.ok index e9ea4d5f..8eebce47 100644 --- a/test/back89.ok +++ b/test/back89.ok @@ -1 +1,2 @@ +gawk: back89.awk:1: warning: regexp escape sequence `\8' treated as plain `8' a8b diff --git a/test/funstack.ok b/test/funstack.ok index e69de29b..04030d3b 100644 --- a/test/funstack.ok +++ b/test/funstack.ok @@ -0,0 +1,10 @@ +gawk: funstack.awk:129: warning: regexp escape sequence `\"' is not a known regexp operator +gawk: funstack.awk:381: warning: regexp escape sequence `\e' is not a known regexp operator +gawk: funstack.awk:386: warning: regexp escape sequence `\i' is not a known regexp operator +gawk: funstack.awk:395: warning: regexp escape sequence `\o' is not a known regexp operator +gawk: funstack.awk:402: warning: regexp escape sequence `\u' is not a known regexp operator +gawk: funstack.awk:412: warning: regexp escape sequence `\A' is not a known regexp operator +gawk: funstack.awk:427: warning: regexp escape sequence `\I' is not a known regexp operator +gawk: funstack.awk:436: warning: regexp escape sequence `\O' is not a known regexp operator +gawk: funstack.awk:443: warning: regexp escape sequence `\U' is not a known regexp operator +gawk: funstack.awk:952: warning: regexp escape sequence `\&' is not a known regexp operator diff --git a/test/gsubtst5.ok b/test/gsubtst5.ok index b038c8af..66488fd1 100644 --- a/test/gsubtst5.ok +++ b/test/gsubtst5.ok @@ -1 +1,5 @@ +gawk: gsubtst5.awk:95: warning: regexp escape sequence `\ ' is not a known regexp operator +gawk: gsubtst5.awk:95: warning: regexp escape sequence `\"' is not a known regexp operator +gawk: gsubtst5.awk:95: warning: regexp escape sequence `\@' is not a known regexp operator +gawk: gsubtst5.awk:95: warning: regexp escape sequence `\,' is not a known regexp operator ThisIsaTitleMyTitle diff --git a/test/lintwarn.awk b/test/lintwarn.awk index cea76bbc..d430a2b4 100644 --- a/test/lintwarn.awk +++ b/test/lintwarn.awk @@ -36,3 +36,8 @@ function zz(aa, aa) return aa } @include "" +BEGIN { + print "foo" > "foo" 1 # should warn + print "foo" > ("foo" 1) # should not warn + system("rm -f foo1 foo2") +} diff --git a/test/lintwarn.ok b/test/lintwarn.ok index bc5226e6..d0993ea7 100644 --- a/test/lintwarn.ok +++ b/test/lintwarn.ok @@ -33,6 +33,7 @@ gawk: lintwarn.awk:32: warning: non-redirected `getline' undefined inside END ac gawk: lintwarn.awk:34: error: function `zz': parameter #2, `aa', duplicates parameter #1 gawk: lintwarn.awk:38: warning: `include' is a gawk extension gawk: lintwarn.awk:38: warning: empty filename after @include +gawk: lintwarn.awk:41: warning: concatenation as I/O `>' redirection target is ambiguous gawk: warning: function `f' called but never defined gawk: warning: function `zz' defined but never called directly EXIT CODE: 1 |