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; | |
2975b4b8 | 28 | void *cls; |
fda63ad4 JVH |
29 | logger_callback_t callback; |
30 | }; | |
31 | ||
32 | logger_t * | |
33 | logger_init() | |
2340bcd3 | 34 | { |
fda63ad4 | 35 | logger_t *logger = calloc(1, sizeof(logger_t)); |
2340bcd3 JVH |
36 | assert(logger); |
37 | ||
fda63ad4 JVH |
38 | MUTEX_CREATE(logger->lvl_mutex); |
39 | MUTEX_CREATE(logger->cb_mutex); | |
40 | ||
02fe4db1 | 41 | logger->level = LOGGER_WARNING; |
2340bcd3 | 42 | logger->callback = NULL; |
fda63ad4 JVH |
43 | return logger; |
44 | } | |
45 | ||
46 | void | |
47 | logger_destroy(logger_t *logger) | |
48 | { | |
49 | MUTEX_DESTROY(logger->lvl_mutex); | |
50 | MUTEX_DESTROY(logger->cb_mutex); | |
51 | free(logger); | |
2340bcd3 JVH |
52 | } |
53 | ||
54 | void | |
55 | logger_set_level(logger_t *logger, int level) | |
56 | { | |
57 | assert(logger); | |
58 | ||
fda63ad4 | 59 | MUTEX_LOCK(logger->lvl_mutex); |
2340bcd3 | 60 | logger->level = level; |
fda63ad4 | 61 | MUTEX_UNLOCK(logger->lvl_mutex); |
2340bcd3 JVH |
62 | } |
63 | ||
64 | void | |
2975b4b8 | 65 | logger_set_callback(logger_t *logger, logger_callback_t callback, void *cls) |
2340bcd3 JVH |
66 | { |
67 | assert(logger); | |
68 | ||
fda63ad4 | 69 | MUTEX_LOCK(logger->cb_mutex); |
2975b4b8 | 70 | logger->cls = cls; |
2340bcd3 | 71 | logger->callback = callback; |
fda63ad4 | 72 | MUTEX_UNLOCK(logger->cb_mutex); |
2340bcd3 JVH |
73 | } |
74 | ||
75 | static char * | |
76 | logger_utf8_to_local(const char *str) | |
77 | { | |
78 | char *ret = NULL; | |
79 | ||
80 | /* FIXME: This is only implemented on Windows for now */ | |
81 | #if defined(_WIN32) || defined(_WIN64) | |
82 | int wclen, mblen; | |
83 | WCHAR *wcstr; | |
84 | BOOL failed; | |
85 | ||
86 | wclen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); | |
87 | wcstr = malloc(sizeof(WCHAR) * wclen); | |
88 | MultiByteToWideChar(CP_UTF8, 0, str, -1, wcstr, wclen); | |
89 | ||
90 | mblen = WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, NULL, 0, NULL, &failed); | |
91 | if (failed) { | |
92 | /* Invalid characters in input, conversion failed */ | |
93 | free(wcstr); | |
94 | return NULL; | |
95 | } | |
96 | ||
97 | ret = malloc(sizeof(CHAR) * mblen); | |
98 | WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, ret, mblen, NULL, NULL); | |
99 | free(wcstr); | |
100 | #endif | |
101 | ||
102 | return ret; | |
103 | } | |
104 | ||
105 | void | |
106 | logger_log(logger_t *logger, int level, const char *fmt, ...) | |
107 | { | |
108 | char buffer[4096]; | |
109 | va_list ap; | |
110 | ||
fda63ad4 JVH |
111 | MUTEX_LOCK(logger->lvl_mutex); |
112 | if (level > logger->level) { | |
113 | MUTEX_UNLOCK(logger->lvl_mutex); | |
2340bcd3 | 114 | return; |
fda63ad4 JVH |
115 | } |
116 | MUTEX_UNLOCK(logger->lvl_mutex); | |
2340bcd3 JVH |
117 | |
118 | buffer[sizeof(buffer)-1] = '\0'; | |
119 | va_start(ap, fmt); | |
120 | vsnprintf(buffer, sizeof(buffer)-1, fmt, ap); | |
121 | va_end(ap); | |
122 | ||
fda63ad4 | 123 | MUTEX_LOCK(logger->cb_mutex); |
2340bcd3 | 124 | if (logger->callback) { |
2975b4b8 | 125 | logger->callback(logger->cls, level, buffer); |
fda63ad4 | 126 | MUTEX_UNLOCK(logger->cb_mutex); |
2340bcd3 | 127 | } else { |
fda63ad4 JVH |
128 | char *local; |
129 | MUTEX_UNLOCK(logger->cb_mutex); | |
130 | local = logger_utf8_to_local(buffer); | |
2340bcd3 | 131 | if (local) { |
46212791 | 132 | fprintf(stderr, "%s\n", local); |
2340bcd3 JVH |
133 | free(local); |
134 | } else { | |
46212791 | 135 | fprintf(stderr, "%s\n", buffer); |
2340bcd3 JVH |
136 | } |
137 | } | |
138 | } | |
139 |