lttng: move log level name to numerical value conversions to a common util
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 27 Aug 2020 19:16:29 +0000 (15:16 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 12 Feb 2021 05:11:20 +0000 (00:11 -0500)
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 <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I3f655bed6cd5b12cae1e93421f9d1c41ab1b6247

src/bin/lttng/Makefile.am
src/bin/lttng/commands/enable_events.c
src/bin/lttng/loglevel.c [new file with mode: 0644]
src/bin/lttng/loglevel.h [new file with mode: 0644]

index a6bd7a9d738372bc5b4f86b5a24add072d24b7d4..5c0356276f21ce8f9dabcb53da4af59bf52e5ce9 100644 (file)
@@ -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)
 
index f41dc9ecac7424e0a4edc458a982f00353646c95..4b37a01aafa40e6a55dc3b45ab0dc914895fb6cd 100644 (file)
 /* Mi dependancy */
 #include <common/mi-lttng.h>
 
+#include <lttng/event-internal.h>
+
 #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 (file)
index 0000000..e59c248
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+#include "loglevel.h"
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#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 (file)
index 0000000..100d332
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+#ifndef _LTTNG_LOGLEVEL_UTILS_H
+#define _LTTNG_LOGLEVEL_UTILS_H
+
+#include <lttng/lttng.h>
+#include <common/macros.h>
+
+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 */
This page took 0.046506 seconds and 4 git commands to generate.