/* -*-c-*-
*
- * $Id: trace.c,v 1.4 1999/05/19 20:27:11 mdw Exp $
+ * $Id: trace.c,v 1.6 2001/02/03 16:23:55 mdw Exp $
*
* Tracing functions for debugging
*
/*----- Revision history --------------------------------------------------*
*
* $Log: trace.c,v $
+ * Revision 1.6 2001/02/03 16:23:55 mdw
+ * New custom trace output interface.
+ *
+ * Revision 1.5 1999/10/22 22:39:52 mdw
+ * New documented interface for tracing.
+ *
* Revision 1.4 1999/05/19 20:27:11 mdw
* Change naming to match newer mLib conventions.
*
/* --- Local headers --- */
+#include "dstr.h"
#include "quis.h"
#include "trace.h"
/*----- Private state information -----------------------------------------*/
-static FILE *tracefp = 0; /* Where does debugging go? */
-static unsigned int tracelvl = 0; /* How much tracing gets done? */
+static void (*tracefunc)(const char *buf, size_t sz, void *v) = 0;
+static void *tracearg;
+static unsigned tracelvl = 0; /* How much tracing gets done? */
/*----- Functions provided ------------------------------------------------*/
+/* --- @t_file@ --- *
+ *
+ * Arguments: @const char *buf@ = buffer to print
+ * @size_t sz@ = buffer size
+ * @void *v@ = file handle
+ *
+ * Returns: ---
+ *
+ * Use: Dumps tracing information to a file.
+ */
+
+static void t_file(const char *buf, size_t sz, void *v)
+{
+ FILE *fp = v;
+ fprintf(fp, "+ %s: ", QUIS);
+ fwrite(buf, 1, sz, fp);
+ fputc('\n', fp);
+}
+
/* --- @trace@ --- *
*
- * Arguments: @unsigned int l@ = trace level for output
+ * Arguments: @unsigned l@ = trace level for output
* @const char *f@ = a @printf@-style format string
* @...@ = other arguments
*
* Use: Reports a message to the trace output.
*/
-void trace(unsigned int l, const char *f, ...)
+void trace(unsigned l, const char *f, ...)
{
va_list ap;
+ dstr d = DSTR_INIT;
if ((l & tracing()) == 0)
return;
va_start(ap, f);
- fprintf(tracefp, "*** %s: ", QUIS);
- vfprintf(tracefp, f, ap);
+ dstr_vputf(&d, f, ap);
va_end(ap);
- putc('\n', tracefp);
- fflush(tracefp);
+ tracefunc(d.buf, d.len, tracearg);
+ dstr_destroy(&d);
}
/* --- @trace_block@ --- *
*
- * Arguments: @unsigned int l@ = trace level for output
+ * Arguments: @unsigned l@ = trace level for output
* @const char *s@ = some header string to write
* @const void *b@ = pointer to a block of memory to dump
* @size_t sz@ = size of the block of memory
* Use: Dumps the contents of a block to the trace output.
*/
-void trace_block(unsigned int l, const char *s, const void *b, size_t sz)
+void trace_block(unsigned l, const char *s, const void *b, size_t sz)
{
const unsigned char *p = b;
size_t i;
unsigned long o = 0;
+ dstr d = DSTR_INIT;
size_t c;
/* --- Skip if the trace level is too high --- */
/* --- Now start work --- */
- fprintf(tracefp, "*** %s: %s\n", QUIS, s);
-
+ tracefunc(s, strlen(s), tracearg);
while (sz) {
- fprintf(tracefp, "*** %s: %08lx : ", QUIS, o);
+ dstr_reset(&d);
+ dstr_putf(&d, " %08lx : ", o);
for (i = 0; i < 8; i++) {
if (i < sz)
- fprintf(tracefp, "%02x ", p[i]);
+ dstr_putf(&d, "%02x ", p[i]);
else
- fputs("** ", tracefp);
+ dstr_puts(&d, "** ");
}
- fputs(": ", tracefp);
+ dstr_puts(&d, ": ");
for (i = 0; i < 8; i++) {
if (i < sz)
- fputc(isprint(p[i]) ? p[i] : '.', tracefp);
+ dstr_putc(&d, isprint(p[i]) ? p[i] : '.');
else
- fputc('*', tracefp);
+ dstr_putc(&d, '*');
}
- fputc('\n', tracefp);
+ dstr_putz(&d);
+ tracefunc(d.buf, d.len, tracearg);
c = (sz >= 8) ? 8 : sz;
sz -= c, p += c, o += c;
}
- fflush(tracefp);
+ dstr_destroy(&d);
}
/* --- @trace_on@ --- *
*
* Arguments: @FILE *fp@ = a file to trace on
- * @unsigned int l@ = trace level to set
+ * @unsigned l@ = trace level to set
*
* Returns: ---
*
* Use: Enables tracing to a file.
*/
-void trace_on(FILE *fp, unsigned int l)
+void trace_on(FILE *fp, unsigned l)
{
- tracefp = fp;
+ tracefunc = t_file;
+ tracearg = fp;
if (!tracelvl)
tracelvl = l;
}
-/* --- @trace_setLevel@ --- *
+/* --- @trace_custom@ --- *
+ *
+ * Arguments: @void (*func)(const char *buf, size_t sz, void *v)@ =
+ * output function
+ * @void *v@ = magic handle to give to function
+ *
+ * Returns: ---
+ *
+ * Use: Sets up a custom trace handler.
+ */
+
+void trace_custom(void (*func)(const char */*buf*/,
+ size_t /*sz*/, void */*v*/),
+ void *v)
+{
+ tracefunc = func;
+ tracearg = v;
+}
+
+/* --- @trace_level@ --- *
*
- * Arguments: @unsigned int l@ = trace level to set
+ * Arguments: @unsigned l@ = trace level to set
*
* Returns: ---
*
* Use: Sets the tracing level.
*/
-void trace_setLevel(unsigned int l)
+void trace_level(unsigned l)
{
tracelvl = l;
}
* Use: Informs the caller whether tracing is enabled.
*/
-unsigned int tracing(void)
+unsigned tracing(void)
{
- return (tracefp ? tracelvl : 0u);
+ return (tracefunc ? tracelvl : 0u);
}
/*----- That's all, folks -------------------------------------------------*/