1#ifndef LOG_H
2#define LOG_H
3
4#include <stdarg.h>
5#include <stdbool.h>
6#include <stdio.h>
7#include <time.h>
8
9/* Format local time as "dd/mm/YYYY HH:MM:SS" */
10static inline void log_datetime(char out[20])
11{
12 time_t t = time(NULL);
13 struct tm tmv;
14
15 localtime_r(&t, &tmv);
16 strftime(out, 20, "%d/%m/%Y %H:%M:%S", &tmv);
17}
18
19/* Print log message if verbose=true
20 In DEBUG builds, also prints [file : line : func()] */
21static inline void log_vprint(bool verbose, const char* tag,
22#if defined(DEBUG)
23 const char* file, int line, const char* func,
24#endif
25 const char* fmt, va_list ap)
26{
27 if (!verbose)
28 return;
29
30 char dt[20];
31 log_datetime(dt);
32 fprintf(stderr, "%s [%s] ", dt, tag);
33
34#if defined(DEBUG)
35 fprintf(stderr, "[%s : %d : %s()] ", file, line, func);
36#endif
37
38 vfprintf(stderr, fmt, ap);
39
40 fputc('\n', stderr);
41}
42
43/* Print a log message if verbose=true */
44static inline void log_print(bool verbose, const char* tag,
45#if defined(DEBUG)
46 const char* file, int line, const char* func,
47#endif
48 const char* fmt, ...)
49{
50 va_list ap;
51 va_start(ap, fmt);
52
53 log_vprint(verbose, tag,
54#if defined(DEBUG)
55 file, line, func,
56#endif
57 fmt, ap);
58
59 va_end(ap);
60}
61
62/* Log macro */
63#if defined(DEBUG)
64#define LOG(verbose_log, tag, fmt, ...) \
65 log_print((verbose_log), (tag), __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
66#else
67#define LOG(verbose_log, tag, fmt, ...) \
68 log_print((verbose_log), (tag), (fmt), ##__VA_ARGS__)
69#endif
70
71/* Align a label before a printf-style message. */
72#define LOG_FIELD(verbose, tag, label, fmt, ...) \
73 LOG((verbose), (tag), "%-24s " fmt, (label), ##__VA_ARGS__)
74
75#endif /* LOG_H */
76