diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2011-02-16 21:17:02 +0200 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2011-02-16 21:17:02 +0200 |
commit | 478829a0f22753b6aa6e8a2227167370a5cf5a37 (patch) | |
tree | c12044c1f5e541c6290c88292f1194cd199f6098 | |
parent | db17aa722cd00f3cf5b7660c3badd3b4b29a648c (diff) | |
download | egawk-478829a0f22753b6aa6e8a2227167370a5cf5a37.tar.gz egawk-478829a0f22753b6aa6e8a2227167370a5cf5a37.tar.bz2 egawk-478829a0f22753b6aa6e8a2227167370a5cf5a37.zip |
Fix line numbers in lint warnings.
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | Checklist | 1 | ||||
-rw-r--r-- | awk.h | 1 | ||||
-rw-r--r-- | awkgram.c | 699 | ||||
-rw-r--r-- | awkgram.y | 327 | ||||
-rw-r--r-- | msg.c | 3 | ||||
-rw-r--r-- | pc/Makefile.tst | 8 | ||||
-rw-r--r-- | test/ChangeLog | 7 | ||||
-rw-r--r-- | test/Makefile.am | 6 | ||||
-rw-r--r-- | test/Makefile.in | 12 | ||||
-rw-r--r-- | test/Maketests | 5 | ||||
-rw-r--r-- | test/funsmnam.ok | 2 | ||||
-rw-r--r-- | test/lintwarn.awk | 38 | ||||
-rw-r--r-- | test/lintwarn.ok | 39 | ||||
-rw-r--r-- | test/noeffect.ok | 2 | ||||
-rw-r--r-- | test/paramdup.ok | 4 | ||||
-rw-r--r-- | test/paramres.ok | 2 | ||||
-rw-r--r-- | vms/vmstest.com | 11 |
18 files changed, 741 insertions, 446 deletions
@@ -1,3 +1,23 @@ +Wed Feb 16 07:12:50 2011 John Haque <j.eh@mchsi.com> + + Fix line numbers in the lint, warning and error messages issued + by the parser. + + * awkgram.y (lintwarn_ln, warning_ln, error_ln): New local versions, + each accepts an additional line number argument. + (print_included_from): New function to seperate 'Included from ..' + message from yyerror. Use it in yyerror, and in the new functions. + (grammar): Use the local versions for messages. + (add_srcfile, include_source, dup_parms, func_install, param_sanity, + mk_binary, add_lint): Ditto. + (dup_params, include_source): Adjust arguments to pass line number. + * awk.h: New definition ATTRIBUTE_PRINTF_2. + + * awkgram.y (yylex): New variable warntab. Use it to issue only one + warning for the same non-standard special token in source. + (parse_program): Avoid spurious warnings. Don't call check_funcs if + yyparse aborts prematurely. + Mon Feb 14 08:03:41 2011 John Haque <j.eh@mchsi.com> * awkgram.y (regexp): Don't use tokstart in lint warning, it isn't @@ -27,6 +27,7 @@ doc/gawk.texi is up to date doc/gawkinet.texi is up to date doc/gawk.1 is up to date doc/awkcard.in is up to date +test/Makefile.am: order and prettify lists of tests Testing on make clean @@ -229,6 +229,7 @@ extern double gawk_strtod(); #ifndef ATTRIBUTE_PRINTF #define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) #define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) +#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) #endif /* ATTRIBUTE_PRINTF */ /* We use __extension__ in some places to suppress -pedantic warnings @@ -80,6 +80,9 @@ #endif static void yyerror(const char *m, ...) ATTRIBUTE_PRINTF_1; +static void error_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2; +static void lintwarn_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2; +static void warning_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2; static char *get_src_buf(void); static int yylex(void); int yyparse(void); @@ -89,7 +92,7 @@ static void pop_params(NODE *params); static NODE *make_param(char *pname); static NODE *mk_rexp(INSTRUCTION *exp); static void append_param(char *pname); -static int dup_parms(NODE *func); +static int dup_parms(INSTRUCTION *fp, NODE *func); static void param_sanity(INSTRUCTION *arglist); static int parms_shadow(INSTRUCTION *pc, int *shadow); static int isnoeffect(OPCODE type); @@ -97,7 +100,7 @@ static INSTRUCTION *make_assignable(INSTRUCTION *ip); static void dumpintlstr(const char *str, size_t len); static void dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2); static int isarray(NODE *n); -static int include_source(char *src); +static int include_source(INSTRUCTION *file); static void next_sourcefile(void); static char *tokexpand(void); @@ -219,7 +222,7 @@ static char builtin_func[] = "@builtin"; /* Line 189 of yacc.c */ -#line 223 "awkgram.c" +#line 226 "awkgram.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -365,7 +368,7 @@ typedef int YYSTYPE; /* Line 264 of yacc.c */ -#line 369 "awkgram.c" +#line 372 "awkgram.c" #ifdef short # undef short @@ -723,25 +726,25 @@ static const yytype_int16 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 215, 215, 217, 222, 223, 227, 239, 243, 254, - 262, 270, 279, 281, 287, 288, 290, 316, 326, 336, - 342, 351, 361, 363, 365, 376, 381, 382, 387, 386, - 416, 415, 446, 448, 453, 454, 467, 472, 473, 477, - 479, 481, 488, 581, 623, 665, 780, 787, 794, 804, - 813, 822, 829, 854, 869, 868, 880, 892, 892, 988, - 988, 1016, 1042, 1048, 1049, 1055, 1056, 1063, 1068, 1080, - 1094, 1096, 1102, 1107, 1109, 1117, 1119, 1128, 1129, 1137, - 1142, 1142, 1153, 1157, 1165, 1166, 1169, 1171, 1176, 1177, - 1184, 1186, 1190, 1196, 1203, 1205, 1207, 1214, 1215, 1221, - 1222, 1227, 1229, 1234, 1236, 1238, 1240, 1246, 1252, 1254, - 1256, 1271, 1280, 1286, 1288, 1293, 1295, 1297, 1305, 1307, - 1312, 1314, 1319, 1321, 1323, 1376, 1378, 1380, 1382, 1384, - 1386, 1388, 1390, 1411, 1416, 1421, 1444, 1450, 1452, 1454, - 1456, 1458, 1460, 1465, 1469, 1500, 1502, 1508, 1514, 1526, - 1527, 1528, 1533, 1538, 1542, 1546, 1558, 1571, 1576, 1612, - 1630, 1631, 1637, 1638, 1643, 1645, 1652, 1669, 1686, 1688, - 1695, 1700, 1708, 1722, 1735, 1744, 1748, 1752, 1756, 1760, - 1764, 1767, 1769, 1773, 1777, 1781 + 0, 218, 218, 220, 225, 226, 230, 242, 246, 257, + 265, 273, 281, 283, 289, 290, 292, 318, 329, 340, + 346, 355, 365, 367, 369, 380, 385, 386, 391, 390, + 420, 419, 452, 454, 459, 460, 473, 478, 479, 483, + 485, 487, 494, 584, 626, 668, 783, 790, 797, 807, + 816, 825, 833, 846, 861, 860, 872, 884, 884, 980, + 980, 1005, 1028, 1034, 1035, 1041, 1042, 1049, 1054, 1066, + 1080, 1082, 1088, 1093, 1095, 1103, 1105, 1114, 1115, 1123, + 1128, 1128, 1139, 1143, 1151, 1152, 1155, 1157, 1162, 1163, + 1170, 1172, 1176, 1182, 1189, 1191, 1193, 1200, 1201, 1207, + 1208, 1213, 1215, 1220, 1222, 1224, 1226, 1232, 1239, 1241, + 1243, 1259, 1269, 1276, 1278, 1283, 1285, 1287, 1295, 1297, + 1302, 1304, 1309, 1311, 1313, 1366, 1368, 1370, 1372, 1374, + 1376, 1378, 1380, 1403, 1408, 1413, 1438, 1444, 1446, 1448, + 1450, 1452, 1454, 1459, 1463, 1494, 1496, 1502, 1508, 1521, + 1522, 1523, 1528, 1533, 1537, 1541, 1553, 1566, 1571, 1607, + 1625, 1626, 1632, 1633, 1638, 1640, 1647, 1664, 1681, 1683, + 1690, 1695, 1703, 1717, 1730, 1739, 1743, 1747, 1751, 1755, + 1759, 1762, 1764, 1768, 1772, 1776 }; #endif @@ -2039,7 +2042,7 @@ yyreduce: case 3: /* Line 1464 of yacc.c */ -#line 218 "awkgram.y" +#line 221 "awkgram.y" { rule = 0; yyerrok; @@ -2049,7 +2052,7 @@ yyreduce: case 5: /* Line 1464 of yacc.c */ -#line 224 "awkgram.y" +#line 227 "awkgram.y" { next_sourcefile(); } @@ -2058,7 +2061,7 @@ yyreduce: case 6: /* Line 1464 of yacc.c */ -#line 228 "awkgram.y" +#line 231 "awkgram.y" { rule = 0; /* @@ -2072,7 +2075,7 @@ yyreduce: case 7: /* Line 1464 of yacc.c */ -#line 240 "awkgram.y" +#line 243 "awkgram.y" { (void) append_rule((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); } @@ -2081,7 +2084,7 @@ yyreduce: case 8: /* Line 1464 of yacc.c */ -#line 244 "awkgram.y" +#line 247 "awkgram.y" { if (rule != Rule) { msg(_("%s blocks must have an action part"), ruletab[rule]); @@ -2097,7 +2100,7 @@ yyreduce: case 9: /* Line 1464 of yacc.c */ -#line 255 "awkgram.y" +#line 258 "awkgram.y" { can_return = FALSE; if ((yyvsp[(1) - (2)]) && func_install((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])) < 0) @@ -2110,7 +2113,7 @@ yyreduce: case 10: /* Line 1464 of yacc.c */ -#line 263 "awkgram.y" +#line 266 "awkgram.y" { want_source = FALSE; yyerrok; @@ -2120,12 +2123,11 @@ yyreduce: case 11: /* Line 1464 of yacc.c */ -#line 271 "awkgram.y" +#line 274 "awkgram.y" { - char *src = (yyvsp[(1) - (1)])->lextok; - if (include_source(src) < 0) + if (include_source((yyvsp[(1) - (1)])) < 0) YYABORT; - efree(src); + efree((yyvsp[(1) - (1)])->lextok); bcfree((yyvsp[(1) - (1)])); (yyval) = NULL; } @@ -2134,35 +2136,35 @@ yyreduce: case 12: /* Line 1464 of yacc.c */ -#line 280 "awkgram.y" +#line 282 "awkgram.y" { (yyval) = NULL; } break; case 13: /* Line 1464 of yacc.c */ -#line 282 "awkgram.y" +#line 284 "awkgram.y" { (yyval) = NULL; } break; case 14: /* Line 1464 of yacc.c */ -#line 287 "awkgram.y" +#line 289 "awkgram.y" { (yyval) = NULL; rule = Rule; } break; case 15: /* Line 1464 of yacc.c */ -#line 289 "awkgram.y" +#line 291 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); rule = Rule; } break; case 16: /* Line 1464 of yacc.c */ -#line 291 "awkgram.y" +#line 293 "awkgram.y" { INSTRUCTION *tp; @@ -2193,11 +2195,12 @@ yyreduce: case 17: /* Line 1464 of yacc.c */ -#line 317 "awkgram.y" +#line 319 "awkgram.y" { static int begin_seen = 0; if (do_lint_old && ++begin_seen == 2) - warning(_("old awk does not support multiple `BEGIN' or `END' rules")); + warning_ln((yyvsp[(1) - (1)])->source_line, + _("old awk does not support multiple `BEGIN' or `END' rules")); (yyvsp[(1) - (1)])->in_rule = rule = BEGIN; (yyvsp[(1) - (1)])->source_file = source; @@ -2208,11 +2211,12 @@ yyreduce: case 18: /* Line 1464 of yacc.c */ -#line 327 "awkgram.y" +#line 330 "awkgram.y" { static int end_seen = 0; if (do_lint_old && ++end_seen == 2) - warning(_("old awk does not support multiple `BEGIN' or `END' rules")); + warning_ln((yyvsp[(1) - (1)])->source_line, + _("old awk does not support multiple `BEGIN' or `END' rules")); (yyvsp[(1) - (1)])->in_rule = rule = END; (yyvsp[(1) - (1)])->source_file = source; @@ -2223,7 +2227,7 @@ yyreduce: case 19: /* Line 1464 of yacc.c */ -#line 337 "awkgram.y" +#line 341 "awkgram.y" { (yyvsp[(1) - (1)])->in_rule = rule = BEGINFILE; (yyvsp[(1) - (1)])->source_file = source; @@ -2234,7 +2238,7 @@ yyreduce: case 20: /* Line 1464 of yacc.c */ -#line 343 "awkgram.y" +#line 347 "awkgram.y" { (yyvsp[(1) - (1)])->in_rule = rule = ENDFILE; (yyvsp[(1) - (1)])->source_file = source; @@ -2245,7 +2249,7 @@ yyreduce: case 21: /* Line 1464 of yacc.c */ -#line 352 "awkgram.y" +#line 356 "awkgram.y" { if ((yyvsp[(2) - (5)]) == NULL) (yyval) = list_create(instruction(Op_no_op)); @@ -2257,21 +2261,21 @@ yyreduce: case 22: /* Line 1464 of yacc.c */ -#line 362 "awkgram.y" +#line 366 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 23: /* Line 1464 of yacc.c */ -#line 364 "awkgram.y" +#line 368 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 24: /* Line 1464 of yacc.c */ -#line 366 "awkgram.y" +#line 370 "awkgram.y" { yyerror(_("`%s' is a built-in function, it cannot be redefined"), tokstart); @@ -2287,14 +2291,14 @@ yyreduce: case 25: /* Line 1464 of yacc.c */ -#line 377 "awkgram.y" +#line 381 "awkgram.y" { (yyval) = (yyvsp[(2) - (2)]); } break; case 28: /* Line 1464 of yacc.c */ -#line 387 "awkgram.y" +#line 391 "awkgram.y" { param_counter = 0; func_params = NULL; @@ -2304,7 +2308,7 @@ yyreduce: case 29: /* Line 1464 of yacc.c */ -#line 392 "awkgram.y" +#line 396 "awkgram.y" { NODE *t; @@ -2318,7 +2322,7 @@ yyreduce: (yyval) = (yyvsp[(1) - (7)]); can_return = TRUE; /* check for duplicate parameter names */ - if (dup_parms(t)) + if (dup_parms((yyvsp[(1) - (7)]), t)) errcount++; } break; @@ -2326,14 +2330,14 @@ yyreduce: case 30: /* Line 1464 of yacc.c */ -#line 416 "awkgram.y" +#line 420 "awkgram.y" { ++want_regexp; } break; case 31: /* Line 1464 of yacc.c */ -#line 418 "awkgram.y" +#line 422 "awkgram.y" { NODE *n, *exp; char *re; @@ -2343,10 +2347,12 @@ yyreduce: len = strlen(re); if (do_lint) { if (len == 0) - lintwarn(_("regexp constant `//' looks like a C++ comment, but is not")); + lintwarn_ln((yyvsp[(3) - (3)])->source_line, + _("regexp constant `//' looks like a C++ comment, but is not")); else if ((re)[0] == '*' && (re)[len-1] == '*') /* possible C comment */ - lintwarn(_("regexp constant `/%s/' looks like a C comment, but is not"), re); + lintwarn_ln((yyvsp[(3) - (3)])->source_line, + _("regexp constant `/%s/' looks like a C comment, but is not"), re); } exp = make_str_node(re, len, ALREADY_MALLOCED); @@ -2364,21 +2370,21 @@ yyreduce: case 32: /* Line 1464 of yacc.c */ -#line 447 "awkgram.y" +#line 453 "awkgram.y" { bcfree((yyvsp[(1) - (1)])); } break; case 34: /* Line 1464 of yacc.c */ -#line 453 "awkgram.y" +#line 459 "awkgram.y" { (yyval) = NULL; } break; case 35: /* Line 1464 of yacc.c */ -#line 455 "awkgram.y" +#line 461 "awkgram.y" { if ((yyvsp[(2) - (2)]) == NULL) (yyval) = (yyvsp[(1) - (2)]); @@ -2396,28 +2402,28 @@ yyreduce: case 36: /* Line 1464 of yacc.c */ -#line 468 "awkgram.y" +#line 474 "awkgram.y" { (yyval) = NULL; } break; case 39: /* Line 1464 of yacc.c */ -#line 478 "awkgram.y" +#line 484 "awkgram.y" { (yyval) = NULL; } break; case 40: /* Line 1464 of yacc.c */ -#line 480 "awkgram.y" +#line 486 "awkgram.y" { (yyval) = (yyvsp[(2) - (3)]); } break; case 41: /* Line 1464 of yacc.c */ -#line 482 "awkgram.y" +#line 488 "awkgram.y" { if (do_profiling) (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count)); @@ -2429,7 +2435,7 @@ yyreduce: case 42: /* Line 1464 of yacc.c */ -#line 489 "awkgram.y" +#line 495 "awkgram.y" { INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt; INSTRUCTION *ip, *nextc, *tbreak; @@ -2461,11 +2467,9 @@ yyreduce: char *caseval; caseval = force_string(caseexp->memory)->stptr; for (i = 0; i < case_count; i++) { - if (strcmp(caseval, case_values[i]) == 0) { - /* can't use yyerror, since may have overshot the source line */ - errcount++; - error(_("duplicate case values in switch body: %s"), caseval); - } + if (strcmp(caseval, case_values[i]) == 0) + error_ln(curr->source_line, + _("duplicate case values in switch body: %s"), caseval); } if (case_values == NULL) @@ -2484,11 +2488,10 @@ yyreduce: (void) list_prepend(cexp, curr); (void) list_prepend(cexp, caseexp); } else { - if (dflt->target_jmp != tbreak) { - /* can't use yyerror, since may have overshot the source line */ - errcount++; - error(_("duplicate `default' detected in switch body")); - } else + if (dflt->target_jmp != tbreak) + error_ln(curr->source_line, + _("duplicate `default' detected in switch body")); + else dflt->target_jmp = casestmt->nexti; if (do_profiling) { @@ -2527,7 +2530,7 @@ yyreduce: case 43: /* Line 1464 of yacc.c */ -#line 582 "awkgram.y" +#line 585 "awkgram.y" { /* * ----------------- @@ -2574,7 +2577,7 @@ yyreduce: case 44: /* Line 1464 of yacc.c */ -#line 624 "awkgram.y" +#line 627 "awkgram.y" { /* * ----------------- @@ -2621,7 +2624,7 @@ yyreduce: case 45: /* Line 1464 of yacc.c */ -#line 666 "awkgram.y" +#line 669 "awkgram.y" { INSTRUCTION *ip; char *var_name = (yyvsp[(3) - (8)])->lextok; @@ -2741,7 +2744,7 @@ regular_loop: case 46: /* Line 1464 of yacc.c */ -#line 781 "awkgram.y" +#line 784 "awkgram.y" { (yyval) = mk_for_loop((yyvsp[(1) - (12)]), (yyvsp[(3) - (12)]), (yyvsp[(6) - (12)]), (yyvsp[(9) - (12)]), (yyvsp[(12) - (12)])); @@ -2753,7 +2756,7 @@ regular_loop: case 47: /* Line 1464 of yacc.c */ -#line 788 "awkgram.y" +#line 791 "awkgram.y" { (yyval) = mk_for_loop((yyvsp[(1) - (11)]), (yyvsp[(3) - (11)]), (INSTRUCTION *) NULL, (yyvsp[(8) - (11)]), (yyvsp[(11) - (11)])); @@ -2765,7 +2768,7 @@ regular_loop: case 48: /* Line 1464 of yacc.c */ -#line 795 "awkgram.y" +#line 798 "awkgram.y" { if (do_profiling) (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count)); @@ -2777,11 +2780,11 @@ regular_loop: case 49: /* Line 1464 of yacc.c */ -#line 805 "awkgram.y" +#line 808 "awkgram.y" { if (! break_allowed) - yyerror(_("`break' is not allowed outside a loop or switch")); - + error_ln((yyvsp[(1) - (2)])->source_line, + _("`break' is not allowed outside a loop or switch")); (yyvsp[(1) - (2)])->target_jmp = NULL; (yyval) = list_create((yyvsp[(1) - (2)])); @@ -2791,11 +2794,11 @@ regular_loop: case 50: /* Line 1464 of yacc.c */ -#line 814 "awkgram.y" +#line 817 "awkgram.y" { if (! continue_allowed) - yyerror(_("`continue' is not allowed outside a loop")); - + error_ln((yyvsp[(1) - (2)])->source_line, + _("`continue' is not allowed outside a loop")); (yyvsp[(1) - (2)])->target_jmp = NULL; (yyval) = list_create((yyvsp[(1) - (2)])); @@ -2805,10 +2808,11 @@ regular_loop: case 51: /* Line 1464 of yacc.c */ -#line 823 "awkgram.y" +#line 826 "awkgram.y" { if (rule != Rule) - yyerror(_("`next' used in %s action"), ruletab[rule]); + error_ln((yyvsp[(1) - (2)])->source_line, + _("`next' used in %s action"), ruletab[rule]); (yyvsp[(1) - (2)])->target_jmp = ip_rec; (yyval) = list_create((yyvsp[(1) - (2)])); } @@ -2817,26 +2821,14 @@ regular_loop: case 52: /* Line 1464 of yacc.c */ -#line 830 "awkgram.y" +#line 834 "awkgram.y" { - static short warned = FALSE; - - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error(_("`nextfile' is a gawk extension")); - } - if (do_lint && ! warned) { - warned = TRUE; - lintwarn(_("`nextfile' is a gawk extension")); - } - if (rule == BEGIN || rule == END || rule == ENDFILE) { - errcount++; - error(_("`nextfile' used in %s action"), ruletab[rule]); - } + if (do_traditional) + error_ln((yyvsp[(1) - (2)])->source_line, + _("`nextfile' is a gawk extension")); + if (rule == BEGIN || rule == END || rule == ENDFILE) + error_ln((yyvsp[(1) - (2)])->source_line, + _("`nextfile' used in %s action"), ruletab[rule]); (yyvsp[(1) - (2)])->target_jmp = ip_newfile; (yyvsp[(1) - (2)])->target_endfile = ip_endfile; @@ -2847,7 +2839,7 @@ regular_loop: case 53: /* Line 1464 of yacc.c */ -#line 855 "awkgram.y" +#line 847 "awkgram.y" { if (rule == END) (yyvsp[(1) - (3)])->target_jmp = ip_atexit; @@ -2866,7 +2858,7 @@ regular_loop: case 54: /* Line 1464 of yacc.c */ -#line 869 "awkgram.y" +#line 861 "awkgram.y" { if (! can_return) yyerror(_("`return' used outside function context")); @@ -2876,7 +2868,7 @@ regular_loop: case 55: /* Line 1464 of yacc.c */ -#line 872 "awkgram.y" +#line 864 "awkgram.y" { if ((yyvsp[(3) - (4)]) == NULL) { (yyval) = list_create((yyvsp[(1) - (4)])); @@ -2890,14 +2882,14 @@ regular_loop: case 57: /* Line 1464 of yacc.c */ -#line 892 "awkgram.y" +#line 884 "awkgram.y" { in_print = TRUE; in_parens = 0; } break; case 58: /* Line 1464 of yacc.c */ -#line 893 "awkgram.y" +#line 885 "awkgram.y" { /* * Optimization: plain `print' has no expression list, so $3 is null. @@ -2935,7 +2927,7 @@ regular_loop: } else { if (do_lint && (rule == BEGIN || rule == END) && ! warned) { warned = TRUE; - lintwarn( + lintwarn_ln((yyvsp[(1) - (4)])->source_line, _("plain `print' in BEGIN or END rule should probably be `print \"\"'")); } } @@ -2997,14 +2989,14 @@ regular_loop: case 59: /* Line 1464 of yacc.c */ -#line 988 "awkgram.y" +#line 980 "awkgram.y" { sub_counter = 0; } break; case 60: /* Line 1464 of yacc.c */ -#line 989 "awkgram.y" +#line 981 "awkgram.y" { char *arr = (yyvsp[(2) - (4)])->lextok; @@ -3013,18 +3005,15 @@ regular_loop: if ((yyvsp[(4) - (4)]) == NULL) { static short warned = FALSE; + if (do_lint && ! warned) { warned = TRUE; - lintwarn(_("`delete array' is a gawk extension")); - } - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error(_("`delete array' is a gawk extension")); + lintwarn_ln((yyvsp[(1) - (4)])->source_line, + _("`delete array' is a gawk extension")); } + if (do_traditional) + error_ln((yyvsp[(1) - (4)])->source_line, + _("`delete array' is a gawk extension")); (yyvsp[(1) - (4)])->expr_count = 0; (yyval) = list_append(list_create((yyvsp[(2) - (4)])), (yyvsp[(1) - (4)])); } else { @@ -3037,22 +3026,19 @@ regular_loop: case 61: /* Line 1464 of yacc.c */ -#line 1021 "awkgram.y" +#line 1010 "awkgram.y" { static short warned = FALSE; char *arr = (yyvsp[(3) - (4)])->lextok; if (do_lint && ! warned) { warned = TRUE; - lintwarn(_("`delete(array)' is a non-portable tawk extension")); + lintwarn_ln((yyvsp[(1) - (4)])->source_line, + _("`delete(array)' is a non-portable tawk extension")); } if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line. - */ - errcount++; - error(_("`delete(array)' is a non-portable tawk extension")); + error_ln((yyvsp[(1) - (4)])->source_line, + _("`delete array' is a gawk extension")); } (yyvsp[(3) - (4)])->memory = variable(arr, Node_var_array); (yyvsp[(3) - (4)])->opcode = Op_push_array; @@ -3064,35 +3050,35 @@ regular_loop: case 62: /* Line 1464 of yacc.c */ -#line 1043 "awkgram.y" +#line 1029 "awkgram.y" { (yyval) = optimize_assignment((yyvsp[(1) - (1)])); } break; case 63: /* Line 1464 of yacc.c */ -#line 1048 "awkgram.y" +#line 1034 "awkgram.y" { (yyval) = NULL; } break; case 64: /* Line 1464 of yacc.c */ -#line 1050 "awkgram.y" +#line 1036 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 65: /* Line 1464 of yacc.c */ -#line 1055 "awkgram.y" +#line 1041 "awkgram.y" { (yyval) = NULL; } break; case 66: /* Line 1464 of yacc.c */ -#line 1057 "awkgram.y" +#line 1043 "awkgram.y" { if ((yyvsp[(1) - (2)]) == NULL) (yyval) = list_create((yyvsp[(2) - (2)])); @@ -3104,14 +3090,14 @@ regular_loop: case 67: /* Line 1464 of yacc.c */ -#line 1064 "awkgram.y" +#line 1050 "awkgram.y" { (yyval) = NULL; } break; case 68: /* Line 1464 of yacc.c */ -#line 1069 "awkgram.y" +#line 1055 "awkgram.y" { INSTRUCTION *casestmt = (yyvsp[(5) - (5)]); if ((yyvsp[(5) - (5)]) == NULL) @@ -3128,7 +3114,7 @@ regular_loop: case 69: /* Line 1464 of yacc.c */ -#line 1081 "awkgram.y" +#line 1067 "awkgram.y" { INSTRUCTION *casestmt = (yyvsp[(4) - (4)]); if ((yyvsp[(4) - (4)]) == NULL) @@ -3144,14 +3130,14 @@ regular_loop: case 70: /* Line 1464 of yacc.c */ -#line 1095 "awkgram.y" +#line 1081 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 71: /* Line 1464 of yacc.c */ -#line 1097 "awkgram.y" +#line 1083 "awkgram.y" { (yyvsp[(2) - (2)])->memory->numbr = -(force_number((yyvsp[(2) - (2)])->memory)); bcfree((yyvsp[(1) - (2)])); @@ -3162,7 +3148,7 @@ regular_loop: case 72: /* Line 1464 of yacc.c */ -#line 1103 "awkgram.y" +#line 1089 "awkgram.y" { bcfree((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); @@ -3172,14 +3158,14 @@ regular_loop: case 73: /* Line 1464 of yacc.c */ -#line 1108 "awkgram.y" +#line 1094 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 74: /* Line 1464 of yacc.c */ -#line 1110 "awkgram.y" +#line 1096 "awkgram.y" { (yyvsp[(1) - (1)])->opcode = Op_push_re; (yyval) = (yyvsp[(1) - (1)]); @@ -3189,21 +3175,21 @@ regular_loop: case 75: /* Line 1464 of yacc.c */ -#line 1118 "awkgram.y" +#line 1104 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 76: /* Line 1464 of yacc.c */ -#line 1120 "awkgram.y" +#line 1106 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 78: /* Line 1464 of yacc.c */ -#line 1130 "awkgram.y" +#line 1116 "awkgram.y" { (yyval) = (yyvsp[(2) - (3)]); } @@ -3212,7 +3198,7 @@ regular_loop: case 79: /* Line 1464 of yacc.c */ -#line 1137 "awkgram.y" +#line 1123 "awkgram.y" { in_print = FALSE; in_parens = 0; @@ -3223,14 +3209,14 @@ regular_loop: case 80: /* Line 1464 of yacc.c */ -#line 1142 "awkgram.y" +#line 1128 "awkgram.y" { in_print = FALSE; in_parens = 0; } break; case 81: /* Line 1464 of yacc.c */ -#line 1143 "awkgram.y" +#line 1129 "awkgram.y" { if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway && (yyvsp[(3) - (3)])->lasti->opcode == Op_K_getline_redir @@ -3243,7 +3229,7 @@ regular_loop: case 82: /* Line 1464 of yacc.c */ -#line 1154 "awkgram.y" +#line 1140 "awkgram.y" { (yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]), (yyvsp[(6) - (6)]), NULL, NULL); } @@ -3252,7 +3238,7 @@ regular_loop: case 83: /* Line 1464 of yacc.c */ -#line 1159 "awkgram.y" +#line 1145 "awkgram.y" { (yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]), (yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)])); } @@ -3261,14 +3247,14 @@ regular_loop: case 88: /* Line 1464 of yacc.c */ -#line 1176 "awkgram.y" +#line 1162 "awkgram.y" { (yyval) = NULL; } break; case 89: /* Line 1464 of yacc.c */ -#line 1178 "awkgram.y" +#line 1164 "awkgram.y" { bcfree((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); @@ -3278,7 +3264,7 @@ regular_loop: case 92: /* Line 1464 of yacc.c */ -#line 1191 "awkgram.y" +#line 1177 "awkgram.y" { append_param((yyvsp[(1) - (1)])->lextok); (yyvsp[(1) - (1)])->lextok = NULL; @@ -3289,7 +3275,7 @@ regular_loop: case 93: /* Line 1464 of yacc.c */ -#line 1197 "awkgram.y" +#line 1183 "awkgram.y" { append_param((yyvsp[(3) - (3)])->lextok); (yyvsp[(3) - (3)])->lextok = NULL; @@ -3301,63 +3287,63 @@ regular_loop: case 94: /* Line 1464 of yacc.c */ -#line 1204 "awkgram.y" +#line 1190 "awkgram.y" { /* func_params = NULL; */ } break; case 95: /* Line 1464 of yacc.c */ -#line 1206 "awkgram.y" +#line 1192 "awkgram.y" { /* func_params = NULL; */ } break; case 96: /* Line 1464 of yacc.c */ -#line 1208 "awkgram.y" +#line 1194 "awkgram.y" { /* func_params = NULL; */ } break; case 97: /* Line 1464 of yacc.c */ -#line 1214 "awkgram.y" +#line 1200 "awkgram.y" { (yyval) = NULL; } break; case 98: /* Line 1464 of yacc.c */ -#line 1216 "awkgram.y" +#line 1202 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 99: /* Line 1464 of yacc.c */ -#line 1221 "awkgram.y" +#line 1207 "awkgram.y" { (yyval) = NULL; } break; case 100: /* Line 1464 of yacc.c */ -#line 1223 "awkgram.y" +#line 1209 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 101: /* Line 1464 of yacc.c */ -#line 1228 "awkgram.y" +#line 1214 "awkgram.y" { (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); } break; case 102: /* Line 1464 of yacc.c */ -#line 1230 "awkgram.y" +#line 1216 "awkgram.y" { (yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); yyerrok; @@ -3367,38 +3353,39 @@ regular_loop: case 103: /* Line 1464 of yacc.c */ -#line 1235 "awkgram.y" +#line 1221 "awkgram.y" { (yyval) = NULL; } break; case 104: /* Line 1464 of yacc.c */ -#line 1237 "awkgram.y" +#line 1223 "awkgram.y" { (yyval) = NULL; } break; case 105: /* Line 1464 of yacc.c */ -#line 1239 "awkgram.y" +#line 1225 "awkgram.y" { (yyval) = NULL; } break; case 106: /* Line 1464 of yacc.c */ -#line 1241 "awkgram.y" +#line 1227 "awkgram.y" { (yyval) = NULL; } break; case 107: /* Line 1464 of yacc.c */ -#line 1247 "awkgram.y" +#line 1233 "awkgram.y" { if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec) - lintwarn(_("regular expression on right of assignment")); + lintwarn_ln((yyvsp[(2) - (3)])->source_line, + _("regular expression on right of assignment")); (yyval) = mk_assignment((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; @@ -3406,24 +3393,25 @@ regular_loop: case 108: /* Line 1464 of yacc.c */ -#line 1253 "awkgram.y" +#line 1240 "awkgram.y" { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 109: /* Line 1464 of yacc.c */ -#line 1255 "awkgram.y" +#line 1242 "awkgram.y" { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 110: /* Line 1464 of yacc.c */ -#line 1257 "awkgram.y" +#line 1244 "awkgram.y" { if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec) - warning(_("regular expression on left of `~' or `!~' operator")); + warning_ln((yyvsp[(2) - (3)])->source_line, + _("regular expression on left of `~' or `!~' operator")); if ((yyvsp[(3) - (3)])->lasti == (yyvsp[(3) - (3)])->nexti && (yyvsp[(3) - (3)])->nexti->opcode == Op_match_rec) { (yyvsp[(2) - (3)])->memory = (yyvsp[(3) - (3)])->nexti->memory; @@ -3440,10 +3428,11 @@ regular_loop: case 111: /* Line 1464 of yacc.c */ -#line 1272 "awkgram.y" +#line 1260 "awkgram.y" { if (do_lint_old) - warning(_("old awk does not support the keyword `in' except after `for'")); + warning_ln((yyvsp[(2) - (3)])->source_line, + _("old awk does not support the keyword `in' except after `for'")); (yyvsp[(3) - (3)])->nexti->opcode = Op_push_array; (yyvsp[(2) - (3)])->opcode = Op_in_array; (yyvsp[(2) - (3)])->expr_count = 1; @@ -3454,10 +3443,11 @@ regular_loop: case 112: /* Line 1464 of yacc.c */ -#line 1281 "awkgram.y" +#line 1270 "awkgram.y" { if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec) - lintwarn(_("regular expression on right of comparison")); + lintwarn_ln((yyvsp[(2) - (3)])->source_line, + _("regular expression on right of comparison")); (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)])); } break; @@ -3465,35 +3455,35 @@ regular_loop: case 113: /* Line 1464 of yacc.c */ -#line 1287 "awkgram.y" +#line 1277 "awkgram.y" { (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]), (yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); } break; case 114: /* Line 1464 of yacc.c */ -#line 1289 "awkgram.y" +#line 1279 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 115: /* Line 1464 of yacc.c */ -#line 1294 "awkgram.y" +#line 1284 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 116: /* Line 1464 of yacc.c */ -#line 1296 "awkgram.y" +#line 1286 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 117: /* Line 1464 of yacc.c */ -#line 1298 "awkgram.y" +#line 1288 "awkgram.y" { (yyvsp[(2) - (2)])->opcode = Op_assign_quotient; (yyval) = (yyvsp[(2) - (2)]); @@ -3503,49 +3493,49 @@ regular_loop: case 118: /* Line 1464 of yacc.c */ -#line 1306 "awkgram.y" +#line 1296 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 119: /* Line 1464 of yacc.c */ -#line 1308 "awkgram.y" +#line 1298 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 120: /* Line 1464 of yacc.c */ -#line 1313 "awkgram.y" +#line 1303 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 121: /* Line 1464 of yacc.c */ -#line 1315 "awkgram.y" +#line 1305 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 122: /* Line 1464 of yacc.c */ -#line 1320 "awkgram.y" +#line 1310 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 123: /* Line 1464 of yacc.c */ -#line 1322 "awkgram.y" +#line 1312 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 124: /* Line 1464 of yacc.c */ -#line 1324 "awkgram.y" +#line 1314 "awkgram.y" { int count = 2; int is_simple_var = FALSE; @@ -3600,67 +3590,69 @@ regular_loop: case 126: /* Line 1464 of yacc.c */ -#line 1379 "awkgram.y" +#line 1369 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 127: /* Line 1464 of yacc.c */ -#line 1381 "awkgram.y" +#line 1371 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 128: /* Line 1464 of yacc.c */ -#line 1383 "awkgram.y" +#line 1373 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 129: /* Line 1464 of yacc.c */ -#line 1385 "awkgram.y" +#line 1375 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 130: /* Line 1464 of yacc.c */ -#line 1387 "awkgram.y" +#line 1377 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 131: /* Line 1464 of yacc.c */ -#line 1389 "awkgram.y" +#line 1379 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 132: /* Line 1464 of yacc.c */ -#line 1391 "awkgram.y" +#line 1381 "awkgram.y" { /* * In BEGINFILE/ENDFILE, allow `getline var < file' */ + if (rule == BEGINFILE || rule == ENDFILE) { if ((yyvsp[(2) - (3)]) != NULL && (yyvsp[(3) - (3)]) != NULL) - ; /* all ok */ + ; /* all ok */ else { if ((yyvsp[(2) - (3)]) != NULL) - yyerror(_("`getline var' invalid inside `%s' rule"), ruletab[rule]); + error_ln((yyvsp[(1) - (3)])->source_line, + _("`getline var' invalid inside `%s' rule"), ruletab[rule]); else - yyerror(_("`getline' invalid inside `%s' rule"), ruletab[rule]); - YYABORT; + error_ln((yyvsp[(1) - (3)])->source_line, + _("`getline' invalid inside `%s' rule"), ruletab[rule]); } } - if (do_lint && rule == END && (yyvsp[(3) - (3)]) == NULL) - lintwarn(_("non-redirected `getline' undefined inside END action")); + lintwarn_ln((yyvsp[(1) - (3)])->source_line, + _("non-redirected `getline' undefined inside END action")); (yyval) = mk_getline((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), redirect_input); } break; @@ -3668,7 +3660,7 @@ regular_loop: case 133: /* Line 1464 of yacc.c */ -#line 1412 "awkgram.y" +#line 1404 "awkgram.y" { (yyvsp[(2) - (2)])->opcode = Op_postincrement; (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)])); @@ -3678,7 +3670,7 @@ regular_loop: case 134: /* Line 1464 of yacc.c */ -#line 1417 "awkgram.y" +#line 1409 "awkgram.y" { (yyvsp[(2) - (2)])->opcode = Op_postdecrement; (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)])); @@ -3688,11 +3680,13 @@ regular_loop: case 135: /* Line 1464 of yacc.c */ -#line 1422 "awkgram.y" +#line 1414 "awkgram.y" { if (do_lint_old) { - warning(_("old awk does not support the keyword `in' except after `for'")); - warning(_("old awk does not support multidimensional arrays")); + warning_ln((yyvsp[(4) - (5)])->source_line, + _("old awk does not support the keyword `in' except after `for'")); + warning_ln((yyvsp[(4) - (5)])->source_line, + _("old awk does not support multidimensional arrays")); } (yyvsp[(5) - (5)])->nexti->opcode = Op_push_array; (yyvsp[(4) - (5)])->opcode = Op_in_array; @@ -3711,7 +3705,7 @@ regular_loop: case 136: /* Line 1464 of yacc.c */ -#line 1445 "awkgram.y" +#line 1439 "awkgram.y" { (yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type); bcfree((yyvsp[(2) - (4)])); @@ -3721,49 +3715,49 @@ regular_loop: case 137: /* Line 1464 of yacc.c */ -#line 1451 "awkgram.y" +#line 1445 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 138: /* Line 1464 of yacc.c */ -#line 1453 "awkgram.y" +#line 1447 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 139: /* Line 1464 of yacc.c */ -#line 1455 "awkgram.y" +#line 1449 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 140: /* Line 1464 of yacc.c */ -#line 1457 "awkgram.y" +#line 1451 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 141: /* Line 1464 of yacc.c */ -#line 1459 "awkgram.y" +#line 1453 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 142: /* Line 1464 of yacc.c */ -#line 1461 "awkgram.y" +#line 1455 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 143: /* Line 1464 of yacc.c */ -#line 1466 "awkgram.y" +#line 1460 "awkgram.y" { (yyval) = list_create((yyvsp[(1) - (1)])); } @@ -3772,7 +3766,7 @@ regular_loop: case 144: /* Line 1464 of yacc.c */ -#line 1470 "awkgram.y" +#line 1464 "awkgram.y" { if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) { (yyvsp[(2) - (2)])->opcode = Op_nomatch; @@ -3808,14 +3802,14 @@ regular_loop: case 145: /* Line 1464 of yacc.c */ -#line 1501 "awkgram.y" +#line 1495 "awkgram.y" { (yyval) = (yyvsp[(2) - (3)]); } break; case 146: /* Line 1464 of yacc.c */ -#line 1503 "awkgram.y" +#line 1497 "awkgram.y" { (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)])); if ((yyval) == NULL) @@ -3826,7 +3820,7 @@ regular_loop: case 147: /* Line 1464 of yacc.c */ -#line 1509 "awkgram.y" +#line 1503 "awkgram.y" { (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)])); if ((yyval) == NULL) @@ -3837,13 +3831,14 @@ regular_loop: case 148: /* Line 1464 of yacc.c */ -#line 1515 "awkgram.y" +#line 1509 "awkgram.y" { static short warned1 = FALSE; if (do_lint && ! warned1) { warned1 = TRUE; - lintwarn(_("call of `length' without parentheses is not portable")); + lintwarn_ln((yyvsp[(1) - (1)])->source_line, + _("call of `length' without parentheses is not portable")); } (yyval) = snode(NULL, (yyvsp[(1) - (1)])); if ((yyval) == NULL) @@ -3854,7 +3849,7 @@ regular_loop: case 151: /* Line 1464 of yacc.c */ -#line 1529 "awkgram.y" +#line 1524 "awkgram.y" { (yyvsp[(1) - (2)])->opcode = Op_preincrement; (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)])); @@ -3864,7 +3859,7 @@ regular_loop: case 152: /* Line 1464 of yacc.c */ -#line 1534 "awkgram.y" +#line 1529 "awkgram.y" { (yyvsp[(1) - (2)])->opcode = Op_predecrement; (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)])); @@ -3874,7 +3869,7 @@ regular_loop: case 153: /* Line 1464 of yacc.c */ -#line 1539 "awkgram.y" +#line 1534 "awkgram.y" { (yyval) = list_create((yyvsp[(1) - (1)])); } @@ -3883,7 +3878,7 @@ regular_loop: case 154: /* Line 1464 of yacc.c */ -#line 1543 "awkgram.y" +#line 1538 "awkgram.y" { (yyval) = list_create((yyvsp[(1) - (1)])); } @@ -3892,7 +3887,7 @@ regular_loop: case 155: /* Line 1464 of yacc.c */ -#line 1547 "awkgram.y" +#line 1542 "awkgram.y" { if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i && ((yyvsp[(2) - (2)])->lasti->memory->flags & (STRCUR|STRING)) == 0) { @@ -3909,7 +3904,7 @@ regular_loop: case 156: /* Line 1464 of yacc.c */ -#line 1559 "awkgram.y" +#line 1554 "awkgram.y" { /* * was: $$ = $2 @@ -3924,7 +3919,7 @@ regular_loop: case 157: /* Line 1464 of yacc.c */ -#line 1572 "awkgram.y" +#line 1567 "awkgram.y" { func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE); (yyval) = (yyvsp[(1) - (1)]); @@ -3934,7 +3929,7 @@ regular_loop: case 158: /* Line 1464 of yacc.c */ -#line 1577 "awkgram.y" +#line 1572 "awkgram.y" { /* indirect function call */ INSTRUCTION *f, *t; @@ -3972,7 +3967,7 @@ regular_loop: case 159: /* Line 1464 of yacc.c */ -#line 1613 "awkgram.y" +#line 1608 "awkgram.y" { param_sanity((yyvsp[(3) - (4)])); (yyvsp[(1) - (4)])->opcode = Op_func_call; @@ -3991,42 +3986,42 @@ regular_loop: case 160: /* Line 1464 of yacc.c */ -#line 1630 "awkgram.y" +#line 1625 "awkgram.y" { (yyval) = NULL; } break; case 161: /* Line 1464 of yacc.c */ -#line 1632 "awkgram.y" +#line 1627 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 162: /* Line 1464 of yacc.c */ -#line 1637 "awkgram.y" +#line 1632 "awkgram.y" { (yyval) = NULL; } break; case 163: /* Line 1464 of yacc.c */ -#line 1639 "awkgram.y" +#line 1634 "awkgram.y" { (yyval) = (yyvsp[(1) - (2)]); } break; case 164: /* Line 1464 of yacc.c */ -#line 1644 "awkgram.y" +#line 1639 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 165: /* Line 1464 of yacc.c */ -#line 1646 "awkgram.y" +#line 1641 "awkgram.y" { (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); } @@ -4035,7 +4030,7 @@ regular_loop: case 166: /* Line 1464 of yacc.c */ -#line 1653 "awkgram.y" +#line 1648 "awkgram.y" { INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti; int count = ip->sub_count; /* # of SUBSEP-seperated expressions */ @@ -4054,12 +4049,12 @@ regular_loop: case 167: /* Line 1464 of yacc.c */ -#line 1670 "awkgram.y" +#line 1665 "awkgram.y" { INSTRUCTION *t = (yyvsp[(2) - (3)]); if ((yyvsp[(2) - (3)]) == NULL) { - errcount++; - error(_("invalid subscript expression")); + error_ln((yyvsp[(3) - (3)])->source_line, + _("invalid subscript expression")); /* install Null string as subscript. */ t = list_create(instruction(Op_push_i)); t->nexti->memory = Nnull_string; @@ -4073,14 +4068,14 @@ regular_loop: case 168: /* Line 1464 of yacc.c */ -#line 1687 "awkgram.y" +#line 1682 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 169: /* Line 1464 of yacc.c */ -#line 1689 "awkgram.y" +#line 1684 "awkgram.y" { (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); } @@ -4089,14 +4084,14 @@ regular_loop: case 170: /* Line 1464 of yacc.c */ -#line 1696 "awkgram.y" +#line 1691 "awkgram.y" { (yyval) = (yyvsp[(1) - (2)]); } break; case 171: /* Line 1464 of yacc.c */ -#line 1701 "awkgram.y" +#line 1696 "awkgram.y" { char *var_name = (yyvsp[(1) - (1)])->lextok; @@ -4109,7 +4104,7 @@ regular_loop: case 172: /* Line 1464 of yacc.c */ -#line 1709 "awkgram.y" +#line 1704 "awkgram.y" { NODE *n; @@ -4125,7 +4120,7 @@ regular_loop: case 173: /* Line 1464 of yacc.c */ -#line 1723 "awkgram.y" +#line 1718 "awkgram.y" { INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti; if (ip->opcode == Op_push @@ -4143,7 +4138,7 @@ regular_loop: case 174: /* Line 1464 of yacc.c */ -#line 1736 "awkgram.y" +#line 1731 "awkgram.y" { (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)])); if ((yyvsp[(3) - (3)]) != NULL) @@ -4154,7 +4149,7 @@ regular_loop: case 175: /* Line 1464 of yacc.c */ -#line 1745 "awkgram.y" +#line 1740 "awkgram.y" { (yyvsp[(1) - (1)])->opcode = Op_postincrement; } @@ -4163,7 +4158,7 @@ regular_loop: case 176: /* Line 1464 of yacc.c */ -#line 1749 "awkgram.y" +#line 1744 "awkgram.y" { (yyvsp[(1) - (1)])->opcode = Op_postdecrement; } @@ -4172,49 +4167,49 @@ regular_loop: case 177: /* Line 1464 of yacc.c */ -#line 1752 "awkgram.y" +#line 1747 "awkgram.y" { (yyval) = NULL; } break; case 179: /* Line 1464 of yacc.c */ -#line 1760 "awkgram.y" +#line 1755 "awkgram.y" { yyerrok; } break; case 180: /* Line 1464 of yacc.c */ -#line 1764 "awkgram.y" +#line 1759 "awkgram.y" { yyerrok; } break; case 183: /* Line 1464 of yacc.c */ -#line 1773 "awkgram.y" +#line 1768 "awkgram.y" { yyerrok; } break; case 184: /* Line 1464 of yacc.c */ -#line 1777 "awkgram.y" +#line 1772 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); yyerrok; } break; case 185: /* Line 1464 of yacc.c */ -#line 1781 "awkgram.y" +#line 1776 "awkgram.y" { yyerrok; } break; /* Line 1464 of yacc.c */ -#line 4230 "awkgram.c" +#line 4225 "awkgram.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -4426,7 +4421,7 @@ yyreturn: /* Line 1684 of yacc.c */ -#line 1783 "awkgram.y" +#line 1778 "awkgram.y" struct token { @@ -4577,42 +4572,27 @@ getfname(NODE *(*fptr)(int)) return NULL; } -/* yyerror --- print a syntax error message, show where */ - -/* - * Function identifier purposely indented to avoid mangling - * by ansi2knr. Sigh. - */ +/* print_included_from --- print `Included from ..' file names and locations */ static void -yyerror(const char *m, ...) +print_included_from() { - va_list args; - const char *mesg = NULL; - char *bp, *cp; - char *scan; - char *buf; - int count; - static char end_of_file_line[] = "(END OF FILE)"; - char save; - int saveline; + int saveline, line; SRCFILE *s; /* suppress current file name, line # from `.. included from ..' msgs */ saveline = sourceline; sourceline = 0; - for (s = sourcefile; s->stype == SRC_INC; ) { - int line; + for (s = sourcefile; s != NULL && s->stype == SRC_INC; ) { s = s->next; - if (s->fd <= INVALID_HANDLE) + if (s == NULL || s->fd <= INVALID_HANDLE) continue; - line = s->srclines; + /* if last token is NEWLINE, line number is off by 1. */ if (s->lasttok == NEWLINE) line--; - msg("%s %s:%d%c", s->prev == sourcefile ? "In file included from" : " from", @@ -4623,6 +4603,80 @@ yyerror(const char *m, ...) ); } sourceline = saveline; +} + +/* warning_ln --- print a warning message with location */ + +static void +warning_ln(int line, const char *mesg, ...) +{ + va_list args; + int saveline; + + saveline = sourceline; + sourceline = line; + print_included_from(); + va_start(args, mesg); + err(_("warning: "), mesg, args); + va_end(args); + sourceline = saveline; +} + +/* lintwarn_ln --- print a lint warning and location */ + +static void +lintwarn_ln(int line, const char *mesg, ...) +{ + va_list args; + int saveline; + + saveline = sourceline; + sourceline = line; + print_included_from(); + va_start(args, mesg); + if (lintfunc == r_fatal) + err(_("fatal: "), mesg, args); + else + err(_("warning: "), mesg, args); + va_end(args); + sourceline = saveline; + if (lintfunc == r_fatal) + gawk_exit(EXIT_FATAL); +} + +/* error_ln --- print an error message and location */ + +static void +error_ln(int line, const char *m, ...) +{ + va_list args; + int saveline; + + saveline = sourceline; + sourceline = line; + print_included_from(); + errcount++; + va_start(args, m); + err("error: ", m, args); + va_end(args); + sourceline = saveline; +} + +/* yyerror --- print a syntax error message, show where */ + +static void +yyerror(const char *m, ...) +{ + va_list args; + const char *mesg = NULL; + char *bp, *cp; + char *scan; + char *buf; + int count; + static char end_of_file_line[] = "(END OF FILE)"; + char save; + + print_included_from(); errcount++; /* Find the current line in the input file */ @@ -4661,10 +4715,10 @@ yyerror(const char *m, ...) msg("%.*s", (int) (bp - thisline), thisline); *bp = save; - va_start(args, m); if (mesg == NULL) mesg = m; + count = (bp - thisline) + strlen(mesg) + 2 + 1; emalloc(buf, char *, count, "yyerror"); @@ -4836,8 +4890,9 @@ parse_program(INSTRUCTION **pcode) /* avoid false source indications */ source = NULL; sourceline = 0; + if (ret == 0) /* avoid spurious warning if parser aborted with YYABORT */ + check_funcs(); - check_funcs(); return (ret || errcount); } @@ -4894,8 +4949,17 @@ add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int if ((s->stype == SRC_FILE || s->stype == SRC_INC) && files_are_same(path, s) ) { - if (do_lint) - lintwarn(_("already included source file `%s'"), src); + if (do_lint) { + int line = sourceline; + /* Kludge: the line number may be off for `@include file'. + * Since, this function is also used for '-f file' in main.c, + * sourceline > 1 check ensures that the call is at + * parse time. + */ + if (sourceline > 1 && lasttok == NEWLINE) + line--; + lintwarn_ln(line, _("already included source file `%s'"), src); + } efree(path); if (already_included) *already_included = TRUE; @@ -4912,21 +4976,21 @@ add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int /* include_source --- read program from source included using `@include' */ static int -include_source(char *src) +include_source(INSTRUCTION *file) { SRCFILE *s; + char *src = file->lextok; int errcode; int already_included; if (do_traditional || do_posix) { - error(_("@include is a gawk extension")); - errcount++; + error_ln(file->source_line, _("@include is a gawk extension")); return -1; } if (strlen(src) == 0) { if (do_lint) - lintwarn(_("empty filename after @include")); + lintwarn_ln(file->source_line, _("empty filename after @include")); return 0; } @@ -4934,9 +4998,9 @@ include_source(char *src) if (s == NULL) { if (already_included) return 0; - error(_("can't open source file `%s' for reading (%s)"), - src, errcode ? strerror(errcode) : _("reason unknown")); - errcount++; + error_ln(file->source_line, + _("can't open source file `%s' for reading (%s)"), + src, errcode ? strerror(errcode) : _("reason unknown")); return -1; } @@ -5196,6 +5260,7 @@ get_src_buf() static short warned = FALSE; if (do_lint && newfile && ! warned){ warned = TRUE; + sourceline = 0; lintwarn(_("source file `%s' is empty"), source); } lexeof = TRUE; @@ -6032,6 +6097,7 @@ retry: /* See if it is a special token. */ if ((mid = check_special(tokstart)) >= 0) { + static int warntab[sizeof(tokentab) / sizeof(tokentab[0])]; int class = tokentab[mid].class; if ((class == LEX_INCLUDE || class == LEX_EVAL) @@ -6039,19 +6105,30 @@ retry: goto out; if (do_lint) { - if (tokentab[mid].flags & GAWKX) + if ((tokentab[mid].flags & GAWKX) && ! (warntab[mid] & GAWKX)) { lintwarn(_("`%s' is a gawk extension"), tokentab[mid].operator); - if (tokentab[mid].flags & RESX) + warntab[mid] |= GAWKX; + } + if ((tokentab[mid].flags & RESX) && ! (warntab[mid] & RESX)) { lintwarn(_("`%s' is a Bell Labs extension"), tokentab[mid].operator); - if (tokentab[mid].flags & NOT_POSIX) + warntab[mid] |= RESX; + } + if ((tokentab[mid].flags & NOT_POSIX) && ! (warntab[mid] & NOT_POSIX)) { lintwarn(_("POSIX does not allow `%s'"), tokentab[mid].operator); + warntab[mid] |= NOT_POSIX; + } } - if (do_lint_old && (tokentab[mid].flags & NOT_OLD)) + if (do_lint_old && (tokentab[mid].flags & NOT_OLD) + && ! (warntab[mid] & NOT_OLD) + ) { warning(_("`%s' is not supported in old awk"), tokentab[mid].operator); + warntab[mid] |= NOT_OLD; + } + if (tokentab[mid].flags & BREAK) break_allowed++; if (tokentab[mid].flags & CONTINUE) @@ -6411,7 +6488,7 @@ append_param(char *pname) /* dup_parms --- return TRUE if there are duplicate parameters */ static int -dup_parms(NODE *func) +dup_parms(INSTRUCTION *fp, NODE *func) { NODE *np; const char *fname, **names; @@ -6447,7 +6524,7 @@ dup_parms(NODE *func) for (j = 0; j < i; j++) { if (strcmp(names[i], names[j]) == 0) { dups++; - error( + error_ln(fp->source_line, _("function `%s': parameter #%d, `%s', duplicates parameter #%d"), fname, i + 1, names[j], j+1); } @@ -6742,14 +6819,13 @@ func_install(INSTRUCTION *func, INSTRUCTION *def) /* check for function foo(foo) { ... }. bleah. */ for (n = params->rnode; n != NULL; n = n->rnode) { if (strcmp(n->param, params->param) == 0) { - error(_("function `%s': can't use function name as parameter name"), - params->param); - errcount++; + error_ln(func->source_line, + _("function `%s': can't use function name as parameter name"), params->param); return -1; } else if (is_std_var(n->param)) { - error(_("function `%s': can't use special variable `%s' as a function parameter"), - params->param, n->param); - errcount++; + error_ln(func->source_line, + _("function `%s': can't use special variable `%s' as a function parameter"), + params->param, n->param); return -1; } } @@ -6763,8 +6839,8 @@ func_install(INSTRUCTION *func, INSTRUCTION *def) freenode(hp); r = lookup(fname); if (r != NULL) { - error(_("function name `%s' previously defined"), fname); - errcount++; + error_ln(func->source_line, + _("function name `%s' previously defined"), fname); return -1; } else if (fname == builtin_func) /* not a valid function name */ goto remove_params; @@ -6972,7 +7048,8 @@ param_sanity(INSTRUCTION *arglist) for (argl = arglist->nexti; argl; ) { arg = argl->lasti; if (arg->opcode == Op_match_rec) - warning(_("regexp constant for parameter #%d yields boolean value"), i); + warning_ln(arg->source_line, + _("regexp constant for parameter #%d yields boolean value"), i); argl = arg->nexti; i++; } @@ -7328,7 +7405,7 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op) case Op_quotient: if (n2->numbr == 0.0) { /* don't fatalize, allow parsing rest of the input */ - yyerror(_("division by zero attempted")); + error_ln(op->source_line, _("division by zero attempted")); goto regular; } @@ -7337,7 +7414,7 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op) case Op_mod: if (n2->numbr == 0.0) { /* don't fatalize, allow parsing rest of the input */ - yyerror(_("division by zero attempted in `%%'")); + error_ln(op->source_line, _("division by zero attempted in `%%'")); goto regular; } #ifdef HAVE_FMOD @@ -8008,7 +8085,7 @@ add_lint(INSTRUCTION *list, LINTTYPE linttype) if (do_lint) { /* compile-time warning */ if (isnoeffect(ip->opcode)) - lintwarn(_("statement may have no effect")); + lintwarn_ln(ip->source_line, ("statement may have no effect")); } if (ip->opcode == Op_push) { /* run-time warning */ @@ -35,6 +35,9 @@ #endif static void yyerror(const char *m, ...) ATTRIBUTE_PRINTF_1; +static void error_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2; +static void lintwarn_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2; +static void warning_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2; static char *get_src_buf(void); static int yylex(void); int yyparse(void); @@ -44,7 +47,7 @@ static void pop_params(NODE *params); static NODE *make_param(char *pname); static NODE *mk_rexp(INSTRUCTION *exp); static void append_param(char *pname); -static int dup_parms(NODE *func); +static int dup_parms(INSTRUCTION *fp, NODE *func); static void param_sanity(INSTRUCTION *arglist); static int parms_shadow(INSTRUCTION *pc, int *shadow); static int isnoeffect(OPCODE type); @@ -52,7 +55,7 @@ static INSTRUCTION *make_assignable(INSTRUCTION *ip); static void dumpintlstr(const char *str, size_t len); static void dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2); static int isarray(NODE *n); -static int include_source(char *src); +static int include_source(INSTRUCTION *file); static void next_sourcefile(void); static char *tokexpand(void); @@ -269,10 +272,9 @@ rule source : FILENAME { - char *src = $1->lextok; - if (include_source(src) < 0) + if (include_source($1) < 0) YYABORT; - efree(src); + efree($1->lextok); bcfree($1); $$ = NULL; } @@ -317,7 +319,8 @@ pattern { static int begin_seen = 0; if (do_lint_old && ++begin_seen == 2) - warning(_("old awk does not support multiple `BEGIN' or `END' rules")); + warning_ln($1->source_line, + _("old awk does not support multiple `BEGIN' or `END' rules")); $1->in_rule = rule = BEGIN; $1->source_file = source; @@ -327,7 +330,8 @@ pattern { static int end_seen = 0; if (do_lint_old && ++end_seen == 2) - warning(_("old awk does not support multiple `BEGIN' or `END' rules")); + warning_ln($1->source_line, + _("old awk does not support multiple `BEGIN' or `END' rules")); $1->in_rule = rule = END; $1->source_file = source; @@ -402,7 +406,7 @@ function_prologue $$ = $1; can_return = TRUE; /* check for duplicate parameter names */ - if (dup_parms(t)) + if (dup_parms($1, t)) errcount++; } ; @@ -424,10 +428,12 @@ regexp len = strlen(re); if (do_lint) { if (len == 0) - lintwarn(_("regexp constant `//' looks like a C++ comment, but is not")); + lintwarn_ln($3->source_line, + _("regexp constant `//' looks like a C++ comment, but is not")); else if ((re)[0] == '*' && (re)[len-1] == '*') /* possible C comment */ - lintwarn(_("regexp constant `/%s/' looks like a C comment, but is not"), re); + lintwarn_ln($3->source_line, + _("regexp constant `/%s/' looks like a C comment, but is not"), re); } exp = make_str_node(re, len, ALREADY_MALLOCED); @@ -517,11 +523,9 @@ statement char *caseval; caseval = force_string(caseexp->memory)->stptr; for (i = 0; i < case_count; i++) { - if (strcmp(caseval, case_values[i]) == 0) { - /* can't use yyerror, since may have overshot the source line */ - errcount++; - error(_("duplicate case values in switch body: %s"), caseval); - } + if (strcmp(caseval, case_values[i]) == 0) + error_ln(curr->source_line, + _("duplicate case values in switch body: %s"), caseval); } if (case_values == NULL) @@ -540,11 +544,10 @@ statement (void) list_prepend(cexp, curr); (void) list_prepend(cexp, caseexp); } else { - if (dflt->target_jmp != tbreak) { - /* can't use yyerror, since may have overshot the source line */ - errcount++; - error(_("duplicate `default' detected in switch body")); - } else + if (dflt->target_jmp != tbreak) + error_ln(curr->source_line, + _("duplicate `default' detected in switch body")); + else dflt->target_jmp = casestmt->nexti; if (do_profiling) { @@ -804,8 +807,8 @@ non_compound_stmt : LEX_BREAK statement_term { if (! break_allowed) - yyerror(_("`break' is not allowed outside a loop or switch")); - + error_ln($1->source_line, + _("`break' is not allowed outside a loop or switch")); $1->target_jmp = NULL; $$ = list_create($1); @@ -813,8 +816,8 @@ non_compound_stmt | LEX_CONTINUE statement_term { if (! continue_allowed) - yyerror(_("`continue' is not allowed outside a loop")); - + error_ln($1->source_line, + _("`continue' is not allowed outside a loop")); $1->target_jmp = NULL; $$ = list_create($1); @@ -822,30 +825,19 @@ non_compound_stmt | LEX_NEXT statement_term { if (rule != Rule) - yyerror(_("`next' used in %s action"), ruletab[rule]); + error_ln($1->source_line, + _("`next' used in %s action"), ruletab[rule]); $1->target_jmp = ip_rec; $$ = list_create($1); } | LEX_NEXTFILE statement_term { - static short warned = FALSE; - - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error(_("`nextfile' is a gawk extension")); - } - if (do_lint && ! warned) { - warned = TRUE; - lintwarn(_("`nextfile' is a gawk extension")); - } - if (rule == BEGIN || rule == END || rule == ENDFILE) { - errcount++; - error(_("`nextfile' used in %s action"), ruletab[rule]); - } + if (do_traditional) + error_ln($1->source_line, + _("`nextfile' is a gawk extension")); + if (rule == BEGIN || rule == END || rule == ENDFILE) + error_ln($1->source_line, + _("`nextfile' used in %s action"), ruletab[rule]); $1->target_jmp = ip_newfile; $1->target_endfile = ip_endfile; @@ -927,7 +919,7 @@ simple_stmt } else { if (do_lint && (rule == BEGIN || rule == END) && ! warned) { warned = TRUE; - lintwarn( + lintwarn_ln($1->source_line, _("plain `print' in BEGIN or END rule should probably be `print \"\"'")); } } @@ -994,18 +986,15 @@ simple_stmt if ($4 == NULL) { static short warned = FALSE; + if (do_lint && ! warned) { warned = TRUE; - lintwarn(_("`delete array' is a gawk extension")); - } - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error(_("`delete array' is a gawk extension")); + lintwarn_ln($1->source_line, + _("`delete array' is a gawk extension")); } + if (do_traditional) + error_ln($1->source_line, + _("`delete array' is a gawk extension")); $1->expr_count = 0; $$ = list_append(list_create($2), $1); } else { @@ -1024,15 +1013,12 @@ simple_stmt if (do_lint && ! warned) { warned = TRUE; - lintwarn(_("`delete(array)' is a non-portable tawk extension")); + lintwarn_ln($1->source_line, + _("`delete(array)' is a non-portable tawk extension")); } if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line. - */ - errcount++; - error(_("`delete(array)' is a non-portable tawk extension")); + error_ln($1->source_line, + _("`delete array' is a gawk extension")); } $3->memory = variable(arr, Node_var_array); $3->opcode = Op_push_array; @@ -1246,7 +1232,8 @@ exp : variable assign_operator exp %prec ASSIGNOP { if (do_lint && $3->lasti->opcode == Op_match_rec) - lintwarn(_("regular expression on right of assignment")); + lintwarn_ln($2->source_line, + _("regular expression on right of assignment")); $$ = mk_assignment($1, $3, $2); } | exp LEX_AND exp @@ -1256,7 +1243,8 @@ exp | exp MATCHOP exp { if ($1->lasti->opcode == Op_match_rec) - warning(_("regular expression on left of `~' or `!~' operator")); + warning_ln($2->source_line, + _("regular expression on left of `~' or `!~' operator")); if ($3->lasti == $3->nexti && $3->nexti->opcode == Op_match_rec) { $2->memory = $3->nexti->memory; @@ -1271,7 +1259,8 @@ exp | exp LEX_IN simple_variable { if (do_lint_old) - warning(_("old awk does not support the keyword `in' except after `for'")); + warning_ln($2->source_line, + _("old awk does not support the keyword `in' except after `for'")); $3->nexti->opcode = Op_push_array; $2->opcode = Op_in_array; $2->expr_count = 1; @@ -1280,7 +1269,8 @@ exp | exp a_relop exp %prec RELOP { if (do_lint && $3->lasti->opcode == Op_match_rec) - lintwarn(_("regular expression on right of comparison")); + lintwarn_ln($2->source_line, + _("regular expression on right of comparison")); $$ = list_append(list_merge($1, $3), $2); } | exp '?' exp ':' exp @@ -1392,20 +1382,22 @@ simp_exp /* * In BEGINFILE/ENDFILE, allow `getline var < file' */ + if (rule == BEGINFILE || rule == ENDFILE) { if ($2 != NULL && $3 != NULL) - ; /* all ok */ + ; /* all ok */ else { if ($2 != NULL) - yyerror(_("`getline var' invalid inside `%s' rule"), ruletab[rule]); + error_ln($1->source_line, + _("`getline var' invalid inside `%s' rule"), ruletab[rule]); else - yyerror(_("`getline' invalid inside `%s' rule"), ruletab[rule]); - YYABORT; + error_ln($1->source_line, + _("`getline' invalid inside `%s' rule"), ruletab[rule]); } } - if (do_lint && rule == END && $3 == NULL) - lintwarn(_("non-redirected `getline' undefined inside END action")); + lintwarn_ln($1->source_line, + _("non-redirected `getline' undefined inside END action")); $$ = mk_getline($1, $2, $3, redirect_input); } | variable INCREMENT @@ -1421,8 +1413,10 @@ simp_exp | '(' expression_list r_paren LEX_IN simple_variable { if (do_lint_old) { - warning(_("old awk does not support the keyword `in' except after `for'")); - warning(_("old awk does not support multidimensional arrays")); + warning_ln($4->source_line, + _("old awk does not support the keyword `in' except after `for'")); + warning_ln($4->source_line, + _("old awk does not support multidimensional arrays")); } $5->nexti->opcode = Op_push_array; $4->opcode = Op_in_array; @@ -1517,7 +1511,8 @@ non_post_simp_exp if (do_lint && ! warned1) { warned1 = TRUE; - lintwarn(_("call of `length' without parentheses is not portable")); + lintwarn_ln($1->source_line, + _("call of `length' without parentheses is not portable")); } $$ = snode(NULL, $1); if ($$ == NULL) @@ -1670,8 +1665,8 @@ bracketed_exp_list { INSTRUCTION *t = $2; if ($2 == NULL) { - errcount++; - error(_("invalid subscript expression")); + error_ln($3->source_line, + _("invalid subscript expression")); /* install Null string as subscript. */ t = list_create(instruction(Op_push_i)); t->nexti->memory = Nnull_string; @@ -1930,42 +1925,27 @@ getfname(NODE *(*fptr)(int)) return NULL; } -/* yyerror --- print a syntax error message, show where */ - -/* - * Function identifier purposely indented to avoid mangling - * by ansi2knr. Sigh. - */ +/* print_included_from --- print `Included from ..' file names and locations */ static void -yyerror(const char *m, ...) +print_included_from() { - va_list args; - const char *mesg = NULL; - char *bp, *cp; - char *scan; - char *buf; - int count; - static char end_of_file_line[] = "(END OF FILE)"; - char save; - int saveline; + int saveline, line; SRCFILE *s; /* suppress current file name, line # from `.. included from ..' msgs */ saveline = sourceline; sourceline = 0; - for (s = sourcefile; s->stype == SRC_INC; ) { - int line; + for (s = sourcefile; s != NULL && s->stype == SRC_INC; ) { s = s->next; - if (s->fd <= INVALID_HANDLE) + if (s == NULL || s->fd <= INVALID_HANDLE) continue; - line = s->srclines; + /* if last token is NEWLINE, line number is off by 1. */ if (s->lasttok == NEWLINE) line--; - msg("%s %s:%d%c", s->prev == sourcefile ? "In file included from" : " from", @@ -1976,6 +1956,80 @@ yyerror(const char *m, ...) ); } sourceline = saveline; +} + +/* warning_ln --- print a warning message with location */ + +static void +warning_ln(int line, const char *mesg, ...) +{ + va_list args; + int saveline; + + saveline = sourceline; + sourceline = line; + print_included_from(); + va_start(args, mesg); + err(_("warning: "), mesg, args); + va_end(args); + sourceline = saveline; +} + +/* lintwarn_ln --- print a lint warning and location */ + +static void +lintwarn_ln(int line, const char *mesg, ...) +{ + va_list args; + int saveline; + + saveline = sourceline; + sourceline = line; + print_included_from(); + va_start(args, mesg); + if (lintfunc == r_fatal) + err(_("fatal: "), mesg, args); + else + err(_("warning: "), mesg, args); + va_end(args); + sourceline = saveline; + if (lintfunc == r_fatal) + gawk_exit(EXIT_FATAL); +} + +/* error_ln --- print an error message and location */ + +static void +error_ln(int line, const char *m, ...) +{ + va_list args; + int saveline; + + saveline = sourceline; + sourceline = line; + print_included_from(); + errcount++; + va_start(args, m); + err("error: ", m, args); + va_end(args); + sourceline = saveline; +} + +/* yyerror --- print a syntax error message, show where */ + +static void +yyerror(const char *m, ...) +{ + va_list args; + const char *mesg = NULL; + char *bp, *cp; + char *scan; + char *buf; + int count; + static char end_of_file_line[] = "(END OF FILE)"; + char save; + + print_included_from(); errcount++; /* Find the current line in the input file */ @@ -2014,10 +2068,10 @@ yyerror(const char *m, ...) msg("%.*s", (int) (bp - thisline), thisline); *bp = save; - va_start(args, m); if (mesg == NULL) mesg = m; + count = (bp - thisline) + strlen(mesg) + 2 + 1; emalloc(buf, char *, count, "yyerror"); @@ -2189,8 +2243,9 @@ parse_program(INSTRUCTION **pcode) /* avoid false source indications */ source = NULL; sourceline = 0; + if (ret == 0) /* avoid spurious warning if parser aborted with YYABORT */ + check_funcs(); - check_funcs(); return (ret || errcount); } @@ -2247,8 +2302,17 @@ add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int if ((s->stype == SRC_FILE || s->stype == SRC_INC) && files_are_same(path, s) ) { - if (do_lint) - lintwarn(_("already included source file `%s'"), src); + if (do_lint) { + int line = sourceline; + /* Kludge: the line number may be off for `@include file'. + * Since, this function is also used for '-f file' in main.c, + * sourceline > 1 check ensures that the call is at + * parse time. + */ + if (sourceline > 1 && lasttok == NEWLINE) + line--; + lintwarn_ln(line, _("already included source file `%s'"), src); + } efree(path); if (already_included) *already_included = TRUE; @@ -2265,21 +2329,21 @@ add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int /* include_source --- read program from source included using `@include' */ static int -include_source(char *src) +include_source(INSTRUCTION *file) { SRCFILE *s; + char *src = file->lextok; int errcode; int already_included; if (do_traditional || do_posix) { - error(_("@include is a gawk extension")); - errcount++; + error_ln(file->source_line, _("@include is a gawk extension")); return -1; } if (strlen(src) == 0) { if (do_lint) - lintwarn(_("empty filename after @include")); + lintwarn_ln(file->source_line, _("empty filename after @include")); return 0; } @@ -2287,9 +2351,9 @@ include_source(char *src) if (s == NULL) { if (already_included) return 0; - error(_("can't open source file `%s' for reading (%s)"), - src, errcode ? strerror(errcode) : _("reason unknown")); - errcount++; + error_ln(file->source_line, + _("can't open source file `%s' for reading (%s)"), + src, errcode ? strerror(errcode) : _("reason unknown")); return -1; } @@ -2549,6 +2613,7 @@ get_src_buf() static short warned = FALSE; if (do_lint && newfile && ! warned){ warned = TRUE; + sourceline = 0; lintwarn(_("source file `%s' is empty"), source); } lexeof = TRUE; @@ -3385,6 +3450,7 @@ retry: /* See if it is a special token. */ if ((mid = check_special(tokstart)) >= 0) { + static int warntab[sizeof(tokentab) / sizeof(tokentab[0])]; int class = tokentab[mid].class; if ((class == LEX_INCLUDE || class == LEX_EVAL) @@ -3392,19 +3458,30 @@ retry: goto out; if (do_lint) { - if (tokentab[mid].flags & GAWKX) + if ((tokentab[mid].flags & GAWKX) && ! (warntab[mid] & GAWKX)) { lintwarn(_("`%s' is a gawk extension"), tokentab[mid].operator); - if (tokentab[mid].flags & RESX) + warntab[mid] |= GAWKX; + } + if ((tokentab[mid].flags & RESX) && ! (warntab[mid] & RESX)) { lintwarn(_("`%s' is a Bell Labs extension"), tokentab[mid].operator); - if (tokentab[mid].flags & NOT_POSIX) + warntab[mid] |= RESX; + } + if ((tokentab[mid].flags & NOT_POSIX) && ! (warntab[mid] & NOT_POSIX)) { lintwarn(_("POSIX does not allow `%s'"), tokentab[mid].operator); + warntab[mid] |= NOT_POSIX; + } } - if (do_lint_old && (tokentab[mid].flags & NOT_OLD)) + if (do_lint_old && (tokentab[mid].flags & NOT_OLD) + && ! (warntab[mid] & NOT_OLD) + ) { warning(_("`%s' is not supported in old awk"), tokentab[mid].operator); + warntab[mid] |= NOT_OLD; + } + if (tokentab[mid].flags & BREAK) break_allowed++; if (tokentab[mid].flags & CONTINUE) @@ -3764,7 +3841,7 @@ append_param(char *pname) /* dup_parms --- return TRUE if there are duplicate parameters */ static int -dup_parms(NODE *func) +dup_parms(INSTRUCTION *fp, NODE *func) { NODE *np; const char *fname, **names; @@ -3800,7 +3877,7 @@ dup_parms(NODE *func) for (j = 0; j < i; j++) { if (strcmp(names[i], names[j]) == 0) { dups++; - error( + error_ln(fp->source_line, _("function `%s': parameter #%d, `%s', duplicates parameter #%d"), fname, i + 1, names[j], j+1); } @@ -4095,14 +4172,13 @@ func_install(INSTRUCTION *func, INSTRUCTION *def) /* check for function foo(foo) { ... }. bleah. */ for (n = params->rnode; n != NULL; n = n->rnode) { if (strcmp(n->param, params->param) == 0) { - error(_("function `%s': can't use function name as parameter name"), - params->param); - errcount++; + error_ln(func->source_line, + _("function `%s': can't use function name as parameter name"), params->param); return -1; } else if (is_std_var(n->param)) { - error(_("function `%s': can't use special variable `%s' as a function parameter"), - params->param, n->param); - errcount++; + error_ln(func->source_line, + _("function `%s': can't use special variable `%s' as a function parameter"), + params->param, n->param); return -1; } } @@ -4116,8 +4192,8 @@ func_install(INSTRUCTION *func, INSTRUCTION *def) freenode(hp); r = lookup(fname); if (r != NULL) { - error(_("function name `%s' previously defined"), fname); - errcount++; + error_ln(func->source_line, + _("function name `%s' previously defined"), fname); return -1; } else if (fname == builtin_func) /* not a valid function name */ goto remove_params; @@ -4325,7 +4401,8 @@ param_sanity(INSTRUCTION *arglist) for (argl = arglist->nexti; argl; ) { arg = argl->lasti; if (arg->opcode == Op_match_rec) - warning(_("regexp constant for parameter #%d yields boolean value"), i); + warning_ln(arg->source_line, + _("regexp constant for parameter #%d yields boolean value"), i); argl = arg->nexti; i++; } @@ -4681,7 +4758,7 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op) case Op_quotient: if (n2->numbr == 0.0) { /* don't fatalize, allow parsing rest of the input */ - yyerror(_("division by zero attempted")); + error_ln(op->source_line, _("division by zero attempted")); goto regular; } @@ -4690,7 +4767,7 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op) case Op_mod: if (n2->numbr == 0.0) { /* don't fatalize, allow parsing rest of the input */ - yyerror(_("division by zero attempted in `%%'")); + error_ln(op->source_line, _("division by zero attempted in `%%'")); goto regular; } #ifdef HAVE_FMOD @@ -5361,7 +5438,7 @@ add_lint(INSTRUCTION *list, LINTTYPE linttype) if (do_lint) { /* compile-time warning */ if (isnoeffect(ip->opcode)) - lintwarn(_("statement may have no effect")); + lintwarn_ln(ip->source_line, ("statement may have no effect")); } if (ip->opcode == Op_push) { /* run-time warning */ @@ -55,7 +55,8 @@ err(const char *s, const char *emsg, va_list argp) srcfile = NULL; } #endif /* GAWKDEBUG */ - if (sourceline != 0) { + + if (sourceline > 0) { if (source != NULL) (void) fprintf(stderr, "%s:", source); else diff --git a/pc/Makefile.tst b/pc/Makefile.tst index d93baea4..36009d93 100644 --- a/pc/Makefile.tst +++ b/pc/Makefile.tst @@ -168,7 +168,8 @@ LOCALE_CHARSET_TESTS = asort asorti fmttest fnarydel fnparydl lc_num1 mbfw1 \ # List of the tests which should be run with --lint option: -NEED_LINT = defref fmtspcl noeffect nofmtch shadow uninit2 uninit3 uninit4 uninit5 uninitialized +NEED_LINT = defref fmtspcl lintwarn noeffect nofmtch shadow uninit2 +uninit3 uninit4 uninit5 uninitialized # List of the tests which should be run with --lint-old option: NEED_LINT_OLD = lintold @@ -1708,6 +1709,11 @@ lint: @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +lintwarn: + @echo lintwarn + @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + lintold: @echo lintold @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint-old < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/ChangeLog b/test/ChangeLog index 6ef33984..542a9d73 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,10 @@ +Wed Feb 16 21:09:50 2011 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (lintwarn): New test. + * lintwarn.awk, lintwarn.ok: New files from John Haque. + * funsmnam.ok, noeffect.ok, paramdup.ok, paramres.ok: Adjust + after fixes to lint warnings. + Mon Feb 14 21:31:10 2011 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (profile2): Add -v sortcmd=sort to pgawk invocation. diff --git a/test/Makefile.am b/test/Makefile.am index 92372197..b8b5016c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -350,6 +350,8 @@ EXTRA_DIST = \ lintold.awk \ lintold.in \ lintold.ok \ + lintwarn.awk \ + lintwarn.ok \ litoct.awk \ litoct.ok \ localenl.ok \ @@ -764,6 +766,7 @@ GAWK_EXT_TESTS = \ fieldwdth fpat1 funlen fsfwfs fwtest fwtest2 gensub gensub2 getlndir \ gnuops2 gnuops3 gnureops \ icasefs icasers igncdym igncfs ignrcas2 ignrcase indirectcall lint \ + lintwarn \ lintold manyfiles match1 match2 match3 mbstr1 nondec nondec2 patsplit \ posix profile1 profile2 printfbad1 printfbad2 \ procinfs rebuf regx8bit reint reint2 rsstart1 rsstart2 rsstart3 \ @@ -779,7 +782,8 @@ LOCALE_CHARSET_TESTS = asort asorti fmttest fnarydel fnparydl lc_num1 mbfw1 \ mbprintf1 mbprintf2 mbprintf3 rebt8b2 sort1 sprintfc # List of the tests which should be run with --lint option: -NEED_LINT = defref fmtspcl noeffect nofmtch shadow uninit2 uninit3 uninit4 uninit5 uninitialized +NEED_LINT = defref fmtspcl lintwarn noeffect nofmtch shadow \ + uninit2 uninit3 uninit4 uninit5 uninitialized # List of the tests which should be run with --lint-old option: NEED_LINT_OLD = lintold diff --git a/test/Makefile.in b/test/Makefile.in index 37c50e0e..c478318f 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -535,6 +535,8 @@ EXTRA_DIST = \ lintold.awk \ lintold.in \ lintold.ok \ + lintwarn.awk \ + lintwarn.ok \ litoct.awk \ litoct.ok \ localenl.ok \ @@ -948,6 +950,7 @@ GAWK_EXT_TESTS = \ fieldwdth fpat1 funlen fsfwfs fwtest fwtest2 gensub gensub2 getlndir \ gnuops2 gnuops3 gnureops \ icasefs icasers igncdym igncfs ignrcas2 ignrcase indirectcall lint \ + lintwarn \ lintold manyfiles match1 match2 match3 mbstr1 nondec nondec2 patsplit \ posix profile1 profile2 printfbad1 printfbad2 \ procinfs rebuf regx8bit reint reint2 rsstart1 rsstart2 rsstart3 \ @@ -961,7 +964,9 @@ LOCALE_CHARSET_TESTS = asort asorti fmttest fnarydel fnparydl lc_num1 mbfw1 \ # List of the tests which should be run with --lint option: -NEED_LINT = defref fmtspcl noeffect nofmtch shadow uninit2 uninit3 uninit4 uninit5 uninitialized +NEED_LINT = defref fmtspcl lintwarn noeffect nofmtch shadow \ + uninit2 uninit3 uninit4 uninit5 uninitialized + # List of the tests which should be run with --lint-old option: NEED_LINT_OLD = lintold @@ -2649,6 +2654,11 @@ lint: @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +lintwarn: + @echo lintwarn + @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + lintold: @echo lintold @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint-old < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index 4872a504..ea4b76d4 100644 --- a/test/Maketests +++ b/test/Maketests @@ -970,6 +970,11 @@ lint: @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +lintwarn: + @echo lintwarn + @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + lintold: @echo lintold @AWKPATH=$(srcdir) $(AWK) -f $@.awk --lint-old < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/funsmnam.ok b/test/funsmnam.ok index f6465258..e4f2174a 100644 --- a/test/funsmnam.ok +++ b/test/funsmnam.ok @@ -1,2 +1,2 @@ -gawk: funsmnam.awk:6: error: function `foo': can't use function name as parameter name +gawk: funsmnam.awk:1: error: function `foo': can't use function name as parameter name EXIT CODE: 1 diff --git a/test/lintwarn.awk b/test/lintwarn.awk new file mode 100644 index 00000000..cea76bbc --- /dev/null +++ b/test/lintwarn.awk @@ -0,0 +1,38 @@ +# gawk --lint -f lintwarn.awk +BEGINFILE { + getline var + getline +} + +BEGIN { + PROCINFO["sorted_in"] + print + nextfile + delete a + delete(a) + y = /a/ + y == /a/ + /b/ ~ x + length + switch(s) { + case 1: + default: + case 1: + default: + } + break + continue + next + a[] + f(/pqr/) + // + /* */ +} +END { + getline +} +function zz(aa, aa) +{ + return aa +} +@include "" diff --git a/test/lintwarn.ok b/test/lintwarn.ok new file mode 100644 index 00000000..169b0020 --- /dev/null +++ b/test/lintwarn.ok @@ -0,0 +1,39 @@ +gawk: lintwarn.awk:2: warning: `BEGINFILE' is a gawk extension +gawk: lintwarn.awk:3: error: `getline var' invalid inside `BEGINFILE' rule +gawk: lintwarn.awk:4: error: `getline' invalid inside `BEGINFILE' rule +gawk: lintwarn.awk:8: warning: statement may have no effect +gawk: lintwarn.awk:9: warning: plain `print' in BEGIN or END rule should probably be `print ""' +gawk: lintwarn.awk:10: warning: `nextfile' is a gawk extension +gawk: lintwarn.awk:10: error: `nextfile' used in BEGIN action +gawk: lintwarn.awk:11: warning: `delete array' is a gawk extension +gawk: lintwarn.awk:12: warning: `delete(array)' is a non-portable tawk extension +gawk: lintwarn.awk:13: warning: regular expression on right of assignment +gawk: lintwarn.awk:14: warning: regular expression on right of comparison +gawk: lintwarn.awk:14: warning: statement may have no effect +gawk: lintwarn.awk:15: warning: regular expression on left of `~' or `!~' operator +gawk: lintwarn.awk:15: warning: statement may have no effect +gawk: lintwarn.awk:16: warning: call of `length' without parentheses is not portable +gawk: lintwarn.awk:17: warning: `switch' is a gawk extension +gawk: lintwarn.awk:18: warning: `case' is a gawk extension +gawk: lintwarn.awk:19: warning: `default' is a gawk extension +gawk: lintwarn.awk:19: error: duplicate `default' detected in switch body +gawk: lintwarn.awk:18: error: duplicate case values in switch body: 1 +gawk: lintwarn.awk:23: error: `break' is not allowed outside a loop or switch +gawk: lintwarn.awk:24: error: `continue' is not allowed outside a loop +gawk: lintwarn.awk:25: error: `next' used in BEGIN action +gawk: lintwarn.awk:26: a[] +gawk: lintwarn.awk:26: ^ syntax error +gawk: lintwarn.awk:26: error: invalid subscript expression +gawk: lintwarn.awk:26: warning: statement may have no effect +gawk: lintwarn.awk:27: warning: regexp constant for parameter #1 yields boolean value +gawk: lintwarn.awk:28: warning: regexp constant `//' looks like a C++ comment, but is not +gawk: lintwarn.awk:28: warning: statement may have no effect +gawk: lintwarn.awk:29: warning: regexp constant `/* */' looks like a C comment, but is not +gawk: lintwarn.awk:29: warning: statement may have no effect +gawk: lintwarn.awk:32: warning: non-redirected `getline' undefined inside END action +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: warning: function `f' called but never defined +gawk: warning: function `zz' defined but never called directly +EXIT CODE: 1 diff --git a/test/noeffect.ok b/test/noeffect.ok index d2da47a2..e9bed995 100644 --- a/test/noeffect.ok +++ b/test/noeffect.ok @@ -1,4 +1,4 @@ +gawk: noeffect.awk:2: warning: statement may have no effect gawk: noeffect.awk:3: warning: statement may have no effect -gawk: noeffect.awk:4: warning: statement may have no effect gawk: noeffect.awk:2: warning: reference to uninitialized variable `s' gawk: noeffect.awk:3: warning: reference to uninitialized variable `s' diff --git a/test/paramdup.ok b/test/paramdup.ok index 9a9df807..cd71822a 100644 --- a/test/paramdup.ok +++ b/test/paramdup.ok @@ -1,3 +1,3 @@ -gawk: paramdup.awk:4: error: function `foo': parameter #4, `b', duplicates parameter #2 -gawk: paramdup.awk:4: error: function `foo': parameter #5, `a', duplicates parameter #1 +gawk: paramdup.awk:3: error: function `foo': parameter #4, `b', duplicates parameter #2 +gawk: paramdup.awk:3: error: function `foo': parameter #5, `a', duplicates parameter #1 EXIT CODE: 1 diff --git a/test/paramres.ok b/test/paramres.ok index fdd7483c..0687f92d 100644 --- a/test/paramres.ok +++ b/test/paramres.ok @@ -1,2 +1,2 @@ -gawk: paramres.awk:6: error: function `foo': can't use special variable `FS' as a function parameter +gawk: paramres.awk:3: error: function `foo': can't use special variable `FS' as a function parameter EXIT CODE: 1 diff --git a/vms/vmstest.com b/vms/vmstest.com index ee2242b1..949b9f21 100644 --- a/vms/vmstest.com +++ b/vms/vmstest.com @@ -103,7 +103,7 @@ $ list = "indirectcall lint lintold match1" - + " nondec2 patsplit posix profile1 procinfs printfbad1" - + " printfbad2 regx8bit rebuf reint reint2 rsstart1" - + " rsstart2 rsstart3 rstest6 shadow sortfor" - - + " splitarg4 strtonum strftime switch2" + + " splitarg4 strtonum strftime switch2 lintwarn" $ gosub list_of_tests $ return $ @@ -899,6 +899,15 @@ $ cmp shadow.ok _shadow.tmp $ if $status then rm _shadow.tmp; $ return $ +$lintwarn: echo "lintwarn" +$ set noOn +$ AWKPATH_srcdir +$ gawk --lint -f lintwarn.awk >_lintwarn.tmp 2>&1 +$ set On +$ cmp lintwarn.ok _lintwarn.tmp +$ if $status then rm _lintwarn.tmp; +$ return +$ $longsub: echo "longsub" $ set noOn $ gawk -f longsub.awk longsub.in >_longsub.tmp |