chiark / gitweb /
buf: Fix two embarassing bugs found while writing Lisp bindings.
[mLib] / trace.c
CommitLineData
0875b58f 1/* -*-c-*-
2 *
8656dc50 3 * $Id: trace.c,v 1.8 2004/04/08 01:36:13 mdw Exp $
0875b58f 4 *
5 * Tracing functions for debugging
6 *
7 * (c) 1998 Straylight/Edgeware
8 */
9
c846879c 10/*----- Licensing notice --------------------------------------------------*
0875b58f 11 *
12 * This file is part of the mLib utilities library.
13 *
14 * mLib is free software; you can redistribute it and/or modify
c846879c 15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
0875b58f 19 * mLib is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c846879c 22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
0bd98442 25 * License along with mLib; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
0875b58f 28 */
29
0875b58f 30/*----- Header files ------------------------------------------------------*/
31
32/* --- ANSI headers --- */
33
34#include <ctype.h>
35#include <stdarg.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39
40/* --- Local headers --- */
41
e4452aaa 42#include "dstr.h"
0875b58f 43#include "quis.h"
44#include "trace.h"
45
46/*----- Private state information -----------------------------------------*/
47
e4452aaa 48static void (*tracefunc)(const char *buf, size_t sz, void *v) = 0;
49static void *tracearg;
de3ceebe 50static unsigned tracelvl = 0; /* How much tracing gets done? */
0875b58f 51
52/*----- Functions provided ------------------------------------------------*/
53
e4452aaa 54/* --- @t_file@ --- *
55 *
56 * Arguments: @const char *buf@ = buffer to print
57 * @size_t sz@ = buffer size
58 * @void *v@ = file handle
59 *
60 * Returns: ---
61 *
62 * Use: Dumps tracing information to a file.
63 */
64
65static void t_file(const char *buf, size_t sz, void *v)
66{
67 FILE *fp = v;
68 fprintf(fp, "+ %s: ", QUIS);
69 fwrite(buf, 1, sz, fp);
70 fputc('\n', fp);
71}
72
0875b58f 73/* --- @trace@ --- *
74 *
de3ceebe 75 * Arguments: @unsigned l@ = trace level for output
0875b58f 76 * @const char *f@ = a @printf@-style format string
77 * @...@ = other arguments
78 *
79 * Returns: ---
80 *
81 * Use: Reports a message to the trace output.
82 */
83
de3ceebe 84void trace(unsigned l, const char *f, ...)
0875b58f 85{
86 va_list ap;
e4452aaa 87 dstr d = DSTR_INIT;
0875b58f 88 if ((l & tracing()) == 0)
89 return;
90 va_start(ap, f);
7d0dd9ff 91 dstr_vputf(&d, f, &ap);
0875b58f 92 va_end(ap);
e4452aaa 93 tracefunc(d.buf, d.len, tracearg);
94 dstr_destroy(&d);
0875b58f 95}
96
97/* --- @trace_block@ --- *
98 *
de3ceebe 99 * Arguments: @unsigned l@ = trace level for output
0875b58f 100 * @const char *s@ = some header string to write
101 * @const void *b@ = pointer to a block of memory to dump
102 * @size_t sz@ = size of the block of memory
103 *
104 * Returns: ---
105 *
106 * Use: Dumps the contents of a block to the trace output.
107 */
108
de3ceebe 109void trace_block(unsigned l, const char *s, const void *b, size_t sz)
0875b58f 110{
111 const unsigned char *p = b;
112 size_t i;
113 unsigned long o = 0;
e4452aaa 114 dstr d = DSTR_INIT;
0875b58f 115 size_t c;
116
117 /* --- Skip if the trace level is too high --- */
118
119 if ((l & tracing()) == 0)
120 return;
121
122 /* --- Now start work --- */
123
e4452aaa 124 tracefunc(s, strlen(s), tracearg);
0875b58f 125 while (sz) {
e4452aaa 126 dstr_reset(&d);
127 dstr_putf(&d, " %08lx : ", o);
0875b58f 128 for (i = 0; i < 8; i++) {
129 if (i < sz)
e4452aaa 130 dstr_putf(&d, "%02x ", p[i]);
0875b58f 131 else
e4452aaa 132 dstr_puts(&d, "** ");
0875b58f 133 }
e4452aaa 134 dstr_puts(&d, ": ");
0875b58f 135 for (i = 0; i < 8; i++) {
136 if (i < sz)
e4452aaa 137 dstr_putc(&d, isprint(p[i]) ? p[i] : '.');
0875b58f 138 else
e4452aaa 139 dstr_putc(&d, '*');
0875b58f 140 }
e4452aaa 141 dstr_putz(&d);
142 tracefunc(d.buf, d.len, tracearg);
0875b58f 143 c = (sz >= 8) ? 8 : sz;
144 sz -= c, p += c, o += c;
145 }
e4452aaa 146 dstr_destroy(&d);
0875b58f 147}
148
149/* --- @trace_on@ --- *
150 *
151 * Arguments: @FILE *fp@ = a file to trace on
de3ceebe 152 * @unsigned l@ = trace level to set
0875b58f 153 *
154 * Returns: ---
155 *
156 * Use: Enables tracing to a file.
157 */
158
de3ceebe 159void trace_on(FILE *fp, unsigned l)
0875b58f 160{
e4452aaa 161 tracefunc = t_file;
162 tracearg = fp;
ff0f0220 163 if (!tracelvl)
164 tracelvl = l;
0875b58f 165}
166
e4452aaa 167/* --- @trace_custom@ --- *
168 *
169 * Arguments: @void (*func)(const char *buf, size_t sz, void *v)@ =
170 * output function
171 * @void *v@ = magic handle to give to function
172 *
173 * Returns: ---
174 *
175 * Use: Sets up a custom trace handler.
176 */
177
178void trace_custom(void (*func)(const char */*buf*/,
179 size_t /*sz*/, void */*v*/),
180 void *v)
181{
182 tracefunc = func;
183 tracearg = v;
184}
185
186/* --- @trace_level@ --- *
0875b58f 187 *
de3ceebe 188 * Arguments: @unsigned l@ = trace level to set
0875b58f 189 *
190 * Returns: ---
191 *
192 * Use: Sets the tracing level.
193 */
194
e4452aaa 195void trace_level(unsigned l)
0875b58f 196{
ff0f0220 197 tracelvl = l;
0875b58f 198}
199
200/* --- @tracing@ --- *
201 *
202 * Arguments: ---
203 *
204 * Returns: Zero if not tracing, tracing level if tracing.
205 *
206 * Use: Informs the caller whether tracing is enabled.
207 */
208
de3ceebe 209unsigned tracing(void)
0875b58f 210{
e4452aaa 211 return (tracefunc ? tracelvl : 0u);
0875b58f 212}
213
214/*----- That's all, folks -------------------------------------------------*/