Fix: lttng: enable-channel: leak of popt arguments
[lttng-tools.git] / src / bin / lttng / loglevel.cpp
CommitLineData
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"
7e8f2e9c 9#include <string.h>
f41294ed 10#include <strings.h>
7e8f2e9c 11#include <ctype.h>
7e8f2e9c 12
f1494934 13namespace {
7e8f2e9c
JG
14struct loglevel_name_value {
15 const char *name;
16 int value;
17};
f1494934 18} /* namespace */
7e8f2e9c
JG
19
20static
21const 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
61static
62const struct loglevel_name_value loglevel_log4j_values[] = {
7e8f2e9c 63 { .name = "OFF", .value = LTTNG_LOGLEVEL_LOG4J_OFF },
85b05318 64 { .name = "LOG4J_OFF", .value = LTTNG_LOGLEVEL_LOG4J_OFF },
7e8f2e9c 65 { .name = "FATAL", .value = LTTNG_LOGLEVEL_LOG4J_FATAL },
85b05318 66 { .name = "LOG4J_FATAL", .value = LTTNG_LOGLEVEL_LOG4J_FATAL },
7e8f2e9c 67 { .name = "ERROR", .value = LTTNG_LOGLEVEL_LOG4J_ERROR },
85b05318 68 { .name = "LOG4J_ERROR", .value = LTTNG_LOGLEVEL_LOG4J_ERROR },
7e8f2e9c 69 { .name = "WARN", .value = LTTNG_LOGLEVEL_LOG4J_WARN },
85b05318 70 { .name = "LOG4J_WARN", .value = LTTNG_LOGLEVEL_LOG4J_WARN },
7e8f2e9c 71 { .name = "INFO", .value = LTTNG_LOGLEVEL_LOG4J_INFO },
85b05318 72 { .name = "LOG4J_INFO", .value = LTTNG_LOGLEVEL_LOG4J_INFO },
7e8f2e9c 73 { .name = "DEBUG", .value = LTTNG_LOGLEVEL_LOG4J_DEBUG },
85b05318 74 { .name = "LOG4J_DEBUG", .value = LTTNG_LOGLEVEL_LOG4J_DEBUG },
7e8f2e9c 75 { .name = "TRACE", .value = LTTNG_LOGLEVEL_LOG4J_TRACE },
85b05318 76 { .name = "LOG4J_TRACE", .value = LTTNG_LOGLEVEL_LOG4J_TRACE },
7e8f2e9c 77 { .name = "ALL", .value = LTTNG_LOGLEVEL_LOG4J_ALL },
85b05318 78 { .name = "LOG4J_ALL", .value = LTTNG_LOGLEVEL_LOG4J_ALL },
7e8f2e9c
JG
79};
80
81static
82const struct loglevel_name_value loglevel_jul_values[] = {
7e8f2e9c 83 { .name = "OFF", .value = LTTNG_LOGLEVEL_JUL_OFF },
85b05318 84 { .name = "JUL_OFF", .value = LTTNG_LOGLEVEL_JUL_OFF },
7e8f2e9c 85 { .name = "SEVERE", .value = LTTNG_LOGLEVEL_JUL_SEVERE },
85b05318 86 { .name = "JUL_SEVERE", .value = LTTNG_LOGLEVEL_JUL_SEVERE },
7e8f2e9c 87 { .name = "WARNING", .value = LTTNG_LOGLEVEL_JUL_WARNING },
85b05318 88 { .name = "JUL_WARNING", .value = LTTNG_LOGLEVEL_JUL_WARNING },
7e8f2e9c 89 { .name = "INFO", .value = LTTNG_LOGLEVEL_JUL_INFO },
85b05318 90 { .name = "JUL_INFO", .value = LTTNG_LOGLEVEL_JUL_INFO },
7e8f2e9c 91 { .name = "CONFIG", .value = LTTNG_LOGLEVEL_JUL_CONFIG },
85b05318 92 { .name = "JUL_CONFIG", .value = LTTNG_LOGLEVEL_JUL_CONFIG },
7e8f2e9c 93 { .name = "FINE", .value = LTTNG_LOGLEVEL_JUL_FINE },
85b05318 94 { .name = "JUL_FINE", .value = LTTNG_LOGLEVEL_JUL_FINE },
7e8f2e9c 95 { .name = "FINER", .value = LTTNG_LOGLEVEL_JUL_FINER },
85b05318 96 { .name = "JUL_FINER", .value = LTTNG_LOGLEVEL_JUL_FINER },
7e8f2e9c 97 { .name = "FINEST", .value = LTTNG_LOGLEVEL_JUL_FINEST },
85b05318 98 { .name = "JUL_FINEST", .value = LTTNG_LOGLEVEL_JUL_FINEST },
7e8f2e9c 99 { .name = "ALL", .value = LTTNG_LOGLEVEL_JUL_ALL },
85b05318 100 { .name = "JUL_ALL", .value = LTTNG_LOGLEVEL_JUL_ALL },
7e8f2e9c
JG
101};
102
103static
104const struct loglevel_name_value loglevel_python_values[] = {
7e8f2e9c 105 { .name = "CRITICAL", .value = LTTNG_LOGLEVEL_PYTHON_CRITICAL },
85b05318 106 { .name = "PYTHON_CRITICAL", .value = LTTNG_LOGLEVEL_PYTHON_CRITICAL },
7e8f2e9c 107 { .name = "ERROR", .value = LTTNG_LOGLEVEL_PYTHON_ERROR },
85b05318 108 { .name = "PYTHON_ERROR", .value = LTTNG_LOGLEVEL_PYTHON_ERROR },
7e8f2e9c 109 { .name = "WARNING", .value = LTTNG_LOGLEVEL_PYTHON_WARNING },
85b05318 110 { .name = "PYTHON_WARNING", .value = LTTNG_LOGLEVEL_PYTHON_WARNING },
7e8f2e9c 111 { .name = "INFO", .value = LTTNG_LOGLEVEL_PYTHON_INFO },
85b05318 112 { .name = "PYTHON_INFO", .value = LTTNG_LOGLEVEL_PYTHON_INFO },
7e8f2e9c 113 { .name = "DEBUG", .value = LTTNG_LOGLEVEL_PYTHON_DEBUG },
85b05318 114 { .name = "PYTNON_DEBUG", .value = LTTNG_LOGLEVEL_PYTHON_DEBUG },
7e8f2e9c 115 { .name = "NOTSET", .value = LTTNG_LOGLEVEL_PYTHON_NOTSET },
85b05318 116 { .name = "PYTHON_NOTSET", .value = LTTNG_LOGLEVEL_PYTHON_NOTSET },
7e8f2e9c
JG
117};
118
119static
120bool string_equal_insensitive(const char *a, const char *b)
121{
f41294ed 122 return strcasecmp(a, b) == 0;
7e8f2e9c
JG
123}
124
125static
126int lookup_value_from_name(const struct loglevel_name_value values[],
127 size_t values_count, const char *name)
128{
129 size_t i;
130 int ret = -1;
131
132 if (!name) {
133 goto end;
134 }
135
136 for (i = 0; i < values_count; i++) {
137 if (string_equal_insensitive(values[i].name, name)) {
138 /* Match found. */
139 ret = values[i].value;
140 goto end;
141 }
142 }
143
144end:
145 return ret;
146}
147
949f049b
SM
148static bool loglevel_parse_range_string_common(const char *str,
149 const struct loglevel_name_value *nvs,
150 size_t nvs_count,
151 int *min,
152 int *max)
153{
154 bool ret;
155 int i;
156 const struct loglevel_name_value *nv;
157
158 for (i = 0; i < nvs_count; i++) {
159 nv = &nvs[i];
160
161 if (strncmp(str, nv->name, strlen(nv->name)) == 0) {
162 break;
163 }
164 }
165
166 if (i == nvs_count) {
167 goto error;
168 }
169
170 *min = nv->value;
171 str += strlen(nv->name);
172
173 if (*str == '\0') {
174 *max = nv->value;
175 ret = true;
176 goto end;
177 }
178
179 if (strncmp(str, "..", strlen("..")) != 0) {
180 goto error;
181 }
182
183 str += strlen("..");
184
185 if (*str == '\0') {
186 *max = LTTNG_LOGLEVEL_EMERG;
187 ret = true;
188 goto end;
189 }
190
191 for (i = 0; i < nvs_count; i++) {
192 nv = &nvs[i];
193
194 if (strcmp(str, nv->name) == 0) {
195 break;
196 }
197 }
198
199 if (i == nvs_count) {
200 goto error;
201 }
202
203 *max = nv->value;
204
205 ret = true;
206 goto end;
207
208error:
209 ret = false;
210
211end:
212 return ret;
213}
214
7e8f2e9c
JG
215int loglevel_name_to_value(const char *name, enum lttng_loglevel *loglevel)
216{
217 int ret = lookup_value_from_name(loglevel_values,
00608d5a 218 ARRAY_SIZE(loglevel_values), name);
7e8f2e9c
JG
219
220 if (ret >= 0) {
221 *loglevel = (typeof(*loglevel)) ret;
222 ret = 0;
223 }
224
225 return ret;
226}
227
949f049b
SM
228bool loglevel_parse_range_string(const char *str,
229 enum lttng_loglevel *min,
230 enum lttng_loglevel *max)
231{
232 int min_int, max_int;
233 bool ret = loglevel_parse_range_string_common(str, loglevel_values,
234 ARRAY_SIZE(loglevel_values), &min_int, &max_int);
235
48a40005
SM
236 *min = (lttng_loglevel) min_int;
237 *max = (lttng_loglevel) max_int;
949f049b
SM
238
239 return ret;
240}
241
7e8f2e9c
JG
242int loglevel_log4j_name_to_value(
243 const char *name, enum lttng_loglevel_log4j *loglevel)
244{
245 int ret = lookup_value_from_name(loglevel_log4j_values,
00608d5a 246 ARRAY_SIZE(loglevel_log4j_values),
7e8f2e9c
JG
247 name);
248
249 if (ret >= 0) {
250 *loglevel = (typeof(*loglevel)) ret;
251 ret = 0;
252 }
253
254 return ret;
255}
256
949f049b
SM
257bool loglevel_log4j_parse_range_string(const char *str,
258 enum lttng_loglevel_log4j *min,
259 enum lttng_loglevel_log4j *max)
260{
261 int min_int, max_int;
262 bool ret = loglevel_parse_range_string_common(str,
263 loglevel_log4j_values,
264 ARRAY_SIZE(loglevel_log4j_values), &min_int, &max_int);
265
48a40005
SM
266 *min = (lttng_loglevel_log4j) min_int;
267 *max = (lttng_loglevel_log4j) max_int;
949f049b
SM
268
269 return ret;
270}
271
7e8f2e9c
JG
272int loglevel_jul_name_to_value(
273 const char *name, enum lttng_loglevel_jul *loglevel)
274{
275 int ret = lookup_value_from_name(loglevel_jul_values,
00608d5a 276 ARRAY_SIZE(loglevel_jul_values),
7e8f2e9c
JG
277 name);
278
279 if (ret >= 0) {
280 *loglevel = (typeof(*loglevel)) ret;
281 ret = 0;
282 }
283
284 return ret;
285}
286
949f049b
SM
287bool loglevel_jul_parse_range_string(const char *str,
288 enum lttng_loglevel_jul *min,
289 enum lttng_loglevel_jul *max)
290{
291 int min_int, max_int;
292 bool ret = loglevel_parse_range_string_common(str, loglevel_jul_values,
293 ARRAY_SIZE(loglevel_jul_values), &min_int, &max_int);
294
48a40005
SM
295 *min = (lttng_loglevel_jul) min_int;
296 *max = (lttng_loglevel_jul) max_int;
949f049b
SM
297
298 return ret;
299}
300
7e8f2e9c
JG
301int loglevel_python_name_to_value(
302 const char *name, enum lttng_loglevel_python *loglevel)
303{
304 int ret = lookup_value_from_name(loglevel_python_values,
00608d5a 305 ARRAY_SIZE(loglevel_python_values),
7e8f2e9c
JG
306 name);
307
308 if (ret >= 0) {
309 *loglevel = (typeof(*loglevel)) ret;
310 ret = 0;
311 }
312
949f049b
SM
313 return ret;
314}
315
949f049b
SM
316bool loglevel_python_parse_range_string(const char *str,
317 enum lttng_loglevel_python *min,
318 enum lttng_loglevel_python *max)
319{
320 int min_int, max_int;
321 bool ret = loglevel_parse_range_string_common(str,
322 loglevel_python_values,
323 ARRAY_SIZE(loglevel_python_values), &min_int, &max_int);
324
48a40005
SM
325 *min = (lttng_loglevel_python) min_int;
326 *max = (lttng_loglevel_python) max_int;
949f049b 327
7e8f2e9c 328 return ret;
00608d5a 329}
85b05318
JR
330
331static
332const char *lookup_name_from_value(const struct loglevel_name_value values[],
333 size_t values_count, int loglevel)
334{
335 size_t i;
336 const char *name = NULL;
337
338 for (i = 0; i < values_count; i++) {
339 if (values[i].value == loglevel) {
340 /* Match found. */
341 name = values[i].name;
342 goto end;
343 }
344 }
345
346end:
347 return name;
348}
349
85b05318
JR
350const char *loglevel_value_to_name(int loglevel)
351{
352 return lookup_name_from_value(
353 loglevel_values, ARRAY_SIZE(loglevel_values), loglevel);
354}
355
85b05318
JR
356const char *loglevel_log4j_value_to_name(int loglevel)
357{
358 return lookup_name_from_value(loglevel_log4j_values,
359 ARRAY_SIZE(loglevel_log4j_values), loglevel);
360}
361
85b05318
JR
362const char *loglevel_jul_value_to_name(int loglevel)
363{
364 return lookup_name_from_value(loglevel_jul_values,
365 ARRAY_SIZE(loglevel_jul_values), loglevel);
366}
367
85b05318
JR
368const char *loglevel_python_value_to_name(int loglevel)
369{
370 return lookup_name_from_value(loglevel_python_values,
371 ARRAY_SIZE(loglevel_python_values), loglevel);
372}
This page took 0.051867 seconds and 4 git commands to generate.