iPXE
Functions
editstring.c File Reference

Editable strings. More...

#include <assert.h>
#include <string.h>
#include <ctype.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)
static void insert_delete (struct edit_string *string, size_t delete_len, const char *insert_text)
 Insert and/or delete text within an editable string.
static void 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.
void 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 ( GPL2_OR_LATER_OR_UBDL  )
static void insert_delete ( struct edit_string string,
size_t  delete_len,
const char *  insert_text 
) [static]

Insert and/or delete text within an editable string.

Parameters:
stringEditable string
delete_lenLength of text to delete from current cursor position
insert_textText to insert at current cursor position, or NULL

Definition at line 57 of file editstring.c.

References assert, edit_string::buf, edit_string::cursor, memcpy(), memmove(), and strlen().

Referenced by delete_character(), insert_character(), kill_eol(), kill_sol(), kill_word(), and replace_string().

                                                      {
        size_t old_len, max_delete_len, insert_len, max_insert_len, new_len;

        /* Calculate lengths */
        old_len = strlen ( string->buf );
        assert ( string->cursor <= old_len );
        max_delete_len = ( old_len - string->cursor );
        if ( delete_len > max_delete_len )
                delete_len = max_delete_len;
        insert_len = ( insert_text ? strlen ( insert_text ) : 0 );
        max_insert_len = ( ( string->len - 1 ) - ( old_len - delete_len ) );
        if ( insert_len > max_insert_len )
                insert_len = max_insert_len;
        new_len = ( old_len - delete_len + insert_len );

        /* Fill in edit history */
        string->mod_start = string->cursor;
        string->mod_end = ( ( new_len > old_len ) ? new_len : old_len );

        /* Move data following the cursor */
        memmove ( ( string->buf + string->cursor + insert_len ),
                  ( string->buf + string->cursor + delete_len ),
                  ( max_delete_len + 1 - delete_len ) );

        /* Copy inserted text to cursor position */
        memcpy ( ( string->buf + string->cursor ), insert_text, insert_len );
        string->cursor += insert_len;
}
static void insert_character ( struct edit_string string,
unsigned int  character 
) [static]

Insert character at current cursor position.

Parameters:
stringEditable string
characterCharacter to insert

Definition at line 93 of file editstring.c.

References insert_delete().

Referenced by edit_string().

                                                       {
        char insert_text[2] = { character, '\0' };
        insert_delete ( string, 0, insert_text );
}
static void delete_character ( struct edit_string string) [static]

Delete character at current cursor position.

Parameters:
stringEditable string

Definition at line 104 of file editstring.c.

References insert_delete(), and NULL.

Referenced by backspace(), and edit_string().

                                                            {
        insert_delete ( string, 1, NULL );
}
static void backspace ( struct edit_string string) [static]

Delete character to left of current cursor position.

Parameters:
stringEditable string

Definition at line 113 of file editstring.c.

References edit_string::cursor, and delete_character().

Referenced by edit_string().

                                                     {
        if ( string->cursor > 0 ) {
                string->cursor--;
                delete_character ( string );
        }
}
static void previous_word ( struct edit_string string) [static]

Move to start of previous word.

Parameters:
stringEditable string

Definition at line 125 of file editstring.c.

References edit_string::buf, edit_string::cursor, and isspace().

Referenced by kill_word().

                                                         {
        while ( string->cursor &&
                isspace ( string->buf[ string->cursor - 1 ] ) ) {
                string->cursor--;
        }
        while ( string->cursor &&
                ( ! isspace ( string->buf[ string->cursor - 1 ] ) ) ) {
                string->cursor--;
        }
}
static void kill_word ( struct edit_string string) [static]

Delete to end of previous word.

Parameters:
stringEditable string

Definition at line 141 of file editstring.c.

References edit_string::cursor, insert_delete(), NULL, and previous_word().

Referenced by edit_string().

                                                     {
        size_t old_cursor = string->cursor;
        previous_word ( string );
        insert_delete ( string, ( old_cursor - string->cursor ), NULL );
}
static void kill_sol ( struct edit_string string) [static]

Delete to start of line.

Parameters:
stringEditable string

Definition at line 152 of file editstring.c.

References insert_delete(), and NULL.

Referenced by edit_string().

                                                    {
        size_t old_cursor = string->cursor;
        string->cursor = 0;
        insert_delete ( string, old_cursor, NULL );
}
static void kill_eol ( struct edit_string string) [static]

Delete to end of line.

Parameters:
stringEditable string

Definition at line 163 of file editstring.c.

References insert_delete(), and NULL.

Referenced by edit_string().

                                                    {
        insert_delete ( string, ~( ( size_t ) 0 ), NULL );
}
void replace_string ( struct edit_string string,
const char *  replacement 
)

Replace editable string.

Parameters:
stringEditable string
replacementReplacement string

Definition at line 173 of file editstring.c.

References insert_delete().

Referenced by readline_history().

                                                                            {
        string->cursor = 0;
        insert_delete ( string, ~( ( size_t ) 0 ), replacement );
}
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, or zero

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.

This function does not update the display in any way.

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

Definition at line 195 of file editstring.c.

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

Referenced by edit_editbox(), and readline_history().

                                                        {
        int retval = 0;
        size_t len = strlen ( string->buf );

        /* Prepare edit history */
        string->last_cursor = string->cursor;
        string->mod_start = string->cursor;
        string->mod_end = string->cursor;

        /* Interpret key */
        if ( ( key >= 0x20 ) && ( key <= 0x7e ) ) {
                /* Printable character; insert at current position */
                insert_character ( string, key );
        } else switch ( key ) {
        case KEY_BACKSPACE:
                /* Backspace */
                backspace ( string );
                break;
        case KEY_DC:
        case CTRL_D:
                /* Delete character */
                delete_character ( string );
                break;
        case CTRL_W:
                /* Delete word */
                kill_word ( string );
                break;
        case CTRL_U:
                /* Delete to start of line */
                kill_sol ( string );
                break;
        case CTRL_K:
                /* Delete to end of line */
                kill_eol ( string );
                break;
        case KEY_HOME:
        case CTRL_A:
                /* Start of line */
                string->cursor = 0;
                break;
        case KEY_END:
        case CTRL_E:
                /* End of line */
                string->cursor = len;
                break;
        case KEY_LEFT:
        case CTRL_B:
                /* Cursor left */
                if ( string->cursor > 0 )
                        string->cursor--;
                break;
        case KEY_RIGHT:
        case CTRL_F:
                /* Cursor right */
                if ( string->cursor < len )
                        string->cursor++;
                break;
        default:
                retval = key;
                break;
        }

        return retval;
}