iPXE
Macros | Functions
readline.c File Reference

Minimal readline. More...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <ipxe/console.h>
#include <ipxe/keys.h>
#include <ipxe/editstring.h>
#include <readline/readline.h>

Go to the source code of this file.

Macros

#define READLINE_MAX   1024
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static void sync_console (struct edit_string *string)
 Synchronise console with edited string. More...
 
static struct readline_history_entryhistory_entry (struct readline_history *history, unsigned int depth)
 Locate history entry. More...
 
static const char * history_fetch (struct readline_history *history, unsigned int depth)
 Read string from history buffer. More...
 
static void history_store (struct readline_history *history, unsigned int depth, const char *string)
 Write temporary string copy to history buffer. More...
 
static const char * history_move (struct readline_history *history, int offset, const char *old_string)
 Move to new history depth. More...
 
static void history_append (struct readline_history *history, const char *string)
 Append new history entry. More...
 
static void history_cleanup (struct readline_history *history)
 Clean up history after editing. More...
 
void history_free (struct readline_history *history)
 Free history buffer. More...
 
int readline_history (const char *prompt, const char *prefill, struct readline_history *history, unsigned long timeout, char **line)
 Read line from console (with history) More...
 
char * readline (const char *prompt)
 Read line from console. More...
 

Detailed Description

Minimal readline.

Definition in file readline.c.

Macro Definition Documentation

◆ READLINE_MAX

#define READLINE_MAX   1024

Definition at line 41 of file readline.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ sync_console()

static void sync_console ( struct edit_string string)
static

Synchronise console with edited string.

Parameters
stringEditable string

Definition at line 48 of file readline.c.

48  {
49  unsigned int mod_start = string->mod_start;
50  unsigned int mod_end = string->mod_end;
51  unsigned int cursor = string->last_cursor;
52  size_t len = strlen ( string->buf );
53 
54  /* Expand region back to old cursor position if applicable */
55  if ( mod_start > string->last_cursor )
56  mod_start = string->last_cursor;
57 
58  /* Expand region forward to new cursor position if applicable */
59  if ( mod_end < string->cursor )
60  mod_end = string->cursor;
61 
62  /* Backspace to start of region */
63  while ( cursor > mod_start ) {
64  putchar ( '\b' );
65  cursor--;
66  }
67 
68  /* Print modified region */
69  while ( cursor < mod_end ) {
70  putchar ( ( cursor >= len ) ? ' ' : string->buf[cursor] );
71  cursor++;
72  }
73 
74  /* Backspace to new cursor position */
75  while ( cursor > string->cursor ) {
76  putchar ( '\b' );
77  cursor--;
78  }
79 }
uint32_t mod_start
Definition: multiboot.h:12
uint32_t mod_end
Definition: multiboot.h:13
uint32_t string
Definition: multiboot.h:14
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
uint32_t len
Length.
Definition: ena.h:14
int putchar(int character)
Write a single character to each console device.
Definition: console.c:28

References len, mod_end, mod_start, putchar(), string, and strlen().

Referenced by readline_history().

◆ history_entry()

static struct readline_history_entry* history_entry ( struct readline_history history,
unsigned int  depth 
)
static

Locate history entry.

Parameters
historyHistory buffer
depthDepth within history buffer
Return values
entryHistory entry

Definition at line 89 of file readline.c.

89  {
90  unsigned int offset;
91 
92  offset = ( ( history->next - depth ) %
93  ( sizeof ( history->entries ) /
94  sizeof ( history->entries[0] ) ) );
95  return &history->entries[offset];
96 }
struct readline_history_entry entries[READLINE_HISTORY_MAX_DEPTH+1]
History entries.
Definition: readline.h:38
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
unsigned int next
Position of next entry within buffer.
Definition: readline.h:44

References readline_history::entries, readline_history::next, and offset.

Referenced by history_append(), history_cleanup(), history_fetch(), and history_store().

◆ history_fetch()

static const char* history_fetch ( struct readline_history history,
unsigned int  depth 
)
static

Read string from history buffer.

Parameters
historyHistory buffer
depthDepth within history buffer
Return values
stringString

Definition at line 105 of file readline.c.

106  {
108 
109  /* Return the temporary copy if it exists, otherwise return
110  * the persistent copy.
111  */
112  entry = history_entry ( history, depth );
113  return ( entry->temp ? entry->temp : entry->string );
114 }
static struct readline_history_entry * history_entry(struct readline_history *history, unsigned int depth)
Locate history entry.
Definition: readline.c:89
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
A readline history entry.
Definition: readline.h:13

References entry, and history_entry().

Referenced by history_move().

◆ history_store()

static void history_store ( struct readline_history history,
unsigned int  depth,
const char *  string 
)
static

Write temporary string copy to history buffer.

Parameters
historyHistory buffer
depthDepth within history buffer
stringString

Definition at line 123 of file readline.c.

124  {
126  char *temp;
127 
128  /* Create temporary copy of string */
129  temp = strdup ( string );
130  if ( ! temp ) {
131  /* Just discard the string; there's nothing we can do */
132  DBGC ( history, "READLINE %p could not store string\n",
133  history );
134  return;
135  }
136 
137  /* Store temporary copy */
138  entry = history_entry ( history, depth );
139  free ( entry->temp );
140  entry->temp = temp;
141 }
static struct readline_history_entry * history_entry(struct readline_history *history, unsigned int depth)
Locate history entry.
Definition: readline.c:89
#define DBGC(...)
Definition: compiler.h:505
char * temp
Temporary copy of string.
Definition: readline.h:21
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
char * strdup(const char *src)
Duplicate string.
Definition: string.c:380
A readline history entry.
Definition: readline.h:13

References DBGC, entry, free, history_entry(), strdup(), and readline_history_entry::temp.

Referenced by history_move().

◆ history_move()

static const char* history_move ( struct readline_history history,
int  offset,
const char *  old_string 
)
static

Move to new history depth.

Parameters
historyHistory buffer
offsetOffset by which to change depth
old_stringString (possibly modified) at current depth
Return values
new_stringString at new depth, or NULL for no movement

Definition at line 151 of file readline.c.

152  {
153  unsigned int new_depth = ( history->depth + offset );
154  const char * new_string = history_fetch ( history, new_depth );
155 
156  /* Depth checks */
157  if ( new_depth > READLINE_HISTORY_MAX_DEPTH )
158  return NULL;
159  if ( ! new_string )
160  return NULL;
161 
162  /* Store temporary copy of old string at current depth */
163  history_store ( history, history->depth, old_string );
164 
165  /* Update depth */
166  history->depth = new_depth;
167 
168  /* Return new string */
169  return new_string;
170 }
unsigned int depth
Current depth within history buffer.
Definition: readline.h:49
static void history_store(struct readline_history *history, unsigned int depth, const char *string)
Write temporary string copy to history buffer.
Definition: readline.c:123
#define READLINE_HISTORY_MAX_DEPTH
Maximum depth of a readline history buffer.
Definition: readline.h:28
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static const char * history_fetch(struct readline_history *history, unsigned int depth)
Read string from history buffer.
Definition: readline.c:105
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References readline_history::depth, history_fetch(), history_store(), NULL, offset, and READLINE_HISTORY_MAX_DEPTH.

Referenced by readline_history().

◆ history_append()

static void history_append ( struct readline_history history,
const char *  string 
)
static

Append new history entry.

Parameters
historyHistory buffer
stringString

Definition at line 178 of file readline.c.

179  {
181 
182  /* Store new entry */
183  entry = history_entry ( history, 0 );
184  assert ( entry->string == NULL );
185  entry->string = strdup ( string );
186  if ( ! entry->string ) {
187  /* Just discard the string; there's nothing we can do */
188  DBGC ( history, "READLINE %p could not append string\n",
189  history );
190  return;
191  }
192 
193  /* Increment history position */
194  history->next++;
195 
196  /* Prepare empty "next" slot */
197  entry = history_entry ( history, 0 );
198  free ( entry->string );
199  entry->string = NULL;
200 }
static struct readline_history_entry * history_entry(struct readline_history *history, unsigned int depth)
Locate history entry.
Definition: readline.c:89
#define DBGC(...)
Definition: compiler.h:505
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int next
Position of next entry within buffer.
Definition: readline.h:44
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
char * strdup(const char *src)
Duplicate string.
Definition: string.c:380
A readline history entry.
Definition: readline.h:13
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References assert(), DBGC, entry, free, history_entry(), readline_history::next, NULL, and strdup().

Referenced by readline_history().

◆ history_cleanup()

static void history_cleanup ( struct readline_history history)
static

Clean up history after editing.

Parameters
historyHistory buffer

Definition at line 207 of file readline.c.

207  {
209  unsigned int i;
210 
211  /* Discard any temporary strings */
212  for ( i = 0 ; i < ( sizeof ( history->entries ) /
213  sizeof ( history->entries[0] ) ) ; i++ ) {
214  entry = &history->entries[i];
215  free ( entry->temp );
216  entry->temp = NULL;
217  }
218 
219  /* Reset depth */
220  history->depth = 0;
221 
222  /* Sanity check */
223  entry = history_entry ( history, 0 );
224  assert ( entry->string == NULL );
225 }
unsigned int depth
Current depth within history buffer.
Definition: readline.h:49
static struct readline_history_entry * history_entry(struct readline_history *history, unsigned int depth)
Locate history entry.
Definition: readline.c:89
struct readline_history_entry entries[READLINE_HISTORY_MAX_DEPTH+1]
History entries.
Definition: readline.h:38
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
A readline history entry.
Definition: readline.h:13
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References assert(), readline_history::depth, readline_history::entries, entry, free, history_entry(), and NULL.

Referenced by readline_history().

◆ history_free()

void history_free ( struct readline_history history)

Free history buffer.

Parameters
historyHistory buffer

Definition at line 232 of file readline.c.

232  {
234  unsigned int i;
235 
236  /* Discard any temporary strings */
237  for ( i = 0 ; i < ( sizeof ( history->entries ) /
238  sizeof ( history->entries[0] ) ) ; i++ ) {
239  entry = &history->entries[i];
240  assert ( entry->temp == NULL );
241  free ( entry->string );
242  }
243 }
struct readline_history_entry entries[READLINE_HISTORY_MAX_DEPTH+1]
History entries.
Definition: readline.h:38
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
A readline history entry.
Definition: readline.h:13
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References assert(), readline_history::entries, entry, free, and NULL.

Referenced by shell().

◆ readline_history()

int readline_history ( const char *  prompt,
const char *  prefill,
struct readline_history history,
unsigned long  timeout,
char **  line 
)

Read line from console (with history)

Parameters
promptPrompt string
prefillPrefill string, or NULL for no prefill
historyHistory buffer, or NULL for no history
timeoutTimeout period, in ticks (0=indefinite)
Return values
lineLine read from console (excluding terminating newline)
rcReturn status code

The returned line is allocated with malloc(); the caller must eventually call free() to release the storage.

Definition at line 258 of file readline.c.

260  {
261  struct edit_string string;
262  char *buf;
263  int key;
264  int move_by;
265  const char *new_string;
266  int rc;
267 
268  /* Avoid returning uninitialised data on error */
269  *line = NULL;
270 
271  /* Display prompt, if applicable */
272  if ( prompt )
273  printf ( "%s", prompt );
274 
275  /* Ensure cursor is visible */
276  printf ( "\033[?25h" );
277 
278  /* Allocate buffer and initialise editable string */
279  buf = zalloc ( READLINE_MAX );
280  if ( ! buf ) {
281  rc = -ENOMEM;
282  goto done;
283  }
284  memset ( &string, 0, sizeof ( string ) );
285  init_editstring ( &string, buf, READLINE_MAX );
286 
287  /* Prefill string, if applicable */
288  if ( prefill ) {
289  replace_string ( &string, prefill );
290  sync_console ( &string );
291  }
292 
293  while ( 1 ) {
294 
295  /* Get keypress */
296  key = getkey ( timeout );
297  if ( key < 0 ) {
298  rc = -ETIMEDOUT;
299  goto done;
300  }
301  timeout = 0;
302 
303  /* Handle keypress */
304  key = edit_string ( &string, key );
305  sync_console ( &string );
306  move_by = 0;
307  switch ( key ) {
308  case CR:
309  case LF:
310  /* Shrink string (ignoring failures) */
311  *line = realloc ( buf,
312  ( strlen ( buf ) + 1 /* NUL */ ) );
313  if ( ! *line )
314  *line = buf;
315  buf = NULL;
316  rc = 0;
317  goto done;
318  case CTRL_C:
319  rc = -ECANCELED;
320  goto done;
321  case KEY_UP:
322  move_by = 1;
323  break;
324  case KEY_DOWN:
325  move_by = -1;
326  break;
327  default:
328  /* Do nothing */
329  break;
330  }
331 
332  /* Handle history movement, if applicable */
333  if ( move_by && history ) {
334  new_string = history_move ( history, move_by, buf );
335  if ( new_string ) {
336  replace_string ( &string, new_string );
337  sync_console ( &string );
338  }
339  }
340  }
341 
342  done:
343  putchar ( '\n' );
344  free ( buf );
345  if ( history ) {
346  if ( *line && (*line)[0] )
347  history_append ( history, *line );
348  history_cleanup ( history );
349  }
350  assert ( ( rc == 0 ) ^ ( *line == NULL ) );
351  return rc;
352 }
int getkey(unsigned long timeout)
Get single keypress.
Definition: getkey.c:71
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
static const char * history_move(struct readline_history *history, int offset, const char *old_string)
Move to new history depth.
Definition: readline.c:151
void replace_string(struct edit_string *string, const char *replacement)
Replace editable string.
Definition: editstring.c:173
static void history_cleanup(struct readline_history *history)
Clean up history after editing.
Definition: readline.c:207
int edit_string(struct edit_string *string, int key)
Edit editable string.
Definition: editstring.c:195
uint32_t string
Definition: multiboot.h:14
#define ECANCELED
Operation canceled.
Definition: errno.h:343
#define KEY_DOWN
Down arrow.
Definition: keys.h:66
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define KEY_UP
Up arrow.
Definition: keys.h:65
static void sync_console(struct edit_string *string)
Synchronise console with edited string.
Definition: readline.c:48
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void init_editstring(struct edit_string *string, char *buf, size_t len)
Initialise editable string.
Definition: editstring.h:38
#define CTRL_C
Definition: keys.h:20
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
int prompt(const char *text, unsigned long timeout, int key)
Prompt for keypress.
Definition: prompt.c:48
#define LF
Definition: keys.h:47
static void history_append(struct readline_history *history, const char *string)
Append new history entry.
Definition: readline.c:178
An editable string.
Definition: editstring.h:13
#define CR
Definition: keys.h:48
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition: malloc.c:521
void timeout(int)
#define READLINE_MAX
Definition: readline.c:41
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
int putchar(int character)
Write a single character to each console device.
Definition: console.c:28
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
struct bofm_section_header done
Definition: bofm_test.c:46
union @382 key
Sense key.
Definition: scsi.h:18
void * memset(void *dest, int character, size_t len) __nonnull
char * buf
Buffer for string.
Definition: editstring.h:15

References assert(), edit_string::buf, CR, CTRL_C, done, ECANCELED, edit_string(), ENOMEM, ETIMEDOUT, free, getkey(), history_append(), history_cleanup(), history_move(), init_editstring(), key, KEY_DOWN, KEY_UP, LF, memset(), NULL, printf(), prompt(), putchar(), rc, READLINE_MAX, realloc(), replace_string(), string, strlen(), sync_console(), timeout(), and zalloc().

Referenced by readline(), and shell().

◆ readline()

char* readline ( const char *  prompt)

Read line from console.

Parameters
promptPrompt string
Return values
lineLine read from console (excluding terminating newline)

The returned line is allocated with malloc(); the caller must eventually call free() to release the storage.

Definition at line 363 of file readline.c.

363  {
364  char *line;
365 
366  readline_history ( prompt, NULL, NULL, 0, &line );
367  return line;
368 }
int readline_history(const char *prompt, const char *prefill, struct readline_history *history, unsigned long timeout, char **line)
Read line from console (with history)
Definition: readline.c:258
int prompt(const char *text, unsigned long timeout, int key)
Prompt for keypress.
Definition: prompt.c:48
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References NULL, prompt(), and readline_history().