Annotation of qemu/roms/ipxe/src/hci/editstring.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (C) 2006 Michael Brown <[email protected]>.
        !             3:  *
        !             4:  * This program is free software; you can redistribute it and/or
        !             5:  * modify it under the terms of the GNU General Public License as
        !             6:  * published by the Free Software Foundation; either version 2 of the
        !             7:  * License, or any later version.
        !             8:  *
        !             9:  * This program is distributed in the hope that it will be useful, but
        !            10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            12:  * General Public License for more details.
        !            13:  *
        !            14:  * You should have received a copy of the GNU General Public License
        !            15:  * along with this program; if not, write to the Free Software
        !            16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            17:  */
        !            18: 
        !            19: FILE_LICENCE ( GPL2_OR_LATER );
        !            20: 
        !            21: #include <assert.h>
        !            22: #include <string.h>
        !            23: #include <ipxe/keys.h>
        !            24: #include <ipxe/editstring.h>
        !            25: 
        !            26: /** @file
        !            27:  *
        !            28:  * Editable strings
        !            29:  *
        !            30:  */
        !            31: 
        !            32: static void insert_delete ( struct edit_string *string, size_t delete_len,
        !            33:                             const char *insert_text ) 
        !            34:                            __attribute__ (( nonnull (1) ));
        !            35: static void insert_character ( struct edit_string *string,
        !            36:                                unsigned int character ) __nonnull;
        !            37: static void delete_character ( struct edit_string *string ) __nonnull;
        !            38: static void backspace ( struct edit_string *string ) __nonnull;
        !            39: static void kill_eol ( struct edit_string *string ) __nonnull;
        !            40: 
        !            41: /**
        !            42:  * Insert and/or delete text within an editable string
        !            43:  *
        !            44:  * @v string           Editable string
        !            45:  * @v delete_len       Length of text to delete from current cursor position
        !            46:  * @v insert_text      Text to insert at current cursor position, or NULL
        !            47:  */
        !            48: static void insert_delete ( struct edit_string *string, size_t delete_len,
        !            49:                            const char *insert_text ) {
        !            50:        size_t old_len, max_delete_len, insert_len, max_insert_len, new_len;
        !            51: 
        !            52:        /* Calculate lengths */
        !            53:        old_len = strlen ( string->buf );
        !            54:        assert ( string->cursor <= old_len );
        !            55:        max_delete_len = ( old_len - string->cursor );
        !            56:        if ( delete_len > max_delete_len )
        !            57:                delete_len = max_delete_len;
        !            58:        insert_len = ( insert_text ? strlen ( insert_text ) : 0 );
        !            59:        max_insert_len = ( ( string->len - 1 ) - ( old_len - delete_len ) );
        !            60:        if ( insert_len > max_insert_len )
        !            61:                insert_len = max_insert_len;
        !            62:        new_len = ( old_len - delete_len + insert_len );
        !            63: 
        !            64:        /* Fill in edit history */
        !            65:        string->mod_start = string->cursor;
        !            66:        string->mod_end = ( ( new_len > old_len ) ? new_len : old_len );
        !            67: 
        !            68:        /* Move data following the cursor */
        !            69:        memmove ( ( string->buf + string->cursor + insert_len ),
        !            70:                  ( string->buf + string->cursor + delete_len ),
        !            71:                  ( max_delete_len + 1 - delete_len ) );
        !            72: 
        !            73:        /* Copy inserted text to cursor position */
        !            74:        memcpy ( ( string->buf + string->cursor ), insert_text, insert_len );
        !            75:        string->cursor += insert_len;
        !            76: }
        !            77: 
        !            78: /**
        !            79:  * Insert character at current cursor position
        !            80:  *
        !            81:  * @v string           Editable string
        !            82:  * @v character                Character to insert
        !            83:  */
        !            84: static void insert_character ( struct edit_string *string,
        !            85:                              unsigned int character ) {
        !            86:        char insert_text[2] = { character, '\0' };
        !            87:        insert_delete ( string, 0, insert_text );
        !            88: }
        !            89: 
        !            90: /**
        !            91:  * Delete character at current cursor position
        !            92:  *
        !            93:  * @v string           Editable string
        !            94:  */
        !            95: static void delete_character ( struct edit_string *string ) {
        !            96:        insert_delete ( string, 1, NULL );
        !            97: }
        !            98: 
        !            99: /**
        !           100:  * Delete character to left of current cursor position
        !           101:  *
        !           102:  * @v string           Editable string
        !           103:  */
        !           104: static void backspace ( struct edit_string *string ) {
        !           105:        if ( string->cursor > 0 ) {
        !           106:                string->cursor--;
        !           107:                delete_character ( string );
        !           108:        }
        !           109: }
        !           110: 
        !           111: /**
        !           112:  * Delete to end of line
        !           113:  *
        !           114:  * @v string           Editable string
        !           115:  */
        !           116: static void kill_eol ( struct edit_string *string ) {
        !           117:        insert_delete ( string, ~( ( size_t ) 0 ), NULL );
        !           118: }
        !           119: 
        !           120: /**
        !           121:  * Replace editable string
        !           122:  *
        !           123:  * @v string           Editable string
        !           124:  * @v replacement      Replacement string
        !           125:  */
        !           126: void replace_string ( struct edit_string *string, const char *replacement ) {
        !           127:        string->cursor = 0;
        !           128:        insert_delete ( string, ~( ( size_t ) 0 ), replacement );
        !           129: }
        !           130: 
        !           131: /**
        !           132:  * Edit editable string
        !           133:  *
        !           134:  * @v string           Editable string
        !           135:  * @v key              Key pressed by user
        !           136:  * @ret key            Key returned to application, or zero
        !           137:  *
        !           138:  * Handles keypresses and updates the content of the editable string.
        !           139:  * Basic line editing facilities (delete/insert/cursor) are supported.
        !           140:  * If edit_string() understands and uses the keypress it will return
        !           141:  * zero, otherwise it will return the original key.
        !           142:  *
        !           143:  * This function does not update the display in any way.
        !           144:  *
        !           145:  * The string's edit history will be updated to allow the caller to
        !           146:  * efficiently bring the display into sync with the string content.
        !           147:  */
        !           148: int edit_string ( struct edit_string *string, int key ) {
        !           149:        int retval = 0;
        !           150:        size_t len = strlen ( string->buf );
        !           151: 
        !           152:        /* Prepare edit history */
        !           153:        string->last_cursor = string->cursor;
        !           154:        string->mod_start = string->cursor;
        !           155:        string->mod_end = string->cursor;
        !           156: 
        !           157:        /* Interpret key */
        !           158:        if ( ( key >= 0x20 ) && ( key <= 0x7e ) ) {
        !           159:                /* Printable character; insert at current position */
        !           160:                insert_character ( string, key );
        !           161:        } else switch ( key ) {
        !           162:        case KEY_BACKSPACE:
        !           163:                /* Backspace */
        !           164:                backspace ( string );
        !           165:                break;
        !           166:        case KEY_DC:
        !           167:        case CTRL_D:
        !           168:                /* Delete character */
        !           169:                delete_character ( string );
        !           170:                break;
        !           171:        case CTRL_K:
        !           172:                /* Delete to end of line */
        !           173:                kill_eol ( string );
        !           174:                break;
        !           175:        case KEY_HOME:
        !           176:        case CTRL_A:
        !           177:                /* Start of line */
        !           178:                string->cursor = 0;
        !           179:                break;
        !           180:        case KEY_END:
        !           181:        case CTRL_E:
        !           182:                /* End of line */
        !           183:                string->cursor = len;
        !           184:                break;
        !           185:        case KEY_LEFT:
        !           186:        case CTRL_B:
        !           187:                /* Cursor left */
        !           188:                if ( string->cursor > 0 )
        !           189:                        string->cursor--;
        !           190:                break;
        !           191:        case KEY_RIGHT:
        !           192:        case CTRL_F:
        !           193:                /* Cursor right */
        !           194:                if ( string->cursor < len )
        !           195:                        string->cursor++;
        !           196:                break;
        !           197:        default:
        !           198:                retval = key;
        !           199:                break;
        !           200:        }
        !           201: 
        !           202:        return retval;
        !           203: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.