aboutsummaryrefslogtreecommitdiffstats
path: root/src/diagnostic
diff options
context:
space:
mode:
authorGravatar Gediminas Jakutis <gediminas@varciai.lt> 2019-11-12 14:36:56 +0200
committerGravatar Gediminas Jakutis <gediminas@varciai.lt> 2019-11-12 14:36:56 +0200
commite2fc18ae456593efe2b968d4af1b8ebfe869d807 (patch)
tree5c1933513a2141a0200819973e96ff61bda55b5e /src/diagnostic
parentae76e4106345035503466bf9dcfa3b0033a526c6 (diff)
downloadlibrin-e2fc18ae456593efe2b968d4af1b8ebfe869d807.tar.gz
librin-e2fc18ae456593efe2b968d4af1b8ebfe869d807.tar.bz2
librin-e2fc18ae456593efe2b968d4af1b8ebfe869d807.zip
diagnostic: use format strings instead.
flags are now dropped in place of per-stream format strings. Signed-off-by: Gediminas Jakutis <gediminas@varciai.lt>
Diffstat (limited to 'src/diagnostic')
-rw-r--r--src/diagnostic/diagnostic.c158
-rw-r--r--src/diagnostic/diagnostic_private.h3
2 files changed, 126 insertions, 35 deletions
diff --git a/src/diagnostic/diagnostic.c b/src/diagnostic/diagnostic.c
index 1258711..a5d7149 100644
--- a/src/diagnostic/diagnostic.c
+++ b/src/diagnostic/diagnostic.c
@@ -20,41 +20,109 @@
#include "diagnostic_private.h"
+#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "rin/diagnostic.h"
#include "rin/time.h"
#include "rin/definitions.h"
+static const char default_format[] = "C:F:mn";
+static const char valid_format[] = "CFtTn:m";
+
static struct iostate {
+ char pidconv[8];
struct timespec start;
FILE *err;
FILE *warn;
FILE *fixme;
FILE *info;
- unsigned int flags;
- char pidconv[8];
-} state = {{0, 0}, NULL, NULL, NULL, NULL, RIN_DIAG_PREFIX, "%08x:"};
+ char *err_format;
+ char *warn_format;
+ char *fixme_format;
+ char *info_format;
+} state = {"%08x:", {0, 0}, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+void rin_diag_cleanup(void)
+{
+ char *tmp;
+
+ tmp = state.err_format;
+ state.err_format = NULL;
+ free(tmp);
+
+ tmp = state.warn_format;
+ state.warn_format = NULL;
+ free(tmp);
+
+ tmp = state.fixme_format;
+ state.fixme_format = NULL;
+ free(tmp);
+
+ tmp = state.info_format;
+ state.info_format = NULL;
+ free(tmp);
+}
void rin_diag_init(void)
{
static const char convstr[8] = "%04hx:";
+ clock_gettime(RIN_CLOCK_WALL_COUNTER, &state.start);
+
if (sizeof(pid_t) == 4) {
memcpy(state.pidconv, convstr, sizeof(convstr));
}
- clock_gettime(RIN_CLOCK_WALL_COUNTER, &state.start);
+ atexit(rin_diag_cleanup);
}
-int rin_diag_flags(int flag, int action)
+int rin_diag_format(enum rin_diag_outstream channel, const char *format)
{
- /* checking for non-existent flags */
- if (flag & ~(RIN_DIAG_ALLFLAGS)) {
- return EINVAL;
+ char *tmp;
+ size_t i, j;
+
+ if (!format) {
+ tmp = NULL;
+ } else {
+ for (i = 0; format[i]; ++i) {
+ int valid = 0;
+
+ for (j = 0; valid_format[j]; ++j) {
+ if (valid_format[j] == format [i]) {
+ valid = 1;
+ break;
+ }
+ }
+
+ if (!valid) {
+ return EINVAL;
+ }
+ }
+
+ tmp = strdup(format);
}
- state.flags = action ? (state.flags | flag) : (state.flags & ~(flag));
+ switch (channel) {
+ case rin_diag_err:
+ free(state.err_format);
+ state.err_format = tmp;
+ break;
+ case rin_diag_warn:
+ free(state.warn_format);
+ state.warn_format = tmp;
+ break;
+ case rin_diag_fixme:
+ free(state.fixme_format);
+ state.fixme_format = tmp;
+ break;
+ case rin_diag_info:
+ free(state.info_format);
+ state.info_format = tmp;
+ break;
+ default:
+ return EINVAL;
+ }
return 0;
}
@@ -86,7 +154,9 @@ void __rin_err(const char *func_name, const char *format, ...)
va_list args;
va_start(args, format);
- __rin_msg(state.err ? state.err : stderr, "error", func_name, format, args);
+ __rin_msg(state.err ? state.err : stderr, "error", func_name,
+ state.err_format ? state.err_format : default_format,
+ format, args);
}
void __rin_warn(const char *func_name, const char *format, ...)
@@ -94,7 +164,9 @@ void __rin_warn(const char *func_name, const char *format, ...)
va_list args;
va_start(args, format);
- __rin_msg(state.warn ? state.warn : stderr, "warning", func_name, format, args);
+ __rin_msg(state.warn ? state.warn : stderr, "warning", func_name,
+ state.warn_format ? state.warn_format : default_format,
+ format, args);
}
void __rin_fixme(const char *func_name, const char *format, ...)
@@ -102,7 +174,9 @@ void __rin_fixme(const char *func_name, const char *format, ...)
va_list args;
va_start(args, format);
- __rin_msg(state.fixme ? state.fixme : stderr, "fixme", func_name, format, args);
+ __rin_msg(state.fixme ? state.fixme : stderr, "fixme", func_name,
+ state.fixme_format ? state.fixme_format : default_format,
+ format, args);
}
void __rin_info(const char *func_name, const char *format, ...)
@@ -110,30 +184,46 @@ void __rin_info(const char *func_name, const char *format, ...)
va_list args;
va_start(args, format);
- __rin_msg(state.info ? state.info : stdout, "info", func_name, format, args);
+ __rin_msg(state.info ? state.info : stdout, "info", func_name,
+ state.info_format ? state.info_format : default_format,
+ format, args);
}
-static void __rin_msg(FILE *stream, const char *prefix, const char *func_name, const char *format, va_list args)
+static void __rin_msg(FILE *stream, const char *prefix, const char *func_name, const char *rin_format, const char *format, va_list args)
{
- if (state.flags & RIN_DIAG_PREFIX) {
- fprintf(stream, "%s:", prefix);
- }
-
- if (state.flags & RIN_DIAG_THREADNUM) {
- fprintf(stream, state.pidconv, gettid());
- }
-
- if (state.flags & RIN_DIAG_FUNC) {
- fprintf(stream, "%s:", func_name);
- }
-
- if (state.flags & RIN_DIAG_TIME) {
- struct timespec t;
- clock_gettime(RIN_CLOCK_WALL_COUNTER, &t);
- t = rin_time_sub(&t, &state.start);
- fprintf(stream, "%lu.%lu:", t.tv_sec, t.tv_nsec);
+ struct timespec t;
+ size_t i;
+ int gottime = 0;
+
+ for (i = 0; rin_format[i]; ++i) {
+ switch (rin_format[i]) {
+ case 'C':
+ fprintf(stream, "%s", prefix);
+ break;
+ case 'F':
+ fprintf(stream, "%s", func_name);
+ break;
+ case 't':
+ fprintf(stream, state.pidconv, gettid());
+ break;
+ case 'T':
+ if (!gottime) {
+ clock_gettime(RIN_CLOCK_WALL_COUNTER, &t);
+ t = rin_time_sub(&t, &state.start);
+ gottime = 1;
+ }
+
+ fprintf(stream, "%lus%06lu.%03luµs", t.tv_sec, t.tv_nsec / 1000, t.tv_nsec % 1000);
+ break;
+ case 'n':
+ fprintf(stream, "\n");
+ break;
+ case ':':
+ fprintf(stream, ":");
+ break;
+ case 'm':
+ vfprintf(stream, format, args);
+ break;
+ }
}
-
- vfprintf(stream, format, args);
- fputc('\n', stream);
}
diff --git a/src/diagnostic/diagnostic_private.h b/src/diagnostic/diagnostic_private.h
index 4f0033f..04778b5 100644
--- a/src/diagnostic/diagnostic_private.h
+++ b/src/diagnostic/diagnostic_private.h
@@ -28,6 +28,7 @@
#define RIN_NEED_GETTID
#include "rin/compat.h"
-static void __rin_msg(FILE *stream, const char *prefix, const char *func_name, const char *format, va_list args);
+static void __rin_msg(FILE *stream, const char *prefix, const char *func_name, const char *rin_format, const char *format, va_list args);
+static void rin_diag_cleanup(void);
#endif /* LIBRIN_DIAGNOSTIC_PRIVATE_INCLUDED */