rough framework
[lemu] / notify.c
diff --git a/notify.c b/notify.c
new file mode 100644 (file)
index 0000000..8662f05
--- /dev/null
+++ b/notify.c
@@ -0,0 +1,52 @@
+#define _GNU_SOURCE 1
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include "notify.h"
+
+/*
+ * Generic console notifier.
+ */
+
+static void
+notify_fn_default_(int level, const char * func_name, const char * fmt, ...)
+{
+       FILE  *f = (level <= 1) ? stderr : stdout;
+       static const char * const levels[] = { "FATAL", "ERROR", "INFO", "DEBUG" };
+       const int levels_num = sizeof levels / sizeof *levels;
+       va_list ap;
+
+       flockfile(f);
+
+       fputs_unlocked((func_name && *func_name) ? func_name : "[null]", f);
+       fputs_unlocked(": --", f);
+       if (level >= 0
+       &&  level <= levels_num) {
+               fputs_unlocked(levels[level], f);
+       } else {
+               fprintf(f, "%d", level);
+       }
+       fputs_unlocked("-- ", f);
+
+       va_start(ap, fmt);
+       vfprintf(f, fmt, ap);
+       va_end(ap);
+
+       fputc_unlocked('\n', f);
+       fflush_unlocked(f);
+
+       funlockfile(f);
+
+}
+
+void (* notify_fn)(int level, const char *func_name, const char *msg, ...) __attribute__((format(printf, 3, 4))) = notify_fn_default_;
+
+void
+notify_fn_set(void (* fn)(int level, const char *func_name, const char *fmt, ...))
+{
+       notify_fn = fn;
+}