From: Jérémie Galarneau Date: Thu, 27 Aug 2020 19:16:29 +0000 (-0400) Subject: lttng: move log level name to numerical value conversions to a common util X-Git-Tag: v2.13.0-rc1~329 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=7e8f2e9cce651c81094a864bbffefcaa4bcc7a51;p=lttng-tools.git lttng: move log level name to numerical value conversions to a common util Move the utils used by the `enable-event` command to convert log level names (textual) to their values (entries in their respective enums). Since these utils will be used by other commands in the future, the code is cleaned-up, notably to maintain type-safety by returning specific enums rather than casting to `int`. Signed-off-by: Jonathan Rajotte Signed-off-by: Jérémie Galarneau Change-Id: I3f655bed6cd5b12cae1e93421f9d1c41ab1b6247 --- diff --git a/src/bin/lttng/Makefile.am b/src/bin/lttng/Makefile.am index a6bd7a9d7..5c0356276 100644 --- a/src/bin/lttng/Makefile.am +++ b/src/bin/lttng/Makefile.am @@ -29,7 +29,9 @@ lttng_SOURCES = command.h conf.c conf.h commands/start.c \ commands/enable_rotation.c \ commands/disable_rotation.c \ commands/clear.c \ - utils.c utils.h lttng.c + loglevel.c loglevel.h \ + utils.c utils.h \ + lttng.c lttng_CFLAGS = $(AM_CFLAGS) $(POPT_CFLAGS) diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c index f41dc9eca..4b37a01aa 100644 --- a/src/bin/lttng/commands/enable_events.c +++ b/src/bin/lttng/commands/enable_events.c @@ -26,7 +26,10 @@ /* Mi dependancy */ #include +#include + #include "../command.h" +#include "../loglevel.h" #if (LTTNG_SYMBOL_NAME_LEN == 256) #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255" @@ -561,190 +564,6 @@ end: return ret; } -/* - * Maps LOG4j loglevel from string to value - */ -static int loglevel_log4j_str_to_value(const char *inputstr) -{ - int i = 0; - char str[LTTNG_SYMBOL_NAME_LEN]; - - if (!inputstr || strlen(inputstr) == 0) { - return -1; - } - - /* - * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is - * added at the end of the loop so a the upper bound we avoid the overflow. - */ - while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') { - str[i] = toupper(inputstr[i]); - i++; - } - str[i] = '\0'; - - if (!strcmp(str, "LOG4J_OFF") || !strcmp(str, "OFF")) { - return LTTNG_LOGLEVEL_LOG4J_OFF; - } else if (!strcmp(str, "LOG4J_FATAL") || !strcmp(str, "FATAL")) { - return LTTNG_LOGLEVEL_LOG4J_FATAL; - } else if (!strcmp(str, "LOG4J_ERROR") || !strcmp(str, "ERROR")) { - return LTTNG_LOGLEVEL_LOG4J_ERROR; - } else if (!strcmp(str, "LOG4J_WARN") || !strcmp(str, "WARN")) { - return LTTNG_LOGLEVEL_LOG4J_WARN; - } else if (!strcmp(str, "LOG4J_INFO") || !strcmp(str, "INFO")) { - return LTTNG_LOGLEVEL_LOG4J_INFO; - } else if (!strcmp(str, "LOG4J_DEBUG") || !strcmp(str, "DEBUG")) { - return LTTNG_LOGLEVEL_LOG4J_DEBUG; - } else if (!strcmp(str, "LOG4J_TRACE") || !strcmp(str, "TRACE")) { - return LTTNG_LOGLEVEL_LOG4J_TRACE; - } else if (!strcmp(str, "LOG4J_ALL") || !strcmp(str, "ALL")) { - return LTTNG_LOGLEVEL_LOG4J_ALL; - } else { - return -1; - } -} - -/* - * Maps JUL loglevel from string to value - */ -static int loglevel_jul_str_to_value(const char *inputstr) -{ - int i = 0; - char str[LTTNG_SYMBOL_NAME_LEN]; - - if (!inputstr || strlen(inputstr) == 0) { - return -1; - } - - /* - * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is - * added at the end of the loop so a the upper bound we avoid the overflow. - */ - while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') { - str[i] = toupper(inputstr[i]); - i++; - } - str[i] = '\0'; - - if (!strcmp(str, "JUL_OFF") || !strcmp(str, "OFF")) { - return LTTNG_LOGLEVEL_JUL_OFF; - } else if (!strcmp(str, "JUL_SEVERE") || !strcmp(str, "SEVERE")) { - return LTTNG_LOGLEVEL_JUL_SEVERE; - } else if (!strcmp(str, "JUL_WARNING") || !strcmp(str, "WARNING")) { - return LTTNG_LOGLEVEL_JUL_WARNING; - } else if (!strcmp(str, "JUL_INFO") || !strcmp(str, "INFO")) { - return LTTNG_LOGLEVEL_JUL_INFO; - } else if (!strcmp(str, "JUL_CONFIG") || !strcmp(str, "CONFIG")) { - return LTTNG_LOGLEVEL_JUL_CONFIG; - } else if (!strcmp(str, "JUL_FINE") || !strcmp(str, "FINE")) { - return LTTNG_LOGLEVEL_JUL_FINE; - } else if (!strcmp(str, "JUL_FINER") || !strcmp(str, "FINER")) { - return LTTNG_LOGLEVEL_JUL_FINER; - } else if (!strcmp(str, "JUL_FINEST") || !strcmp(str, "FINEST")) { - return LTTNG_LOGLEVEL_JUL_FINEST; - } else if (!strcmp(str, "JUL_ALL") || !strcmp(str, "ALL")) { - return LTTNG_LOGLEVEL_JUL_ALL; - } else { - return -1; - } -} - -/* - * Maps Python loglevel from string to value - */ -static int loglevel_python_str_to_value(const char *inputstr) -{ - int i = 0; - char str[LTTNG_SYMBOL_NAME_LEN]; - - if (!inputstr || strlen(inputstr) == 0) { - return -1; - } - - /* - * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is - * added at the end of the loop so a the upper bound we avoid the overflow. - */ - while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') { - str[i] = toupper(inputstr[i]); - i++; - } - str[i] = '\0'; - - if (!strcmp(str, "PYTHON_CRITICAL") || !strcmp(str, "CRITICAL")) { - return LTTNG_LOGLEVEL_PYTHON_CRITICAL; - } else if (!strcmp(str, "PYTHON_ERROR") || !strcmp(str, "ERROR")) { - return LTTNG_LOGLEVEL_PYTHON_ERROR; - } else if (!strcmp(str, "PYTHON_WARNING") || !strcmp(str, "WARNING")) { - return LTTNG_LOGLEVEL_PYTHON_WARNING; - } else if (!strcmp(str, "PYTHON_INFO") || !strcmp(str, "INFO")) { - return LTTNG_LOGLEVEL_PYTHON_INFO; - } else if (!strcmp(str, "PYTNON_DEBUG") || !strcmp(str, "DEBUG")) { - return LTTNG_LOGLEVEL_PYTHON_DEBUG; - } else if (!strcmp(str, "PYTHON_NOTSET") || !strcmp(str, "NOTSET")) { - return LTTNG_LOGLEVEL_PYTHON_NOTSET; - } else { - return -1; - } -} - -/* - * Maps loglevel from string to value - */ -static -int loglevel_str_to_value(const char *inputstr) -{ - int i = 0; - char str[LTTNG_SYMBOL_NAME_LEN]; - - if (!inputstr || strlen(inputstr) == 0) { - return -1; - } - - /* - * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is - * added at the end of the loop so a the upper bound we avoid the overflow. - */ - while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') { - str[i] = toupper(inputstr[i]); - i++; - } - str[i] = '\0'; - if (!strcmp(str, "TRACE_EMERG") || !strcmp(str, "EMERG")) { - return LTTNG_LOGLEVEL_EMERG; - } else if (!strcmp(str, "TRACE_ALERT") || !strcmp(str, "ALERT")) { - return LTTNG_LOGLEVEL_ALERT; - } else if (!strcmp(str, "TRACE_CRIT") || !strcmp(str, "CRIT")) { - return LTTNG_LOGLEVEL_CRIT; - } else if (!strcmp(str, "TRACE_ERR") || !strcmp(str, "ERR")) { - return LTTNG_LOGLEVEL_ERR; - } else if (!strcmp(str, "TRACE_WARNING") || !strcmp(str, "WARNING")) { - return LTTNG_LOGLEVEL_WARNING; - } else if (!strcmp(str, "TRACE_NOTICE") || !strcmp(str, "NOTICE")) { - return LTTNG_LOGLEVEL_NOTICE; - } else if (!strcmp(str, "TRACE_INFO") || !strcmp(str, "INFO")) { - return LTTNG_LOGLEVEL_INFO; - } else if (!strcmp(str, "TRACE_DEBUG_SYSTEM") || !strcmp(str, "DEBUG_SYSTEM") || !strcmp(str, "SYSTEM")) { - return LTTNG_LOGLEVEL_DEBUG_SYSTEM; - } else if (!strcmp(str, "TRACE_DEBUG_PROGRAM") || !strcmp(str, "DEBUG_PROGRAM") || !strcmp(str, "PROGRAM")) { - return LTTNG_LOGLEVEL_DEBUG_PROGRAM; - } else if (!strcmp(str, "TRACE_DEBUG_PROCESS") || !strcmp(str, "DEBUG_PROCESS") || !strcmp(str, "PROCESS")) { - return LTTNG_LOGLEVEL_DEBUG_PROCESS; - } else if (!strcmp(str, "TRACE_DEBUG_MODULE") || !strcmp(str, "DEBUG_MODULE") || !strcmp(str, "MODULE")) { - return LTTNG_LOGLEVEL_DEBUG_MODULE; - } else if (!strcmp(str, "TRACE_DEBUG_UNIT") || !strcmp(str, "DEBUG_UNIT") || !strcmp(str, "UNIT")) { - return LTTNG_LOGLEVEL_DEBUG_UNIT; - } else if (!strcmp(str, "TRACE_DEBUG_FUNCTION") || !strcmp(str, "DEBUG_FUNCTION") || !strcmp(str, "FUNCTION")) { - return LTTNG_LOGLEVEL_DEBUG_FUNCTION; - } else if (!strcmp(str, "TRACE_DEBUG_LINE") || !strcmp(str, "DEBUG_LINE") || !strcmp(str, "LINE")) { - return LTTNG_LOGLEVEL_DEBUG_LINE; - } else if (!strcmp(str, "TRACE_DEBUG") || !strcmp(str, "DEBUG")) { - return LTTNG_LOGLEVEL_DEBUG; - } else { - return -1; - } -} - static const char *print_channel_name(const char *name) { @@ -1081,17 +900,33 @@ static int enable_events(char *session_name) strcpy(ev->name, "*"); ev->loglevel_type = opt_loglevel_type; if (opt_loglevel) { + int name_search_ret; + assert(opt_userspace || opt_jul || opt_log4j || opt_python); + if (opt_userspace) { - ev->loglevel = loglevel_str_to_value(opt_loglevel); + enum lttng_loglevel loglevel; + + name_search_ret = loglevel_name_to_value(opt_loglevel, &loglevel); + ev->loglevel = (int) loglevel; } else if (opt_jul) { - ev->loglevel = loglevel_jul_str_to_value(opt_loglevel); + enum lttng_loglevel_jul loglevel; + + name_search_ret = loglevel_jul_name_to_value(opt_loglevel, &loglevel); + ev->loglevel = (int) loglevel; } else if (opt_log4j) { - ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel); + enum lttng_loglevel_log4j loglevel; + + name_search_ret = loglevel_log4j_name_to_value(opt_loglevel, &loglevel); + ev->loglevel = (int) loglevel; } else if (opt_python) { - ev->loglevel = loglevel_python_str_to_value(opt_loglevel); + enum lttng_loglevel_python loglevel; + + name_search_ret = loglevel_python_name_to_value(opt_loglevel, &loglevel); + ev->loglevel = (int) loglevel; } - if (ev->loglevel == -1) { + + if (name_search_ret == -1) { ERR("Unknown loglevel %s", opt_loglevel); ret = -LTTNG_ERR_INVALID; goto error; @@ -1440,12 +1275,16 @@ static int enable_events(char *session_name) ev->loglevel_type = opt_loglevel_type; if (opt_loglevel) { - ev->loglevel = loglevel_str_to_value(opt_loglevel); - if (ev->loglevel == -1) { + enum lttng_loglevel loglevel; + const int name_search_ret = loglevel_name_to_value(opt_loglevel, &loglevel); + + if (name_search_ret == -1) { ERR("Unknown loglevel %s", opt_loglevel); ret = -LTTNG_ERR_INVALID; goto error; } + + ev->loglevel = (int) loglevel; } else { ev->loglevel = -1; } @@ -1459,14 +1298,26 @@ static int enable_events(char *session_name) ev->loglevel_type = opt_loglevel_type; if (opt_loglevel) { + int name_search_ret; + if (opt_jul) { - ev->loglevel = loglevel_jul_str_to_value(opt_loglevel); + enum lttng_loglevel_jul loglevel; + + name_search_ret = loglevel_jul_name_to_value(opt_loglevel, &loglevel); + ev->loglevel = (int) loglevel; } else if (opt_log4j) { - ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel); + enum lttng_loglevel_log4j loglevel; + + name_search_ret = loglevel_log4j_name_to_value(opt_loglevel, &loglevel); + ev->loglevel = (int) loglevel; } else if (opt_python) { - ev->loglevel = loglevel_python_str_to_value(opt_loglevel); + enum lttng_loglevel_python loglevel; + + name_search_ret = loglevel_python_name_to_value(opt_loglevel, &loglevel); + ev->loglevel = (int) loglevel; } - if (ev->loglevel == -1) { + + if (name_search_ret) { ERR("Unknown loglevel %s", opt_loglevel); ret = -LTTNG_ERR_INVALID; goto error; diff --git a/src/bin/lttng/loglevel.c b/src/bin/lttng/loglevel.c new file mode 100644 index 000000000..e59c24813 --- /dev/null +++ b/src/bin/lttng/loglevel.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2021 Jérémie Galarneau + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#include "loglevel.h" +#include +#include +#include + +#define LOGLEVEL_NAME_VALUE_ARRAY_COUNT(name) (sizeof(name) / sizeof(struct loglevel_name_value)) + +struct loglevel_name_value { + const char *name; + int value; +}; + +static +const struct loglevel_name_value loglevel_values[] = { + { .name = "TRACE_EMERG", .value = LTTNG_LOGLEVEL_EMERG }, + { .name = "EMERG", .value = LTTNG_LOGLEVEL_EMERG }, + { .name = "TRACE_ALERT", .value = LTTNG_LOGLEVEL_ALERT }, + { .name = "ALERT", .value = LTTNG_LOGLEVEL_ALERT }, + { .name = "TRACE_CRIT", .value = LTTNG_LOGLEVEL_CRIT }, + { .name = "CRIT", .value = LTTNG_LOGLEVEL_CRIT }, + { .name = "TRACE_ERR", .value = LTTNG_LOGLEVEL_ERR }, + { .name = "ERR", .value = LTTNG_LOGLEVEL_ERR }, + { .name = "TRACE_WARNING", .value = LTTNG_LOGLEVEL_WARNING }, + { .name = "WARNING", .value = LTTNG_LOGLEVEL_WARNING }, + { .name = "TRACE_NOTICE", .value = LTTNG_LOGLEVEL_NOTICE }, + { .name = "NOTICE", .value = LTTNG_LOGLEVEL_NOTICE }, + { .name = "TRACE_INFO", .value = LTTNG_LOGLEVEL_INFO }, + { .name = "INFO", .value = LTTNG_LOGLEVEL_INFO }, + { .name = "TRACE_DEBUG_SYSTEM", .value = LTTNG_LOGLEVEL_DEBUG_SYSTEM }, + { .name = "DEBUG_SYSTEM", .value = LTTNG_LOGLEVEL_DEBUG_SYSTEM }, + { .name = "SYSTEM", .value = LTTNG_LOGLEVEL_DEBUG_SYSTEM }, + { .name = "TRACE_DEBUG_PROGRAM", .value = LTTNG_LOGLEVEL_DEBUG_PROGRAM }, + { .name = "DEBUG_PROGRAM", .value = LTTNG_LOGLEVEL_DEBUG_PROGRAM }, + { .name = "PROGRAM", .value = LTTNG_LOGLEVEL_DEBUG_PROGRAM }, + { .name = "TRACE_DEBUG_PROCESS", .value = LTTNG_LOGLEVEL_DEBUG_PROCESS }, + { .name = "DEBUG_PROCESS", .value = LTTNG_LOGLEVEL_DEBUG_PROCESS }, + { .name = "PROCESS", .value = LTTNG_LOGLEVEL_DEBUG_PROCESS }, + { .name = "TRACE_DEBUG_MODULE", .value = LTTNG_LOGLEVEL_DEBUG_MODULE }, + { .name = "DEBUG_MODULE", .value = LTTNG_LOGLEVEL_DEBUG_MODULE }, + { .name = "MODULE", .value = LTTNG_LOGLEVEL_DEBUG_MODULE }, + { .name = "TRACE_DEBUG_UNIT", .value = LTTNG_LOGLEVEL_DEBUG_UNIT }, + { .name = "DEBUG_UNIT", .value = LTTNG_LOGLEVEL_DEBUG_UNIT }, + { .name = "UNIT", .value = LTTNG_LOGLEVEL_DEBUG_UNIT }, + { .name = "TRACE_DEBUG_FUNCTION", .value = LTTNG_LOGLEVEL_DEBUG_FUNCTION }, + { .name = "DEBUG_FUNCTION", .value = LTTNG_LOGLEVEL_DEBUG_FUNCTION }, + { .name = "FUNCTION", .value = LTTNG_LOGLEVEL_DEBUG_FUNCTION }, + { .name = "TRACE_DEBUG_LINE", .value = LTTNG_LOGLEVEL_DEBUG_LINE }, + { .name = "DEBUG_LINE", .value = LTTNG_LOGLEVEL_DEBUG_LINE }, + { .name = "LINE", .value = LTTNG_LOGLEVEL_DEBUG_LINE }, + { .name = "TRACE_DEBUG", .value = LTTNG_LOGLEVEL_DEBUG }, + { .name = "DEBUG", .value = LTTNG_LOGLEVEL_DEBUG }, +}; + +static +const struct loglevel_name_value loglevel_log4j_values[] = { + { .name = "LOG4J_OFF", .value = LTTNG_LOGLEVEL_LOG4J_OFF }, + { .name = "OFF", .value = LTTNG_LOGLEVEL_LOG4J_OFF }, + { .name = "LOG4J_FATAL", .value = LTTNG_LOGLEVEL_LOG4J_FATAL }, + { .name = "FATAL", .value = LTTNG_LOGLEVEL_LOG4J_FATAL }, + { .name = "LOG4J_ERROR", .value = LTTNG_LOGLEVEL_LOG4J_ERROR }, + { .name = "ERROR", .value = LTTNG_LOGLEVEL_LOG4J_ERROR }, + { .name = "LOG4J_WARN", .value = LTTNG_LOGLEVEL_LOG4J_WARN }, + { .name = "WARN", .value = LTTNG_LOGLEVEL_LOG4J_WARN }, + { .name = "LOG4J_INFO", .value = LTTNG_LOGLEVEL_LOG4J_INFO }, + { .name = "INFO", .value = LTTNG_LOGLEVEL_LOG4J_INFO }, + { .name = "LOG4J_DEBUG", .value = LTTNG_LOGLEVEL_LOG4J_DEBUG }, + { .name = "DEBUG", .value = LTTNG_LOGLEVEL_LOG4J_DEBUG }, + { .name = "LOG4J_TRACE", .value = LTTNG_LOGLEVEL_LOG4J_TRACE }, + { .name = "TRACE", .value = LTTNG_LOGLEVEL_LOG4J_TRACE }, + { .name = "LOG4J_ALL", .value = LTTNG_LOGLEVEL_LOG4J_ALL }, + { .name = "ALL", .value = LTTNG_LOGLEVEL_LOG4J_ALL }, +}; + +static +const struct loglevel_name_value loglevel_jul_values[] = { + { .name = "JUL_OFF", .value = LTTNG_LOGLEVEL_JUL_OFF }, + { .name = "OFF", .value = LTTNG_LOGLEVEL_JUL_OFF }, + { .name = "JUL_SEVERE", .value = LTTNG_LOGLEVEL_JUL_SEVERE }, + { .name = "SEVERE", .value = LTTNG_LOGLEVEL_JUL_SEVERE }, + { .name = "JUL_WARNING", .value = LTTNG_LOGLEVEL_JUL_WARNING }, + { .name = "WARNING", .value = LTTNG_LOGLEVEL_JUL_WARNING }, + { .name = "JUL_INFO", .value = LTTNG_LOGLEVEL_JUL_INFO }, + { .name = "INFO", .value = LTTNG_LOGLEVEL_JUL_INFO }, + { .name = "JUL_CONFIG", .value = LTTNG_LOGLEVEL_JUL_CONFIG }, + { .name = "CONFIG", .value = LTTNG_LOGLEVEL_JUL_CONFIG }, + { .name = "JUL_FINE", .value = LTTNG_LOGLEVEL_JUL_FINE }, + { .name = "FINE", .value = LTTNG_LOGLEVEL_JUL_FINE }, + { .name = "JUL_FINER", .value = LTTNG_LOGLEVEL_JUL_FINER }, + { .name = "FINER", .value = LTTNG_LOGLEVEL_JUL_FINER }, + { .name = "JUL_FINEST", .value = LTTNG_LOGLEVEL_JUL_FINEST }, + { .name = "FINEST", .value = LTTNG_LOGLEVEL_JUL_FINEST }, + { .name = "JUL_ALL", .value = LTTNG_LOGLEVEL_JUL_ALL }, + { .name = "ALL", .value = LTTNG_LOGLEVEL_JUL_ALL }, +}; + +static +const struct loglevel_name_value loglevel_python_values[] = { + { .name = "PYTHON_CRITICAL", .value = LTTNG_LOGLEVEL_PYTHON_CRITICAL }, + { .name = "CRITICAL", .value = LTTNG_LOGLEVEL_PYTHON_CRITICAL }, + { .name = "PYTHON_ERROR", .value = LTTNG_LOGLEVEL_PYTHON_ERROR }, + { .name = "ERROR", .value = LTTNG_LOGLEVEL_PYTHON_ERROR }, + { .name = "PYTHON_WARNING", .value = LTTNG_LOGLEVEL_PYTHON_WARNING }, + { .name = "WARNING", .value = LTTNG_LOGLEVEL_PYTHON_WARNING }, + { .name = "PYTHON_INFO", .value = LTTNG_LOGLEVEL_PYTHON_INFO }, + { .name = "INFO", .value = LTTNG_LOGLEVEL_PYTHON_INFO }, + { .name = "PYTNON_DEBUG", .value = LTTNG_LOGLEVEL_PYTHON_DEBUG }, + { .name = "DEBUG", .value = LTTNG_LOGLEVEL_PYTHON_DEBUG }, + { .name = "PYTHON_NOTSET", .value = LTTNG_LOGLEVEL_PYTHON_NOTSET }, + { .name = "NOTSET", .value = LTTNG_LOGLEVEL_PYTHON_NOTSET }, +}; + +static +bool string_equal_insensitive(const char *a, const char *b) +{ + bool result; + + assert(a && b); + + while (*a && *b) { + if (toupper(*a) != toupper(*b)) { + result = false; + goto end; + } + + a++; + b++; + } + + /* If a and b don't have the same length, consider them unequal. */ + result = *a == *b; + +end: + return result; +} + +static +int lookup_value_from_name(const struct loglevel_name_value values[], + size_t values_count, const char *name) +{ + size_t i; + int ret = -1; + + if (!name) { + goto end; + } + + for (i = 0; i < values_count; i++) { + if (string_equal_insensitive(values[i].name, name)) { + /* Match found. */ + ret = values[i].value; + goto end; + } + } + +end: + return ret; +} + +LTTNG_HIDDEN +int loglevel_name_to_value(const char *name, enum lttng_loglevel *loglevel) +{ + int ret = lookup_value_from_name(loglevel_values, + LOGLEVEL_NAME_VALUE_ARRAY_COUNT(loglevel_values), name); + + if (ret >= 0) { + *loglevel = (typeof(*loglevel)) ret; + ret = 0; + } + + return ret; +} + +LTTNG_HIDDEN +int loglevel_log4j_name_to_value( + const char *name, enum lttng_loglevel_log4j *loglevel) +{ + int ret = lookup_value_from_name(loglevel_log4j_values, + LOGLEVEL_NAME_VALUE_ARRAY_COUNT(loglevel_log4j_values), + name); + + if (ret >= 0) { + *loglevel = (typeof(*loglevel)) ret; + ret = 0; + } + + return ret; +} + +LTTNG_HIDDEN +int loglevel_jul_name_to_value( + const char *name, enum lttng_loglevel_jul *loglevel) +{ + int ret = lookup_value_from_name(loglevel_jul_values, + LOGLEVEL_NAME_VALUE_ARRAY_COUNT(loglevel_jul_values), + name); + + if (ret >= 0) { + *loglevel = (typeof(*loglevel)) ret; + ret = 0; + } + + return ret; +} + +LTTNG_HIDDEN +int loglevel_python_name_to_value( + const char *name, enum lttng_loglevel_python *loglevel) +{ + int ret = lookup_value_from_name(loglevel_python_values, + LOGLEVEL_NAME_VALUE_ARRAY_COUNT(loglevel_python_values), + name); + + if (ret >= 0) { + *loglevel = (typeof(*loglevel)) ret; + ret = 0; + } + + return ret; +} \ No newline at end of file diff --git a/src/bin/lttng/loglevel.h b/src/bin/lttng/loglevel.h new file mode 100644 index 000000000..100d33267 --- /dev/null +++ b/src/bin/lttng/loglevel.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 Jérémie Galarneau + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#ifndef _LTTNG_LOGLEVEL_UTILS_H +#define _LTTNG_LOGLEVEL_UTILS_H + +#include +#include + +LTTNG_HIDDEN +int loglevel_name_to_value(const char *name, enum lttng_loglevel *loglevel); + +LTTNG_HIDDEN +int loglevel_log4j_name_to_value( + const char *name, enum lttng_loglevel_log4j *loglevel); + +LTTNG_HIDDEN +int loglevel_jul_name_to_value( + const char *name, enum lttng_loglevel_jul *loglevel); + +LTTNG_HIDDEN +int loglevel_python_name_to_value( + const char *name, enum lttng_loglevel_python *loglevel); + +#endif /* _LTTNG_LOGLEVEL_UTILS_H */