summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-06-07 23:49:41 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-06-07 23:55:45 +0300
commit4e7f5b5c08095818d7876a86ad6657c57c9a8ad1 (patch)
treec2333cbb60922137543181b6fc18ea1a95b76148
parent7bca245a054a58c7aaf889243fcacd73a5bd0982 (diff)
downloadmailutils-4e7f5b5c08095818d7876a86ad6657c57c9a8ad1.tar.gz
mailutils-4e7f5b5c08095818d7876a86ad6657c57c9a8ad1.tar.bz2
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.
-rw-r--r--include/mailutils/debug.h2
-rw-r--r--include/mailutils/locus.h12
-rw-r--r--include/mailutils/log.h4
-rw-r--r--include/mailutils/mailutils.h1
-rw-r--r--include/mailutils/stream.h11
-rw-r--r--include/mailutils/sys/logstream.h3
-rw-r--r--libmailutils/locus/debug.c100
-rw-r--r--libmailutils/locus/ident.c12
-rw-r--r--libmailutils/stream/logstream.c276
-rw-r--r--libmailutils/tests/.gitignore1
-rw-r--r--libmailutils/tests/Makefile.am2
-rw-r--r--libmailutils/tests/logstr.at80
-rw-r--r--libmailutils/tests/logstr.c754
-rw-r--r--libmailutils/tests/testsuite.at5
-rw-r--r--libmailutils/tests/xscript.at1
-rw-r--r--sieve/tests/i-numeric.at2
-rw-r--r--testsuite/.gitignore1
17 files changed, 1138 insertions, 129 deletions
diff --git a/include/mailutils/debug.h b/include/mailutils/debug.h
index 647a0582c..8ec2e88c7 100644
--- a/include/mailutils/debug.h
+++ b/include/mailutils/debug.h
@@ -106,7 +106,7 @@ int mu_debug_get_iterator (mu_iterator_t *piterator, int skipunset);
if (mu_debug_line_info) \
{ \
mu_debug_log_begin ("\033X<%d>%s:%d: ", \
- MU_LOGMODE_LOCUS, __FILE__, __LINE__); \
+ MU_LOGMODE_LOCUS, __FILE__, __LINE__); \
mu_debug_log_end s; \
} \
else \
diff --git a/include/mailutils/locus.h b/include/mailutils/locus.h
index 383b6ecea..4a454098c 100644
--- a/include/mailutils/locus.h
+++ b/include/mailutils/locus.h
@@ -2,6 +2,7 @@
#define _MAILUTILS_LOCUS_H
#include <string.h>
+#include <stdarg.h>
struct mu_locus_point
{
@@ -49,6 +50,17 @@ void mu_locus_tracker_advance (struct mu_locus_track *trk,
char const *text, size_t leng);
void mu_locus_tracker_retreat (struct mu_locus_track *trk, size_t n);
+void mu_stream_print_locus_range (mu_stream_t stream,
+ struct mu_locus_range const *loc);
+
+void mu_stream_vlprintf (mu_stream_t stream,
+ struct mu_locus_range const *loc,
+ char const *fmt, va_list ap);
+void mu_stream_lprintf (mu_stream_t stream,
+ struct mu_locus_range const *loc,
+ char const *fmt, ...);
+void mu_lrange_debug (struct mu_locus_range const *loc,
+ char const *fmt, ...);
#endif
diff --git a/include/mailutils/log.h b/include/mailutils/log.h
index 53cccd21b..34aeb63dc 100644
--- a/include/mailutils/log.h
+++ b/include/mailutils/log.h
@@ -32,8 +32,8 @@ extern "C" {
#define MU_LOG_ALERT 6
#define MU_LOG_EMERG 7
-#define MU_LOGMODE_SEVERITY 0x0001
-#define MU_LOGMODE_LOCUS 0x0002
+#define MU_LOGMODE_SEVERITY 0x0001
+#define MU_LOGMODE_LOCUS 0x0002
int mu_log_stream_create (mu_stream_t *, mu_stream_t);
int mu_syslog_stream_create (mu_stream_t *, int);
diff --git a/include/mailutils/mailutils.h b/include/mailutils/mailutils.h
index be4985e53..51cfe09c3 100644
--- a/include/mailutils/mailutils.h
+++ b/include/mailutils/mailutils.h
@@ -36,6 +36,7 @@
#include <mailutils/header.h>
#include <mailutils/iterator.h>
#include <mailutils/kwd.h>
+/* FIXME #include <mailutils/locus.h> */
#include <mailutils/sieve.h>
#include <mailutils/list.h>
#include <mailutils/locker.h>
diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h
index f7f58ba8a..d200c2840 100644
--- a/include/mailutils/stream.h
+++ b/include/mailutils/stream.h
@@ -83,7 +83,7 @@ enum mu_buffer_type
/* Opcodes common for various families */
#define MU_IOCTL_OP_GET 0
#define MU_IOCTL_OP_SET 1
-
+
/* Opcodes for MU_IOCTL_PROGSTREAM */
#define MU_IOCTL_PROG_STATUS 0
#define MU_IOCTL_PROG_PID 1
@@ -158,6 +158,15 @@ enum mu_buffer_type
Arg: mu_stream_t*
*/
#define MU_IOCTL_LOGSTREAM_CLONE 14
+
+ /* Get locus range.
+ Arg: struct mu_locus_range *
+ */
+#define MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE 15
+ /* Set locus range.
+ Arg: struct mu_locus_range *
+ */
+#define MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE 16
/* Opcodes for MU_IOCTL_XSCRIPTSTREAM */
/* Swap transcript levels.
diff --git a/include/mailutils/sys/logstream.h b/include/mailutils/sys/logstream.h
index 8bb1c1e25..d480110c4 100644
--- a/include/mailutils/sys/logstream.h
+++ b/include/mailutils/sys/logstream.h
@@ -19,6 +19,7 @@
#include <mailutils/types.h>
#include <mailutils/sys/stream.h>
+#include <mailutils/locus.h>
struct _mu_log_stream
{
@@ -30,7 +31,7 @@ struct _mu_log_stream
int logmode; /* Mode flags */
int sevmask; /* Mask out the output of severity level for
these severities. */
- struct mu_locus locus; /* Location */
+ struct mu_locus_range locrange; /* Location in the source file */
};
void _mu_log_stream_setup (struct _mu_log_stream *sp, mu_stream_t transport);
diff --git a/libmailutils/locus/debug.c b/libmailutils/locus/debug.c
index 1e5e720aa..81e5f3e50 100644
--- a/libmailutils/locus/debug.c
+++ b/libmailutils/locus/debug.c
@@ -9,12 +9,78 @@
#include <mailutils/stdstream.h>
void
+mu_stream_print_locus_range (mu_stream_t stream,
+ struct mu_locus_range const *loc)
+{
+ if (loc->beg.mu_col == 0)
+ {
+ if (loc->end.mu_file
+ && (!mu_locus_point_same_file (&loc->beg, &loc->end)
+ || loc->beg.mu_line != loc->end.mu_line))
+ mu_stream_printf (stream, "%s:%u-%u",
+ loc->beg.mu_file,
+ loc->beg.mu_line,
+ loc->end.mu_line);
+ else
+ mu_stream_printf (stream, "%s:%u",
+ loc->beg.mu_file,
+ loc->beg.mu_line);
+ }
+ else
+ {
+ if (loc->end.mu_file
+ && !mu_locus_point_same_file (&loc->beg, &loc->end))
+ mu_stream_printf (stream, "%s:%u.%u-%s:%u.%u",
+ loc->beg.mu_file,
+ loc->beg.mu_line, loc->beg.mu_col,
+ loc->end.mu_file,
+ loc->end.mu_line, loc->end.mu_col);
+ else if (loc->end.mu_file && loc->beg.mu_line != loc->end.mu_line)
+ mu_stream_printf (stream, "%s:%u.%u-%u.%u",
+ loc->beg.mu_file,
+ loc->beg.mu_line, loc->beg.mu_col,
+ loc->end.mu_line, loc->end.mu_col);
+ else if (loc->end.mu_file && loc->beg.mu_col != loc->end.mu_col)
+ mu_stream_printf (stream, "%s:%u.%u-%u",
+ loc->beg.mu_file,
+ loc->beg.mu_line, loc->beg.mu_col,
+ loc->end.mu_col);
+ else
+ mu_stream_printf (stream, "%s:%u.%u",
+ loc->beg.mu_file,
+ loc->beg.mu_line, loc->beg.mu_col);
+ }
+}
+
+void
+mu_stream_vlprintf (mu_stream_t stream,
+ struct mu_locus_range const *loc,
+ char const *fmt, va_list ap)
+{
+ mu_stream_print_locus_range (stream, loc);
+ mu_stream_write (stream, ": ", 2, NULL);
+ mu_stream_vprintf (mu_strerr, fmt, ap);
+ mu_stream_write (stream, "\n", 1, NULL);
+}
+
+void
+mu_stream_lprintf (mu_stream_t stream,
+ struct mu_locus_range const *loc,
+ char const *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ mu_stream_vlprintf (stream, loc, fmt, ap);
+ va_end (ap);
+}
+
+void
mu_lrange_debug (struct mu_locus_range const *loc,
char const *fmt, ...)
{
va_list ap;
int rc, mode;
-
+
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_GET_MODE, &mode);
if (rc == 0)
@@ -23,37 +89,13 @@ mu_lrange_debug (struct mu_locus_range const *loc,
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_SET_MODE, &new_mode);
}
-
- if (loc->beg.mu_col == 0)
- mu_debug_log_begin ("%s:%u", loc->beg.mu_file, loc->beg.mu_line);
- else if (!mu_locus_point_same_file (&loc->beg, &loc->end))
- mu_debug_log_begin ("%s:%u.%u-%s:%u.%u",
- loc->beg.mu_file,
- loc->beg.mu_line, loc->beg.mu_col,
- loc->end.mu_file,
- loc->end.mu_line, loc->end.mu_col);
- else if (loc->beg.mu_line != loc->end.mu_line)
- mu_debug_log_begin ("%s:%u.%u-%u.%u",
- loc->beg.mu_file,
- loc->beg.mu_line, loc->beg.mu_col,
- loc->end.mu_line, loc->end.mu_col);
- else if (loc->beg.mu_col != loc->end.mu_col)
- mu_debug_log_begin ("%s:%u.%u-%u",
- loc->beg.mu_file,
- loc->beg.mu_line, loc->beg.mu_col,
- loc->end.mu_col);
- else
- mu_debug_log_begin ("%s:%u.%u",
- loc->beg.mu_file,
- loc->beg.mu_line, loc->beg.mu_col);
-
- mu_stream_write (mu_strerr, ": ", 2, NULL);
-
+
va_start (ap, fmt);
- mu_stream_vprintf (mu_strerr, fmt, ap);
+ mu_stream_lprintf (mu_strerr, loc, fmt, ap);
va_end (ap);
- mu_debug_log_nl ();
+
if (rc == 0)
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
+
}
diff --git a/libmailutils/locus/ident.c b/libmailutils/locus/ident.c
index 7d16f5f64..8434084ef 100644
--- a/libmailutils/locus/ident.c
+++ b/libmailutils/locus/ident.c
@@ -20,10 +20,13 @@ mu_ident_ref (char const *name, char const **refname)
int rc;
struct mu_ident_ref *ref, **refptr;
- if (!name)
- return EINVAL;
if (!refname)
return MU_ERR_OUT_PTR_NULL;
+ if (!name)
+ {
+ *refname = NULL;
+ return 0;
+ }
if (!nametab)
{
@@ -46,6 +49,7 @@ mu_ident_ref (char const *name, char const **refname)
mu_assoc_remove (nametab, name);
return rc;
}
+ *refptr = ref;
ref->count = 0;
break;
@@ -68,9 +72,7 @@ mu_ident_deref (char const *name)
struct mu_ident_ref *ref;
int rc;
- if (!name)
- return EINVAL;
- if (!nametab)
+ if (!name || !nametab)
return 0;
rc = mu_assoc_lookup (nametab, name, &ref);
diff --git a/libmailutils/stream/logstream.c b/libmailutils/stream/logstream.c
index 5bca3c278..1a76285bb 100644
--- a/libmailutils/stream/logstream.c
+++ b/libmailutils/stream/logstream.c
@@ -30,6 +30,7 @@
#include <mailutils/nls.h>
#include <mailutils/stream.h>
#include <mailutils/debug.h>
+#include <mailutils/locus.h>
#include <mailutils/sys/logstream.h>
char *_mu_severity_str[] = {
@@ -69,25 +70,77 @@ mu_severity_to_string (unsigned n, const char **pstr)
return 0;
}
+static void
+lr_set_line (struct mu_locus_range *loc, unsigned val, int end)
+{
+ if (end)
+ loc->end.mu_line = val;
+ else
+ loc->beg.mu_line = val;
+}
+
+static void
+lr_set_col (struct mu_locus_range *loc, unsigned val, int end)
+{
+ if (end)
+ loc->end.mu_col = val;
+ else
+ loc->beg.mu_col = val;
+}
+
static int
-_locus_set_file (struct mu_locus *loc, const char *file, size_t len)
+lr_set_file (struct mu_locus_range *loc, char const *fname, unsigned len,
+ int end)
{
- free (loc->mu_file);
- if (file)
+ char const *refname;
+ struct mu_locus_point *pt = end ? &loc->end : &loc->beg;
+ int rc;
+
+ if (fname == NULL)
{
- loc->mu_file = malloc (len + 1);
- if (!loc->mu_file)
- return ENOMEM;
- memcpy (loc->mu_file, file, len);
- loc->mu_file[len] = 0;
+ refname = NULL;
+ rc = 0;
}
+ else if (len == 0)
+ rc = mu_ident_ref (fname, &refname);
else
- loc->mu_file = NULL;
+ {
+ char *name;
+
+ name = malloc (len + 1);
+ if (!name)
+ return errno;
+ memcpy (name, fname, len);
+ name[len] = 0;
+ rc = mu_ident_ref (name, &refname);
+ free (name);
+ }
+ if (rc)
+ return rc;
+ mu_ident_deref (pt->mu_file);
+ pt->mu_file = refname;
return 0;
}
-#define _locus_set_line(loc, line) ((loc)->mu_line = line)
-#define _locus_set_col(loc, col) ((loc)->mu_col = col)
+/* Field modification map (binary):
+
+ FfLlCc
+
+ The bits f, l, and c (file, line, and column) are toggled cyclically.
+ The value 0 means locus beg, 1 meand locus end.
+ The bits F, L, and C are set once and indicate that the corresponding
+ bit was toggled at least once.
+ */
+#define FMM_COL 0
+#define FMM_LINE 1
+#define FMM_FILE 2
+
+#define FMM_SHIFT(n) ((n)<<1)
+#define FMM_MASK(n) (0x3 << FMM_SHIFT (n))
+#define FMM_VAL(m,n) (((m) >> FMM_SHIFT (n)) & 0x1)
+#define FMM_SET(m,n,v) ((m) = ((m) & ~FMM_MASK (n)) | (((v) << FMM_SHIFT (n))|0x2))
+#define FMM_CYCLE(m, n) \
+ FMM_SET ((m), (n), ((FMM_VAL ((m), (n)) + 1) % 2))
static int
_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,
struct _mu_log_stream *sp = (struct _mu_log_stream *)str;
unsigned severity = sp->severity;
int logmode = sp->logmode;
- struct mu_locus loc = sp->locus;
- const char *fname = NULL;
+ struct mu_locus_range loc;
+ int fmm = 0;
unsigned flen = 0;
int save_locus = 0;
int rc;
@@ -120,6 +173,10 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
n = __x; \
} while (0)
+ loc = sp->locrange;
+ mu_ident_ref (loc.beg.mu_file, &loc.beg.mu_file);
+ mu_ident_ref (loc.end.mu_file, &loc.end.mu_file);
+
/* Tell them we've consumed everything */
*pnwrite = size;
@@ -167,21 +224,24 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
case 'l':
/* Input line (decimal) */
READNUM (n);
- _locus_set_line (&loc, n);
+ lr_set_line (&loc, n, FMM_VAL (fmm, FMM_LINE));
+ FMM_CYCLE (fmm, FMM_LINE);
logmode |= MU_LOGMODE_LOCUS;
break;
case 'c':
/* Column in input line (decimal) */
READNUM (n);
- _locus_set_col (&loc, n);
+ lr_set_col (&loc, n, FMM_VAL (fmm, FMM_COL));
+ FMM_CYCLE (fmm, FMM_COL);
logmode |= MU_LOGMODE_LOCUS;
break;
case 'f':
/* File name. Format: <N>S */
READNUM (flen);
- fname = buf;
+ lr_set_file (&loc, buf, flen, FMM_VAL (fmm, FMM_FILE));
+ FMM_CYCLE (fmm, FMM_FILE);
buf += flen;
size -= flen;
logmode |= MU_LOGMODE_LOCUS;
@@ -197,58 +257,41 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size,
if (severity >= _mu_severity_num)
severity = MU_LOG_EMERG;
- if (fname)
- {
- loc.mu_file = NULL;
- _locus_set_file (&loc, fname, flen);
- }
-
if (save_locus)
{
- _locus_set_file (&sp->locus, loc.mu_file, strlen (loc.mu_file));
- _locus_set_line (&sp->locus, loc.mu_line);
- _locus_set_col (&sp->locus, loc.mu_col);
+ sp->locrange = loc;
+ mu_ident_ref (sp->locrange.beg.mu_file, &sp->locrange.beg.mu_file);
+ mu_ident_ref (sp->locrange.end.mu_file, &sp->locrange.end.mu_file);
}
if (severity < sp->threshold)
+ rc = 0;
+ else
{
- if (fname)
- free (loc.mu_file);
- return 0;
- }
-
- mu_stream_ioctl (sp->transport, MU_IOCTL_LOGSTREAM,
- MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
+ mu_stream_ioctl (sp->transport, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
- if (logmode & MU_LOGMODE_LOCUS)
- {
- if (loc.mu_file)
+ if ((logmode & MU_LOGMODE_LOCUS) && loc.beg.mu_file)
+ {
+ mu_stream_print_locus_range (sp->transport, &loc);
+ mu_stream_write (sp->transport, ": ", 2, NULL);
+ }
+
+ if ((logmode & MU_LOGMODE_SEVERITY) &&
+ !(sp->sevmask & MU_DEBUG_LEVEL_MASK (severity)))
{
- mu_stream_write (sp->transport, loc.mu_file,
- strlen (loc.mu_file), NULL);
- mu_stream_write (sp->transport, ":", 1, NULL);
- if (loc.mu_line)
- mu_stream_printf (sp->transport, "%u", loc.mu_line);
- mu_stream_write (sp->transport, ":", 1, NULL);
- if (loc.mu_col)
- mu_stream_printf (sp->transport, "%u:", loc.mu_col);
- mu_stream_write (sp->transport, " ", 1, NULL);
+ char *s = gettext (_mu_severity_str[severity]);
+ rc = mu_stream_write (sp->transport, s, strlen (s), NULL);
+ if (rc)
+ return rc;
+ mu_stream_write (sp->transport, ": ", 2, NULL);
}
+ rc = mu_stream_write (sp->transport, buf, size, NULL);
}
-
- if (fname)
- free (loc.mu_file);
- if ((logmode & MU_LOGMODE_SEVERITY) &&
- !(sp->sevmask & MU_DEBUG_LEVEL_MASK(severity)))
- {
- char *s = gettext (_mu_severity_str[severity]);
- rc = mu_stream_write (sp->transport, s, strlen (s), NULL);
- if (rc)
- return rc;
- mu_stream_write (sp->transport, ": ", 2, NULL);
- }
- return mu_stream_write (sp->transport, buf, size, NULL);
+ mu_ident_deref (loc.beg.mu_file);
+ mu_ident_deref (loc.end.mu_file);
+ return rc;
}
static int
@@ -375,72 +418,133 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg)
sp->logmode = *(int*)arg;
break;
+ case MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE:
+ {
+ struct mu_locus_range *lr = arg;
+ if (!arg)
+ {
+ mu_ident_deref (sp->locrange.beg.mu_file);
+ mu_ident_deref (sp->locrange.end.mu_file);
+ memset (&sp->locrange, 0, sizeof sp->locrange);
+ }
+ else
+ {
+ char const *begname, *endname;
+
+ status = mu_ident_ref (lr->beg.mu_file, &begname);
+ if (status)
+ return status;
+ status = mu_ident_ref (lr->end.mu_file, &endname);
+ if (status)
+ {
+ mu_ident_deref (begname);
+ return status;
+ }
+ mu_ident_deref (sp->locrange.beg.mu_file);
+ sp->locrange.beg.mu_file = begname;
+ sp->locrange.beg.mu_line = lr->beg.mu_line;
+ sp->locrange.beg.mu_col = lr->beg.mu_col;
+
+ mu_ident_deref (sp->locrange.end.mu_file);
+ sp->locrange.end.mu_file = endname;
+ sp->locrange.end.mu_line = lr->end.mu_line;
+ sp->locrange.end.mu_col = lr->end.mu_col;
+ }
+ }
+ break;
+
+ case MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE:
+ if (!arg)
+ return EINVAL;
+ else
+ {
+ struct mu_locus_range *lr = arg;
+ char const *begname, *endname;
+
+ status = mu_ident_ref (sp->locrange.beg.mu_file, &begname);
+ if (status)
+ return status;
+ status = mu_ident_ref (sp->locrange.end.mu_file, &endname);
+ if (status)
+ {
+ mu_ident_deref (begname);
+ return status;
+ }
+ lr->beg.mu_file = begname;
+ lr->beg.mu_line = sp->locrange.beg.mu_line;
+ lr->beg.mu_col = sp->locrange.beg.mu_col;
+ lr->end.mu_file = endname;
+ lr->end.mu_line = sp->locrange.end.mu_line;
+ lr->end.mu_col = sp->locrange.end.mu_col;
+ }
+ break;
+
case MU_IOCTL_LOGSTREAM_GET_LOCUS:
if (!arg)
return EINVAL;
else
{
struct mu_locus *ploc = arg;
- if (sp->locus.mu_file)
+ if (sp->locrange.beg.mu_file)
{
- ploc->mu_file = strdup (sp->locus.mu_file);
+ ploc->mu_file = strdup (sp->locrange.beg.mu_file);
if (!ploc->mu_file)
return ENOMEM;
}
else
ploc->mu_file = NULL;
- ploc->mu_line = sp->locus.mu_line;
- ploc->mu_col = sp->locus.mu_col;
+ ploc->mu_line = sp->locrange.beg.mu_line;
+ ploc->mu_col = sp->locrange.beg.mu_col;
}
break;
case MU_IOCTL_LOGSTREAM_SET_LOCUS:
{
struct mu_locus *ploc = arg;
- if (!arg)
+
+ mu_ident_deref (sp->locrange.end.mu_file);
+ sp->locrange.end.mu_file = NULL;
+ if (arg)
{
- free (sp->locus.mu_file);
- sp->locus.mu_file = NULL;
- sp->locus.mu_line = 0;
- sp->locus.mu_col = 0;
+ status = lr_set_file (&sp->locrange, ploc->mu_file, 0, 0);
+ if (status)
+ return status;
+ lr_set_line (&sp->locrange, ploc->mu_line, 0);
+ lr_set_col (&sp->locrange, ploc->mu_col, 0);
}
else
{
- if (ploc->mu_file)
- _locus_set_file (&sp->locus, ploc->mu_file,
- strlen (ploc->mu_file));
- if (ploc->mu_line)
- _locus_set_line (&sp->locus, ploc->mu_line);
- if (ploc->mu_col)
- _locus_set_col (&sp->locus, ploc->mu_col);
+ mu_ident_deref (sp->locrange.beg.mu_file);
+ sp->locrange.beg.mu_file = NULL;
}
+
break;
}
case MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE:
if (!arg)
return EINVAL;
- sp->locus.mu_line = *(unsigned*)arg;
+ sp->locrange.beg.mu_line = *(unsigned*)arg;
break;
case MU_IOCTL_LOGSTREAM_SET_LOCUS_COL:
if (!arg)
return EINVAL;
- sp->locus.mu_col = *(unsigned*)arg;
+ sp->locrange.beg.mu_col = *(unsigned*)arg;
break;
case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE:
if (!arg)
- sp->locus.mu_line++;
+ sp->locrange.beg.mu_line++;
else
- sp->locus.mu_line += *(int*)arg;
+ sp->locrange.beg.mu_line += *(int*)arg;
break;
case MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL:
if (!arg)
- sp->locus.mu_col++;
+ sp->locrange.beg.mu_col++;
else
- sp->locus.mu_col += *(int*)arg;
+ sp->locrange.beg.mu_col += *(int*)arg;
break;
case MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY:
@@ -484,14 +588,12 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg)
newp->threshold = sp->threshold;
newp->logmode = sp->logmode;
newp->sevmask = sp->sevmask;
- if (sp->locus.mu_file)
- {
- newp->locus.mu_file = strdup (sp->locus.mu_file);
- if (!newp->locus.mu_file)
- return ENOMEM;
- }
- newp->locus.mu_line = sp->locus.mu_line;
- newp->locus.mu_col = sp->locus.mu_col;
+ newp->locrange = sp->locrange;
+ mu_ident_ref (sp->locrange.beg.mu_file,
+ &sp->locrange.beg.mu_file);
+ mu_ident_ref (sp->locrange.end.mu_file,
+ &sp->locrange.end.mu_file);
+
*(mu_stream_t*) arg = str;
}
break;
diff --git a/libmailutils/tests/.gitignore b/libmailutils/tests/.gitignore
index 3454b7360..04ceff27e 100644
--- a/libmailutils/tests/.gitignore
+++ b/libmailutils/tests/.gitignore
@@ -19,6 +19,7 @@ fsfolder
globtest
imapio
listop
+logstr
mailcap
mimehdr
modmesg
diff --git a/libmailutils/tests/Makefile.am b/libmailutils/tests/Makefile.am
index 83951ba40..e0cccaccf 100644
--- a/libmailutils/tests/Makefile.am
+++ b/libmailutils/tests/Makefile.am
@@ -54,6 +54,7 @@ noinst_PROGRAMS = \
globtest\
imapio\
listop\
+ logstr\
mailcap\
mimehdr\
modtofsaf\
@@ -106,6 +107,7 @@ TESTSUITE_AT = \
inline-comment.at\
linecon.at\
list.at\
+ logstr.at\
mailcap.at\
mimehdr.at\
modmesg00.at\
diff --git a/libmailutils/tests/logstr.at b/libmailutils/tests/logstr.at
new file mode 100644
index 000000000..6d7d8db56
--- /dev/null
+++ b/libmailutils/tests/logstr.at
@@ -0,0 +1,80 @@
+# This file is part of GNU Mailutils. -*- Autotest -*-
+# Copyright (C) 2017 Free Software Foundation, Inc.
+#
+# GNU Mailutils is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3, or (at
+# your option) any later version.
+#
+# GNU Mailutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP(Logger stream)
+AT_KEYWORDS([logstream])
+AT_CHECK([logstr],
+[0],
+[00. simple print
+hello world
+01. severity
+info: one
+emerg: two
+mode was: 0x0001
+02. suppress severity
+info: this message is seen
+emerg: and this one as well
+03. suppress severity name
+info: this message is seen
+emerg: and this one as well
+04. severity mask
+one
+two
+emerg: three
+05. set/get locus point
+input:1: filename and line number
+input:1.3: filename, line and column numbers
+06. locus: file, line
+input:1: file, line
+07. locus: file, line, col
+input:1.1-10: file, line, col
+08. locus: file, line-range
+input:1-2: file, line-range
+09. locus: file, line-range, col
+input:1.1-2.10: file, line-range, col
+10. locus: file-range, line-range, col-range
+input:1.1-next:2.10: file-range, line-range, col-range
+11. set locus line
+input:1.1-next:2.10: initial
+input:8.1-next:2.10: locus line changed
+12. advance locus line
+input:1.1-next:5.10: initial
+input:3.1-next:5.10: locus line advanced
+13. set locus column
+input:1.1-next:2.10: initial
+input:1.8-next:2.10: locus column changed
+14. advance locus column
+input:1.1-next:5.10: initial
+input:1.5-next:5.10: locus line advanced
+15. fmt: severity
+info: severity
+16. fmt: locus (file, line)
+a:10: one
+17. fmt: locus (file, line, column)
+a:10.5: one
+18. fmt: locus (range)
+a:10.5-b:14.8: one
+19. fmt: locus; restore defaults
+a:10.5-b:14.8: one
+default
+20. fmt: locus; restore defaults, display locus
+a:10.5-b:14.8: one
+input:1.1-next:5.10: default
+21. fmt: set locus
+a:10.5-b:14.8: one
+a:10.5-b:14.8: default
+])
+AT_CLEANUP \ No newline at end of file
diff --git a/libmailutils/tests/logstr.c b/libmailutils/tests/logstr.c
new file mode 100644
index 000000000..66c1cc60e
--- /dev/null
+++ b/libmailutils/tests/logstr.c
@@ -0,0 +1,754 @@
+/* This file is part of GNU Mailutils test suite
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ GNU Mailutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Mailutils is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <mailutils/mailutils.h>
+#include <mailutils/locus.h>
+
+/* Check normal operation.
+ Expected output: hello world
+*/
+static void
+simple_print (mu_stream_t str)
+{
+ mu_stream_printf (str, "hello world\n");
+}
+
+/* Check severity control.
+ Expected output:
+ info: one
+ emerg: two
+ mode was: 0x0001
+*/
+static void
+check_severity (mu_stream_t str)
+{
+ unsigned severity = MU_DIAG_INFO;
+ int mode = MU_LOGMODE_SEVERITY, old_mode;
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
+ mu_stream_printf (str, "one\n");
+
+ severity = MU_DIAG_EMERG;
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
+ mu_stream_printf (str, "two\n");
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_GET_MODE, &old_mode);
+
+ mode = 0;
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
+ mu_stream_printf (str, "mode was: 0x%04X\n", old_mode);
+}
+
+/* Check severity suppression mechanism.
+ Expected output:
+ info: this message is seen
+ emerg: and this one as well
+*/
+static void
+check_suppress (mu_stream_t str)
+{
+ unsigned severity;
+ int mode = MU_LOGMODE_SEVERITY;
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
+
+ severity = MU_DIAG_INFO;
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY,
+ &severity);
+
+ severity = MU_DIAG_DEBUG;
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
+
+ mu_stream_printf (str, "this message is not seen\n");
+
+ severity = MU_DIAG_INFO;
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
+ mu_stream_printf (str, "this message is seen\n");
+
+ severity = MU_DIAG_EMERG;
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);
+ mu_stream_printf (str, "and this one as well\n");
+}
+
+/* Check suppression by severity name.
+ Expected output:
+ info: this message is seen
+ emerg: and this one as well
+*/
+static void
+check_suppress_name (mu_stream_t str)
+{
+ int mode = MU_LOGMODE_SEVERITY, severity;
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
+
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY_NAME,
+ "info");
+
+ severity = MU_DIAG_DEBUG;
+ mu_stream_ioctl (str, MU_IOCTL_LOGSTREAM,
+ MU_IOCTL_LOGSTREAM_SET_SEVERITY, &severity);