diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-05 23:54:47 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-05 23:54:47 +0300 |
commit | 7c94a5dc87cff630f2629b054b287372fc71991d (patch) | |
tree | cb738da9ebf9383e96aa3995941ef71ff4d459cf | |
parent | 09ddf182b45b1ba890272eaa766ad3e7a3ae3bd5 (diff) | |
download | mailfromd-7c94a5dc87cff630f2629b054b287372fc71991d.tar.gz mailfromd-7c94a5dc87cff630f2629b054b287372fc71991d.tar.bz2 |
Improve locations in diagnostic messages (port b4e793c6329 from master).
* mfd/deprecation.c (deprecation_warning_locus): New function.
(deprecation_warning): Use print_parse_message.
* mfd/gram.y: Improve error diagnostics by using Bison's locations
feature.
* mfd/lex.l (advance_line): Set point and leng to 0.
(YY_USER_ACTION): Set yyloc.
(keyword): Remove. Rely on YY_USER_ACTION for setting locations.
(print_parse_message): Change scope of visibility.
Print column information if location_column_option is set.
(vparse_warning): Remove.
* mfd/mailfromd.h (location_column_option): New extern.
(struct locus): New members: point and leng.
(LOCUS_EQ): Avoid coredumps on NULL file names.
(mf_yyltype_t): New typedef.
(YYLTYPE): New define.
(vparse_warning): Remove.
(print_parse_message): New proto.
(deprecation_warning_locus): New proto.
* mfd/main.c (location_column_option): New variable.
(OPTION_LOCATION_COLUMN): New option.
(options): New option --location-column.
(parse_opt): Handle OPTION_LOCATION_COLUMN.
* mfd/pp.c (assign_locus): Reset point and leng.
* tests/poll04.at: Reflect changes in error messages.
-rw-r--r-- | mfd/deprecation.c | 15 | ||||
-rw-r--r-- | mfd/gram.y | 323 | ||||
-rw-r--r-- | mfd/lex.l | 173 | ||||
-rw-r--r-- | mfd/mailfromd.h | 21 | ||||
-rw-r--r-- | mfd/main.c | 9 | ||||
-rw-r--r-- | mfd/pp.c | 2 | ||||
-rw-r--r-- | tests/poll04.at | 2 |
7 files changed, 323 insertions, 222 deletions
diff --git a/mfd/deprecation.c b/mfd/deprecation.c index 3585ecc6..04d45fec 100644 --- a/mfd/deprecation.c +++ b/mfd/deprecation.c @@ -38,13 +38,26 @@ enable_deprecation_warnings() } void +deprecation_warning_locus(const struct locus *locus, const char *fmt, ...) +{ + if (enable_deprecation_warnings()) { + va_list ap; + + va_start(ap, fmt); + print_parse_message(locus, _("warning"), fmt, ap); + va_end(ap); + } + deprecated_features = 1; +} + +void deprecation_warning(const char *fmt, ...) { if (enable_deprecation_warnings()) { va_list ap; va_start(ap, fmt); - vparse_warning(fmt, ap); + print_parse_message(get_locus(), _("warning"), fmt, ap); va_end(ap); } deprecated_features = 1; @@ -212,12 +212,13 @@ type_to_string(data_type_t t) } static int -check_func_usage(struct function *fp) +check_func_usage(struct function *fp, const struct locus *locus) { switch (outer_context) { case context_handler: if (fp->statemask && !(EXMASK(state_tag) & fp->statemask)) { - parse_error(_("function `%s' cannot be used in " + parse_error_locus(locus, + _("function `%s' cannot be used in " "prog `%s'"), fp->sym.name, state_to_string(state_tag)); @@ -283,9 +284,36 @@ _create_alias(void *item, void *data) return 0; } +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do { \ + if (N) { \ + (Current).beg = YYRHSLOC(Rhs, 1).beg; \ + (Current).end = YYRHSLOC(Rhs, N).end; \ + } else { \ + (Current).beg = YYRHSLOC(Rhs, 0).end; \ + (Current).end = (Current).beg; \ + } \ + } while (0) + +#define YY_LOCATION_PRINT(File, Loc) do { \ + if (LOCUS_EQ(&(Loc).beg, &(Loc).end)) \ + fprintf(File, "%s:%lu.%lu-%lu.%lu", \ + (Loc).beg.file, \ + (Loc).beg.line, (Loc).beg.point, \ + (Loc).end.line, (Loc).end.point); \ + else \ + fprintf(File, "%s:%lu.%lu-%s:%lu.%lu", \ + (Loc).beg.file, \ + (Loc).beg.line, (Loc).beg.point, \ + (Loc).end.file, \ + (Loc).end.line, (Loc).end.point); \ + } while (0) + + %} %error-verbose +%locations /*%expect 1*/ %union { @@ -294,7 +322,6 @@ _create_alias(void *item, void *data) NODE *node; struct return_node ret; struct poll_data poll; - struct locus locus; struct pollarg { int kw; NODE *expr; @@ -309,7 +336,6 @@ _create_alias(void *item, void *data) struct variable *var; enum smtp_state state; struct { - struct locus locus; int qualifier; } matchtype; data_type_t type; @@ -333,7 +359,6 @@ _create_alias(void *item, void *data) struct case_stmt *case_stmt; struct loop_node loop; struct { - struct locus locus; int code; } progspecial; mu_list_t list; @@ -341,7 +366,7 @@ _create_alias(void *item, void *data) char *string; }; -%token <locus> T_ACCEPT "accept" +%token T_ACCEPT "accept" T_REJECT "reject" T_TEMPFAIL "tempfail" T_CONTINUE "continue" @@ -546,17 +571,20 @@ opt_moddecl: /* empty */ moddecl : T_MODULE literal '.' { if (top_module->dclname) - parse_error(_("duplicate module declaration")); + parse_error_locus(&@2.beg, + _("duplicate module declaration")); else top_module->dclname = $2->text; } | T_MODULE literal qualifier '.' { if (top_module->dclname) - parse_error(_("duplicate module declaration")); + parse_error_locus(&@2.beg, + _("duplicate module declaration")); else { if (($3 & (SYM_STATIC|SYM_PUBLIC)) == 0) - parse_error(_("invalid module declaration")); + parse_error_locus(&@3.beg, + _("invalid module declaration")); top_module->dclname = $2->text; top_module->flags = $3; } @@ -599,7 +627,7 @@ literal : T_STRING decl : T_PROG state_ident T_DO stmtlist T_DONE { - $$ = alloc_node(node_type_progdecl, &$1); + $$ = alloc_node(node_type_progdecl, &@1.beg); $$->v.progdecl.tag = $2; $$->v.progdecl.auto_count = forget_autos(PARMCOUNT(), 0, 0); @@ -614,7 +642,7 @@ decl : T_PROG state_ident T_DO stmtlist T_DONE NODE *np = progspecial[$1.code]; if (!np) { - np = alloc_node(node_type_progdecl, &$1.locus); + np = alloc_node(node_type_progdecl, &@1.beg); $$ = progspecial[$1.code] = np; np->v.progdecl.tag = state_tag; np->v.progdecl.tree = $3.head; @@ -637,16 +665,16 @@ decl : T_PROG state_ident T_DO stmtlist T_DONE | qualifiers T_FUNC fundecl T_DO stmtlist T_DONE { if ($1 & SYM_PRECIOUS) - parse_error_locus(&$2, + parse_error_locus(&@2.beg, _("precious used with func")); if (($1 & (SYM_STATIC|SYM_PUBLIC)) == (SYM_STATIC|SYM_PUBLIC)) - parse_error_locus(&$2, + parse_error_locus(&@2.beg, _("`static' and `public' " "used together")); func->sym.flags = $1; func->node = $5.head; - $$ = declare_function(func, &$2, + $$ = declare_function(func, &@2.beg, forget_autos(PARMCOUNT() + FUNC_HIDDEN_ARGS(func), 0, FUNC_HIDDEN_ARGS(func))); outer_context = inner_context = context_none; @@ -666,14 +694,12 @@ progspecial: T_BEGIN { state_tag = smtp_state_begin; outer_context = inner_context = context_handler; - $$.locus = $1; $$.code = PS_BEGIN; } | T_END { state_tag = smtp_state_end; outer_context = inner_context = context_handler; - $$.locus = $1; $$.code = PS_END; } ; @@ -691,7 +717,8 @@ vardecl : qualifiers T_TYPE varname if (($1 & (SYM_STATIC|SYM_PUBLIC)) == (SYM_STATIC|SYM_PUBLIC)) - parse_error(_("`static' and `public' " + parse_error_locus(&@1.beg, + _("`static' and `public' " "used together")); var = vardecl($3->text, $2, storage_extern, NULL); if (!var) @@ -705,7 +732,8 @@ vardecl : qualifiers T_TYPE varname if (($1 & (SYM_STATIC|SYM_PUBLIC)) == (SYM_STATIC|SYM_PUBLIC)) - parse_error(_("`static' and `public' " + parse_error_locus(&@1.beg, + _("`static' and `public' " "used together")); var = vardecl($3->text, $2, storage_extern, NULL); @@ -756,7 +784,7 @@ vardecl : qualifiers T_TYPE varname yyerror("initializer element is not constant"); YYERROR; } - if (!externdecl($2->text, &value, &$1)) + if (!externdecl($2->text, &value, &@1.beg)) YYERROR; } ; @@ -796,11 +824,11 @@ constdecl : qualifiers T_CONST varname expr struct variable *pvar; if ($1 & SYM_PRECIOUS) - parse_error_locus(&$2, + parse_error_locus(&@1.beg, _("precious used with const")); if (($1 & (SYM_STATIC|SYM_PUBLIC)) == (SYM_STATIC|SYM_PUBLIC)) - parse_error_locus(&$2, + parse_error_locus(&@1.beg, _("`static' and `public' " "used together")); /* FIXME: This is necessary because constants can be @@ -831,7 +859,7 @@ constdecl : qualifiers T_CONST varname expr yyerror(_("initializer element is not constant")); YYERROR; } - define_constant($3->text, &value, $1, &$2); + define_constant($3->text, &value, $1, &@2.beg); $$ = NULL; } ; @@ -857,7 +885,7 @@ fundecl : varname '(' parmdecl ')' aliasdecl retdecl $3.count, $3.optcount, $3.varargs, ptypes, $6, - get_locus()); + &@1.beg); if ($5) { mu_list_do($5, _create_alias, $$); mu_list_destroy(&$5); @@ -907,6 +935,7 @@ parmlist : parm { $$.count = 1; $$.varargs = 0; + $$.optcount = 0; $$.head = $$.tail = $1; } | parmlist ',' parm @@ -983,7 +1012,8 @@ state_ident: T_IDENTIFIER { $$ = string_to_state($1->text); if ($$ == smtp_state_none) - parse_error(_("unknown smtp state tag: %s"), + parse_error_locus(&@1.beg, + _("unknown smtp state tag: %s"), $1->text); state_tag = $$; outer_context = inner_context = context_handler; @@ -1035,18 +1065,19 @@ asgn : T_SET varname expr data_type_t t = node_type($3); if (t == dtype_unspecified) { - parse_error(_("unspecified value not ignored as " + parse_error_locus(&@3.beg, + _("unspecified value not ignored as " "it should be")); YYERROR; } var = variable_lookup($2->text); if (!var) { - var = vardecl($2->text, t, storage_auto, &$1); + var = vardecl($2->text, t, storage_auto, &@1.beg); if (!var) YYERROR; } - $$ = create_asgn_node(var, $3, &$1); + $$ = create_asgn_node(var, $3, &@1.beg); if (!$$) YYERROR; } @@ -1064,7 +1095,7 @@ autodcl : T_TYPE varname storage_auto, NULL); if (!var) YYERROR; - $$ = create_asgn_node(var, $3, get_locus()); + $$ = create_asgn_node(var, $3, &@1.beg); if (!$$) YYERROR; } @@ -1074,10 +1105,12 @@ action : sendmail_action { if (inner_context == context_handler) { if (state_tag == smtp_state_begin) - parse_error(_("Sendmail action is not " + parse_error_locus(&@1.beg, + _("Sendmail action is not " "allowed in begin block")); else if (state_tag == smtp_state_end) - parse_error(_("Sendmail action is not " + parse_error_locus(&@1.beg, + _("Sendmail action is not " "allowed in end block")); } } @@ -1085,16 +1118,17 @@ action : sendmail_action { if (inner_context == context_handler && state_tag == smtp_state_end) - parse_error(_("header action is not allowed " + parse_error_locus(&@1.beg, + _("header action is not allowed " "in end block")); } | T_PASS { - $$ = alloc_node(node_type_noop, &$1); + $$ = alloc_node(node_type_noop, &@1.beg); } | T_ECHO expr { - $$ = alloc_node(node_type_echo, &$1); + $$ = alloc_node(node_type_echo, &@1.beg); $$->v.node = cast_to(dtype_string, $2); } ; @@ -1104,19 +1138,19 @@ sendmail_action: { if ($2.code || $2.xcode || $2.message) parse_warning(_("arguments are ignored for accept")); - $$ = alloc_node(node_type_result, &$1); + $$ = alloc_node(node_type_result, &@1.beg); $$->v.ret = $2; $$->v.ret.stat = SMFIS_ACCEPT; } | T_REJECT maybe_triplet { - $$ = alloc_node(node_type_result, &$1); + $$ = alloc_node(node_type_result, &@1.beg); $$->v.ret = $2; $$->v.ret.stat = SMFIS_REJECT; } | T_REJECT '(' maybe_expr ',' maybe_xcode_expr ',' maybe_expr ')' { - $$ = alloc_node(node_type_result, &$1); + $$ = alloc_node(node_type_result, &@1.beg); $$->v.ret.stat = SMFIS_REJECT; $$->v.ret.code = $3 ? cast_to(dtype_string, $3) : NULL; $$->v.ret.xcode = $5 ? cast_to(dtype_string, $5) : NULL; @@ -1124,13 +1158,13 @@ sendmail_action: } | T_TEMPFAIL maybe_triplet { - $$ = alloc_node(node_type_result, &$1); + $$ = alloc_node(node_type_result, &@1.beg); $$->v.ret = $2; $$->v.ret.stat = SMFIS_TEMPFAIL; } | T_TEMPFAIL '(' maybe_expr ',' maybe_xcode_expr ',' maybe_expr ')' { - $$ = alloc_node(node_type_result, &$1); + $$ = alloc_node(node_type_result, &@1.beg); $$->v.ret.stat = SMFIS_TEMPFAIL; $$->v.ret.code = $3 ? cast_to(dtype_string, $3) : NULL; $$->v.ret.xcode = $5 ? cast_to(dtype_string, $5) : NULL; @@ -1138,13 +1172,13 @@ sendmail_action: } | T_CONTINUE { - $$ = alloc_node(node_type_result, &$1); + $$ = alloc_node(node_type_result, &@1.beg); memset(&$$->v.ret, 0, sizeof $$->v.ret); $$->v.ret.stat = SMFIS_CONTINUE; } | T_DISCARD { - $$ = alloc_node(node_type_result, &$1); + $$ = alloc_node(node_type_result, &@1.beg); memset(&$$->v.ret, 0, sizeof $$->v.ret); $$->v.ret.stat = SMFIS_DISCARD; } @@ -1153,7 +1187,7 @@ sendmail_action: maybe_xcode_expr: maybe_expr | xcode { - $$ = alloc_node(node_type_string, get_locus()); + $$ = alloc_node(node_type_string, &@1.beg); $$->v.literal = $1; } ; @@ -1162,21 +1196,21 @@ maybe_xcode_expr: maybe_expr header_action: T_ADD string expr { - $$ = alloc_node(node_type_header, &$1); + $$ = alloc_node(node_type_header, &@1.beg); $$->v.hdr.opcode = header_add; $$->v.hdr.name = $2; $$->v.hdr.value = cast_to(dtype_string, $3); } | T_REPLACE string expr { - $$ = alloc_node(node_type_header, &$1); + $$ = alloc_node(node_type_header, &@1.beg); $$->v.hdr.opcode = header_replace; $$->v.hdr.name = $2; $$->v.hdr.value = cast_to(dtype_string, $3); } | T_DELETE string { - $$ = alloc_node(node_type_header, &$1); + $$ = alloc_node(node_type_header, &@1.beg); $$->v.hdr.opcode = header_delete; $$->v.hdr.name = $2; $$->v.hdr.value = NULL; @@ -1192,30 +1226,30 @@ maybe_triplet: /* empty */ triplet : code { - $$.code = alloc_node(node_type_string, get_locus()); + $$.code = alloc_node(node_type_string, &@1.beg); $$.code->v.literal = $1; $$.xcode = NULL; $$.message = NULL; } | code xcode { - $$.code = alloc_node(node_type_string, get_locus()); + $$.code = alloc_node(node_type_string, &@1.beg); $$.code->v.literal = $1; - $$.xcode = alloc_node(node_type_string, get_locus()); + $$.xcode = alloc_node(node_type_string, &@2.beg); $$.xcode->v.literal = $2; $$.message = NULL; } | code xcode expr { - $$.code = alloc_node(node_type_string, get_locus()); + $$.code = alloc_node(node_type_string, &@1.beg); $$.code->v.literal = $1; - $$.xcode = alloc_node(node_type_string, get_locus()); + $$.xcode = alloc_node(node_type_string, &@2.beg); $$.xcode->v.literal = $2; $$.message = cast_to(dtype_string, $3); } | code expr { - $$.code = alloc_node(node_type_string, get_locus()); + $$.code = alloc_node(node_type_string, &@1.beg); $$.code->v.literal = $1; $$.xcode = NULL; $$.message = cast_to(dtype_string, $2); @@ -1265,7 +1299,7 @@ condition : if_cond if_cond : T_IF expr stmtlist else_cond T_FI { - $$ = alloc_node(node_type_if, &$1); + $$ = alloc_node(node_type_if, &@1.beg); $$->v.cond.cond = $2; $$->v.cond.if_true = $3.head; $$->v.cond.if_false = $4; @@ -1278,7 +1312,7 @@ else_cond : /* empty */ } | T_ELIF expr stmtlist else_cond { - $$ = alloc_node(node_type_if, &$1); + $$ = alloc_node(node_type_if, &@1.beg); $$->v.cond.cond = $2; $$->v.cond.if_true = $3.head; $$->v.cond.if_false = $4; @@ -1293,7 +1327,7 @@ case_cond : T_SWITCH expr T_DO cond_branches T_DONE { struct case_stmt *defcase = NULL, *pcase, *prev; - $$ = alloc_node(node_type_switch, &$1); + $$ = alloc_node(node_type_switch, &@1.beg); $$->v.switch_stmt.node = $2; /* Make sure there is only one default case and @@ -1323,7 +1357,7 @@ case_cond : T_SWITCH expr T_DO cond_branches T_DONE if (!defcase) { defcase = xmalloc(sizeof *defcase); - defcase->locus = *get_locus(); + defcase->locus = @5.beg; defcase->valist = NULL; defcase->node = alloc_node(node_type_noop, &defcase->locus); @@ -1348,7 +1382,7 @@ cond_branch: T_CASE valist ':' stmtlist { $$ = xmalloc(sizeof *$$); $$->next = NULL; - $$->locus = $1; + $$->locus = @1.beg; $$->valist = $2.head; $$->node = $4.head; } @@ -1356,7 +1390,7 @@ cond_branch: T_CASE valist ':' stmtlist { $$ = xmalloc(sizeof *$$); $$->next = NULL; - $$->locus = $1; + $$->locus = @1.beg; $$->valist = NULL; $$->node = $3.head; } @@ -1394,7 +1428,8 @@ value : T_STRING string : value { if ($1.type != dtype_string) { - parse_error(_("expected string, but found %s"), + parse_error_locus(&@1.beg, + _("expected string, but found %s"), type_to_string($1.type)); /* Make sure we return something usable: */ $$ = string_alloc("ERROR", 5); @@ -1405,24 +1440,20 @@ string : value matches : T_MATCHES { - $$.locus = $1; $$.qualifier = 0; } | T_MXMATCHES { - $$.locus = $1; $$.qualifier = QUALIFIER_MX; } ; fnmatches : T_FNMATCHES { - $$.locus = $1; $$.qualifier = 0; } | T_MXFNMATCHES { - $$.locus = $1; $$.qualifier = QUALIFIER_MX; } ; @@ -1434,7 +1465,7 @@ loopstmt : T_LOOP loop_ident opt_loop_parms T_DO stmtlist T_DONE opt_while { leave_loop(); $3.end_while = $7; - $$ = alloc_node(node_type_loop, &$1); + $$ = alloc_node(node_type_loop, &@1.beg); $3.body = $5.head; $3.ident = $2; $$->v.loop = $3; @@ -1486,19 +1517,22 @@ loop_parm_list: loop_parm switch ($3.kw) { case 0: if ($$.stmt) - parse_error(_("duplicate loop increment")); + parse_error_locus(&@3.beg, + _("duplicate loop increment")); $$.stmt = $3.expr; break; case T_FOR: if ($$.for_stmt) - parse_error(_("duplicate for statement")); + parse_error_locus(&@3.beg, + _("duplicate for statement")); $$.for_stmt = $3.expr; break; case T_WHILE: if ($$.beg_while) - parse_error(_("duplicate while statement")); + parse_error_locus(&@3.beg, + _("duplicate while statement")); $$.beg_while = $3.expr; break; @@ -1539,27 +1573,34 @@ jumpstmt : T_BREAK opt_ident { if (!within_loop($2)) { if ($2) - parse_error(_("no such loop: %s"), + parse_error_locus(&@2.beg, + _("no such loop: %s"), $2->text); - parse_error(_("`break' used outside of `loop'")); + parse_error_locus(&@1.beg, + _("`break' used outside of `loop'")); YYERROR; } - $$ = alloc_node(node_type_break, &$1); + $$ = alloc_node(node_type_break, &@1.beg); $$->v.literal = $2; } | T_NEXT opt_ident { if (!within_loop($2)) { if ($2) { - parse_error(_("no such loop: %s"), $2->text); - parse_error(_("`next' used outside `loop'")); + parse_error_locus(&@2.beg, + _("no such loop: %s"), + $2->text); + parse_error_locus(&@1.beg, + _("`next' used outside `loop'")); YYERROR; } else { - parse_error(_("`next' is used outside `loop'; did you mean `pass'?")); + parse_error_locus(&@1.beg, + _("`next' is used outside `loop'; " + "did you mean `pass'?")); YYERROR; } } else { - $$ = alloc_node(node_type_next, &$1); + $$ = alloc_node(node_type_next, &@1.beg); $$->v.literal = $2; } } @@ -1569,48 +1610,48 @@ jumpstmt : T_BREAK opt_ident /* Expressions */ expr : T_NOT expr { - $$ = alloc_node(node_type_un, &$1); + $$ = alloc_node(node_type_un, &@1.beg); $$->v.un.opcode = unary_not; $$->v.un.arg = cast_to(dtype_number, $2); } | expr T_EQ expr { - $$ = alloc_node(node_type_bin, &$2); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_eq; $$->v.bin.arg[0] = $1; $$->v.bin.arg[1] = cast_to(node_type($1), $3); } | expr T_NE expr { - $$ = alloc_node(node_type_bin, &$2); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_ne; $$->v.bin.arg[0] = $1; $$->v.bin.arg[1] = cast_to(node_type($1), $3); } | expr T_LT expr { - $$ = alloc_node(node_type_bin, &$2); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_lt; $$->v.bin.arg[0] = $1; $$->v.bin.arg[1] = cast_to(node_type($1), $3); } | expr T_LE expr { - $$ = alloc_node(node_type_bin, &$2); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_le; $$->v.bin.arg[0] = $1; $$->v.bin.arg[1] = cast_to(node_type($1), $3); } | expr T_GT expr { - $$ = alloc_node(node_type_bin, &$2); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_gt; $$->v.bin.arg[0] = $1; $$->v.bin.arg[1] = cast_to(node_type($1), $3); } | expr T_GE expr { - $$ = alloc_node(node_type_bin, &$2); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_ge; $$->v.bin.arg[0] = $1; $$->v.bin.arg[1] = cast_to(node_type($1), $3); @@ -1619,18 +1660,19 @@ expr : T_NOT expr { NODE *p; - $$ = alloc_node(node_type_bin, &$2.locus); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_match; $$->v.bin.qualifier = $2.qualifier; $$->v.bin.arg[0] = cast_to(dtype_string, $1); - $$->v.bin.arg[1] = p = alloc_node(node_type_regcomp, &$2.locus); + $$->v.bin.arg[1] = p = alloc_node(node_type_regcomp, + &@2.beg); p->v.regcomp_data.expr = cast_to(dtype_string, $3); p->v.regcomp_data.flags = regex_flags; p->v.regcomp_data.regind = -1; } | expr fnmatches expr %prec T_MATCHES { - $$ = alloc_node(node_type_bin, &$2.locus); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_fnmatch; $$->v.bin.qualifier = $2.qualifier; $$->v.bin.arg[0] = cast_to(dtype_string, $1); @@ -1638,14 +1680,14 @@ expr : T_NOT expr } | expr T_OR expr { - $$ = alloc_node(node_type_bin, &$2); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_or; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); } | expr T_AND expr { - $$ = alloc_node(node_type_bin, &$2); + $$ = alloc_node(node_type_bin, &@2.beg); $$->v.bin.opcode = bin_and; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); @@ -1663,55 +1705,55 @@ maybe_expr : /* empty */ simp_expr : atom_expr | simp_expr '+' simp_expr { - $$ = alloc_node(node_type_bin, get_locus()); + $$ = alloc_node(node_type_bin, &@1.beg); $$->v.bin.opcode = bin_add; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); } | simp_expr '.' simp_expr { - $$ = alloc_node(node_type_concat, get_locus()); + $$ = alloc_node(node_type_concat, &@2.beg); $$->v.concat.arg[0] = cast_to(dtype_string, $1); $$->v.concat.arg[1] = cast_to(dtype_string, $3); } | simp_expr '-' simp_expr { - $$ = alloc_node(node_type_bin, get_locus()); + $$ = alloc_node(node_type_bin, &@1.beg); $$->v.bin.opcode = bin_sub; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); } | simp_expr '*' simp_expr { - $$ = alloc_node(node_type_bin, get_locus()); + $$ = alloc_node(node_type_bin, &@1.beg); $$->v.bin.opcode = bin_mul; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); } | simp_expr '/' simp_expr { - $$ = alloc_node(node_type_bin, get_locus()); + $$ = alloc_node(node_type_bin, &@1.beg); $$->v.bin.opcode = bin_div; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); } | simp_expr T_LOGAND simp_expr { - $$ = alloc_node(node_type_bin, get_locus()); + $$ = alloc_node(node_type_bin, &@1.beg); $$->v.bin.opcode = bin_logand; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); } | simp_expr T_LOGOR simp_expr { - $$ = alloc_node(node_type_bin, get_locus()); + $$ = alloc_node(node_type_bin, &@1.beg); $$->v.bin.opcode = bin_logor; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); } | simp_expr T_LOGXOR simp_expr { - $$ = alloc_node(node_type_bin, get_locus()); + $$ = alloc_node(node_type_bin, &@1.beg); $$->v.bin.opcode = bin_logxor; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); @@ -1734,7 +1776,7 @@ atom_expr : funcall | atom | '-' simp_expr %prec T_UMINUS { - $$ = alloc_node(node_type_un, get_locus()); + $$ = alloc_node(node_type_un, &@1.beg); $$->v.un.opcode = unary_minus; $$->v.un.arg = cast_to(dtype_number, $2); } @@ -1744,7 +1786,7 @@ atom_expr : funcall } | T_LOGNOT simp_expr %prec T_UMINUS { - $$ = alloc_node(node_type_un, get_locus()); + $$ = alloc_node(node_type_un, &@1.beg); $$->v.un.opcode = unary_lognot; $$->v.un.arg = cast_to(dtype_number, $2); } @@ -1752,31 +1794,31 @@ atom_expr : funcall atom : T_SYMBOL { - $$ = create_node_symbol($1, get_locus()); + $$ = create_node_symbol($1, &@1.beg); } | T_NUMBER { - $$ = alloc_node(node_type_number, get_locus()); + $$ = alloc_node(node_type_number, &@1.beg); $$->v.number = $1; } | T_BACKREF { - $$ = create_node_backref($1, get_locus()); + $$ = create_node_backref($1, &@1.beg); } | argref | T_ARGCOUNT { - $$ = create_node_argcount(&$1); + $$ = create_node_argcount(&@1.beg); } | '@' T_VARIABLE { - $$ = alloc_node(node_type_offset, get_locus()); + $$ = alloc_node(node_type_offset, &@1.beg); $$->v.var_ref.variable = $2; $$->v.var_ref.nframes = catch_nesting; } | T_VAPTR paren_argref { - $$ = alloc_node(node_type_vaptr, get_locus()); + $$ = alloc_node(node_type_vaptr, &@1.beg); $$->v.node = $2; } | strcat @@ -1785,7 +1827,7 @@ atom : T_SYMBOL strcat : strval | strcat strval { - $$ = alloc_node(node_type_concat, get_locus()); + $$ = alloc_node(node_type_concat, &@2.beg); $$->v.concat.arg[0] = $1; $$->v.concat.arg[1] = $2; } @@ -1793,7 +1835,7 @@ strcat : strval strval : T_STRING { - $$ = alloc_node(node_type_string, get_locus()); + $$ = alloc_node(node_type_string, &@1.beg); $$->v.literal = $1; } | T_COMPOSE @@ -1801,30 +1843,32 @@ strval : T_STRING argref : variable { - $$ = create_node_variable($1, get_locus()); + $$ = create_node_variable($1, &@1.beg); } | T_ARG { - $$ = create_node_arg($1, get_locus()); + $$ = create_node_arg($1, &@1.beg); } | T_ARGX '(' expr ')' { if (outer_context == context_function) { if (func->varargs) { - $$ = alloc_node(node_type_argx, &$1); + $$ = alloc_node(node_type_argx, &@1.beg); $$->v.argx.nargs = PARMCOUNT() + FUNC_HIDDEN_ARGS(func); $$->v.argx.node = $3; } else { - $$ = alloc_node(node_type_noop, &$1); - parse_error(_("$(expr) is allowed only " + $$ = alloc_node(node_type_noop, &@1.beg); + parse_error_locus(&@1.beg, + _("$(expr) is allowed only " "in a function with " "variable number of " "argumen |