Module: Mesa Branch: main Commit: 0e47171abea1afe89c0e368a0a6c8867de69fa68 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0e47171abea1afe89c0e368a0a6c8867de69fa68
Author: Illia Abernikhin <[email protected]> Date: Tue Nov 1 05:59:26 2022 +0800 utils: Move functions from debug.* to u_debug.* Add unit tests for debug_get_bool_option and debug_get_num_option Merge env_var_as_boolean and debug_get_bool_option and implement env_var_as_boolean with debug_get_bool_option in a stricter side. Merge env_var_as_unsigned and debug_get_num_option and implement env_var_as_unsigned with debug_get_num_option in a stricter side. Move debug_control, parse_debug_string, parse_enable_string, comma_separated_list_contains from debug.* to u_debug.* Main changes: os_get_option() is used instead of getenv() for env_var_as_boolean and env_var_as_unsigned; also debug_get_bool_option() has logic like "true" always if not "false"; env_var_as_boolean() now uses different logic: if env variable is neither "true" nor "false" returns the default value, we left the second one; but if you want the behavior to be the same as in the old version of debug_get_bool_option() use dfault=true Signed-off-by: Illia Abernikhin <[email protected]> Reviewed-by: Yonggang Luo <[email protected]> Reviewed-by: Rob Clark <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19336> --- src/util/debug.c | 114 +------------------------------ src/util/debug.h | 16 +---- src/util/meson.build | 1 + src/util/tests/u_debug_test.cpp | 148 ++++++++++++++++++++++++++++++++++++++++ src/util/u_debug.c | 115 ++++++++++++++++++++++++++++--- src/util/u_debug.h | 20 ++++++ 6 files changed, 279 insertions(+), 135 deletions(-) diff --git a/src/util/debug.c b/src/util/debug.c index b7b49ae8974..97ed5cae527 100644 --- a/src/util/debug.c +++ b/src/util/debug.c @@ -24,90 +24,6 @@ #include <errno.h> #include <string.h> #include "debug.h" -#include "u_string.h" - -uint64_t -parse_debug_string(const char *debug, - const struct debug_control *control) -{ - uint64_t flag = 0; - - if (debug != NULL) { - for (; control->string != NULL; control++) { - if (!strcmp(debug, "all")) { - flag |= control->flag; - - } else { - const char *s = debug; - unsigned n; - - for (; n = strcspn(s, ", "), *s; s += MAX2(1, n)) { - if (strlen(control->string) == n && - !strncmp(control->string, s, n)) - flag |= control->flag; - } - } - } - } - - return flag; -} - -uint64_t -parse_enable_string(const char *debug, - uint64_t default_value, - const struct debug_control *control) -{ - uint64_t flag = default_value; - - if (debug != NULL) { - for (; control->string != NULL; control++) { - if (!strcmp(debug, "all")) { - flag |= control->flag; - - } else { - const char *s = debug; - unsigned n; - - for (; n = strcspn(s, ", "), *s; s += MAX2(1, n)) { - bool enable; - if (s[0] == '+') { - enable = true; - s++; n--; - } else if (s[0] == '-') { - enable = false; - s++; n--; - } else { - enable = true; - } - if (strlen(control->string) == n && - !strncmp(control->string, s, n)) { - if (enable) - flag |= control->flag; - else - flag &= ~control->flag; - } - } - } - } - } - - return flag; -} - -bool -comma_separated_list_contains(const char *list, const char *s) -{ - assert(list); - const size_t len = strlen(s); - - for (unsigned n; n = strcspn(list, ","), *list; list += MAX2(1, n)) { - if (n == len && !strncmp(list, s, n)) - return true; - } - - return false; -} /** * Reads an environment variable and interprets its value as a boolean. @@ -117,23 +33,7 @@ comma_separated_list_contains(const char *list, const char *s) bool env_var_as_boolean(const char *var_name, bool default_value) { - const char *str = getenv(var_name); - if (str == NULL) - return default_value; - - if (strcmp(str, "1") == 0 || - strcasecmp(str, "true") == 0 || - strcasecmp(str, "y") == 0 || - strcasecmp(str, "yes") == 0) { - return true; - } else if (strcmp(str, "0") == 0 || - strcasecmp(str, "false") == 0 || - strcasecmp(str, "n") == 0 || - strcasecmp(str, "no") == 0) { - return false; - } else { - return default_value; - } + return debug_get_bool_option(var_name, default_value); } /** @@ -142,15 +42,5 @@ env_var_as_boolean(const char *var_name, bool default_value) unsigned env_var_as_unsigned(const char *var_name, unsigned default_value) { - char *str = getenv(var_name); - if (str) { - char *end; - unsigned long result; - - errno = 0; - result = strtoul(str, &end, 0); - if (errno == 0 && end != str && *end == '\0') - return result; - } - return default_value; + return debug_get_num_option(var_name, default_value); } diff --git a/src/util/debug.h b/src/util/debug.h index 6d48ea08fcf..6c3df5739f5 100644 --- a/src/util/debug.h +++ b/src/util/debug.h @@ -27,24 +27,12 @@ #include <stdint.h> #include <stdbool.h> +#include "u_debug.h" + #ifdef __cplusplus extern "C" { #endif -struct debug_control { - const char * string; - uint64_t flag; -}; - -uint64_t -parse_debug_string(const char *debug, - const struct debug_control *control); -uint64_t -parse_enable_string(const char *debug, - uint64_t default_value, - const struct debug_control *control); -bool -comma_separated_list_contains(const char *list, const char *s); bool env_var_as_boolean(const char *var_name, bool default_value); unsigned diff --git a/src/util/meson.build b/src/util/meson.build index 0666022ae79..3102b41acb2 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -356,6 +356,7 @@ if with_tests 'tests/u_atomic_test.cpp', 'tests/u_call_once_test.cpp', 'tests/u_debug_stack_test.cpp', + 'tests/u_debug_test.cpp', 'tests/u_printf_test.cpp', 'tests/u_qsort_test.cpp', 'tests/vector_test.cpp', diff --git a/src/util/tests/u_debug_test.cpp b/src/util/tests/u_debug_test.cpp new file mode 100644 index 00000000000..7168986a586 --- /dev/null +++ b/src/util/tests/u_debug_test.cpp @@ -0,0 +1,148 @@ +/* + * Copyright © 2022 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * \author Illia Abernikhin <[email protected]> + * + */ + +#include <gtest/gtest.h> +#include "util/u_debug.h" + +/* When testing, the environment variable name should not be the same */ + +TEST(u_debug, debug_get_bool_option) +{ + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_0=10"; + putenv(env_str); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_0", true)); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_0", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_1"; + putenv(env_str); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_1", true)); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_1", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_2=INVALID"; + putenv(env_str); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_2", true)); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_2", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_3=0"; + putenv(env_str); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_3", true)); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_3", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_4=n"; + putenv(env_str); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_4", true)); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_4", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_5=No"; + putenv(env_str); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_5", true)); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_5", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_6=F"; + putenv(env_str); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_6", true)); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_6", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_7=fAlse"; + putenv(env_str); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_7", true)); + EXPECT_FALSE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_7", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_8=1"; + putenv(env_str); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_8", true)); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_8", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_9=Y"; + putenv(env_str); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_9", true)); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_9", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_10=Yes"; + putenv(env_str); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_10", true)); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_10", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_11=t"; + putenv(env_str); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_11", true)); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_11", false)); + } + + { + static char env_str[] = "MESA_UNIT_TEST_BOOL_VARIABLE_12=True"; + putenv(env_str); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_12", true)); + EXPECT_TRUE(debug_get_bool_option("MESA_UNIT_TEST_BOOL_VARIABLE_12", false)); + } +} + +TEST(u_debug, debug_get_num_option) +{ + { + static char env_str[] = "MESA_UNIT_TEST_NUM_VARIABLE_0=101"; + putenv(env_str); + EXPECT_EQ(debug_get_num_option("MESA_UNIT_TEST_NUM_VARIABLE_0", 10), 101); + EXPECT_EQ(debug_get_num_option("MESA_UNIT_TEST_NUM_VARIABLE_0", 0), 101); + } + + { + static char env_str[] = "MESA_UNIT_TEST_NUM_VARIABLE_1"; + putenv(env_str); + EXPECT_EQ(debug_get_num_option("MESA_UNIT_TEST_NUM_VARIABLE_1", 10), 10); + EXPECT_EQ(debug_get_num_option("MESA_UNIT_TEST_NUM_VARIABLE_1", 100), 100); + } + + { + static char env_str[] = "MESA_UNIT_TEST_NUM_VARIABLE_2=something"; + putenv(env_str); + EXPECT_EQ(debug_get_num_option("MESA_UNIT_TEST_NUM_VARIABLE_2", 10), 10); + EXPECT_EQ(debug_get_num_option("MESA_UNIT_TEST_NUM_VARIABLE_2", 100), 100); + } +} diff --git a/src/util/u_debug.c b/src/util/u_debug.c index f017886ebf1..d34b804be0d 100644 --- a/src/util/u_debug.c +++ b/src/util/u_debug.c @@ -154,6 +154,12 @@ debug_get_option(const char *name, const char *dfault) } +/** + * Reads an environment variable and interprets its value as a boolean. + * Recognizes 0/n/no/f/false case insensitive as false. + * Recognizes 1/y/yes/t/true case insensitive as true. + * Other values result in the default value. + */ bool debug_get_bool_option(const char *name, bool dfault) { @@ -162,22 +168,28 @@ debug_get_bool_option(const char *name, bool dfault) if (str == NULL) result = dfault; - else if (!strcmp(str, "n")) - result = false; - else if (!strcmp(str, "no")) - result = false; else if (!strcmp(str, "0")) result = false; - else if (!strcmp(str, "f")) + else if (!strcasecmp(str, "n")) result = false; - else if (!strcmp(str, "F")) + else if (!strcasecmp(str, "no")) result = false; - else if (!strcmp(str, "false")) + else if (!strcasecmp(str, "f")) result = false; - else if (!strcmp(str, "FALSE")) + else if (!strcasecmp(str, "false")) result = false; - else + else if (!strcmp(str, "1")) + result = true; + else if (!strcasecmp(str, "y")) + result = true; + else if (!strcasecmp(str, "yes")) result = true; + else if (!strcasecmp(str, "t")) + result = true; + else if (!strcasecmp(str, "true")) + result = true; + else + result = dfault; if (debug_get_option_should_print()) debug_printf("%s: %s = %s\n", __FUNCTION__, name, @@ -408,6 +420,91 @@ debug_dump_flags(const struct debug_named_value *names, unsigned long value) } +uint64_t +parse_debug_string(const char *debug, + const struct debug_control *control) +{ + uint64_t flag = 0; + + if (debug != NULL) { + for (; control->string != NULL; control++) { + if (!strcmp(debug, "all")) { + flag |= control->flag; + + } else { + const char *s = debug; + unsigned n; + + for (; n = strcspn(s, ", "), *s; s += MAX2(1, n)) { + if (strlen(control->string) == n && + !strncmp(control->string, s, n)) + flag |= control->flag; + } + } + } + } + + return flag; +} + + +uint64_t +parse_enable_string(const char *debug, + uint64_t default_value, + const struct debug_control *control) +{ + uint64_t flag = default_value; + + if (debug != NULL) { + for (; control->string != NULL; control++) { + if (!strcmp(debug, "all")) { + flag |= control->flag; + + } else { + const char *s = debug; + unsigned n; + + for (; n = strcspn(s, ", "), *s; s += MAX2(1, n)) { + bool enable; + if (s[0] == '+') { + enable = true; + s++; n--; + } else if (s[0] == '-') { + enable = false; + s++; n--; + } else { + enable = true; + } + if (strlen(control->string) == n && + !strncmp(control->string, s, n)) { + if (enable) + flag |= control->flag; + else + flag &= ~control->flag; + } + } + } + } + } + + return flag; +} + + +bool +comma_separated_list_contains(const char *list, const char *s) +{ + assert(list); + const size_t len = strlen(s); + + for (unsigned n; n = strcspn(list, ","), *list; list += MAX2(1, n)) { + if (n == len && !strncmp(list, s, n)) + return true; + } + + return false; +} + #ifdef DEBUG int fl_indent = 0; diff --git a/src/util/u_debug.h b/src/util/u_debug.h index 1b91f657092..805d7977686 100644 --- a/src/util/u_debug.h +++ b/src/util/u_debug.h @@ -347,6 +347,26 @@ debug_dump_flags(const struct debug_named_value *names, unsigned long value); +struct debug_control { + const char * string; + uint64_t flag; +}; + +uint64_t +parse_debug_string(const char *debug, + const struct debug_control *control); + + +uint64_t +parse_enable_string(const char *debug, + uint64_t default_value, + const struct debug_control *control); + + +bool +comma_separated_list_contains(const char *list, const char *s); + + /** * Function enter exit loggers */
