qnetdice

view src/logger.cc @ 1:92377189a5c6

moving along
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 22 Dec 2013 04:08:50 +0200
parents
children
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdarg.h>
5 #include <list>
6 #include "logger.h"
8 struct LogTarget {
9 enum LogTargetType { LOG_TYPE_STREAM, LOG_TYPE_CALLBACK } type;
10 FILE *fp;
11 void (*func)(const char*, void*);
12 void *func_cls;
13 };
15 static void logmsg(LogTarget &out, const char *msg);
17 static LogTarget def_log_target = { LogTarget::LOG_TYPE_STREAM, stderr, 0, 0 };
18 static std::list<LogTarget> targets;
20 void set_log_file(FILE *fp)
21 {
22 LogTarget targ;
23 memset(&targ, 0, sizeof targ);
24 targ.type = LogTarget::LOG_TYPE_STREAM;
25 targ.fp = fp;
26 targets.push_back(targ);
27 }
29 void set_log_callback(void (*cb)(const char*, void*), void *cls)
30 {
31 LogTarget targ;
32 memset(&targ, 0, sizeof targ);
33 targ.type = LogTarget::LOG_TYPE_CALLBACK;
34 targ.func = cb;
35 targ.func_cls = cls;
36 targets.push_back(targ);
37 }
39 void log_message(const char *fmt, ...)
40 {
41 static char buf[512];
43 va_list ap;
44 va_start(ap, fmt);
45 vsnprintf(buf, sizeof buf, fmt, ap);
46 va_end(ap);
48 if(targets.empty()) {
49 logmsg(def_log_target, buf);
50 } else {
51 std::list<LogTarget>::iterator it = targets.begin();
52 while(it != targets.end()) {
53 logmsg(*it++, buf);
54 }
55 }
56 }
59 static void logmsg(LogTarget &out, const char *msg)
60 {
61 switch(out.type) {
62 case LogTarget::LOG_TYPE_STREAM:
63 fputs(msg, out.fp);
64 fflush(out.fp);
65 break;
67 case LogTarget::LOG_TYPE_CALLBACK:
68 out.func(msg, out.func_cls);
69 break;
71 default:
72 break;
73 }
74 }