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 JVH |
22 | |
23 | void | |
24 | logger_init(logger_t *logger) | |
25 | { | |
26 | assert(logger); | |
27 | ||
28 | logger->level = LOGGER_INFO; | |
29 | logger->callback = NULL; | |
30 | } | |
31 | ||
32 | void | |
33 | logger_set_level(logger_t *logger, int level) | |
34 | { | |
35 | assert(logger); | |
36 | ||
37 | logger->level = level; | |
38 | } | |
39 | ||
40 | void | |
41 | logger_set_callback(logger_t *logger, logger_callback_t callback) | |
42 | { | |
43 | assert(logger); | |
44 | ||
45 | logger->callback = callback; | |
46 | } | |
47 | ||
48 | static char * | |
49 | logger_utf8_to_local(const char *str) | |
50 | { | |
51 | char *ret = NULL; | |
52 | ||
53 | /* FIXME: This is only implemented on Windows for now */ | |
54 | #if defined(_WIN32) || defined(_WIN64) | |
55 | int wclen, mblen; | |
56 | WCHAR *wcstr; | |
57 | BOOL failed; | |
58 | ||
59 | wclen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); | |
60 | wcstr = malloc(sizeof(WCHAR) * wclen); | |
61 | MultiByteToWideChar(CP_UTF8, 0, str, -1, wcstr, wclen); | |
62 | ||
63 | mblen = WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, NULL, 0, NULL, &failed); | |
64 | if (failed) { | |
65 | /* Invalid characters in input, conversion failed */ | |
66 | free(wcstr); | |
67 | return NULL; | |
68 | } | |
69 | ||
70 | ret = malloc(sizeof(CHAR) * mblen); | |
71 | WideCharToMultiByte(CP_ACP, 0, wcstr, wclen, ret, mblen, NULL, NULL); | |
72 | free(wcstr); | |
73 | #endif | |
74 | ||
75 | return ret; | |
76 | } | |
77 | ||
78 | void | |
79 | logger_log(logger_t *logger, int level, const char *fmt, ...) | |
80 | { | |
81 | char buffer[4096]; | |
82 | va_list ap; | |
83 | ||
84 | if (level > logger->level) | |
85 | return; | |
86 | ||
87 | buffer[sizeof(buffer)-1] = '\0'; | |
88 | va_start(ap, fmt); | |
89 | vsnprintf(buffer, sizeof(buffer)-1, fmt, ap); | |
90 | va_end(ap); | |
91 | ||
92 | if (logger->callback) { | |
93 | logger->callback(level, buffer); | |
94 | } else { | |
95 | char *local = logger_utf8_to_local(buffer); | |
96 | ||
97 | if (local) { | |
98 | fprintf(stderr, "%s", local); | |
99 | free(local); | |
100 | } else { | |
101 | fprintf(stderr, "%s", buffer); | |
102 | } | |
103 | } | |
104 | } | |
105 |