iPXE
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.
static void delete_character (struct edit_string *string)
 Delete character at current cursor position.
static void backspace (struct edit_string *string)
 Delete character to left of current cursor position.
static void previous_word (struct edit_string *string)
 Move to start of previous word.
static void kill_word (struct edit_string *string)
 Delete to end of previous word.
static void kill_sol (struct edit_string *string)
 Delete to start of line.
static void kill_eol (struct edit_string *string)
 Delete to end of line.
int replace_string (struct edit_string *string, const char *replacement)
 Replace editable string.
int edit_string (struct edit_string *string, int key)
 Edit editable string.

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__()

__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}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define ENOMEM
Not enough space.
Definition errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memmove(void *dest, const void *src, size_t len) __nonnull
unsigned long tmp
Definition linux_pci.h:65
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition malloc.c:607
uint32_t string
Definition multiboot.h:2
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

References __nonnull, assert, backspace(), delete_character(), ENOMEM, insert_character(), kill_eol(), kill_sol(), kill_word(), memcpy(), memmove(), previous_word(), realloc(), string, strlen(), and tmp.

◆ insert_character()

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 __attribute__(), and edit_string().

◆ delete_character()

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}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3

References assert, NULL, rc, and string.

Referenced by __attribute__(), backspace(), and edit_string().

◆ backspace()

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}
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 __attribute__(), and edit_string().

◆ previous_word()

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 __attribute__(), and kill_word().

◆ kill_word()

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}
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 __attribute__(), and edit_string().

◆ kill_sol()

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}

References assert, NULL, rc, and string.

Referenced by __attribute__(), and edit_string().

◆ kill_eol()

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}

References assert, NULL, rc, and string.

Referenced by __attribute__(), and 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}
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
unsigned long retval
Definition xen.h:46
ring len
Length.
Definition dwmac.h:226
static void kill_eol(struct edit_string *string)
Delete to end of line.
Definition editstring.c:202
static void backspace(struct edit_string *string)
Delete character to left of current cursor position.
Definition editstring.c:143
static int insert_character(struct edit_string *string, unsigned int character)
Insert character at current cursor position.
Definition editstring.c:119
static void kill_sol(struct edit_string *string)
Delete to start of line.
Definition editstring.c:188
static void kill_word(struct edit_string *string)
Delete to end of previous word.
Definition editstring.c:174
#define KEY_RIGHT
Right arrow.
Definition keys.h:108
#define KEY_DC
Delete.
Definition keys.h:113
#define CTRL_E
Definition keys.h:23
#define KEY_BACKSPACE
Definition keys.h:128
#define CTRL_W
Definition keys.h:41
#define CTRL_B
Definition keys.h:20
#define CTRL_D
Definition keys.h:22
#define CTRL_F
Definition keys.h:24
#define CTRL_U
Definition keys.h:39
#define CTRL_K
Definition keys.h:29
#define KEY_END
End.
Definition keys.h:110
#define CTRL_A
Definition keys.h:19
#define KEY_LEFT
Left arrow.
Definition keys.h:109
#define KEY_HOME
Home.
Definition keys.h:111

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().