--- /dev/null
+/* -*-c-*-
+ *
+ * Tracing functions for debugging
+ *
+ * (c) 1998 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the mLib utilities library.
+ *
+ * mLib is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * mLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with mLib; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+/* --- ANSI headers --- */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* --- Local headers --- */
+
+#include "dstr.h"
+#include "quis.h"
+#include "trace.h"
+
+/*----- Private state information -----------------------------------------*/
+
+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 l@ = trace level for output
+ * @const char *f@ = a @printf@-style format string
+ * @...@ = other arguments
+ *
+ * Returns: ---
+ *
+ * Use: Reports a message to the trace output.
+ */
+
+void trace(unsigned l, const char *f, ...)
+{
+ va_list ap;
+ dstr d = DSTR_INIT;
+ if ((l & tracing()) == 0)
+ return;
+ va_start(ap, f);
+ dstr_vputf(&d, f, &ap);
+ va_end(ap);
+ tracefunc(d.buf, d.len, tracearg);
+ dstr_destroy(&d);
+}
+
+/* --- @trace_block@ --- *
+ *
+ * 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
+ *
+ * Returns: ---
+ *
+ * Use: Dumps the contents of a block to the trace output.
+ */
+
+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 --- */
+
+ if ((l & tracing()) == 0)
+ return;
+
+ /* --- Now start work --- */
+
+ tracefunc(s, strlen(s), tracearg);
+ while (sz) {
+ dstr_reset(&d);
+ dstr_putf(&d, " %08lx : ", o);
+ for (i = 0; i < 8; i++) {
+ if (i < sz)
+ dstr_putf(&d, "%02x ", p[i]);
+ else
+ dstr_puts(&d, "** ");
+ }
+ dstr_puts(&d, ": ");
+ for (i = 0; i < 8; i++) {
+ if (i < sz)
+ dstr_putc(&d, isprint(p[i]) ? p[i] : '.');
+ else
+ dstr_putc(&d, '*');
+ }
+ dstr_putz(&d);
+ tracefunc(d.buf, d.len, tracearg);
+ c = (sz >= 8) ? 8 : sz;
+ sz -= c, p += c, o += c;
+ }
+ dstr_destroy(&d);
+}
+
+/* --- @trace_on@ --- *
+ *
+ * Arguments: @FILE *fp@ = a file to trace on
+ * @unsigned l@ = trace level to set
+ *
+ * Returns: ---
+ *
+ * Use: Enables tracing to a file.
+ */
+
+void trace_on(FILE *fp, unsigned l)
+{
+ tracefunc = t_file;
+ tracearg = fp;
+ if (!tracelvl)
+ tracelvl = l;
+}
+
+/* --- @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 l@ = trace level to set
+ *
+ * Returns: ---
+ *
+ * Use: Sets the tracing level.
+ */
+
+void trace_level(unsigned l)
+{
+ tracelvl = l;
+}
+
+/* --- @tracing@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: Zero if not tracing, tracing level if tracing.
+ *
+ * Use: Informs the caller whether tracing is enabled.
+ */
+
+unsigned tracing(void)
+{
+ return (tracefunc ? tracelvl : 0u);
+}
+
+/*----- That's all, folks -------------------------------------------------*/