Commit | Line | Data |
---|---|---|
23e7e3ae JVH |
1 | /** |
2 | * Copyright (C) 2011-2012 Juho Vähä-Herttua | |
3 | * | |
4 | * This library is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU Lesser General Public | |
6 | * License as published by the Free Software Foundation; either | |
7 | * version 2.1 of the License, or (at your option) any later version. | |
8 | * | |
9 | * This library is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | * Lesser General Public License for more details. | |
13 | */ | |
14 | ||
2340bcd3 JVH |
15 | #include <stdlib.h> |
16 | #include <stdio.h> | |
17 | #include <stdarg.h> | |
18 | #include <assert.h> | |
19 | ||
20 | #include "logger.h" | |
979533c3 | 21 | #include "compat.h" |
2340bcd3 | 22 | |
fda63ad4 JVH |
23 | struct logger_s { |
24 | mutex_handle_t lvl_mutex; | |
25 | mutex_handle_t cb_mutex; | |
26 | ||
27 | int level; | |
28 | logger_callback_t callback; | |
29 | }; | |
30 | ||
31 | logger_t * | |
32 | logger_init() | |
2340bcd3 | 33 | { |
fda63ad4 | 34 | logger_t *logger = calloc(1, sizeof(logger_t)); |
2340bcd3 JVH |
35 | assert(logger); |
36 | ||
fda63ad4 JVH |
37 | MUTEX_CREATE(logger->lvl_mutex); |
38 | MUTEX_CREATE(logger->cb_mutex); | |
39 | ||
46212791 | 40 | logger->level = LOGGER_DEBUG; |
2340bcd3 | 41 | logger->callback = NULL; |
fda63ad4 JVH |
42 | return logger; |
43 | } | |
44 | ||
45 | void | |
46 | logger_destroy(logger_t *logger) | |
47 | { | |
48 | MUTEX_DESTROY(logger->lvl_mutex); | |
49 | MUTEX_DESTROY(logger->cb_mutex); | |
50 | free(logger); | |
2340bcd3 JVH |
51 | } |
52 | ||
53 | void | |
54 | logger_set_level(logger_t *logger, int level) | |
55 | { | |
56 | assert(logger); | |
57 | ||
fda63ad4 | 58 | MUTEX_LOCK(logger->lvl_mutex); |
2340bcd3 | 59 | logger->level = level; |
fda63ad4 | 60 | MUTEX_UNLOCK(logger->lvl_mutex); |
2340bcd3 JVH |
61 | } |
62 | ||
63 | void | |
64 | logger_set_callback(logger_t *logger, logger_callback_t callback) | |
65 | { | |
66 | assert(logger); | |
67 | ||
fda63ad4 | 68 | MUTEX_LOCK(logger->cb_mutex); |
2340bcd3 | 69 | logger->callback = callback; |
fda63ad4 | 70 | MUTEX_UNLOCK(logger->cb_mutex); |
2340bcd3 JVH |
71 | } |
72 | ||
73 | static char * | |
74 | logger_utf8_to_local(const char *str) | |
75 | { | |
76 | char *ret = NULL; | |
77 | ||
78 | /* FIXME: This is only implemented on Windows for now */ | |
79 | #if defined(_WIN32) || defined(_WIN64) | |
80 | int wclen, mblen; | |
81 | WCHAR *wcstr; | |
82 | BOOL failed; | |
83 | ||
84 | wclen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); | |
85 | wcstr = malloc(sizeof(WCHAR) * wclen); | |
86 | MultiByteToWideChar(CP_UTF8, 0, str, -1, wcstr, wclen); | |
87 | ||
88 | mblen = WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, NULL, 0, NULL, &failed); | |
89 | if (failed) { | |
90 | /* Invalid characters in input, conversion failed */ | |
91 | free(wcstr); | |
92 | return NULL; | |
93 | } | |
94 | ||
95 | ret = malloc(sizeof(CHAR) * mblen); | |
96 | WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, ret, mblen, NULL, NULL); | |
97 | free(wcstr); | |
98 | #endif | |
99 | ||
100 | return ret; | |
101 | } | |
102 | ||
103 | void | |
104 | logger_log(logger_t *logger, int level, const char *fmt, ...) | |
105 | { | |
106 | char buffer[4096]; | |
107 | va_list ap; | |
108 | ||
fda63ad4 JVH |
109 | MUTEX_LOCK(logger->lvl_mutex); |
110 | if (level > logger->level) { | |
111 | MUTEX_UNLOCK(logger->lvl_mutex); | |
2340bcd3 | 112 | return; |
fda63ad4 JVH |
113 | } |
114 | MUTEX_UNLOCK(logger->lvl_mutex); | |
2340bcd3 JVH |
115 | |
116 | buffer[sizeof(buffer)-1] = '\0'; | |
117 | va_start(ap, fmt); | |
118 | vsnprintf(buffer, sizeof(buffer)-1, fmt, ap); | |
119 | va_end(ap); | |
120 | ||
fda63ad4 | 121 | MUTEX_LOCK(logger->cb_mutex); |
2340bcd3 JVH |
122 | if (logger->callback) { |
123 | logger->callback(level, buffer); | |
fda63ad4 | 124 | MUTEX_UNLOCK(logger->cb_mutex); |
2340bcd3 | 125 | } else { |
fda63ad4 JVH |
126 | char *local; |
127 | MUTEX_UNLOCK(logger->cb_mutex); | |
128 | local = logger_utf8_to_local(buffer); | |
2340bcd3 | 129 | if (local) { |
46212791 | 130 | fprintf(stderr, "%s\n", local); |
2340bcd3 JVH |
131 | free(local); |
132 | } else { | |
46212791 | 133 | fprintf(stderr, "%s\n", buffer); |
2340bcd3 JVH |
134 | } |
135 | } | |
136 | } | |
137 |