Commit 4e7f5b5c 4e7f5b5c08095818d7876a86ad6657c57c9a8ad1 by Sergey Poznyakoff

Fix logstream to support mu_locus_range.

* include/mailutils/locus.h (mu_stream_print_locus_range)
(mu_stream_vlprintf, mu_stream_lprintf, mu_lrange_debug): New protos.
* include/mailutils/stream.h (MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE)
(MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE): New ioctls.
* include/mailutils/sys/logstream.h (_mu_log_stream): Replace
locus with struct mu_locus_range locrange.
* libmailutils/locus/debug.c: Rewrite.
* libmailutils/locus/ident.c (mu_ident_ref): Accept NULL argument.
Fix initialization.
(mu_ident_deref): Accept NULL argument.
* libmailutils/stream/logstream.c: Rewrite.
* libmailutils/tests/.gitignore: Update.
* libmailutils/tests/Makefile.am: Add new tests.
* libmailutils/tests/testsuite.at: Likewise.
* libmailutils/tests/logstr.at: New testcase.
* libmailutils/tests/logstr.c: New file.
* libmailutils/tests/xscript.at: Minor change.
* sieve/tests/i-numeric.at: Minor change.
1 parent 7bca245a
...@@ -106,7 +106,7 @@ int mu_debug_get_iterator (mu_iterator_t *piterator, int skipunset); ...@@ -106,7 +106,7 @@ int mu_debug_get_iterator (mu_iterator_t *piterator, int skipunset);
106 if (mu_debug_line_info) \ 106 if (mu_debug_line_info) \
107 { \ 107 { \
108 mu_debug_log_begin ("\033X<%d>%s:%d: ", \ 108 mu_debug_log_begin ("\033X<%d>%s:%d: ", \
109 MU_LOGMODE_LOCUS, __FILE__, __LINE__); \ 109 MU_LOGMODE_LOCUS, __FILE__, __LINE__); \
110 mu_debug_log_end s; \ 110 mu_debug_log_end s; \
111 } \ 111 } \
112 else \ 112 else \
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
2 #define _MAILUTILS_LOCUS_H 2 #define _MAILUTILS_LOCUS_H
3 3
4 #include <string.h> 4 #include <string.h>
5 #include <stdarg.h>
5 6
6 struct mu_locus_point 7 struct mu_locus_point
7 { 8 {
...@@ -49,6 +50,17 @@ void mu_locus_tracker_advance (struct mu_locus_track *trk, ...@@ -49,6 +50,17 @@ void mu_locus_tracker_advance (struct mu_locus_track *trk,
49 char const *text, size_t leng); 50 char const *text, size_t leng);
50 void mu_locus_tracker_retreat (struct mu_locus_track *trk, size_t n); 51 void mu_locus_tracker_retreat (struct mu_locus_track *trk, size_t n);
51 52
53 void mu_stream_print_locus_range (mu_stream_t stream,
54 struct mu_locus_range const *loc);
55
56 void mu_stream_vlprintf (mu_stream_t stream,
57 struct mu_locus_range const *loc,
58 char const *fmt, va_list ap);
59 void mu_stream_lprintf (mu_stream_t stream,
60 struct mu_locus_range const *loc,
61 char const *fmt, ...);
62 void mu_lrange_debug (struct mu_locus_range const *loc,
63 char const *fmt, ...);
52 64
53 65
54 #endif 66 #endif
......
...@@ -32,8 +32,8 @@ extern "C" { ...@@ -32,8 +32,8 @@ extern "C" {
32 #define MU_LOG_ALERT 6 32 #define MU_LOG_ALERT 6
33 #define MU_LOG_EMERG 7 33 #define MU_LOG_EMERG 7
34 34
35 #define MU_LOGMODE_SEVERITY 0x0001 35 #define MU_LOGMODE_SEVERITY 0x0001
36 #define MU_LOGMODE_LOCUS 0x0002 36 #define MU_LOGMODE_LOCUS 0x0002
37 37
38 int mu_log_stream_create (mu_stream_t *, mu_stream_t); 38 int mu_log_stream_create (mu_stream_t *, mu_stream_t);
39 int mu_syslog_stream_create (mu_stream_t *, int); 39 int mu_syslog_stream_create (mu_stream_t *, int);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +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/sieve.h> 40 #include <mailutils/sieve.h>
40 #include <mailutils/list.h> 41 #include <mailutils/list.h>
41 #include <mailutils/locker.h> 42 #include <mailutils/locker.h>
......
...@@ -83,7 +83,7 @@ enum mu_buffer_type ...@@ -83,7 +83,7 @@ enum mu_buffer_type
83 /* Opcodes common for various families */ 83 /* Opcodes common for various families */
84 #define MU_IOCTL_OP_GET 0 84 #define MU_IOCTL_OP_GET 0
85 #define MU_IOCTL_OP_SET 1 85 #define MU_IOCTL_OP_SET 1
86 86
87 /* Opcodes for MU_IOCTL_PROGSTREAM */ 87 /* Opcodes for MU_IOCTL_PROGSTREAM */
88 #define MU_IOCTL_PROG_STATUS 0 88 #define MU_IOCTL_PROG_STATUS 0
89 #define MU_IOCTL_PROG_PID 1 89 #define MU_IOCTL_PROG_PID 1
...@@ -158,6 +158,15 @@ enum mu_buffer_type ...@@ -158,6 +158,15 @@ enum mu_buffer_type
158 Arg: mu_stream_t* 158 Arg: mu_stream_t*
159 */ 159 */
160 #define MU_IOCTL_LOGSTREAM_CLONE 14 160 #define MU_IOCTL_LOGSTREAM_CLONE 14
161
162 /* Get locus range.
163 Arg: struct mu_locus_range *
164 */
165 #define MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE 15
166 /* Set locus range.
167 Arg: struct mu_locus_range *
168 */
169 #define MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE 16
161 170
162 /* Opcodes for MU_IOCTL_XSCRIPTSTREAM */ 171 /* Opcodes for MU_IOCTL_XSCRIPTSTREAM */
163 /* Swap transcript levels. 172 /* Swap transcript levels.
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
19 19
20 #include <mailutils/types.h> 20 #include <mailutils/types.h>
21 #include <mailutils/sys/stream.h> 21 #include <mailutils/sys/stream.h>
22 #include <mailutils/locus.h>
22 23
23 struct _mu_log_stream 24 struct _mu_log_stream
24 { 25 {
...@@ -30,7 +31,7 @@ struct _mu_log_stream ...@@ -30,7 +31,7 @@ struct _mu_log_stream
30 int logmode; /* Mode flags */ 31 int logmode; /* Mode flags */
31 int sevmask; /* Mask out the output of severity level for 32 int sevmask; /* Mask out the output of severity level for
32 these severities. */ 33 these severities. */
33 struct mu_locus locus; /* Location */ 34 struct mu_locus_range locrange; /* Location in the source file */
34 }; 35 };
35 36
36 void _mu_log_stream_setup (struct _mu_log_stream *sp, mu_stream_t transport); 37 void _mu_log_stream_setup (struct _mu_log_stream *sp, mu_stream_t transport);
......
...@@ -9,12 +9,78 @@ ...@@ -9,12 +9,78 @@
9 #include <mailutils/stdstream.h> 9 #include <mailutils/stdstream.h>
10 10
11 void 11 void
12 mu_stream_print_locus_range (mu_stream_t stream,
13 struct mu_locus_range const *loc)
14 {
15 if (loc->beg.mu_col == 0)
16 {
17 if (loc->end.mu_file
18 && (!mu_locus_point_same_file (&loc->beg, &loc->end)
19 || loc->beg.mu_line != loc->end.mu_line))
20 mu_stream_printf (stream, "%s:%u-%u",
21 loc->beg.mu_file,
22 loc->beg.mu_line,
23 loc->end.mu_line);
24 else
25 mu_stream_printf (stream, "%s:%u",
26 loc->beg.mu_file,
27 loc->beg.mu_line);
28 }
29 else
30 {
31 if (loc->end.mu_file
32 && !mu_locus_point_same_file (&loc->beg, &loc->end))
33 mu_stream_printf (stream, "%s:%u.%u-%s:%u.%u",
34 loc->beg.mu_file,
35 loc->beg.mu_line, loc->beg.mu_col,
36 loc->end.mu_file,
37 loc->end.mu_line, loc->end.mu_col);
38 else if (loc->end.mu_file && loc->beg.mu_line != loc->end.mu_line)
39 mu_stream_printf (stream, "%s:%u.%u-%u.%u",
40 loc->beg.mu_file,
41 loc->beg.mu_line, loc->beg.mu_col,
42 loc->end.mu_line, loc->end.mu_col);
43 else if (loc->end.mu_file && loc->beg.mu_col != loc->end.mu_col)
44 mu_stream_printf (stream, "%s:%u.%u-%u",
45 loc->beg.mu_file,
46 loc->beg.mu_line, loc->beg.mu_col,
47 loc->end.mu_col);
48 else
49 mu_stream_printf (stream, "%s:%u.%u",
50 loc->beg.mu_file,
51 loc->beg.mu_line, loc->beg.mu_col);
52 }
53 }
54
55 void
56 mu_stream_vlprintf (mu_stream_t stream,
57 struct mu_locus_range const *loc,
58 char const *fmt, va_list ap)
59 {
60 mu_stream_print_locus_range (stream, loc);
61 mu_stream_write (stream, ": ", 2, NULL);
62 mu_stream_vprintf (mu_strerr, fmt, ap);
63 mu_stream_write (stream, "\n", 1, NULL);
64 }
65
66 void
67 mu_stream_lprintf (mu_stream_t stream,
68 struct mu_locus_range const *loc,
69 char const *fmt, ...)
70 {
71 va_list ap;
72 va_start (ap, fmt);
73 mu_stream_vlprintf (stream, loc, fmt, ap);
74 va_end (ap);
75 }
76
77 void
12 mu_lrange_debug (struct mu_locus_range const *loc, 78 mu_lrange_debug (struct mu_locus_range const *loc,
13 char const *fmt, ...) 79 char const *fmt, ...)
14 { 80 {
15 va_list ap; 81 va_list ap;
16 int rc, mode; 82 int rc, mode;
17 83
18 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 84 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
19 MU_IOCTL_LOGSTREAM_GET_MODE, &mode); 85 MU_IOCTL_LOGSTREAM_GET_MODE, &mode);
20 if (rc == 0) 86 if (rc == 0)
...@@ -23,37 +89,13 @@ mu_lrange_debug (struct mu_locus_range const *loc, ...@@ -23,37 +89,13 @@ mu_lrange_debug (struct mu_locus_range const *loc,
23 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 89 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
24 MU_IOCTL_LOGSTREAM_SET_MODE, &new_mode); 90 MU_IOCTL_LOGSTREAM_SET_MODE, &new_mode);
25 } 91 }
26 92
27 if (loc->beg.mu_col == 0)
28 mu_debug_log_begin ("%s:%u", loc->beg.mu_file, loc->beg.mu_line);
29 else if (!mu_locus_point_same_file (&loc->beg, &loc->end))
30 mu_debug_log_begin ("%s:%u.%u-%s:%u.%u",
31 loc->beg.mu_file,
32 loc->beg.mu_line, loc->beg.mu_col,
33 loc->end.mu_file,
34 loc->end.mu_line, loc->end.mu_col);
35 else if (loc->beg.mu_line != loc->end.mu_line)
36 mu_debug_log_begin ("%s:%u.%u-%u.%u",
37 loc->beg.mu_file,
38 loc->beg.mu_line, loc->beg.mu_col,
39 loc->end.mu_line, loc->end.mu_col);
40 else if (loc->beg.mu_col != loc->end.mu_col)
41 mu_debug_log_begin ("%s:%u.%u-%u",
42 loc->beg.mu_file,
43 loc->beg.mu_line, loc->beg.mu_col,
44 loc->end.mu_col);
45 else
46 mu_debug_log_begin ("%s:%u.%u",
47 loc->beg.mu_file,
48 loc->beg.mu_line, loc->beg.mu_col);
49
50 mu_stream_write (mu_strerr, ": ", 2, NULL);
51
52 va_start (ap, fmt); 93 va_start (ap, fmt);
53 mu_stream_vprintf (mu_strerr, fmt, ap); 94 mu_stream_lprintf (mu_strerr, loc, fmt, ap);
54 va_end (ap); 95 va_end (ap);
55 mu_debug_log_nl (); 96
56 if (rc == 0) 97 if (rc == 0)
57 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, 98 mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
58 MU_IOCTL_LOGSTREAM_SET_MODE, &mode); 99 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
100
59 } 101 }
......
...@@ -20,10 +20,13 @@ mu_ident_ref (char const *name, char const **refname) ...@@ -20,10 +20,13 @@ mu_ident_ref (char const *name, char const **refname)
20 int rc; 20 int rc;
21 struct mu_ident_ref *ref, **refptr; 21 struct mu_ident_ref *ref, **refptr;
22 22
23 if (!name)
24 return EINVAL;
25 if (!refname) 23 if (!refname)
26 return MU_ERR_OUT_PTR_NULL; 24 return MU_ERR_OUT_PTR_NULL;
25 if (!name)
26 {
27 *refname = NULL;
28 return 0;
29 }
27 30
28 if (!nametab) 31 if (!nametab)
29 { 32 {
...@@ -46,6 +49,7 @@ mu_ident_ref (char const *name, char const **refname) ...@@ -46,6 +49,7 @@ mu_ident_ref (char const *name, char const **refname)
46 mu_assoc_remove (nametab, name); 49 mu_assoc_remove (nametab, name);
47 return rc; 50 return rc;
48 } 51 }
52 *refptr = ref;
49 ref->count = 0; 53 ref->count = 0;
50 break; 54 break;
51 55
...@@ -68,9 +72,7 @@ mu_ident_deref (char const *name) ...@@ -68,9 +72,7 @@ mu_ident_deref (char const *name)
68 struct mu_ident_ref *ref; 72 struct mu_ident_ref *ref;
69 int rc; 73 int rc;
70 74
71 if (!name) 75 if (!name || !nametab)
72 return EINVAL;
73 if (!nametab)
74 return 0; 76 return 0;
75 77
76 rc = mu_assoc_lookup (nametab, name, &ref); 78 rc = mu_assoc_lookup (nametab, name, &ref);
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
30 #include <mailutils/nls.h> 30 #include <mailutils/nls.h>
31 #include <mailutils/stream.h> 31 #include <mailutils/stream.h>
32 #include <mailutils/debug.h> 32 #include <mailutils/debug.h>
33 #include <mailutils/locus.h>
33 #include <mailutils/sys/logstream.h> 34 #include <mailutils/sys/logstream.h>
34 35
35 char *_mu_severity_str[] = { 36 char *_mu_severity_str[] = {
...@@ -69,25 +70,77 @@ mu_severity_to_string (unsigned n, const char **pstr) ...@@ -69,25 +70,77 @@ mu_severity_to_string (unsigned n, const char **pstr)
69 return 0; 70 return 0;
70 } 71 }
71 72
73 static void
74 lr_set_line (struct mu_locus_range *loc, unsigned val, int end)
75 {
76 if (end)
77 loc->end.mu_line = val;
78 else
79 loc->beg.mu_line = val;
80 }
81
82 static void
83 lr_set_col (struct mu_locus_range *loc, unsigned val, int end)
84 {
85 if (end)
86 loc->end.mu_col = val;
87 else
88 loc->beg.mu_col = val;
89 }
90
72 static int 91 static int
73 _locus_set_file (struct mu_locus *loc, const char *file, size_t len) 92 lr_set_file (struct mu_locus_range *loc, char const *fname, unsigned len,
93 int end)
74 { 94 {
75 free (loc->mu_file); 95 char const *refname;
76 if (file) 96 struct mu_locus_point *pt = end ? &loc->end : &loc->beg;
97 int rc;
98
99 if (fname == NULL)
77 { 100 {
78 loc->mu_file = malloc (len + 1); 101 refname = NULL;
79 if (!loc->mu_file) 102 rc = 0;
80 return ENOMEM;
81 memcpy (loc->mu_file, file, len);
82 loc->mu_file[len] = 0;
83 } 103 }
104 else if (len == 0)
105 rc = mu_ident_ref (fname, &refname);
84 else 106 else
85 loc->mu_file = NULL; 107 {
108 char *name;
109
110 name = malloc (len + 1);
111 if (!name)
112 return errno;
113 memcpy (name, fname, len);
114 name[len] = 0;
115 rc = mu_ident_ref (name, &refname);
116 free (name);
117 }
118 if (rc)
119 return rc;
120 mu_ident_deref (pt->mu_file);
121 pt->mu_file = refname;
86 return 0; 122 return 0;
87 } 123 }
88 124
89 #define _locus_set_line(loc, line) ((loc)->mu_line = line) 125 /* Field modification map (binary):
90 #define _locus_set_col(loc, col) ((loc)->mu_col = col) 126
127 FfLlCc
128
129 The bits f, l, and c (file, line, and column) are toggled cyclically.
130 The value 0 means locus beg, 1 meand locus end.
131 The bits F, L, and C are set once and indicate that the corresponding
132 bit was toggled at least once.
133 */
134 #define FMM_COL 0
135 #define FMM_LINE 1
136 #define FMM_FILE 2
137
138 #define FMM_SHIFT(n) ((n)<<1)
139 #define FMM_MASK(n) (0x3 << FMM_SHIFT (n))
140 #define FMM_VAL(m,n) (((m) >> FMM_SHIFT (n)) & 0x1)
141 #define FMM_SET(m,n,v) ((m) = ((m) & ~FMM_MASK (n)) | (((v) << FMM_SHIFT (n))|0x2))
142 #define FMM_CYCLE(m, n) \
143 FMM_SET ((m), (n), ((FMM_VAL ((m), (n)) + 1) % 2))
91 144
92 static int 145 static int
93 _log_write (struct _mu_stream *str, const char *buf, size_t size, 146 _log_write (struct _mu_stream *str, const char *buf, size_t size,
...@@ -96,8 +149,8 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, ...@@ -96,8 +149,8 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
96 struct _mu_log_stream *sp = (struct _mu_log_stream *)str; 149 struct _mu_log_stream *sp = (struct _mu_log_stream *)str;
97 unsigned severity = sp->severity; 150 unsigned severity = sp->severity;
98 int logmode = sp->logmode; 151 int logmode = sp->logmode;
99 struct mu_locus loc = sp->locus; 152 struct mu_locus_range loc;
100 const char *fname = NULL; 153 int fmm = 0;
101 unsigned flen = 0; 154 unsigned flen = 0;
102 int save_locus = 0; 155 int save_locus = 0;
103 int rc; 156 int rc;
...@@ -120,6 +173,10 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, ...@@ -120,6 +173,10 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
120 n = __x; \ 173 n = __x; \
121 } while (0) 174 } while (0)
122 175
176 loc = sp->locrange;
177 mu_ident_ref (loc.beg.mu_file, &loc.beg.mu_file);
178 mu_ident_ref (loc.end.mu_file, &loc.end.mu_file);
179
123 /* Tell them we've consumed everything */ 180 /* Tell them we've consumed everything */
124 *pnwrite = size; 181 *pnwrite = size;
125 182
...@@ -167,21 +224,24 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, ...@@ -167,21 +224,24 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
167 case 'l': 224 case 'l':
168 /* Input line (decimal) */ 225 /* Input line (decimal) */
169 READNUM (n); 226 READNUM (n);
170 _locus_set_line (&loc, n); 227 lr_set_line (&loc, n, FMM_VAL (fmm, FMM_LINE));
228 FMM_CYCLE (fmm, FMM_LINE);
171 logmode |= MU_LOGMODE_LOCUS; 229 logmode |= MU_LOGMODE_LOCUS;
172 break; 230 break;
173 231
174 case 'c': 232 case 'c':
175 /* Column in input line (decimal) */ 233 /* Column in input line (decimal) */
176 READNUM (n); 234 READNUM (n);
177 _locus_set_col (&loc, n); 235 lr_set_col (&loc, n, FMM_VAL (fmm, FMM_COL));
236 FMM_CYCLE (fmm, FMM_COL);
178 logmode |= MU_LOGMODE_LOCUS; 237 logmode |= MU_LOGMODE_LOCUS;
179 break; 238 break;
180 239
181 case 'f': 240 case 'f':
182 /* File name. Format: <N>S */ 241 /* File name. Format: <N>S */
183 READNUM (flen); 242 READNUM (flen);
184 fname = buf; 243 lr_set_file (&loc, buf, flen, FMM_VAL (fmm, FMM_FILE));
244 FMM_CYCLE (fmm, FMM_FILE);
185 buf += flen; 245 buf += flen;
186 size -= flen; 246 size -= flen;
187 logmode |= MU_LOGMODE_LOCUS; 247 logmode |= MU_LOGMODE_LOCUS;
...@@ -197,58 +257,41 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, ...@@ -197,58 +257,41 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
197 if (severity >= _mu_severity_num) 257 if (severity >= _mu_severity_num)
198 severity = MU_LOG_EMERG; 258 severity = MU_LOG_EMERG;
199 259
200 if (fname)
201 {
202 loc.mu_file = NULL;
203 _locus_set_file (&loc, fname, flen);
204 }
205
206 if (save_locus) 260 if (save_locus)
207 { 261 {
208 _locus_set_file (&sp->locus, loc.mu_file, strlen (loc.mu_file)); 262 sp->locrange = loc;
209 _locus_set_line (&sp->locus, loc.mu_line); 263 mu_ident_ref (sp->locrange.beg.mu_file, &sp->locrange.beg.mu_file);
210 _locus_set_col (&sp->locus, loc.mu_col); 264 mu_ident_ref (sp->locrange.end.mu_file, &sp->locrange.end.mu_file);
211 } 265 }
212 266
213 if (severity < sp->threshold) 267 if (severity < sp->threshold)
268 rc = 0;
269 else
214 { 270 {
215 if (fname) 271 mu_stream_ioctl (sp->transport, MU_IOCTL_LOGSTREAM,
216 free (loc.mu_file); 272 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
217 return 0;
218 }
219
220 mu_stream_ioctl (sp->transport, MU_IOCTL_LOGSTREAM,
221 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
222 273
223 if (logmode & MU_LOGMODE_LOCUS) 274 if ((logmode & MU_LOGMODE_LOCUS) && loc.beg.mu_file)
224 { 275 {
225 if (loc.mu_file) 276 mu_stream_print_locus_range (sp->transport, &loc);
277 mu_stream_write (sp->transport, ": ", 2, NULL);
278 }
279
280 if ((logmode & MU_LOGMODE_SEVERITY) &&
281 !(sp->sevmask & MU_DEBUG_LEVEL_MASK (severity)))
226 { 282 {
227 mu_stream_write (sp->transport, loc.mu_file, 283 char *s = gettext (_mu_severity_str[severity]);
228 strlen (loc.mu_file), NULL); 284 rc = mu_stream_write (sp->transport, s, strlen (s), NULL);
229 mu_stream_write (sp->transport, ":", 1, NULL); 285 if (rc)
230 if (loc.mu_line) 286 return rc;
231 mu_stream_printf (sp->transport, "%u", loc.mu_line); 287 mu_stream_write (sp->transport, ": ", 2, NULL);
232 mu_stream_write (sp->transport, ":", 1, NULL);
233 if (loc.mu_col)
234 mu_stream_printf (sp->transport, "%u:", loc.mu_col);
235 mu_stream_write (sp->transport, " ", 1, NULL);
236 } 288 }
289 rc = mu_stream_write (sp->transport, buf, size, NULL);
237 } 290 }
238
239 if (fname)
240 free (loc.mu_file);
241 291
242 if ((logmode & MU_LOGMODE_SEVERITY) && 292 mu_ident_deref (loc.beg.mu_file);
243 !(sp->sevmask & MU_DEBUG_LEVEL_MASK(severity))) 293 mu_ident_deref (loc.end.mu_file);
244 { 294 return rc;
245 char *s = gettext (_mu_severity_str[severity]);
246 rc = mu_stream_write (sp->transport, s, strlen (s), NULL);
247 if (rc)
248 return rc;
249 mu_stream_write (sp->transport, ": ", 2, NULL);
250 }
251 return mu_stream_write (sp->transport, buf, size, NULL);
252 } 295 }
253 296
254 static int 297 static int
...@@ -375,72 +418,133 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg) ...@@ -375,72 +418,133 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg)
375 sp->logmode = *(int*)arg; 418 sp->logmode = *(int*)arg;
376 break; 419 break;
377 420
421 case MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE:
422 {
423 struct mu_locus_range *lr = arg;
424 if (!arg)
425 {
426 mu_ident_deref (sp->locrange.beg.mu_file);
427 mu_ident_deref (sp->locrange.end.mu_file);
428 memset (&sp->locrange, 0, sizeof sp->locrange);
429 }
430 else
431 {
432 char const *begname, *endname;
433
434 status = mu_ident_ref (lr->beg.mu_file, &begname);
435 if (status)
436 return status;
437 status = mu_ident_ref (lr->end.mu_file, &endname);
438 if (status)
439 {
440 mu_ident_deref (begname);
441 return status;
442 }
443 mu_ident_deref (sp->locrange.beg.mu_file);
444 sp->locrange.beg.mu_file = begname;
445 sp->locrange.beg.mu_line = lr->beg.mu_line;
446 sp->locrange.beg.mu_col = lr->beg.mu_col;
447
448 mu_ident_deref (sp->locrange.end.mu_file);
449 sp->locrange.end.mu_file = endname;
450 sp->locrange.end.mu_line = lr->end.mu_line;
451 sp->locrange.end.mu_col = lr->end.mu_col;
452 }
453 }
454 break;
455
456 case MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE:
457 if (!arg)
458 return EINVAL;
459 else
460 {
461 struct mu_locus_range *lr = arg;
462 char const *begname, *endname;
463
464 status = mu_ident_ref (sp->locrange.beg.mu_file, &begname);
465 if (status)
466 return status;
467 status = mu_ident_ref (sp->locrange.end.mu_file, &endname);
468 if (status)
469 {
470 mu_ident_deref (begname);
471 return status;
472 }
473 lr->beg.mu_file = begname;
474 lr->beg.mu_line = sp->locrange.beg.mu_line;
475 lr->beg.mu_col = sp->locrange.beg.mu_col;
476 lr->end.mu_file = endname;
477 lr->end.mu_line = sp->locrange.end.mu_line;
478 lr->end.mu_col = sp->locrange.end.mu_col;
479 }
480 break;
481
378 case MU_IOCTL_LOGSTREAM_GET_LOCUS: 482 case MU_IOCTL_LOGSTREAM_GET_LOCUS:
379 if (!arg) 483 if (!arg)
380 return EINVAL; 484 return EINVAL;
381 else 485 else
382 { 486 {
383 struct mu_locus *ploc = arg; 487 struct mu_locus *ploc = arg;
384 if (sp->locus.mu_file) 488 if (sp->locrange.beg.mu_file)
385 { 489 {
386 ploc->mu_file = strdup (sp->locus.mu_file); 490 ploc->mu_file = strdup (sp->locrange.beg.mu_file);
387 if (!ploc->mu_file) 491 if (!ploc->mu_file)
388 return ENOMEM; 492 return ENOMEM;
389 } 493 }
390 else 494 else
391 ploc->mu_file = NULL; 495 ploc->mu_file = NULL;
392 ploc->mu_line = sp->locus.mu_line; 496 ploc->mu_line = sp->locrange.beg.mu_line;
393 ploc->mu_col = sp->locus.mu_col; 497 ploc->mu_col = sp->locrange.beg.mu_col;
394 } 498 }
395 break; 499 break;
396 500
397 case MU_IOCTL_LOGSTREAM_SET_LOCUS: 501 case MU_IOCTL_LOGSTREAM_SET_LOCUS:
398 { 502 {
399 struct mu_locus *ploc = arg; 503 struct mu_locus *ploc = arg;
400 if (!arg) 504
505 mu_ident_deref (sp->locrange.end.mu_file);
506 sp->locrange.end.mu_file = NULL;
507 if (arg)
401 { 508 {
402 free (sp->locus.mu_file); 509 status = lr_set_file (&sp->locrange, ploc->mu_file, 0, 0);
403 sp->locus.mu_file = NULL; 510 if (status)
404 sp->locus.mu_line = 0; 511 return status;
405 sp->locus.mu_col = 0; 512 lr_set_line (&sp->locrange, ploc->mu_line, 0);
513 lr_set_col (&sp->locrange, ploc->mu_col, 0);
406 } 514 }
407 else 515 else
408 { 516 {
409 if (ploc->mu_file) 517 mu_ident_deref (sp->locrange.beg.mu_file);
410 _locus_set_file (&sp->locus, ploc->mu_file, 518 sp->locrange.beg.mu_file = NULL;
411 strlen (ploc->mu_file));
412 if (ploc->mu_line)
413 _locus_set_line (&sp->locus, ploc->mu_line);
414 if (ploc->mu_col)
415 _locus_set_col (&sp->locus, ploc->mu_col);
416 } 519 }
520
417 break; 521 break;
418 } 522 }
419 523
420 case MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE: 524 case MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE:
421 if (!arg) 525 if (!arg)
422 return EINVAL; 526 return EINVAL;
423 sp->locus.mu_line = *(unsigned*)arg; 527 sp->locrange.beg.mu_line = *(unsigned*)arg;
424 break; 528 break;
425 529
426 case MU_IOCTL_LOGSTREAM_SET_LOCUS_COL: 530 case MU_IOCTL_LOGSTREAM_SET_LOCUS_COL:
427 if (!arg) 531 if (!arg)
428 return EINVAL; 532 return EINVAL;
429 sp->locus.mu_col = *(unsigned*)arg; 533 sp->locrange.beg.mu_col = *(unsigned*)arg;
430 break; 534 break;
431 535
432 case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE: 536 case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE:
433 if (!arg) 537 if (!arg)
434 sp->locus.mu_line++; 538 sp->locrange.beg.mu_line++;
435 else 539 else
436 sp->locus.mu_line += *(int*)arg; 540 sp->locrange.beg.mu_line += *(int*)arg;
437 break; 541 break;
438 542
439 case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL: 543 case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL:
440 if (!arg) 544 if (!arg)
441 sp->locus.mu_col++; 545 sp->locrange.beg.mu_col++;
442 else 546 else
443 sp->locus.mu_col += *(int*)arg; 547 sp->locrange.beg.mu_col += *(int*)arg;
444 break; 548 break;
445 549
446 case MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY: 550 case MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY:
...@@ -484,14 +588,12 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg) ...@@ -484,14 +588,12 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg)
484 newp->threshold = sp->threshold; 588 newp->threshold = sp->threshold;
485 newp->logmode = sp->logmode; 589 newp->logmode = sp->logmode;
486 newp->sevmask = sp->sevmask; 590 newp->sevmask = sp->sevmask;
487 if (sp->locus.mu_file) 591 newp->locrange = sp->locrange;
488 { 592 mu_ident_ref (sp->locrange.beg.mu_file,
489 newp->locus.mu_file = strdup (sp->locus.mu_file); 593 &sp->locrange.beg.mu_file);
490 if (!newp->locus.mu_file) 594 mu_ident_ref (sp->locrange.end.mu_file,
491 return ENOMEM; 595 &sp->locrange.end.mu_file);
492 } 596
493 newp->locus.mu_line = sp->locus.mu_line;
494 newp->locus.mu_col = sp->locus.mu_col;
495 *(mu_stream_t*) arg = str; 597 *(mu_stream_t*) arg = str;
496 } 598 }
497 break; 599 break;
......
...@@ -19,6 +19,7 @@ fsfolder ...@@ -19,6 +19,7 @@ fsfolder
19 globtest 19 globtest
20 imapio 20 imapio
21 listop 21 listop
22 logstr
22 mailcap 23 mailcap
23 mimehdr 24 mimehdr
24 modmesg 25 modmesg
......
...@@ -54,6 +54,7 @@ noinst_PROGRAMS = \ ...@@ -54,6 +54,7 @@ noinst_PROGRAMS = \
54 globtest\ 54 globtest\
55 imapio\ 55 imapio\
56 listop\ 56 listop\
57 logstr\
57 mailcap\ 58 mailcap\
58 mimehdr\ 59 mimehdr\
59 modtofsaf\ 60 modtofsaf\
...@@ -106,6 +107,7 @@ TESTSUITE_AT = \ ...@@ -106,6 +107,7 @@ TESTSUITE_AT = \
106 inline-comment.at\ 107 inline-comment.at\
107 linecon.at\ 108 linecon.at\
108 list.at\ 109 list.at\
110 logstr.at\
109 mailcap.at\ 111 mailcap.at\
110 mimehdr.at\ 112 mimehdr.at\
111 modmesg00.at\ 113 modmesg00.at\
......
1 # This file is part of GNU Mailutils. -*- Autotest -*-
2 # Copyright (C) 2017 Free Software Foundation, Inc.
3 #
4 # GNU Mailutils is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3, or (at
7 # your option) any later version.
8 #
9 # GNU Mailutils is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16
17 AT_SETUP(Logger stream)
18 AT_KEYWORDS([logstream])
19 AT_CHECK([logstr],
20 [0],
21 [00. simple print
22 hello world
23 01. severity
24 info: one
25 emerg: two
26 mode was: 0x0001
27 02. suppress severity
28 info: this message is seen
29 emerg: and this one as well
30 03. suppress severity name
31 info: this message is seen
32 emerg: and this one as well
33 04. severity mask
34 one
35 two
36 emerg: three
37 05. set/get locus point
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
42 07. locus: file, line, col
43 input:1.1-10: file, line, col
44 08. locus: file, line-range
45 input:1-2: file, line-range
46 09. locus: file, line-range, col
47 input:1.1-2.10: file, line-range, col
48 10. locus: file-range, line-range, col-range
49 input:1.1-next:2.10: file-range, line-range, col-range
50 11. set locus line
51 input:1.1-next:2.10: initial
52 input:8.1-next:2.10: locus line changed
53 12. advance locus line
54 input:1.1-next:5.10: initial
55 input:3.1-next:5.10: locus line advanced
56 13. set locus column
57 input:1.1-next:2.10: initial
58 input:1.8-next:2.10: locus column changed
59 14. advance locus column
60 input:1.1-next:5.10: initial
61 input:1.5-next:5.10: locus line advanced
62 15. fmt: severity
63 info: severity
64 16. fmt: locus (file, line)
65 a:10: one
66 17. fmt: locus (file, line, column)
67 a:10.5: one
68 18. fmt: locus (range)
69 a:10.5-b:14.8: one
70 19. fmt: locus; restore defaults
71 a:10.5-b:14.8: one
72 default
73 20. fmt: locus; restore defaults, display locus
74 a:10.5-b:14.8: one
75 input:1.1-next:5.10: default
76 21. fmt: set locus
77 a:10.5-b:14.8: one
78 a:10.5-b:14.8: default
79 ])
80 AT_CLEANUP
...\ No newline at end of file ...\ No newline at end of file
1 /* This file is part of GNU Mailutils test suite
2 Copyright (C) 2017 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <mailutils/mailutils.h>
18 #include <mailutils/locus.h>
19
20 /* Check normal operation.
21 Expected output: hello world
22 */
23 static void
24 simple_print (mu_stream_t str)
25 {
26 mu_stream_printf (str, "hello world\n");
27 }
28
29 /* Check severity control.
30 Expected output:
31 info: one
32 emerg: two
33 mode was: 0x0001
34 */
35 static void
36 check_severity (mu_stream_t str)
37 {
38 unsigned severity = MU_DIAG_INFO;
39 int mode = MU_LOGMODE_SEVERITY, old_mode;
40
41 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
42 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
43
44 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
45 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
46 mu_stream_printf (str, "one\n");
47
48 severity = MU_DIAG_EMERG;
49 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
50 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
51 mu_stream_printf (str, "two\n");
52
53 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
54 MU_IOCTL_LOGSTREAM_GET_MODE, &old_mode);
55
56 mode = 0;
57 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
58 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
59 mu_stream_printf (str, "mode was: 0x%04X\n", old_mode);
60 }
61
62 /* Check severity suppression mechanism.
63 Expected output:
64 info: this message is seen
65 emerg: and this one as well
66 */
67 static void
68 check_suppress (mu_stream_t str)
69 {
70 unsigned severity;
71 int mode = MU_LOGMODE_SEVERITY;
72
73 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
74 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
75
76 severity = MU_DIAG_INFO;
77 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
78 MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY,
79 &severity);
80
81 severity = MU_DIAG_DEBUG;
82 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
83 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
84
85 mu_stream_printf (str, "this message is not seen\n");
86
87 severity = MU_DIAG_INFO;
88 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
89 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
90 mu_stream_printf (str, "this message is seen\n");
91
92 severity = MU_DIAG_EMERG;
93 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
94 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
95 mu_stream_printf (str, "and this one as well\n");
96 }
97
98 /* Check suppression by severity name.
99 Expected output:
100 info: this message is seen
101 emerg: and this one as well
102 */
103 static void
104 check_suppress_name (mu_stream_t str)
105 {
106 int mode = MU_LOGMODE_SEVERITY, severity;
107
108 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
109 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
110
111 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
112 MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY_NAME,
113 "info");
114
115 severity = MU_DIAG_DEBUG;
116 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
117 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
118
119 mu_stream_printf (str, "this message is not seen\n");
120
121 severity = MU_DIAG_INFO;
122 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
123 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
124 mu_stream_printf (str, "this message is seen\n");
125
126 severity = MU_DIAG_EMERG;
127 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
128 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
129 mu_stream_printf (str, "and this one as well\n");
130 }
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
178 comp_range (mu_stream_t str, struct mu_locus_range *lr1,
179 char const *file, int line)
180 {
181 struct mu_locus_range lr2;
182
183 MU_ASSERT (mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
184 MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE, &lr2));
185 if (strcmp (lr1->beg.mu_file, lr2.beg.mu_file))
186 mu_error ("%s:%d: beg.mu_file differs", file, line);
187 if (lr1->beg.mu_line != lr2.beg.mu_line)
188 mu_error ("%s:%d: beg.mu_line differs", file, line);
189 if (lr1->beg.mu_col != lr2.beg.mu_col)
190 mu_error ("%s:%d: beg.mu_col differs", file, line);
191 mu_ident_deref (lr2.beg.mu_file);
192
193 if (strcmp (lr1->end.mu_file, lr2.end.mu_file))
194 mu_error ("%s:%d: end.mu_file differs", __FILE__, __LINE__);
195 if (lr1->end.mu_line != lr2.end.mu_line)
196 mu_error ("%s:%d: end.mu_line differs", __FILE__, __LINE__);
197 if (lr1->end.mu_col != lr2.end.mu_col)
198 mu_error ("%s:%d: end.mu_col differs", __FILE__, __LINE__);
199
200 mu_ident_deref (lr2.end.mu_file);
201 }
202
203 /* Check MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE.
204 Passed: file, line.
205 Expected output:
206 input:1: file, line
207 */
208 static void
209 lr_file_line (mu_stream_t str)
210 {
211 int mode = MU_LOGMODE_LOCUS;
212 struct mu_locus_range lr;
213
214 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
215 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
216
217 lr.beg.mu_file = "input";
218 lr.beg.mu_line = 1;
219 lr.beg.mu_col = 0;
220
221 lr.end.mu_file = "input";
222 lr.end.mu_line = 1;
223 lr.end.mu_col = 0;
224
225 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
226 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
227
228 mu_stream_printf (str, "file, line\n");
229
230 comp_range (str, &lr, __FILE__, __LINE__);
231 }
232
233 /* Check MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE.
234 Passed: file, line, col.
235 Expected output:
236 input:1.1-10: file, line, col
237 */
238 static void
239 lr_file_line_col (mu_stream_t str)
240 {
241 int mode = MU_LOGMODE_LOCUS;
242 struct mu_locus_range lr;
243
244 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
245 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
246
247 lr.beg.mu_file = "input";
248 lr.beg.mu_line = 1;
249 lr.beg.mu_col = 1;
250
251 lr.end.mu_file = "input";
252 lr.end.mu_line = 1;
253 lr.end.mu_col = 10;
254
255 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
256 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
257
258 mu_stream_printf (str, "file, line, col\n");
259
260 comp_range (str, &lr, __FILE__, __LINE__);
261 }
262
263 /* Check MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE.
264 Passed: file, line-range
265 Expected output:
266 input:1-2: file, line-range
267 */
268 static void
269 lr_file_line2 (mu_stream_t str)
270 {
271 int mode = MU_LOGMODE_LOCUS;
272 struct mu_locus_range lr;
273
274 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
275 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
276
277 lr.beg.mu_file = "input";
278 lr.beg.mu_line = 1;
279 lr.beg.mu_col = 0;
280
281 lr.end.mu_file = "input";
282 lr.end.mu_line = 2;
283 lr.end.mu_col = 0;
284
285 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
286 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
287
288 mu_stream_printf (str, "file, line-range\n");
289
290 comp_range (str, &lr, __FILE__, __LINE__);
291 }
292
293 /* Check MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE.
294 Passed: file, line-range, column
295 Expected output:
296 input:1.1-2.10: file, line-range, col
297 */
298 static void
299 lr_file_line2_col (mu_stream_t str)
300 {
301 int mode = MU_LOGMODE_LOCUS;
302 struct mu_locus_range lr;
303
304 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
305 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
306
307 lr.beg.mu_file = "input";
308 lr.beg.mu_line = 1;
309 lr.beg.mu_col = 1;
310
311 lr.end.mu_file = "input";
312 lr.end.mu_line = 2;
313 lr.end.mu_col = 10;
314
315 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
316 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
317
318 mu_stream_printf (str, "file, line-range, col\n");
319
320 comp_range (str, &lr, __FILE__, __LINE__);
321 }
322
323 /* Check MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE.
324 Passed: file-range, line-range, column-range
325 Expected output:
326 input:1.1-next:2.10: file-range, line-range, col-range
327 */
328 static void
329 lr_file2_line_col (mu_stream_t str)
330 {
331 int mode = MU_LOGMODE_LOCUS;
332 struct mu_locus_range lr;
333
334 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
335 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
336
337 lr.beg.mu_file = "input";
338 lr.beg.mu_line = 1;
339 lr.beg.mu_col = 1;
340
341 lr.end.mu_file = "next";
342 lr.end.mu_line = 2;
343 lr.end.mu_col = 10;
344
345 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
346 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
347
348 mu_stream_printf (str, "file-range, line-range, col-range\n");
349
350 comp_range (str, &lr, __FILE__, __LINE__);
351 }
352
353 /* Check MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE.
354 Expected output:
355 input:1.1-next:2.10: initial
356 input:8.1-next:2.10: locus line changed
357 */
358 static void
359 set_locus_line (mu_stream_t str)
360 {
361 int mode = MU_LOGMODE_LOCUS;
362 struct mu_locus_range lr;
363 unsigned line;
364
365 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
366 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
367
368 lr.beg.mu_file = "input";
369 lr.beg.mu_line = 1;
370 lr.beg.mu_col = 1;
371
372 lr.end.mu_file = "next";
373 lr.end.mu_line = 2;
374 lr.end.mu_col = 10;
375
376 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
377 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
378 mu_stream_printf (str, "initial\n");
379 line = 8;
380 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
381 MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE, &line);
382 mu_stream_printf (str, "locus line changed\n");
383 lr.beg.mu_line = line;
384 comp_range (str, &lr, __FILE__, __LINE__);
385 }
386
387 /* Check MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE.
388 Expected output:
389 input:1.1-next:5.10: initial
390 input:3.1-next:5.10: locus line advanced
391 */
392 static void
393 advance_locus_line (mu_stream_t str)
394 {
395 int mode = MU_LOGMODE_LOCUS;
396 struct mu_locus_range lr;
397 unsigned line;
398
399 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
400 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
401
402 lr.beg.mu_file = "input";
403 lr.beg.mu_line = 1;
404 lr.beg.mu_col = 1;
405
406 lr.end.mu_file = "next";
407 lr.end.mu_line = 5;
408 lr.end.mu_col = 10;
409
410 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
411 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
412 mu_stream_printf (str, "initial\n");
413 line = 2;
414 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
415 MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE, &line);
416 mu_stream_printf (str, "locus line advanced\n");
417
418 lr.beg.mu_line += line;
419 comp_range (str, &lr, __FILE__, __LINE__);
420 }
421
422 /* Check MU_IOCTL_LOGSTREAM_SET_LOCUS_COL.
423 Expected output:
424 input:1.1-next:2.10: initial
425 input:1.8-next:2.10: locus column changed
426 */
427 static void
428 set_locus_col (mu_stream_t str)
429 {
430 int mode = MU_LOGMODE_LOCUS;
431 struct mu_locus_range lr;
432 unsigned col;
433
434 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
435 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
436
437 lr.beg.mu_file = "input";
438 lr.beg.mu_line = 1;
439 lr.beg.mu_col = 1;
440
441 lr.end.mu_file = "next";
442 lr.end.mu_line = 2;
443 lr.end.mu_col = 10;
444
445 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
446 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
447 mu_stream_printf (str, "initial\n");
448 col = 8;
449 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
450 MU_IOCTL_LOGSTREAM_SET_LOCUS_COL, &col);
451 mu_stream_printf (str, "locus column changed\n");
452 lr.beg.mu_col = col;
453 comp_range (str, &lr, __FILE__, __LINE__);
454 }
455
456 /* Check MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL.
457 Expected output:
458 input:1.1-next:5.10: initial
459 input:1.5-next:5.10: locus line advanced
460 */
461 static void
462 advance_locus_col (mu_stream_t str)
463 {
464 int mode = MU_LOGMODE_LOCUS;
465 struct mu_locus_range lr;
466 unsigned col;
467
468 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
469 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
470
471 lr.beg.mu_file = "input";
472 lr.beg.mu_line = 1;
473 lr.beg.mu_col = 1;
474
475 lr.end.mu_file = "next";
476 lr.end.mu_line = 5;
477 lr.end.mu_col = 10;
478
479 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
480 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
481 mu_stream_printf (str, "initial\n");
482 col = 4;
483 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
484 MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL, &col);
485 mu_stream_printf (str, "locus line advanced\n");
486
487 lr.beg.mu_col += col;
488 comp_range (str, &lr, __FILE__, __LINE__);
489 }
490
491 /* Check severity mask.
492 Expected output:
493 one
494 two
495 emerg: two
496 */
497 static void
498 check_severity_mask (mu_stream_t str)
499 {
500 unsigned severity;
501 int mode = MU_LOGMODE_SEVERITY, mask;
502
503 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
504 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
505
506 mask = MU_DEBUG_LEVEL_UPTO (MU_DIAG_NOTICE);
507 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
508 MU_IOCTL_LOGSTREAM_SET_SEVERITY_MASK, &mask);
509
510 severity = MU_DIAG_INFO;
511 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
512 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
513 mu_stream_printf (str, "one\n");
514
515 severity = MU_DIAG_NOTICE;
516 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
517 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
518 mu_stream_printf (str, "two\n");
519
520 severity = MU_DIAG_EMERG;
521 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
522 MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
523 mu_stream_printf (str, "three\n");
524 }
525
526 /* Check ESC-s & ESC-O format specifiers.
527 Expected output:
528 info: severity
529 */
530 static void
531 fmt_severity (mu_stream_t str)
532 {
533 mu_stream_printf (str, "\033s<%d>\033O<%d>severity\n",
534 MU_DIAG_INFO, MU_LOGMODE_SEVERITY);
535 }
536
537 /* Check ESC-f and ESC-l format specifiers.
538 Expected output:
539 a:10: one
540 */
541 static void
542 fmt_locus1 (mu_stream_t str)
543 {
544 char *file = "a";
545 mu_stream_printf (str, "\033f<%d>%s\033l<%d>one\n",
546 strlen (file), file, 10);
547 }
548
549 /* Check ESC-f, ESC-l, and ESC-c format specifiers.
550 Expected output:
551 a:10.5: one
552 */
553 static void
554 fmt_locus2 (mu_stream_t str)
555 {
556 char *file = "a";
557 mu_stream_printf (str, "\033f<%d>%s\033l<%d>\033c<%d>one\n",
558 strlen (file), file, 10, 5);
559 }
560
561 /* Check setting range with ESC-f, ESC-l, and ESC-c format specifiers.
562 Expected output:
563 a:10.5-b:14.8: one
564 */
565 static void
566 fmt_locus3 (mu_stream_t str)
567 {
568 char *file[] = { "a", "b" };
569 mu_stream_printf (str, "\033f<%d>%s\033l<%d>\033c<%d>"
570 "\033f<%d>%s\033l<%d>\033c<%d>one\n",
571 strlen (file[0]), file[0], 10, 5,
572 strlen (file[1]), file[1], 14, 8);
573 }
574
575 /* Check that ESC-f, ESC-l, and ESC-c format specifiers don't clobber
576 default stream settings.
577 Expected output:
578 a:10.5-b:14.8: one
579 default
580 */
581 static void
582 fmt_locus4 (mu_stream_t str)
583 {
584 char *file[] = { "a", "b" };
585 struct mu_locus_range lr;
586
587 lr.beg.mu_file = "input";
588 lr.beg.mu_line = 1;
589 lr.beg.mu_col = 1;
590
591 lr.end.mu_file = "next";
592 lr.end.mu_line = 5;
593 lr.end.mu_col = 10;
594
595 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
596 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
597
598 mu_stream_printf (str, "\033f<%d>%s\033l<%d>\033c<%d>"
599 "\033f<%d>%s\033l<%d>\033c<%d>one\n",
600 strlen (file[0]), file[0], 10, 5,
601 strlen (file[1]), file[1], 14, 8);
602 mu_stream_printf (str, "default\n");
603 }
604
605 /* Check that ESC-f, ESC-l, and ESC-c format specifiers don't clobber
606 default stream settings and locus.
607 Expected output:
608 a:10.5-b:14.8: one
609 input:1.1-next:5.10: default
610 */
611 static void
612 fmt_locus5 (mu_stream_t str)
613 {
614 char *file[] = { "a", "b" };
615 struct mu_locus_range lr;
616 int mode;
617
618 lr.beg.mu_file = "input";
619 lr.beg.mu_line = 1;
620 lr.beg.mu_col = 1;
621
622 lr.end.mu_file = "next";
623 lr.end.mu_line = 5;
624 lr.end.mu_col = 10;
625
626 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
627 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
628
629 mode = MU_LOGMODE_LOCUS;
630 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
631 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
632 mu_stream_printf (str, "\033f<%d>%s\033l<%d>\033c<%d>"
633 "\033f<%d>%s\033l<%d>\033c<%d>one\n",
634 strlen (file[0]), file[0], 10, 5,
635 strlen (file[1]), file[1], 14, 8);
636 mu_stream_printf (str, "default\n");
637 }
638
639 /* Check the ESC-S specifier (store locus).
640 Expected output:
641 a:10.5-b:14.8: one
642 a:10.5-b:14.8: default
643 */
644 static void
645 fmt_locus6 (mu_stream_t str)
646 {
647 char *file[] = { "a", "b" };
648 struct mu_locus_range lr;
649 int mode;
650
651 lr.beg.mu_file = "input";
652 lr.beg.mu_line = 1;
653 lr.beg.mu_col = 1;
654
655 lr.end.mu_file = "next";
656 lr.end.mu_line = 5;
657 lr.end.mu_col = 10;
658
659 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
660 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &lr);
661
662 mode = MU_LOGMODE_LOCUS;
663 mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
664 MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
665 mu_stream_printf (str, "\033S\033f<%d>%s\033l<%d>\033c<%d>"
666 "\033f<%d>%s\033l<%d>\033c<%d>one\n",
667 strlen (file[0]), file[0], 10, 5,
668 strlen (file[1]), file[1], 14, 8);
669 mu_stream_printf (str, "default\n");
670 }
671
672
673 struct testcase
674 {
675 char const *id;
676 void (*handler) (mu_stream_t);
677 };
678
679 struct testcase testcases[] = {
680 { "simple print", simple_print },
681 { "severity", check_severity },
682 { "suppress severity", check_suppress },
683 { "suppress severity name", check_suppress_name },
684 { "severity mask", check_severity_mask },
685 { "set/get locus point", set_locus_point },
686 { "locus: file, line", lr_file_line },
687 { "locus: file, line, col", lr_file_line_col },
688 { "locus: file, line-range", lr_file_line2 },
689 { "locus: file, line-range, col", lr_file_line2_col },
690 { "locus: file-range, line-range, col-range", lr_file2_line_col },
691 { "set locus line", set_locus_line },
692 { "advance locus line", advance_locus_line },
693 { "set locus column", set_locus_col },
694 { "advance locus column", advance_locus_col },
695 { "fmt: severity", fmt_severity },
696 { "fmt: locus (file, line)", fmt_locus1 },
697 { "fmt: locus (file, line, column)", fmt_locus2 },
698 { "fmt: locus (range)", fmt_locus3 },
699 { "fmt: locus; restore defaults", fmt_locus4 },
700 { "fmt: locus; restore defaults, display locus", fmt_locus5 },
701 { "fmt: set locus", fmt_locus6 },
702 { NULL }
703 };
704
705 static mu_stream_t
706 create_log (void)
707 {
708 mu_stream_t str, transport;
709 int yes = 1;
710
711 MU_ASSERT (mu_stdio_stream_create (&transport, MU_STDOUT_FD, 0));
712 mu_stream_ioctl (transport, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
713 MU_ASSERT (mu_log_stream_create (&str, transport));
714 mu_stream_unref (transport);
715 return str;
716 }
717
718 static void
719 log_reset (mu_stream_t str)
720 {
721 int mode = 0;
722 MU_ASSERT (mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
723 MU_IOCTL_LOGSTREAM_SET_MODE, &mode));
724 MU_ASSERT (mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
725 MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, NULL));
726 mode = 0;
727 MU_ASSERT (mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
728 MU_IOCTL_LOGSTREAM_SET_SEVERITY_MASK,
729 &mode));
730 }
731
732 int
733 main (int argc, char **argv)
734 {
735 mu_stream_t log;
736 struct testcase *tp;
737 int i;
738
739 mu_set_program_name (argv[0]);
740 mu_stdstream_setup (MU_STDSTREAM_RESET_NONE);
741
742 log = create_log ();
743
744 for (i = 0, tp = testcases; tp->id; tp++, i++)
745 {
746 mu_stream_printf (log, "%02d. %s\n", i, tp->id);
747 tp->handler (log);
748 log_reset (log);
749 }
750
751 return 0;
752 }
753
754
...@@ -152,6 +152,10 @@ m4_include([strin.at]) ...@@ -152,6 +152,10 @@ m4_include([strin.at])
152 m4_include([strout.at]) 152 m4_include([strout.at])
153 m4_include([strerr.at]) 153 m4_include([strerr.at])
154 154
155 AT_BANNER([Streams])
156 m4_include([logstr.at])
157 m4_include([xscript.at])
158
155 m4_include([list.at]) 159 m4_include([list.at])
156 m4_include([address.at]) 160 m4_include([address.at])
157 m4_include([wordsplit.at]) 161 m4_include([wordsplit.at])
...@@ -208,4 +212,3 @@ m4_include([msgset.at]) ...@@ -208,4 +212,3 @@ m4_include([msgset.at])
208 212
209 m4_include([globtest.at]) 213 m4_include([globtest.at])
210 214
211 m4_include([xscript.at])
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
14 # You should have received a copy of the GNU General Public License 14 # You should have received a copy of the GNU General Public License
15 # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. 15 # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16 16
17 AT_BANNER([Transcript stream])
18 AT_SETUP([Transcript stream]) 17 AT_SETUP([Transcript stream])
19 AT_KEYWORDS([stream xscript]) 18 AT_KEYWORDS([stream xscript])
20 AT_DATA([input],[first line 19 AT_DATA([input],[first line
......
...@@ -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.1: comparator `i;ascii-numeric' is incompatible with match type `contains' in call to `header'
42 ]) 42 ])
43 AT_CLEANUP 43 AT_CLEANUP
44 44
......
1 atconfig 1 atconfig
2 atlocal 2 atlocal
3 bs 3 bs
4 cwdrepl
4 fldel 5 fldel
5 lstuid 6 lstuid
6 package.m4 7 package.m4
......