Commit | Line | Data |
---|---|---|
7e8f2e9c JG |
1 | /* |
2 | * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0-only | |
5 | * | |
6 | */ | |
7 | ||
c9e313bc | 8 | #include "loglevel.hpp" |
28ab034a JG |
9 | |
10 | #include <ctype.h> | |
7e8f2e9c | 11 | #include <string.h> |
f41294ed | 12 | #include <strings.h> |
7e8f2e9c | 13 | |
f1494934 | 14 | namespace { |
7e8f2e9c JG |
15 | struct loglevel_name_value { |
16 | const char *name; | |
17 | int value; | |
18 | }; | |
f1494934 | 19 | } /* namespace */ |
7e8f2e9c | 20 | |
28ab034a | 21 | static const struct loglevel_name_value loglevel_values[] = { |
7e8f2e9c | 22 | { .name = "EMERG", .value = LTTNG_LOGLEVEL_EMERG }, |
85b05318 | 23 | { .name = "TRACE_EMERG", .value = LTTNG_LOGLEVEL_EMERG }, |
7e8f2e9c | 24 | { .name = "ALERT", .value = LTTNG_LOGLEVEL_ALERT }, |
85b05318 | 25 | { .name = "TRACE_ALERT", .value = LTTNG_LOGLEVEL_ALERT }, |
7e8f2e9c | 26 | { .name = "CRIT", .value = LTTNG_LOGLEVEL_CRIT }, |
85b05318 | 27 | { .name = "TRACE_CRIT", .value = LTTNG_LOGLEVEL_CRIT }, |
7e8f2e9c | 28 | { .name = "ERR", .value = LTTNG_LOGLEVEL_ERR }, |
85b05318 | 29 | { .name = "TRACE_ERR", .value = LTTNG_LOGLEVEL_ERR }, |
7e8f2e9c | 30 | { .name = "WARNING", .value = LTTNG_LOGLEVEL_WARNING }, |
85b05318 | 31 | { .name = "TRACE_WARNING", .value = LTTNG_LOGLEVEL_WARNING }, |
7e8f2e9c | 32 | { .name = "NOTICE", .value = LTTNG_LOGLEVEL_NOTICE }, |
85b05318 | 33 | { .name = "TRACE_NOTICE", .value = LTTNG_LOGLEVEL_NOTICE }, |
7e8f2e9c | 34 | { .name = "INFO", .value = LTTNG_LOGLEVEL_INFO }, |
85b05318 | 35 | { .name = "TRACE_INFO", .value = LTTNG_LOGLEVEL_INFO }, |
7e8f2e9c | 36 | { .name = "DEBUG_SYSTEM", .value = LTTNG_LOGLEVEL_DEBUG_SYSTEM }, |
85b05318 | 37 | { .name = "TRACE_DEBUG_SYSTEM", .value = LTTNG_LOGLEVEL_DEBUG_SYSTEM }, |
7e8f2e9c | 38 | { .name = "SYSTEM", .value = LTTNG_LOGLEVEL_DEBUG_SYSTEM }, |
7e8f2e9c | 39 | { .name = "DEBUG_PROGRAM", .value = LTTNG_LOGLEVEL_DEBUG_PROGRAM }, |
85b05318 | 40 | { .name = "TRACE_DEBUG_PROGRAM", .value = LTTNG_LOGLEVEL_DEBUG_PROGRAM }, |
7e8f2e9c | 41 | { .name = "PROGRAM", .value = LTTNG_LOGLEVEL_DEBUG_PROGRAM }, |
7e8f2e9c | 42 | { .name = "DEBUG_PROCESS", .value = LTTNG_LOGLEVEL_DEBUG_PROCESS }, |
85b05318 | 43 | { .name = "TRACE_DEBUG_PROCESS", .value = LTTNG_LOGLEVEL_DEBUG_PROCESS }, |
7e8f2e9c | 44 | { .name = "PROCESS", .value = LTTNG_LOGLEVEL_DEBUG_PROCESS }, |
7e8f2e9c | 45 | { .name = "DEBUG_MODULE", .value = LTTNG_LOGLEVEL_DEBUG_MODULE }, |
85b05318 | 46 | { .name = "TRACE_DEBUG_MODULE", .value = LTTNG_LOGLEVEL_DEBUG_MODULE }, |
7e8f2e9c | 47 | { .name = "MODULE", .value = LTTNG_LOGLEVEL_DEBUG_MODULE }, |
7e8f2e9c | 48 | { .name = "DEBUG_UNIT", .value = LTTNG_LOGLEVEL_DEBUG_UNIT }, |
85b05318 | 49 | { .name = "TRACE_DEBUG_UNIT", .value = LTTNG_LOGLEVEL_DEBUG_UNIT }, |
7e8f2e9c | 50 | { .name = "UNIT", .value = LTTNG_LOGLEVEL_DEBUG_UNIT }, |
7e8f2e9c | 51 | { .name = "DEBUG_FUNCTION", .value = LTTNG_LOGLEVEL_DEBUG_FUNCTION }, |
85b05318 | 52 | { .name = "TRACE_DEBUG_FUNCTION", .value = LTTNG_LOGLEVEL_DEBUG_FUNCTION }, |
7e8f2e9c | 53 | { .name = "FUNCTION", .value = LTTNG_LOGLEVEL_DEBUG_FUNCTION }, |
7e8f2e9c | 54 | { .name = "DEBUG_LINE", .value = LTTNG_LOGLEVEL_DEBUG_LINE }, |
85b05318 | 55 | { .name = "TRACE_DEBUG_LINE", .value = LTTNG_LOGLEVEL_DEBUG_LINE }, |
7e8f2e9c | 56 | { .name = "LINE", .value = LTTNG_LOGLEVEL_DEBUG_LINE }, |
7e8f2e9c | 57 | { .name = "DEBUG", .value = LTTNG_LOGLEVEL_DEBUG }, |
85b05318 | 58 | { .name = "TRACE_DEBUG", .value = LTTNG_LOGLEVEL_DEBUG }, |
7e8f2e9c JG |
59 | }; |
60 | ||
28ab034a | 61 | static const struct loglevel_name_value loglevel_log4j_values[] = { |
7e8f2e9c | 62 | { .name = "OFF", .value = LTTNG_LOGLEVEL_LOG4J_OFF }, |
85b05318 | 63 | { .name = "LOG4J_OFF", .value = LTTNG_LOGLEVEL_LOG4J_OFF }, |
7e8f2e9c | 64 | { .name = "FATAL", .value = LTTNG_LOGLEVEL_LOG4J_FATAL }, |
85b05318 | 65 | { .name = "LOG4J_FATAL", .value = LTTNG_LOGLEVEL_LOG4J_FATAL }, |
7e8f2e9c | 66 | { .name = "ERROR", .value = LTTNG_LOGLEVEL_LOG4J_ERROR }, |
85b05318 | 67 | { .name = "LOG4J_ERROR", .value = LTTNG_LOGLEVEL_LOG4J_ERROR }, |
7e8f2e9c | 68 | { .name = "WARN", .value = LTTNG_LOGLEVEL_LOG4J_WARN }, |
85b05318 | 69 | { .name = "LOG4J_WARN", .value = LTTNG_LOGLEVEL_LOG4J_WARN }, |
7e8f2e9c | 70 | { .name = "INFO", .value = LTTNG_LOGLEVEL_LOG4J_INFO }, |
85b05318 | 71 | { .name = "LOG4J_INFO", .value = LTTNG_LOGLEVEL_LOG4J_INFO }, |
7e8f2e9c | 72 | { .name = "DEBUG", .value = LTTNG_LOGLEVEL_LOG4J_DEBUG }, |
85b05318 | 73 | { .name = "LOG4J_DEBUG", .value = LTTNG_LOGLEVEL_LOG4J_DEBUG }, |
7e8f2e9c | 74 | { .name = "TRACE", .value = LTTNG_LOGLEVEL_LOG4J_TRACE }, |
85b05318 | 75 | { .name = "LOG4J_TRACE", .value = LTTNG_LOGLEVEL_LOG4J_TRACE }, |
7e8f2e9c | 76 | { .name = "ALL", .value = LTTNG_LOGLEVEL_LOG4J_ALL }, |
85b05318 | 77 | { .name = "LOG4J_ALL", .value = LTTNG_LOGLEVEL_LOG4J_ALL }, |
7e8f2e9c JG |
78 | }; |
79 | ||
28ab034a | 80 | static const struct loglevel_name_value loglevel_jul_values[] = { |
7e8f2e9c | 81 | { .name = "OFF", .value = LTTNG_LOGLEVEL_JUL_OFF }, |
85b05318 | 82 | { .name = "JUL_OFF", .value = LTTNG_LOGLEVEL_JUL_OFF }, |
7e8f2e9c | 83 | { .name = "SEVERE", .value = LTTNG_LOGLEVEL_JUL_SEVERE }, |
85b05318 | 84 | { .name = "JUL_SEVERE", .value = LTTNG_LOGLEVEL_JUL_SEVERE }, |
7e8f2e9c | 85 | { .name = "WARNING", .value = LTTNG_LOGLEVEL_JUL_WARNING }, |
85b05318 | 86 | { .name = "JUL_WARNING", .value = LTTNG_LOGLEVEL_JUL_WARNING }, |
7e8f2e9c | 87 | { .name = "INFO", .value = LTTNG_LOGLEVEL_JUL_INFO }, |
85b05318 | 88 | { .name = "JUL_INFO", .value = LTTNG_LOGLEVEL_JUL_INFO }, |
7e8f2e9c | 89 | { .name = "CONFIG", .value = LTTNG_LOGLEVEL_JUL_CONFIG }, |
85b05318 | 90 | { .name = "JUL_CONFIG", .value = LTTNG_LOGLEVEL_JUL_CONFIG }, |
7e8f2e9c | 91 | { .name = "FINE", .value = LTTNG_LOGLEVEL_JUL_FINE }, |
85b05318 | 92 | { .name = "JUL_FINE", .value = LTTNG_LOGLEVEL_JUL_FINE }, |
7e8f2e9c | 93 | { .name = "FINER", .value = LTTNG_LOGLEVEL_JUL_FINER }, |
85b05318 | 94 | { .name = "JUL_FINER", .value = LTTNG_LOGLEVEL_JUL_FINER }, |
7e8f2e9c | 95 | { .name = "FINEST", .value = LTTNG_LOGLEVEL_JUL_FINEST }, |
85b05318 | 96 | { .name = "JUL_FINEST", .value = LTTNG_LOGLEVEL_JUL_FINEST }, |
7e8f2e9c | 97 | { .name = "ALL", .value = LTTNG_LOGLEVEL_JUL_ALL }, |
85b05318 | 98 | { .name = "JUL_ALL", .value = LTTNG_LOGLEVEL_JUL_ALL }, |
7e8f2e9c JG |
99 | }; |
100 | ||
28ab034a | 101 | static const struct loglevel_name_value loglevel_python_values[] = { |
7e8f2e9c | 102 | { .name = "CRITICAL", .value = LTTNG_LOGLEVEL_PYTHON_CRITICAL }, |
85b05318 | 103 | { .name = "PYTHON_CRITICAL", .value = LTTNG_LOGLEVEL_PYTHON_CRITICAL }, |
7e8f2e9c | 104 | { .name = "ERROR", .value = LTTNG_LOGLEVEL_PYTHON_ERROR }, |
85b05318 | 105 | { .name = "PYTHON_ERROR", .value = LTTNG_LOGLEVEL_PYTHON_ERROR }, |
7e8f2e9c | 106 | { .name = "WARNING", .value = LTTNG_LOGLEVEL_PYTHON_WARNING }, |
85b05318 | 107 | { .name = "PYTHON_WARNING", .value = LTTNG_LOGLEVEL_PYTHON_WARNING }, |
7e8f2e9c | 108 | { .name = "INFO", .value = LTTNG_LOGLEVEL_PYTHON_INFO }, |
85b05318 | 109 | { .name = "PYTHON_INFO", .value = LTTNG_LOGLEVEL_PYTHON_INFO }, |
7e8f2e9c | 110 | { .name = "DEBUG", .value = LTTNG_LOGLEVEL_PYTHON_DEBUG }, |
85b05318 | 111 | { .name = "PYTNON_DEBUG", .value = LTTNG_LOGLEVEL_PYTHON_DEBUG }, |
7e8f2e9c | 112 | { .name = "NOTSET", .value = LTTNG_LOGLEVEL_PYTHON_NOTSET }, |
85b05318 | 113 | { .name = "PYTHON_NOTSET", .value = LTTNG_LOGLEVEL_PYTHON_NOTSET }, |
7e8f2e9c JG |
114 | }; |
115 | ||
28ab034a | 116 | static bool string_equal_insensitive(const char *a, const char *b) |
7e8f2e9c | 117 | { |
f41294ed | 118 | return strcasecmp(a, b) == 0; |
7e8f2e9c JG |
119 | } |
120 | ||
28ab034a JG |
121 | static int lookup_value_from_name(const struct loglevel_name_value values[], |
122 | size_t values_count, | |
123 | const char *name) | |
7e8f2e9c JG |
124 | { |
125 | size_t i; | |
126 | int ret = -1; | |
127 | ||
128 | if (!name) { | |
129 | goto end; | |
130 | } | |
131 | ||
132 | for (i = 0; i < values_count; i++) { | |
133 | if (string_equal_insensitive(values[i].name, name)) { | |
134 | /* Match found. */ | |
135 | ret = values[i].value; | |
136 | goto end; | |
137 | } | |
138 | } | |
139 | ||
140 | end: | |
141 | return ret; | |
142 | } | |
143 | ||
949f049b | 144 | static bool loglevel_parse_range_string_common(const char *str, |
28ab034a JG |
145 | const struct loglevel_name_value *nvs, |
146 | size_t nvs_count, | |
147 | int *min, | |
148 | int *max) | |
949f049b SM |
149 | { |
150 | bool ret; | |
151 | int i; | |
152 | const struct loglevel_name_value *nv; | |
153 | ||
154 | for (i = 0; i < nvs_count; i++) { | |
155 | nv = &nvs[i]; | |
156 | ||
157 | if (strncmp(str, nv->name, strlen(nv->name)) == 0) { | |
158 | break; | |
159 | } | |
160 | } | |
161 | ||
162 | if (i == nvs_count) { | |
163 | goto error; | |
164 | } | |
165 | ||
166 | *min = nv->value; | |
167 | str += strlen(nv->name); | |
168 | ||
169 | if (*str == '\0') { | |
170 | *max = nv->value; | |
171 | ret = true; | |
172 | goto end; | |
173 | } | |
174 | ||
175 | if (strncmp(str, "..", strlen("..")) != 0) { | |
176 | goto error; | |
177 | } | |
178 | ||
179 | str += strlen(".."); | |
180 | ||
181 | if (*str == '\0') { | |
182 | *max = LTTNG_LOGLEVEL_EMERG; | |
183 | ret = true; | |
184 | goto end; | |
185 | } | |
186 | ||
187 | for (i = 0; i < nvs_count; i++) { | |
188 | nv = &nvs[i]; | |
189 | ||
190 | if (strcmp(str, nv->name) == 0) { | |
191 | break; | |
192 | } | |
193 | } | |
194 | ||
195 | if (i == nvs_count) { | |
196 | goto error; | |
197 | } | |
198 | ||
199 | *max = nv->value; | |
200 | ||
201 | ret = true; | |
202 | goto end; | |
203 | ||
204 | error: | |
205 | ret = false; | |
206 | ||
207 | end: | |
208 | return ret; | |
209 | } | |
210 | ||
7e8f2e9c JG |
211 | int loglevel_name_to_value(const char *name, enum lttng_loglevel *loglevel) |
212 | { | |
28ab034a | 213 | int ret = lookup_value_from_name(loglevel_values, ARRAY_SIZE(loglevel_values), name); |
7e8f2e9c JG |
214 | |
215 | if (ret >= 0) { | |
216 | *loglevel = (typeof(*loglevel)) ret; | |
217 | ret = 0; | |
218 | } | |
219 | ||
220 | return ret; | |
221 | } | |
222 | ||
949f049b | 223 | bool loglevel_parse_range_string(const char *str, |
28ab034a JG |
224 | enum lttng_loglevel *min, |
225 | enum lttng_loglevel *max) | |
949f049b SM |
226 | { |
227 | int min_int, max_int; | |
28ab034a JG |
228 | bool ret = loglevel_parse_range_string_common( |
229 | str, loglevel_values, ARRAY_SIZE(loglevel_values), &min_int, &max_int); | |
949f049b | 230 | |
48a40005 SM |
231 | *min = (lttng_loglevel) min_int; |
232 | *max = (lttng_loglevel) max_int; | |
949f049b SM |
233 | |
234 | return ret; | |
235 | } | |
236 | ||
28ab034a | 237 | int loglevel_log4j_name_to_value(const char *name, enum lttng_loglevel_log4j *loglevel) |
7e8f2e9c | 238 | { |
28ab034a JG |
239 | int ret = lookup_value_from_name( |
240 | loglevel_log4j_values, ARRAY_SIZE(loglevel_log4j_values), name); | |
7e8f2e9c JG |
241 | |
242 | if (ret >= 0) { | |
243 | *loglevel = (typeof(*loglevel)) ret; | |
244 | ret = 0; | |
245 | } | |
246 | ||
247 | return ret; | |
248 | } | |
249 | ||
949f049b | 250 | bool loglevel_log4j_parse_range_string(const char *str, |
28ab034a JG |
251 | enum lttng_loglevel_log4j *min, |
252 | enum lttng_loglevel_log4j *max) | |
949f049b SM |
253 | { |
254 | int min_int, max_int; | |
28ab034a JG |
255 | bool ret = loglevel_parse_range_string_common( |
256 | str, loglevel_log4j_values, ARRAY_SIZE(loglevel_log4j_values), &min_int, &max_int); | |
949f049b | 257 | |
48a40005 SM |
258 | *min = (lttng_loglevel_log4j) min_int; |
259 | *max = (lttng_loglevel_log4j) max_int; | |
949f049b SM |
260 | |
261 | return ret; | |
262 | } | |
263 | ||
28ab034a | 264 | int loglevel_jul_name_to_value(const char *name, enum lttng_loglevel_jul *loglevel) |
7e8f2e9c | 265 | { |
28ab034a JG |
266 | int ret = |
267 | lookup_value_from_name(loglevel_jul_values, ARRAY_SIZE(loglevel_jul_values), name); | |
7e8f2e9c JG |
268 | |
269 | if (ret >= 0) { | |
270 | *loglevel = (typeof(*loglevel)) ret; | |
271 | ret = 0; | |
272 | } | |
273 | ||
274 | return ret; | |
275 | } | |
276 | ||
949f049b | 277 | bool loglevel_jul_parse_range_string(const char *str, |
28ab034a JG |
278 | enum lttng_loglevel_jul *min, |
279 | enum lttng_loglevel_jul *max) | |
949f049b SM |
280 | { |
281 | int min_int, max_int; | |
28ab034a JG |
282 | bool ret = loglevel_parse_range_string_common( |
283 | str, loglevel_jul_values, ARRAY_SIZE(loglevel_jul_values), &min_int, &max_int); | |
949f049b | 284 | |
48a40005 SM |
285 | *min = (lttng_loglevel_jul) min_int; |
286 | *max = (lttng_loglevel_jul) max_int; | |
949f049b SM |
287 | |
288 | return ret; | |
289 | } | |
290 | ||
28ab034a | 291 | int loglevel_python_name_to_value(const char *name, enum lttng_loglevel_python *loglevel) |
7e8f2e9c | 292 | { |
28ab034a JG |
293 | int ret = lookup_value_from_name( |
294 | loglevel_python_values, ARRAY_SIZE(loglevel_python_values), name); | |
7e8f2e9c JG |
295 | |
296 | if (ret >= 0) { | |
297 | *loglevel = (typeof(*loglevel)) ret; | |
298 | ret = 0; | |
299 | } | |
300 | ||
949f049b SM |
301 | return ret; |
302 | } | |
303 | ||
949f049b | 304 | bool loglevel_python_parse_range_string(const char *str, |
28ab034a JG |
305 | enum lttng_loglevel_python *min, |
306 | enum lttng_loglevel_python *max) | |
949f049b SM |
307 | { |
308 | int min_int, max_int; | |
309 | bool ret = loglevel_parse_range_string_common(str, | |
28ab034a JG |
310 | loglevel_python_values, |
311 | ARRAY_SIZE(loglevel_python_values), | |
312 | &min_int, | |
313 | &max_int); | |
949f049b | 314 | |
48a40005 SM |
315 | *min = (lttng_loglevel_python) min_int; |
316 | *max = (lttng_loglevel_python) max_int; | |
949f049b | 317 | |
7e8f2e9c | 318 | return ret; |
00608d5a | 319 | } |
85b05318 | 320 | |
28ab034a JG |
321 | static const char * |
322 | lookup_name_from_value(const struct loglevel_name_value values[], size_t values_count, int loglevel) | |
85b05318 JR |
323 | { |
324 | size_t i; | |
cd9adb8b | 325 | const char *name = nullptr; |
85b05318 JR |
326 | |
327 | for (i = 0; i < values_count; i++) { | |
328 | if (values[i].value == loglevel) { | |
329 | /* Match found. */ | |
330 | name = values[i].name; | |
331 | goto end; | |
332 | } | |
333 | } | |
334 | ||
335 | end: | |
336 | return name; | |
337 | } | |
338 | ||
85b05318 JR |
339 | const char *loglevel_value_to_name(int loglevel) |
340 | { | |
28ab034a | 341 | return lookup_name_from_value(loglevel_values, ARRAY_SIZE(loglevel_values), loglevel); |
85b05318 JR |
342 | } |
343 | ||
85b05318 JR |
344 | const char *loglevel_log4j_value_to_name(int loglevel) |
345 | { | |
28ab034a JG |
346 | return lookup_name_from_value( |
347 | loglevel_log4j_values, ARRAY_SIZE(loglevel_log4j_values), loglevel); | |
85b05318 JR |
348 | } |
349 | ||
85b05318 JR |
350 | const char *loglevel_jul_value_to_name(int loglevel) |
351 | { | |
28ab034a JG |
352 | return lookup_name_from_value( |
353 | loglevel_jul_values, ARRAY_SIZE(loglevel_jul_values), loglevel); | |
85b05318 JR |
354 | } |
355 | ||
85b05318 JR |
356 | const char *loglevel_python_value_to_name(int loglevel) |
357 | { | |
28ab034a JG |
358 | return lookup_name_from_value( |
359 | loglevel_python_values, ARRAY_SIZE(loglevel_python_values), loglevel); | |
85b05318 | 360 | } |