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
1 2007-11-28 Sergey Poznyakoff <gray@gnu.org.ua> 1 2007-11-28 Sergey Poznyakoff <gray@gnu.org.ua>
2 2
3 Further improvement of mu_debug_t.
4
5 * include/mailutils/debug.hm4 (struct mu_debug_locus): New data
6 type.
7 (mu_debug_set_locus, mu_debug_get_locus)
8 (mu_debug_set_function, mu_debug_get_function): New prototypes.
9 (mu_debug_printer_fp, mu_debug_syslog_printer)
10 (mu_debug_stderr_printer): Change type of the first argument.
11 (mu_debug_set_data): New function.
12 (all proto): Remove argument names, use only types to avoid
13 problems on some broken systems (FreeBSD comes to mind).
14 * libproto/include/debug0.h (struct _mu_debug): printer: change
15 type of the first argument.
16 locus, function, data, destroy: New fields.
17
18 * mailbox/dbgstderr.c (mu_debug_stderr_printer): Change type of
19 the first argument.
20 * mailbox/dbgsyslog.c (mu_debug_syslog_printer): Change type of
21 the first argument.
22
23 * mailbox/debug.c (mu_debug_destroy): Flush any left over data.
24 Call destroy, if supplied.
25 (mu_debug_set_data): New function.
26 (mu_debug_vprintf): Print locus and function (if supplied) at the
27 beginning of the buffer.
28 (mu_debug_set_locus, mu_debug_get_locus, mu_debug_set_function)
29 (mu_debug_get_function): New functions.
30
31 * scripts/debugdef.m4 (MKDEBUG): Use mu_debug_set_locus and
32 mu_debug_set_function to print source locations. This allows for
33 easy i18n of the MU_DEBUG[0-9]* format strings.
34
35 2007-11-28 Sergey Poznyakoff <gray@gnu.org.ua>
36
3 Introduce "global debug settings". Mailutils objects are supposed 37 Introduce "global debug settings". Mailutils objects are supposed
4 to set their default mu_debug_t objects basing on these settings. 38 to set their default mu_debug_t objects basing on these settings.
5 39
......
...@@ -47,40 +47,48 @@ extern "C" { ...@@ -47,40 +47,48 @@ extern "C" {
47 47
48 #define MU_DEBUG_INHERIT 0xf0000 48 #define MU_DEBUG_INHERIT 0xf0000
49 #define MU_DEBUG_EXTRACT_LEVEL(s) ((s) & ~MU_DEBUG_INHERIT) 49 #define MU_DEBUG_EXTRACT_LEVEL(s) ((s) & ~MU_DEBUG_INHERIT)
50
51 struct mu_debug_locus
52 {
53 const char *file;
54 int line;
55 };
50 56
51 int mu_debug_create (mu_debug_t *, void *owner); 57 int mu_debug_create (mu_debug_t *, void *);
52 void mu_debug_destroy (mu_debug_t *, void *owner); 58 void mu_debug_destroy (mu_debug_t *, void *);
53 void *mu_debug_get_owner (mu_debug_t); 59 void *mu_debug_get_owner (mu_debug_t);
54 int mu_debug_set_level (mu_debug_t, size_t level); 60 int mu_debug_set_level (mu_debug_t, size_t);
55 int mu_debug_get_level (mu_debug_t, size_t *plevel); 61 int mu_debug_get_level (mu_debug_t, size_t *);
56 int mu_debug_print (mu_debug_t debug, size_t level, 62 int mu_debug_set_locus (mu_debug_t, const char *, int);
57 const char *format, ...) MU_PRINTFLIKE(3,4); 63 int mu_debug_get_locus (mu_debug_t, struct mu_debug_locus *);
58 int mu_debug_printv (mu_debug_t debug, size_t level, 64 int mu_debug_set_function (mu_debug_t, const char *);
59 const char *format, va_list ap); 65 int mu_debug_get_function (mu_debug_t, const char **);
60 int mu_debug_check_level (mu_debug_t debug, size_t level); 66
61 67 int mu_debug_print (mu_debug_t, size_t, const char *, ...)
62 int mu_debug_printf (mu_debug_t debug, size_t level, const char *format, ...) 68 MU_PRINTFLIKE(3,4);
69 int mu_debug_printv (mu_debug_t, size_t, const char *, va_list);
70 int mu_debug_check_level (mu_debug_t, size_t);
71
72 int mu_debug_printf (mu_debug_t, size_t, const char *, ...)
63 MU_PRINTFLIKE(3,4); 73 MU_PRINTFLIKE(3,4);
64 74
65 int mu_debug_vprintf (mu_debug_t debug, size_t level, const char *format, 75 int mu_debug_vprintf (mu_debug_t, size_t, const char *, va_list);
66 va_list ap);
67 76
68 extern int mu_debug_line_info; 77 extern int mu_debug_line_info;
69 78
70 typedef int (*mu_debug_printer_fp) (mu_debug_t, size_t level, const char *buf); 79 typedef int (*mu_debug_printer_fp) (void*, size_t, const char *);
71 80
72 extern int mu_debug_set_print (mu_debug_t, 81 int mu_debug_set_print (mu_debug_t, mu_debug_printer_fp, void *);
73 mu_debug_printer_fp printer, 82 int mu_debug_set_data (mu_debug_t, void *, void (*) (void*), void *);
74 void *owner);
75 extern mu_debug_printer_fp mu_debug_default_printer; 83 extern mu_debug_printer_fp mu_debug_default_printer;
76 84
77 int mu_debug_syslog_printer (mu_debug_t, size_t, const char *); 85 int mu_debug_syslog_printer (void *, size_t, const char *);
78 int mu_debug_stderr_printer (mu_debug_t, size_t, const char *); 86 int mu_debug_stderr_printer (void *, size_t, const char *);
79 87
80 unsigned mu_global_debug_level (const char *object_name); 88 unsigned mu_global_debug_level (const char *);
81 int mu_global_debug_set_level (const char *object_name, unsigned level); 89 int mu_global_debug_set_level (const char *, unsigned);
82 int mu_global_debug_clear_level (const char *object_name); 90 int mu_global_debug_clear_level (const char *);
83 int mu_global_debug_from_string (const char *string, const char *errpfx); 91 int mu_global_debug_from_string (const char *, const char *);
84 92
85 forloop(`i',1,11,`MKDEBUG(i)') 93 forloop(`i',1,11,`MKDEBUG(i)')
86 94
......
...@@ -35,7 +35,11 @@ struct _mu_debug ...@@ -35,7 +35,11 @@ struct _mu_debug
35 size_t level; 35 size_t level;
36 mu_stream_t stream; 36 mu_stream_t stream;
37 void *owner; 37 void *owner;
38 int (*printer) (mu_debug_t, size_t level, const char *buf); 38 struct mu_debug_locus locus;
39 const char *function;
40 void *data;
41 mu_debug_printer_fp printer;
42 void (*destroy) (void *data);
39 }; 43 };
40 44
41 #ifdef __cplusplus 45 #ifdef __cplusplus
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
24 #include <stdio.h> 24 #include <stdio.h>
25 25
26 int 26 int
27 mu_debug_stderr_printer (mu_debug_t unused, size_t level, const char *str) 27 mu_debug_stderr_printer (void *unused, size_t level, const char *str)
28 { 28 {
29 fprintf (stderr, "%s: %s", 29 fprintf (stderr, "%s: %s",
30 (level == MU_DEBUG_ERROR) ? "ERROR" : "DEBUG", 30 (level == MU_DEBUG_ERROR) ? "ERROR" : "DEBUG",
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
24 #include <syslog.h> 24 #include <syslog.h>
25 25
26 int 26 int
27 mu_debug_syslog_printer (mu_debug_t unused, size_t level, const char *str) 27 mu_debug_syslog_printer (void *unused, size_t level, const char *str)
28 { 28 {
29 syslog ((level == MU_DEBUG_ERROR) ? LOG_ERR : LOG_DEBUG, "%s", str); 29 syslog ((level == MU_DEBUG_ERROR) ? LOG_ERR : LOG_DEBUG, "%s", str);
30 return 0; 30 return 0;
......
...@@ -55,8 +55,16 @@ mu_debug_destroy (mu_debug_t *pdebug, void *owner) ...@@ -55,8 +55,16 @@ mu_debug_destroy (mu_debug_t *pdebug, void *owner)
55 mu_debug_t debug = *pdebug; 55 mu_debug_t debug = *pdebug;
56 if (debug->owner == owner) 56 if (debug->owner == owner)
57 { 57 {
58 mu_off_t len = 0;
59 int rc = mu_stream_size (debug->stream, &len);
60 if (rc == 0 && len)
61 /* Flush leftover data */
62 mu_debug_printf (debug, 0, "\n");
63
58 mu_stream_destroy (&debug->stream, 64 mu_stream_destroy (&debug->stream,
59 mu_stream_get_owner (debug->stream)); 65 mu_stream_get_owner (debug->stream));
66 if (debug->destroy)
67 debug->destroy (debug->data);
60 free (*pdebug); 68 free (*pdebug);
61 *pdebug = NULL; 69 *pdebug = NULL;
62 } 70 }
...@@ -100,6 +108,19 @@ mu_debug_set_print (mu_debug_t debug, mu_debug_printer_fp printer, void *owner) ...@@ -100,6 +108,19 @@ mu_debug_set_print (mu_debug_t debug, mu_debug_printer_fp printer, void *owner)
100 } 108 }
101 109
102 int 110 int
111 mu_debug_set_data (mu_debug_t debug, void *data, void (*destroy) (void*),
112 void *owner)
113 {
114 if (!debug)
115 return EINVAL;
116 if (debug->owner != owner)
117 return EACCES;
118 debug->data = data;
119 debug->destroy = destroy;
120 return 0;
121 }
122
123 int
103 mu_debug_vprintf (mu_debug_t debug, size_t level, 124 mu_debug_vprintf (mu_debug_t debug, size_t level,
104 const char *format, va_list ap) 125 const char *format, va_list ap)
105 { 126 {
...@@ -112,6 +133,7 @@ mu_debug_vprintf (mu_debug_t debug, size_t level, ...@@ -112,6 +133,7 @@ mu_debug_vprintf (mu_debug_t debug, size_t level,
112 mu_transport_t tbuf; 133 mu_transport_t tbuf;
113 char *ptr, *start, *p; 134 char *ptr, *start, *p;
114 size_t nseg; 135 size_t nseg;
136 int need_space = 0;
115 137
116 if (debug->stream == NULL) 138 if (debug->stream == NULL)
117 { 139 {
...@@ -139,7 +161,7 @@ mu_debug_vprintf (mu_debug_t debug, size_t level, ...@@ -139,7 +161,7 @@ mu_debug_vprintf (mu_debug_t debug, size_t level,
139 { 161 {
140 int c = *++p; 162 int c = *++p;
141 *p = 0; 163 *p = 0;
142 debug->printer (debug, level, ptr); 164 debug->printer (debug->data, level, ptr);
143 *p = c; 165 *p = c;
144 ptr = p; 166 ptr = p;
145 nseg++; 167 nseg++;
...@@ -158,7 +180,26 @@ mu_debug_vprintf (mu_debug_t debug, size_t level, ...@@ -158,7 +180,26 @@ mu_debug_vprintf (mu_debug_t debug, size_t level,
158 180
159 mu_stream_truncate (debug->stream, len); 181 mu_stream_truncate (debug->stream, len);
160 mu_stream_seek (debug->stream, len, SEEK_SET); 182 mu_stream_seek (debug->stream, len, SEEK_SET);
183 if (len)
184 return 0;
161 } 185 }
186
187 if (debug->locus.file)
188 {
189 mu_stream_sequential_printf (debug->stream, "%s:%d:",
190 debug->locus.file, debug->locus.line);
191 need_space = 1;
192 }
193
194 if (debug->function)
195 {
196 mu_stream_sequential_printf (debug->stream, "%s:",
197 debug->function);
198 need_space = 1;
199 }
200
201 if (need_space)
202 mu_stream_sequential_write (debug->stream, " ", 1);
162 } 203 }
163 else 204 else
164 vfprintf (stderr, format, ap); 205 vfprintf (stderr, format, ap);
...@@ -205,3 +246,41 @@ mu_debug_check_level (mu_debug_t debug, size_t level) ...@@ -205,3 +246,41 @@ mu_debug_check_level (mu_debug_t debug, size_t level)
205 return 0; 246 return 0;
206 return debug->level & MU_DEBUG_LEVEL_MASK (level); 247 return debug->level & MU_DEBUG_LEVEL_MASK (level);
207 } 248 }
249
250 int
251 mu_debug_set_locus (mu_debug_t debug, const char *file, int line)
252 {
253 if (!debug)
254 return EINVAL;
255 debug->locus.file = file;
256 debug->locus.line = line;
257 return 0;
258 }
259
260 int
261 mu_debug_get_locus (mu_debug_t debug, struct mu_debug_locus *ploc)
262 {
263 if (!debug)
264 return EINVAL;
265 *ploc = debug->locus;
266 return 0;
267 }
268
269 int
270 mu_debug_set_function (mu_debug_t debug, const char *function)
271 {
272 if (!debug)
273 return EINVAL;
274 debug->function = function;
275 return 0;
276 }
277
278 int
279 mu_debug_get_function (mu_debug_t debug, const char **pfunction)
280 {
281 if (!debug)
282 return EINVAL;
283 *pfunction = debug->function;
284 return 0;
285 }
286
......
1 divert(-1) 1 divert(-1)
2 # This file is part of Mailutils. 2 # This file is part of Mailutils.
3 # Copyright (C) 2006, 2007 Sergey Poznyakoff 3 # Copyright (C) 2006, 2007 Free Software Foundation, Inc.
4 #
5 # Initially written by Sergey Poznyakoff for Mailfromd project.
4 # 6 #
5 # This program is free software; you can redistribute it and/or modify 7 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by 8 # it under the terms of the GNU General Public License as published by
...@@ -26,11 +28,11 @@ define(`MKDEBUG',` ...@@ -26,11 +28,11 @@ define(`MKDEBUG',`
26 do \ 28 do \
27 { \ 29 { \
28 if (mu_debug_line_info) \ 30 if (mu_debug_line_info) \
29 mu_debug_printf (dbg, lev, "%s:%d:%s: " fmt, \ 31 { \
30 __FILE__, __LINE__, __FUNCTION__, \' 32 mu_debug_set_locus (dbg, __FILE__, __LINE__); \
31 __arglist(1,$1)`); \ 33 mu_debug_set_function (dbg, __FUNCTION__); \
32 else \ 34 } \
33 mu_debug_printf (dbg, lev, fmt,'dnl 35 mu_debug_printf (dbg, lev, fmt, 'dnl
34 __arglist(1,$1)`); \ 36 __arglist(1,$1)`); \
35 } \ 37 } \
36 while (0) 38 while (0)
......