27 static int flib_loglevel = FLIB_LOGLEVEL_INFO; |
27 static int flib_loglevel = FLIB_LOGLEVEL_INFO; |
28 static FILE *flib_logfile = NULL; |
28 static FILE *flib_logfile = NULL; |
29 void (*flib_logCallback)(int level, const char *msg) = NULL; |
29 void (*flib_logCallback)(int level, const char *msg) = NULL; |
30 |
30 |
31 char* flib_format_ip(uint32_t numip) { |
31 char* flib_format_ip(uint32_t numip) { |
32 static char ip[16]; |
32 static char ip[16]; |
33 snprintf(ip, 16, "%u.%u.%u.%u", (unsigned)(numip>>24), (unsigned)((numip>>16)&0xff), (unsigned)((numip>>8)&0xff), (unsigned)(numip&0xff)); |
33 snprintf(ip, 16, "%u.%u.%u.%u", (unsigned)(numip>>24), (unsigned)((numip>>16)&0xff), (unsigned)((numip>>8)&0xff), (unsigned)(numip&0xff)); |
34 return ip; |
34 return ip; |
35 } |
35 } |
36 |
36 |
37 static inline FILE *flib_log_getfile() { |
37 static inline FILE *flib_log_getfile() { |
38 if(flib_logfile==NULL) { |
38 if(flib_logfile==NULL) { |
39 return stdout; |
39 return stdout; |
40 } else { |
40 } else { |
41 return flib_logfile; |
41 return flib_logfile; |
42 } |
42 } |
43 } |
43 } |
44 |
44 |
45 static int log_time(char *buffer) { |
45 static int log_time(char *buffer) { |
46 time_t timer; |
46 time_t timer; |
47 struct tm* tm_info; |
47 struct tm* tm_info; |
51 |
51 |
52 return strftime(buffer, 25, "%Y-%m-%d %H:%M:%S", tm_info); |
52 return strftime(buffer, 25, "%Y-%m-%d %H:%M:%S", tm_info); |
53 } |
53 } |
54 |
54 |
55 static char getPrefix(int level) { |
55 static char getPrefix(int level) { |
56 switch(level) { |
56 switch(level) { |
57 case FLIB_LOGLEVEL_ERROR: return 'E'; |
57 case FLIB_LOGLEVEL_ERROR: return 'E'; |
58 case FLIB_LOGLEVEL_WARNING: return 'W'; |
58 case FLIB_LOGLEVEL_WARNING: return 'W'; |
59 case FLIB_LOGLEVEL_INFO: return 'I'; |
59 case FLIB_LOGLEVEL_INFO: return 'I'; |
60 case FLIB_LOGLEVEL_DEBUG: return 'D'; |
60 case FLIB_LOGLEVEL_DEBUG: return 'D'; |
61 default: return '?'; |
61 default: return '?'; |
62 } |
62 } |
63 } |
63 } |
64 |
64 |
65 static void _flib_vflog(const char *func, int level, const char *fmt, va_list args) { |
65 static void _flib_vflog(const char *func, int level, const char *fmt, va_list args) { |
66 if(level >= flib_loglevel) { |
66 if(level >= flib_loglevel) { |
67 char logbuffer[1024]; |
67 char logbuffer[1024]; |
68 logbuffer[0] = getPrefix(level); |
68 logbuffer[0] = getPrefix(level); |
69 logbuffer[1] = ' '; |
69 logbuffer[1] = ' '; |
70 |
70 |
71 int pos = 2; |
71 int pos = 2; |
72 |
72 |
73 int len = log_time(logbuffer+pos); |
73 int len = log_time(logbuffer+pos); |
74 if(len>=0) { |
74 if(len>=0) { |
75 pos += len; |
75 pos += len; |
76 if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; |
76 if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; |
77 } else { |
77 } else { |
78 return; |
78 return; |
79 } |
79 } |
80 |
80 |
81 len = snprintf(logbuffer+pos, sizeof(logbuffer)-pos, " [%-30s] ", func); |
81 len = snprintf(logbuffer+pos, sizeof(logbuffer)-pos, " [%-30s] ", func); |
82 if(len>=0) { |
82 if(len>=0) { |
83 pos += len; |
83 pos += len; |
84 if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; |
84 if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; |
85 } else { |
85 } else { |
86 return; |
86 return; |
87 } |
87 } |
88 |
88 |
89 len = vsnprintf(logbuffer+pos, sizeof(logbuffer)-pos, fmt, args); |
89 len = vsnprintf(logbuffer+pos, sizeof(logbuffer)-pos, fmt, args); |
90 if(len>=0) { |
90 if(len>=0) { |
91 pos += len; |
91 pos += len; |
92 if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; |
92 if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; |
93 } else { |
93 } else { |
94 return; |
94 return; |
95 } |
95 } |
96 |
96 |
97 if(flib_logCallback != NULL) { |
97 if(flib_logCallback != NULL) { |
98 flib_logCallback(level, logbuffer); |
98 flib_logCallback(level, logbuffer); |
99 } else { |
99 } else { |
100 FILE *logfile = flib_log_getfile(); |
100 FILE *logfile = flib_log_getfile(); |
101 fputs(logbuffer, logfile); |
101 fputs(logbuffer, logfile); |
102 fputc('\n', logfile); |
102 fputc('\n', logfile); |
103 fflush(logfile); |
103 fflush(logfile); |
104 } |
104 } |
105 } |
105 } |
106 } |
106 } |
107 |
107 |
108 void _flib_flog(const char *func, int level, const char *fmt, ...) { |
108 void _flib_flog(const char *func, int level, const char *fmt, ...) { |
109 va_list argp; |
109 va_list argp; |
110 va_start(argp, fmt); |
110 va_start(argp, fmt); |
111 _flib_vflog(func, level, fmt, argp); |
111 _flib_vflog(func, level, fmt, argp); |
112 va_end(argp); |
112 va_end(argp); |
113 } |
113 } |
114 |
114 |
115 bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...) { |
115 bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...) { |
116 if(!cond) { |
116 if(!cond) { |
117 va_list argp; |
117 va_list argp; |
118 va_start(argp, fmt); |
118 va_start(argp, fmt); |
119 _flib_vflog(func, level, fmt, argp); |
119 _flib_vflog(func, level, fmt, argp); |
120 va_end(argp); |
120 va_end(argp); |
121 } |
121 } |
122 return !cond; |
122 return !cond; |
123 } |
123 } |
124 |
124 |
125 int flib_log_getLevel() { |
125 int flib_log_getLevel() { |
126 return flib_loglevel; |
126 return flib_loglevel; |
127 } |
127 } |
128 |
128 |
129 void flib_log_setLevel(int level) { |
129 void flib_log_setLevel(int level) { |
130 flib_loglevel = level; |
130 flib_loglevel = level; |
131 } |
131 } |
132 |
132 |
133 void flib_log_setFile(FILE *file) { |
133 void flib_log_setFile(FILE *file) { |
134 flib_logfile = file; |
134 flib_logfile = file; |
135 flib_logCallback = NULL; |
135 flib_logCallback = NULL; |
136 } |
136 } |
137 |
137 |
138 bool flib_log_isActive(int level) { |
138 bool flib_log_isActive(int level) { |
139 return level >= flib_log_getLevel(); |
139 return level >= flib_log_getLevel(); |
140 } |
140 } |
141 |
141 |
142 void flib_log_setCallback(void (*logCallback)(int level, const char *msg)) { |
142 void flib_log_setCallback(void (*logCallback)(int level, const char *msg)) { |
143 flib_logCallback = logCallback; |
143 flib_logCallback = logCallback; |
144 flib_logfile = NULL; |
144 flib_logfile = NULL; |
145 } |
145 } |