diff options
author | Michael Brown | 2006-12-20 00:25:44 +0100 |
---|---|---|
committer | Michael Brown | 2006-12-20 00:25:44 +0100 |
commit | 22289ca8f65f779448bf823b62c7f824160acb91 (patch) | |
tree | 644eeeb1c8297e1af0201214dca01e1da8749d00 | |
parent | Provide an edit history to allow caller to efficiently update display. (diff) | |
download | ipxe-22289ca8f65f779448bf823b62c7f824160acb91.tar.gz ipxe-22289ca8f65f779448bf823b62c7f824160acb91.tar.xz ipxe-22289ca8f65f779448bf823b62c7f824160acb91.zip |
Functioning readline()
-rw-r--r-- | src/hci/readline.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/src/hci/readline.c b/src/hci/readline.c index 3fa5f2d4..36ba429e 100644 --- a/src/hci/readline.c +++ b/src/hci/readline.c @@ -31,6 +31,44 @@ #define READLINE_MAX 256 /** + * Synchronise console with edited string + * + * @v string Editable string + */ +static void sync_console ( struct edit_string *string ) { + unsigned int mod_start = string->mod_start; + unsigned int mod_end = string->mod_end; + unsigned int cursor = string->last_cursor; + size_t len = strlen ( string->buf ); + + /* Expand region back to old cursor position if applicable */ + if ( mod_start > string->last_cursor ) + mod_start = string->last_cursor; + + /* Expand region forward to new cursor position if applicable */ + if ( mod_end < string->cursor ) + mod_end = string->cursor; + + /* Backspace to start of region */ + while ( cursor > mod_start ) { + putchar ( '\b' ); + cursor--; + } + + /* Print modified region */ + while ( cursor < mod_end ) { + putchar ( ( cursor >= len ) ? ' ' : string->buf[cursor] ); + cursor++; + } + + /* Backspace to new cursor position */ + while ( cursor > string->cursor ) { + putchar ( '\b' ); + cursor--; + } +} + +/** * Read line from console * * @v prompt Prompt string @@ -47,6 +85,7 @@ char * readline ( const char *prompt ) { .cursor = 0, }; int key; + char *line = NULL; if ( prompt ) printf ( "%s", prompt ); @@ -54,15 +93,21 @@ char * readline ( const char *prompt ) { buf[0] = '\0'; while ( 1 ) { key = edit_string ( &string, getchar() ); + sync_console ( &string ); switch ( key ) { case 0x0d: /* Carriage return */ case 0x0a: /* Line feed */ - return ( strdup ( buf ) ); + line = strdup ( buf ); + goto out; case 0x03: /* Ctrl-C */ - return NULL; + goto out; default: /* Do nothing */ break; } } + + out: + putchar ( '\n' ); + return line; } |