-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmilo.h
289 lines (245 loc) · 8.16 KB
/
milo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/*****************
** shared part **
*****************/
#ifndef MILO_H
# define MILO_H
# ifdef __cplusplus
extern "C"
# endif
/// @brief Extracts filename from filepath.
/// @param filepath file path or name
/// @return pointer to the first character after last occurence of `\\` or
/// `/`
char const *
milo_filename(char const *const filepath);
# ifdef MILO_IMPL
char const *milo_filename(char const *const filepath) {
char const *filename = filepath;
for (char const *c = filepath; *c != '\0'; c++)
if (*c == '\\' || *c == '/') filename = c + 1;
return filename;
}
# endif
/** shared **/
// lvls
# define MILO_LVL_ALL MILO_LVL_TRACE
# define MILO_LVL_TRACE (5)
# define MILO_LVL_INFO (4)
# define MILO_LVL_WARN (3)
# define MILO_LVL_ERROR (2)
# define MILO_LVL_FATAL (1)
# define MILO_LVL_SILENT MILO_LVL_NONE
# define MILO_LVL_NONE (0)
// formatting
# define MILO_FILE (milo_filename(__FILE__))
# define MILO_LINE (__LINE__)
# define MILO_FUNC (__func__)
/** config **/
# ifdef MILO_CONFIG
# include MILO_CONFIG
# endif
// `printf` and `eprintf`
# if (!defined milo_printf)
# if (defined milo_eprintf)
# warning \
"Your `milo_eprintf` will be redefined by MiLo because `milo_printf` wasn't defined. Consider either removing your definition for `milo_eprintf` or adding one for `milo_printf`."
# endif
# include <stdio.h>
# define milo_printf(format, ...) printf(format, ##__VA_ARGS__)
# define milo_eprintf(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
# elif (!defined milo_eprintf)
# define milo_eprintf milo_printf
# endif
// default lvl
# ifndef MILO_DEFAULT_LVL
# define MILO_DEFAULT_LVL MILO_LVL_INFO
# endif
// text attributes
# if (!defined MILO_TA_TRACE && !defined MILO_TA_INFO && \
!defined MILO_TA_WARN && !defined MILO_TA_ERROR && \
!defined MILO_TA_FATAL && !defined MILO_TA_CLEAR && \
!defined MILO_TA_FILE)
# ifdef MILO_NO_TA
# define MILO_TA_TRACE ("")
# define MILO_TA_INFO ("")
# define MILO_TA_WARN ("")
# define MILO_TA_ERROR ("")
# define MILO_TA_FATAL ("")
# define MILO_TA_FILE
# define MILO_TA_CLEAR
# else
# define MILO_TA_TRACE ("\033[0;36m")
# define MILO_TA_INFO ("\033[0;32m")
# define MILO_TA_WARN ("\033[0;93m")
# define MILO_TA_ERROR ("\033[0;31m")
# define MILO_TA_FATAL ("\033[0;1;31m")
# define MILO_TA_FILE "\033[0;2m"
# define MILO_TA_CLEAR "\033[0m"
# endif
# endif
// level names
# if (!defined MILO_LVL_NAME_TRACE && !defined MILO_LVL_NAME_INFO && \
!defined MILO_LVL_NAME_WARN && !defined MILO_LVL_NAME_ERROR && \
!defined MILO_LVL_NAME_FATAL)
# define MILO_LVL_NAME_TRACE ("trc")
# define MILO_LVL_NAME_INFO ("inf")
# define MILO_LVL_NAME_WARN ("wrn")
# define MILO_LVL_NAME_ERROR ("err")
# define MILO_LVL_NAME_FATAL ("ftl")
# endif
// prefix format
# if (!defined MILO_PREFIX_FORMAT && !defined milo_prefix_args)
# define MILO_PREFIX_FORMAT \
MILO_TA_CLEAR "[%s%s" MILO_TA_CLEAR " " MILO_TA_FILE \
"%s:%i" MILO_TA_CLEAR "] " // space before log body
# define milo_prefix_args(attr, lvl) (attr), (lvl), MILO_FILE, MILO_LINE
# endif
#else
# undef milo_trace
# undef milo_info
# undef milo_warn
# undef milo_error
# undef milo_fatal
#endif
/***************
** sole part **
***************/
#ifndef MILO_LVL
# define MILO_LVL MILO_DEFAULT_LVL
#endif
#ifndef MILO_USE_SHORTCUTS
# define MILO_USE_SHORTCUTS (1)
#endif
#if (MILO_LVL) >= (MILO_LVL_ALL)
/// @brief Prints a trace message.
/// @param format
/// @return the same as underlying
# define milo_trace(format, ...) \
milo_printf( \
MILO_PREFIX_FORMAT format "\n", \
milo_prefix_args(MILO_TA_TRACE, MILO_LVL_NAME_TRACE), \
##__VA_ARGS__ \
)
# if (MILO_USE_SHORTCUTS)
/// @brief Prints a trace message.
/// @param format
/// @return the same as underlying
# define trace milo_trace
# endif
#else
/// @brief Does nothing.
/// @return void
# define milo_trace(...) ((void)0)
# if (MILO_USE_SHORTCUTS)
/// @brief Does nothing.
/// @return void
# define trace milo_trace
# endif
#endif
#if (MILO_LVL) >= (MILO_LVL_INFO)
/// @brief Prints an info message.
/// @param format
/// @return the same as underlying
# define milo_info(format, ...) \
milo_printf( \
MILO_PREFIX_FORMAT format "\n", \
milo_prefix_args(MILO_TA_INFO, MILO_LVL_NAME_INFO), \
##__VA_ARGS__ \
)
# if (MILO_USE_SHORTCUTS)
/// @brief Prints an info message.
/// @param format
/// @return the same as underlying
# define info milo_info
# endif
#else
/// @brief Does nothing.
/// @return void
# define milo_info(...) ((void)0)
# if (MILO_USE_SHORTCUTS)
/// @brief Does nothing.
/// @return void
# define info milo_info
# endif
#endif
#if (MILO_LVL) >= (MILO_LVL_WARN)
/// @brief Prints a warning message.
/// @param format
/// @return the same as underlying
# define milo_warn(format, ...) \
milo_printf( \
MILO_PREFIX_FORMAT format "\n", \
milo_prefix_args(MILO_TA_WARN, MILO_LVL_NAME_WARN), \
##__VA_ARGS__ \
)
# if (MILO_USE_SHORTCUTS)
/// @brief Prints a warning message.
/// @param format
/// @return the same as underlying
# define warn milo_warn
# endif
#else
/// @brief Does nothing.
/// @return void
# define milo_warn(...) ((void)0)
# if (MILO_USE_SHORTCUTS)
/// @brief Does nothing.
/// @return void
# define warn milo_warn
# endif
#endif
#if (MILO_LVL) >= (MILO_LVL_ERROR)
/// @brief Prints an error message.
/// @param format
/// @return the same as underlying
# define milo_error(format, ...) \
milo_eprintf( \
MILO_PREFIX_FORMAT format "\n", \
milo_prefix_args(MILO_TA_ERROR, MILO_LVL_NAME_ERROR), \
##__VA_ARGS__ \
)
# if (MILO_USE_SHORTCUTS)
/// @brief Prints an error message.
/// @param format
/// @return the same as underlying
# define error milo_error
# endif
#else
/// @brief Does nothing.
/// @return void
# define milo_error(...) ((void)0)
# if (MILO_USE_SHORTCUTS)
/// @brief Does nothing.
/// @return void
# define error milo_error
# endif
#endif
#if (MILO_LVL) >= (MILO_LVL_FATAL)
/// @brief Prints a fatal error message.
/// @param format
/// @return the same as underlying
# define milo_fatal(format, ...) \
milo_eprintf( \
MILO_PREFIX_FORMAT format "\n", \
milo_prefix_args(MILO_TA_FATAL, MILO_LVL_NAME_FATAL), \
##__VA_ARGS__ \
)
# if (MILO_USE_SHORTCUTS)
/// @brief Prints a fatal error message.
/// @param format
/// @return the same as underlying
# define fatal milo_fatal
# endif
#else
/// @brief Does nothing.
/// @return void
# define milo_fatal(...) ((void)0)
# if (MILO_USE_SHORTCUTS)
/// @brief Does nothing.
/// @return void
# define fatal milo_fatal
# endif
#endif
// this should be unique for each file
#undef MILO_LVL
#undef MILO_USE_SHORTCUTS