libdmtx 0.7.8.7
libdmtx is a software library that enables programs to read and write Data Matrix barcodes of the modern ECC200 variety.
Loading...
Searching...
No Matches
dmtxlog.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 rxi
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 */
22
23#include <stdarg.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <time.h>
27
28#include "dmtx.h"
29#include "dmtxstatic.h"
30
31#define MAX_CALLBACKS 32
32
33#if _WIN32
34# define DmtxPrint fprintf_s
35#else
36# define DmtxPrint fprintf
37#endif
38
39typedef struct
40{
42 void *udata;
43 int level;
44} Callback;
45
46static struct
47{
48 void *udata;
50 int level;
51 unsigned int quiet;
53} l;
54
55static const char *levelStrings[] = {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
56
57#ifdef LOG_USE_COLOR
58static const char *level_colors[] = {"\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m"};
59#endif
60
62{
63 char buf[16];
64 buf[strftime(buf, sizeof(buf), "%H:%M:%S", ev->time)] = '\0';
65#ifdef LOG_USE_COLOR
66 DmtxPrint(ev->udata, "%s %s%-5s\x1b[0m \x1b[90m%s:%d:\x1b[0m ", buf, level_colors[ev->level],
67 level_strings[ev->level], ev->file, ev->line);
68#else
69 DmtxPrint(ev->udata, "%s %-5s %s:%d: ", buf, levelStrings[ev->level], ev->file, ev->line);
70#endif
71 vfprintf(ev->udata, ev->fmt, ev->ap);
72 DmtxPrint(ev->udata, "\n");
73 fflush(ev->udata);
74}
75
76static void fileCallback(DmtxLogEvent *ev)
77{
78 char buf[64];
79 buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0';
80 DmtxPrint(ev->udata, "%s %-5s %s:%d: ", buf, levelStrings[ev->level], ev->file, ev->line);
81 vfprintf(ev->udata, ev->fmt, ev->ap);
82 DmtxPrint(ev->udata, "\n");
83 fflush(ev->udata);
84}
85
86static void lock(void)
87{
88 if (l.lock) {
89 l.lock(1, l.udata);
90 }
91}
92
93static void unlock(void)
94{
95 if (l.lock) {
96 l.lock(0, l.udata);
97 }
98}
99
100const char *dmtxLogLevelString(int level)
101{
102 return levelStrings[level];
103}
104
106{
107 l.lock = fn;
108 l.udata = udata;
109}
110
111extern void dmtxLogSetLevel(int level)
112{
113 l.level = level;
114}
115
116extern void dmtxLogSetQuiet(DmtxBoolean enable)
117{
118 l.quiet = enable;
119}
120
122{
123 for (int i = 0; i < MAX_CALLBACKS; i++) {
124 if (!l.callbacks[i].fn) {
125 l.callbacks[i] = (Callback){fn, udata, level};
126 return 0;
127 }
128 }
129 return -1;
130}
131
132int dmtxLogAddFp(FILE *fp, int level)
133{
135}
136
137static void initEvent(DmtxLogEvent *ev, void *udata)
138{
139 if (ev->time == NULL) {
140 ev->time = malloc(sizeof(struct tm));
141 }
142
143 time_t t = time(NULL);
144#if defined(_WIN32) || defined(_WIN64)
145 localtime_s(ev->time, &t);
146#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
147 localtime_r(&t, ev->time);
148#else
149# error "Unsupported platform"
150#endif
151 ev->udata = udata;
152}
153
154extern void dmtxLog(int level, const char *file, int line, const char *fmt, ...)
155{
156 DmtxLogEvent ev = {.fmt = fmt, .file = file, .line = line, .level = level, .time = malloc(sizeof(struct tm))};
157
158 lock();
159
160 if (!l.quiet && level >= l.level) {
161 initEvent(&ev, stderr);
162 va_start(ev.ap, fmt);
163 stdoutCallback(&ev);
164 va_end(ev.ap);
165 }
166
167 for (int i = 0; i < MAX_CALLBACKS && l.callbacks[i].fn; i++) {
168 Callback *cb = &l.callbacks[i];
169 if (level >= cb->level) {
170 initEvent(&ev, cb->udata);
171 va_start(ev.ap, fmt);
172 cb->fn(&ev);
173 va_end(ev.ap);
174 }
175 }
176
177 free(ev.time);
178 unlock();
179}
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
#define DmtxBoolean
Definition dmtx.h:46
static void initEvent(DmtxLogEvent *ev, void *udata)
Definition dmtxlog.c:137
int dmtxLogAddFp(FILE *fp, int level)
Definition dmtxlog.c:132
void dmtxLogSetQuiet(DmtxBoolean enable)
Definition dmtxlog.c:116
static void fileCallback(DmtxLogEvent *ev)
Definition dmtxlog.c:76
static struct @0 l
Callback callbacks[MAX_CALLBACKS]
Definition dmtxlog.c:52
void * udata
Definition dmtxlog.c:48
#define DmtxPrint
Definition dmtxlog.c:36
void dmtxLogSetLevel(int level)
Definition dmtxlog.c:111
static const char * levelStrings[]
Definition dmtxlog.c:55
const char * dmtxLogLevelString(int level)
Definition dmtxlog.c:100
DmtxLogLockFn lock
Definition dmtxlog.c:49
static void unlock(void)
Definition dmtxlog.c:93
static void stdoutCallback(DmtxLogEvent *ev)
Definition dmtxlog.c:61
int dmtxLogAddCallback(DmtxLogFn fn, void *udata, int level)
Definition dmtxlog.c:121
int level
Definition dmtxlog.c:50
void dmtxLogSetLock(DmtxLogLockFn fn, void *udata)
Definition dmtxlog.c:105
unsigned int quiet
Definition dmtxlog.c:51
#define MAX_CALLBACKS
Definition dmtxlog.c:31
void dmtxLog(int level, const char *file, int line, const char *fmt,...)
Definition dmtxlog.c:154
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
void(* DmtxLogFn)(DmtxLogEvent *ev)
Definition dmtxstatic.h:189
void(* DmtxLogLockFn)(DmtxBoolean lock, void *udata)
Definition dmtxstatic.h:190
DmtxLogFn fn
Definition dmtxlog.c:41
void * udata
Definition dmtxlog.c:42
int level
Definition dmtxlog.c:43
const char * fmt
Definition dmtxstatic.h:181
const char * file
Definition dmtxstatic.h:182