+/*----- Trace messages ----------------------------------------------------*/
+
+#if !defined(NDEBUG) && !defined(TRACING)
+# define TRACING
+#endif
+
+#ifdef TRACING
+
+/* --- @trace@ --- *
+ *
+ * Arguments: @unsigned int lvl@ = trace level for output
+ * @const char *f@ = a @printf@-style format string
+ * @...@ = other arguments
+ *
+ * Returns: ---
+ *
+ * Use: Reports a message to the trace output.
+ */
+
+extern void trace(unsigned int /*lvl*/, const char */*f*/, ...);
+
+/* --- @traceblk@ --- *
+ *
+ * Arguments: @unsigned int lvl@ = trace level for output
+ * @const char *hdr@ = some header string to write
+ * @const void *blk@ = 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.
+ */
+
+extern void traceblk(unsigned int /*lvl*/, const char */*hdr*/,
+ const void */*blk*/, size_t /*sz*/);
+
+/* --- @traceon@ --- *
+ *
+ * Arguments: @FILE *fp@ = a file to trace on
+ * @unsigned int lvl@ = trace level to set
+ *
+ * Returns: ---
+ *
+ * Use: Enables tracing to a file.
+ */
+
+extern void traceon(FILE */*fp*/, unsigned int /*lvl*/);
+
+/* --- @tracesetlvl@ --- *
+ *
+ * Arguments: @unsigned int lvl@ = trace level to set
+ *
+ * Returns: ---
+ *
+ * Use: Sets the tracing level.
+ */
+
+extern void tracesetlvl(unsigned int /*lvl*/);
+
+/* --- @tracing@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: Zero if not tracing, tracing level if tracing.
+ *
+ * Use: Informs the caller whether tracing is enabled.
+ */
+
+extern unsigned int tracing(void);
+
+#endif
+
+/* --- Some hacky macros --- */
+
+#ifdef TRACING
+# define T(x) x
+# define IF_TRACING(lvl, x) if ((lvl) & tracing()) x
+#else
+# define T(x)
+# define IF_TRACING(lvl, x)
+#endif
+