16c5c6571SChengwen Feng /* SPDX-License-Identifier: BSD-3-Clause 26c5c6571SChengwen Feng * Copyright(c) 2024 HiSilicon Limited 36c5c6571SChengwen Feng */ 46c5c6571SChengwen Feng 56c5c6571SChengwen Feng #include <stdio.h> 66c5c6571SChengwen Feng #include <string.h> 76c5c6571SChengwen Feng 86c5c6571SChengwen Feng #include <rte_argparse.h> 96c5c6571SChengwen Feng 106c5c6571SChengwen Feng #include "test.h" 116c5c6571SChengwen Feng 126c5c6571SChengwen Feng static int default_argc; 136c5c6571SChengwen Feng static char *default_argv[1]; 146c5c6571SChengwen Feng 156c5c6571SChengwen Feng #define MAX_STRDUP_STORE_NUM 512 166c5c6571SChengwen Feng static char *strdup_store_array[MAX_STRDUP_STORE_NUM]; 176c5c6571SChengwen Feng static uint32_t strdup_store_index; 186c5c6571SChengwen Feng 196c5c6571SChengwen Feng /* 206c5c6571SChengwen Feng * Define strdup wrapper. 216c5c6571SChengwen Feng * 1. Mainly to fix compile error "warning: assignment discards 'const' 226c5c6571SChengwen Feng * qualifier from pointer target type [-Wdiscarded-qualifiers]" for 236c5c6571SChengwen Feng * following code: 246c5c6571SChengwen Feng * argv[x] = "100"; 256c5c6571SChengwen Feng * 2. The strdup result will store in the strdup_store_array, and then 266c5c6571SChengwen Feng * freed in the teardown function, prevent ASAN errors from being 276c5c6571SChengwen Feng * triggered. 286c5c6571SChengwen Feng */ 296c5c6571SChengwen Feng static char * 306c5c6571SChengwen Feng test_strdup(const char *str) 316c5c6571SChengwen Feng { 326c5c6571SChengwen Feng char *s = strdup(str); 336c5c6571SChengwen Feng if (s == NULL) { 346c5c6571SChengwen Feng printf("strdup failed! exiting...\n"); 356c5c6571SChengwen Feng exit(-ENOMEM); 366c5c6571SChengwen Feng } 376c5c6571SChengwen Feng if (strdup_store_index >= MAX_STRDUP_STORE_NUM) { 386c5c6571SChengwen Feng printf("too much strdup calls! exiting...\n"); 396c5c6571SChengwen Feng exit(-ERANGE); 406c5c6571SChengwen Feng } 416c5c6571SChengwen Feng strdup_store_array[strdup_store_index++] = s; 426c5c6571SChengwen Feng return s; 436c5c6571SChengwen Feng } 446c5c6571SChengwen Feng 456c5c6571SChengwen Feng static int 466c5c6571SChengwen Feng test_argparse_setup(void) 476c5c6571SChengwen Feng { 486c5c6571SChengwen Feng strdup_store_index = 0; 496c5c6571SChengwen Feng default_argc = 1; 506c5c6571SChengwen Feng default_argv[0] = test_strdup("test_argparse"); 516c5c6571SChengwen Feng return 0; 526c5c6571SChengwen Feng } 536c5c6571SChengwen Feng 546c5c6571SChengwen Feng static void 556c5c6571SChengwen Feng test_argparse_teardown(void) 566c5c6571SChengwen Feng { 576c5c6571SChengwen Feng uint32_t i; 586c5c6571SChengwen Feng printf("total used strdup_store_index = %u\n", strdup_store_index); 596c5c6571SChengwen Feng for (i = 0; i < strdup_store_index; i++) 606c5c6571SChengwen Feng free(strdup_store_array[i]); 616c5c6571SChengwen Feng strdup_store_index = 0; 626c5c6571SChengwen Feng } 636c5c6571SChengwen Feng 646c5c6571SChengwen Feng static int 656c5c6571SChengwen Feng test_argparse_callback(uint32_t index, const char *value, void *opaque) 666c5c6571SChengwen Feng { 676c5c6571SChengwen Feng RTE_SET_USED(index); 686c5c6571SChengwen Feng RTE_SET_USED(value); 696c5c6571SChengwen Feng RTE_SET_USED(opaque); 706c5c6571SChengwen Feng return 0; 716c5c6571SChengwen Feng } 726c5c6571SChengwen Feng 736c5c6571SChengwen Feng /* valid templater, must contain at least two args. */ 746c5c6571SChengwen Feng #define argparse_templater() { \ 756c5c6571SChengwen Feng .prog_name = "test_argparse", \ 766c5c6571SChengwen Feng .usage = "-a xx -b yy", \ 776c5c6571SChengwen Feng .descriptor = NULL, \ 786c5c6571SChengwen Feng .epilog = NULL, \ 796c5c6571SChengwen Feng .exit_on_error = false, \ 806c5c6571SChengwen Feng .callback = test_argparse_callback, \ 816c5c6571SChengwen Feng .args = { \ 826c5c6571SChengwen Feng { "--abc", "-a", "abc argument", (void *)1, (void *)1, RTE_ARGPARSE_ARG_NO_VALUE | RTE_ARGPARSE_ARG_VALUE_INT }, \ 836c5c6571SChengwen Feng { "--xyz", "-x", "xyz argument", (void *)1, (void *)2, RTE_ARGPARSE_ARG_NO_VALUE | RTE_ARGPARSE_ARG_VALUE_INT }, \ 846c5c6571SChengwen Feng ARGPARSE_ARG_END(), \ 856c5c6571SChengwen Feng }, \ 866c5c6571SChengwen Feng } 876c5c6571SChengwen Feng 886c5c6571SChengwen Feng static void 896c5c6571SChengwen Feng test_argparse_copy(struct rte_argparse *dst, struct rte_argparse *src) 906c5c6571SChengwen Feng { 916c5c6571SChengwen Feng uint32_t i; 926c5c6571SChengwen Feng memcpy(dst, src, sizeof(*src)); 936c5c6571SChengwen Feng for (i = 0; /* NULL */; i++) { 946c5c6571SChengwen Feng memcpy(&dst->args[i], &src->args[i], sizeof(src->args[i])); 956c5c6571SChengwen Feng if (src->args[i].name_long == NULL) 966c5c6571SChengwen Feng break; 976c5c6571SChengwen Feng } 986c5c6571SChengwen Feng } 996c5c6571SChengwen Feng 1006c5c6571SChengwen Feng static struct rte_argparse * 1016c5c6571SChengwen Feng test_argparse_init_obj(void) 1026c5c6571SChengwen Feng { 1036c5c6571SChengwen Feng static struct rte_argparse backup = argparse_templater(); 1046c5c6571SChengwen Feng static struct rte_argparse obj = argparse_templater(); 1056c5c6571SChengwen Feng /* Because obj may be overwritten, do a deep copy. */ 1066c5c6571SChengwen Feng test_argparse_copy(&obj, &backup); 1076c5c6571SChengwen Feng return &obj; 1086c5c6571SChengwen Feng } 1096c5c6571SChengwen Feng 1106c5c6571SChengwen Feng static int 1116c5c6571SChengwen Feng test_argparse_invalid_basic_param(void) 1126c5c6571SChengwen Feng { 1136c5c6571SChengwen Feng struct rte_argparse *obj; 1146c5c6571SChengwen Feng int ret; 1156c5c6571SChengwen Feng 1166c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1176c5c6571SChengwen Feng obj->prog_name = NULL; 1186c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1196c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1206c5c6571SChengwen Feng 1216c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1226c5c6571SChengwen Feng obj->usage = NULL; 1236c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1246c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1256c5c6571SChengwen Feng 1266c5c6571SChengwen Feng return TEST_SUCCESS; 1276c5c6571SChengwen Feng } 1286c5c6571SChengwen Feng 1296c5c6571SChengwen Feng static int 1306c5c6571SChengwen Feng test_argparse_invalid_arg_name(void) 1316c5c6571SChengwen Feng { 1326c5c6571SChengwen Feng struct rte_argparse *obj; 1336c5c6571SChengwen Feng int ret; 1346c5c6571SChengwen Feng 1356c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1366c5c6571SChengwen Feng obj->args[0].name_long = "-ab"; 1376c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1386c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1396c5c6571SChengwen Feng 1406c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1416c5c6571SChengwen Feng obj->args[0].name_long = "-abc"; 1426c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1436c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1446c5c6571SChengwen Feng 1456c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1466c5c6571SChengwen Feng obj->args[0].name_long = "---c"; 1476c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1486c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1496c5c6571SChengwen Feng 1506c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1516c5c6571SChengwen Feng obj->args[0].name_long = "abc"; 1526c5c6571SChengwen Feng obj->args[0].name_short = "-a"; 1536c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1546c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1556c5c6571SChengwen Feng 1566c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1576c5c6571SChengwen Feng obj->args[0].name_short = "a"; 1586c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1596c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1606c5c6571SChengwen Feng 1616c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1626c5c6571SChengwen Feng obj->args[0].name_short = "abc"; 1636c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1646c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1656c5c6571SChengwen Feng 1666c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1676c5c6571SChengwen Feng obj->args[0].name_short = "ab"; 1686c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1696c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1706c5c6571SChengwen Feng 1716c5c6571SChengwen Feng return 0; 1726c5c6571SChengwen Feng } 1736c5c6571SChengwen Feng 1746c5c6571SChengwen Feng static int 1756c5c6571SChengwen Feng test_argparse_invalid_arg_help(void) 1766c5c6571SChengwen Feng { 1776c5c6571SChengwen Feng struct rte_argparse *obj; 1786c5c6571SChengwen Feng int ret; 1796c5c6571SChengwen Feng 1806c5c6571SChengwen Feng obj = test_argparse_init_obj(); 1816c5c6571SChengwen Feng obj->args[0].help = NULL; 1826c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 1836c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 1846c5c6571SChengwen Feng 1856c5c6571SChengwen Feng return 0; 1866c5c6571SChengwen Feng } 1876c5c6571SChengwen Feng 1886c5c6571SChengwen Feng static int 1896c5c6571SChengwen Feng test_argparse_invalid_has_val(void) 1906c5c6571SChengwen Feng { 191f48e4eedSChengwen Feng uint64_t set_mask[] = { 0, 1926c5c6571SChengwen Feng RTE_ARGPARSE_ARG_NO_VALUE, 1936c5c6571SChengwen Feng RTE_ARGPARSE_ARG_OPTIONAL_VALUE 1946c5c6571SChengwen Feng }; 1956c5c6571SChengwen Feng struct rte_argparse *obj; 1966c5c6571SChengwen Feng uint32_t index; 1976c5c6571SChengwen Feng int ret; 1986c5c6571SChengwen Feng 199*9684dfeaSChengwen Feng /* test optional arg don't config has-value. */ 2006c5c6571SChengwen Feng obj = test_argparse_init_obj(); 201f48e4eedSChengwen Feng obj->args[0].flags &= ~RTE_ARGPARSE_HAS_VAL_BITMASK; 2026c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2036c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2046c5c6571SChengwen Feng 205*9684dfeaSChengwen Feng /* test positional arg don't config required-value. */ 2066c5c6571SChengwen Feng for (index = 0; index < RTE_DIM(set_mask); index++) { 2076c5c6571SChengwen Feng obj = test_argparse_init_obj(); 2086c5c6571SChengwen Feng obj->args[0].name_long = "abc"; 2096c5c6571SChengwen Feng obj->args[0].name_short = NULL; 210f48e4eedSChengwen Feng obj->args[0].flags &= ~RTE_ARGPARSE_HAS_VAL_BITMASK; 2116c5c6571SChengwen Feng obj->args[0].flags |= set_mask[index]; 2126c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2136c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2146c5c6571SChengwen Feng } 2156c5c6571SChengwen Feng 2166c5c6571SChengwen Feng return 0; 2176c5c6571SChengwen Feng } 2186c5c6571SChengwen Feng 2196c5c6571SChengwen Feng static int 2206c5c6571SChengwen Feng test_argparse_invalid_arg_saver(void) 2216c5c6571SChengwen Feng { 2226c5c6571SChengwen Feng struct rte_argparse *obj; 2236c5c6571SChengwen Feng int ret; 2246c5c6571SChengwen Feng 2256c5c6571SChengwen Feng /* test saver == NULL with val-type != 0. */ 2266c5c6571SChengwen Feng obj = test_argparse_init_obj(); 2276c5c6571SChengwen Feng obj->args[0].val_saver = NULL; 2286c5c6571SChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_NO_VALUE | RTE_ARGPARSE_ARG_VALUE_INT; 2296c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2306c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2316c5c6571SChengwen Feng 2326c5c6571SChengwen Feng /* test saver == NULL with callback is NULL. */ 2336c5c6571SChengwen Feng obj = test_argparse_init_obj(); 2346c5c6571SChengwen Feng obj->args[0].val_saver = NULL; 2356c5c6571SChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_NO_VALUE; 2366c5c6571SChengwen Feng obj->callback = NULL; 2376c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2386c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2396c5c6571SChengwen Feng 2406c5c6571SChengwen Feng /* test saver != NULL with val-type is zero! */ 2416c5c6571SChengwen Feng obj = test_argparse_init_obj(); 2426c5c6571SChengwen Feng obj->args[0].val_saver = (void *)1; 2436c5c6571SChengwen Feng obj->args[0].val_set = (void *)1; 2446c5c6571SChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_NO_VALUE; 2456c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2466c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2476c5c6571SChengwen Feng 2486c5c6571SChengwen Feng /* test saver != NULL with val-type is max. */ 2496c5c6571SChengwen Feng obj = test_argparse_init_obj(); 2506c5c6571SChengwen Feng obj->args[0].val_saver = (void *)1; 2516c5c6571SChengwen Feng obj->args[0].val_set = (void *)1; 2526c5c6571SChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_NO_VALUE | RTE_ARGPARSE_ARG_VALUE_MAX; 2536c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2546c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2556c5c6571SChengwen Feng 2566c5c6571SChengwen Feng /* test saver != NULL with required value, but val-set is not NULL. */ 2576c5c6571SChengwen Feng obj = test_argparse_init_obj(); 2586c5c6571SChengwen Feng obj->args[0].val_saver = (void *)1; 2596c5c6571SChengwen Feng obj->args[0].val_set = (void *)1; 2606c5c6571SChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE | RTE_ARGPARSE_ARG_VALUE_INT; 2616c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2626c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2636c5c6571SChengwen Feng 2646c5c6571SChengwen Feng return 0; 2656c5c6571SChengwen Feng } 2666c5c6571SChengwen Feng 2676c5c6571SChengwen Feng static int 2686c5c6571SChengwen Feng test_argparse_invalid_arg_flags(void) 2696c5c6571SChengwen Feng { 2706c5c6571SChengwen Feng struct rte_argparse *obj; 2716c5c6571SChengwen Feng int ret; 2726c5c6571SChengwen Feng 273*9684dfeaSChengwen Feng /* test set unused bits. */ 2746c5c6571SChengwen Feng obj = test_argparse_init_obj(); 275f48e4eedSChengwen Feng obj->args[0].flags |= ~(RTE_ARGPARSE_HAS_VAL_BITMASK | 276f48e4eedSChengwen Feng RTE_ARGPARSE_VAL_TYPE_BITMASK | 277f48e4eedSChengwen Feng RTE_ARGPARSE_ARG_SUPPORT_MULTI); 2786c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2796c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2806c5c6571SChengwen Feng 281*9684dfeaSChengwen Feng /* test positional arg should not config multiple. */ 2826c5c6571SChengwen Feng obj = test_argparse_init_obj(); 2836c5c6571SChengwen Feng obj->args[0].name_long = "positional"; 2846c5c6571SChengwen Feng obj->args[0].name_short = NULL; 2856c5c6571SChengwen Feng obj->args[0].val_saver = (void *)1; 286*9684dfeaSChengwen Feng obj->args[0].val_set = NULL; 2876c5c6571SChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE | RTE_ARGPARSE_ARG_VALUE_INT | 2886c5c6571SChengwen Feng RTE_ARGPARSE_ARG_SUPPORT_MULTI; 2896c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2906c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2916c5c6571SChengwen Feng 292*9684dfeaSChengwen Feng /* test optional arg enabled multiple but prased by autosave. */ 2936c5c6571SChengwen Feng obj = test_argparse_init_obj(); 2946c5c6571SChengwen Feng obj->args[0].flags |= RTE_ARGPARSE_ARG_SUPPORT_MULTI; 2956c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 2966c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 2976c5c6571SChengwen Feng 2986c5c6571SChengwen Feng return 0; 2996c5c6571SChengwen Feng } 3006c5c6571SChengwen Feng 3016c5c6571SChengwen Feng static int 3026c5c6571SChengwen Feng test_argparse_invalid_arg_repeat(void) 3036c5c6571SChengwen Feng { 3046c5c6571SChengwen Feng struct rte_argparse *obj; 3056c5c6571SChengwen Feng int ret; 3066c5c6571SChengwen Feng 3076c5c6571SChengwen Feng /* test for long name repeat! */ 3086c5c6571SChengwen Feng obj = test_argparse_init_obj(); 3096c5c6571SChengwen Feng obj->args[1].name_long = obj->args[0].name_long; 3106c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 3116c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 3126c5c6571SChengwen Feng 3136c5c6571SChengwen Feng /* test for short name repeat! */ 3146c5c6571SChengwen Feng obj = test_argparse_init_obj(); 3156c5c6571SChengwen Feng obj->args[1].name_short = obj->args[0].name_short; 3166c5c6571SChengwen Feng ret = rte_argparse_parse(obj, default_argc, default_argv); 3176c5c6571SChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 3186c5c6571SChengwen Feng 3196c5c6571SChengwen Feng return 0; 3206c5c6571SChengwen Feng } 3216c5c6571SChengwen Feng 32231ed9f9fSChengwen Feng static int 32331ed9f9fSChengwen Feng test_argparse_invalid_option(void) 32431ed9f9fSChengwen Feng { 32531ed9f9fSChengwen Feng struct rte_argparse *obj; 32631ed9f9fSChengwen Feng char *argv[2]; 32731ed9f9fSChengwen Feng int ret; 32831ed9f9fSChengwen Feng 32931ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 330*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 33131ed9f9fSChengwen Feng argv[1] = test_strdup("--invalid"); 33231ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 33331ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 33431ed9f9fSChengwen Feng 33531ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 336*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 33731ed9f9fSChengwen Feng argv[1] = test_strdup("invalid"); 33831ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 33931ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 34031ed9f9fSChengwen Feng 34131ed9f9fSChengwen Feng return 0; 34231ed9f9fSChengwen Feng } 34331ed9f9fSChengwen Feng 34431ed9f9fSChengwen Feng static int 34531ed9f9fSChengwen Feng test_argparse_opt_autosave_parse_int_of_no_val(void) 34631ed9f9fSChengwen Feng { 347f48e4eedSChengwen Feng uint64_t flags = RTE_ARGPARSE_ARG_NO_VALUE | RTE_ARGPARSE_ARG_VALUE_INT; 34831ed9f9fSChengwen Feng struct rte_argparse *obj; 34931ed9f9fSChengwen Feng int val_saver = 0; 35031ed9f9fSChengwen Feng char *argv[2]; 35131ed9f9fSChengwen Feng int ret; 35231ed9f9fSChengwen Feng 35331ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 35431ed9f9fSChengwen Feng obj->args[0].name_long = "--test-long"; 35531ed9f9fSChengwen Feng obj->args[0].name_short = "-t"; 35631ed9f9fSChengwen Feng obj->args[0].val_saver = (void *)&val_saver; 35731ed9f9fSChengwen Feng obj->args[0].val_set = (void *)100; 35831ed9f9fSChengwen Feng obj->args[0].flags = flags; 35931ed9f9fSChengwen Feng obj->args[1].name_long = NULL; 360*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 36131ed9f9fSChengwen Feng argv[1] = test_strdup("--test-long"); 36231ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 36331ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 36431ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 36531ed9f9fSChengwen Feng 36631ed9f9fSChengwen Feng obj->args[0].flags = flags; 36731ed9f9fSChengwen Feng val_saver = 0; 36831ed9f9fSChengwen Feng argv[1] = test_strdup("-t"); 36931ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 37031ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 37131ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 37231ed9f9fSChengwen Feng 37331ed9f9fSChengwen Feng return 0; 37431ed9f9fSChengwen Feng } 37531ed9f9fSChengwen Feng 37631ed9f9fSChengwen Feng static int 37731ed9f9fSChengwen Feng test_argparse_opt_autosave_parse_int_of_required_val(void) 37831ed9f9fSChengwen Feng { 379f48e4eedSChengwen Feng uint64_t flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE | RTE_ARGPARSE_ARG_VALUE_INT; 38031ed9f9fSChengwen Feng struct rte_argparse *obj; 38131ed9f9fSChengwen Feng int val_saver = 0; 38231ed9f9fSChengwen Feng char *argv[3]; 38331ed9f9fSChengwen Feng int ret; 38431ed9f9fSChengwen Feng 38531ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 38631ed9f9fSChengwen Feng obj->args[0].name_long = "--test-long"; 38731ed9f9fSChengwen Feng obj->args[0].name_short = "-t"; 38831ed9f9fSChengwen Feng obj->args[0].val_saver = (void *)&val_saver; 38931ed9f9fSChengwen Feng obj->args[0].val_set = NULL; 39031ed9f9fSChengwen Feng obj->args[0].flags = flags; 39131ed9f9fSChengwen Feng obj->args[1].name_long = NULL; 392*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 39331ed9f9fSChengwen Feng argv[1] = test_strdup("--test-long"); 39431ed9f9fSChengwen Feng argv[2] = test_strdup("100"); 39531ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 3, argv); 39631ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 39731ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 39831ed9f9fSChengwen Feng 39931ed9f9fSChengwen Feng obj->args[0].flags = flags; 40031ed9f9fSChengwen Feng val_saver = 0; 40131ed9f9fSChengwen Feng argv[1] = test_strdup("-t"); 40231ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 3, argv); 40331ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 40431ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 40531ed9f9fSChengwen Feng 40631ed9f9fSChengwen Feng /* test invalid value. */ 40731ed9f9fSChengwen Feng obj->args[0].flags = flags; 40831ed9f9fSChengwen Feng val_saver = 0; 40931ed9f9fSChengwen Feng argv[1] = test_strdup("-t"); 41031ed9f9fSChengwen Feng argv[2] = test_strdup("100a"); 41131ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 3, argv); 41231ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 41331ed9f9fSChengwen Feng 41431ed9f9fSChengwen Feng return 0; 41531ed9f9fSChengwen Feng } 41631ed9f9fSChengwen Feng 41731ed9f9fSChengwen Feng static int 41831ed9f9fSChengwen Feng test_argparse_opt_autosave_parse_int_of_optional_val(void) 41931ed9f9fSChengwen Feng { 420f48e4eedSChengwen Feng uint64_t flags = RTE_ARGPARSE_ARG_OPTIONAL_VALUE | RTE_ARGPARSE_ARG_VALUE_INT; 42131ed9f9fSChengwen Feng struct rte_argparse *obj; 42231ed9f9fSChengwen Feng int val_saver = 0; 42331ed9f9fSChengwen Feng char *argv[2]; 42431ed9f9fSChengwen Feng int ret; 42531ed9f9fSChengwen Feng 426*9684dfeaSChengwen Feng /* test without value. */ 42731ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 42831ed9f9fSChengwen Feng obj->args[0].name_long = "--test-long"; 42931ed9f9fSChengwen Feng obj->args[0].name_short = "-t"; 43031ed9f9fSChengwen Feng obj->args[0].val_saver = (void *)&val_saver; 43131ed9f9fSChengwen Feng obj->args[0].val_set = (void *)100; 43231ed9f9fSChengwen Feng obj->args[0].flags = flags; 43331ed9f9fSChengwen Feng obj->args[1].name_long = NULL; 434*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 43531ed9f9fSChengwen Feng argv[1] = test_strdup("--test-long"); 43631ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 43731ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 43831ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 43931ed9f9fSChengwen Feng obj->args[0].flags = flags; 44031ed9f9fSChengwen Feng val_saver = 0; 44131ed9f9fSChengwen Feng argv[1] = test_strdup("-t"); 44231ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 44331ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 44431ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 44531ed9f9fSChengwen Feng 44631ed9f9fSChengwen Feng /* test with value. */ 44731ed9f9fSChengwen Feng obj->args[0].flags = flags; 44831ed9f9fSChengwen Feng val_saver = 0; 44931ed9f9fSChengwen Feng argv[1] = test_strdup("--test-long=200"); 45031ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 45131ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 45231ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 200, "Argparse parse expect success!"); 45331ed9f9fSChengwen Feng obj->args[0].flags = flags; 45431ed9f9fSChengwen Feng val_saver = 0; 45531ed9f9fSChengwen Feng argv[1] = test_strdup("-t=200"); 45631ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 45731ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 45831ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 200, "Argparse parse expect success!"); 45931ed9f9fSChengwen Feng 46031ed9f9fSChengwen Feng /* test with option value, but with wrong value. */ 46131ed9f9fSChengwen Feng obj->args[0].flags = flags; 46231ed9f9fSChengwen Feng val_saver = 0; 46331ed9f9fSChengwen Feng argv[1] = test_strdup("--test-long=200a"); 46431ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 46531ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 46631ed9f9fSChengwen Feng obj->args[0].flags = flags; 46731ed9f9fSChengwen Feng val_saver = 0; 46831ed9f9fSChengwen Feng argv[1] = test_strdup("-t=200a"); 46931ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 47031ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 47131ed9f9fSChengwen Feng 47231ed9f9fSChengwen Feng return 0; 47331ed9f9fSChengwen Feng } 47431ed9f9fSChengwen Feng 47531ed9f9fSChengwen Feng static int 47631ed9f9fSChengwen Feng opt_callback_parse_int_of_no_val(uint32_t index, const char *value, void *opaque) 47731ed9f9fSChengwen Feng { 478*9684dfeaSChengwen Feng if (index != 1) 479*9684dfeaSChengwen Feng return -EINVAL; 48031ed9f9fSChengwen Feng if (value != NULL) 48131ed9f9fSChengwen Feng return -EINVAL; 48231ed9f9fSChengwen Feng *(int *)opaque = 100; 48331ed9f9fSChengwen Feng return 0; 48431ed9f9fSChengwen Feng } 48531ed9f9fSChengwen Feng 48631ed9f9fSChengwen Feng static int 48731ed9f9fSChengwen Feng test_argparse_opt_callback_parse_int_of_no_val(void) 48831ed9f9fSChengwen Feng { 48931ed9f9fSChengwen Feng struct rte_argparse *obj; 49031ed9f9fSChengwen Feng int val_saver = 0; 49131ed9f9fSChengwen Feng char *argv[2]; 49231ed9f9fSChengwen Feng int ret; 49331ed9f9fSChengwen Feng 49431ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 49531ed9f9fSChengwen Feng obj->callback = opt_callback_parse_int_of_no_val; 49631ed9f9fSChengwen Feng obj->opaque = (void *)&val_saver; 49731ed9f9fSChengwen Feng obj->args[0].name_long = "--test-long"; 49831ed9f9fSChengwen Feng obj->args[0].name_short = "-t"; 49931ed9f9fSChengwen Feng obj->args[0].val_saver = NULL; 500*9684dfeaSChengwen Feng obj->args[0].val_set = (void *)1; 50131ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_NO_VALUE; 50231ed9f9fSChengwen Feng obj->args[1].name_long = NULL; 503*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 50431ed9f9fSChengwen Feng argv[1] = test_strdup("--test-long"); 50531ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 50631ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 50731ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 50831ed9f9fSChengwen Feng 50931ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_NO_VALUE; 51031ed9f9fSChengwen Feng val_saver = 0; 51131ed9f9fSChengwen Feng argv[1] = test_strdup("-t"); 51231ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 51331ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 51431ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 51531ed9f9fSChengwen Feng 51631ed9f9fSChengwen Feng return 0; 51731ed9f9fSChengwen Feng } 51831ed9f9fSChengwen Feng 51931ed9f9fSChengwen Feng static int 52031ed9f9fSChengwen Feng opt_callback_parse_int_of_required_val(uint32_t index, const char *value, void *opaque) 52131ed9f9fSChengwen Feng { 52231ed9f9fSChengwen Feng char *s = NULL; 52331ed9f9fSChengwen Feng 52431ed9f9fSChengwen Feng if (index != 1) 52531ed9f9fSChengwen Feng return -EINVAL; 52631ed9f9fSChengwen Feng 52731ed9f9fSChengwen Feng if (value == NULL) 52831ed9f9fSChengwen Feng return -EINVAL; 52931ed9f9fSChengwen Feng *(int *)opaque = strtol(value, &s, 0); 53031ed9f9fSChengwen Feng 53131ed9f9fSChengwen Feng if (s[0] != '\0') 53231ed9f9fSChengwen Feng return -EINVAL; 53331ed9f9fSChengwen Feng 53431ed9f9fSChengwen Feng return 0; 53531ed9f9fSChengwen Feng } 53631ed9f9fSChengwen Feng 53731ed9f9fSChengwen Feng static int 53831ed9f9fSChengwen Feng test_argparse_opt_callback_parse_int_of_required_val(void) 53931ed9f9fSChengwen Feng { 54031ed9f9fSChengwen Feng struct rte_argparse *obj; 54131ed9f9fSChengwen Feng int val_saver = 0; 54231ed9f9fSChengwen Feng char *argv[3]; 54331ed9f9fSChengwen Feng int ret; 54431ed9f9fSChengwen Feng 54531ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 54631ed9f9fSChengwen Feng obj->callback = opt_callback_parse_int_of_required_val; 54731ed9f9fSChengwen Feng obj->opaque = (void *)&val_saver; 54831ed9f9fSChengwen Feng obj->args[0].name_long = "--test-long"; 54931ed9f9fSChengwen Feng obj->args[0].name_short = "-t"; 55031ed9f9fSChengwen Feng obj->args[0].val_saver = NULL; 55131ed9f9fSChengwen Feng obj->args[0].val_set = (void *)1; 55231ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE; 55331ed9f9fSChengwen Feng obj->args[1].name_long = NULL; 554*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 55531ed9f9fSChengwen Feng argv[1] = test_strdup("--test-long"); 55631ed9f9fSChengwen Feng argv[2] = test_strdup("100"); 55731ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 3, argv); 55831ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 55931ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 56031ed9f9fSChengwen Feng 56131ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE; 56231ed9f9fSChengwen Feng val_saver = 0; 56331ed9f9fSChengwen Feng argv[1] = test_strdup("-t"); 56431ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 3, argv); 56531ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 56631ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 56731ed9f9fSChengwen Feng 56831ed9f9fSChengwen Feng /* test no more parameters. */ 56931ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE; 57031ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 57131ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 57231ed9f9fSChengwen Feng 57331ed9f9fSChengwen Feng /* test callback return failed. */ 57431ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE; 57531ed9f9fSChengwen Feng argv[2] = test_strdup("100a"); 57631ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 3, argv); 57731ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 57831ed9f9fSChengwen Feng 57931ed9f9fSChengwen Feng return 0; 58031ed9f9fSChengwen Feng } 58131ed9f9fSChengwen Feng 58231ed9f9fSChengwen Feng static int 58331ed9f9fSChengwen Feng opt_callback_parse_int_of_optional_val(uint32_t index, const char *value, void *opaque) 58431ed9f9fSChengwen Feng { 58531ed9f9fSChengwen Feng char *s = NULL; 58631ed9f9fSChengwen Feng 58731ed9f9fSChengwen Feng if (index != 1) 58831ed9f9fSChengwen Feng return -EINVAL; 58931ed9f9fSChengwen Feng 59031ed9f9fSChengwen Feng if (value == NULL) { 59131ed9f9fSChengwen Feng *(int *)opaque = 10; 59231ed9f9fSChengwen Feng } else { 59331ed9f9fSChengwen Feng *(int *)opaque = strtol(value, &s, 0); 59431ed9f9fSChengwen Feng if (s[0] != '\0') 59531ed9f9fSChengwen Feng return -EINVAL; 59631ed9f9fSChengwen Feng } 59731ed9f9fSChengwen Feng 59831ed9f9fSChengwen Feng return 0; 59931ed9f9fSChengwen Feng } 60031ed9f9fSChengwen Feng 60131ed9f9fSChengwen Feng static int 60231ed9f9fSChengwen Feng test_argparse_opt_callback_parse_int_of_optional_val(void) 60331ed9f9fSChengwen Feng { 60431ed9f9fSChengwen Feng struct rte_argparse *obj; 60531ed9f9fSChengwen Feng int val_saver = 0; 60631ed9f9fSChengwen Feng char *argv[2]; 60731ed9f9fSChengwen Feng int ret; 60831ed9f9fSChengwen Feng 60931ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 61031ed9f9fSChengwen Feng obj->callback = opt_callback_parse_int_of_optional_val; 61131ed9f9fSChengwen Feng obj->opaque = (void *)&val_saver; 61231ed9f9fSChengwen Feng obj->args[0].name_long = "--test-long"; 61331ed9f9fSChengwen Feng obj->args[0].name_short = "-t"; 61431ed9f9fSChengwen Feng obj->args[0].val_saver = NULL; 61531ed9f9fSChengwen Feng obj->args[0].val_set = (void *)1; 61631ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_OPTIONAL_VALUE; 61731ed9f9fSChengwen Feng obj->args[1].name_long = NULL; 618*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 61931ed9f9fSChengwen Feng argv[1] = test_strdup("--test-long"); 62031ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 62131ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 62231ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 10, "Argparse parse expect success!"); 62331ed9f9fSChengwen Feng 62431ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_OPTIONAL_VALUE; 62531ed9f9fSChengwen Feng val_saver = 0; 62631ed9f9fSChengwen Feng argv[1] = test_strdup("-t"); 62731ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 62831ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 62931ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 10, "Argparse parse expect success!"); 63031ed9f9fSChengwen Feng 63131ed9f9fSChengwen Feng /* test with value. */ 63231ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_OPTIONAL_VALUE; 63331ed9f9fSChengwen Feng val_saver = 0; 63431ed9f9fSChengwen Feng argv[1] = test_strdup("--test-long=100"); 63531ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 63631ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 63731ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 63831ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_OPTIONAL_VALUE; 63931ed9f9fSChengwen Feng val_saver = 0; 64031ed9f9fSChengwen Feng argv[1] = test_strdup("-t=100"); 64131ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 64231ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 64331ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 64431ed9f9fSChengwen Feng 64531ed9f9fSChengwen Feng /* test callback return failed. */ 64631ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_OPTIONAL_VALUE; 64731ed9f9fSChengwen Feng argv[1] = test_strdup("-t=100a"); 64831ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 64931ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 65031ed9f9fSChengwen Feng 65131ed9f9fSChengwen Feng return 0; 65231ed9f9fSChengwen Feng } 65331ed9f9fSChengwen Feng 65431ed9f9fSChengwen Feng static int 65531ed9f9fSChengwen Feng test_argparse_pos_autosave_parse_int(void) 65631ed9f9fSChengwen Feng { 657f48e4eedSChengwen Feng uint64_t flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE | RTE_ARGPARSE_ARG_VALUE_INT; 65831ed9f9fSChengwen Feng struct rte_argparse *obj; 65931ed9f9fSChengwen Feng int val_saver = 0; 66031ed9f9fSChengwen Feng char *argv[3]; 66131ed9f9fSChengwen Feng int ret; 66231ed9f9fSChengwen Feng 663*9684dfeaSChengwen Feng /* test positional autosave parse successful. */ 66431ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 66531ed9f9fSChengwen Feng obj->args[0].name_long = "test-long"; 66631ed9f9fSChengwen Feng obj->args[0].name_short = NULL; 66731ed9f9fSChengwen Feng obj->args[0].val_saver = (void *)&val_saver; 66831ed9f9fSChengwen Feng obj->args[0].val_set = NULL; 66931ed9f9fSChengwen Feng obj->args[0].flags = flags; 67031ed9f9fSChengwen Feng obj->args[1].name_long = NULL; 671*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 67231ed9f9fSChengwen Feng argv[1] = test_strdup("100"); 67331ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 67431ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 67531ed9f9fSChengwen Feng TEST_ASSERT(val_saver == 100, "Argparse parse expect success!"); 67631ed9f9fSChengwen Feng 677*9684dfeaSChengwen Feng /* test positional autosave parse failed. */ 67831ed9f9fSChengwen Feng obj->args[0].flags = flags; 67931ed9f9fSChengwen Feng val_saver = 0; 68031ed9f9fSChengwen Feng argv[1] = test_strdup("100a"); 68131ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 2, argv); 68231ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 68331ed9f9fSChengwen Feng 684*9684dfeaSChengwen Feng /* test too much position parameters. */ 68531ed9f9fSChengwen Feng obj->args[0].flags = flags; 68631ed9f9fSChengwen Feng argv[1] = test_strdup("100"); 68731ed9f9fSChengwen Feng argv[2] = test_strdup("200"); 68831ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 3, argv); 68931ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 69031ed9f9fSChengwen Feng 69131ed9f9fSChengwen Feng return 0; 69231ed9f9fSChengwen Feng } 69331ed9f9fSChengwen Feng 69431ed9f9fSChengwen Feng static int 69531ed9f9fSChengwen Feng pos_callback_parse_int(uint32_t index, const char *value, void *opaque) 69631ed9f9fSChengwen Feng { 69731ed9f9fSChengwen Feng uint32_t int_val; 69831ed9f9fSChengwen Feng char *s = NULL; 69931ed9f9fSChengwen Feng 70031ed9f9fSChengwen Feng if (index != 1 && index != 2) 70131ed9f9fSChengwen Feng return -EINVAL; 70231ed9f9fSChengwen Feng if (value == NULL) 70331ed9f9fSChengwen Feng return -EINVAL; 70431ed9f9fSChengwen Feng 70531ed9f9fSChengwen Feng int_val = strtol(value, &s, 0); 70631ed9f9fSChengwen Feng if (s[0] != '\0') 70731ed9f9fSChengwen Feng return -EINVAL; 70831ed9f9fSChengwen Feng 70931ed9f9fSChengwen Feng *((int *)opaque + index) = int_val; 71031ed9f9fSChengwen Feng 71131ed9f9fSChengwen Feng return 0; 71231ed9f9fSChengwen Feng } 71331ed9f9fSChengwen Feng 71431ed9f9fSChengwen Feng static int 71531ed9f9fSChengwen Feng test_argparse_pos_callback_parse_int(void) 71631ed9f9fSChengwen Feng { 71731ed9f9fSChengwen Feng int val_saver[3] = { 0, 0, 0 }; 71831ed9f9fSChengwen Feng struct rte_argparse *obj; 71931ed9f9fSChengwen Feng char *argv[3]; 72031ed9f9fSChengwen Feng int ret; 72131ed9f9fSChengwen Feng 722*9684dfeaSChengwen Feng /* test positional callback parse successful. */ 72331ed9f9fSChengwen Feng obj = test_argparse_init_obj(); 72431ed9f9fSChengwen Feng obj->callback = pos_callback_parse_int; 72531ed9f9fSChengwen Feng obj->opaque = (void *)val_saver; 72631ed9f9fSChengwen Feng obj->args[0].name_long = "test-long1"; 72731ed9f9fSChengwen Feng obj->args[0].name_short = NULL; 72831ed9f9fSChengwen Feng obj->args[0].val_saver = NULL; 72931ed9f9fSChengwen Feng obj->args[0].val_set = (void *)1; 73031ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE; 73131ed9f9fSChengwen Feng obj->args[1].name_long = "test-long2"; 73231ed9f9fSChengwen Feng obj->args[1].name_short = NULL; 73331ed9f9fSChengwen Feng obj->args[1].val_saver = NULL; 73431ed9f9fSChengwen Feng obj->args[1].val_set = (void *)2; 73531ed9f9fSChengwen Feng obj->args[1].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE; 73631ed9f9fSChengwen Feng obj->args[2].name_long = NULL; 737*9684dfeaSChengwen Feng argv[0] = test_strdup(obj->prog_name); 73831ed9f9fSChengwen Feng argv[1] = test_strdup("100"); 73931ed9f9fSChengwen Feng argv[2] = test_strdup("200"); 74031ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 3, argv); 74131ed9f9fSChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse expect success!"); 74231ed9f9fSChengwen Feng TEST_ASSERT(val_saver[1] == 100, "Argparse parse expect success!"); 74331ed9f9fSChengwen Feng TEST_ASSERT(val_saver[2] == 200, "Argparse parse expect success!"); 74431ed9f9fSChengwen Feng 745*9684dfeaSChengwen Feng /* test positional callback parse failed. */ 74631ed9f9fSChengwen Feng obj->args[0].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE; 74731ed9f9fSChengwen Feng obj->args[1].flags = RTE_ARGPARSE_ARG_REQUIRED_VALUE; 74831ed9f9fSChengwen Feng argv[2] = test_strdup("200a"); 74931ed9f9fSChengwen Feng ret = rte_argparse_parse(obj, 3, argv); 75031ed9f9fSChengwen Feng TEST_ASSERT(ret == -EINVAL, "Argparse parse expect failed!"); 75131ed9f9fSChengwen Feng 75231ed9f9fSChengwen Feng return 0; 75331ed9f9fSChengwen Feng } 75431ed9f9fSChengwen Feng 7559ccd7b27SChengwen Feng static int 7569ccd7b27SChengwen Feng test_argparse_parse_type(void) 7579ccd7b27SChengwen Feng { 7589ccd7b27SChengwen Feng char *str_erange = test_strdup("9999999999999999999999999999999999"); 7595357c248SChengwen Feng char *str_erange_u32 = test_strdup("4294967296"); 7605357c248SChengwen Feng char *str_erange_u16 = test_strdup("65536"); 7615357c248SChengwen Feng char *str_erange_u8 = test_strdup("256"); 7629ccd7b27SChengwen Feng char *str_invalid = test_strdup("1a"); 7639ccd7b27SChengwen Feng char *str_ok = test_strdup("123"); 7645357c248SChengwen Feng uint16_t val_u16; 7655357c248SChengwen Feng uint32_t val_u32; 7665357c248SChengwen Feng uint64_t val_u64; 7675357c248SChengwen Feng uint8_t val_u8; 7685357c248SChengwen Feng int val_int; 7699ccd7b27SChengwen Feng int ret; 7709ccd7b27SChengwen Feng 7719ccd7b27SChengwen Feng /* test for int parsing */ 7725357c248SChengwen Feng ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_INT, &val_int); 7739ccd7b27SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 7745357c248SChengwen Feng ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_INT, &val_int); 7759ccd7b27SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 7765357c248SChengwen Feng ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_INT, &val_int); 7779ccd7b27SChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); 7785357c248SChengwen Feng TEST_ASSERT(val_int == 123, "Argparse parse type expect failed!"); 7795357c248SChengwen Feng 7805357c248SChengwen Feng /* test for u8 parsing */ 7815357c248SChengwen Feng ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_U8, &val_u8); 7825357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 7835357c248SChengwen Feng ret = rte_argparse_parse_type(str_erange_u8, RTE_ARGPARSE_ARG_VALUE_U8, &val_u8); 7845357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 7855357c248SChengwen Feng ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_U8, &val_u8); 7865357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 7875357c248SChengwen Feng val_u8 = 0; 7885357c248SChengwen Feng ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_U8, &val_u8); 7895357c248SChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); 7905357c248SChengwen Feng TEST_ASSERT(val_u8 == 123, "Argparse parse type expect failed!"); 7915357c248SChengwen Feng 7925357c248SChengwen Feng /* test for u16 parsing */ 7935357c248SChengwen Feng ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_U16, &val_u16); 7945357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 7955357c248SChengwen Feng ret = rte_argparse_parse_type(str_erange_u16, RTE_ARGPARSE_ARG_VALUE_U16, &val_u16); 7965357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 7975357c248SChengwen Feng ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_U16, &val_u16); 7985357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 7995357c248SChengwen Feng val_u16 = 0; 8005357c248SChengwen Feng ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_U16, &val_u16); 8015357c248SChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); 8025357c248SChengwen Feng TEST_ASSERT(val_u16 == 123, "Argparse parse type expect failed!"); 8035357c248SChengwen Feng 8045357c248SChengwen Feng /* test for u32 parsing */ 8055357c248SChengwen Feng ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_U32, &val_u32); 8065357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 8075357c248SChengwen Feng ret = rte_argparse_parse_type(str_erange_u32, RTE_ARGPARSE_ARG_VALUE_U32, &val_u32); 8085357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 8095357c248SChengwen Feng ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_U32, &val_u32); 8105357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 8115357c248SChengwen Feng val_u32 = 0; 8125357c248SChengwen Feng ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_U32, &val_u32); 8135357c248SChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); 8145357c248SChengwen Feng TEST_ASSERT(val_u32 == 123, "Argparse parse type expect failed!"); 8155357c248SChengwen Feng 8165357c248SChengwen Feng /* test for u64 parsing */ 8175357c248SChengwen Feng ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_U64, &val_u64); 8185357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 8195357c248SChengwen Feng ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_U64, &val_u64); 8205357c248SChengwen Feng TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); 8215357c248SChengwen Feng val_u64 = 0; 8225357c248SChengwen Feng ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_U64, &val_u64); 8235357c248SChengwen Feng TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); 8245357c248SChengwen Feng TEST_ASSERT(val_u64 == 123, "Argparse parse type expect failed!"); 8259ccd7b27SChengwen Feng 8269ccd7b27SChengwen Feng return 0; 8279ccd7b27SChengwen Feng } 8289ccd7b27SChengwen Feng 8296c5c6571SChengwen Feng static struct unit_test_suite argparse_test_suite = { 8306c5c6571SChengwen Feng .suite_name = "Argparse Unit Test Suite", 8316c5c6571SChengwen Feng .setup = test_argparse_setup, 8326c5c6571SChengwen Feng .teardown = test_argparse_teardown, 8336c5c6571SChengwen Feng .unit_test_cases = { 8346c5c6571SChengwen Feng TEST_CASE(test_argparse_invalid_basic_param), 8356c5c6571SChengwen Feng TEST_CASE(test_argparse_invalid_arg_name), 8366c5c6571SChengwen Feng TEST_CASE(test_argparse_invalid_arg_help), 8376c5c6571SChengwen Feng TEST_CASE(test_argparse_invalid_has_val), 8386c5c6571SChengwen Feng TEST_CASE(test_argparse_invalid_arg_saver), 8396c5c6571SChengwen Feng TEST_CASE(test_argparse_invalid_arg_flags), 8406c5c6571SChengwen Feng TEST_CASE(test_argparse_invalid_arg_repeat), 84131ed9f9fSChengwen Feng TEST_CASE(test_argparse_invalid_option), 84231ed9f9fSChengwen Feng TEST_CASE(test_argparse_opt_autosave_parse_int_of_no_val), 84331ed9f9fSChengwen Feng TEST_CASE(test_argparse_opt_autosave_parse_int_of_required_val), 84431ed9f9fSChengwen Feng TEST_CASE(test_argparse_opt_autosave_parse_int_of_optional_val), 84531ed9f9fSChengwen Feng TEST_CASE(test_argparse_opt_callback_parse_int_of_no_val), 84631ed9f9fSChengwen Feng TEST_CASE(test_argparse_opt_callback_parse_int_of_required_val), 84731ed9f9fSChengwen Feng TEST_CASE(test_argparse_opt_callback_parse_int_of_optional_val), 84831ed9f9fSChengwen Feng TEST_CASE(test_argparse_pos_autosave_parse_int), 84931ed9f9fSChengwen Feng TEST_CASE(test_argparse_pos_callback_parse_int), 8509ccd7b27SChengwen Feng TEST_CASE(test_argparse_parse_type), 8516c5c6571SChengwen Feng 8526c5c6571SChengwen Feng TEST_CASES_END() /**< NULL terminate unit test array */ 8536c5c6571SChengwen Feng } 8546c5c6571SChengwen Feng }; 8556c5c6571SChengwen Feng 8566c5c6571SChengwen Feng static int 8576c5c6571SChengwen Feng test_argparse(void) 8586c5c6571SChengwen Feng { 8596c5c6571SChengwen Feng return unit_test_suite_runner(&argparse_test_suite); 8606c5c6571SChengwen Feng } 8616c5c6571SChengwen Feng 8626c5c6571SChengwen Feng REGISTER_FAST_TEST(argparse_autotest, true, true, test_argparse); 863