aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--Checklist1
-rw-r--r--awk.h1
-rw-r--r--awkgram.c699
-rw-r--r--awkgram.y327
-rw-r--r--msg.c3
-rw-r--r--pc/Makefile.tst8
-rw-r--r--test/ChangeLog7
-rw-r--r--test/Makefile.am6
-rw-r--r--test/Makefile.in12
-rw-r--r--test/Maketests5
-rw-r--r--test/funsmnam.ok2
-rw-r--r--test/lintwarn.awk38
-rw-r--r--test/lintwarn.ok39
-rw-r--r--test/noeffect.ok2
-rw-r--r--test/paramdup.ok4
-rw-r--r--test/paramres.ok2
-rw-r--r--vms/vmstest.com11
18 files changed, 741 insertions, 446 deletions
diff --git a/ChangeLog b/ChangeLog
index d7478a82..b0c003c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/Checklist b/Checklist
index 0029255a..47c11cb7 100644
--- a/Checklist
+++ b/Checklist
@@ -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
diff --git a/awk.h b/awk.h
index 919d7b03..726131e6 100644
--- a/awk.h
+++ b/awk.h
@@ -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
diff --git a/awkgram.c b/awkgram.c
index 5f794df4..350dbbce 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -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 */
diff --git a/awkgram.y b/awkgram.y
index 279b502b..c024afd5 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -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 */
diff --git a/msg.c b/msg.c
index a75396f5..84a4e5cd 100644
--- a/msg.c
+++ b/msg.c
@@ -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