Commit 3a78309a 3a78309aa59c245c14e29d3e7eb953c6a2ea1035 by Sergey Poznyakoff

Switch to new locus types

* include/mailutils/types.hin (mu_locus): Remove.

* include/mailutils/diag.h (mu_diag_at_locus): Remove.
(mu_diag_at_locus_point,mu_diag_at_locus_range): New protos.
* include/mailutils/mailutils.h: Include locus.h

* include/mailutils/stream.h (MU_IOCTL_LOGSTREAM_GET_LOCUS)
(MU_IOCTL_LOGSTREAM_SET_LOCUS): Remove.
* libmailutils/stream/logstream.c (_log_ctl): Reflect this.
* libmailutils/tests/logstr.at: Remove the related test.
* libmailutils/tests/logstr.c: Ditto.

* libmailutils/cfg/Makefile.am: Add new header.
* libmailutils/cfg/cfg.h: New file.
* libmailutils/cfg/format.c: Use mu_locus_range
* libmailutils/cfg/lexer.l: Use the mu_linetrack facility
* libmailutils/cfg/parser.y: LIkewise.
* libmailutils/diag/diag.c (mu_diag_at_locus): Remove.
(mu_diag_at_locus_point,mu_diag_at_locus_range): New protos.

* comsat/action.c: Use mu_locus_point and mu_locus_range
instead of the removed mu_locus.
* include/mailutils/auth.h: Likewise.
* include/mailutils/cfg.h: Likewise.
* include/mailutils/sieve.h: Likewise.
* libmailutils/base/wicket.c: Likewise.
* libmailutils/tests/wicket.c: Likewise.
* libmu_auth/radius.c: Likewise.
* libmu_sieve/actions.c: Likewise.
* libmu_sieve/comparator.c: Likewise.
* libmu_sieve/extensions/moderator.c: Likewise.
* libmu_sieve/mem.c: Likewise.
* libmu_sieve/prog.c: Likewise.
* libmu_sieve/require.c: Likewise.
* libmu_sieve/runtime.c: Likewise.
* libmu_sieve/sieve-priv.h: Likewise.
* libmu_sieve/sieve.l: Use the mu_linetrack facility.
* libmu_sieve/sieve.y: Likewise.
* libmu_sieve/util.c: Use mu_locus_point and mu_locus_range
instead of the removed mu_locus
* libmu_sieve/variables.c: Likewise.
* mail/source.c: Likewise.
* mu/libexec/dbm.c: Likewise.
* mu/libexec/logger.c: Likewise.
* mu/libexec/wicket.c: Likewise.
* sieve/sieve.c: Likewise.
* sieve/tests/i-numeric.at: Update expected locations
1 parent 16383a01
...@@ -298,7 +298,7 @@ struct biffrc_environ ...@@ -298,7 +298,7 @@ struct biffrc_environ
298 mu_stream_t logstr; 298 mu_stream_t logstr;
299 mu_message_t msg; 299 mu_message_t msg;
300 mu_stream_t input; 300 mu_stream_t input;
301 struct mu_locus locus; 301 struct mu_locus_range locus;
302 int use_default; 302 int use_default;
303 char *errbuf; 303 char *errbuf;
304 size_t errsize; 304 size_t errsize;
...@@ -523,16 +523,16 @@ eval_biffrc (struct biffrc_environ *env) ...@@ -523,16 +523,16 @@ eval_biffrc (struct biffrc_environ *env)
523 ws.ws_comment = "#"; 523 ws.ws_comment = "#";
524 wsflags = MU_WRDSF_DEFFLAGS | MU_WRDSF_COMMENT; 524 wsflags = MU_WRDSF_DEFFLAGS | MU_WRDSF_COMMENT;
525 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 525 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
526 MU_IOCTL_LOGSTREAM_SET_LOCUS, &env->locus); 526 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &env->locus);
527 mu_stream_ioctl (env->logstr, MU_IOCTL_LOGSTREAM, 527 mu_stream_ioctl (env->logstr, MU_IOCTL_LOGSTREAM,
528 MU_IOCTL_LOGSTREAM_SET_LOCUS, &env->locus); 528 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &env->locus);
529 while (mu_stream_getline (env->input, &stmt, &size, &n) == 0 && n > 0) 529 while (mu_stream_getline (env->input, &stmt, &size, &n) == 0 && n > 0)
530 { 530 {
531 if (strncmp (stmt, "#line ", 6) == 0) 531 if (strncmp (stmt, "#line ", 6) == 0)
532 { 532 {
533 char *p; 533 char *p;
534 534
535 env->locus.mu_line = strtoul (stmt + 6, &p, 10); 535 env->locus.beg.mu_line = strtoul (stmt + 6, &p, 10);
536 if (*p != '\n') 536 if (*p != '\n')
537 { 537 {
538 report_error (env, _("malformed #line directive: %s")); 538 report_error (env, _("malformed #line directive: %s"));
...@@ -541,10 +541,10 @@ eval_biffrc (struct biffrc_environ *env) ...@@ -541,10 +541,10 @@ eval_biffrc (struct biffrc_environ *env)
541 { 541 {
542 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 542 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
543 MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE, 543 MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE,
544 &env->locus.mu_line); 544 &env->locus.beg.mu_line);
545 mu_stream_ioctl (env->logstr, MU_IOCTL_LOGSTREAM, 545 mu_stream_ioctl (env->logstr, MU_IOCTL_LOGSTREAM,
546 MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE, 546 MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE,
547 &env->locus.mu_line); 547 &env->locus.beg.mu_line);
548 } 548 }
549 continue; 549 continue;
550 } 550 }
...@@ -600,9 +600,9 @@ eval_biffrc (struct biffrc_environ *env) ...@@ -600,9 +600,9 @@ eval_biffrc (struct biffrc_environ *env)
600 free (stmt); 600 free (stmt);
601 mu_wordsplit_free (&ws); 601 mu_wordsplit_free (&ws);
602 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 602 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
603 MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL); 603 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, NULL);
604 mu_stream_ioctl (env->logstr, MU_IOCTL_LOGSTREAM, 604 mu_stream_ioctl (env->logstr, MU_IOCTL_LOGSTREAM,
605 MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL); 605 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, NULL);
606 } 606 }
607 607
608 void 608 void
...@@ -645,13 +645,14 @@ run_user_action (const char *device, mu_message_t msg) ...@@ -645,13 +645,14 @@ run_user_action (const char *device, mu_message_t msg)
645 if (!rcname) 645 if (!rcname)
646 { 646 {
647 mu_diag_funcall (MU_DIAG_ERROR, "mu_make_file_name", NULL, ENOMEM); 647 mu_diag_funcall (MU_DIAG_ERROR, "mu_make_file_name", NULL, ENOMEM);
648 env.locus.mu_file = BIFF_RC; 648 env.locus.beg.mu_file = BIFF_RC;
649 } 649 }
650 else 650 else
651 env.locus.mu_file = rcname; 651 env.locus.beg.mu_file = rcname;
652 652
653 env.locus.mu_line = 1; 653 env.locus.beg.mu_line = 1;
654 env.locus.mu_col = 0; 654 env.locus.beg.mu_col = 0;
655 memset (&env.locus.end, 0, sizeof env.locus.end);
655 env.use_default = 0; 656 env.use_default = 0;
656 eval_biffrc (&env); 657 eval_biffrc (&env);
657 mu_stream_destroy (&env.input); 658 mu_stream_destroy (&env.input);
...@@ -679,9 +680,9 @@ run_user_action (const char *device, mu_message_t msg) ...@@ -679,9 +680,9 @@ run_user_action (const char *device, mu_message_t msg)
679 } 680 }
680 else 681 else
681 { 682 {
682 env.locus.mu_file = "<default>"; 683 env.locus.beg.mu_file = "<default>";
683 env.locus.mu_line = 1; 684 env.locus.beg.mu_line = 1;
684 env.locus.mu_col = 0; 685 env.locus.beg.mu_col = 0;
685 eval_biffrc (&env); 686 eval_biffrc (&env);
686 mu_stream_destroy (&env.input); 687 mu_stream_destroy (&env.input);
687 } 688 }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 #define _MAILUTILS_AUTH_H 20 #define _MAILUTILS_AUTH_H
21 21
22 #include <mailutils/types.h> 22 #include <mailutils/types.h>
23 #include <mailutils/locus.h>
23 24
24 #ifdef __cplusplus 25 #ifdef __cplusplus
25 extern "C" { 26 extern "C" {
...@@ -77,7 +78,7 @@ int mu_wicket_set_get_ticket (mu_wicket_t wicket, ...@@ -77,7 +78,7 @@ int mu_wicket_set_get_ticket (mu_wicket_t wicket,
77 int mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename); 78 int mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename);
78 79
79 struct mu_debug_locus; 80 struct mu_debug_locus;
80 int mu_wicket_stream_match_url (mu_stream_t stream, struct mu_locus *loc, 81 int mu_wicket_stream_match_url (mu_stream_t stream, struct mu_locus_point *loc,
81 mu_url_t url, int parse_flags, 82 mu_url_t url, int parse_flags,
82 mu_url_t *pticket_url); 83 mu_url_t *pticket_url);
83 int mu_wicket_file_match_url (const char *name, mu_url_t url, 84 int mu_wicket_file_match_url (const char *name, mu_url_t url,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
23 #include <mailutils/debug.h> 23 #include <mailutils/debug.h>
24 #include <mailutils/opool.h> 24 #include <mailutils/opool.h>
25 #include <mailutils/util.h> 25 #include <mailutils/util.h>
26 #include <mailutils/locus.h>
26 #include <sys/socket.h> 27 #include <sys/socket.h>
27 #include <netinet/in.h> 28 #include <netinet/in.h>
28 #include <arpa/inet.h> 29 #include <arpa/inet.h>
...@@ -64,7 +65,7 @@ enum mu_cfg_node_type ...@@ -64,7 +65,7 @@ enum mu_cfg_node_type
64 65
65 struct mu_cfg_node 66 struct mu_cfg_node
66 { 67 {
67 struct mu_locus locus; 68 struct mu_locus_range locus;
68 enum mu_cfg_node_type type; 69 enum mu_cfg_node_type type;
69 char *tag; 70 char *tag;
70 mu_config_value_t *label; 71 mu_config_value_t *label;
...@@ -119,8 +120,6 @@ int mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb); ...@@ -119,8 +120,6 @@ int mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb);
119 int mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, 120 int mu_cfg_tree_postprocess (mu_cfg_tree_t *tree,
120 struct mu_cfg_parse_hints *hints); 121 struct mu_cfg_parse_hints *hints);
121 122
122 extern struct mu_locus mu_cfg_locus;
123
124 mu_opool_t mu_cfg_lexer_pool (void); 123 mu_opool_t mu_cfg_lexer_pool (void);
125 124
126 #define MU_CFG_ITER_OK 0 125 #define MU_CFG_ITER_OK 0
...@@ -285,7 +284,7 @@ int mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, ...@@ -285,7 +284,7 @@ int mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file,
285 int mu_cfg_tree_create (struct mu_cfg_tree **ptree); 284 int mu_cfg_tree_create (struct mu_cfg_tree **ptree);
286 mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree, 285 mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
287 enum mu_cfg_node_type type, 286 enum mu_cfg_node_type type,
288 const struct mu_locus *loc, 287 const struct mu_locus_range *loc,
289 const char *tag, 288 const char *tag,
290 const char *label, 289 const char *label,
291 mu_list_t nodelist); 290 mu_list_t nodelist);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
24 #include <mailutils/types.h> 24 #include <mailutils/types.h>
25 #include <mailutils/log.h> 25 #include <mailutils/log.h>
26 #include <mailutils/debug.h> 26 #include <mailutils/debug.h>
27 #include <mailutils/locus.h>
27 28
28 #ifdef __cplusplus 29 #ifdef __cplusplus
29 extern "C" { 30 extern "C" {
...@@ -51,7 +52,9 @@ void mu_diag_cont_printf (const char *fmt, ...) MU_PRINTFLIKE(1,2); ...@@ -51,7 +52,9 @@ void mu_diag_cont_printf (const char *fmt, ...) MU_PRINTFLIKE(1,2);
51 52
52 void mu_diag_voutput (int, const char *, va_list); 53 void mu_diag_voutput (int, const char *, va_list);
53 void mu_diag_output (int, const char *, ...) MU_PRINTFLIKE(2,3); 54 void mu_diag_output (int, const char *, ...) MU_PRINTFLIKE(2,3);
54 void mu_diag_at_locus (int level, struct mu_locus const *loc, 55 void mu_diag_at_locus_point (int level, struct mu_locus_point const *loc,
56 const char *fmt, ...);
57 void mu_diag_at_locus_range (int level, struct mu_locus_range const *loc,
55 const char *fmt, ...); 58 const char *fmt, ...);
56 59
57 int mu_diag_level_to_syslog (int level); 60 int mu_diag_level_to_syslog (int level);
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
36 #include <mailutils/header.h> 36 #include <mailutils/header.h>
37 #include <mailutils/iterator.h> 37 #include <mailutils/iterator.h>
38 #include <mailutils/kwd.h> 38 #include <mailutils/kwd.h>
39 /* FIXME #include <mailutils/locus.h> */ 39 #include <mailutils/locus.h>
40 #include <mailutils/sieve.h> 40 #include <mailutils/sieve.h>
41 #include <mailutils/list.h> 41 #include <mailutils/list.h>
42 #include <mailutils/locker.h> 42 #include <mailutils/locker.h>
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
23 #include <stdarg.h> 23 #include <stdarg.h>
24 #include <mailutils/mailutils.h> 24 #include <mailutils/mailutils.h>
25 #include <mailutils/cli.h> 25 #include <mailutils/cli.h>
26 #include <mailutils/locus.h>
26 27
27 #ifdef __cplusplus 28 #ifdef __cplusplus
28 extern "C" { 29 extern "C" {
...@@ -287,7 +288,7 @@ int mu_sieve_set_dry_run (mu_sieve_machine_t mach, int val); ...@@ -287,7 +288,7 @@ int mu_sieve_set_dry_run (mu_sieve_machine_t mach, int val);
287 void mu_sieve_get_argc (mu_sieve_machine_t mach, size_t *args, size_t *tags); 288 void mu_sieve_get_argc (mu_sieve_machine_t mach, size_t *args, size_t *tags);
288 289
289 mu_mailer_t mu_sieve_get_mailer (mu_sieve_machine_t mach); 290 mu_mailer_t mu_sieve_get_mailer (mu_sieve_machine_t mach);
290 int mu_sieve_get_locus (mu_sieve_machine_t mach, struct mu_locus *); 291 int mu_sieve_get_locus (mu_sieve_machine_t mach, struct mu_locus_range *);
291 char *mu_sieve_get_daemon_email (mu_sieve_machine_t mach); 292 char *mu_sieve_get_daemon_email (mu_sieve_machine_t mach);
292 const char *mu_sieve_get_identifier (mu_sieve_machine_t mach); 293 const char *mu_sieve_get_identifier (mu_sieve_machine_t mach);
293 294
...@@ -324,7 +325,7 @@ const char *mu_sieve_type_str (mu_sieve_data_type type); ...@@ -324,7 +325,7 @@ const char *mu_sieve_type_str (mu_sieve_data_type type);
324 int mu_sieve_compile (mu_sieve_machine_t mach, const char *name); 325 int mu_sieve_compile (mu_sieve_machine_t mach, const char *name);
325 int mu_sieve_compile_buffer (mu_sieve_machine_t mach, 326 int mu_sieve_compile_buffer (mu_sieve_machine_t mach,
326 const char *buf, int bufsize, 327 const char *buf, int bufsize,
327 const char *fname, int line); 328 struct mu_locus_point const *pt);
328 int mu_sieve_mailbox (mu_sieve_machine_t mach, mu_mailbox_t mbox); 329 int mu_sieve_mailbox (mu_sieve_machine_t mach, mu_mailbox_t mbox);
329 int mu_sieve_message (mu_sieve_machine_t mach, mu_message_t message); 330 int mu_sieve_message (mu_sieve_machine_t mach, mu_message_t message);
330 int mu_sieve_disass (mu_sieve_machine_t mach); 331 int mu_sieve_disass (mu_sieve_machine_t mach);
......
...@@ -106,11 +106,9 @@ enum mu_buffer_type ...@@ -106,11 +106,9 @@ enum mu_buffer_type
106 */ 106 */
107 #define MU_IOCTL_LOGSTREAM_GET_SEVERITY 0 107 #define MU_IOCTL_LOGSTREAM_GET_SEVERITY 0
108 #define MU_IOCTL_LOGSTREAM_SET_SEVERITY 1 108 #define MU_IOCTL_LOGSTREAM_SET_SEVERITY 1
109 /* Get or set locus. 109
110 Arg: struct mu_locus * 110 /* Codes 2 and 3 are reserved */
111 */ 111
112 #define MU_IOCTL_LOGSTREAM_GET_LOCUS 2
113 #define MU_IOCTL_LOGSTREAM_SET_LOCUS 3
114 /* Get or set log mode. 112 /* Get or set log mode.
115 Arg: int * 113 Arg: int *
116 */ 114 */
......
...@@ -149,13 +149,6 @@ typedef unsigned int mu_debug_level_t; ...@@ -149,13 +149,6 @@ typedef unsigned int mu_debug_level_t;
149 149
150 #define MU_DEFAULT_RECORD _MU_DEFAULT_RECORD_ 150 #define MU_DEFAULT_RECORD _MU_DEFAULT_RECORD_
151 151
152 struct mu_locus
153 {
154 char *mu_file;
155 unsigned mu_line;
156 unsigned mu_col;
157 };
158
159 #ifdef __cplusplus 152 #ifdef __cplusplus
160 } 153 }
161 #endif 154 #endif
......
...@@ -248,7 +248,7 @@ _file_wicket_get_ticket (mu_wicket_t wicket, void *data, ...@@ -248,7 +248,7 @@ _file_wicket_get_ticket (mu_wicket_t wicket, void *data,
248 } 248 }
249 249
250 int 250 int
251 mu_wicket_stream_match_url (mu_stream_t stream, struct mu_locus *loc, 251 mu_wicket_stream_match_url (mu_stream_t stream, struct mu_locus_point *loc,
252 mu_url_t url, int parse_flags, 252 mu_url_t url, int parse_flags,
253 mu_url_t *pticket_url) 253 mu_url_t *pticket_url)
254 { 254 {
...@@ -329,7 +329,7 @@ mu_wicket_file_match_url (const char *name, mu_url_t url, ...@@ -329,7 +329,7 @@ mu_wicket_file_match_url (const char *name, mu_url_t url,
329 { 329 {
330 mu_stream_t stream; 330 mu_stream_t stream;
331 int rc; 331 int rc;
332 struct mu_locus loc; 332 struct mu_locus_point loc;
333 333
334 rc = mu_file_stream_create (&stream, name, MU_STREAM_READ); 334 rc = mu_file_stream_create (&stream, name, MU_STREAM_READ);
335 if (rc) 335 if (rc)
......
...@@ -21,7 +21,8 @@ libcfg_la_SOURCES = \ ...@@ -21,7 +21,8 @@ libcfg_la_SOURCES = \
21 driver.c\ 21 driver.c\
22 format.c\ 22 format.c\
23 lexer.c\ 23 lexer.c\
24 parser.c 24 parser.c\
25 cfg.h
25 26
26 localedir = $(datadir)/locale 27 localedir = $(datadir)/locale
27 AM_CPPFLAGS = \ 28 AM_CPPFLAGS = \
......
1 #include <mailutils/yyloc.h>
...@@ -152,10 +152,10 @@ format_node (const mu_cfg_node_t *node, void *data) ...@@ -152,10 +152,10 @@ format_node (const mu_cfg_node_t *node, void *data)
152 { 152 {
153 struct tree_print *tp = data; 153 struct tree_print *tp = data;
154 154
155 if ((tp->flags & MU_CF_FMT_LOCUS) && node->locus.mu_file) 155 if ((tp->flags & MU_CF_FMT_LOCUS) && node->locus.beg.mu_file)
156 mu_stream_printf (tp->stream, "# %lu \"%s\"\n", 156 mu_stream_printf (tp->stream, "# %lu \"%s\"\n",
157 (unsigned long) node->locus.mu_line, 157 (unsigned long) node->locus.beg.mu_line,
158 node->locus.mu_file); 158 node->locus.beg.mu_file);
159 format_level (tp->stream, tp->level); 159 format_level (tp->stream, tp->level);
160 switch (node->type) 160 switch (node->type)
161 { 161 {
......
...@@ -38,7 +38,10 @@ ...@@ -38,7 +38,10 @@
38 #include <mailutils/cfg.h> 38 #include <mailutils/cfg.h>
39 #include <mailutils/list.h> 39 #include <mailutils/list.h>
40 #include <mailutils/util.h> 40 #include <mailutils/util.h>
41 41 #include <mailutils/locus.h>
42 #include <mailutils/stream.h>
43 #include <mailutils/stdstream.h>
44 #include "cfg.h"
42 #include "parser.h" 45 #include "parser.h"
43 46
44 void _mu_line_begin (void); 47 void _mu_line_begin (void);
...@@ -66,7 +69,16 @@ static int (*char_to_strip)(char); /* Strip matching characters of each ...@@ -66,7 +69,16 @@ static int (*char_to_strip)(char); /* Strip matching characters of each
66 static int isemptystr(int off); 69 static int isemptystr(int off);
67 70
68 static mu_opool_t pool; 71 static mu_opool_t pool;
69 72 static mu_linetrack_t trk;
73 static struct mu_locus_point string_beg;
74 #define YY_USER_ACTION \
75 do \
76 { \
77 mu_linetrack_advance (trk, &yylloc, yytext, yyleng); \
78 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, \
79 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &yylloc); \
80 } \
81 while (0);
70 %} 82 %}
71 83
72 %option nounput 84 %option nounput
...@@ -83,7 +95,7 @@ P [1-9][0-9]* ...@@ -83,7 +95,7 @@ P [1-9][0-9]*
83 "/*" BEGIN(COMMENT); 95 "/*" BEGIN(COMMENT);
84 <COMMENT>[^*\n]* /* eat anything that's not a '*' */ 96 <COMMENT>[^*\n]* /* eat anything that's not a '*' */
85 <COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ 97 <COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
86 <COMMENT>\n ++mu_cfg_locus.mu_line; 98 <COMMENT>\n ;
87 <COMMENT>"*"+"/" BEGIN (INITIAL); 99 <COMMENT>"*"+"/" BEGIN (INITIAL);
88 /* End-of-line comments */ 100 /* End-of-line comments */
89 #debug=.*\n { 101 #debug=.*\n {
...@@ -91,9 +103,9 @@ P [1-9][0-9]* ...@@ -91,9 +103,9 @@ P [1-9][0-9]*
91 mu_cfg_set_debug (); 103 mu_cfg_set_debug ();
92 mu_cfg_set_lex_debug (); 104 mu_cfg_set_lex_debug ();
93 } 105 }
94 #.*\n { mu_cfg_locus.mu_line++; } 106 #.*\n ;
95 #.* /* end-of-file comment */; 107 #.* /* end-of-file comment */;
96 "//".*\n { mu_cfg_locus.mu_line++; } 108 "//".*\n ;
97 "//".* /* end-of-file comment */; 109 "//".* /* end-of-file comment */;
98 /* Identifiers */ 110 /* Identifiers */
99 <INITIAL>{ID} { 111 <INITIAL>{ID} {
...@@ -113,6 +125,7 @@ P [1-9][0-9]* ...@@ -113,6 +125,7 @@ P [1-9][0-9]*
113 return MU_TOK_QSTRING; } 125 return MU_TOK_QSTRING; }
114 \"[^\\"\n]*\\. | 126 \"[^\\"\n]*\\. |
115 \"[^\\"\n]*\\\n { BEGIN (STR); 127 \"[^\\"\n]*\\\n { BEGIN (STR);
128 mu_locus_point_copy (&string_beg, &yylloc.beg);
116 _mu_line_begin (); 129 _mu_line_begin ();
117 _mu_line_add_unescape_last (yytext + 1, yyleng - 1); } 130 _mu_line_add_unescape_last (yytext + 1, yyleng - 1); }
118 <STR>[^\\"\n]*\\. | 131 <STR>[^\\"\n]*\\. |
...@@ -121,6 +134,10 @@ P [1-9][0-9]* ...@@ -121,6 +134,10 @@ P [1-9][0-9]*
121 if (yyleng > 1) 134 if (yyleng > 1)
122 _mu_line_add (yytext, yyleng - 1); 135 _mu_line_add (yytext, yyleng - 1);
123 yylval.string = _mu_line_finish (); 136 yylval.string = _mu_line_finish ();
137
138 mu_locus_point_copy (&yylloc.beg, &string_beg);
139 mu_locus_point_deinit (&string_beg);
140
124 return MU_TOK_QSTRING; } 141 return MU_TOK_QSTRING; }
125 /* Multiline strings */ 142 /* Multiline strings */
126 "<<"(-" "?)?\\?{ID}[ \t]*#.*\n | 143 "<<"(-" "?)?\\?{ID}[ \t]*#.*\n |
...@@ -130,8 +147,8 @@ P [1-9][0-9]* ...@@ -130,8 +147,8 @@ P [1-9][0-9]*
130 "<<"(-" "?)?\"{ID}\"[ \t]*"//".*\n | 147 "<<"(-" "?)?\"{ID}\"[ \t]*"//".*\n |
131 "<<"(-" "?)?\"{ID}\"[ \t]*\n { 148 "<<"(-" "?)?\"{ID}\"[ \t]*\n {
132 BEGIN (ML); 149 BEGIN (ML);
150 mu_locus_point_copy (&string_beg, &yylloc.beg);
133 multiline_begin (yytext+2); 151 multiline_begin (yytext+2);
134 mu_cfg_locus.mu_line++;
135 } 152 }
136 <ML>.*\n { char *p = multiline_strip_tabs (yytext); 153 <ML>.*\n { char *p = multiline_strip_tabs (yytext);
137 154
...@@ -142,21 +159,21 @@ P [1-9][0-9]* ...@@ -142,21 +159,21 @@ P [1-9][0-9]*
142 multiline_delimiter = NULL; 159 multiline_delimiter = NULL;
143 BEGIN (INITIAL); 160 BEGIN (INITIAL);
144 yylval.string = multiline_finish (); 161 yylval.string = multiline_finish ();
162
163 mu_locus_point_copy (&yylloc.beg, &string_beg);
164 mu_locus_point_deinit (&string_beg);
165 /* FIXME: Adjust yylloc.end without retreating trk */
145 return MU_TOK_MSTRING; 166 return MU_TOK_MSTRING;
146 } 167 }
147 mu_cfg_locus.mu_line++;
148 multiline_add (p); } 168 multiline_add (p); }
149 {WS} ; 169 {WS} ;
150 /* Other tokens */ 170 /* Other tokens */
151 \n { mu_cfg_locus.mu_line++; } 171 \n ;
152 [,;{}()] return yytext[0]; 172 [,;{}()] return yytext[0];
153 . { if (mu_isprint (yytext[0])) 173 . { if (mu_isprint (yytext[0]))
154 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, 174 mu_error (_("stray character %c"), yytext[0]);
155 _("stray character %c"), yytext[0]);
156 else 175 else
157 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, 176 mu_error (_("stray character \\%03o"), (unsigned char) yytext[0]);
158 _("stray character \\%03o"),
159 (unsigned char) yytext[0]);
160 mu_cfg_error_count++; 177 mu_cfg_error_count++;
161 } 178 }
162 %% 179 %%
...@@ -175,8 +192,7 @@ unescape_to_line (int c) ...@@ -175,8 +192,7 @@ unescape_to_line (int c)
175 char t = mu_wordsplit_c_unquote_char (c); 192 char t = mu_wordsplit_c_unquote_char (c);
176 if (t == c && t != '\\' && t != '\"') 193 if (t == c && t != '\\' && t != '\"')
177 { 194 {
178 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, 195 mu_error (_("unknown escape sequence '\\%c'"), c);
179 _("unknown escape sequence '\\%c'"), c);
180 mu_cfg_error_count++; 196 mu_cfg_error_count++;
181 } 197 }
182 mu_opool_append_char (pool, t); 198 mu_opool_append_char (pool, t);
...@@ -365,29 +381,24 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags) ...@@ -365,29 +381,24 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
365 381
366 mu_cfg_set_lex_debug (); 382 mu_cfg_set_lex_debug ();
367 383
368 /* Initialize locus: */ 384 /* Initialize tracker */
369 /* 1. Save file name in the lexer object pool and point `file' member 385 mu_linetrack_create (&trk, full_name, 2);
370 to this copy. Free full_name: it is not used after that. */ 386 memset (&string_beg, 0, sizeof string_beg);
371 _mu_line_begin ();
372 _mu_line_add (full_name, strlen (full_name));
373 mu_cfg_locus.mu_file = _mu_line_finish ();
374 free (full_name);
375 /* 2. Initialize line number */
376 mu_cfg_locus.mu_line = 1;
377
378 /* Parse configuration */ 387 /* Parse configuration */
379 yyrestart (fp); 388 yyrestart (fp);
380 rc = mu_cfg_parse (return_tree); 389 rc = mu_cfg_parse (return_tree);
381 fclose (fp); 390 fclose (fp);
382 if (flags & MU_CF_VERBOSE) 391 if (flags & MU_CF_VERBOSE)
383 mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"), 392 mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"), full_name);
384 mu_cfg_locus.mu_file); 393 free (full_name);
385 394 mu_linetrack_destroy (&trk);
395 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
396 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, NULL);
386 return rc == 0 ? 0 : MU_ERR_FAILURE; 397 return rc == 0 ? 0 : MU_ERR_FAILURE;
387 } 398 }
388 399
389 mu_opool_t 400 mu_opool_t
390 mu_cfg_lexer_pool () 401 mu_cfg_lexer_pool (void)
391 { 402 {
392 mu_opool_t p = pool; 403 mu_opool_t p = pool;
393 pool = NULL; 404 pool = NULL;
......
...@@ -40,10 +40,10 @@ ...@@ -40,10 +40,10 @@
40 #include <mailutils/stream.h> 40 #include <mailutils/stream.h>
41 #include <mailutils/stdstream.h> 41 #include <mailutils/stdstream.h>
42 #include <mailutils/cidr.h> 42 #include <mailutils/cidr.h>
43 #include "cfg.h"
43 44
44 int mu_cfg_parser_verbose; 45 int mu_cfg_parser_verbose;
45 static mu_list_t /* of mu_cfg_node_t */ parse_node_list; 46 static mu_list_t /* of mu_cfg_node_t */ parse_node_list;
46 struct mu_locus mu_cfg_locus;
47 size_t mu_cfg_error_count; 47 size_t mu_cfg_error_count;
48 48
49 static int _mu_cfg_errcnt; 49 static int _mu_cfg_errcnt;
...@@ -57,7 +57,7 @@ char *_mu_line_finish (void); ...@@ -57,7 +57,7 @@ char *_mu_line_finish (void);
57 static int 57 static int
58 yyerror (char *s) 58 yyerror (char *s)
59 { 59 {
60 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, "%s", s); 60 mu_error ("%s", s);
61 mu_cfg_error_count++; 61 mu_cfg_error_count++;
62 return 0; 62 return 0;
63 } 63 }
...@@ -85,7 +85,7 @@ _node_set_parent (void *item, void *data) ...@@ -85,7 +85,7 @@ _node_set_parent (void *item, void *data)
85 } 85 }
86 86
87 static mu_cfg_node_t * 87 static mu_cfg_node_t *
88 mu_cfg_alloc_node (enum mu_cfg_node_type type, struct mu_locus *loc, 88 mu_cfg_alloc_node (enum mu_cfg_node_type type, struct mu_locus_range *loc,
89 const char *tag, mu_config_value_t *label, 89 const char *tag, mu_config_value_t *label,
90 mu_list_t nodelist) 90 mu_list_t nodelist)
91 { 91 {
...@@ -94,7 +94,7 @@ mu_cfg_alloc_node (enum mu_cfg_node_type type, struct mu_locus *loc, ...@@ -94,7 +94,7 @@ mu_cfg_alloc_node (enum mu_cfg_node_type type, struct mu_locus *loc,
94 size_t size = sizeof *np + strlen (tag) + 1; 94 size_t size = sizeof *np + strlen (tag) + 1;
95 np = mu_alloc (size); 95 np = mu_alloc (size);
96 np->type = type; 96 np->type = type;
97 np->locus = *loc; 97 mu_locus_range_copy (&np->locus, loc);
98 p = (char*) (np + 1); 98 p = (char*) (np + 1);
99 np->tag = p; 99 np->tag = p;
100 strcpy (p, tag); 100 strcpy (p, tag);
...@@ -121,15 +121,13 @@ debug_print_node (mu_cfg_node_t *node) ...@@ -121,15 +121,13 @@ debug_print_node (mu_cfg_node_t *node)
121 if (node->type == mu_cfg_node_undefined) 121 if (node->type == mu_cfg_node_undefined)
122 { 122 {
123 /* Stay on the safe side */ 123 /* Stay on the safe side */
124 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, 124 mu_error (_("unknown statement type!"));
125 _("unknown statement type!"));
126 mu_cfg_error_count++; 125 mu_cfg_error_count++;
127 } 126 }
128 else 127 else
129 { 128 {
130 /* FIXME: How to print label? */ 129 /* FIXME: How to print label? */
131 mu_diag_at_locus (MU_LOG_DEBUG, &node->locus, 130 mu_error ("statement: %s, id: %s",
132 "statement: %s, id: %s",
133 node_type_str (node->type), 131 node_type_str (node->type),
134 node->tag ? node->tag : "(null)"); 132 node->tag ? node->tag : "(null)");
135 } 133 }
...@@ -170,6 +168,9 @@ mu_cfg_create_node_list (mu_list_t *plist) ...@@ -170,6 +168,9 @@ mu_cfg_create_node_list (mu_list_t *plist)
170 168
171 %} 169 %}
172 170
171 %locations
172 %expect 1
173
173 %union { 174 %union {
174 mu_cfg_node_t node; 175 mu_cfg_node_t node;
175 mu_cfg_node_t *pnode; 176 mu_cfg_node_t *pnode;
...@@ -177,7 +178,6 @@ mu_cfg_create_node_list (mu_list_t *plist) ...@@ -177,7 +178,6 @@ mu_cfg_create_node_list (mu_list_t *plist)
177 char *string; 178 char *string;
178 mu_config_value_t value, *pvalue; 179 mu_config_value_t value, *pvalue;
179 mu_list_t list; 180 mu_list_t list;
180 struct { const char *name; struct mu_locus locus; } ident;
181 } 181 }
182 182
183 %token <string> MU_TOK_IDENT MU_TOK_STRING MU_TOK_QSTRING MU_TOK_MSTRING 183 %token <string> MU_TOK_IDENT MU_TOK_STRING MU_TOK_QSTRING MU_TOK_MSTRING
...@@ -186,7 +186,7 @@ mu_cfg_create_node_list (mu_list_t *plist) ...@@ -186,7 +186,7 @@ mu_cfg_create_node_list (mu_list_t *plist)
186 %type <value> value 186 %type <value> value
187 %type <pvalue> tag vallist 187 %type <pvalue> tag vallist
188 %type <list> values list vlist 188 %type <list> values list vlist
189 %type <ident> ident 189 %type <string> ident
190 %type <nodelist> stmtlist 190 %type <nodelist> stmtlist
191 %type <pnode> stmt simple block 191 %type <pnode> stmt simple block
192 192
...@@ -217,31 +217,31 @@ stmt : simple ...@@ -217,31 +217,31 @@ stmt : simple
217 217
218 simple : ident vallist ';' 218 simple : ident vallist ';'
219 { 219 {
220 $$ = mu_cfg_alloc_node (mu_cfg_node_param, &$1.locus, 220 struct mu_locus_range lr;
221 $1.name, $2, 221 lr.beg = @1.beg;
222 NULL); 222 lr.end = @3.end;
223 $$ = mu_cfg_alloc_node (mu_cfg_node_param, &lr, $1, $2, NULL);
223 } 224 }
224 ; 225 ;
225 226
226 block : ident tag '{' '}' opt_sc 227 block : ident tag '{' '}' opt_sc
227 { 228 {
228 $$ = mu_cfg_alloc_node (mu_cfg_node_statement, &$1.locus, 229 struct mu_locus_range lr;
229 $1.name, $2, 230 lr.beg = @1.beg;
230 NULL); 231 lr.end = @5.end;
232 $$ = mu_cfg_alloc_node (mu_cfg_node_statement, &lr, $1, $2, NULL);
231 } 233 }
232 | ident tag '{' stmtlist '}' opt_sc 234 | ident tag '{' stmtlist '}' opt_sc
233 { 235 {
234 $$ = mu_cfg_alloc_node (mu_cfg_node_statement, &$1.locus, 236 struct mu_locus_range lr;
235 $1.name, $2, $4); 237 lr.beg = @1.beg;
238 lr.end = @6.end;
239 $$ = mu_cfg_alloc_node (mu_cfg_node_statement, &lr, $1, $2, $4);
236 mu_list_foreach ($4, _node_set_parent, $$); 240 mu_list_foreach ($4, _node_set_parent, $$);
237 } 241 }
238 ; 242 ;
239 243
240 ident : MU_TOK_IDENT 244 ident : MU_TOK_IDENT
241 {
242 $$.name = $1;
243 $$.locus = mu_cfg_locus;
244 }
245 ; 245 ;
246 246
247 tag : /* empty */ 247 tag : /* empty */
...@@ -270,8 +270,7 @@ vallist : vlist ...@@ -270,8 +270,7 @@ vallist : vlist
270 val.v.arg.v = mu_alloc (n * sizeof (val.v.arg.v[0])); 270 val.v.arg.v = mu_alloc (n * sizeof (val.v.arg.v[0]));
271 if (!val.v.arg.v) 271 if (!val.v.arg.v)
272 { 272 {
273 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, 273 mu_error (_("not enough memory"));
274 _("not enough memory"));
275 abort(); 274 abort();
276 } 275 }
277 276
...@@ -292,9 +291,7 @@ vlist : value ...@@ -292,9 +291,7 @@ vlist : value
292 int rc = mu_list_create (&$$); 291 int rc = mu_list_create (&$$);
293 if (rc) 292 if (rc)
294 { 293 {
295 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, 294 mu_error (_("cannot create list: %s"), mu_strerror (rc));
296 _("cannot create list: %s"),
297 mu_strerror (rc));
298 abort (); 295 abort ();
299 } 296 }
300 mu_list_append ($$, config_value_dup (&$1)); /* FIXME */ 297 mu_list_append ($$, config_value_dup (&$1)); /* FIXME */
...@@ -401,14 +398,15 @@ mu_cfg_parse (mu_cfg_tree_t **ptree) ...@@ -401,14 +398,15 @@ mu_cfg_parse (mu_cfg_tree_t **ptree)
401 mu_cfg_tree_t *tree; 398 mu_cfg_tree_t *tree;
402 mu_opool_t pool; 399 mu_opool_t pool;
403 int save_mode = 0, mode; 400 int save_mode = 0, mode;
404 struct mu_locus save_locus = { NULL, }; 401 struct mu_locus_range save_locus = MU_LOCUS_RANGE_INITIALIZER;
405 402
406 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_GET_MODE, 403 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_GET_MODE,
407 &save_mode); 404 &save_mode);
408 mode = save_mode | MU_LOGMODE_LOCUS; 405 mode = save_mode | MU_LOGMODE_LOCUS;
409 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_MODE, 406 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_MODE,
410 &mode); 407 &mode);
411 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_GET_LOCUS, 408 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
409 MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE,
412 &save_locus); 410 &save_locus);
413 411
414 mu_cfg_set_debug (); 412 mu_cfg_set_debug ();
...@@ -432,9 +430,10 @@ mu_cfg_parse (mu_cfg_tree_t **ptree) ...@@ -432,9 +430,10 @@ mu_cfg_parse (mu_cfg_tree_t **ptree)
432 430
433 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_MODE, 431 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_MODE,
434 &save_mode); 432 &save_mode);
435 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_LOCUS, 433 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
434 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE,
436 &save_locus); 435 &save_locus);
437 free (save_locus.mu_file); 436 mu_locus_range_deinit (&save_locus); /* FIXME: refcount? */
438 437
439 return rc; 438 return rc;
440 } 439 }
...@@ -480,7 +479,7 @@ mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb) ...@@ -480,7 +479,7 @@ mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb)
480 479
481 static mu_cfg_tree_t * 480 static mu_cfg_tree_t *
482 do_include (const char *name, struct mu_cfg_parse_hints *hints, 481 do_include (const char *name, struct mu_cfg_parse_hints *hints,
483 struct mu_locus *loc) 482 struct mu_locus_range const *loc)
484 { 483 {
485 struct stat sb; 484 struct stat sb;
486 char *tmpname = NULL; 485 char *tmpname = NULL;
...@@ -520,13 +519,13 @@ do_include (const char *name, struct mu_cfg_parse_hints *hints, ...@@ -520,13 +519,13 @@ do_include (const char *name, struct mu_cfg_parse_hints *hints,
520 } 519 }
521 else if (errno == ENOENT) 520 else if (errno == ENOENT)
522 { 521 {
523 mu_diag_at_locus (MU_LOG_ERROR, loc, 522 mu_diag_at_locus_range (MU_LOG_ERROR, loc,
524 _("include file or directory does not exist")); 523 _("include file or directory does not exist"));
525 mu_cfg_error_count++; 524 mu_cfg_error_count++;
526 } 525 }
527 else 526 else
528 { 527 {
529 mu_diag_at_locus (MU_LOG_ERROR, loc, 528 mu_diag_at_locus_range (MU_LOG_ERROR, loc,
530 _("cannot stat include file or directory: %s"), 529 _("cannot stat include file or directory: %s"),
531 mu_strerror (errno)); 530 mu_strerror (errno));
532 mu_cfg_error_count++; 531 mu_cfg_error_count++;
...@@ -576,7 +575,7 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, struct mu_cfg_parse_hints *hints) ...@@ -576,7 +575,7 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, struct mu_cfg_parse_hints *hints)
576 } 575 }
577 else 576 else
578 { 577 {
579 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, 578 mu_diag_at_locus_range (MU_LOG_ERROR, &node->locus,
580 _("argument to `program' is not a string")); 579 _("argument to `program' is not a string"));
581 mu_cfg_error_count++; 580 mu_cfg_error_count++;
582 mu_iterator_ctl (itr, mu_itrctl_delete, NULL); 581 mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
...@@ -602,7 +601,7 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, struct mu_cfg_parse_hints *hints) ...@@ -602,7 +601,7 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, struct mu_cfg_parse_hints *hints)
602 } 601 }
603 else 602 else
604 { 603 {
605 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, 604 mu_diag_at_locus_range (MU_LOG_ERROR, &node->locus,
606 _("argument to `include' is not a string")); 605 _("argument to `include' is not a string"));
607 mu_cfg_error_count++; 606 mu_cfg_error_count++;
608 } 607 }
...@@ -760,8 +759,7 @@ push_section (struct scan_tree_data *dat, struct mu_cfg_section *sec) ...@@ -760,8 +759,7 @@ push_section (struct scan_tree_data *dat, struct mu_cfg_section *sec)
760 struct mu_cfg_section_list *p = mu_alloc (sizeof *p); 759 struct mu_cfg_section_list *p = mu_alloc (sizeof *p);
761 if (!p) 760 if (!p)
762 { 761 {
763 mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, 762 mu_error (_("not enough memory"));
764 _("not enough memory"));
765 mu_cfg_error_count++; 763 mu_cfg_error_count++;
766 return 1; 764 return 1;
767 } 765 }
...@@ -782,7 +780,7 @@ pop_section (struct scan_tree_data *dat) ...@@ -782,7 +780,7 @@ pop_section (struct scan_tree_data *dat)
782 } 780 }
783 781
784 static int 782 static int
785 valcvt (const struct mu_locus *locus, 783 valcvt (const struct mu_locus_range *locus,
786 void *tgt, mu_c_type_t type, mu_config_value_t *val) 784 void *tgt, mu_c_type_t type, mu_config_value_t *val)
787 { 785 {
788 int rc; 786 int rc;
...@@ -790,7 +788,7 @@ valcvt (const struct mu_locus *locus, ...@@ -790,7 +788,7 @@ valcvt (const struct mu_locus *locus,
790 788
791 if (val->type != MU_CFG_STRING) 789 if (val->type != MU_CFG_STRING)
792 { 790 {
793 mu_diag_at_locus (MU_LOG_ERROR, locus, _("expected string value")); 791 mu_diag_at_locus_range (MU_LOG_ERROR, locus, _("expected string value"));
794 mu_cfg_error_count++; 792 mu_cfg_error_count++;
795 return 1; 793 return 1;
796 } 794 }
...@@ -798,7 +796,7 @@ valcvt (const struct mu_locus *locus, ...@@ -798,7 +796,7 @@ valcvt (const struct mu_locus *locus,
798 rc = mu_str_to_c (val->v.string, type, tgt, &errmsg); 796 rc = mu_str_to_c (val->v.string, type, tgt, &errmsg);
799 if (rc) 797 if (rc)
800 { 798 {
801 mu_diag_at_locus (MU_LOG_ERROR, locus, "%s", 799 mu_diag_at_locus_range (MU_LOG_ERROR, locus, "%s",
802 errmsg ? errmsg : mu_strerror (rc)); 800 errmsg ? errmsg : mu_strerror (rc));
803 free (errmsg); 801 free (errmsg);
804 } 802 }
...@@ -810,7 +808,7 @@ struct set_closure ...@@ -810,7 +808,7 @@ struct set_closure
810 mu_list_t list; 808 mu_list_t list;
811 int type; 809 int type;
812 struct scan_tree_data *sdata; 810 struct scan_tree_data *sdata;
813 const struct mu_locus *locus; 811 const struct mu_locus_range *locus;
814 }; 812 };
815 813
816 static size_t config_type_size[] = { 814 static size_t config_type_size[] = {
...@@ -840,7 +838,7 @@ _set_fun (void *item, void *data) ...@@ -840,7 +838,7 @@ _set_fun (void *item, void *data)
840 if ((size_t) clos->type >= MU_ARRAY_SIZE(config_type_size) 838 if ((size_t) clos->type >= MU_ARRAY_SIZE(config_type_size)
841 || (size = config_type_size[clos->type]) == 0) 839 || (size = config_type_size[clos->type]) == 0)
842 { 840 {
843 mu_diag_at_locus (MU_LOG_EMERG, clos->locus, 841 mu_diag_at_locus_range (MU_LOG_EMERG, clos->locus,
844 _("INTERNAL ERROR at %s:%d: unhandled data type %d"), 842 _("INTERNAL ERROR at %s:%d: unhandled data type %d"),
845 __FILE__, __LINE__, clos->type); 843 __FILE__, __LINE__, clos->type);
846 mu_cfg_error_count++; 844 mu_cfg_error_count++;
...@@ -850,7 +848,8 @@ _set_fun (void *item, void *data) ...@@ -850,7 +848,8 @@ _set_fun (void *item, void *data)
850 tgt = mu_alloc (size); 848 tgt = mu_alloc (size);
851 if (!tgt) 849 if (!tgt)
852 { 850 {
853 mu_diag_at_locus (MU_LOG_ERROR, clos->locus, _("not enough memory")); 851 mu_diag_at_locus_range (MU_LOG_ERROR, clos->locus,
852 _("not enough memory"));
854 mu_cfg_error_count++; 853 mu_cfg_error_count++;
855 return 1; 854 return 1;
856 } 855 }
...@@ -870,7 +869,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) ...@@ -870,7 +869,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
870 869
871 if (!param) 870 if (!param)
872 { 871 {
873 mu_diag_at_locus (MU_LOG_ERROR, &node->locus, 872 mu_diag_at_locus_range (MU_LOG_ERROR, &node->locus,
874 _("unknown keyword `%s'"), 873 _("unknown keyword `%s'"),
875 node->tag); 874 node->tag);
876 mu_cfg_error_count++; 875 mu_cfg_error_count++;
...@@ -887,7 +886,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) ...@@ -887,7 +886,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
887 tgt = NULL; 886 tgt = NULL;
888 else 887 else
889 { 888 {
890 mu_diag_at_locus (MU_LOG_EMERG, &node->locus, 889 mu_diag_at_locus_range (MU_LOG_EMERG, &node->locus,
891 _("INTERNAL ERROR: cannot determine target offset for " 890 _("INTERNAL ERROR: cannot determine target offset for "
892 "%s"), param->ident); 891 "%s"), param->ident);
893 abort (); 892 abort ();
...@@ -915,7 +914,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) ...@@ -915,7 +914,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
915 break; 914 break;
916 915
917 case MU_CFG_ARRAY: 916 case MU_CFG_ARRAY:
918 mu_diag_at_locus (MU_LOG_ERROR, &node->locus, 917 mu_diag_at_locus_range (MU_LOG_ERROR, &node->locus,
919 _("expected list, but found array")); 918 _("expected list, but found array"));
920 mu_cfg_error_count++; 919 mu_cfg_error_count++;
921 return 1; 920 return 1;
...@@ -929,13 +928,13 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) ...@@ -929,13 +928,13 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
929 { 928 {
930 if (!param->callback) 929 if (!param->callback)
931 { 930 {
932 mu_diag_at_locus (MU_LOG_EMERG, &node->locus, 931 mu_diag_at_locus_range (MU_LOG_EMERG, &node->locus,
933 _("INTERNAL ERROR: %s: callback not defined"), 932 _("INTERNAL ERROR: %s: callback not defined"),
934 node->tag); 933 node->tag);
935 abort (); 934 abort ();
936 } 935 }
937 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 936 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
938 MU_IOCTL_LOGSTREAM_SET_LOCUS, 937 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE,
939 (void*) &node->locus); 938 (void*) &node->locus);
940 if (param->callback (tgt, node->label)) 939 if (param->callback (tgt, node->label))
941 return 1; 940 return 1;
...@@ -964,7 +963,7 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data) ...@@ -964,7 +963,7 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data)
964 { 963 {
965 if (mu_cfg_parser_verbose) 964 if (mu_cfg_parser_verbose)
966 { 965 {
967 mu_diag_at_locus (MU_LOG_WARNING, &node->locus, 966 mu_diag_at_locus_range (MU_LOG_WARNING, &node->locus,
968 _("unknown section `%s'"), 967 _("unknown section `%s'"),
969 node->tag); 968 node->tag);
970 } 969 }
...@@ -983,7 +982,7 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data) ...@@ -983,7 +982,7 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data)
983 if (sec->parser) 982 if (sec->parser)
984 { 983 {
985 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 984 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
986 MU_IOCTL_LOGSTREAM_SET_LOCUS, 985 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE,
987 (void*) &node->locus); 986 (void*) &node->locus);
988 if (sec->parser (mu_cfg_section_start, node, 987 if (sec->parser (mu_cfg_section_start, node,
989 sec->label, &sec->target, 988 sec->label, &sec->target,
...@@ -1041,7 +1040,7 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, ...@@ -1041,7 +1040,7 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
1041 struct scan_tree_data dat; 1040 struct scan_tree_data dat;
1042 struct mu_cfg_iter_closure clos; 1041 struct mu_cfg_iter_closure clos;
1043 int save_mode = 0, mode; 1042 int save_mode = 0, mode;
1044 struct mu_locus save_locus = { NULL, }; 1043 struct mu_locus_range save_locus = MU_LOCUS_RANGE_INITIALIZER;
1045 int rc; 1044 int rc;
1046 1045
1047 dat.tree = tree; 1046 dat.tree = tree;
...@@ -1056,7 +1055,7 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, ...@@ -1056,7 +1055,7 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
1056 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 1055 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1057 MU_IOCTL_LOGSTREAM_SET_MODE, &mode); 1056 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
1058 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 1057 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1059 MU_IOCTL_LOGSTREAM_GET_LOCUS, &save_locus); 1058 MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE, &save_locus);
1060 1059
1061 if (push_section (&dat, sections)) 1060 if (push_section (&dat, sections))
1062 return 1; 1061 return 1;
...@@ -1070,8 +1069,7 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, ...@@ -1070,8 +1069,7 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
1070 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 1069 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1071 MU_IOCTL_LOGSTREAM_SET_MODE, &save_mode); 1070 MU_IOCTL_LOGSTREAM_SET_MODE, &save_mode);
1072 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 1071 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1073 MU_IOCTL_LOGSTREAM_SET_LOCUS, &save_locus); 1072 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &save_locus);
1074 free (save_locus.mu_file);
1075 1073
1076 return dat.error; 1074 return dat.error;
1077 } 1075 }
...@@ -1124,7 +1122,7 @@ mu_cfg_tree_create (struct mu_cfg_tree **ptree) ...@@ -1124,7 +1122,7 @@ mu_cfg_tree_create (struct mu_cfg_tree **ptree)
1124 mu_cfg_node_t * 1122 mu_cfg_node_t *
1125 mu_cfg_tree_create_node (struct mu_cfg_tree *tree, 1123 mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
1126 enum mu_cfg_node_type type, 1124 enum mu_cfg_node_type type,
1127 const struct mu_locus *loc, 1125 const struct mu_locus_range *loc,
1128 const char *tag, const char *label, 1126 const char *tag, const char *label,
1129 mu_list_t nodelist) 1127 mu_list_t nodelist)
1130 { 1128 {
...@@ -1136,7 +1134,7 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree, ...@@ -1136,7 +1134,7 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
1136 np = mu_alloc (size); 1134 np = mu_alloc (size);
1137 np->type = type; 1135 np->type = type;
1138 if (loc) 1136 if (loc)
1139 np->locus = *loc; 1137 mu_locus_range_copy (&np->locus, loc);
1140 else 1138 else
1141 memset (&np->locus, 0, sizeof np->locus); 1139 memset (&np->locus, 0, sizeof np->locus);
1142 p = (char*) (np + 1); 1140 p = (char*) (np + 1);
...@@ -1478,11 +1476,7 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode) ...@@ -1478,11 +1476,7 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode)
1478 char **argv; 1476 char **argv;
1479 enum mu_cfg_node_type type; 1477 enum mu_cfg_node_type type;
1480 mu_cfg_node_t *node = NULL; 1478 mu_cfg_node_t *node = NULL;
1481 struct mu_locus locus; 1479 struct mu_locus_range locus = MU_LOCUS_RANGE_INITIALIZER;
1482
1483 locus.mu_file = "<int>";
1484 locus.mu_line = 0;
1485 locus.mu_col = 0;
1486 1480
1487 rc = split_cfg_path (path, &argc, &argv); 1481 rc = split_cfg_path (path, &argc, &argv);
1488 if (rc) 1482 if (rc)
......
...@@ -57,25 +57,9 @@ mu_diag_output (int level, const char *fmt, ...) ...@@ -57,25 +57,9 @@ mu_diag_output (int level, const char *fmt, ...)
57 } 57 }
58 58
59 void 59 void
60 mu_diag_at_locus (int level, struct mu_locus const *loc, const char *fmt, ...) 60 mu_vdiag_at_locus_range (int level, struct mu_locus_range const *loc,
61 const char *fmt, va_list ap)
61 { 62 {
62 va_list ap;
63
64 va_start (ap, fmt);
65 if (loc && loc->mu_file)
66 mu_stream_printf (mu_strerr, "\033f<%d>%s\033l<%u>\033c<%u>",
67 (unsigned) strlen (loc->mu_file), loc->mu_file,
68 loc->mu_line,
69 loc->mu_col);
70 mu_diag_voutput (level, fmt, ap);
71 va_end (ap);
72 }
73
74 void
75 mu_diag_at_locus_range (int level, struct mu_locus_range const *loc,
76 const char *fmt, ...)
77 {
78 va_list ap;
79 struct mu_locus_range old = MU_LOCUS_RANGE_INITIALIZER; 63 struct mu_locus_range old = MU_LOCUS_RANGE_INITIALIZER;
80 int restore = 0; 64 int restore = 0;
81 65
...@@ -90,9 +74,7 @@ mu_diag_at_locus_range (int level, struct mu_locus_range const *loc, ...@@ -90,9 +74,7 @@ mu_diag_at_locus_range (int level, struct mu_locus_range const *loc,
90 } 74 }
91 } 75 }
92 76
93 va_start (ap, fmt);
94 mu_diag_voutput (level, fmt, ap); 77 mu_diag_voutput (level, fmt, ap);
95 va_end (ap);
96 78
97 if (restore) 79 if (restore)
98 { 80 {
...@@ -103,6 +85,28 @@ mu_diag_at_locus_range (int level, struct mu_locus_range const *loc, ...@@ -103,6 +85,28 @@ mu_diag_at_locus_range (int level, struct mu_locus_range const *loc,
103 } 85 }
104 86
105 void 87 void
88 mu_diag_at_locus_range (int level, struct mu_locus_range const *loc,
89 const char *fmt, ...)
90 {
91 va_list ap;
92 va_start (ap, fmt);
93 mu_vdiag_at_locus_range (level, loc, fmt, ap);
94 va_end (ap);
95 }
96
97 void
98 mu_diag_at_locus_point (int level, struct mu_locus_point const *loc,
99 const char *fmt, ...)
100 {
101 va_list ap;
102 struct mu_locus_range lr = MU_LOCUS_RANGE_INITIALIZER;
103 lr.beg = *loc;
104 va_start (ap, fmt);
105 mu_vdiag_at_locus_range (level, &lr, fmt, ap);
106 va_end (ap);
107 }
108
109 void
106 mu_diag_vprintf (int level, const char *fmt, va_list ap) 110 mu_diag_vprintf (int level, const char *fmt, va_list ap)
107 { 111 {
108 mu_diag_init (); 112 mu_diag_init ();
......
...@@ -480,48 +480,6 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg) ...@@ -480,48 +480,6 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg)
480 } 480 }
481 break; 481 break;
482 482
483 case MU_IOCTL_LOGSTREAM_GET_LOCUS:
484 if (!arg)
485 return EINVAL;
486 else
487 {
488 struct mu_locus *ploc = arg;
489 if (sp->locrange.beg.mu_file)
490 {
491 ploc->mu_file = strdup (sp->locrange.beg.mu_file);
492 if (!ploc->mu_file)
493 return ENOMEM;
494 }
495 else
496 ploc->mu_file = NULL;
497 ploc->mu_line = sp->locrange.beg.mu_line;
498 ploc->mu_col = sp->locrange.beg.mu_col;
499 }
500 break;
501
502 case MU_IOCTL_LOGSTREAM_SET_LOCUS:
503 {
504 struct mu_locus *ploc = arg;
505
506 mu_ident_deref (sp->locrange.end.mu_file);
507 sp->locrange.end.mu_file = NULL;
508 if (arg)
509 {
510 status = lr_set_file (&sp->locrange, ploc->mu_file, 0, 0);
511 if (status)
512 return status;
513 lr_set_line (&sp->locrange, ploc->mu_line, 0);
514 lr_set_col (&sp->locrange, ploc->mu_col, 0);
515 }
516 else
517 {
518 mu_ident_deref (sp->locrange.beg.mu_file);
519 sp->locrange.beg.mu_file = NULL;
520 }
521
522 break;
523 }
524
525 case MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE: 483 case MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE:
526 if (!arg) 484 if (!arg)
527 return EINVAL; 485 return EINVAL;
......
...@@ -34,46 +34,43 @@ emerg: and this one as well ...@@ -34,46 +34,43 @@ emerg: and this one as well
34 one 34 one
35 two 35 two
36 emerg: three 36 emerg: three
37 05. set/get locus point 37 05. locus: file, line
38 input:1: filename and line number
39 input:1.3: filename, line and column numbers
40 06. locus: file, line
41 input:1: file, line 38 input:1: file, line
42 07. locus: file, line, col 39 06. locus: file, line, col
43 input:1.1-10: file, line, col 40 input:1.1-10: file, line, col
44 08. locus: file, line-range 41 07. locus: file, line-range
45 input:1-2: file, line-range 42 input:1-2: file, line-range
46 09. locus: file, line-range, col 43 08. locus: file, line-range, col
47 input:1.1-2.10: file, line-range, col 44 input:1.1-2.10: file, line-range, col
48 10. locus: file-range, line-range, col-range 45 09. locus: file-range, line-range, col-range
49 input:1.1-next:2.10: file-range, line-range, col-range 46 input:1.1-next:2.10: file-range, line-range, col-range
50 11. set locus line 47 10. set locus line
51 input:1.1-next:2.10: initial 48 input:1.1-next:2.10: initial
52 input:8.1-next:2.10: locus line changed 49 input:8.1-next:2.10: locus line changed
53 12. advance locus line 50 11. advance locus line
54 input:1.1-next:5.10: initial 51 input:1.1-next:5.10: initial
55 input:3.1-next:5.10: locus line advanced 52 input:3.1-next:5.10: locus line advanced
56 13. set locus column 53 12. set locus column
57 input:1.1-next:2.10: initial 54 input:1.1-next:2.10: initial
58 input:1.8-next:2.10: locus column changed 55 input:1.8-next:2.10: locus column changed
59 14. advance locus column 56 13. advance locus column
60 input:1.1-next:5.10: initial 57 input:1.1-next:5.10: initial
61 input:1.5-next:5.10: locus line advanced 58 input:1.5-next:5.10: locus line advanced
62 15. fmt: severity 59 14. fmt: severity
63 info: severity 60 info: severity
64 16. fmt: locus (file, line) 61 15. fmt: locus (file, line)
65 a:10: one 62 a:10: one
66 17. fmt: locus (file, line, column) 63 16. fmt: locus (file, line, column)
67 a:10.5: one 64 a:10.5: one
68 18. fmt: locus (range) 65 17. fmt: locus (range)
69 a:10.5-b:14.8: one 66 a:10.5-b:14.8: one
70 19. fmt: locus; restore defaults 67 18. fmt: locus; restore defaults
71 a:10.5-b:14.8: one 68 a:10.5-b:14.8: one
72 default 69 default
73 20. fmt: locus; restore defaults, display locus 70 19. fmt: locus; restore defaults, display locus
74 a:10.5-b:14.8: one 71 a:10.5-b:14.8: one
75 input:1.1-next:5.10: default 72 input:1.1-next:5.10: default
76 21. fmt: set locus 73 20. fmt: set locus
77 a:10.5-b:14.8: one 74 a:10.5-b:14.8: one
78 a:10.5-b:14.8: default 75 a:10.5-b:14.8: default
79 ]) 76 ])
......
...@@ -129,51 +129,6 @@ check_suppress_name (mu_stream_t str) ...@@ -129,51 +129,6 @@ check_suppress_name (mu_stream_t str)
129 mu_stream_printf (str, "and this one as well\n"); 129 mu_stream_printf (str, "and this one as well\n");
130 } 130 }
131 131
132 /* Check setting locus point
133 Expected output:
134 input:1: filename and line number
135 input:1.3: filename, line and column numbers
136 */
137 static void
138 set_locus_point (mu_stream_t str)
139 {
140 int mode = MU_LOGMODE_LOCUS;
141 struct mu_locus pt, pt2;
142
143 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
144 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
145
146 pt.mu_file = "input";
147 pt.mu_line = 1;
148 pt.mu_col = 0;
149
150 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
151 MU_IOCTL_LOGSTREAM_SET_LOCUS, &pt);
152
153 mu_stream_printf (str, "filename and line number\n");
154
155 pt.mu_file = "input";
156 pt.mu_line = 1;
157 pt.mu_col = 3;
158
159 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
160 MU_IOCTL_LOGSTREAM_SET_LOCUS, &pt);
161
162 mu_stream_printf (str, "filename, line and column numbers\n");
163
164 MU_ASSERT (mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
165 MU_IOCTL_LOGSTREAM_GET_LOCUS, &pt2));
166
167 if (strcmp (pt.mu_file, pt2.mu_file))
168 mu_error ("%s:%d: mu_file differs\n", __FILE__, __LINE__);
169 if (pt.mu_line != pt2.mu_line)
170 mu_error ("%s:%d: mu_line differs\n", __FILE__, __LINE__);
171 if (pt.mu_col != pt2.mu_col)
172 mu_error ("%s:%d: mu_col differs\n", __FILE__, __LINE__);
173 /* FIXME: remove this after switching to mu_locus_point */
174 free (pt2.mu_file);
175 }
176
177 static void 132 static void
178 comp_range (mu_stream_t str, struct mu_locus_range *lr1, 133 comp_range (mu_stream_t str, struct mu_locus_range *lr1,
179 char const *file, int line) 134 char const *file, int line)
...@@ -682,7 +637,6 @@ struct testcase testcases[] = { ...@@ -682,7 +637,6 @@ struct testcase testcases[] = {
682 { "suppress severity", check_suppress }, 637 { "suppress severity", check_suppress },
683 { "suppress severity name", check_suppress_name }, 638 { "suppress severity name", check_suppress_name },
684 { "severity mask", check_severity_mask }, 639 { "severity mask", check_severity_mask },
685 { "set/get locus point", set_locus_point },
686 { "locus: file, line", lr_file_line }, 640 { "locus: file, line", lr_file_line },
687 { "locus: file, line, col", lr_file_line_col }, 641 { "locus: file, line, col", lr_file_line_col },
688 { "locus: file, line-range", lr_file_line2 }, 642 { "locus: file, line-range", lr_file_line2 },
......
...@@ -30,7 +30,7 @@ match_string (const char *str) ...@@ -30,7 +30,7 @@ match_string (const char *str)
30 { 30 {
31 int rc; 31 int rc;
32 mu_url_t u, url; 32 mu_url_t u, url;
33 struct mu_locus loc; 33 struct mu_locus_point loc;
34 34
35 if ((rc = mu_url_create (&u, str)) != 0) 35 if ((rc = mu_url_create (&u, str)) != 0)
36 { 36 {
......
...@@ -84,7 +84,8 @@ enum parse_state ...@@ -84,7 +84,8 @@ enum parse_state
84 state_lhs, 84 state_lhs,
85 state_op, 85 state_op,
86 state_rhs, 86 state_rhs,
87 state_delim 87 state_delim,
88 state_err
88 }; 89 };
89 90
90 static int 91 static int
...@@ -96,7 +97,7 @@ cb_request (void *data, mu_config_value_t *val) ...@@ -96,7 +97,7 @@ cb_request (void *data, mu_config_value_t *val)
96 enum parse_state state; 97 enum parse_state state;
97 grad_locus_t loc; 98 grad_locus_t loc;
98 char *name; 99 char *name;
99 struct mu_locus locus; 100 struct mu_locus_range locus;
100 101
101 if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) 102 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
102 return 1; 103 return 1;
...@@ -111,11 +112,11 @@ cb_request (void *data, mu_config_value_t *val) ...@@ -111,11 +112,11 @@ cb_request (void *data, mu_config_value_t *val)
111 } 112 }
112 113
113 if (mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 114 if (mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
114 MU_IOCTL_LOGSTREAM_GET_LOCUS, 115 MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE,
115 &locus) == 0) 116 &locus) == 0)
116 { 117 {
117 loc.file = locus.mu_file; 118 loc.file = (char*) locus.beg.mu_file;
118 loc.line = locus.mu_line; 119 loc.line = locus.beg.mu_line;
119 } 120 }
120 else 121 else
121 { 122 {
...@@ -123,7 +124,7 @@ cb_request (void *data, mu_config_value_t *val) ...@@ -123,7 +124,7 @@ cb_request (void *data, mu_config_value_t *val)
123 loc.line = 0; 124 loc.line = 0;
124 } 125 }
125 126
126 for (i = 0, state = state_lhs; i < ws.ws_wordc; i++) 127 for (i = 0, state = state_lhs; state != state_err && i < ws.ws_wordc; i++)
127 { 128 {
128 grad_avp_t *pair; 129 grad_avp_t *pair;
129 130
...@@ -146,22 +147,35 @@ cb_request (void *data, mu_config_value_t *val) ...@@ -146,22 +147,35 @@ cb_request (void *data, mu_config_value_t *val)
146 if (!pair) 147 if (!pair)
147 { 148 {
148 mu_error (_("cannot create radius A/V pair `%s'"), name); 149 mu_error (_("cannot create radius A/V pair `%s'"), name);
149 return 1; 150 state = state_err;
150 } 151 }
152 else
153 {
151 grad_avl_merge (plist, &pair); 154 grad_avl_merge (plist, &pair);
152 state = state_delim; 155 state = state_delim;
156 }
153 break; 157 break;
154 158
155 case state_delim: 159 case state_delim:
156 if (strcmp (ws.ws_wordv[i], ",")) 160 if (strcmp (ws.ws_wordv[i], ","))
157 { 161 {
158 mu_error (_("expected `,' but found `%s'"), ws.ws_wordv[i]); 162 mu_error (_("expected `,' but found `%s'"), ws.ws_wordv[i]);
159 return 1; 163 state = state_err;
160 } 164 }
165 else
161 state = state_lhs; 166 state = state_lhs;
167 break;
168
169 default:
170 abort ();
162 } 171 }
163 } 172 }
173
164 mu_wordsplit_free (&ws); 174 mu_wordsplit_free (&ws);
175 mu_locus_range_deinit (&locus);
176
177 if (state == state_err)
178 return 1;
165 179
166 if (state != state_delim && state != state_delim) 180 if (state != state_delim && state != state_delim)
167 { 181 {
......
...@@ -528,7 +528,7 @@ perms_tag_checker (mu_sieve_machine_t mach) ...@@ -528,7 +528,7 @@ perms_tag_checker (mu_sieve_machine_t mach)
528 { 528 {
529 if (mu_parse_stream_perm_string (&flag, t->v.string, &p)) 529 if (mu_parse_stream_perm_string (&flag, t->v.string, &p))
530 { 530 {
531 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 531 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
532 _("invalid permissions (near %s)"), p); 532 _("invalid permissions (near %s)"), p);
533 mu_i_sv_error (mach); 533 mu_i_sv_error (mach);
534 err = 1; 534 err = 1;
......
...@@ -174,7 +174,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach) ...@@ -174,7 +174,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
174 { 174 {
175 if (match) 175 if (match)
176 { 176 {
177 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 177 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
178 _("match type specified twice in call to `%s'"), 178 _("match type specified twice in call to `%s'"),
179 mach->identifier); 179 mach->identifier);
180 mu_i_sv_error (mach); 180 mu_i_sv_error (mach);
...@@ -209,7 +209,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach) ...@@ -209,7 +209,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
209 209
210 if (compname && strcmp (compname, "i;ascii-numeric")) 210 if (compname && strcmp (compname, "i;ascii-numeric"))
211 { 211 {
212 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 212 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
213 /* TRANSLATORS: Do not translate ':count'. 213 /* TRANSLATORS: Do not translate ':count'.
214 It is the name of a Sieve tag */ 214 It is the name of a Sieve tag */
215 _("comparator %s is incompatible with " 215 _("comparator %s is incompatible with "
...@@ -235,7 +235,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach) ...@@ -235,7 +235,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
235 break; 235 break;
236 /* fall through */ 236 /* fall through */
237 default: 237 default:
238 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 238 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
239 _(":count requires second argument to be a list of one element")); 239 _(":count requires second argument to be a list of one element"));
240 mu_i_sv_error (mach); 240 mu_i_sv_error (mach);
241 return 1; 241 return 1;
...@@ -246,7 +246,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach) ...@@ -246,7 +246,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
246 char *p = mu_str_skip_class (argstr->orig, MU_CTYPE_DIGIT); 246 char *p = mu_str_skip_class (argstr->orig, MU_CTYPE_DIGIT);
247 if (*p) 247 if (*p)
248 { 248 {
249 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 249 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
250 _("second argument cannot be converted to number")); 250 _("second argument cannot be converted to number"));
251 mu_i_sv_error (mach); 251 mu_i_sv_error (mach);
252 return 1; 252 return 1;
...@@ -258,7 +258,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach) ...@@ -258,7 +258,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
258 258
259 if (mu_sieve_str_to_relcmp (str, NULL, NULL)) 259 if (mu_sieve_str_to_relcmp (str, NULL, NULL))
260 { 260 {
261 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 261 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
262 _("invalid relational match `%s' in call to `%s'"), 262 _("invalid relational match `%s' in call to `%s'"),
263 str, mach->identifier); 263 str, mach->identifier);
264 mu_i_sv_error (mach); 264 mu_i_sv_error (mach);
...@@ -278,7 +278,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach) ...@@ -278,7 +278,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
278 compfun = mu_sieve_comparator_lookup (mach, compname, matchtype); 278 compfun = mu_sieve_comparator_lookup (mach, compname, matchtype);
279 if (!compfun) 279 if (!compfun)
280 { 280 {
281 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 281 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
282 _("comparator `%s' is incompatible with match type `%s' in call to `%s'"), 282 _("comparator `%s' is incompatible with match type `%s' in call to `%s'"),
283 compname, match ? match->tag : "is", 283 compname, match ? match->tag : "is",
284 mach->identifier); 284 mach->identifier);
......
...@@ -103,7 +103,7 @@ moderator_filter_message (mu_sieve_machine_t mach, ...@@ -103,7 +103,7 @@ moderator_filter_message (mu_sieve_machine_t mach,
103 } 103 }
104 else if (mu_sieve_get_tag (mach, "program", SVT_STRING, &arg)) 104 else if (mu_sieve_get_tag (mach, "program", SVT_STRING, &arg))
105 { 105 {
106 struct mu_locus locus; 106 struct mu_locus_range locrange;
107 107
108 rc = mu_sieve_machine_clone (mach, &newmach); 108 rc = mu_sieve_machine_clone (mach, &newmach);
109 if (rc) 109 if (rc)
...@@ -112,10 +112,10 @@ moderator_filter_message (mu_sieve_machine_t mach, ...@@ -112,10 +112,10 @@ moderator_filter_message (mu_sieve_machine_t mach,
112 mu_strerror (rc)); 112 mu_strerror (rc));
113 return 1; 113 return 1;
114 } 114 }
115 mu_sieve_get_locus (mach, &locus); 115 mu_sieve_get_locus (mach, &locrange);
116 rc = mu_sieve_compile_buffer (newmach, 116 rc = mu_sieve_compile_buffer (newmach,
117 arg, strlen (arg), 117 arg, strlen (arg),
118 locus.mu_file, locus.mu_line); 118 &locrange.beg);
119 if (rc) 119 if (rc)
120 mu_sieve_error (mach, _("cannot compile subprogram")); 120 mu_sieve_error (mach, _("cannot compile subprogram"));
121 } 121 }
......
...@@ -218,7 +218,7 @@ mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb, ...@@ -218,7 +218,7 @@ mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb,
218 worth the trouble. */ 218 worth the trouble. */
219 if ((size_t) -1 / 3 * 2 / size <= nmemb) 219 if ((size_t) -1 / 3 * 2 / size <= nmemb)
220 { 220 {
221 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 221 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
222 _("requested too much memory %zu * %zu"), 222 _("requested too much memory %zu * %zu"),
223 nmemb, size); 223 nmemb, size);
224 mu_sieve_abort (mach); 224 mu_sieve_abort (mach);
...@@ -232,19 +232,19 @@ mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb, ...@@ -232,19 +232,19 @@ mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb,
232 *pnmemb = nmemb; 232 *pnmemb = nmemb;
233 } 233 }
234 234
235 char * 235 size_t
236 mu_i_sv_id_canon (mu_sieve_machine_t mach, char const *name) 236 mu_i_sv_id_num (mu_sieve_machine_t mach, char const *name)
237 { 237 {
238 size_t i; 238 size_t i;
239 char *p; 239 char *p;
240 240
241 if (!name) 241 if (!name)
242 return NULL; 242 abort ();
243 243
244 for (i = 0; i < mach->idcount; i++) 244 for (i = 0; i < mach->idcount; i++)
245 { 245 {
246 if (strcmp (mach->idspace[i], name) == 0) 246 if (strcmp (mach->idspace[i], name) == 0)
247 return mach->idspace[i]; 247 return i;
248 } 248 }
249 249
250 if (mach->idcount == mach->idmax) 250 if (mach->idcount == mach->idmax)
...@@ -256,22 +256,9 @@ mu_i_sv_id_canon (mu_sieve_machine_t mach, char const *name) ...@@ -256,22 +256,9 @@ mu_i_sv_id_canon (mu_sieve_machine_t mach, char const *name)
256 } 256 }
257 257
258 p = mu_sieve_strdup (mach, name); 258 p = mu_sieve_strdup (mach, name);
259 mach->idspace[mach->idcount++] = p; 259 mach->idspace[mach->idcount] = p;
260 260
261 return p; 261 return mach->idcount++;
262 }
263
264 size_t
265 mu_i_sv_id_num (mu_sieve_machine_t mach, char const *name)
266 {
267 size_t i;
268
269 for (i = 0; i < mach->idcount; i++)
270 {
271 if (mach->idspace[i] == name || strcmp (mach->idspace[i], name) == 0)
272 return i;
273 }
274 abort ();
275 } 262 }
276 263
277 char * 264 char *
......
...@@ -35,32 +35,48 @@ mu_i_sv_code (struct mu_sieve_machine *mach, sieve_op_t op) ...@@ -35,32 +35,48 @@ mu_i_sv_code (struct mu_sieve_machine *mach, sieve_op_t op)
35 mach->prog[mach->pc++] = op; 35 mach->prog[mach->pc++] = op;
36 } 36 }
37 37
38 static int
39 file_eq (char const *a, char const *b)
40 {
41 if (a)
42 return b ? (strcmp (a, b) == 0) : 1;
43 return b ? 0 : 1;
44 }
45
46 /* FIXME: 1. Only beg is stored
47 2. mu_col is not used
48 */
49 int 38 int
50 mu_i_sv_locus (struct mu_sieve_machine *mach, struct mu_locus_range *lr) 39 mu_i_sv_locus (struct mu_sieve_machine *mach, struct mu_locus_range *lr)
51 { 40 {
52 if (!file_eq (mach->locus.mu_file, lr->beg.mu_file)) 41 if (!mu_locus_point_same_file (&mach->locus.beg, &lr->beg))
53 { 42 {
54 mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_source); 43 mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_source);
55 mu_i_sv_code (mach, (sieve_op_t) mu_i_sv_id_num (mach, lr->beg.mu_file)); 44 mu_i_sv_code (mach, (sieve_op_t) mu_i_sv_id_num (mach, lr->beg.mu_file));
45 mu_i_sv_code (mach, (sieve_op_t) (int) 0);
56 } 46 }
57 if (mach->locus.mu_line != lr->beg.mu_line) 47 if (mach->locus.beg.mu_line != lr->beg.mu_line)
58 { 48 {
59 mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_line); 49 mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_line);
60 mu_i_sv_code (mach, (sieve_op_t) lr->beg.mu_line); 50 mu_i_sv_code (mach, (sieve_op_t) lr->beg.mu_line);
51 mu_i_sv_code (mach, (sieve_op_t) (int) 0);
52 }
53 if (mach->locus.beg.mu_col != lr->beg.mu_col)
54 {
55 mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_col);
56 mu_i_sv_code (mach, (sieve_op_t) lr->beg.mu_col);
57 mu_i_sv_code (mach, (sieve_op_t) (int) 0);
58 }
59
60 if (!mu_locus_point_same_file (&mach->locus.end, &lr->end))
61 {
62 mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_source);
63 mu_i_sv_code (mach, (sieve_op_t) mu_i_sv_id_num (mach, lr->end.mu_file));
64 mu_i_sv_code (mach, (sieve_op_t) (int) 1);
65 }
66 if (mach->locus.end.mu_line != lr->end.mu_line)
67 {
68 mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_line);
69 mu_i_sv_code (mach, (sieve_op_t) lr->end.mu_line);
70 mu_i_sv_code (mach, (sieve_op_t) (int) 1);
71 }
72 if (mach->locus.end.mu_col != lr->end.mu_col)
73 {
74 mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_col);
75 mu_i_sv_code (mach, (sieve_op_t) lr->end.mu_col);
76 mu_i_sv_code (mach, (sieve_op_t) (int) 1);
61 } 77 }
62 78
63 mach->locus = lr->beg; 79 mu_locus_range_copy (&mach->locus, lr);
64 return 0; 80 return 0;
65 } 81 }
66 82
...@@ -155,7 +171,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, ...@@ -155,7 +171,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
155 171
156 if (!tag) 172 if (!tag)
157 { 173 {
158 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 174 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
159 _("invalid tag name `%s' for `%s'"), 175 _("invalid tag name `%s' for `%s'"),
160 val->v.string, reg->name); 176 val->v.string, reg->name);
161 mu_i_sv_error (mach); 177 mu_i_sv_error (mach);
...@@ -175,7 +191,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, ...@@ -175,7 +191,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
175 { 191 {
176 if (i + 1 == node->v.command.argcount) 192 if (i + 1 == node->v.command.argcount)
177 { 193 {
178 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 194 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
179 _("required argument for tag %s is missing"), 195 _("required argument for tag %s is missing"),
180 tag->name); 196 tag->name);
181 mu_i_sv_error (mach); 197 mu_i_sv_error (mach);
...@@ -192,11 +208,11 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, ...@@ -192,11 +208,11 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
192 208
193 if (val->type != tag->argtype) 209 if (val->type != tag->argtype)
194 { 210 {
195 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 211 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
196 _("type mismatch in argument to " 212 _("type mismatch in argument to "
197 "tag `%s'"), 213 "tag `%s'"),
198 tag->name); 214 tag->name);
199 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 215 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
200 _("expected %s but passed %s"), 216 _("expected %s but passed %s"),
201 mu_sieve_type_str (tag->argtype), 217 mu_sieve_type_str (tag->argtype),
202 mu_sieve_type_str (val->type)); 218 mu_sieve_type_str (val->type));
...@@ -210,7 +226,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, ...@@ -210,7 +226,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
210 { 226 {
211 if (!chk_list && (rc = mu_list_create (&chk_list))) 227 if (!chk_list && (rc = mu_list_create (&chk_list)))
212 { 228 {
213 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 229 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
214 _("cannot create check list: %s"), 230 _("cannot create check list: %s"),
215 mu_strerror (rc)); 231 mu_strerror (rc));
216 mu_i_sv_error (mach); 232 mu_i_sv_error (mach);
...@@ -222,7 +238,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, ...@@ -222,7 +238,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
222 rc = mu_list_append (chk_list, cf); 238 rc = mu_list_append (chk_list, cf);
223 if (rc) 239 if (rc)
224 { 240 {
225 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 241 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
226 "mu_list_append: %s", 242 "mu_list_append: %s",
227 mu_strerror (rc)); 243 mu_strerror (rc));
228 mu_i_sv_error (mach); 244 mu_i_sv_error (mach);
...@@ -243,7 +259,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, ...@@ -243,7 +259,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
243 } 259 }
244 else 260 else
245 { 261 {
246 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 262 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
247 _("too many arguments in call to `%s'"), 263 _("too many arguments in call to `%s'"),
248 reg->name); 264 reg->name);
249 mu_i_sv_error (mach); 265 mu_i_sv_error (mach);
...@@ -258,11 +274,11 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, ...@@ -258,11 +274,11 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
258 /* compatible types */; 274 /* compatible types */;
259 else 275 else
260 { 276 {
261 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 277 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
262 _("type mismatch in argument %lu to `%s'"), 278 _("type mismatch in argument %lu to `%s'"),
263 (unsigned long) (exp_arg - reg->v.command.req_args + 1), 279 (unsigned long) (exp_arg - reg->v.command.req_args + 1),
264 reg->name); 280 reg->name);
265 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 281 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
266 _("expected %s but passed %s"), 282 _("expected %s but passed %s"),
267 mu_sieve_type_str (*exp_arg), 283 mu_sieve_type_str (*exp_arg),
268 mu_sieve_type_str (val->type)); 284 mu_sieve_type_str (val->type));
...@@ -277,7 +293,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, ...@@ -277,7 +293,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
277 293
278 if (!err && !opt_args && *exp_arg != SVT_VOID) 294 if (!err && !opt_args && *exp_arg != SVT_VOID)
279 { 295 {
280 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 296 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
281 _("too few arguments in call to `%s'"), 297 _("too few arguments in call to `%s'"),
282 reg->name); 298 reg->name);
283 mu_i_sv_error (mach); 299 mu_i_sv_error (mach);
......
...@@ -56,7 +56,7 @@ mu_sieve_require (mu_sieve_machine_t mach, mu_sieve_slice_t list) ...@@ -56,7 +56,7 @@ mu_sieve_require (mu_sieve_machine_t mach, mu_sieve_slice_t list)
56 56
57 if (rc) 57 if (rc)
58 { 58 {
59 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, _("can't require %s"), 59 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus, _("can't require %s"),
60 name); 60 name);
61 mu_i_sv_error (mach); 61 mu_i_sv_error (mach);
62 } 62 }
......
...@@ -34,26 +34,46 @@ ...@@ -34,26 +34,46 @@
34 void 34 void
35 _mu_i_sv_instr_source (mu_sieve_machine_t mach) 35 _mu_i_sv_instr_source (mu_sieve_machine_t mach)
36 { 36 {
37 mach->locus.mu_file = mu_i_sv_id_str (mach, SIEVE_RT_ARG (mach, 0, pc)); 37 char const *file = mu_i_sv_id_str (mach, SIEVE_RT_ARG (mach, 0, pc));
38 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, 38 int what = SIEVE_RT_ARG (mach, 1, inum);
39 MU_IOCTL_LOGSTREAM_SET_LOCUS, 39 mu_locus_point_set_file (what ? &mach->locus.beg : &mach->locus.end, file);
40 &mach->locus);
41 if (INSTR_DEBUG (mach)) 40 if (INSTR_DEBUG (mach))
42 mu_i_sv_debug (mach, mach->pc - 1, "SOURCE %s", mach->locus.mu_file); 41 mu_i_sv_debug (mach, mach->pc - 2, "SOURCE %s %d", file, what);
43 SIEVE_RT_ADJUST (mach, 1); 42 SIEVE_RT_ADJUST (mach, 2);
43 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM,
44 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &mach->locus);
44 } 45 }
45 46
46 void 47 void
47 _mu_i_sv_instr_line (mu_sieve_machine_t mach) 48 _mu_i_sv_instr_line (mu_sieve_machine_t mach)
48 { 49 {
49 mach->locus.mu_line = SIEVE_RT_ARG (mach, 0, line); 50 unsigned line = SIEVE_RT_ARG (mach, 0, line);
51 int what = SIEVE_RT_ARG (mach, 1, inum);
52 if (what == 0)
53 mach->locus.beg.mu_line = line;
54 else
55 mach->locus.end.mu_line = line;
56 if (INSTR_DEBUG (mach))
57 mu_i_sv_debug (mach, mach->pc - 1, "LINE %u %d", line, what);
58 SIEVE_RT_ADJUST (mach, 2);
50 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, 59 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM,
51 MU_IOCTL_LOGSTREAM_SET_LOCUS, 60 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &mach->locus);
52 &mach->locus); 61 }
62
63 void
64 _mu_i_sv_instr_col (mu_sieve_machine_t mach)
65 {
66 unsigned col = SIEVE_RT_ARG (mach, 0, line);
67 int what = SIEVE_RT_ARG (mach, 1, inum);
68 if (what == 0)
69 mach->locus.beg.mu_col = col;
70 else
71 mach->locus.end.mu_col = col;
53 if (INSTR_DEBUG (mach)) 72 if (INSTR_DEBUG (mach))
54 mu_i_sv_debug (mach, mach->pc - 1, "LINE %u", 73 mu_i_sv_debug (mach, mach->pc - 2, "COLUMN %u %d", col, what);
55 mach->locus.mu_line); 74 SIEVE_RT_ADJUST (mach, 2);
56 SIEVE_RT_ADJUST (mach, 1); 75 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM,
76 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &mach->locus);
57 } 77 }
58 78
59 static int 79 static int
...@@ -173,14 +193,9 @@ mu_sieve_get_data (mu_sieve_machine_t mach) ...@@ -173,14 +193,9 @@ mu_sieve_get_data (mu_sieve_machine_t mach)
173 } 193 }
174 194
175 int 195 int
176 mu_sieve_get_locus (mu_sieve_machine_t mach, struct mu_locus *loc) 196 mu_sieve_get_locus (mu_sieve_machine_t mach, struct mu_locus_range *loc)
177 { 197 {
178 if (mach->locus.mu_file) 198 return mu_locus_range_copy (loc, &mach->locus);
179 {
180 *loc = mach->locus;
181 return 0;
182 }
183 return 1;
184 } 199 }
185 200
186 mu_mailbox_t 201 mu_mailbox_t
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
18 18
19 #include <mailutils/sieve.h> 19 #include <mailutils/sieve.h>
20 #include <mailutils/assoc.h> 20 #include <mailutils/assoc.h>
21 #include <mailutils/locus.h>
22 #include <mailutils/yyloc.h>
21 #include <setjmp.h> 23 #include <setjmp.h>
22 #include <string.h> 24 #include <string.h>
23 #include <regex.h> 25 #include <regex.h>
...@@ -38,13 +40,6 @@ typedef union ...@@ -38,13 +40,6 @@ typedef union
38 unsigned unum; 40 unsigned unum;
39 } sieve_op_t; 41 } sieve_op_t;
40 42
41 struct mu_locus_range
42 {
43 struct mu_locus beg;
44 struct mu_locus end;
45 };
46
47 #define YYLTYPE struct mu_locus_range
48 43
49 #define MU_SV_SAVED_ERR_STATE 0x01 44 #define MU_SV_SAVED_ERR_STATE 0x01
50 #define MU_SV_SAVED_DBG_STATE 0x02 45 #define MU_SV_SAVED_DBG_STATE 0x02
...@@ -62,7 +57,7 @@ enum mu_sieve_state ...@@ -62,7 +57,7 @@ enum mu_sieve_state
62 struct mu_sieve_machine 57 struct mu_sieve_machine
63 { 58 {
64 /* Static data */ 59 /* Static data */
65 struct mu_locus locus; /* Approximate location in the code */ 60 struct mu_locus_range locus; /* Approximate location in the code */
66 61
67 mu_list_t memory_pool; /* Pool of allocated memory objects */ 62 mu_list_t memory_pool; /* Pool of allocated memory objects */
68 mu_list_t destr_list; /* List of destructor functions */ 63 mu_list_t destr_list; /* List of destructor functions */
...@@ -118,9 +113,9 @@ struct mu_sieve_machine ...@@ -118,9 +113,9 @@ struct mu_sieve_machine
118 /* Stream state info */ 113 /* Stream state info */
119 int state_flags; 114 int state_flags;
120 int err_mode; 115 int err_mode;
121 struct mu_locus err_locus; 116 struct mu_locus_range err_locus;
122 int dbg_mode; 117 int dbg_mode;
123 struct mu_locus dbg_locus; 118 struct mu_locus_range dbg_locus;
124 119
125 /* User supplied data */ 120 /* User supplied data */
126 mu_stream_t errstream; 121 mu_stream_t errstream;
...@@ -182,7 +177,7 @@ int mu_sieve_yylex (void); ...@@ -182,7 +177,7 @@ int mu_sieve_yylex (void);
182 177
183 int mu_i_sv_lex_begin (const char *name); 178 int mu_i_sv_lex_begin (const char *name);
184 int mu_i_sv_lex_begin_string (const char *buf, int bufsize, 179 int mu_i_sv_lex_begin_string (const char *buf, int bufsize,
185 const char *fname, int line); 180 struct mu_locus_point const *pt);
186 void mu_i_sv_lex_finish (void); 181 void mu_i_sv_lex_finish (void);
187 182
188 extern mu_sieve_machine_t mu_sieve_machine; 183 extern mu_sieve_machine_t mu_sieve_machine;
...@@ -204,6 +199,7 @@ void _mu_i_sv_instr_brz (mu_sieve_machine_t mach); ...@@ -204,6 +199,7 @@ void _mu_i_sv_instr_brz (mu_sieve_machine_t mach);
204 void _mu_i_sv_instr_brnz (mu_sieve_machine_t mach); 199 void _mu_i_sv_instr_brnz (mu_sieve_machine_t mach);
205 void _mu_i_sv_instr_source (mu_sieve_machine_t mach); 200 void _mu_i_sv_instr_source (mu_sieve_machine_t mach);
206 void _mu_i_sv_instr_line (mu_sieve_machine_t mach); 201 void _mu_i_sv_instr_line (mu_sieve_machine_t mach);
202 void _mu_i_sv_instr_col (mu_sieve_machine_t mach);
207 203
208 int mu_i_sv_load_add_dir (mu_sieve_machine_t mach, const char *name); 204 int mu_i_sv_load_add_dir (mu_sieve_machine_t mach, const char *name);
209 205
...@@ -244,7 +240,6 @@ void mu_i_sv_lint_command (struct mu_sieve_machine *mach, ...@@ -244,7 +240,6 @@ void mu_i_sv_lint_command (struct mu_sieve_machine *mach,
244 240
245 size_t mu_i_sv_string_create (mu_sieve_machine_t mach, char *str); 241 size_t mu_i_sv_string_create (mu_sieve_machine_t mach, char *str);
246 242
247 char *mu_i_sv_id_canon (mu_sieve_machine_t mach, char const *name);
248 size_t mu_i_sv_id_num (mu_sieve_machine_t mach, char const *name); 243 size_t mu_i_sv_id_num (mu_sieve_machine_t mach, char const *name);
249 char *mu_i_sv_id_str (mu_sieve_machine_t mach, size_t n); 244 char *mu_i_sv_id_str (mu_sieve_machine_t mach, size_t n);
250 void mu_i_sv_free_idspace (mu_sieve_machine_t mach); 245 void mu_i_sv_free_idspace (mu_sieve_machine_t mach);
......
...@@ -54,10 +54,8 @@ static void sieve_searchpath (void); ...@@ -54,10 +54,8 @@ static void sieve_searchpath (void);
54 static char *str_unescape (char *text, size_t len); 54 static char *str_unescape (char *text, size_t len);
55 static int isemptystr (char *text); 55 static int isemptystr (char *text);
56 56
57 static mu_linetrack_t trk;
57 static ino_t sieve_source_inode; 58 static ino_t sieve_source_inode;
58 struct mu_locus mu_sieve_locus;
59 static int newline;
60
61 static mu_stream_t input_stream; 59 static mu_stream_t input_stream;
62 60
63 static int 61 static int
...@@ -71,8 +69,10 @@ fillbuf (char *buf, size_t max_size) ...@@ -71,8 +69,10 @@ fillbuf (char *buf, size_t max_size)
71 rc = mu_stream_read (input_stream, buf, max_size, &max_size); 69 rc = mu_stream_read (input_stream, buf, max_size, &max_size);
72 if (rc) 70 if (rc)
73 { 71 {
74 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_read", 72 struct mu_locus_point pt;
75 mu_sieve_locus.mu_file, rc); 73 mu_linetrack_locus (trk, &pt);
74 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_read", pt.mu_file, rc);
75 mu_locus_point_deinit (&pt);
76 return 0; 76 return 0;
77 } 77 }
78 return max_size; 78 return max_size;
...@@ -90,40 +90,33 @@ fillbuf (char *buf, size_t max_size) ...@@ -90,40 +90,33 @@ fillbuf (char *buf, size_t max_size)
90 yy_switch_to_buffer (s); \ 90 yy_switch_to_buffer (s); \
91 } while (0) 91 } while (0)
92 92
93 static void 93 #define YY_USER_ACTION \
94 init_locus (char const *name, ino_t ino) 94 do \
95 { 95 { \
96 mu_sieve_locus.mu_file = mu_i_sv_id_canon (mu_sieve_machine, name); 96 mu_linetrack_advance (trk, &yylloc, yytext, yyleng); \
97 mu_sieve_locus.mu_line = 1; 97 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, \
98 mu_sieve_locus.mu_col = 0; 98 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &yylloc); \
99 newline = 0; 99 } \
100 sieve_source_inode = ino; 100 while (0);
101 } 101
102 102
103 static void 103 static void
104 advance_locus (void) 104 init_locus (char const *name, ino_t ino)
105 { 105 {
106 if (newline) 106 if (name)
107 { 107 {
108 mu_sieve_locus.mu_line++; 108 MU_ASSERT (mu_linetrack_create (&trk, name, 2));
109 mu_sieve_locus.mu_col = 0;
110 yylloc.beg = yylloc.end = mu_sieve_locus;
111 } 109 }
112 else 110 else
113 { 111 mu_linetrack_destroy (&trk);
114 mu_sieve_locus.mu_col += yyleng; 112 sieve_source_inode = ino;
115 yylloc.beg = yylloc.end = mu_sieve_locus;
116 yylloc.beg.mu_col -= yyleng;
117 }
118 newline = yytext[yyleng-1] == '\n';
119 } 113 }
120 114
121 #define YY_USER_ACTION advance_locus ();
122
123 struct buffer_ctx 115 struct buffer_ctx
124 { 116 {
125 struct buffer_ctx *prev; 117 struct buffer_ctx *prev;
126 struct mu_locus locus; 118 mu_linetrack_t trk;
119 struct mu_locus_range incl_range;
127 ino_t i_node; 120 ino_t i_node;
128 mu_stream_t input; 121 mu_stream_t input;
129 LEX_BUFFER_STATE state; 122 LEX_BUFFER_STATE state;
...@@ -156,13 +149,12 @@ push_source (const char *name) ...@@ -156,13 +149,12 @@ push_source (const char *name)
156 149
157 if (stat (name, &st)) 150 if (stat (name, &st))
158 { 151 {
159 mu_diag_at_locus (MU_LOG_ERROR, &mu_sieve_locus, 152 mu_error (_("cannot stat `%s': %s"), name, strerror (errno));
160 _("cannot stat `%s': %s"), name, strerror (errno));
161 mu_i_sv_error (mu_sieve_machine); 153 mu_i_sv_error (mu_sieve_machine);
162 return 1; 154 return 1;
163 } 155 }
164 156
165 if (mu_sieve_locus.mu_file && st.st_ino == sieve_source_inode) 157 if (yylloc.beg.mu_file && st.st_ino == sieve_source_inode)
166 { 158 {
167 yyerror (_("recursive inclusion")); 159 yyerror (_("recursive inclusion"));
168 return 1; 160 return 1;
...@@ -172,16 +164,14 @@ push_source (const char *name) ...@@ -172,16 +164,14 @@ push_source (const char *name)
172 yyerror (_("recursive inclusion")); 164 yyerror (_("recursive inclusion"));
173 if (ctx->prev) 165 if (ctx->prev)
174 { 166 {
175 mu_diag_at_locus (MU_LOG_ERROR, &ctx->prev->locus, 167 mu_diag_at_locus_range (MU_LOG_ERROR, &ctx->incl_range,
176 _("`%s' already included here"), 168 _("`%s' already included here"),
177 name); 169 name);
178 mu_i_sv_error (mu_sieve_machine); 170 mu_i_sv_error (mu_sieve_machine);
179 } 171 }
180 else 172 else
181 { 173 {
182 mu_diag_at_locus (MU_LOG_ERROR, &mu_sieve_locus, 174 mu_error (_("`%s' already included at top level"), name);
183 _("`%s' already included at top level"),
184 name);
185 mu_i_sv_error (mu_sieve_machine); 175 mu_i_sv_error (mu_sieve_machine);
186 } 176 }
187 return 1; 177 return 1;
...@@ -190,19 +180,16 @@ push_source (const char *name) ...@@ -190,19 +180,16 @@ push_source (const char *name)
190 rc = mu_file_stream_create (&stream, name, MU_STREAM_READ); 180 rc = mu_file_stream_create (&stream, name, MU_STREAM_READ);
191 if (rc) 181 if (rc)
192 { 182 {
193 mu_diag_at_locus (MU_LOG_ERROR, &mu_sieve_locus, 183 mu_error (_("cannot open file `%s': %s"), name, mu_strerror (rc));
194 _("cannot open file `%s': %s"),
195 name, mu_strerror (rc));
196 mu_i_sv_error (mu_sieve_machine); 184 mu_i_sv_error (mu_sieve_machine);
197 return 1; 185 return 1;
198 } 186 }
199 187
200 /* Push current context */ 188 /* Push current context */
201 if (mu_sieve_locus.mu_file) 189 if (trk)
202 { 190 {
203 advance_locus (); 191 ctx->trk = trk;
204 ctx = mu_sieve_malloc (mu_sieve_machine, sizeof (*ctx)); 192 mu_locus_range_copy (&ctx->incl_range, &yylloc);
205 ctx->locus = mu_sieve_locus;
206 ctx->i_node = sieve_source_inode; 193 ctx->i_node = sieve_source_inode;
207 ctx->input = input_stream; 194 ctx->input = input_stream;
208 ctx->prev = context_stack; 195 ctx->prev = context_stack;
...@@ -233,7 +220,9 @@ pop_source () ...@@ -233,7 +220,9 @@ pop_source ()
233 } 220 }
234 /* Restore previous context */ 221 /* Restore previous context */
235 input_stream = context_stack->input; 222 input_stream = context_stack->input;
236 mu_sieve_locus = context_stack->locus; 223 mu_linetrack_destroy (&trk);
224 trk = context_stack->trk;
225 mu_locus_range_deinit (&context_stack->incl_range);
237 sieve_source_inode = context_stack->i_node; 226 sieve_source_inode = context_stack->i_node;
238 RESTORE_BUFFER_STATE (context_stack->state); 227 RESTORE_BUFFER_STATE (context_stack->state);
239 ctx = context_stack->prev; 228 ctx = context_stack->prev;
...@@ -449,12 +438,10 @@ mu_i_sv_lex_begin (const char *name) ...@@ -449,12 +438,10 @@ mu_i_sv_lex_begin (const char *name)
449 438
450 int 439 int
451 mu_i_sv_lex_begin_string (const char *buf, int bufsize, 440 mu_i_sv_lex_begin_string (const char *buf, int bufsize,
452 const char *fname, int line) 441 struct mu_locus_point const *pt)
453 { 442 {
454 int rc; 443 int rc;
455 444
456 if (!fname)
457 return 1;
458 yyrestart (NULL); 445 yyrestart (NULL);
459 446
460 rc = mu_static_memory_stream_create (&input_stream, buf, bufsize); 447 rc = mu_static_memory_stream_create (&input_stream, buf, bufsize);
...@@ -465,7 +452,8 @@ mu_i_sv_lex_begin_string (const char *buf, int bufsize, ...@@ -465,7 +452,8 @@ mu_i_sv_lex_begin_string (const char *buf, int bufsize,
465 return 1; 452 return 1;
466 } 453 }
467 454
468 init_locus (fname, 0); 455 init_locus (pt->mu_file, 0);
456 mu_linetrack_rebase (trk, pt);
469 457
470 return 0; 458 return 0;
471 } 459 }
...@@ -643,9 +631,7 @@ line_finish (void) ...@@ -643,9 +631,7 @@ line_finish (void)
643 } 631 }
644 else if (rc != MU_ERR_CANCELED) 632 else if (rc != MU_ERR_CANCELED)
645 { 633 {
646 mu_diag_at_locus (MU_LOG_ERROR, &mu_sieve_locus, 634 mu_error (_("error expandind string: %s"), mu_strerror (rc));
647 _("error expandind string: %s"),
648 mu_strerror (rc));
649 } 635 }
650 } 636 }
651 yylval.string = str; 637 yylval.string = str;
......
...@@ -36,44 +36,6 @@ static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type, ...@@ -36,44 +36,6 @@ static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type,
36 static void node_list_add (struct mu_sieve_node_list *list, 36 static void node_list_add (struct mu_sieve_node_list *list,
37 struct mu_sieve_node *node); 37 struct mu_sieve_node *node);
38 38
39
40 #define YYLLOC_DEFAULT(Current, Rhs, N) \
41 do \
42 { \
43 if (N) \
44 { \
45 (Current).beg = YYRHSLOC(Rhs, 1).beg; \
46 (Current).end = YYRHSLOC(Rhs, N).end; \
47 } \
48 else \
49 { \
50 (Current).beg = YYRHSLOC(Rhs, 0).end; \
51 (Current).end = (Current).beg; \
52 } \
53 } while (0)
54
55 #define LOCUS_EQ(a,b) \
56 ((((a)->mu_file == (b)->mu_file) \
57 || ((a)->mu_file && (b)->mu_file \
58 && strcmp((a)->mu_file, (b)->mu_file) == 0)) \
59 && (a)->mu_line == (b)->mu_line)
60
61 #define YY_LOCATION_PRINT(File, Loc) \
62 do \
63 { \
64 if (LOCUS_EQ(&(Loc).beg, &(Loc).end)) \
65 fprintf(File, "%s:%u.%u-%u.%u", \
66 (Loc).beg.mu_file, \
67 (Loc).beg.mu_line, (Loc).beg.mu_col, \
68 (Loc).end.mu_line, (Loc).end.mu_col); \
69 else \
70 fprintf(File, "%s:%u.%u-%s:%u.%u", \
71 (Loc).beg.mu_file, \
72 (Loc).beg.mu_line, (Loc).beg.mu_col, \
73 (Loc).end.mu_file, \
74 (Loc).end.mu_line, (Loc).end.mu_col); \
75 } \
76 while (0)
77 %} 39 %}
78 40
79 %error-verbose 41 %error-verbose
...@@ -87,6 +49,7 @@ static void node_list_add (struct mu_sieve_node_list *list, ...@@ -87,6 +49,7 @@ static void node_list_add (struct mu_sieve_node_list *list,
87 struct 49 struct
88 { 50 {
89 char *ident; 51 char *ident;
52 struct mu_locus_range idloc;
90 size_t first; 53 size_t first;
91 size_t count; 54 size_t count;
92 } command; 55 } command;
...@@ -242,19 +205,19 @@ test : command ...@@ -242,19 +205,19 @@ test : command
242 { 205 {
243 mu_sieve_registry_t *reg; 206 mu_sieve_registry_t *reg;
244 207
245 mu_sieve_machine->locus = @1.beg; 208 mu_locus_range_copy (&mu_sieve_machine->locus, &@1);
246 reg = mu_sieve_registry_lookup (mu_sieve_machine, $1.ident, 209 reg = mu_sieve_registry_lookup (mu_sieve_machine, $1.ident,
247 mu_sieve_record_test); 210 mu_sieve_record_test);
248 if (!reg) 211 if (!reg)
249 { 212 {
250 mu_diag_at_locus (MU_LOG_ERROR, &@1.beg, 213 mu_diag_at_locus_range (MU_LOG_ERROR, &$1.idloc,
251 _("unknown test: %s"), 214 _("unknown test: %s"),
252 $1.ident); 215 $1.ident);
253 mu_i_sv_error (mu_sieve_machine); 216 mu_i_sv_error (mu_sieve_machine);
254 } 217 }
255 else if (!reg->required) 218 else if (!reg->required)
256 { 219 {
257 mu_diag_at_locus (MU_LOG_ERROR, &@1.beg, 220 mu_diag_at_locus_range (MU_LOG_ERROR, &$1.idloc,
258 _("test `%s' has not been required"), 221 _("test `%s' has not been required"),
259 $1.ident); 222 $1.ident);
260 mu_i_sv_error (mu_sieve_machine); 223 mu_i_sv_error (mu_sieve_machine);
...@@ -281,6 +244,7 @@ test : command ...@@ -281,6 +244,7 @@ test : command
281 command : IDENT maybe_arglist 244 command : IDENT maybe_arglist
282 { 245 {
283 $$.ident = $1; 246 $$.ident = $1;
247 $$.idloc = @1;
284 $$.first = $2.first; 248 $$.first = $2.first;
285 $$.count = $2.count; 249 $$.count = $2.count;
286 } 250 }
...@@ -290,20 +254,20 @@ action : command ...@@ -290,20 +254,20 @@ action : command
290 { 254 {
291 mu_sieve_registry_t *reg; 255 mu_sieve_registry_t *reg;
292 256
293 mu_sieve_machine->locus = @1.beg; 257 mu_locus_range_copy (&mu_sieve_machine->locus, &@1);
294 reg = mu_sieve_registry_lookup (mu_sieve_machine, $1.ident, 258 reg = mu_sieve_registry_lookup (mu_sieve_machine, $1.ident,
295 mu_sieve_record_action); 259 mu_sieve_record_action);
296 260
297 if (!reg) 261 if (!reg)
298 { 262 {
299 mu_diag_at_locus (MU_LOG_ERROR, &@1.beg, 263 mu_diag_at_locus_range (MU_LOG_ERROR, &$1.idloc,
300 _("unknown action: %s"), 264 _("unknown action: %s"),
301 $1.ident); 265 $1.ident);
302 mu_i_sv_error (mu_sieve_machine); 266 mu_i_sv_error (mu_sieve_machine);
303 } 267 }
304 else if (!reg->required) 268 else if (!reg->required)
305 { 269 {
306 mu_diag_at_locus (MU_LOG_ERROR, &@1.beg, 270 mu_diag_at_locus_range (MU_LOG_ERROR, &$1.idloc,
307 _("action `%s' has not been required"), 271 _("action `%s' has not been required"),
308 $1.ident); 272 $1.ident);
309 mu_i_sv_error (mu_sieve_machine); 273 mu_i_sv_error (mu_sieve_machine);
...@@ -393,10 +357,7 @@ slist : STRING ...@@ -393,10 +357,7 @@ slist : STRING
393 int 357 int
394 yyerror (const char *s) 358 yyerror (const char *s)
395 { 359 {
396 extern struct mu_locus mu_sieve_locus; 360 mu_error ("%s", s);
397
398 mu_sieve_machine->locus = mu_sieve_locus;
399 mu_diag_at_locus (MU_LOG_ERROR, &mu_sieve_locus, "%s", s);
400 mu_i_sv_error (mu_sieve_machine); 361 mu_i_sv_error (mu_sieve_machine);
401 return 0; 362 return 0;
402 } 363 }
...@@ -423,7 +384,7 @@ node_alloc (enum mu_sieve_node_type type, struct mu_locus_range *lr) ...@@ -423,7 +384,7 @@ node_alloc (enum mu_sieve_node_type type, struct mu_locus_range *lr)
423 { 384 {
424 node->prev = node->next = NULL; 385 node->prev = node->next = NULL;
425 node->type = type; 386 node->type = type;
426 node->locus = *lr; 387 mu_locus_range_copy (&node->locus, lr);
427 } 388 }
428 return node; 389 return node;
429 } 390 }
...@@ -1104,15 +1065,9 @@ copy_stream_state (mu_sieve_machine_t child, mu_sieve_machine_t parent) ...@@ -1104,15 +1065,9 @@ copy_stream_state (mu_sieve_machine_t child, mu_sieve_machine_t parent)
1104 { 1065 {
1105 child->state_flags = parent->state_flags; 1066 child->state_flags = parent->state_flags;
1106 child->err_mode = parent->err_mode; 1067 child->err_mode = parent->err_mode;
1107 child->err_locus = parent->err_locus; 1068 mu_locus_range_copy (&child->err_locus, &parent->err_locus);
1108 if (child->err_locus.mu_file)
1109 child->err_locus.mu_file =
1110 mu_sieve_strdup (child, child->err_locus.mu_file);
1111 child->dbg_mode = parent->dbg_mode; 1069 child->dbg_mode = parent->dbg_mode;
1112 child->dbg_locus = parent->dbg_locus; 1070 mu_locus_range_copy (&child->dbg_locus, &parent->dbg_locus);
1113 if (child->dbg_locus.mu_file)
1114 child->dbg_locus.mu_file =
1115 mu_sieve_strdup (child, child->dbg_locus.mu_file);
1116 child->errstream = parent->errstream; 1071 child->errstream = parent->errstream;
1117 mu_stream_ref (child->errstream); 1072 mu_stream_ref (child->errstream);
1118 child->dbgstream = parent->dbgstream; 1073 child->dbgstream = parent->dbgstream;
...@@ -1266,9 +1221,9 @@ mu_sieve_machine_dup (mu_sieve_machine_t const in, mu_sieve_machine_t *out) ...@@ -1266,9 +1221,9 @@ mu_sieve_machine_dup (mu_sieve_machine_t const in, mu_sieve_machine_t *out)
1266 1221
1267 mach->state_flags = in->state_flags; 1222 mach->state_flags = in->state_flags;
1268 mach->err_mode = in->err_mode; 1223 mach->err_mode = in->err_mode;
1269 mach->err_locus = in->err_locus; 1224 mu_locus_range_copy (&mach->err_locus, &in->err_locus);
1270 mach->dbg_mode = in->dbg_mode; 1225 mach->dbg_mode = in->dbg_mode;
1271 mach->dbg_locus = in->dbg_locus; 1226 mu_locus_range_copy (&mach->dbg_locus, &in->dbg_locus);
1272 1227
1273 copy_stream_state (mach, in); 1228 copy_stream_state (mach, in);
1274 1229
...@@ -1456,8 +1411,7 @@ mu_sieve_machine_destroy (mu_sieve_machine_t *pmach) ...@@ -1456,8 +1411,7 @@ mu_sieve_machine_destroy (mu_sieve_machine_t *pmach)
1456 } 1411 }
1457 1412
1458 int 1413 int
1459 with_machine (mu_sieve_machine_t mach, char const *name, 1414 with_machine (mu_sieve_machine_t mach, int (*thunk) (void *), void *data)
1460 int (*thunk) (void *), void *data)
1461 { 1415 {
1462 int rc = 0; 1416 int rc = 0;
1463 mu_stream_t save_errstr; 1417 mu_stream_t save_errstr;
...@@ -1523,11 +1477,21 @@ static int ...@@ -1523,11 +1477,21 @@ static int
1523 sieve_parse (void) 1477 sieve_parse (void)
1524 { 1478 {
1525 int rc; 1479 int rc;
1480 int old_mode, mode;
1526 1481
1527 sieve_tree = NULL; 1482 sieve_tree = NULL;
1528 yydebug = mu_debug_level_p (mu_sieve_debug_handle, MU_DEBUG_TRACE3); 1483 yydebug = mu_debug_level_p (mu_sieve_debug_handle, MU_DEBUG_TRACE3);
1529 1484
1485 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1486 MU_IOCTL_LOGSTREAM_GET_MODE, &old_mode);
1487 mode = old_mode | MU_LOGMODE_LOCUS;
1488 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1489 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
1490
1530 rc = yyparse (); 1491 rc = yyparse ();
1492 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1493 MU_IOCTL_LOGSTREAM_SET_MODE, &old_mode);
1494
1531 mu_i_sv_lex_finish (); 1495 mu_i_sv_lex_finish ();
1532 if (rc) 1496 if (rc)
1533 mu_i_sv_error (mu_sieve_machine); 1497 mu_i_sv_error (mu_sieve_machine);
...@@ -1547,9 +1511,8 @@ sieve_parse (void) ...@@ -1547,9 +1511,8 @@ sieve_parse (void)
1547 mu_i_sv_code (mu_sieve_machine, (sieve_op_t) (sieve_instr_t) 0); 1511 mu_i_sv_code (mu_sieve_machine, (sieve_op_t) (sieve_instr_t) 0);
1548 1512
1549 /* Clear location, so that mu_i_sv_locus will do its job. */ 1513 /* Clear location, so that mu_i_sv_locus will do its job. */
1550 mu_sieve_machine->locus.mu_file = NULL; 1514 /* FIXME: is it still needed? */
1551 mu_sieve_machine->locus.mu_line = 0; 1515 mu_locus_range_deinit (&mu_sieve_machine->locus);
1552 mu_sieve_machine->locus.mu_col = 0;
1553 1516
1554 tree_code (mu_sieve_machine, sieve_tree); 1517 tree_code (mu_sieve_machine, sieve_tree);
1555 mu_i_sv_code (mu_sieve_machine, (sieve_op_t) (sieve_instr_t) 0); 1518 mu_i_sv_code (mu_sieve_machine, (sieve_op_t) (sieve_instr_t) 0);
...@@ -1581,22 +1544,21 @@ sieve_compile_file (void *name) ...@@ -1581,22 +1544,21 @@ sieve_compile_file (void *name)
1581 int 1544 int
1582 mu_sieve_compile (mu_sieve_machine_t mach, const char *name) 1545 mu_sieve_compile (mu_sieve_machine_t mach, const char *name)
1583 { 1546 {
1584 return with_machine (mach, name, sieve_compile_file, (void *) name); 1547 return with_machine (mach, sieve_compile_file, (void *) name);
1585 } 1548 }
1586 1549
1587 struct strbuf 1550 struct strbuf
1588 { 1551 {
1589 const char *ptr; 1552 const char *ptr;
1590 size_t size; 1553 size_t size;
1591 const char *file; 1554 struct mu_locus_point const *pt;
1592 int line;
1593 }; 1555 };
1594 1556
1595 static int 1557 static int
1596 sieve_compile_strbuf (void *name) 1558 sieve_compile_strbuf (void *name)
1597 { 1559 {
1598 struct strbuf *buf = name; 1560 struct strbuf *buf = name;
1599 if (mu_i_sv_lex_begin_string (buf->ptr, buf->size, buf->file, buf->line) == 0) 1561 if (mu_i_sv_lex_begin_string (buf->ptr, buf->size, buf->pt) == 0)
1600 return sieve_parse (); 1562 return sieve_parse ();
1601 return MU_ERR_FAILURE; 1563 return MU_ERR_FAILURE;
1602 } 1564 }
...@@ -1604,14 +1566,13 @@ sieve_compile_strbuf (void *name) ...@@ -1604,14 +1566,13 @@ sieve_compile_strbuf (void *name)
1604 int 1566 int
1605 mu_sieve_compile_buffer (mu_sieve_machine_t mach, 1567 mu_sieve_compile_buffer (mu_sieve_machine_t mach,
1606 const char *str, int strsize, 1568 const char *str, int strsize,
1607 const char *fname, int line) 1569 struct mu_locus_point const *loc)
1608 { 1570 {
1609 struct strbuf buf; 1571 struct strbuf buf;
1610 buf.ptr = str; 1572 buf.ptr = str;
1611 buf.size = strsize; 1573 buf.size = strsize;
1612 buf.file = fname; 1574 buf.pt = loc;
1613 buf.line = line; 1575 return with_machine (mach, sieve_compile_strbuf, &buf);
1614 return with_machine (mach, fname, sieve_compile_strbuf, &buf);
1615 } 1576 }
1616 1577
1617 1578
......
...@@ -205,12 +205,6 @@ mu_sieve_error (mu_sieve_machine_t mach, const char *fmt, ...) ...@@ -205,12 +205,6 @@ mu_sieve_error (mu_sieve_machine_t mach, const char *fmt, ...)
205 205
206 va_start (ap, fmt); 206 va_start (ap, fmt);
207 mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_ERROR); 207 mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_ERROR);
208 if (mach->locus.mu_file)
209 mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
210 MU_LOGMODE_LOCUS,
211 (unsigned) strlen (mach->locus.mu_file),
212 mach->locus.mu_file,
213 mach->locus.mu_line);
214 if (mach->identifier) 208 if (mach->identifier)
215 mu_stream_printf (mach->errstream, "%s: ", mach->identifier); 209 mu_stream_printf (mach->errstream, "%s: ", mach->identifier);
216 mu_stream_vprintf (mach->errstream, fmt, ap); 210 mu_stream_vprintf (mach->errstream, fmt, ap);
...@@ -253,11 +247,11 @@ mu_i_sv_debug (mu_sieve_machine_t mach, size_t pc, const char *fmt, ...) ...@@ -253,11 +247,11 @@ mu_i_sv_debug (mu_sieve_machine_t mach, size_t pc, const char *fmt, ...)
253 unsigned severity = MU_LOG_DEBUG; 247 unsigned severity = MU_LOG_DEBUG;
254 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 248 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
255 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity); 249 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
256 if (mach->locus.mu_file) 250 if (mach->locus.beg.mu_file)
257 { 251 {
258 int mode = mach->dbg_mode | MU_LOGMODE_LOCUS; 252 int mode = mach->dbg_mode | MU_LOGMODE_LOCUS;
259 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 253 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
260 MU_IOCTL_LOGSTREAM_SET_LOCUS, &mach->locus); 254 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &mach->locus);
261 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 255 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
262 MU_IOCTL_LOGSTREAM_SET_MODE, &mode); 256 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
263 } 257 }
...@@ -281,11 +275,11 @@ mu_i_sv_debug_command (mu_sieve_machine_t mach, ...@@ -281,11 +275,11 @@ mu_i_sv_debug_command (mu_sieve_machine_t mach,
281 unsigned severity = MU_LOG_DEBUG; 275 unsigned severity = MU_LOG_DEBUG;
282 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 276 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
283 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity); 277 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
284 if (mach->locus.mu_file) 278 if (mach->locus.beg.mu_file)
285 { 279 {
286 int mode = mach->dbg_mode | MU_LOGMODE_LOCUS; 280 int mode = mach->dbg_mode | MU_LOGMODE_LOCUS;
287 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 281 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
288 MU_IOCTL_LOGSTREAM_SET_LOCUS, &mach->locus); 282 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &mach->locus);
289 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 283 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
290 MU_IOCTL_LOGSTREAM_SET_MODE, &mode); 284 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
291 } 285 }
...@@ -309,12 +303,6 @@ mu_i_sv_trace (mu_sieve_machine_t mach, const char *what) ...@@ -309,12 +303,6 @@ mu_i_sv_trace (mu_sieve_machine_t mach, const char *what)
309 return; 303 return;
310 304
311 mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_DEBUG); 305 mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_DEBUG);
312 if (mach->locus.mu_file)
313 mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
314 MU_LOGMODE_LOCUS,
315 (unsigned) strlen (mach->locus.mu_file),
316 mach->locus.mu_file,
317 mach->locus.mu_line);
318 mu_stream_printf (mach->errstream, "%zu: %s %s", mach->msgno, what, 306 mu_stream_printf (mach->errstream, "%zu: %s %s", mach->msgno, what,
319 mach->identifier); 307 mach->identifier);
320 for (i = 0; i < mach->argcount; i++) 308 for (i = 0; i < mach->argcount; i++)
...@@ -333,8 +321,6 @@ mu_sieve_log_action (mu_sieve_machine_t mach, const char *action, ...@@ -333,8 +321,6 @@ mu_sieve_log_action (mu_sieve_machine_t mach, const char *action,
333 if (!mach->logger) 321 if (!mach->logger)
334 return; 322 return;
335 323
336 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM,
337 MU_IOCTL_LOGSTREAM_SET_LOCUS, &mach->locus);
338 va_start (ap, fmt); 324 va_start (ap, fmt);
339 mach->logger (mach, action, fmt, ap); 325 mach->logger (mach, action, fmt, ap);
340 va_end (ap); 326 va_end (ap);
...@@ -479,13 +465,15 @@ mu_sieve_stream_save (mu_sieve_machine_t mach) ...@@ -479,13 +465,15 @@ mu_sieve_stream_save (mu_sieve_machine_t mach)
479 if (mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, 465 if (mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM,
480 MU_IOCTL_LOGSTREAM_GET_MODE, &mach->err_mode) == 0 466 MU_IOCTL_LOGSTREAM_GET_MODE, &mach->err_mode) == 0
481 && mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, 467 && mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM,
482 MU_IOCTL_LOGSTREAM_GET_LOCUS, &mach->err_locus) == 0) 468 MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE,
469 &mach->err_locus) == 0)
483 mach->state_flags |= MU_SV_SAVED_ERR_STATE; 470 mach->state_flags |= MU_SV_SAVED_ERR_STATE;
484 471
485 if (mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 472 if (mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
486 MU_IOCTL_LOGSTREAM_GET_MODE, &mach->dbg_mode) == 0 473 MU_IOCTL_LOGSTREAM_GET_MODE, &mach->dbg_mode) == 0
487 && mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 474 && mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
488 MU_IOCTL_LOGSTREAM_GET_LOCUS, &mach->dbg_locus) == 0) 475 MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE,
476 &mach->dbg_locus) == 0)
489 mach->state_flags |= MU_SV_SAVED_DBG_STATE; 477 mach->state_flags |= MU_SV_SAVED_DBG_STATE;
490 478
491 mach->state_flags |= MU_SV_SAVED_STATE; 479 mach->state_flags |= MU_SV_SAVED_STATE;
...@@ -502,7 +490,7 @@ mu_sieve_stream_restore (mu_sieve_machine_t mach) ...@@ -502,7 +490,7 @@ mu_sieve_stream_restore (mu_sieve_machine_t mach)
502 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, 490 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM,
503 MU_IOCTL_LOGSTREAM_SET_MODE, &mach->err_mode); 491 MU_IOCTL_LOGSTREAM_SET_MODE, &mach->err_mode);
504 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, 492 mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM,
505 MU_IOCTL_LOGSTREAM_SET_LOCUS, &mach->err_locus); 493 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &mach->err_locus);
506 } 494 }
507 495
508 if (mach->dbgstream != mach->errstream 496 if (mach->dbgstream != mach->errstream
...@@ -511,7 +499,7 @@ mu_sieve_stream_restore (mu_sieve_machine_t mach) ...@@ -511,7 +499,7 @@ mu_sieve_stream_restore (mu_sieve_machine_t mach)
511 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 499 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
512 MU_IOCTL_LOGSTREAM_SET_MODE, &mach->dbg_mode); 500 MU_IOCTL_LOGSTREAM_SET_MODE, &mach->dbg_mode);
513 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM, 501 mu_stream_ioctl (mach->dbgstream, MU_IOCTL_LOGSTREAM,
514 MU_IOCTL_LOGSTREAM_SET_LOCUS, &mach->dbg_locus); 502 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &mach->dbg_locus);
515 } 503 }
516 504
517 mach->state_flags = 0; 505 mach->state_flags = 0;
......
...@@ -226,7 +226,7 @@ set_tag_checker (mu_sieve_machine_t mach) ...@@ -226,7 +226,7 @@ set_tag_checker (mu_sieve_machine_t mach)
226 *mu_sieve_get_tag_n (mach, j + 1) = *t; 226 *mu_sieve_get_tag_n (mach, j + 1) = *t;
227 else if (prec == tmp_prec) 227 else if (prec == tmp_prec)
228 { 228 {
229 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, 229 mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
230 _("%s and %s can't be used together"), 230 _("%s and %s can't be used together"),
231 tmp.tag, t->tag); 231 tmp.tag, t->tag);
232 mu_i_sv_error (mach); 232 mu_i_sv_error (mach);
......
...@@ -49,7 +49,7 @@ mail_source (int argc, char **argv) ...@@ -49,7 +49,7 @@ mail_source (int argc, char **argv)
49 { 49 {
50 mu_stream_t input; 50 mu_stream_t input;
51 int save_term; 51 int save_term;
52 struct mu_locus locus; 52 struct mu_locus_range locus = MU_LOCUS_RANGE_INITIALIZER;
53 int rc; 53 int rc;
54 54
55 if (argc != 2) 55 if (argc != 2)
...@@ -69,15 +69,15 @@ mail_source (int argc, char **argv) ...@@ -69,15 +69,15 @@ mail_source (int argc, char **argv)
69 69
70 save_term = interactive; 70 save_term = interactive;
71 interactive = 0; 71 interactive = 0;
72 locus.mu_file = argv[1]; 72 locus.beg.mu_file = argv[1];
73 locus.mu_line = 0; 73 locus.beg.mu_line = 0;
74 locus.mu_col = 0; 74 locus.beg.mu_col = 0;
75 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 75 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
76 MU_IOCTL_LOGSTREAM_SET_LOCUS, &locus); 76 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &locus);
77 mail_mainloop (source_readline, input, 0); 77 mail_mainloop (source_readline, input, 0);
78 interactive = save_term; 78 interactive = save_term;
79 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 79 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
80 MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL); 80 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, NULL);
81 mu_stream_unref (input); 81 mu_stream_unref (input);
82 return 0; 82 return 0;
83 } 83 }
......
...@@ -260,15 +260,17 @@ input_getline (struct iobuf *inp) ...@@ -260,15 +260,17 @@ input_getline (struct iobuf *inp)
260 inp->length = mu_rtrim_class (inp->buffer, MU_CTYPE_ENDLN); 260 inp->length = mu_rtrim_class (inp->buffer, MU_CTYPE_ENDLN);
261 if (inp->buffer[0] == '#' && !is_dbm_directive (inp)) 261 if (inp->buffer[0] == '#' && !is_dbm_directive (inp))
262 { 262 {
263 struct mu_locus loc; 263 struct mu_locus_range loc;
264 mu_stream_ioctl (mu_strerr, 264 mu_stream_ioctl (mu_strerr,
265 MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_GET_LOCUS, 265 MU_IOCTL_LOGSTREAM,
266 MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE,
266 &loc); 267 &loc);
267 loc.mu_line = strtoul (inp->buffer + 1, NULL, 10); 268 loc.beg.mu_line = strtoul (inp->buffer + 1, NULL, 10);
268 mu_stream_ioctl (mu_strerr, 269 mu_stream_ioctl (mu_strerr,
269 MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_LOCUS, 270 MU_IOCTL_LOGSTREAM,
271 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE,
270 &loc); 272 &loc);
271 free (loc.mu_file); 273 mu_locus_range_deinit (&loc);
272 continue; 274 continue;
273 } 275 }
274 break; 276 break;
...@@ -1322,7 +1324,8 @@ add_records (int mode, int replace) ...@@ -1322,7 +1324,8 @@ add_records (int mode, int replace)
1322 const char *flt_argv[] = { "inline-comment", "#", "-S", "-i", "#", NULL }; 1324 const char *flt_argv[] = { "inline-comment", "#", "-S", "-i", "#", NULL };
1323 int rc; 1325 int rc;
1324 int save_log_mode = 0, log_mode; 1326 int save_log_mode = 0, log_mode;
1325 struct mu_locus save_locus = { NULL, }, locus; 1327 struct mu_locus_range save_locus = MU_LOCUS_RANGE_INITIALIZER,
1328 locus = MU_LOCUS_RANGE_INITIALIZER;
1326 struct mu_dbm_datum key, contents; 1329 struct mu_dbm_datum key, contents;
1327 struct iobuf input; 1330 struct iobuf input;
1328 struct mu_wordsplit ws; 1331 struct mu_wordsplit ws;
...@@ -1364,18 +1367,21 @@ add_records (int mode, int replace) ...@@ -1364,18 +1367,21 @@ add_records (int mode, int replace)
1364 1367
1365 /* Configure error stream to output input file location before each error 1368 /* Configure error stream to output input file location before each error
1366 message */ 1369 message */
1367 locus.mu_file = input_file ? input_file : "<stdin>"; 1370 locus.beg.mu_file = input_file ? input_file : "<stdin>";
1368 locus.mu_line = 0; 1371 locus.beg.mu_line = 0;
1369 locus.mu_col = 0; 1372 locus.beg.mu_col = 0;
1373 memset (&locus.end, 0, sizeof locus.end);
1370 1374
1371 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_GET_MODE, 1375 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_GET_MODE,
1372 &save_log_mode); 1376 &save_log_mode);
1373 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_GET_LOCUS, 1377 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1378 MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE,
1374 &save_locus); 1379 &save_locus);
1375 log_mode = save_log_mode | MU_LOGMODE_LOCUS; 1380 log_mode = save_log_mode | MU_LOGMODE_LOCUS;
1376 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_MODE, 1381 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_MODE,
1377 &log_mode); 1382 &log_mode);
1378 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_LOCUS, 1383 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1384 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE,
1379 &locus); 1385 &locus);
1380 1386
1381 /* Initialize I/O data */ 1387 /* Initialize I/O data */
...@@ -1443,7 +1449,8 @@ add_records (int mode, int replace) ...@@ -1443,7 +1449,8 @@ add_records (int mode, int replace)
1443 1449
1444 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_MODE, 1450 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_MODE,
1445 &save_log_mode); 1451 &save_log_mode);
1446 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_LOCUS, 1452 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
1453 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE,
1447 &save_locus); 1454 &save_locus);
1448 1455
1449 if (known_meta_data) 1456 if (known_meta_data)
......
...@@ -26,7 +26,7 @@ static char logger_args_doc[] = N_("[TEXT]"); ...@@ -26,7 +26,7 @@ static char logger_args_doc[] = N_("[TEXT]");
26 static char *input_file = NULL; 26 static char *input_file = NULL;
27 static int logger_type = MU_STRERR_STDERR; 27 static int logger_type = MU_STRERR_STDERR;
28 static int log_severity = MU_LOG_ERROR; 28 static int log_severity = MU_LOG_ERROR;
29 static struct mu_locus locus; 29 static struct mu_locus_range locus;
30 static int syslog_facility = LOG_USER; 30 static int syslog_facility = LOG_USER;
31 static int syslog_priority = LOG_ERR; 31 static int syslog_priority = LOG_ERR;
32 static char *syslog_tag = NULL; 32 static char *syslog_tag = NULL;
...@@ -83,32 +83,67 @@ set_severity (struct mu_parseopt *po, struct mu_option *opt, ...@@ -83,32 +83,67 @@ set_severity (struct mu_parseopt *po, struct mu_option *opt,
83 } 83 }
84 84
85 static void 85 static void
86 set_locus (struct mu_parseopt *po, struct mu_option *opt, 86 parse_locus_point (char **ptr, struct mu_locus_point *pt,
87 char const *arg) 87 struct mu_parseopt *po)
88 { 88 {
89 char *str = *ptr;
89 char *s; 90 char *s;
90 91
91 locus.mu_file = mu_strdup (arg); 92 s = strchr (str, ':');
92 s = strchr (arg, ':');
93 if (s) 93 if (s)
94 { 94 {
95 char *end;
95 *s++ = 0; 96 *s++ = 0;
96 locus.mu_line = strtoul (s, &s, 10); 97 if (*str)
97 if (*s == ':') 98 mu_locus_point_init (pt, str);
99 pt->mu_line = strtoul (s, &end, 10);
100 if (end == s)
98 { 101 {
99 locus.mu_col = strtoul (s + 1, &s, 10); 102 mu_parseopt_error (po, _("bad line number: %s"), s);
100 if (*s) 103 exit (po->po_exit_error);
104 }
105 s = end;
106 if (*s == '.' || *s == ':')
101 { 107 {
102 mu_parseopt_error (po, _("bad column number: %s"), arg); 108 s++;
109 pt->mu_col = strtoul (s, &end, 10);
110 if (end == s)
111 {
112 mu_parseopt_error (po, _("bad column number: %s"), s);
103 exit (po->po_exit_error); 113 exit (po->po_exit_error);
104 } 114 }
115 s = end;
116 }
105 } 117 }
106 else if (*s) 118 else
107 { 119 {
108 mu_parseopt_error (po, _("bad line number: %s"), arg); 120 mu_parseopt_error (po, _("missing line number after %s"), s);
109 exit (po->po_exit_error); 121 exit (po->po_exit_error);
110 } 122 }
123 *ptr = s;
124 }
125
126 static void
127 set_locus (struct mu_parseopt *po, struct mu_option *opt,
128 char const *arg)
129 {
130 char *s;
131 char *tmp;
132
133 tmp = mu_strdup (arg);
134 s = tmp;
135 parse_locus_point (&s, &locus.beg, po);
136 if (*s == '-')
137 {
138 mu_locus_point_init (&locus.end, locus.beg.mu_file);
139 locus.end.mu_line = locus.beg.mu_line;
140 locus.end.mu_col = locus.end.mu_col;
141 s++;
142 parse_locus_point (&s, &locus.end, po);
111 } 143 }
144
145 if (*s)
146 mu_parseopt_error (po, _("locus format error near %s"), s);
112 } 147 }
113 148
114 static struct mu_option logger_options[] = { 149 static struct mu_option logger_options[] = {
...@@ -127,7 +162,7 @@ static struct mu_option logger_options[] = { ...@@ -127,7 +162,7 @@ static struct mu_option logger_options[] = {
127 { "severity", 's', N_("SEV"), MU_OPTION_DEFAULT, 162 { "severity", 's', N_("SEV"), MU_OPTION_DEFAULT,
128 N_("log at Mailutils severity level SEV"), 163 N_("log at Mailutils severity level SEV"),
129 mu_c_string, NULL, set_severity }, 164 mu_c_string, NULL, set_severity },
130 { "locus", 'l', N_("FILE:LINE[:COL]"), MU_OPTION_DEFAULT, 165 { "locus", 'l', N_("FILE:LINE[.COL][-FILE:LINE[.COL]]"), MU_OPTION_DEFAULT,
131 N_("set locus for logging"), 166 N_("set locus for logging"),
132 mu_c_string, NULL, set_locus }, 167 mu_c_string, NULL, set_locus },
133 { "tag", 't', N_("TAG"), MU_OPTION_DEFAULT, 168 { "tag", 't', N_("TAG"), MU_OPTION_DEFAULT,
...@@ -166,9 +201,9 @@ main (int argc, char **argv) ...@@ -166,9 +201,9 @@ main (int argc, char **argv)
166 mode = MU_LOGMODE_SEVERITY | MU_LOGMODE_LOCUS; 201 mode = MU_LOGMODE_SEVERITY | MU_LOGMODE_LOCUS;
167 mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM, 202 mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM,
168 MU_IOCTL_LOGSTREAM_SET_MODE, &mode); 203 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
169 if (locus.mu_file) 204 if (locus.beg.mu_file)
170 mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM, 205 mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM,
171 MU_IOCTL_LOGSTREAM_SET_LOCUS, &locus); 206 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &locus);
172 mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM, 207 mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM,
173 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &log_severity); 208 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &log_severity);
174 209
......
...@@ -52,7 +52,7 @@ wicket_match (mu_stream_t stream, const char *str) ...@@ -52,7 +52,7 @@ wicket_match (mu_stream_t stream, const char *str)
52 { 52 {
53 int rc, ret; 53 int rc, ret;
54 mu_url_t u, url; 54 mu_url_t u, url;
55 struct mu_locus loc; 55 struct mu_locus_point loc;
56 int flags = MU_URL_PARSE_ALL; 56 int flags = MU_URL_PARSE_ALL;
57 57
58 if (wicket_verbose > 2) 58 if (wicket_verbose > 2)
......
...@@ -495,8 +495,13 @@ main (int argc, char *argv[]) ...@@ -495,8 +495,13 @@ main (int argc, char *argv[])
495 mu_sieve_set_logger (mach, _sieve_action_log); 495 mu_sieve_set_logger (mach, _sieve_action_log);
496 496
497 if (expression_option) 497 if (expression_option)
498 rc = mu_sieve_compile_buffer (mach, script, strlen (script), 498 {
499 "stdin", 1); 499 struct mu_locus_point pt;
500 pt.mu_file = "stdin";
501 pt.mu_line = 1;
502 pt.mu_col = 0;
503 rc = mu_sieve_compile_buffer (mach, script, strlen (script), &pt);
504 }
500 else 505 else
501 rc = mu_sieve_compile (mach, script); 506 rc = mu_sieve_compile (mach, script);
502 if (rc) 507 if (rc)
......
...@@ -38,7 +38,7 @@ if header :comparator "i;ascii-numeric" :contains "X-Number" "15" ...@@ -38,7 +38,7 @@ if header :comparator "i;ascii-numeric" :contains "X-Number" "15"
38 discard; 38 discard;
39 } 39 }
40 ],[78],[], 40 ],[78],[],
41 [sieve: prog:4.1: comparator `i;ascii-numeric' is incompatible with match type `contains' in call to `header' 41 [sieve: prog:4.4-65: comparator `i;ascii-numeric' is incompatible with match type `contains' in call to `header'
42 ]) 42 ])
43 AT_CLEANUP 43 AT_CLEANUP
44 44
......