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