shell: Support output using a va_list
At present it is not possible to write a printf()-like function in board code which outputs to the shell. Add shell_vfprintf() to permit this. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
2a8463e2b8
commit
fc0e10d064
3 changed files with 59 additions and 9 deletions
|
@ -726,6 +726,21 @@ int shell_stop(const struct shell *shell);
|
|||
void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
|
||||
const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* @brief vprintf-like function which sends formatted data stream to the shell.
|
||||
*
|
||||
* This function can be used from the command handler or from threads, but not
|
||||
* from an interrupt context. It is similar to shell_fprintf() but takes a
|
||||
* va_list instead of variable arguments.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
* @param[in] color Printed text color.
|
||||
* @param[in] fmt Format string.
|
||||
* @param[in] args List of parameters to print.
|
||||
*/
|
||||
void shell_vfprintf(const struct shell *shell, enum shell_vt100_color color,
|
||||
const char *fmt, va_list args);
|
||||
|
||||
/**
|
||||
* @brief Print data in hexadecimal format.
|
||||
*
|
||||
|
|
|
@ -1304,8 +1304,8 @@ void shell_process(const struct shell *shell)
|
|||
/* This function mustn't be used from shell context to avoid deadlock.
|
||||
* However it can be used in shell command handlers.
|
||||
*/
|
||||
void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
|
||||
const char *fmt, ...)
|
||||
void shell_vfprintf(const struct shell *shell, enum shell_vt100_color color,
|
||||
const char *fmt, va_list args)
|
||||
{
|
||||
__ASSERT_NO_MSG(shell);
|
||||
__ASSERT(!k_is_in_isr(), "Thread context required.");
|
||||
|
@ -1315,17 +1315,11 @@ void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
|
|||
__ASSERT_NO_MSG(shell->fprintf_ctx);
|
||||
__ASSERT_NO_MSG(fmt);
|
||||
|
||||
va_list args;
|
||||
|
||||
k_mutex_lock(&shell->ctx->wr_mtx, K_FOREVER);
|
||||
if (!flag_cmd_ctx_get(shell)) {
|
||||
shell_cmd_line_erase(shell);
|
||||
}
|
||||
|
||||
va_start(args, fmt);
|
||||
shell_internal_vfprintf(shell, color, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (!flag_cmd_ctx_get(shell)) {
|
||||
shell_print_prompt_and_cmd(shell);
|
||||
}
|
||||
|
@ -1333,6 +1327,19 @@ void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
|
|||
k_mutex_unlock(&shell->ctx->wr_mtx);
|
||||
}
|
||||
|
||||
/* This function mustn't be used from shell context to avoid deadlock.
|
||||
* However it can be used in shell command handlers.
|
||||
*/
|
||||
void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
shell_vfprintf(shell, color, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void shell_hexdump_line(const struct shell *shell, unsigned int offset,
|
||||
const u8_t *data, size_t len)
|
||||
{
|
||||
|
|
|
@ -316,6 +316,33 @@ static void test_set_root_cmd(void)
|
|||
test_shell_execute_cmd("shell colors on", 0);
|
||||
}
|
||||
|
||||
static void test_shell_fprintf(void)
|
||||
{
|
||||
static const char expect[] = "testing 1 2 3";
|
||||
const struct shell *shell;
|
||||
const char *buf;
|
||||
size_t size;
|
||||
|
||||
shell = shell_backend_dummy_get_ptr();
|
||||
zassert_not_null(shell, "Failed to get shell");
|
||||
|
||||
/* Clear the output buffer */
|
||||
shell_backend_dummy_get_output(shell, &size);
|
||||
|
||||
shell_fprintf(shell, SHELL_VT100_COLOR_DEFAULT, "testing %d %s %c",
|
||||
1, "2", '3');
|
||||
buf = shell_backend_dummy_get_output(shell, &size);
|
||||
zassert_true(size >= sizeof(expect), "Expected size > %u, got %d",
|
||||
sizeof(expect), size);
|
||||
|
||||
/*
|
||||
* There are prompts and various ANSI characters in the output, so just
|
||||
* check that the string is in there somewhere.
|
||||
*/
|
||||
zassert_true(strstr(buf, expect),
|
||||
"Expected string to contain '%s', got '%s'", expect, buf);
|
||||
}
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(shell_test_suite,
|
||||
|
@ -328,7 +355,8 @@ void test_main(void)
|
|||
ztest_unit_test(test_cmd_resize),
|
||||
ztest_unit_test(test_shell_module),
|
||||
ztest_unit_test(test_shell_wildcards_static),
|
||||
ztest_unit_test(test_shell_wildcards_dynamic));
|
||||
ztest_unit_test(test_shell_wildcards_dynamic),
|
||||
ztest_unit_test(test_shell_fprintf));
|
||||
|
||||
ztest_run_test_suite(shell_test_suite);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue