console: Provide a way to output without the pager
Sometimes output should be sent ignoring the pager, such as when it is a message related to paging. Add a parameter to support this. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
@@ -14,12 +14,12 @@
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
const char *pager_post(struct pager *pag, const char *s)
|
||||
const char *pager_post(struct pager *pag, bool use_pager, const char *s)
|
||||
{
|
||||
struct membuf old;
|
||||
int ret, len;
|
||||
|
||||
if (!pag)
|
||||
if (!pag || !use_pager)
|
||||
return s;
|
||||
|
||||
len = strlen(s);
|
||||
@@ -44,14 +44,17 @@ const char *pager_post(struct pager *pag, const char *s)
|
||||
pag->mb = old;
|
||||
}
|
||||
|
||||
return pager_next(pag, 0);
|
||||
return pager_next(pag, true, 0);
|
||||
}
|
||||
|
||||
const char *pager_next(struct pager *pag, int key)
|
||||
const char *pager_next(struct pager *pag, bool use_pager, int key)
|
||||
{
|
||||
char *str, *p, *end;
|
||||
int ret;
|
||||
|
||||
if (!use_pager)
|
||||
return NULL;
|
||||
|
||||
/* replace the real character we overwrite with nul, if needed */
|
||||
if (pag->nulch) {
|
||||
*pag->nulch = pag->oldch;
|
||||
|
||||
@@ -81,7 +81,7 @@ struct pager {
|
||||
/**
|
||||
* pager_post() - Add text to the input buffer for later handling
|
||||
*
|
||||
* The text is added to the pager buffer and fed out a screenful
|
||||
* If @use_pager the text is added to the pager buffer and fed out a screenful
|
||||
* at a time. This function calls pager_post() after storing the text.
|
||||
*
|
||||
* After calling pager_post(), if it returns anything other than NULL, you must
|
||||
@@ -91,10 +91,12 @@ struct pager {
|
||||
* If @pag is NULL, this does nothing but return @s
|
||||
*
|
||||
* @pag: Pager to use, may be NULL
|
||||
* @use_pager: Whether or not to use the pager functionality
|
||||
* @s: Text to add
|
||||
* Return: text which should be sent to output, or NULL if there is no more.
|
||||
* If !@use_pager this just returns @s and does not affect the pager state
|
||||
*/
|
||||
const char *pager_post(struct pager *pag, const char *s);
|
||||
const char *pager_post(struct pager *pag, bool use_pager, const char *s);
|
||||
|
||||
/**
|
||||
* pager_next() - Returns the next screenful of text to show
|
||||
@@ -105,12 +107,14 @@ const char *pager_post(struct pager *pag, const char *s);
|
||||
* return PAGER_WAITING until @ch is non-zero.
|
||||
*
|
||||
* @pag: Pager to use
|
||||
* @use_pager: Whether or not to use the pager functionality
|
||||
* @ch: Key that the user has pressed, or 0 if none
|
||||
*
|
||||
* Return: text which should be sent to output, or PAGER_WAITING if waiting for
|
||||
* the user to press a key, or NULL if there is no more text.
|
||||
* If !@use_pager this just returns NULL and does not affect the pager state
|
||||
*/
|
||||
const char *pager_next(struct pager *pag, int ch);
|
||||
const char *pager_next(struct pager *pag, bool use_pager, int ch);
|
||||
|
||||
/**
|
||||
* pager_uninit() - Uninit the pager
|
||||
@@ -122,12 +126,13 @@ const char *pager_next(struct pager *pag, int ch);
|
||||
void pager_uninit(struct pager *pag);
|
||||
|
||||
#else
|
||||
static inline const char *pager_post(struct pager *pag, const char *s)
|
||||
static inline const char *pager_post(struct pager *pag, bool use_pager,
|
||||
const char *s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline const char *pager_next(struct pager *pag, int ch)
|
||||
static inline const char *pager_next(struct pager *pag, bool use_pager, int ch)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -50,12 +50,12 @@ static int pager_test_simple_text(struct unit_test_state *uts)
|
||||
ut_assertok(pager_init(&pag, 20, 1024));
|
||||
|
||||
/* Post some text and get it back */
|
||||
result = pager_post(pag, text);
|
||||
result = pager_post(pag, true, text);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(text, result);
|
||||
|
||||
/* Should be no more text */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnull(result);
|
||||
|
||||
pager_uninit(pag);
|
||||
@@ -79,28 +79,28 @@ static int pager_test_multiline(struct unit_test_state *uts)
|
||||
ut_assertok(pager_init(&pag, 20, 1024));
|
||||
|
||||
/* Post multiple pieces of text */
|
||||
result = pager_post(pag, text1);
|
||||
result = pager_post(pag, true, text1);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(text1, result);
|
||||
|
||||
/* Should be no more text after first post */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnull(result);
|
||||
|
||||
result = pager_post(pag, text2);
|
||||
result = pager_post(pag, true, text2);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(text2, result);
|
||||
|
||||
/* Should be no more text after second post */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnull(result);
|
||||
|
||||
result = pager_post(pag, text3);
|
||||
result = pager_post(pag, true, text3);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(text3, result);
|
||||
|
||||
/* Should be no more text after third post */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnull(result);
|
||||
|
||||
pager_uninit(pag);
|
||||
@@ -121,10 +121,10 @@ static int pager_test_large_text(struct unit_test_state *uts)
|
||||
ut_assertok(pager_init(&pag, 20, 16)); /* Small buffer */
|
||||
|
||||
/* Post large text - should fit in buffer */
|
||||
result = pager_post(pag, "this is 16 chars");
|
||||
result = pager_post(pag, true, "this is 16 chars");
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str("this is 16 chars", result);
|
||||
ut_assertnull(pager_next(pag, 0));
|
||||
ut_assertnull(pager_next(pag, true, 0));
|
||||
|
||||
pager_uninit(pag);
|
||||
|
||||
@@ -141,12 +141,12 @@ static int pager_test_overflow(struct unit_test_state *uts)
|
||||
ut_assertok(pager_init(&pag, 20, 4)); /* Small buffer */
|
||||
|
||||
/* send some text which is too long for the buffer */
|
||||
result = pager_post(pag, "test1");
|
||||
result = pager_post(pag, true, "test1");
|
||||
ut_assertnonnull(result);
|
||||
|
||||
/* overflow handling should return the text */
|
||||
ut_asserteq_str("test1", result);
|
||||
ut_assertnull(pager_next(pag, 0));
|
||||
ut_assertnull(pager_next(pag, true, 0));
|
||||
|
||||
pager_uninit(pag);
|
||||
|
||||
@@ -160,7 +160,7 @@ static int pager_test_null_input(struct unit_test_state *uts)
|
||||
const char *result;
|
||||
|
||||
/* Test pager_post with NULL pager */
|
||||
result = pager_post(NULL, "test");
|
||||
result = pager_post(NULL, true, "test");
|
||||
ut_asserteq_str("test", result);
|
||||
|
||||
return 0;
|
||||
@@ -176,11 +176,11 @@ static int pager_test_empty_strings(struct unit_test_state *uts)
|
||||
ut_assertok(pager_init(&pag, 20, 1024));
|
||||
|
||||
/* Post empty string */
|
||||
result = pager_post(pag, "");
|
||||
result = pager_post(pag, true, "");
|
||||
ut_assertnull(result);
|
||||
|
||||
/* Should be no more text */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnull(result);
|
||||
|
||||
pager_uninit(pag);
|
||||
@@ -203,7 +203,7 @@ static int pager_test_buffer_management(struct unit_test_state *uts)
|
||||
ut_asserteq(1024, pag->buf.size);
|
||||
|
||||
/* Post text and verify buffer state */
|
||||
result = pager_post(pag, text);
|
||||
result = pager_post(pag, true, text);
|
||||
ut_assertnonnull(result);
|
||||
|
||||
/* Verify the buffer contains our text */
|
||||
@@ -229,7 +229,7 @@ static int pager_test_long_single_line(struct unit_test_state *uts)
|
||||
long_line[sizeof(long_line) - 1] = '\0';
|
||||
|
||||
/* Post the long line */
|
||||
result = pager_post(pag, long_line);
|
||||
result = pager_post(pag, true, long_line);
|
||||
ut_assertnonnull(result);
|
||||
|
||||
/* Should get our text back */
|
||||
@@ -252,7 +252,7 @@ static int pager_test_line_counting(struct unit_test_state *uts)
|
||||
ut_assertok(pager_init(&pag, 4, 1024));
|
||||
|
||||
/* Post multiline text */
|
||||
result = pager_post(pag, multiline_text);
|
||||
result = pager_post(pag, true, multiline_text);
|
||||
ut_assertnonnull(result);
|
||||
|
||||
/* Should get first 3 lines (excluding the 3rd newline) */
|
||||
@@ -261,22 +261,22 @@ static int pager_test_line_counting(struct unit_test_state *uts)
|
||||
ut_asserteq(0, pag->line_count);
|
||||
|
||||
/* Next call should return pager prompt */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(PAGER_PROMPT, result);
|
||||
|
||||
/* Press space to continue */
|
||||
result = pager_next(pag, ' ');
|
||||
result = pager_next(pag, true, ' ');
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(PAGER_BLANK, result);
|
||||
|
||||
/* Get remaining lines */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str("Line 4\nLine 5\n", result);
|
||||
|
||||
/* Should be no more text */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnull(result);
|
||||
|
||||
pager_uninit(pag);
|
||||
@@ -295,30 +295,30 @@ static int pager_test_pager_waiting(struct unit_test_state *uts)
|
||||
ut_assertok(pager_init(&pag, 3, 1024));
|
||||
|
||||
/* Post text that fills exactly the page limit */
|
||||
result = pager_post(pag, "Line 1\nLine 2\n");
|
||||
result = pager_post(pag, true, "Line 1\nLine 2\n");
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str("Line 1\nLine 2", result);
|
||||
|
||||
/* Next call should return the prompt */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(PAGER_PROMPT, result);
|
||||
|
||||
/* Next call without space key should return PAGER_WAITING */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_asserteq_ptr(PAGER_WAITING, result);
|
||||
|
||||
/* Another call without space should still return PAGER_WAITING */
|
||||
result = pager_next(pag, 'x'); /* Wrong key */
|
||||
result = pager_next(pag, true, 'x'); /* Wrong key */
|
||||
ut_asserteq_ptr(PAGER_WAITING, result);
|
||||
|
||||
/* Pressing space should clear the prompt */
|
||||
result = pager_next(pag, ' ');
|
||||
result = pager_next(pag, true, ' ');
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str("\r \r", result);
|
||||
ut_asserteq_str(PAGER_BLANK, result);
|
||||
|
||||
/* Now should return NULL (no more content) */
|
||||
result = pager_next(pag, 0);
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnull(result);
|
||||
|
||||
pager_uninit(pag);
|
||||
@@ -326,3 +326,70 @@ static int pager_test_pager_waiting(struct unit_test_state *uts)
|
||||
return 0;
|
||||
}
|
||||
COMMON_TEST(pager_test_pager_waiting, 0);
|
||||
|
||||
/* Test use_pager parameter - output text directly, while buffer is non-empty */
|
||||
static int pager_test_use_pager_param(struct unit_test_state *uts)
|
||||
{
|
||||
struct pager *pag;
|
||||
const char *buffered_text = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n";
|
||||
const char *direct_text = "This should be written immediately";
|
||||
const char *result;
|
||||
|
||||
/* Init with small page length to ensure paging occurs */
|
||||
ut_assertok(pager_init(&pag, 3, 1024));
|
||||
|
||||
/* Post text with use_pager=true - should trigger paging */
|
||||
result = pager_post(pag, true, buffered_text);
|
||||
ut_assertnonnull(result);
|
||||
/* Should get first 2 lines */
|
||||
ut_asserteq_str("Line 1\nLine 2", result);
|
||||
|
||||
/* Now call pager_post with use_pager=false while text is still buffered */
|
||||
result = pager_post(pag, false, direct_text);
|
||||
/* Should get the text immediately, not from buffer */
|
||||
ut_asserteq_ptr(direct_text, result);
|
||||
|
||||
/* Call pager_next with use_pager=false - should return NULL */
|
||||
result = pager_next(pag, false, 0);
|
||||
ut_assertnull(result);
|
||||
|
||||
/* Now continue with use_pager=true to get buffered text */
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnonnull(result);
|
||||
/* Should get the pager prompt */
|
||||
ut_asserteq_str(PAGER_PROMPT, result);
|
||||
|
||||
/* Press space to continue */
|
||||
result = pager_next(pag, true, ' ');
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(PAGER_BLANK, result);
|
||||
|
||||
/* Get remaining buffered lines - should be next 2 lines due to page limit */
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str("Line 3\nLine 4", result);
|
||||
|
||||
/* Should get pager prompt again */
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(PAGER_PROMPT, result);
|
||||
|
||||
/* Press space to continue */
|
||||
result = pager_next(pag, true, ' ');
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str(PAGER_BLANK, result);
|
||||
|
||||
/* Get final line */
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnonnull(result);
|
||||
ut_asserteq_str("Line 5\n", result);
|
||||
|
||||
/* Should be no more text */
|
||||
result = pager_next(pag, true, 0);
|
||||
ut_assertnull(result);
|
||||
|
||||
pager_uninit(pag);
|
||||
|
||||
return 0;
|
||||
}
|
||||
COMMON_TEST(pager_test_use_pager_param, 0);
|
||||
|
||||
Reference in New Issue
Block a user