Simplify the ctype unit tests to allow combining specification strings in any order and no longer require repeating class names. Changes since v1: * Added checks to guard string length calculation using sizeof. * Kept the definition string in the error output. * Added patches 2 and 3 with further cosmetic changes. * Dropped the last patch with the huge output for now, as it needs further thought. t-ctype: allow NUL anywhere in the specification string t-ctype: simplify EOF check t-ctype: align output of i t-ctype: avoid duplicating class names t/unit-tests/t-ctype.c | 81 ++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 54 deletions(-) Range-Diff gegen v1: 1: ae9b5468db ! 1: 28fba8bda9 t-ctype: allow NUL anywhere in the specification string @@ Commit message if we ever want to support more character classes that contain it. Getting the string size using sizeof only works in a macro and with a - string constant, but that's exactly what we have and I don't see it - changing anytime soon. + string constant. Use ARRAY_SIZE and compile-time checks to make sure we + are not passed a string pointer. ## t/unit-tests/t-ctype.c ## @@ @@ t/unit-tests/t-ctype.c /* Macro to test a character type */ #define TEST_CTYPE_FUNC(func, string) \ static void test_ctype_##func(void) { \ ++ size_t len = ARRAY_SIZE(string) - 1 + \ ++ BUILD_ASSERT_OR_ZERO(ARRAY_SIZE(string) > 0) + \ ++ BUILD_ASSERT_OR_ZERO(sizeof(string[0]) == sizeof(char)); \ for (int i = 0; i < 256; i++) { \ - if (!check_int(func(i), ==, is_in(string, i))) \ -+ int expect = !!memchr(string, i, sizeof(string) - 1); \ -+ if (!check_int(func(i), ==, expect)) \ ++ if (!check_int(func(i), ==, !!memchr(string, i, len))) \ test_msg(" i: 0x%02x", i); \ } \ if (!check(!func(EOF))) \ -: ---------- > 2: 1eab0d289c t-ctype: simplify EOF check -: ---------- > 3: 901312e980 t-ctype: align output of i 2: 688e6b6cb5 ! 4: 5dac51cfeb t-ctype: avoid duplicating class names @@ t/unit-tests/t-ctype.c -/* Macro to test a character type */ -#define TEST_CTYPE_FUNC(func, string) \ -static void test_ctype_##func(void) { \ -- for (int i = 0; i < 256; i++) { \ -- int expect = !!memchr(string, i, sizeof(string) - 1); \ -- if (!check_int(func(i), ==, expect)) \ -- test_msg(" i: 0x%02x", i); \ -- } \ -- if (!check(!func(EOF))) \ +#define TEST_CHAR_CLASS(class, string) do { \ + size_t len = ARRAY_SIZE(string) - 1 + \ + BUILD_ASSERT_OR_ZERO(ARRAY_SIZE(string) > 0) + \ + BUILD_ASSERT_OR_ZERO(sizeof(string[0]) == sizeof(char)); \ +- for (int i = 0; i < 256; i++) { \ +- if (!check_int(func(i), ==, !!memchr(string, i, len))) \ +- test_msg(" i: 0x%02x", i); \ + int skip = test__run_begin(); \ + if (!skip) { \ + for (int i = 0; i < 256; i++) { \ -+ int expect = !!memchr(string, i, sizeof(string) - 1); \ -+ if (!check_int(class(i), ==, expect)) \ -+ test_msg(" i: 0x%02x", i); \ ++ if (!check_int(class(i), ==, !!memchr(string, i, len)))\ ++ test_msg(" i: 0x%02x", i); \ + } \ -+ if (!check(!class(EOF))) \ - test_msg(" i: 0x%02x (EOF)", EOF); \ ++ check(!class(EOF)); \ + } \ +- check(!func(EOF)); \ -} - -#define TEST_CHAR_CLASS(class) TEST(test_ctype_##class(), #class " works") -+ } \ + test__run_end(!skip, TEST_LOCATION(), #class " works"); \ +} while (0) 3: caf2acbd09 < -: ---------- t-ctype: do one test per class and char -- 2.44.0