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/**
10 * @brief Format local time as "dd/mm/YYYY HH:MM:SS"
11 *
12 * @param out Output buffer (must be at least 20 bytes)
13 */
14static inline void log_datetime(char out[20])
15{
16 time_t t = time(NULL);
17 struct tm tmv;
18
19 localtime_r(&t, &tmv);
20 strftime(out, 20, "%d/%m/%Y %H:%M:%S", &tmv);
21}
22
23/**
24 * @brief Print log message if verbose=true
25 *
26 * @note In DEBUG builds, also prints [file : line : func()]
27 *
28 * @param verbose Whether to emit the log line
29 * @param tag Short tag (e.g. "HTTP", "CONF")
30 * @param fmt printf-style format string
31 * @param ap va_list
32 */
33static inline void log_vprint(bool verbose, const char* tag,
34#if defined(DEBUG)
35 const char* file, int line, const char* func,
36#endif
37 const char* fmt, va_list ap)
38{
39 if (!verbose)
40 return;
41
42 char dt[20];
43 log_datetime(dt);
44 fprintf(stderr, "%s [%s] ", dt, tag);
45
46#if defined(DEBUG)
47 fprintf(stderr, "[%s : %d : %s()] ", file, line, func);
48#endif
49
50 vfprintf(stderr, fmt, ap);
51
52 fputc('\n', stderr);
53}
54
55/**
56 * @brief Print a log message if verbose=true
57 *
58 * @param verbose Whether to emit the log line
59 * @param tag Short tag (e.g. "HTTP", "CONF")
60 * @param fmt printf-style format string
61 */
62static inline void log_print(bool verbose, const char* tag,
63#if defined(DEBUG)
64 const char* file, int line, const char* func,
65#endif
66 const char* fmt, ...)
67{
68 va_list ap;
69 va_start(ap, fmt);
70
71 log_vprint(verbose, tag,
72#if defined(DEBUG)
73 file, line, func,
74#endif
75 fmt, ap);
76
77 va_end(ap);
78}
79
80/**
81 * @brief Log macro
82 *
83 * @param verbose_log Whether to emit the log line
84 * @param tag Short tag string
85 * @param fmt printf-style format string
86 */
87#if defined(DEBUG)
88#define LOG(verbose_log, tag, fmt, ...) \
89 log_print((verbose_log), (tag), __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
90#else
91#define LOG(verbose_log, tag, fmt, ...) \
92 log_print((verbose_log), (tag), (fmt), ##__VA_ARGS__)
93#endif
94
95#endif /* LOG_H */
96