aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-10-25 23:23:00 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-10-25 23:23:00 +0000
commit0112ff5203e1bbc37425b87a71326aa0a85ec283 (patch)
tree93d798f5a0611f77e6eb9983368710875be334a3
parent73d702ee07347f5cf82175c28a12bdd8d297251f (diff)
downloadbusybox-w32-0112ff5203e1bbc37425b87a71326aa0a85ec283.tar.gz
busybox-w32-0112ff5203e1bbc37425b87a71326aa0a85ec283.tar.bz2
busybox-w32-0112ff5203e1bbc37425b87a71326aa0a85ec283.zip
vi: move key reading routine out of vi into llbbb
function old new delta read_key - 310 +310 .... static.esccmds 170 61 -109 readit 286 60 -226 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 9/10 up/down: 349/-367) Total: -18 bytes
-rw-r--r--editors/vi.c229
-rw-r--r--include/libbb.h33
-rw-r--r--libbb/Kbuild1
3 files changed, 78 insertions, 185 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 55154dcd7..0e7b729fe 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -57,34 +57,6 @@ enum {
57 MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN, 57 MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN,
58}; 58};
59 59
60// "Keycodes" that report an escape sequence.
61// We use something which fits into signed char,
62// yet doesn't represent any valid Unicode characher.
63enum {
64 VI_K_UP = -1, // cursor key Up
65 VI_K_DOWN = -2, // cursor key Down
66 VI_K_RIGHT = -3, // Cursor Key Right
67 VI_K_LEFT = -4, // cursor key Left
68 VI_K_HOME = -5, // Cursor Key Home
69 VI_K_END = -6, // Cursor Key End
70 VI_K_INSERT = -7, // Cursor Key Insert
71 VI_K_DELETE = -8, // Cursor Key Insert
72 VI_K_PAGEUP = -9, // Cursor Key Page Up
73 VI_K_PAGEDOWN = -10, // Cursor Key Page Down
74 VI_K_FUN1 = -11, // Function Key F1
75 VI_K_FUN2 = -12, // Function Key F2
76 VI_K_FUN3 = -13, // Function Key F3
77 VI_K_FUN4 = -14, // Function Key F4
78 VI_K_FUN5 = -15, // Function Key F5
79 VI_K_FUN6 = -16, // Function Key F6
80 VI_K_FUN7 = -17, // Function Key F7
81 VI_K_FUN8 = -18, // Function Key F8
82 VI_K_FUN9 = -19, // Function Key F9
83 VI_K_FUN10 = -20, // Function Key F10
84 VI_K_FUN11 = -21, // Function Key F11
85 VI_K_FUN12 = -22, // Function Key F12
86};
87
88/* vt102 typical ESC sequence */ 60/* vt102 typical ESC sequence */
89/* terminal standout start/normal ESC sequence */ 61/* terminal standout start/normal ESC sequence */
90static const char SOs[] ALIGN1 = "\033[7m"; 62static const char SOs[] ALIGN1 = "\033[7m";
@@ -179,6 +151,7 @@ struct globals {
179 char erase_char; // the users erase character 151 char erase_char; // the users erase character
180 char last_input_char; // last char read from user 152 char last_input_char; // last char read from user
181 153
154 smalluint chars_to_parse;
182#if ENABLE_FEATURE_VI_DOT_CMD 155#if ENABLE_FEATURE_VI_DOT_CMD
183 smallint adding2q; // are we currently adding user input to q 156 smallint adding2q; // are we currently adding user input to q
184 int lmc_len; // length of last_modifying_cmd 157 int lmc_len; // length of last_modifying_cmd
@@ -193,7 +166,7 @@ struct globals {
193#if ENABLE_FEATURE_VI_SEARCH 166#if ENABLE_FEATURE_VI_SEARCH
194 char *last_search_pattern; // last pattern from a '/' or '?' search 167 char *last_search_pattern; // last pattern from a '/' or '?' search
195#endif 168#endif
196 int chars_to_parse; 169
197 /* former statics */ 170 /* former statics */
198#if ENABLE_FEATURE_VI_YANKMARK 171#if ENABLE_FEATURE_VI_YANKMARK
199 char *edit_file__cur_line; 172 char *edit_file__cur_line;
@@ -259,9 +232,10 @@ struct globals {
259#define screensize (G.screensize ) 232#define screensize (G.screensize )
260#define screenbegin (G.screenbegin ) 233#define screenbegin (G.screenbegin )
261#define tabstop (G.tabstop ) 234#define tabstop (G.tabstop )
235#define last_forward_char (G.last_forward_char )
262#define erase_char (G.erase_char ) 236#define erase_char (G.erase_char )
263#define last_input_char (G.last_input_char ) 237#define last_input_char (G.last_input_char )
264#define last_forward_char (G.last_forward_char ) 238#define chars_to_parse (G.chars_to_parse )
265#if ENABLE_FEATURE_VI_READONLY 239#if ENABLE_FEATURE_VI_READONLY
266#define readonly_mode (G.readonly_mode ) 240#define readonly_mode (G.readonly_mode )
267#else 241#else
@@ -274,7 +248,6 @@ struct globals {
274#define last_row (G.last_row ) 248#define last_row (G.last_row )
275#define my_pid (G.my_pid ) 249#define my_pid (G.my_pid )
276#define last_search_pattern (G.last_search_pattern) 250#define last_search_pattern (G.last_search_pattern)
277#define chars_to_parse (G.chars_to_parse )
278 251
279#define edit_file__cur_line (G.edit_file__cur_line) 252#define edit_file__cur_line (G.edit_file__cur_line)
280#define refresh__old_offset (G.refresh__old_offset) 253#define refresh__old_offset (G.refresh__old_offset)
@@ -2200,130 +2173,14 @@ static int mysleep(int hund) // sleep for 'h' 1/100 seconds
2200static int readit(void) // read (maybe cursor) key from stdin 2173static int readit(void) // read (maybe cursor) key from stdin
2201{ 2174{
2202 int c; 2175 int c;
2203 int n;
2204
2205 // Known escape sequences for cursor and function keys.
2206 static const struct esc_cmds {
2207 const char seq[4];
2208 signed char val;
2209 } esccmds[] = {
2210 {"OA" , VI_K_UP }, // Cursor Key Up
2211 {"OB" , VI_K_DOWN }, // Cursor Key Down
2212 {"OC" , VI_K_RIGHT }, // Cursor Key Right
2213 {"OD" , VI_K_LEFT }, // Cursor Key Left
2214 {"OH" , VI_K_HOME }, // Cursor Key Home
2215 {"OF" , VI_K_END }, // Cursor Key End
2216 {"OP" , VI_K_FUN1 }, // Function Key F1
2217 {"OQ" , VI_K_FUN2 }, // Function Key F2
2218 {"OR" , VI_K_FUN3 }, // Function Key F3
2219 {"OS" , VI_K_FUN4 }, // Function Key F4
2220
2221 {"[A" , VI_K_UP }, // Cursor Key Up
2222 {"[B" , VI_K_DOWN }, // Cursor Key Down
2223 {"[C" , VI_K_RIGHT }, // Cursor Key Right
2224 {"[D" , VI_K_LEFT }, // Cursor Key Left
2225 {"[H" , VI_K_HOME }, // Cursor Key Home
2226 {"[F" , VI_K_END }, // Cursor Key End
2227 {"[1~" , VI_K_HOME }, // Cursor Key Home
2228 {"[2~" , VI_K_INSERT }, // Cursor Key Insert
2229 {"[3~" , VI_K_DELETE }, // Cursor Key Delete
2230 {"[4~" , VI_K_END }, // Cursor Key End
2231 {"[5~" , VI_K_PAGEUP }, // Cursor Key Page Up
2232 {"[6~" , VI_K_PAGEDOWN}, // Cursor Key Page Down
2233 // careful: these have no terminating NUL!
2234 {"[11~", VI_K_FUN1 }, // Function Key F1
2235 {"[12~", VI_K_FUN2 }, // Function Key F2
2236 {"[13~", VI_K_FUN3 }, // Function Key F3
2237 {"[14~", VI_K_FUN4 }, // Function Key F4
2238 {"[15~", VI_K_FUN5 }, // Function Key F5
2239 {"[17~", VI_K_FUN6 }, // Function Key F6
2240 {"[18~", VI_K_FUN7 }, // Function Key F7
2241 {"[19~", VI_K_FUN8 }, // Function Key F8
2242 {"[20~", VI_K_FUN9 }, // Function Key F9
2243 {"[21~", VI_K_FUN10 }, // Function Key F10
2244 {"[23~", VI_K_FUN11 }, // Function Key F11
2245 {"[24~", VI_K_FUN12 }, // Function Key F12
2246 };
2247 2176
2248 fflush(stdout); 2177 fflush(stdout);
2249 2178 c = read_key(STDIN_FILENO, &chars_to_parse, readbuffer);
2250 n = chars_to_parse; 2179 if (c == -1) { // EOF/error
2251 if (n == 0) { 2180 go_bottom_and_clear_to_eol();
2252 // If no data, block waiting for input. (If we read more than the 2181 cookmode(); // terminal to "cooked"
2253 // minimal ESC sequence size, the "n=0" below would instead have to 2182 bb_error_msg_and_die("can't read user input");
2254 // figure out how much to keep, resulting in larger code.)
2255 n = safe_read(0, readbuffer, 3);
2256 if (n <= 0) {
2257 error:
2258 go_bottom_and_clear_to_eol();
2259 cookmode(); // terminal to "cooked"
2260 bb_error_msg_and_die("can't read user input");
2261 }
2262 }
2263
2264 // Grab character to return from buffer
2265 c = (unsigned char)readbuffer[0];
2266 // Returning NUL from this routine would be bad.
2267 if (c == '\0')
2268 c = ' ';
2269 n--;
2270 if (n) memmove(readbuffer, readbuffer + 1, n);
2271
2272 // If it's an escape sequence, loop through known matches.
2273 if (c == 27) {
2274 const struct esc_cmds *eindex;
2275 struct pollfd pfd;
2276
2277 pfd.fd = STDIN_FILENO;
2278 pfd.events = POLLIN;
2279 for (eindex = esccmds; eindex < esccmds + ARRAY_SIZE(esccmds); eindex++)
2280 {
2281 // n - position in sequence we did not read yet
2282 int i = 0; // position in sequence to compare
2283
2284 // Loop through chars in this sequence
2285 for (;;) {
2286 // So far escape sequence matches up to [i-1]
2287 if (n <= i) {
2288 // Need more chars, read another one if it wouldn't block.
2289 // (Note that escape sequences come in as a unit,
2290 // so if we would block it's not really an escape sequence.)
2291
2292 // Timeout is needed to reconnect escape sequences
2293 // split up by transmission over a serial console.
2294
2295 if (safe_poll(&pfd, 1, 50)) {
2296 if (safe_read(0, readbuffer + n, 1) <= 0)
2297 goto error;
2298 n++;
2299 } else {
2300 // No more data!
2301 // Array is sorted from shortest to longest,
2302 // we can't match anything later in array,
2303 // break out of both loops.
2304 goto loop_out;
2305 }
2306 }
2307 if (readbuffer[i] != eindex->seq[i])
2308 break; // try next seq
2309 i++;
2310 if (i == 4 || !eindex->seq[i]) { // entire seq matched
2311 c = eindex->val; // sign extended!
2312 n = 0;
2313 // n -= i; memmove(...);
2314 // would be more correct,
2315 // but we never read ahead that much,
2316 // and n == i here.
2317 goto loop_out;
2318 }
2319 }
2320 }
2321 // We did not find matching sequence, it was a bare ESC.
2322 // We possibly read and stored more input in readbuffer by now.
2323 } 2183 }
2324 loop_out:
2325
2326 chars_to_parse = n;
2327 return c; 2184 return c;
2328} 2185}
2329 2186
@@ -3013,21 +2870,21 @@ static void do_cmd(int c)
3013 2870
3014 /* if this is a cursor key, skip these checks */ 2871 /* if this is a cursor key, skip these checks */
3015 switch (c) { 2872 switch (c) {
3016 case VI_K_UP: 2873 case KEYCODE_UP:
3017 case VI_K_DOWN: 2874 case KEYCODE_DOWN:
3018 case VI_K_LEFT: 2875 case KEYCODE_LEFT:
3019 case VI_K_RIGHT: 2876 case KEYCODE_RIGHT:
3020 case VI_K_HOME: 2877 case KEYCODE_HOME:
3021 case VI_K_END: 2878 case KEYCODE_END:
3022 case VI_K_PAGEUP: 2879 case KEYCODE_PAGEUP:
3023 case VI_K_PAGEDOWN: 2880 case KEYCODE_PAGEDOWN:
3024 case VI_K_DELETE: 2881 case KEYCODE_DELETE:
3025 goto key_cmd_mode; 2882 goto key_cmd_mode;
3026 } 2883 }
3027 2884
3028 if (cmd_mode == 2) { 2885 if (cmd_mode == 2) {
3029 // flip-flop Insert/Replace mode 2886 // flip-flop Insert/Replace mode
3030 if (c == VI_K_INSERT) 2887 if (c == KEYCODE_INSERT)
3031 goto dc_i; 2888 goto dc_i;
3032 // we are 'R'eplacing the current *dot with new char 2889 // we are 'R'eplacing the current *dot with new char
3033 if (*dot == '\n') { 2890 if (*dot == '\n') {
@@ -3044,7 +2901,7 @@ static void do_cmd(int c)
3044 } 2901 }
3045 if (cmd_mode == 1) { 2902 if (cmd_mode == 1) {
3046 // hitting "Insert" twice means "R" replace mode 2903 // hitting "Insert" twice means "R" replace mode
3047 if (c == VI_K_INSERT) goto dc5; 2904 if (c == KEYCODE_INSERT) goto dc5;
3048 // insert the char c at "dot" 2905 // insert the char c at "dot"
3049 if (1 <= c || Isprint(c)) { 2906 if (1 <= c || Isprint(c)) {
3050 dot = char_insert(dot, c); 2907 dot = char_insert(dot, c);
@@ -3108,7 +2965,7 @@ static void do_cmd(int c)
3108 case 0x00: // nul- ignore 2965 case 0x00: // nul- ignore
3109 break; 2966 break;
3110 case 2: // ctrl-B scroll up full screen 2967 case 2: // ctrl-B scroll up full screen
3111 case VI_K_PAGEUP: // Cursor Key Page Up 2968 case KEYCODE_PAGEUP: // Cursor Key Page Up
3112 dot_scroll(rows - 2, -1); 2969 dot_scroll(rows - 2, -1);
3113 break; 2970 break;
3114 case 4: // ctrl-D scroll down half screen 2971 case 4: // ctrl-D scroll down half screen
@@ -3118,14 +2975,14 @@ static void do_cmd(int c)
3118 dot_scroll(1, 1); 2975 dot_scroll(1, 1);
3119 break; 2976 break;
3120 case 6: // ctrl-F scroll down full screen 2977 case 6: // ctrl-F scroll down full screen
3121 case VI_K_PAGEDOWN: // Cursor Key Page Down 2978 case KEYCODE_PAGEDOWN: // Cursor Key Page Down
3122 dot_scroll(rows - 2, 1); 2979 dot_scroll(rows - 2, 1);
3123 break; 2980 break;
3124 case 7: // ctrl-G show current status 2981 case 7: // ctrl-G show current status
3125 last_status_cksum = 0; // force status update 2982 last_status_cksum = 0; // force status update
3126 break; 2983 break;
3127 case 'h': // h- move left 2984 case 'h': // h- move left
3128 case VI_K_LEFT: // cursor key Left 2985 case KEYCODE_LEFT: // cursor key Left
3129 case 8: // ctrl-H- move left (This may be ERASE char) 2986 case 8: // ctrl-H- move left (This may be ERASE char)
3130 case 0x7f: // DEL- move left (This may be ERASE char) 2987 case 0x7f: // DEL- move left (This may be ERASE char)
3131 if (cmdcnt-- > 1) { 2988 if (cmdcnt-- > 1) {
@@ -3135,7 +2992,7 @@ static void do_cmd(int c)
3135 break; 2992 break;
3136 case 10: // Newline ^J 2993 case 10: // Newline ^J
3137 case 'j': // j- goto next line, same col 2994 case 'j': // j- goto next line, same col
3138 case VI_K_DOWN: // cursor key Down 2995 case KEYCODE_DOWN: // cursor key Down
3139 if (cmdcnt-- > 1) { 2996 if (cmdcnt-- > 1) {
3140 do_cmd(c); 2997 do_cmd(c);
3141 } // repeat cnt 2998 } // repeat cnt
@@ -3174,7 +3031,7 @@ static void do_cmd(int c)
3174 break; 3031 break;
3175 case ' ': // move right 3032 case ' ': // move right
3176 case 'l': // move right 3033 case 'l': // move right
3177 case VI_K_RIGHT: // Cursor Key Right 3034 case KEYCODE_RIGHT: // Cursor Key Right
3178 if (cmdcnt-- > 1) { 3035 if (cmdcnt-- > 1) {
3179 do_cmd(c); 3036 do_cmd(c);
3180 } // repeat cnt 3037 } // repeat cnt
@@ -3259,7 +3116,7 @@ static void do_cmd(int c)
3259 break; 3116 break;
3260#endif /* FEATURE_VI_YANKMARK */ 3117#endif /* FEATURE_VI_YANKMARK */
3261 case '$': // $- goto end of line 3118 case '$': // $- goto end of line
3262 case VI_K_END: // Cursor Key End 3119 case KEYCODE_END: // Cursor Key End
3263 if (cmdcnt-- > 1) { 3120 if (cmdcnt-- > 1) {
3264 do_cmd(c); 3121 do_cmd(c);
3265 } // repeat cnt 3122 } // repeat cnt
@@ -3584,7 +3441,7 @@ static void do_cmd(int c)
3584 dot_skip_over_ws(); 3441 dot_skip_over_ws();
3585 //**** fall through to ... 'i' 3442 //**** fall through to ... 'i'
3586 case 'i': // i- insert before current char 3443 case 'i': // i- insert before current char
3587 case VI_K_INSERT: // Cursor Key Insert 3444 case KEYCODE_INSERT: // Cursor Key Insert
3588 dc_i: 3445 dc_i:
3589 cmd_mode = 1; // start insrting 3446 cmd_mode = 1; // start insrting
3590 break; 3447 break;
@@ -3637,7 +3494,7 @@ static void do_cmd(int c)
3637 dc5: 3494 dc5:
3638 cmd_mode = 2; 3495 cmd_mode = 2;
3639 break; 3496 break;
3640 case VI_K_DELETE: 3497 case KEYCODE_DELETE:
3641 c = 'x'; 3498 c = 'x';
3642 // fall through 3499 // fall through
3643 case 'X': // X- delete char before dot 3500 case 'X': // X- delete char before dot
@@ -3787,7 +3644,7 @@ static void do_cmd(int c)
3787 break; 3644 break;
3788 } 3645 }
3789 case 'k': // k- goto prev line, same col 3646 case 'k': // k- goto prev line, same col
3790 case VI_K_UP: // cursor key Up 3647 case KEYCODE_UP: // cursor key Up
3791 if (cmdcnt-- > 1) { 3648 if (cmdcnt-- > 1) {
3792 do_cmd(c); 3649 do_cmd(c);
3793 } // repeat cnt 3650 } // repeat cnt
@@ -3852,23 +3709,25 @@ static void do_cmd(int c)
3852 end_cmd_q(); // stop adding to q 3709 end_cmd_q(); // stop adding to q
3853 break; 3710 break;
3854 //----- The Cursor and Function Keys ----------------------------- 3711 //----- The Cursor and Function Keys -----------------------------
3855 case VI_K_HOME: // Cursor Key Home 3712 case KEYCODE_HOME: // Cursor Key Home
3856 dot_begin(); 3713 dot_begin();
3857 break; 3714 break;
3858 // The Fn keys could point to do_macro which could translate them 3715 // The Fn keys could point to do_macro which could translate them
3859 case VI_K_FUN1: // Function Key F1 3716#if 0
3860 case VI_K_FUN2: // Function Key F2 3717 case KEYCODE_FUN1: // Function Key F1
3861 case VI_K_FUN3: // Function Key F3 3718 case KEYCODE_FUN2: // Function Key F2
3862 case VI_K_FUN4: // Function Key F4 3719 case KEYCODE_FUN3: // Function Key F3
3863 case VI_K_FUN5: // Function Key F5 3720 case KEYCODE_FUN4: // Function Key F4
3864 case VI_K_FUN6: // Function Key F6 3721 case KEYCODE_FUN5: // Function Key F5
3865 case VI_K_FUN7: // Function Key F7 3722 case KEYCODE_FUN6: // Function Key F6
3866 case VI_K_FUN8: // Function Key F8 3723 case KEYCODE_FUN7: // Function Key F7
3867 case VI_K_FUN9: // Function Key F9 3724 case KEYCODE_FUN8: // Function Key F8
3868 case VI_K_FUN10: // Function Key F10 3725 case KEYCODE_FUN9: // Function Key F9
3869 case VI_K_FUN11: // Function Key F11 3726 case KEYCODE_FUN10: // Function Key F10
3870 case VI_K_FUN12: // Function Key F12 3727 case KEYCODE_FUN11: // Function Key F11
3728 case KEYCODE_FUN12: // Function Key F12
3871 break; 3729 break;
3730#endif
3872 } 3731 }
3873 3732
3874 dc1: 3733 dc1:
diff --git a/include/libbb.h b/include/libbb.h
index 5b92574dd..931710962 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -921,6 +921,39 @@ void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC;
921#endif 921#endif
922 922
923 923
924/* "Keycodes" that report an escape sequence.
925 * We use something which fits into signed char,
926 * yet doesn't represent any valid Unicode characher.
927 * Also, -1 is reserved for error indication and we don't use it. */
928enum {
929 KEYCODE_UP = -2,
930 KEYCODE_DOWN = -3,
931 KEYCODE_RIGHT = -4,
932 KEYCODE_LEFT = -5,
933 KEYCODE_HOME = -6,
934 KEYCODE_END = -7,
935 KEYCODE_INSERT = -8,
936 KEYCODE_DELETE = -9,
937 KEYCODE_PAGEUP = -10,
938 KEYCODE_PAGEDOWN = -11,
939#if 0
940 KEYCODE_FUN1 = -12,
941 KEYCODE_FUN2 = -13,
942 KEYCODE_FUN3 = -14,
943 KEYCODE_FUN4 = -15,
944 KEYCODE_FUN5 = -16,
945 KEYCODE_FUN6 = -17,
946 KEYCODE_FUN7 = -18,
947 KEYCODE_FUN8 = -19,
948 KEYCODE_FUN9 = -20,
949 KEYCODE_FUN10 = -21,
950 KEYCODE_FUN11 = -22,
951 KEYCODE_FUN12 = -23,
952#endif
953};
954int read_key(int fd, smalluint *nbuffered, char *buffer) FAST_FUNC;
955
956
924/* Networking */ 957/* Networking */
925int create_icmp_socket(void) FAST_FUNC; 958int create_icmp_socket(void) FAST_FUNC;
926int create_icmp6_socket(void) FAST_FUNC; 959int create_icmp6_socket(void) FAST_FUNC;
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 726200675..786cbee80 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -75,6 +75,7 @@ lib-y += process_escape_sequence.o
75lib-y += procps.o 75lib-y += procps.o
76lib-y += ptr_to_globals.o 76lib-y += ptr_to_globals.o
77lib-y += read.o 77lib-y += read.o
78lib-y += read_key.o
78lib-y += recursive_action.o 79lib-y += recursive_action.o
79lib-y += remove_file.o 80lib-y += remove_file.o
80lib-y += restricted_shell.o 81lib-y += restricted_shell.o