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.
Showing
7 changed files
with
160 additions
and
33 deletions
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) | ... | ... |
-
Please register or sign in to post a comment