diff options
| author | Tom Rini <[email protected]> | 2026-03-25 14:38:02 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-03-25 14:38:02 -0600 |
| commit | 6701997e9ca2cab0c0e1cde96437ac1dabefdaa1 (patch) | |
| tree | 66be5429de16b766e7eef0132b498e71bbfcfd27 | |
| parent | 1e2052f76e98ae70ab29113d271bb376ed23e8bb (diff) | |
| parent | 8b0619579b2282050e7fb0d92fbc645b79d18bae (diff) | |
Merge patch series "add [ as alias for test, fix 0/1 argument handling"
Rasmus Villemoes <[email protected]> says:
Make 'test' behave a little more like its cousins in other shells, by
allowing the [ ... ] spelling, and while here, fix up the handling of
a single, non-empty argument to comply with POSIX.
Link: https://lore.kernel.org/r/[email protected]
| -rw-r--r-- | cmd/test.c | 30 | ||||
| -rw-r--r-- | doc/usage/cmd/test.rst | 5 | ||||
| -rw-r--r-- | test/hush/if.c | 73 |
3 files changed, 105 insertions, 3 deletions
diff --git a/cmd/test.c b/cmd/test.c index a9ac07e6143..0d0f090386c 100644 --- a/cmd/test.c +++ b/cmd/test.c @@ -63,10 +63,25 @@ static int do_test(struct cmd_tbl *cmdtp, int flag, int argc, char * const *ap; int i, op, left, adv, expr, last_expr, last_unop, last_binop; - /* args? */ - if (argc < 3) + if (!strcmp(argv[0], "[")) { + if (strcmp(argv[argc - 1], "]")) { + printf("[: missing terminating ]\n"); + return 1; + } + argc--; + } + + /* + * Per POSIX, 'test' with 0 arguments should return 1, while + * 'test <arg>' should be equivalent to 'test -n <arg>', + * i.e. true if and only if <arg> is not empty. + */ + if (argc < 2) return 1; + if (argc == 2) + return !strcmp(argv[1], ""); + #ifdef DEBUG { debug("test(%d):", argc); @@ -212,6 +227,17 @@ U_BOOT_CMD( "[args..]" ); +/* + * This does not use the U_BOOT_CMD macro as [ can't be used in symbol names + */ +ll_entry_declare(struct cmd_tbl, lbracket, cmd) = { + "[", CONFIG_SYS_MAXARGS, cmd_always_repeatable, do_test, + "alias for 'test'", +#ifdef CONFIG_SYS_LONGHELP + " <test expression> ]" +#endif /* CONFIG_SYS_LONGHELP */ +}; + static int do_false(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { diff --git a/doc/usage/cmd/test.rst b/doc/usage/cmd/test.rst index d1379117fca..037a9ee1774 100644 --- a/doc/usage/cmd/test.rst +++ b/doc/usage/cmd/test.rst @@ -20,11 +20,14 @@ Synopsis test -e <interface> <dev[:part]> <path> test <s> =~ <re> + [ <test expression> ] + Description ----------- The ``test`` command is similar to the ordinary shell built-in by the -same name. Unlike in ordinary shells, it cannot be spelled ``[``. +same name. Like in ordinary shells, it can also be spelled ``[``, +provided the test expression is followed by a separate ``]`` argument. Strings ~~~~~~~ diff --git a/test/hush/if.c b/test/hush/if.c index ea615b246a9..6129e2c530c 100644 --- a/test/hush/if.c +++ b/test/hush/if.c @@ -32,6 +32,15 @@ static int hush_test_if_base(struct unit_test_state *uts) sprintf(if_formatted, if_format, "false"); ut_asserteq(1, run_command(if_formatted, 0)); + sprintf(if_formatted, if_format, "test"); + ut_asserteq(1, run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "test ''"); + ut_asserteq(1, run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "test 'abc'"); + ut_assertok(run_command(if_formatted, 0)); + return 0; } HUSH_TEST(hush_test_if_base, 0); @@ -315,3 +324,67 @@ static int hush_test_if_z_operator(struct unit_test_state *uts) return 0; } HUSH_TEST(hush_test_if_z_operator, 0); + +static int hush_test_lbracket_alias(struct unit_test_state *uts) +{ + char if_formatted[128]; + const char *missing_rbracket_error = "[: missing terminating ]"; + + sprintf(if_formatted, if_format, "[ aaa = aaa ]"); + ut_assertok(run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "[ aaa = bbb ]"); + ut_asserteq(1, run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "[ aaa = aaa"); + ut_asserteq(1, run_command(if_formatted, 0)); + ut_assert_nextline(missing_rbracket_error); + + sprintf(if_formatted, if_format, "[ aaa = bbb"); + ut_asserteq(1, run_command(if_formatted, 0)); + ut_assert_nextline(missing_rbracket_error); + + sprintf(if_formatted, if_format, "[ aaa = aaa]"); + ut_asserteq(1, run_command(if_formatted, 0)); + ut_assert_nextline(missing_rbracket_error); + + sprintf(if_formatted, if_format, "[ aaa = bbb]"); + ut_asserteq(1, run_command(if_formatted, 0)); + ut_assert_nextline(missing_rbracket_error); + + sprintf(if_formatted, if_format, "[ aaa != aaa -o bbb != bbb ]"); + ut_asserteq(1, run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "[ aaa != aaa -o bbb = bbb ]"); + ut_assertok(run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "[ ! aaa != aaa -o ! bbb != bbb ]"); + ut_assertok(run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "[ ! aaa != aaa -o ! bbb = bbb ]"); + ut_assertok(run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "[ ]"); + ut_asserteq(1, run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "["); + ut_asserteq(1, run_command(if_formatted, 0)); + ut_assert_nextline(missing_rbracket_error); + + sprintf(if_formatted, if_format, "[ '' ]"); + ut_asserteq(1, run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "[ ''"); + ut_asserteq(1, run_command(if_formatted, 0)); + ut_assert_nextline(missing_rbracket_error); + + sprintf(if_formatted, if_format, "[ 'abc' ]"); + ut_assertok(run_command(if_formatted, 0)); + + sprintf(if_formatted, if_format, "[ 'abc'"); + ut_asserteq(1, run_command(if_formatted, 0)); + ut_assert_nextline(missing_rbracket_error); + + return 0; +} +HUSH_TEST(hush_test_lbracket_alias, UTF_CONSOLE); |
