@@ -290,6 +290,190 @@ TEST(foreach_pointer) {
290290 assert_se (k == 11 );
291291}
292292
293+ TEST (foreach_va_args ) {
294+ size_t i ;
295+
296+ i = 0 ;
297+ uint8_t u8 , u8_1 = 1 , u8_2 = 2 , u8_3 = 3 ;
298+ VA_ARGS_FOREACH (u8 , u8_2 , 8 , 0xff , u8_1 , u8_3 , 0 , 1 ) {
299+ switch (i ++ ) {
300+ case 0 : assert_se (u8 == u8_2 ); break ;
301+ case 1 : assert_se (u8 == 8 ); break ;
302+ case 2 : assert_se (u8 == 0xff ); break ;
303+ case 3 : assert_se (u8 == u8_1 ); break ;
304+ case 4 : assert_se (u8 == u8_3 ); break ;
305+ case 5 : assert_se (u8 == 0 ); break ;
306+ case 6 : assert_se (u8 == 1 ); break ;
307+ default : assert_se (false);
308+ }
309+ }
310+ assert_se (i == 7 );
311+ i = 0 ;
312+ VA_ARGS_FOREACH (u8 , 0 ) {
313+ assert_se (u8 == 0 );
314+ assert_se (i ++ == 0 );
315+ }
316+ assert_se (i == 1 );
317+ i = 0 ;
318+ VA_ARGS_FOREACH (u8 , 0xff ) {
319+ assert_se (u8 == 0xff );
320+ assert_se (i ++ == 0 );
321+ }
322+ assert_se (i == 1 );
323+ VA_ARGS_FOREACH (u8 )
324+ assert_se (false );
325+
326+ i = 0 ;
327+ uint32_t u32 , u32_1 = 0xffff0000 , u32_2 = 10 , u32_3 = 0xffff ;
328+ VA_ARGS_FOREACH (u32 , 1 , 100 , u32_2 , 1000 , u32_3 , u32_1 , 1 , 0 ) {
329+ switch (i ++ ) {
330+ case 0 : assert_se (u32 == 1 ); break ;
331+ case 1 : assert_se (u32 == 100 ); break ;
332+ case 2 : assert_se (u32 == u32_2 ); break ;
333+ case 3 : assert_se (u32 == 1000 ); break ;
334+ case 4 : assert_se (u32 == u32_3 ); break ;
335+ case 5 : assert_se (u32 == u32_1 ); break ;
336+ case 6 : assert_se (u32 == 1 ); break ;
337+ case 7 : assert_se (u32 == 0 ); break ;
338+ default : assert_se (false);
339+ }
340+ }
341+ assert_se (i == 8 );
342+ i = 0 ;
343+ VA_ARGS_FOREACH (u32 , 0 ) {
344+ assert_se (u32 == 0 );
345+ assert_se (i ++ == 0 );
346+ }
347+ assert_se (i == 1 );
348+ i = 0 ;
349+ VA_ARGS_FOREACH (u32 , 1000 ) {
350+ assert_se (u32 == 1000 );
351+ assert_se (i ++ == 0 );
352+ }
353+ assert_se (i == 1 );
354+ VA_ARGS_FOREACH (u32 )
355+ assert_se (false );
356+
357+ i = 0 ;
358+ uint64_t u64 , u64_1 = 0xffffffffffffffff , u64_2 = 50 , u64_3 = 0xffff ;
359+ VA_ARGS_FOREACH (u64 , 44 , 0 , u64_3 , 100 , u64_2 , u64_1 , 50000 ) {
360+ switch (i ++ ) {
361+ case 0 : assert_se (u64 == 44 ); break ;
362+ case 1 : assert_se (u64 == 0 ); break ;
363+ case 2 : assert_se (u64 == u64_3 ); break ;
364+ case 3 : assert_se (u64 == 100 ); break ;
365+ case 4 : assert_se (u64 == u64_2 ); break ;
366+ case 5 : assert_se (u64 == u64_1 ); break ;
367+ case 6 : assert_se (u64 == 50000 ); break ;
368+ default : assert_se (false);
369+ }
370+ }
371+ assert_se (i == 7 );
372+ i = 0 ;
373+ VA_ARGS_FOREACH (u64 , 0 ) {
374+ assert_se (u64 == 0 );
375+ assert_se (i ++ == 0 );
376+ }
377+ assert_se (i == 1 );
378+ i = 0 ;
379+ VA_ARGS_FOREACH (u64 , 0xff00ff00000000 ) {
380+ assert_se (u64 == 0xff00ff00000000 );
381+ assert_se (i ++ == 0 );
382+ }
383+ assert_se (i == 1 );
384+ VA_ARGS_FOREACH (u64 )
385+ assert_se (false );
386+
387+ struct test {
388+ int a ;
389+ char b ;
390+ };
391+
392+ i = 0 ;
393+ struct test s ,
394+ s_1 = { .a = 0 , .b = 'c' , },
395+ s_2 = { .a = 100000 , .b = 'z' , },
396+ s_3 = { .a = 0xff , .b = 'q' , },
397+ s_4 = { .a = 1 , .b = 'x' , };
398+ VA_ARGS_FOREACH (s , s_1 , (struct test ){ .a = 10 , .b = 'd' , }, s_2 , (struct test ){}, s_3 , s_4 ) {
399+ switch (i ++ ) {
400+ case 0 : assert_se (s .a == 0 ); assert_se (s .b == 'c' ); break ;
401+ case 1 : assert_se (s .a == 10 ); assert_se (s .b == 'd' ); break ;
402+ case 2 : assert_se (s .a == 100000 ); assert_se (s .b == 'z' ); break ;
403+ case 3 : assert_se (s .a == 0 ); assert_se (s .b == 0 ); break ;
404+ case 4 : assert_se (s .a == 0xff ); assert_se (s .b == 'q' ); break ;
405+ case 5 : assert_se (s .a == 1 ); assert_se (s .b == 'x' ); break ;
406+ default : assert_se (false);
407+ }
408+ }
409+ assert_se (i == 6 );
410+ i = 0 ;
411+ VA_ARGS_FOREACH (s , (struct test ){ .a = 1 , .b = 'A' , }) {
412+ assert_se (s .a == 1 );
413+ assert_se (s .b == 'A' );
414+ assert_se (i ++ == 0 );
415+ }
416+ assert_se (i == 1 );
417+ VA_ARGS_FOREACH (s )
418+ assert_se (false );
419+
420+ i = 0 ;
421+ struct test * p , * p_1 = & s_1 , * p_2 = & s_2 , * p_3 = & s_3 , * p_4 = & s_4 ;
422+ VA_ARGS_FOREACH (p , p_1 , NULL , p_2 , p_3 , NULL , p_4 , NULL ) {
423+ switch (i ++ ) {
424+ case 0 : assert_se (p == p_1 ); break ;
425+ case 1 : assert_se (p == NULL ); break ;
426+ case 2 : assert_se (p == p_2 ); break ;
427+ case 3 : assert_se (p == p_3 ); break ;
428+ case 4 : assert_se (p == NULL ); break ;
429+ case 5 : assert_se (p == p_4 ); break ;
430+ case 6 : assert_se (p == NULL ); break ;
431+ default : assert_se (false);
432+ }
433+ }
434+ assert_se (i == 7 );
435+ i = 0 ;
436+ VA_ARGS_FOREACH (p , p_3 ) {
437+ assert_se (p == p_3 );
438+ assert_se (i ++ == 0 );
439+ }
440+ assert_se (i == 1 );
441+ VA_ARGS_FOREACH (p )
442+ assert_se (false );
443+
444+ i = 0 ;
445+ void * v , * v_1 = p_1 , * v_2 = p_2 , * v_3 = p_3 ;
446+ uint32_t * u32p = & u32 ;
447+ VA_ARGS_FOREACH (v , v_1 , NULL , u32p , v_3 , p_2 , p_4 , v_2 , NULL ) {
448+ switch (i ++ ) {
449+ case 0 : assert_se (v == v_1 ); break ;
450+ case 1 : assert_se (v == NULL ); break ;
451+ case 2 : assert_se (v == u32p ); break ;
452+ case 3 : assert_se (v == v_3 ); break ;
453+ case 4 : assert_se (v == p_2 ); break ;
454+ case 5 : assert_se (v == p_4 ); break ;
455+ case 6 : assert_se (v == v_2 ); break ;
456+ case 7 : assert_se (v == NULL ); break ;
457+ default : assert_se (false);
458+ }
459+ }
460+ assert_se (i == 8 );
461+ i = 0 ;
462+ VA_ARGS_FOREACH (v , NULL ) {
463+ assert_se (v == NULL );
464+ assert_se (i ++ == 0 );
465+ }
466+ assert_se (i == 1 );
467+ i = 0 ;
468+ VA_ARGS_FOREACH (v , v_1 ) {
469+ assert_se (v == v_1 );
470+ assert_se (i ++ == 0 );
471+ }
472+ assert_se (i == 1 );
473+ VA_ARGS_FOREACH (v )
474+ assert_se (false );
475+ }
476+
293477TEST (align_to ) {
294478 assert_se (ALIGN_TO (0 , 1 ) == 0 );
295479 assert_se (ALIGN_TO (1 , 1 ) == 1 );
0 commit comments