shared: support zero arguments for NM_NARG() macro

It relies on the GCC extension ##__VA_ARGS__, but we
do that on various places already.

Also add a test.
This commit is contained in:
Thomas Haller 2018-07-10 08:45:39 +02:00
parent 159ff23268
commit 0d3bb64008
2 changed files with 58 additions and 2 deletions

View file

@ -7006,6 +7006,57 @@ test_get_start_time_for_pid (void)
/*****************************************************************************/
static void
test_nm_va_args_macros (void)
{
#define GET_NARG_1(...) \
NM_NARG (__VA_ARGS__)
g_assert_cmpint ( 0, ==, GET_NARG_1 ());
g_assert_cmpint ( 1, ==, GET_NARG_1 (x));
g_assert_cmpint ( 2, ==, GET_NARG_1 ( , ));
g_assert_cmpint ( 2, ==, GET_NARG_1 ( , x));
g_assert_cmpint ( 2, ==, GET_NARG_1 (x, ));
g_assert_cmpint ( 2, ==, GET_NARG_1 (x, x));
g_assert_cmpint ( 3, ==, GET_NARG_1 ( , , ));
g_assert_cmpint ( 3, ==, GET_NARG_1 ( , , x));
g_assert_cmpint ( 3, ==, GET_NARG_1 ( , x, ));
g_assert_cmpint ( 3, ==, GET_NARG_1 ( , x, x));
g_assert_cmpint ( 3, ==, GET_NARG_1 (x, , ));
g_assert_cmpint ( 3, ==, GET_NARG_1 (x, , x));
g_assert_cmpint ( 3, ==, GET_NARG_1 (x, x, ));
g_assert_cmpint ( 3, ==, GET_NARG_1 (x, x, x));
g_assert_cmpint ( 4, ==, GET_NARG_1 ( , , , ));
g_assert_cmpint ( 4, ==, GET_NARG_1 ( , , , x));
g_assert_cmpint ( 4, ==, GET_NARG_1 ( , , x, ));
g_assert_cmpint ( 4, ==, GET_NARG_1 ( , , x, x));
g_assert_cmpint ( 4, ==, GET_NARG_1 ( , x, , ));
g_assert_cmpint ( 4, ==, GET_NARG_1 ( , x, , x));
g_assert_cmpint ( 4, ==, GET_NARG_1 ( , x, x, ));
g_assert_cmpint ( 4, ==, GET_NARG_1 ( , x, x, x));
g_assert_cmpint ( 4, ==, GET_NARG_1 (x, , , ));
g_assert_cmpint ( 4, ==, GET_NARG_1 (x, , , x));
g_assert_cmpint ( 4, ==, GET_NARG_1 (x, , x, ));
g_assert_cmpint ( 4, ==, GET_NARG_1 (x, , x, x));
g_assert_cmpint ( 4, ==, GET_NARG_1 (x, x, , ));
g_assert_cmpint ( 4, ==, GET_NARG_1 (x, x, , x));
g_assert_cmpint ( 4, ==, GET_NARG_1 (x, x, x, ));
g_assert_cmpint ( 4, ==, GET_NARG_1 (x, x, x, x));
g_assert_cmpint ( 5, ==, GET_NARG_1 (x, x, x, x, x));
g_assert_cmpint ( 6, ==, GET_NARG_1 (x, x, x, x, x, x));
g_assert_cmpint ( 7, ==, GET_NARG_1 (x, x, x, x, x, x, x));
g_assert_cmpint ( 8, ==, GET_NARG_1 (x, x, x, x, x, x, x, x));
g_assert_cmpint ( 9, ==, GET_NARG_1 (x, x, x, x, x, x, x, x, x));
g_assert_cmpint (10, ==, GET_NARG_1 (x, x, x, x, x, x, x, x, x, x));
G_STATIC_ASSERT_EXPR (0 == GET_NARG_1 ());
G_STATIC_ASSERT_EXPR (1 == GET_NARG_1 (x));
G_STATIC_ASSERT_EXPR (2 == GET_NARG_1 (x, x));
}
/*****************************************************************************/
NMTST_DEFINE ();
int main (int argc, char **argv)
@ -7161,6 +7212,8 @@ int main (int argc, char **argv)
g_test_add_func ("/core/general/get_start_time_for_pid", test_get_start_time_for_pid);
g_test_add_func ("/core/general/test_nm_va_args_macros", test_nm_va_args_macros);
return g_test_run ();
}

View file

@ -342,13 +342,16 @@ _nm_auto_freev (gpointer ptr)
/*****************************************************************************/
/* http://stackoverflow.com/a/2124385/354393 */
/* http://stackoverflow.com/a/2124385/354393
* https://stackoverflow.com/questions/11317474/macro-to-count-number-of-arguments
*/
#define NM_NARG(...) \
_NM_NARG(__VA_ARGS__,_NM_NARG_RSEQ_N())
_NM_NARG(, ##__VA_ARGS__, _NM_NARG_RSEQ_N())
#define _NM_NARG(...) \
_NM_NARG_ARG_N(__VA_ARGS__)
#define _NM_NARG_ARG_N( \
_0, \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \