1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-27 05:21:16 +02:00

cli: Create a function to process characters

Move most of the inner loop from cread_line() into a new function. This
will allow using it from other code.

This involves adding a few more members to the state struct.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2023-10-01 19:13:13 -06:00
committed by Tom Rini
parent 8d997aab6e
commit e5509ce87b
2 changed files with 78 additions and 45 deletions

View File

@@ -253,52 +253,17 @@ static void cread_add_str(char *str, int strsize, int insert,
} }
} }
static int cread_line(const char *const prompt, char *buf, unsigned int *len, int cread_line_process_ch(struct cli_line_state *cls, char ichar)
int timeout)
{ {
struct cli_ch_state s_cch, *cch = &s_cch; char *buf = cls->buf;
struct cli_line_state s_cls, *cls = &s_cls;
char ichar;
int init_len = strlen(buf);
int first = 1;
cli_ch_init(cch);
memset(cls, '\0', sizeof(struct cli_line_state));
cls->insert = true;
if (init_len)
cread_add_str(buf, init_len, 1, &cls->num, &cls->eol_num, buf,
*len);
while (1) {
/* Check for saved characters */
ichar = cli_ch_process(cch, 0);
if (!ichar) {
if (bootretry_tstc_timeout())
return -2; /* timed out */
if (first && timeout) {
u64 etime = endtick(timeout);
while (!tstc()) { /* while no incoming data */
if (get_ticks() >= etime)
return -2; /* timed out */
schedule();
}
first = 0;
}
ichar = getcmd_getch();
ichar = cli_ch_process(cch, ichar);
}
/* ichar=0x0 when error occurs in U-Boot getc */ /* ichar=0x0 when error occurs in U-Boot getc */
if (!ichar) if (!ichar)
continue; return -EAGAIN;
if (ichar == '\n') { if (ichar == '\n') {
putc('\n'); putc('\n');
break; return 0;
} }
switch (ichar) { switch (ichar) {
@@ -307,7 +272,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len,
break; break;
case CTL_CH('c'): /* ^C - break */ case CTL_CH('c'): /* ^C - break */
*buf = '\0'; /* discard input */ *buf = '\0'; /* discard input */
return -1; return -EINTR;
case CTL_CH('f'): case CTL_CH('f'):
if (cls->num < cls->eol_num) { if (cls->num < cls->eol_num) {
getcmd_putch(buf[cls->num]); getcmd_putch(buf[cls->num]);
@@ -405,7 +370,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len,
if (!hline) { if (!hline) {
getcmd_cbeep(); getcmd_cbeep();
continue; break;
} }
/* nuke the current line */ /* nuke the current line */
@@ -419,7 +384,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len,
strcpy(buf, hline); strcpy(buf, hline);
cls->eol_num = strlen(buf); cls->eol_num = strlen(buf);
REFRESH_TO_EOL(); REFRESH_TO_EOL();
continue; break;
} }
case '\t': case '\t':
if (IS_ENABLED(CONFIG_AUTO_COMPLETE)) { if (IS_ENABLED(CONFIG_AUTO_COMPLETE)) {
@@ -432,9 +397,9 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len,
} }
buf[cls->num] = '\0'; buf[cls->num] = '\0';
col = strlen(prompt) + cls->eol_num; col = strlen(cls->prompt) + cls->eol_num;
num2 = cls->num; num2 = cls->num;
if (cmd_auto_complete(prompt, buf, &num2, &col)) { if (cmd_auto_complete(cls->prompt, buf, &num2, &col)) {
col = num2 - cls->num; col = num2 - cls->num;
cls->num += col; cls->num += col;
cls->eol_num += col; cls->eol_num += col;
@@ -444,9 +409,62 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len,
fallthrough; fallthrough;
default: default:
cread_add_char(ichar, cls->insert, &cls->num, &cls->eol_num, cread_add_char(ichar, cls->insert, &cls->num, &cls->eol_num,
buf, *len); buf, cls->len);
break; break;
} }
return -EAGAIN;
}
static int cread_line(const char *const prompt, char *buf, unsigned int *len,
int timeout)
{
struct cli_ch_state s_cch, *cch = &s_cch;
struct cli_line_state s_cls, *cls = &s_cls;
char ichar;
int init_len = strlen(buf);
int first = 1;
cli_ch_init(cch);
memset(cls, '\0', sizeof(struct cli_line_state));
cls->insert = true;
cls->len = *len;
cls->prompt = prompt;
cls->buf = buf;
if (init_len)
cread_add_str(buf, init_len, 1, &cls->num, &cls->eol_num, buf,
*len);
while (1) {
int ret;
/* Check for saved characters */
ichar = cli_ch_process(cch, 0);
if (!ichar) {
if (bootretry_tstc_timeout())
return -2; /* timed out */
if (first && timeout) {
u64 etime = endtick(timeout);
while (!tstc()) { /* while no incoming data */
if (get_ticks() >= etime)
return -2; /* timed out */
schedule();
}
first = 0;
}
ichar = getcmd_getch();
ichar = cli_ch_process(cch, ichar);
}
ret = cread_line_process_ch(cls, ichar);
if (ret == -EINTR)
return -1;
else if (!ret)
break;
} }
*len = cls->eol_num; *len = cls->eol_num;
buf[cls->eol_num] = '\0'; /* lose the newline */ buf[cls->eol_num] = '\0'; /* lose the newline */

View File

@@ -31,11 +31,16 @@ struct cli_ch_state {
* @num: Current cursor position, where 0 is the start * @num: Current cursor position, where 0 is the start
* @eol_num: Number of characters in the buffer * @eol_num: Number of characters in the buffer
* @insert: true if in 'insert' mode * @insert: true if in 'insert' mode
* @buf: Buffer containing line
* @prompt: Prompt for the line
*/ */
struct cli_line_state { struct cli_line_state {
uint num; uint num;
uint eol_num; uint eol_num;
uint len;
bool insert; bool insert;
char *buf;
const char *prompt;
}; };
/** /**
@@ -243,6 +248,16 @@ void cli_ch_init(struct cli_ch_state *cch);
*/ */
int cli_ch_process(struct cli_ch_state *cch, int ichar); int cli_ch_process(struct cli_ch_state *cch, int ichar);
/**
* cread_line_process_ch() - Process a character for line input
*
* @cls: CLI line state
* @ichar: Character to process
* Return: 0 if input is complete, with line in cls->buf, -EINTR if input was
* cancelled with Ctrl-C, -EAGAIN if more characters are needed
*/
int cread_line_process_ch(struct cli_line_state *cls, char ichar);
/** cread_print_hist_list() - Print the command-line history list */ /** cread_print_hist_list() - Print the command-line history list */
void cread_print_hist_list(void); void cread_print_hist_list(void);