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