chiark / gitweb /
Infrastructure: Split the files into subdirectories.
[mLib] / trace / trace.c
diff --git a/trace/trace.c b/trace/trace.c
new file mode 100644 (file)
index 0000000..2681cd3
--- /dev/null
@@ -0,0 +1,212 @@
+/* -*-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 -------------------------------------------------*/