aboutsummaryrefslogtreecommitdiffstats
path: root/vlib
diff options
context:
space:
mode:
Diffstat (limited to 'vlib')
-rw-r--r--vlib/vlib/unix/cli.c452
1 files changed, 364 insertions, 88 deletions
diff --git a/vlib/vlib/unix/cli.c b/vlib/vlib/unix/cli.c
index 70ffdec74b9..c34ae219297 100644
--- a/vlib/vlib/unix/cli.c
+++ b/vlib/vlib/unix/cli.c
@@ -116,6 +116,18 @@ _("\n")
};
#undef _
+/** Pager line index */
+typedef struct {
+ /** Index into pager_vector */
+ u32 line;
+
+ /** Offset of the string in the line */
+ u32 offset;
+
+ /** Length of the string in the line */
+ u32 length;
+} unix_cli_pager_index_t;
+
/** Unix CLI session. */
typedef struct {
@@ -164,8 +176,8 @@ typedef struct {
/** Pager buffer */
u8 ** pager_vector;
- /** Lines currently displayed */
- u32 pager_lines;
+ /** Index of line fragments in the pager buffer */
+ unix_cli_pager_index_t * pager_index;
/** Line number of top of page */
u32 pager_start;
@@ -188,12 +200,16 @@ unix_cli_pager_reset (unix_cli_file_t *f)
{
u8 ** p;
- f->pager_lines = f->pager_start = 0;
+ f->pager_start = 0;
+
+ vec_free (f->pager_index);
+ f->pager_index = 0;
+
vec_foreach (p, f->pager_vector)
{
- vec_free(*p);
+ vec_free (*p);
}
- vec_free(f->pager_vector);
+ vec_free (f->pager_vector);
f->pager_vector = 0;
}
@@ -205,7 +221,7 @@ unix_cli_file_free (unix_cli_file_t * f)
{
vec_free (f->output_vector);
vec_free (f->input_vector);
- unix_cli_pager_reset(f);
+ unix_cli_pager_reset (f);
}
/** CLI actions */
@@ -240,6 +256,7 @@ typedef enum {
UNIX_CLI_PARSE_ACTION_PAGER_BOTTOM,
UNIX_CLI_PARSE_ACTION_PAGER_PGDN,
UNIX_CLI_PARSE_ACTION_PAGER_PGUP,
+ UNIX_CLI_PARSE_ACTION_PAGER_REDRAW,
UNIX_CLI_PARSE_ACTION_PAGER_SEARCH,
UNIX_CLI_PARSE_ACTION_PARTIALMATCH,
@@ -344,6 +361,8 @@ static unix_cli_parse_actions_t unix_cli_parse_pager[] = {
/* Pager commands */
_( " ", UNIX_CLI_PARSE_ACTION_PAGER_NEXT ),
_( "q", UNIX_CLI_PARSE_ACTION_PAGER_QUIT ),
+ _( CTL('L'), UNIX_CLI_PARSE_ACTION_PAGER_REDRAW ),
+ _( CTL('R'), UNIX_CLI_PARSE_ACTION_PAGER_REDRAW ),
_( "/", UNIX_CLI_PARSE_ACTION_PAGER_SEARCH ),
/* VT100 */
@@ -615,7 +634,7 @@ static void unix_cli_pager_prompt(unix_cli_file_t * cf, unix_file_t * uf)
cf->ansi_capable ? ANSI_BOLD : "",
cf->pager_start + 1,
cf->pager_start + cf->height,
- cf->pager_lines,
+ vec_len (cf->pager_index),
cf->ansi_capable ? ANSI_RESET: "");
unix_vlib_cli_output_cooked(cf, uf, prompt, vec_len(prompt));
@@ -673,7 +692,205 @@ static void unix_cli_ansi_cursor(unix_cli_file_t * cf, unix_file_t * uf,
vec_free(str);
}
-/** \brief VLIB CLI output function. */
+/** Redraw the currently displayed page of text.
+ * @param cf CLI session to redraw the pager buffer of.
+ * @param uf Unix file of the CLI session.
+ */
+static void unix_cli_pager_redraw(unix_cli_file_t * cf, unix_file_t * uf)
+{
+ unix_cli_pager_index_t * pi = NULL;
+ u8 * line = NULL;
+ word i;
+
+ /* No active pager? Do nothing. */
+ if (!vec_len (cf->pager_index))
+ return;
+
+ if (cf->ansi_capable)
+ {
+ /* If we have ANSI, send the clear screen sequence */
+ unix_vlib_cli_output_cooked (cf, uf,
+ (u8 *)ANSI_CLEAR, sizeof(ANSI_CLEAR) - 1);
+ }
+ else
+ {
+ /* Otherwise make sure we're on a blank line */
+ unix_cli_pager_prompt_erase (cf, uf);
+ }
+
+ /* (Re-)send the current page of content */
+ for (i = 0; i < cf->height - 1 &&
+ i + cf->pager_start < vec_len (cf->pager_index);
+ i ++)
+ {
+ pi = &cf->pager_index[cf->pager_start + i];
+ line = cf->pager_vector[pi->line] + pi->offset;
+
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
+ }
+ /* if the last line didn't end in newline, add a newline */
+ if (pi && line[pi->length - 1] != '\n')
+ unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1);
+
+ unix_cli_pager_prompt (cf, uf);
+}
+
+/** @brief Process and add a line to the pager index.
+ * In normal operation this function will take the given character string
+ * found in @c line and with length @c len_or_index and iterates the over the
+ * contents, adding each line of text discovered within it to the
+ * pager index. Lines are identified by newlines ("<code>\\n</code>") and by
+ * strings longer than the width of the terminal.
+ *
+ * If instead @c line is @c NULL then @c len_or_index is taken to mean the
+ * index of an existing line in the pager buffer; this simply means that the
+ * input line does not need to be cloned since we alreayd have it. This is
+ * typical if we are reindexing the pager buffer.
+ *
+ * @param cf The CLI session whose pager we are adding to.
+ * @param line The string of text to be indexed into the pager buffer.
+ * If @c line is @c NULL then the mode of operation
+ * changes slightly; see the description above.
+ * @param len_or_index If @c line is a pointer to a string then this parameter
+ * indicates the length of that string; Otherwise this
+ * value provides the index in the pager buffer of an
+ * existing string to be indexed.
+ */
+static void unix_cli_pager_add_line (unix_cli_file_t * cf,
+ u8 * line,
+ word len_or_index)
+{
+ u8 * p;
+ word i, j, k;
+ word line_index, len;
+ u32 width = cf->width;
+ unix_cli_pager_index_t * pi;
+
+ if (line == NULL)
+ {
+ /* Use a line already in the pager buffer */
+ line_index = len_or_index;
+ p = cf->pager_vector[line_index];
+ len = vec_len (p);
+ }
+ else
+ {
+ len = len_or_index;
+ /* Add a copy of the raw string to the pager buffer */
+ p = vec_new (u8, len);
+ clib_memcpy (p, line, len);
+
+ /* store in pager buffer */
+ line_index = vec_len (cf->pager_vector);
+ vec_add1 (cf->pager_vector, p);
+ }
+
+ i = 0;
+ while (i < len)
+ {
+ /* Find the next line, or run to terminal width, or run to EOL */
+ int l = len - i;
+ j = unix_vlib_findchr((u8)'\n', p, l < width ? l : width);
+
+ if (j < l && p[j] == '\n') /* incl \n */
+ j ++;
+
+ /* Add the line to the index */
+ k = vec_len (cf->pager_index);
+ vec_validate (cf->pager_index, k);
+ pi = &cf->pager_index[k];
+
+ pi->line = line_index;
+ pi->offset = i;
+ pi->length = j;
+
+ i += j;
+ p += j;
+ }
+}
+
+/** @brief Reindex entire pager buffer.
+ * Resets the current pager index and then re-adds the lines in the pager
+ * buffer to the index.
+ *
+ * Additionally this function attempts to retain the current page start
+ * line offset by searching for the same top-of-screen line in the new index.
+ *
+ * @param cf The CLI session whose pager buffer should be reindexed.
+ */
+static void unix_cli_pager_reindex (unix_cli_file_t * cf)
+{
+ word i, old_line, old_offset;
+ unix_cli_pager_index_t * pi;
+
+ /* If there is nothing in the pager buffer then make sure the index
+ * is empty and move on.
+ */
+ if (cf->pager_vector == 0)
+ {
+ vec_reset_length (cf->pager_index);
+ return;
+ }
+
+ /* Retain a pointer to the current page start line so we can
+ * find it later
+ */
+ pi = &cf->pager_index[cf->pager_start];
+ old_line = pi->line;
+ old_offset = pi->offset;
+
+ /* Re-add the buffered lines to the index */
+ vec_reset_length (cf->pager_index);
+ vec_foreach_index(i, cf->pager_vector)
+ {
+ unix_cli_pager_add_line(cf, NULL, i);
+ }
+
+ /* Attempt to re-locate the previously stored page start line */
+ vec_foreach_index(i, cf->pager_index)
+ {
+ pi = &cf->pager_index[i];
+
+ if (pi->line == old_line &&
+ (pi->offset <= old_offset ||
+ pi->offset + pi->length > old_offset))
+ {
+ /* Found it! */
+ cf->pager_start = i;
+ break;
+ }
+ }
+
+ /* In case the start line was not found (rare), ensure the pager start
+ * index is within bounds
+ */
+ if (cf->pager_start >= vec_len (cf->pager_index))
+ {
+ cf->pager_start = vec_len (cf->pager_index) - cf->height + 1;
+
+ if (cf->pager_start < 0)
+ cf->pager_start = 0;
+ }
+}
+
+/** VLIB CLI output function.
+ *
+ * If the terminal has a pager configured then this function takes care
+ * of collating output into the pager buffer; ensuring only the first page
+ * is displayed and any lines in excess of the first page are buffered.
+ *
+ * If the maximum number of index lines in the buffer is exceeded then the
+ * pager is cancelled and the contents of the current buffer are sent to the
+ * terminal.
+ *
+ * If there is no pager configured then the output is sent directly to the
+ * terminal.
+ *
+ * @param cli_file_index Index of the CLI session where this output is
+ * directed.
+ * @param buffer String of printabe bytes to be output.
+ * @param buffer_bytes The number of bytes in @c buffer to be output.
+ */
static void unix_vlib_cli_output (uword cli_file_index,
u8 * buffer,
uword buffer_bytes)
@@ -688,75 +905,80 @@ static void unix_vlib_cli_output (uword cli_file_index,
if (cf->no_pager || um->cli_pager_buffer_limit == 0 || cf->height == 0)
{
- unix_vlib_cli_output_cooked(cf, uf, buffer, buffer_bytes);
+ unix_vlib_cli_output_cooked (cf, uf, buffer, buffer_bytes);
}
else
{
- /* At each \n add the line to the pager buffer.
- * If we've not yet displayed a whole page in this command then
- * also output the line.
- * If we have displayed a whole page then display a pager prompt
- * and count the lines we've buffered.
- */
- u8 * p = buffer;
+ word row = vec_len (cf->pager_index);
u8 * line;
- uword i, len = buffer_bytes;
-
- while (len)
- {
- i = unix_vlib_findchr('\n', p, len);
- if (i < len)
- i ++; /* include the '\n' */
-
- /* make a vec out of this substring */
- line = vec_new(u8, i);
- memcpy(line, p, i);
+ unix_cli_pager_index_t * pi;
- /* store in pager buffer */
- vec_add1(cf->pager_vector, line);
- cf->pager_lines ++;
+ /* Index and add the output lines to the pager buffer. */
+ unix_cli_pager_add_line (cf, buffer, buffer_bytes);
- if (cf->pager_lines < cf->height)
+ /* Now iterate what was added to display the lines.
+ * If we reach the bottom of the page, display a prompt.
+ */
+ while (row < vec_len (cf->pager_index))
+ {
+ if (row < cf->height - 1)
{
/* output this line */
- unix_vlib_cli_output_cooked(cf, uf, p, i);
- /* TODO: stop if line longer than cf->width and would
- * overflow cf->height */
+ pi = &cf->pager_index[row];
+ line = cf->pager_vector[pi->line] + pi->offset;
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
+
+ /* if the last line didn't end in newline, and we're at the
+ * bottom of the page, add a newline */
+ if (line[pi->length - 1] != '\n' && row == cf->height - 2)
+ unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1);
}
else
{
/* Display the pager prompt every 10 lines */
- if (!(cf->pager_lines % 10))
+ if (!(row % 10))
unix_cli_pager_prompt(cf, uf);
}
-
- p += i;
- len -= i;
+ row ++;
}
- /* Check if we went over the pager buffer limit */
- if (cf->pager_lines > um->cli_pager_buffer_limit)
- {
- /* Stop using the pager for the remainder of this CLI command */
- cf->no_pager = 2;
+ /* Check if we went over the pager buffer limit */
+ if (vec_len (cf->pager_index) > um->cli_pager_buffer_limit)
+ {
+ /* Stop using the pager for the remainder of this CLI command */
+ cf->no_pager = 2;
- /* If we likely printed the prompt, erase it */
- if (cf->pager_lines > cf->height - 1)
- unix_cli_pager_prompt_erase (cf, uf);
+ /* If we likely printed the prompt, erase it */
+ if (vec_len (cf->pager_index) > cf->height - 1)
+ unix_cli_pager_prompt_erase (cf, uf);
- /* Dump out the contents of the buffer */
- for (i = cf->pager_start + (cf->height - 1);
- i < cf->pager_lines; i ++)
- unix_vlib_cli_output_cooked (cf, uf,
- cf->pager_vector[i],
- vec_len(cf->pager_vector[i]));
+ /* Dump out the contents of the buffer */
+ for (row = cf->pager_start + (cf->height - 1);
+ row < vec_len (cf->pager_index); row ++)
+ {
+ pi = &cf->pager_index[row];
+ line = cf->pager_vector[pi->line] + pi->offset;
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
+ }
- unix_cli_pager_reset (cf);
- }
+ unix_cli_pager_reset (cf);
+ }
}
}
-/** \brief Identify whether a terminal type is ANSI capable. */
+/** Identify whether a terminal type is ANSI capable.
+ *
+ * Compares the string given in @term with a list of terminal types known
+ * to support ANSI escape sequences.
+ *
+ * This list contains, for example, @c xterm, @c screen and @c ansi.
+ *
+ * @param term A string with a terminal type in it.
+ * @param len The length of the string in @term.
+ *
+ * @return @c 1 if the terminal type is recognized as supporting ANSI
+ * terminal sequences; @c 0 otherwise.
+ */
static u8 unix_cli_terminal_type(u8 * term, uword len)
{
/* This may later be better done as a hash of some sort. */
@@ -906,6 +1128,10 @@ static i32 unix_cli_process_telnet(unix_main_t * um,
break;
cf->width = clib_net_to_host_u16(*((u16 *)(input_vector + 3)));
cf->height = clib_net_to_host_u16(*((u16 *)(input_vector + 5)));
+ /* reindex pager buffer */
+ unix_cli_pager_reindex (cf);
+ /* redraw page */
+ unix_cli_pager_redraw (cf, uf);
break;
default:
@@ -1308,18 +1534,24 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm,
case UNIX_CLI_PARSE_ACTION_PAGER_NEXT:
case UNIX_CLI_PARSE_ACTION_PAGER_PGDN:
/* show next page of the buffer */
- if (cf->height + cf->pager_start < cf->pager_lines)
+ if (cf->height + cf->pager_start < vec_len (cf->pager_index))
{
- u8 * line;
+ u8 * line = NULL;
+ unix_cli_pager_index_t * pi = NULL;
+
int m = cf->pager_start + (cf->height - 1);
unix_cli_pager_prompt_erase (cf, uf);
for (j = m;
- j < cf->pager_lines && cf->pager_start < m;
+ j < vec_len (cf->pager_index) && cf->pager_start < m;
j ++, cf->pager_start ++)
{
- line = cf->pager_vector[j];
- unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line));
+ pi = &cf->pager_index[j];
+ line = cf->pager_vector[pi->line] + pi->offset;
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
}
+ /* if the last line didn't end in newline, add a newline */
+ if (pi && line[pi->length - 1] != '\n')
+ unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1);
unix_cli_pager_prompt (cf, uf);
}
else
@@ -1333,13 +1565,19 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm,
case UNIX_CLI_PARSE_ACTION_PAGER_DN:
case UNIX_CLI_PARSE_ACTION_PAGER_CRLF:
/* display the next line of the buffer */
- if (cf->pager_start < cf->pager_lines - (cf->height - 1))
+ if (cf->pager_start < vec_len (cf->pager_index) - (cf->height - 1))
{
u8 * line;
+ unix_cli_pager_index_t * pi;
+
unix_cli_pager_prompt_erase (cf, uf);
- line = cf->pager_vector[cf->pager_start + (cf->height - 1)];
- unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line));
+ pi = &cf->pager_index[cf->pager_start + (cf->height - 1)];
+ line = cf->pager_vector[pi->line] + pi->offset;
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
cf->pager_start ++;
+ /* if the last line didn't end in newline, add a newline */
+ if (line[pi->length - 1] != '\n')
+ unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1);
unix_cli_pager_prompt (cf, uf);
}
else
@@ -1355,16 +1593,20 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm,
/* scroll the page back one line */
if (cf->pager_start > 0)
{
- u8 * line;
+ u8 * line = NULL;
+ unix_cli_pager_index_t * pi = NULL;
+
cf->pager_start --;
if (cf->ansi_capable)
{
+ pi = &cf->pager_index[cf->pager_start];
+ line = cf->pager_vector[pi->line] + pi->offset;
unix_cli_pager_prompt_erase (cf, uf);
unix_vlib_cli_output_cooked (cf, uf, (u8 *)ANSI_SCROLLDN, sizeof(ANSI_SCROLLDN) - 1);
unix_vlib_cli_output_cooked (cf, uf, (u8 *)ANSI_SAVECURSOR, sizeof(ANSI_SAVECURSOR) - 1);
unix_cli_ansi_cursor(cf, uf, 1, 1);
unix_vlib_cli_output_cooked (cf, uf, (u8 *)ANSI_CLEARLINE, sizeof(ANSI_CLEARLINE) - 1);
- unix_vlib_cli_output_cooked (cf, uf, cf->pager_vector[cf->pager_start], vec_len(cf->pager_vector[cf->pager_start]));
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
unix_vlib_cli_output_cooked (cf, uf, (u8 *)ANSI_RESTCURSOR, sizeof(ANSI_RESTCURSOR) - 1);
unix_cli_pager_prompt_erase (cf, uf);
unix_cli_pager_prompt (cf, uf);
@@ -1373,11 +1615,15 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm,
{
int m = cf->pager_start + (cf->height - 1);
unix_cli_pager_prompt_erase (cf, uf);
- for (j = cf->pager_start; j < cf->pager_lines && j < m; j ++)
+ for (j = cf->pager_start; j < vec_len (cf->pager_index) && j < m; j ++)
{
- line = cf->pager_vector[j];
- unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line));
+ pi = &cf->pager_index[j];
+ line = cf->pager_vector[pi->line] + pi->offset;
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
}
+ /* if the last line didn't end in newline, add a newline */
+ if (pi && line[pi->length - 1] != '\n')
+ unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1);
unix_cli_pager_prompt (cf, uf);
}
}
@@ -1387,32 +1633,44 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm,
/* back to the first page of the buffer */
if (cf->pager_start > 0)
{
- u8 * line;
+ u8 * line = NULL;
+ unix_cli_pager_index_t * pi = NULL;
+
cf->pager_start = 0;
int m = cf->pager_start + (cf->height - 1);
unix_cli_pager_prompt_erase (cf, uf);
- for (j = cf->pager_start; j < cf->pager_lines && j < m; j ++)
+ for (j = cf->pager_start; j < vec_len (cf->pager_index) && j < m; j ++)
{
- line = cf->pager_vector[j];
- unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line));
+ pi = &cf->pager_index[j];
+ line = cf->pager_vector[pi->line] + pi->offset;
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
}
+ /* if the last line didn't end in newline, add a newline */
+ if (pi && line[pi->length - 1] != '\n')
+ unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1);
unix_cli_pager_prompt (cf, uf);
}
break;
case UNIX_CLI_PARSE_ACTION_PAGER_BOTTOM:
/* skip to the last page of the buffer */
- if (cf->pager_start < cf->pager_lines - (cf->height - 1))
+ if (cf->pager_start < vec_len (cf->pager_index) - (cf->height - 1))
{
- u8 * line;
- cf->pager_start = cf->pager_lines - (cf->height - 1);
+ u8 * line = NULL;
+ unix_cli_pager_index_t * pi = NULL;
+
+ cf->pager_start = vec_len (cf->pager_index) - (cf->height - 1);
unix_cli_pager_prompt_erase (cf, uf);
unix_cli_pager_message (cf, uf, "skipping", "\n");
- for (j = cf->pager_start; j < cf->pager_lines; j ++)
+ for (j = cf->pager_start; j < vec_len (cf->pager_index); j ++)
{
- line = cf->pager_vector[j];
- unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line));
+ pi = &cf->pager_index[j];
+ line = cf->pager_vector[pi->line] + pi->offset;
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
}
+ /* if the last line didn't end in newline, add a newline */
+ if (pi && line[pi->length - 1] != '\n')
+ unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1);
unix_cli_pager_prompt (cf, uf);
}
break;
@@ -1421,23 +1679,34 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm,
/* wander back one page in the buffer */
if (cf->pager_start > 0)
{
- u8 * line;
+ u8 * line = NULL;
+ unix_cli_pager_index_t * pi = NULL;
int m;
+
if (cf->pager_start >= cf->height)
cf->pager_start -= cf->height - 1;
else
- cf->pager_start = 1;
+ cf->pager_start = 0;
m = cf->pager_start + cf->height - 1;
unix_cli_pager_prompt_erase (cf, uf);
- for (j = cf->pager_start; j < cf->pager_lines && j < m; j ++)
+ for (j = cf->pager_start; j < vec_len (cf->pager_index) && j < m; j ++)
{
- line = cf->pager_vector[j];
- unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line));
+ pi = &cf->pager_index[j];
+ line = cf->pager_vector[pi->line] + pi->offset;
+ unix_vlib_cli_output_cooked (cf, uf, line, pi->length);
}
+ /* if the last line didn't end in newline, add a newline */
+ if (pi && line[pi->length - 1] != '\n')
+ unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1);
unix_cli_pager_prompt (cf, uf);
}
break;
+ case UNIX_CLI_PARSE_ACTION_PAGER_REDRAW:
+ /* Redraw the current pager screen */
+ unix_cli_pager_redraw (cf, uf);
+ break;
+
case UNIX_CLI_PARSE_ACTION_PAGER_SEARCH:
/* search forwards in the buffer */
break;
@@ -1482,7 +1751,7 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm,
case UNIX_CLI_PARSE_ACTION_PARTIALMATCH:
case UNIX_CLI_PARSE_ACTION_NOMATCH:
- if (cf->pager_lines)
+ if (vec_len (cf->pager_index))
{
/* no-op for now */
}
@@ -1605,7 +1874,7 @@ static int unix_cli_line_edit (unix_cli_main_t * cm,
unix_cli_parse_actions_t *a;
/* If we're in the pager mode, search the pager actions */
- a = cf->pager_lines ? unix_cli_parse_pager : unix_cli_parse_strings;
+ a = vec_len (cf->pager_index) ? unix_cli_parse_pager : unix_cli_parse_strings;
/* See if the input buffer is some sort of control code */
action = unix_cli_match_action(a, &cf->input_vector[i],
@@ -1714,8 +1983,7 @@ more:
(void) unformat (&input, "");
cm->current_input_file_index = cli_file_index;
- cf->pager_lines = 0; /* start a new pager session */
- cf->pager_start = 0;
+ cf->pager_start = 0; /* start a new pager session */
if (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT)
vlib_cli_input (um->vlib_main, &input, unix_vlib_cli_output, cli_file_index);
@@ -1743,7 +2011,7 @@ done:
cf->no_pager = um->cli_no_pager;
}
- if (cf->pager_lines == 0 || cf->pager_lines < cf->height)
+ if (vec_len (cf->pager_index) == 0 || vec_len (cf->pager_index) < cf->height)
{
/* There was no need for the pager */
unix_cli_pager_reset (cf);
@@ -2034,9 +2302,11 @@ static clib_error_t * unix_cli_listen_read_ready (unix_file_t * uf)
static void
unix_cli_resize_interrupt (int signum)
{
+ unix_main_t * um = &unix_main;
unix_cli_main_t * cm = &unix_cli_main;
unix_cli_file_t * cf = pool_elt_at_index (cm->cli_file_pool,
cm->stdin_cli_file_index);
+ unix_file_t * uf = pool_elt_at_index (um->file_pool, cf->unix_file_index);
struct winsize ws;
(void)signum;
@@ -2044,6 +2314,12 @@ unix_cli_resize_interrupt (int signum)
ioctl(UNIX_CLI_STDIN_FD, TIOCGWINSZ, &ws);
cf->width = ws.ws_col;
cf->height = ws.ws_row;
+
+ /* Reindex the pager buffer */
+ unix_cli_pager_reindex (cf);
+
+ /* Redraw the page */
+ unix_cli_pager_redraw (cf, uf);
}
/** Handle configuration directives in the @em unix section. */