editstring.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <assert.h>
00022 #include <string.h>
00023 #include <gpxe/keys.h>
00024 #include <gpxe/editstring.h>
00025
00026
00027
00028
00029
00030
00031
00032 static void insert_delete ( struct edit_string *string, size_t delete_len,
00033 const char *insert_text )
00034 __attribute__ (( nonnull (1) ));
00035 static void insert_character ( struct edit_string *string,
00036 unsigned int character ) __nonnull;
00037 static void delete_character ( struct edit_string *string ) __nonnull;
00038 static void backspace ( struct edit_string *string ) __nonnull;
00039 static void kill_eol ( struct edit_string *string ) __nonnull;
00040
00041
00042
00043
00044
00045
00046
00047
00048 static void insert_delete ( struct edit_string *string, size_t delete_len,
00049 const char *insert_text ) {
00050 size_t old_len, max_delete_len, insert_len, max_insert_len, new_len;
00051
00052
00053 old_len = strlen ( string->buf );
00054 assert ( string->cursor <= old_len );
00055 max_delete_len = ( old_len - string->cursor );
00056 if ( delete_len > max_delete_len )
00057 delete_len = max_delete_len;
00058 insert_len = ( insert_text ? strlen ( insert_text ) : 0 );
00059 max_insert_len = ( ( string->len - 1 ) - ( old_len - delete_len ) );
00060 if ( insert_len > max_insert_len )
00061 insert_len = max_insert_len;
00062 new_len = ( old_len - delete_len + insert_len );
00063
00064
00065 string->mod_start = string->cursor;
00066 string->mod_end = ( ( new_len > old_len ) ? new_len : old_len );
00067
00068
00069 memmove ( ( string->buf + string->cursor + insert_len ),
00070 ( string->buf + string->cursor + delete_len ),
00071 ( max_delete_len + 1 - delete_len ) );
00072
00073
00074 memcpy ( ( string->buf + string->cursor ), insert_text, insert_len );
00075 string->cursor += insert_len;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084 static void insert_character ( struct edit_string *string,
00085 unsigned int character ) {
00086 char insert_text[2] = { character, '\0' };
00087 insert_delete ( string, 0, insert_text );
00088 }
00089
00090
00091
00092
00093
00094
00095 static void delete_character ( struct edit_string *string ) {
00096 insert_delete ( string, 1, NULL );
00097 }
00098
00099
00100
00101
00102
00103
00104 static void backspace ( struct edit_string *string ) {
00105 if ( string->cursor > 0 ) {
00106 string->cursor--;
00107 delete_character ( string );
00108 }
00109 }
00110
00111
00112
00113
00114
00115
00116 static void kill_eol ( struct edit_string *string ) {
00117 insert_delete ( string, ~( ( size_t ) 0 ), NULL );
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 int edit_string ( struct edit_string *string, int key ) {
00138 int retval = 0;
00139 size_t len = strlen ( string->buf );
00140
00141
00142 string->last_cursor = string->cursor;
00143 string->mod_start = string->cursor;
00144 string->mod_end = string->cursor;
00145
00146
00147 if ( ( key >= 0x20 ) && ( key <= 0x7e ) ) {
00148
00149 insert_character ( string, key );
00150 } else switch ( key ) {
00151 case KEY_BACKSPACE:
00152
00153 backspace ( string );
00154 break;
00155 case KEY_DC:
00156 case CTRL_D:
00157
00158 delete_character ( string );
00159 break;
00160 case CTRL_K:
00161
00162 kill_eol ( string );
00163 break;
00164 case KEY_HOME:
00165 case CTRL_A:
00166
00167 string->cursor = 0;
00168 break;
00169 case KEY_END:
00170 case CTRL_E:
00171
00172 string->cursor = len;
00173 break;
00174 case KEY_LEFT:
00175 case CTRL_B:
00176
00177 if ( string->cursor > 0 )
00178 string->cursor--;
00179 break;
00180 case KEY_RIGHT:
00181 case CTRL_F:
00182
00183 if ( string->cursor < len )
00184 string->cursor++;
00185 break;
00186 default:
00187 retval = key;
00188 break;
00189 }
00190
00191 return retval;
00192 }