Commit 0c81afb7 0c81afb7bef1b3c182dae633c73ec65694225aaf by Sergey Poznyakoff

Further improvement of mu_debug_t.

* include/mailutils/debug.hm4 (struct mu_debug_locus): New data
type.
(mu_debug_set_locus, mu_debug_get_locus)
(mu_debug_set_function, mu_debug_get_function): New prototypes.
(mu_debug_printer_fp, mu_debug_syslog_printer)
(mu_debug_stderr_printer): Change type of the first argument.
(mu_debug_set_data): New function.
(all proto): Remove argument names, use only types to avoid
problems on some broken systems (FreeBSD comes to mind).
* libproto/include/debug0.h (struct _mu_debug): printer: change
type of the first argument.
locus, function, data, destroy: New fields.

* mailbox/dbgstderr.c (mu_debug_stderr_printer): Change type of
the first argument.
* mailbox/dbgsyslog.c (mu_debug_syslog_printer): Change type of
the first argument.

* mailbox/debug.c (mu_debug_destroy): Flush any left over data.
Call destroy, if supplied.
(mu_debug_set_data): New function.
(mu_debug_vprintf): Print locus and function (if supplied) at the
beginning of the buffer.
(mu_debug_set_locus, mu_debug_get_locus, mu_debug_set_function)
(mu_debug_get_function): New functions.

* scripts/debugdef.m4 (MKDEBUG): Use mu_debug_set_locus and
mu_debug_set_function to print source locations. This allows for
easy i18n of the MU_DEBUG[0-9]* format strings.
1 parent 88c1e336
2007-11-28 Sergey Poznyakoff <gray@gnu.org.ua>
Further improvement of mu_debug_t.
* include/mailutils/debug.hm4 (struct mu_debug_locus): New data
type.
(mu_debug_set_locus, mu_debug_get_locus)
(mu_debug_set_function, mu_debug_get_function): New prototypes.
(mu_debug_printer_fp, mu_debug_syslog_printer)
(mu_debug_stderr_printer): Change type of the first argument.
(mu_debug_set_data): New function.
(all proto): Remove argument names, use only types to avoid
problems on some broken systems (FreeBSD comes to mind).
* libproto/include/debug0.h (struct _mu_debug): printer: change
type of the first argument.
locus, function, data, destroy: New fields.
* mailbox/dbgstderr.c (mu_debug_stderr_printer): Change type of
the first argument.
* mailbox/dbgsyslog.c (mu_debug_syslog_printer): Change type of
the first argument.
* mailbox/debug.c (mu_debug_destroy): Flush any left over data.
Call destroy, if supplied.
(mu_debug_set_data): New function.
(mu_debug_vprintf): Print locus and function (if supplied) at the
beginning of the buffer.
(mu_debug_set_locus, mu_debug_get_locus, mu_debug_set_function)
(mu_debug_get_function): New functions.
* scripts/debugdef.m4 (MKDEBUG): Use mu_debug_set_locus and
mu_debug_set_function to print source locations. This allows for
easy i18n of the MU_DEBUG[0-9]* format strings.
2007-11-28 Sergey Poznyakoff <gray@gnu.org.ua>
Introduce "global debug settings". Mailutils objects are supposed
to set their default mu_debug_t objects basing on these settings.
......
......@@ -47,40 +47,48 @@ extern "C" {
#define MU_DEBUG_INHERIT 0xf0000
#define MU_DEBUG_EXTRACT_LEVEL(s) ((s) & ~MU_DEBUG_INHERIT)
struct mu_debug_locus
{
const char *file;
int line;
};
int mu_debug_create (mu_debug_t *, void *owner);
void mu_debug_destroy (mu_debug_t *, void *owner);
int mu_debug_create (mu_debug_t *, void *);
void mu_debug_destroy (mu_debug_t *, void *);
void *mu_debug_get_owner (mu_debug_t);
int mu_debug_set_level (mu_debug_t, size_t level);
int mu_debug_get_level (mu_debug_t, size_t *plevel);
int mu_debug_print (mu_debug_t debug, size_t level,
const char *format, ...) MU_PRINTFLIKE(3,4);
int mu_debug_printv (mu_debug_t debug, size_t level,
const char *format, va_list ap);
int mu_debug_check_level (mu_debug_t debug, size_t level);
int mu_debug_printf (mu_debug_t debug, size_t level, const char *format, ...)
int mu_debug_set_level (mu_debug_t, size_t);
int mu_debug_get_level (mu_debug_t, size_t *);
int mu_debug_set_locus (mu_debug_t, const char *, int);
int mu_debug_get_locus (mu_debug_t, struct mu_debug_locus *);
int mu_debug_set_function (mu_debug_t, const char *);
int mu_debug_get_function (mu_debug_t, const char **);
int mu_debug_print (mu_debug_t, size_t, const char *, ...)
MU_PRINTFLIKE(3,4);
int mu_debug_printv (mu_debug_t, size_t, const char *, va_list);
int mu_debug_check_level (mu_debug_t, size_t);
int mu_debug_printf (mu_debug_t, size_t, const char *, ...)
MU_PRINTFLIKE(3,4);
int mu_debug_vprintf (mu_debug_t debug, size_t level, const char *format,
va_list ap);
int mu_debug_vprintf (mu_debug_t, size_t, const char *, va_list);
extern int mu_debug_line_info;
typedef int (*mu_debug_printer_fp) (mu_debug_t, size_t level, const char *buf);
typedef int (*mu_debug_printer_fp) (void*, size_t, const char *);
extern int mu_debug_set_print (mu_debug_t,
mu_debug_printer_fp printer,
void *owner);
int mu_debug_set_print (mu_debug_t, mu_debug_printer_fp, void *);
int mu_debug_set_data (mu_debug_t, void *, void (*) (void*), void *);
extern mu_debug_printer_fp mu_debug_default_printer;
int mu_debug_syslog_printer (mu_debug_t, size_t, const char *);
int mu_debug_stderr_printer (mu_debug_t, size_t, const char *);
int mu_debug_syslog_printer (void *, size_t, const char *);
int mu_debug_stderr_printer (void *, size_t, const char *);
unsigned mu_global_debug_level (const char *object_name);
int mu_global_debug_set_level (const char *object_name, unsigned level);
int mu_global_debug_clear_level (const char *object_name);
int mu_global_debug_from_string (const char *string, const char *errpfx);
unsigned mu_global_debug_level (const char *);
int mu_global_debug_set_level (const char *, unsigned);
int mu_global_debug_clear_level (const char *);
int mu_global_debug_from_string (const char *, const char *);
forloop(`i',1,11,`MKDEBUG(i)')
......
......@@ -35,7 +35,11 @@ struct _mu_debug
size_t level;
mu_stream_t stream;
void *owner;
int (*printer) (mu_debug_t, size_t level, const char *buf);
struct mu_debug_locus locus;
const char *function;
void *data;
mu_debug_printer_fp printer;
void (*destroy) (void *data);
};
#ifdef __cplusplus
......
......@@ -24,7 +24,7 @@
#include <stdio.h>
int
mu_debug_stderr_printer (mu_debug_t unused, size_t level, const char *str)
mu_debug_stderr_printer (void *unused, size_t level, const char *str)
{
fprintf (stderr, "%s: %s",
(level == MU_DEBUG_ERROR) ? "ERROR" : "DEBUG",
......
......@@ -24,7 +24,7 @@
#include <syslog.h>
int
mu_debug_syslog_printer (mu_debug_t unused, size_t level, const char *str)
mu_debug_syslog_printer (void *unused, size_t level, const char *str)
{
syslog ((level == MU_DEBUG_ERROR) ? LOG_ERR : LOG_DEBUG, "%s", str);
return 0;
......
......@@ -55,8 +55,16 @@ mu_debug_destroy (mu_debug_t *pdebug, void *owner)
mu_debug_t debug = *pdebug;
if (debug->owner == owner)
{
mu_off_t len = 0;
int rc = mu_stream_size (debug->stream, &len);
if (rc == 0 && len)
/* Flush leftover data */
mu_debug_printf (debug, 0, "\n");
mu_stream_destroy (&debug->stream,
mu_stream_get_owner (debug->stream));
if (debug->destroy)
debug->destroy (debug->data);
free (*pdebug);
*pdebug = NULL;
}
......@@ -100,6 +108,19 @@ mu_debug_set_print (mu_debug_t debug, mu_debug_printer_fp printer, void *owner)
}
int
mu_debug_set_data (mu_debug_t debug, void *data, void (*destroy) (void*),
void *owner)
{
if (!debug)
return EINVAL;
if (debug->owner != owner)
return EACCES;
debug->data = data;
debug->destroy = destroy;
return 0;
}
int
mu_debug_vprintf (mu_debug_t debug, size_t level,
const char *format, va_list ap)
{
......@@ -112,6 +133,7 @@ mu_debug_vprintf (mu_debug_t debug, size_t level,
mu_transport_t tbuf;
char *ptr, *start, *p;
size_t nseg;
int need_space = 0;
if (debug->stream == NULL)
{
......@@ -139,7 +161,7 @@ mu_debug_vprintf (mu_debug_t debug, size_t level,
{
int c = *++p;
*p = 0;
debug->printer (debug, level, ptr);
debug->printer (debug->data, level, ptr);
*p = c;
ptr = p;
nseg++;
......@@ -158,7 +180,26 @@ mu_debug_vprintf (mu_debug_t debug, size_t level,
mu_stream_truncate (debug->stream, len);
mu_stream_seek (debug->stream, len, SEEK_SET);
if (len)
return 0;
}
if (debug->locus.file)
{
mu_stream_sequential_printf (debug->stream, "%s:%d:",
debug->locus.file, debug->locus.line);
need_space = 1;
}
if (debug->function)
{
mu_stream_sequential_printf (debug->stream, "%s:",
debug->function);
need_space = 1;
}
if (need_space)
mu_stream_sequential_write (debug->stream, " ", 1);
}
else
vfprintf (stderr, format, ap);
......@@ -205,3 +246,41 @@ mu_debug_check_level (mu_debug_t debug, size_t level)
return 0;
return debug->level & MU_DEBUG_LEVEL_MASK (level);
}
int
mu_debug_set_locus (mu_debug_t debug, const char *file, int line)
{
if (!debug)
return EINVAL;
debug->locus.file = file;
debug->locus.line = line;
return 0;
}
int
mu_debug_get_locus (mu_debug_t debug, struct mu_debug_locus *ploc)
{
if (!debug)
return EINVAL;
*ploc = debug->locus;
return 0;
}
int
mu_debug_set_function (mu_debug_t debug, const char *function)
{
if (!debug)
return EINVAL;
debug->function = function;
return 0;
}
int
mu_debug_get_function (mu_debug_t debug, const char **pfunction)
{
if (!debug)
return EINVAL;
*pfunction = debug->function;
return 0;
}
......
divert(-1)
# This file is part of Mailutils.
# Copyright (C) 2006, 2007 Sergey Poznyakoff
# Copyright (C) 2006, 2007 Free Software Foundation, Inc.
#
# Initially written by Sergey Poznyakoff for Mailfromd project.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -26,11 +28,11 @@ define(`MKDEBUG',`
do \
{ \
if (mu_debug_line_info) \
mu_debug_printf (dbg, lev, "%s:%d:%s: " fmt, \
__FILE__, __LINE__, __FUNCTION__, \'
__arglist(1,$1)`); \
else \
mu_debug_printf (dbg, lev, fmt,'dnl
{ \
mu_debug_set_locus (dbg, __FILE__, __LINE__); \
mu_debug_set_function (dbg, __FUNCTION__); \
} \
mu_debug_printf (dbg, lev, fmt, 'dnl
__arglist(1,$1)`); \
} \
while (0)
......