1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright © 2024 Intel Corporation 4 */ 5 6 #include <kunit/test.h> 7 8 #include "xe_args.h" 9 10 static void call_args_example(struct kunit *test) 11 { 12 #define foo X, Y, Z, Q 13 #define bar COUNT_ARGS(foo) 14 #define buz CALL_ARGS(COUNT_ARGS, foo) 15 16 KUNIT_EXPECT_EQ(test, bar, 1); 17 KUNIT_EXPECT_EQ(test, buz, 4); 18 19 #undef foo 20 #undef bar 21 #undef buz 22 } 23 24 static void drop_first_arg_example(struct kunit *test) 25 { 26 #define foo X, Y, Z, Q 27 #define bar CALL_ARGS(COUNT_ARGS, DROP_FIRST_ARG(foo)) 28 29 KUNIT_EXPECT_EQ(test, bar, 3); 30 31 #undef foo 32 #undef bar 33 } 34 35 static void first_arg_example(struct kunit *test) 36 { 37 int X = 1; 38 39 #define foo X, Y, Z, Q 40 #define bar FIRST_ARG(foo) 41 42 KUNIT_EXPECT_EQ(test, bar, X); 43 KUNIT_EXPECT_STREQ(test, __stringify(bar), "X"); 44 45 #undef foo 46 #undef bar 47 } 48 49 static void last_arg_example(struct kunit *test) 50 { 51 int Q = 1; 52 53 #define foo X, Y, Z, Q 54 #define bar LAST_ARG(foo) 55 56 KUNIT_EXPECT_EQ(test, bar, Q); 57 KUNIT_EXPECT_STREQ(test, __stringify(bar), "Q"); 58 59 #undef foo 60 #undef bar 61 } 62 63 static void pick_arg_example(struct kunit *test) 64 { 65 int Y = 1, Z = 2; 66 67 #define foo X, Y, Z, Q 68 #define bar PICK_ARG(2, foo) 69 #define buz PICK_ARG3(foo) 70 71 KUNIT_EXPECT_EQ(test, bar, Y); 72 KUNIT_EXPECT_STREQ(test, __stringify(bar), "Y"); 73 KUNIT_EXPECT_EQ(test, buz, Z); 74 KUNIT_EXPECT_STREQ(test, __stringify(buz), "Z"); 75 76 #undef foo 77 #undef bar 78 #undef buz 79 } 80 81 static void if_args_example(struct kunit *test) 82 { 83 enum { Z = 1, Q }; 84 85 #define foo X, Y 86 #define bar IF_ARGS(Z, Q, foo) 87 #define buz IF_ARGS(Z, Q, DROP_FIRST_ARG(FIRST_ARG(foo))) 88 89 KUNIT_EXPECT_EQ(test, bar, Z); 90 KUNIT_EXPECT_EQ(test, buz, Q); 91 KUNIT_EXPECT_STREQ(test, __stringify(bar), "Z"); 92 KUNIT_EXPECT_STREQ(test, __stringify(buz), "Q"); 93 94 #undef foo 95 #undef bar 96 #undef buz 97 } 98 99 static void sep_comma_example(struct kunit *test) 100 { 101 #define foo(f) f(X) f(Y) f(Z) f(Q) 102 #define bar DROP_FIRST_ARG(foo(ARGS_SEP_COMMA __stringify)) 103 #define buz CALL_ARGS(COUNT_ARGS, DROP_FIRST_ARG(foo(ARGS_SEP_COMMA))) 104 105 static const char * const a[] = { bar }; 106 107 KUNIT_EXPECT_STREQ(test, a[0], "X"); 108 KUNIT_EXPECT_STREQ(test, a[1], "Y"); 109 KUNIT_EXPECT_STREQ(test, a[2], "Z"); 110 KUNIT_EXPECT_STREQ(test, a[3], "Q"); 111 112 KUNIT_EXPECT_EQ(test, buz, 4); 113 114 #undef foo 115 #undef bar 116 #undef buz 117 } 118 119 #define NO_ARGS 120 #define FOO_ARGS X, Y, Z, Q 121 #define MAX_ARGS -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12 122 123 static void count_args_test(struct kunit *test) 124 { 125 int count; 126 127 /* COUNT_ARGS() counts to 12 */ 128 129 count = COUNT_ARGS(); 130 KUNIT_EXPECT_EQ(test, count, 0); 131 132 count = COUNT_ARGS(1); 133 KUNIT_EXPECT_EQ(test, count, 1); 134 135 count = COUNT_ARGS(a, b, c, d, e); 136 KUNIT_EXPECT_EQ(test, count, 5); 137 138 count = COUNT_ARGS(a, b, c, d, e, f, g, h, i, j, k, l); 139 KUNIT_EXPECT_EQ(test, count, 12); 140 141 /* COUNT_ARGS() does not expand params */ 142 143 count = COUNT_ARGS(NO_ARGS); 144 KUNIT_EXPECT_EQ(test, count, 1); 145 146 count = COUNT_ARGS(FOO_ARGS); 147 KUNIT_EXPECT_EQ(test, count, 1); 148 } 149 150 static void call_args_test(struct kunit *test) 151 { 152 int count; 153 154 count = CALL_ARGS(COUNT_ARGS, NO_ARGS); 155 KUNIT_EXPECT_EQ(test, count, 0); 156 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, NO_ARGS), 0); 157 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, FOO_ARGS), 4); 158 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, FOO_ARGS, FOO_ARGS), 8); 159 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, MAX_ARGS), 12); 160 } 161 162 static void drop_first_arg_test(struct kunit *test) 163 { 164 int Y = -2, Z = -3, Q = -4; 165 int a[] = { DROP_FIRST_ARG(FOO_ARGS) }; 166 167 KUNIT_EXPECT_EQ(test, DROP_FIRST_ARG(0, -1), -1); 168 KUNIT_EXPECT_EQ(test, DROP_FIRST_ARG(DROP_FIRST_ARG(0, -1, -2)), -2); 169 170 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, DROP_FIRST_ARG(FOO_ARGS)), 3); 171 KUNIT_EXPECT_EQ(test, DROP_FIRST_ARG(DROP_FIRST_ARG(DROP_FIRST_ARG(FOO_ARGS))), -4); 172 KUNIT_EXPECT_EQ(test, a[0], -2); 173 KUNIT_EXPECT_EQ(test, a[1], -3); 174 KUNIT_EXPECT_EQ(test, a[2], -4); 175 176 #define foo DROP_FIRST_ARG(FOO_ARGS) 177 #define bar DROP_FIRST_ARG(DROP_FIRST_ARG(FOO_ARGS)) 178 #define buz DROP_FIRST_ARG(DROP_FIRST_ARG(DROP_FIRST_ARG(FOO_ARGS))) 179 180 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, foo), 3); 181 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, bar), 2); 182 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, buz), 1); 183 KUNIT_EXPECT_STREQ(test, __stringify(buz), "Q"); 184 185 #undef foo 186 #undef bar 187 #undef buz 188 } 189 190 static void first_arg_test(struct kunit *test) 191 { 192 int X = -1; 193 int a[] = { FIRST_ARG(FOO_ARGS) }; 194 195 KUNIT_EXPECT_EQ(test, FIRST_ARG(-1, -2), -1); 196 197 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, FIRST_ARG(FOO_ARGS)), 1); 198 KUNIT_EXPECT_EQ(test, FIRST_ARG(FOO_ARGS), -1); 199 KUNIT_EXPECT_EQ(test, a[0], -1); 200 KUNIT_EXPECT_STREQ(test, __stringify(FIRST_ARG(FOO_ARGS)), "X"); 201 } 202 203 static void last_arg_test(struct kunit *test) 204 { 205 int Q = -4; 206 int a[] = { LAST_ARG(FOO_ARGS) }; 207 208 KUNIT_EXPECT_EQ(test, LAST_ARG(-1, -2), -2); 209 210 KUNIT_EXPECT_EQ(test, CALL_ARGS(COUNT_ARGS, LAST_ARG(FOO_ARGS)), 1); 211 KUNIT_EXPECT_EQ(test, LAST_ARG(FOO_ARGS), -4); 212 KUNIT_EXPECT_EQ(test, a[0], -4); 213 KUNIT_EXPECT_STREQ(test, __stringify(LAST_ARG(FOO_ARGS)), "Q"); 214 215 KUNIT_EXPECT_EQ(test, LAST_ARG(MAX_ARGS), -12); 216 KUNIT_EXPECT_STREQ(test, __stringify(LAST_ARG(MAX_ARGS)), "-12"); 217 } 218 219 static void if_args_test(struct kunit *test) 220 { 221 bool with_args = true; 222 bool no_args = false; 223 enum { X = 100 }; 224 225 KUNIT_EXPECT_TRUE(test, IF_ARGS(true, false, FOO_ARGS)); 226 KUNIT_EXPECT_FALSE(test, IF_ARGS(true, false, NO_ARGS)); 227 228 KUNIT_EXPECT_TRUE(test, CONCATENATE(IF_ARGS(with, no, FOO_ARGS), _args)); 229 KUNIT_EXPECT_FALSE(test, CONCATENATE(IF_ARGS(with, no, NO_ARGS), _args)); 230 231 KUNIT_EXPECT_STREQ(test, __stringify(IF_ARGS(yes, no, FOO_ARGS)), "yes"); 232 KUNIT_EXPECT_STREQ(test, __stringify(IF_ARGS(yes, no, NO_ARGS)), "no"); 233 234 KUNIT_EXPECT_EQ(test, IF_ARGS(CALL_ARGS(COUNT_ARGS, FOO_ARGS), -1, FOO_ARGS), 4); 235 KUNIT_EXPECT_EQ(test, IF_ARGS(CALL_ARGS(COUNT_ARGS, FOO_ARGS), -1, NO_ARGS), -1); 236 KUNIT_EXPECT_EQ(test, IF_ARGS(CALL_ARGS(COUNT_ARGS, NO_ARGS), -1, FOO_ARGS), 0); 237 KUNIT_EXPECT_EQ(test, IF_ARGS(CALL_ARGS(COUNT_ARGS, NO_ARGS), -1, NO_ARGS), -1); 238 239 KUNIT_EXPECT_EQ(test, 240 CALL_ARGS(FIRST_ARG, 241 CALL_ARGS(CONCATENATE, IF_ARGS(FOO, MAX, FOO_ARGS), _ARGS)), X); 242 KUNIT_EXPECT_EQ(test, 243 CALL_ARGS(FIRST_ARG, 244 CALL_ARGS(CONCATENATE, IF_ARGS(FOO, MAX, NO_ARGS), _ARGS)), -1); 245 KUNIT_EXPECT_EQ(test, 246 CALL_ARGS(COUNT_ARGS, 247 CALL_ARGS(CONCATENATE, IF_ARGS(FOO, MAX, FOO_ARGS), _ARGS)), 4); 248 KUNIT_EXPECT_EQ(test, 249 CALL_ARGS(COUNT_ARGS, 250 CALL_ARGS(CONCATENATE, IF_ARGS(FOO, MAX, NO_ARGS), _ARGS)), 12); 251 } 252 253 static struct kunit_case args_tests[] = { 254 KUNIT_CASE(count_args_test), 255 KUNIT_CASE(call_args_example), 256 KUNIT_CASE(call_args_test), 257 KUNIT_CASE(drop_first_arg_example), 258 KUNIT_CASE(drop_first_arg_test), 259 KUNIT_CASE(first_arg_example), 260 KUNIT_CASE(first_arg_test), 261 KUNIT_CASE(last_arg_example), 262 KUNIT_CASE(last_arg_test), 263 KUNIT_CASE(pick_arg_example), 264 KUNIT_CASE(if_args_example), 265 KUNIT_CASE(if_args_test), 266 KUNIT_CASE(sep_comma_example), 267 {} 268 }; 269 270 static struct kunit_suite args_test_suite = { 271 .name = "args", 272 .test_cases = args_tests, 273 }; 274 275 kunit_test_suite(args_test_suite); 276