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