diff options
Diffstat (limited to 'libmisc/tests/test_macro.c')
-rw-r--r-- | libmisc/tests/test_macro.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/libmisc/tests/test_macro.c b/libmisc/tests/test_macro.c index 1320eb3..39a8b40 100644 --- a/libmisc/tests/test_macro.c +++ b/libmisc/tests/test_macro.c @@ -4,10 +4,34 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +#include <stdlib.h> /* for free() */ +#include <string.h> /* for strcmp(), strlen(), memcmp(), strdup() */ + #include <libmisc/macro.h> #include "test.h" +/** Given `N` from `#define _LM_EVAL _LM_EVAL__{N}`, UNDER is `(N*2)-2`. (16*2)-2=30. */ +#define UNDER 30 +/** Given `N` from `#define _LM_EVAL _LM_EVAL__{N}`, OVER is `(N*2)-1`. (16*2)-1=31. */ +#define OVER 31 + +/** XUNDER is 0 through `UNDER` inclusive. */ +#define XUNDER \ + X(0) X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) \ + X(16) X(17) X(18) X(19) X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) X(29) X(30) +/** XUNDER is 0 through `OVER` inclusive. */ +#define XOVER XUNDER X(OVER) + +static char *without_spaces(const char *in) { + char *out = strdup(in); + for (size_t i = 0; out[i]; i++) + while (out[i] == ' ') + for (size_t j = i; out[j]; j++) + out[j] = out[j+1]; + return out; +} + int main() { printf("== LM_NEXT_POWER_OF_2 =====================================\n"); /* valid down to 0. */ @@ -50,5 +74,61 @@ int main() { /* ... */ test_assert(LM_FLOORLOG2(0xFFFFFFFFFFFFFFFF) == 63); + printf("== LM_TUPLE ===============================================\n"); + test_assert(LM_IF(LM_IS_TUPLE( 9 ))(0)(1)); + test_assert(LM_IF(LM_IS_TUPLE( a ))(0)(1)); + test_assert(LM_IF(LM_IS_TUPLE( () ))(1)(0)); + test_assert(LM_IF(LM_IS_TUPLE( (9) ))(1)(0)); + test_assert(LM_IF(LM_IS_TUPLE( (a) ))(1)(0)); + test_assert(LM_IF(LM_IS_TUPLE( (a, b) ))(1)(0)); + + printf("== LM_TUPLES ==============================================\n"); + test_assert(LM_IF(LM_TUPLES_IS_NONEMPTY( ))(0)(1)); + test_assert(LM_IF(LM_TUPLES_IS_NONEMPTY( () ))(1)(0)); + test_assert(LM_IF(LM_TUPLES_IS_NONEMPTY( (a) ))(1)(0)); + test_assert(LM_IF(LM_TUPLES_IS_NONEMPTY( (a)(b) ))(1)(0)); + test_assert(LM_IF(LM_TUPLES_IS_NONEMPTY( (a)(b)(c) ))(1)(0)); + + printf("== LM_FOREACH_TUPLE =======================================\n"); + /* Basic test. */ + { + #define FN(a, b) a "-" b + const char *str = LM_FOREACH_TUPLE( ("a") ("b") ("c"), FN, " "); + #undef FN + test_assert(strcmp(str, " -a -b -c") == 0); + } + + /* Test that it works with the documented limit of tuples. */ + { + #define X(n) (n) + #define FN(n) #n "\n" + const char *str = LM_FOREACH_TUPLE(XUNDER, FN); + #undef FN + #undef X + #define X(n) #n "\n" + test_assert(strcmp(str, XUNDER) == 0); + #undef X + } + + /* Test that it breaks at documented_limit+1 tuples. */ + { + #define X(n) (n) + #define FN(n) n + const char *str = LM_STR_(LM_FOREACH_TUPLE(XOVER, FN)); + #undef FN + #undef X + /* This comparison is a little extra complicated in + * order to not be sensitive to whitespace in the + * suffix. */ + #define X(n) #n " " + const char *exp_prefix = XUNDER; + #undef X + const char *exp_suffix = "FN(" LM_STR_(OVER) ")_LM_FOREACH_TUPLE_indirect()(,FN,)"; + test_assert(strlen(exp_prefix) < strlen(str) && memcmp(exp_prefix, str, strlen(exp_prefix)) == 0); + char *act_suffix = without_spaces(&str[strlen(exp_prefix)]); + test_assert(strcmp(act_suffix, exp_suffix) == 0); + free(act_suffix); + } + return 0; } |