iPXE
Functions
editstring.c File Reference

Editable strings. More...

#include <assert.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <ipxe/keys.h>
#include <ipxe/editstring.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FILE_SECBOOT (PERMITTED)
 
static __attribute__ ((nonnull(1)))
 
static int insert_character (struct edit_string *string, unsigned int character)
 Insert character at current cursor position. More...
 
static void delete_character (struct edit_string *string)
 Delete character at current cursor position. More...
 
static void backspace (struct edit_string *string)
 Delete character to left of current cursor position. More...
 
static void previous_word (struct edit_string *string)
 Move to start of previous word. More...
 
static void kill_word (struct edit_string *string)
 Delete to end of previous word. More...
 
static void kill_sol (struct edit_string *string)
 Delete to start of line. More...
 
static void kill_eol (struct edit_string *string)
 Delete to end of line. More...
 
int replace_string (struct edit_string *string, const char *replacement)
 Replace editable string. More...
 
int edit_string (struct edit_string *string, int key)
 Edit editable string. More...
 

Detailed Description

Editable strings.

Definition in file editstring.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ __attribute__()

static __attribute__ ( (nonnull(1))  )
static

Definition at line 41 of file editstring.c.

62  {
63  size_t old_len, max_delete_len, move_len, insert_len, new_len;
64  char *buf;
65  char *tmp;
66 
67  /* Prepare edit history */
68  string->mod_start = string->cursor;
69  string->mod_end = string->cursor;
70 
71  /* Calculate lengths */
72  buf = *(string->buf);
73  old_len = ( buf ? strlen ( buf ) : 0 );
74  assert ( string->cursor <= old_len );
75  max_delete_len = ( old_len - string->cursor );
76  if ( delete_len > max_delete_len )
77  delete_len = max_delete_len;
78  move_len = ( max_delete_len - delete_len );
79  insert_len = ( insert_text ? strlen ( insert_text ) : 0 );
80  new_len = ( old_len - delete_len + insert_len );
81 
82  /* Delete existing text */
83  memmove ( ( buf + string->cursor ),
84  ( buf + string->cursor + delete_len ), move_len );
85 
86  /* Reallocate string, ignoring failures if shrinking */
87  tmp = realloc ( buf, ( new_len + 1 /* NUL */ ) );
88  if ( tmp ) {
89  buf = tmp;
90  *(string->buf) = buf;
91  } else if ( ( new_len > old_len ) || ( ! buf ) ) {
92  return -ENOMEM;
93  }
94 
95  /* Create space for inserted text */
96  memmove ( ( buf + string->cursor + insert_len ),
97  ( buf + string->cursor ), move_len );
98 
99  /* Copy inserted text to cursor position */
100  memcpy ( ( buf + string->cursor ), insert_text, insert_len );
101  string->cursor += insert_len;
102 
103  /* Terminate string */
104  buf[new_len] = '\0';
105 
106  /* Update edit history */
107  string->mod_end = ( ( new_len > old_len ) ? new_len : old_len );
108 
109  return 0;
110 }
uint32_t string
Definition: multiboot.h:14
unsigned long tmp
Definition: linux_pci.h:65
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
void * memmove(void *dest, const void *src, size_t len) __nonnull
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition: malloc.c:607

References assert(), ENOMEM, memcpy(), memmove(), realloc(), string, strlen(), and tmp.

◆ insert_character()

static int insert_character ( struct edit_string string,
unsigned int  character 
)
static

Insert character at current cursor position.

Parameters
stringEditable string
characterCharacter to insert
Return values
rcReturn status code

Definition at line 119 of file editstring.c.

120  {
121  char insert_text[2] = { character, '\0' };
122 
123  return insert_delete ( string, 0, insert_text );
124 }

Referenced by edit_string().

◆ delete_character()

static void delete_character ( struct edit_string string)
static

Delete character at current cursor position.

Parameters
stringEditable string

Definition at line 131 of file editstring.c.

131  {
132  int rc;
133 
134  rc = insert_delete ( string, 1, NULL );
135  assert ( ( rc == 0 ) || ( *(string->buf) == NULL ) );
136 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t string
Definition: multiboot.h:14
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References assert(), NULL, rc, and string.

Referenced by backspace(), and edit_string().

◆ backspace()

static void backspace ( struct edit_string string)
static

Delete character to left of current cursor position.

Parameters
stringEditable string

Definition at line 143 of file editstring.c.

143  {
144 
145  if ( string->cursor > 0 ) {
146  string->cursor--;
147  delete_character ( string );
148  }
149 }
uint32_t string
Definition: multiboot.h:14
static void delete_character(struct edit_string *string)
Delete character at current cursor position.
Definition: editstring.c:131

References delete_character(), and string.

Referenced by edit_string().

◆ previous_word()

static void previous_word ( struct edit_string string)
static

Move to start of previous word.

Parameters
stringEditable string

Definition at line 156 of file editstring.c.

156  {
157  const char *buf = *(string->buf);
158  size_t cursor = string->cursor;
159 
160  while ( cursor && isspace ( buf[ cursor - 1 ] ) ) {
161  cursor--;
162  }
163  while ( cursor && ( ! isspace ( buf[ cursor - 1 ] ) ) ) {
164  cursor--;
165  }
166  string->cursor = cursor;
167 }
int isspace(int character)
Check to see if character is a space.
Definition: ctype.c:42

References isspace().

Referenced by kill_word().

◆ kill_word()

static void kill_word ( struct edit_string string)
static

Delete to end of previous word.

Parameters
stringEditable string

Definition at line 174 of file editstring.c.

174  {
175  size_t old_cursor = string->cursor;
176  int rc;
177 
178  previous_word ( string );
179  rc = insert_delete ( string, ( old_cursor - string->cursor ), NULL );
180  assert ( ( rc == 0 ) || ( *(string->buf) == NULL ) );
181 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t string
Definition: multiboot.h:14
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static void previous_word(struct edit_string *string)
Move to start of previous word.
Definition: editstring.c:156

References assert(), NULL, previous_word(), rc, and string.

Referenced by edit_string().

◆ kill_sol()

static void kill_sol ( struct edit_string string)
static

Delete to start of line.

Parameters
stringEditable string

Definition at line 188 of file editstring.c.

188  {
189  size_t old_cursor = string->cursor;
190  int rc;
191 
192  string->cursor = 0;
193  rc = insert_delete ( string, old_cursor, NULL );
194  assert ( ( rc == 0 ) || ( *(string->buf) == NULL ) );
195 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t string
Definition: multiboot.h:14
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References assert(), NULL, rc, and string.

Referenced by edit_string().

◆ kill_eol()

static void kill_eol ( struct edit_string string)
static

Delete to end of line.

Parameters
stringEditable string

Definition at line 202 of file editstring.c.

202  {
203  int rc;
204 
205  rc = insert_delete ( string, ~( ( size_t ) 0 ), NULL );
206  assert ( ( rc == 0 ) || ( *(string->buf) == NULL ) );
207 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t string
Definition: multiboot.h:14
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References assert(), NULL, rc, and string.

Referenced by edit_string().

◆ replace_string()

int replace_string ( struct edit_string string,
const char *  replacement 
)

Replace editable string.

Parameters
stringEditable string
replacementReplacement string, or NULL to empty the string
Return values
rcReturn status code

Replace the entire content of the editable string and update the edit history to allow the caller to bring the display into sync with the string content.

This function does not itself update the display in any way.

Upon success, the string buffer is guaranteed to be non-NULL (even if the replacement string is NULL or empty).

Errors may safely be ignored if it is deemed that subsequently failing to update the display will provide sufficient feedback to the user.

Definition at line 229 of file editstring.c.

229  {
230 
231  string->cursor = 0;
232  return insert_delete ( string, ~( ( size_t ) 0 ), replacement );
233 }
const char * replacement
Definition: editstring.h:54

References replacement.

Referenced by editstring_okx(), and readline_history().

◆ edit_string()

int edit_string ( struct edit_string string,
int  key 
)

Edit editable string.

Parameters
stringEditable string
keyKey pressed by user
Return values
keyKey returned to application, zero, or negative error

Handles keypresses and updates the content of the editable string. Basic line editing facilities (delete/insert/cursor) are supported. If edit_string() understands and uses the keypress it will return zero, otherwise it will return the original key.

The string's edit history will be updated to allow the caller to efficiently bring the display into sync with the string content.

This function does not itself update the display in any way.

Errors may safely be ignored if it is deemed that subsequently failing to update the display will provide sufficient feedback to the user.

Definition at line 256 of file editstring.c.

256  {
257  const char *buf = *(string->buf);
258  size_t len = ( buf ? strlen ( buf ) : 0 );
259  int retval = 0;
260 
261  /* Prepare edit history */
262  string->last_cursor = string->cursor;
263  string->mod_start = string->cursor;
264  string->mod_end = string->cursor;
265 
266  /* Interpret key */
267  if ( ( key >= 0x20 ) && ( key <= 0x7e ) ) {
268  /* Printable character; insert at current position */
269  retval = insert_character ( string, key );
270  } else switch ( key ) {
271  case KEY_BACKSPACE:
272  /* Backspace */
273  backspace ( string );
274  break;
275  case KEY_DC:
276  case CTRL_D:
277  /* Delete character */
278  delete_character ( string );
279  break;
280  case CTRL_W:
281  /* Delete word */
282  kill_word ( string );
283  break;
284  case CTRL_U:
285  /* Delete to start of line */
286  kill_sol ( string );
287  break;
288  case CTRL_K:
289  /* Delete to end of line */
290  kill_eol ( string );
291  break;
292  case KEY_HOME:
293  case CTRL_A:
294  /* Start of line */
295  string->cursor = 0;
296  break;
297  case KEY_END:
298  case CTRL_E:
299  /* End of line */
300  string->cursor = len;
301  break;
302  case KEY_LEFT:
303  case CTRL_B:
304  /* Cursor left */
305  if ( string->cursor > 0 )
306  string->cursor--;
307  break;
308  case KEY_RIGHT:
309  case CTRL_F:
310  /* Cursor right */
311  if ( string->cursor < len )
312  string->cursor++;
313  break;
314  default:
315  retval = key;
316  break;
317  }
318 
319  return retval;
320 }
#define CTRL_B
Definition: keys.h:20
#define CTRL_E
Definition: keys.h:23
static int insert_character(struct edit_string *string, unsigned int character)
Insert character at current cursor position.
Definition: editstring.c:119
uint32_t string
Definition: multiboot.h:14
#define KEY_HOME
Home.
Definition: keys.h:111
static void backspace(struct edit_string *string)
Delete character to left of current cursor position.
Definition: editstring.c:143
#define CTRL_K
Definition: keys.h:29
ring len
Length.
Definition: dwmac.h:231
#define CTRL_W
Definition: keys.h:41
#define KEY_END
End.
Definition: keys.h:110
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
#define CTRL_F
Definition: keys.h:24
#define CTRL_A
Definition: keys.h:19
#define CTRL_U
Definition: keys.h:39
static void kill_eol(struct edit_string *string)
Delete to end of line.
Definition: editstring.c:202
unsigned long retval
Definition: xen.h:46
#define KEY_DC
Delete.
Definition: keys.h:113
static void kill_sol(struct edit_string *string)
Delete to start of line.
Definition: editstring.c:188
#define KEY_RIGHT
Right arrow.
Definition: keys.h:108
#define CTRL_D
Definition: keys.h:22
#define KEY_BACKSPACE
Definition: keys.h:128
static void kill_word(struct edit_string *string)
Delete to end of previous word.
Definition: editstring.c:174
#define KEY_LEFT
Left arrow.
Definition: keys.h:109
union @391 key
Sense key.
Definition: scsi.h:18
static void delete_character(struct edit_string *string)
Delete character at current cursor position.
Definition: editstring.c:131

References backspace(), CTRL_A, CTRL_B, CTRL_D, CTRL_E, CTRL_F, CTRL_K, CTRL_U, CTRL_W, delete_character(), insert_character(), key, KEY_BACKSPACE, KEY_DC, KEY_END, KEY_HOME, KEY_LEFT, KEY_RIGHT, kill_eol(), kill_sol(), kill_word(), len, retval, string, and strlen().

Referenced by edit_editbox(), and readline_history().