1 // SPDX-License-Identifier: GPL-2.0+
5 * Portions of these tests were inspired by glibc's posix/bug-getopt1.c and
6 * posix/tst-getopt-cancel.c
12 #include <test/test.h>
15 static int do_test_getopt(struct unit_test_state *uts, int line,
16 struct getopt_state *gs, const char *optstring,
17 int args, char *argv[], int expected_count,
22 getopt_init_state(gs);
23 for (int i = 0; i < expected_count; i++) {
24 opt = getopt_silent(gs, args, argv, optstring);
25 if (expected[i] != opt) {
27 * Fudge the line number so we can tell which test
30 ut_failf(uts, __FILE__, line, __func__,
31 "expected[i] == getopt()",
32 "Expected '%c' (%d) with i=%d, got '%c' (%d)",
33 expected[i], expected[i], i, opt, opt);
34 return CMD_RET_FAILURE;
38 opt = getopt_silent(gs, args, argv, optstring);
40 ut_failf(uts, __FILE__, line, __func__,
42 "Expected -1, got '%c' (%d)", opt, opt);
43 return CMD_RET_FAILURE;
49 #define test_getopt(optstring, argv, expected) do { \
50 int ret = do_test_getopt(uts, __LINE__, &gs, optstring, \
51 ARRAY_SIZE(argv) - 1, argv, \
52 ARRAY_SIZE(expected), expected); \
57 static int lib_test_getopt(struct unit_test_state *uts)
59 struct getopt_state gs;
63 ((char *[]){ "program", "-cb", "x", "-a", "foo", 0 }),
64 ((int []){ 'c', 'b', 'a' }));
65 ut_asserteq(4, gs.index);
67 /* Make sure we pick up the optional argument */
69 ((char *[]){ "program", "-cbx", "-a", "foo", 0 }),
70 ((int []){ 'c', 'b', 'a' }));
71 ut_asserteq(4, gs.index);
73 /* Test required arguments */
74 test_getopt("a:b", ((char *[]){ "program", "-a", 0 }),
76 ut_asserteq('a', gs.opt);
77 test_getopt("a:b", ((char *[]){ "program", "-b", "-a", 0 }),
78 ((int []){ 'b', ':' }));
79 ut_asserteq('a', gs.opt);
81 /* Test invalid arguments */
82 test_getopt("ab:c", ((char *[]){ "program", "-d", 0 }),
84 ut_asserteq('d', gs.opt);
88 ((char *[]){ "program", "-a", 0 }),
90 ut_asserteq(2, gs.index);
91 ut_assertnull(gs.arg);
94 ((char *[]){ "program", "-afoo", 0 }),
96 ut_asserteq(2, gs.index);
97 ut_assertnonnull(gs.arg);
98 ut_asserteq_str("foo", gs.arg);
100 test_getopt("a::b:c",
101 ((char *[]){ "program", "-a", "foo", 0 }),
103 ut_asserteq(3, gs.index);
104 ut_assertnonnull(gs.arg);
105 ut_asserteq_str("foo", gs.arg);
107 test_getopt("a::b:c",
108 ((char *[]){ "program", "-bfoo", 0 }),
110 ut_asserteq(2, gs.index);
111 ut_assertnonnull(gs.arg);
112 ut_asserteq_str("foo", gs.arg);
114 test_getopt("a::b:c",
115 ((char *[]){ "program", "-b", "foo", 0 }),
117 ut_asserteq(3, gs.index);
118 ut_assertnonnull(gs.arg);
119 ut_asserteq_str("foo", gs.arg);
123 LIB_TEST(lib_test_getopt, 0);