aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-10-20 08:59:03 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-10-20 08:59:03 +0000
commit4c9e9c4314e6f997f37814fffc6b49ebd24bd6be (patch)
tree5df6ccef20e28a939ee1a1cebcb60ee1b4f94c7b
parent078323010b5d88485748d05e512d451b876992b5 (diff)
downloadbusybox-w32-4c9e9c4314e6f997f37814fffc6b49ebd24bd6be.tar.gz
busybox-w32-4c9e9c4314e6f997f37814fffc6b49ebd24bd6be.tar.bz2
busybox-w32-4c9e9c4314e6f997f37814fffc6b49ebd24bd6be.zip
vi: handle chars 0x80, 0x81... correctly
-rw-r--r--editors/vi.c125
1 files changed, 64 insertions, 61 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 50dda7f3a..55154dcd7 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -57,29 +57,33 @@ enum {
57 MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN, 57 MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN,
58}; 58};
59 59
60// Misc. non-Ascii keys that report an escape sequence 60// "Keycodes" that report an escape sequence.
61#define VI_K_UP (char)128 // cursor key Up 61// We use something which fits into signed char,
62#define VI_K_DOWN (char)129 // cursor key Down 62// yet doesn't represent any valid Unicode characher.
63#define VI_K_RIGHT (char)130 // Cursor Key Right 63enum {
64#define VI_K_LEFT (char)131 // cursor key Left 64 VI_K_UP = -1, // cursor key Up
65#define VI_K_HOME (char)132 // Cursor Key Home 65 VI_K_DOWN = -2, // cursor key Down
66#define VI_K_END (char)133 // Cursor Key End 66 VI_K_RIGHT = -3, // Cursor Key Right
67#define VI_K_INSERT (char)134 // Cursor Key Insert 67 VI_K_LEFT = -4, // cursor key Left
68#define VI_K_DELETE (char)135 // Cursor Key Insert 68 VI_K_HOME = -5, // Cursor Key Home
69#define VI_K_PAGEUP (char)136 // Cursor Key Page Up 69 VI_K_END = -6, // Cursor Key End
70#define VI_K_PAGEDOWN (char)137 // Cursor Key Page Down 70 VI_K_INSERT = -7, // Cursor Key Insert
71#define VI_K_FUN1 (char)138 // Function Key F1 71 VI_K_DELETE = -8, // Cursor Key Insert
72#define VI_K_FUN2 (char)139 // Function Key F2 72 VI_K_PAGEUP = -9, // Cursor Key Page Up
73#define VI_K_FUN3 (char)140 // Function Key F3 73 VI_K_PAGEDOWN = -10, // Cursor Key Page Down
74#define VI_K_FUN4 (char)141 // Function Key F4 74 VI_K_FUN1 = -11, // Function Key F1
75#define VI_K_FUN5 (char)142 // Function Key F5 75 VI_K_FUN2 = -12, // Function Key F2
76#define VI_K_FUN6 (char)143 // Function Key F6 76 VI_K_FUN3 = -13, // Function Key F3
77#define VI_K_FUN7 (char)144 // Function Key F7 77 VI_K_FUN4 = -14, // Function Key F4
78#define VI_K_FUN8 (char)145 // Function Key F8 78 VI_K_FUN5 = -15, // Function Key F5
79#define VI_K_FUN9 (char)146 // Function Key F9 79 VI_K_FUN6 = -16, // Function Key F6
80#define VI_K_FUN10 (char)147 // Function Key F10 80 VI_K_FUN7 = -17, // Function Key F7
81#define VI_K_FUN11 (char)148 // Function Key F11 81 VI_K_FUN8 = -18, // Function Key F8
82#define VI_K_FUN12 (char)149 // Function Key F12 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};
83 87
84/* vt102 typical ESC sequence */ 88/* vt102 typical ESC sequence */
85/* terminal standout start/normal ESC sequence */ 89/* terminal standout start/normal ESC sequence */
@@ -171,9 +175,9 @@ struct globals {
171 char *screen; // pointer to the virtual screen buffer 175 char *screen; // pointer to the virtual screen buffer
172 int screensize; // and its size 176 int screensize; // and its size
173 int tabstop; 177 int tabstop;
178 int last_forward_char; // last char searched for with 'f' (int because of Unicode)
174 char erase_char; // the users erase character 179 char erase_char; // the users erase character
175 char last_input_char; // last char read from user 180 char last_input_char; // last char read from user
176 char last_forward_char; // last char searched for with 'f'
177 181
178#if ENABLE_FEATURE_VI_DOT_CMD 182#if ENABLE_FEATURE_VI_DOT_CMD
179 smallint adding2q; // are we currently adding user input to q 183 smallint adding2q; // are we currently adding user input to q
@@ -298,7 +302,7 @@ struct globals {
298 302
299static int init_text_buffer(char *); // init from file or create new 303static int init_text_buffer(char *); // init from file or create new
300static void edit_file(char *); // edit one file 304static void edit_file(char *); // edit one file
301static void do_cmd(char); // execute a command 305static void do_cmd(int); // execute a command
302static int next_tabstop(int); 306static int next_tabstop(int);
303static void sync_cursor(char *, int *, int *); // synchronize the screen cursor to dot 307static void sync_cursor(char *, int *, int *); // synchronize the screen cursor to dot
304static char *begin_line(char *); // return pointer to cur line B-o-l 308static char *begin_line(char *); // return pointer to cur line B-o-l
@@ -334,8 +338,8 @@ static void rawmode(void); // set "raw" mode on tty
334static void cookmode(void); // return to "cooked" mode on tty 338static void cookmode(void); // return to "cooked" mode on tty
335// sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready) 339// sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready)
336static int mysleep(int); 340static int mysleep(int);
337static char readit(void); // read (maybe cursor) key from stdin 341static int readit(void); // read (maybe cursor) key from stdin
338static char get_one_char(void); // read 1 char from stdin 342static int get_one_char(void); // read 1 char from stdin
339static int file_size(const char *); // what is the byte size of "fn" 343static int file_size(const char *); // what is the byte size of "fn"
340#if ENABLE_FEATURE_VI_READONLY 344#if ENABLE_FEATURE_VI_READONLY
341static int file_insert(const char *, char *, int); 345static int file_insert(const char *, char *, int);
@@ -524,7 +528,7 @@ static void edit_file(char *fn)
524#if ENABLE_FEATURE_VI_YANKMARK 528#if ENABLE_FEATURE_VI_YANKMARK
525#define cur_line edit_file__cur_line 529#define cur_line edit_file__cur_line
526#endif 530#endif
527 char c; 531 int c;
528 int size; 532 int size;
529#if ENABLE_FEATURE_VI_USE_SIGNALS 533#if ENABLE_FEATURE_VI_USE_SIGNALS
530 int sig; 534 int sig;
@@ -622,8 +626,10 @@ static void edit_file(char *fn)
622 // These are commands that change text[]. 626 // These are commands that change text[].
623 // Remember the input for the "." command 627 // Remember the input for the "." command
624 if (!adding2q && ioq_start == NULL 628 if (!adding2q && ioq_start == NULL
625 && cmd_mode == 0 /* command mode */ 629 && cmd_mode == 0 // command mode
626 && c != '\0' && strchr(modifying_cmds, c) 630 && c > '\0' // exclude NUL and non-ASCII chars
631 && c < 0x7f // (Unicode and such)
632 && strchr(modifying_cmds, c)
627 ) { 633 ) {
628 start_new_cmd_q(c); 634 start_new_cmd_q(c);
629 } 635 }
@@ -1198,7 +1204,7 @@ static void colon(char *buf)
1198 1204
1199static void Hit_Return(void) 1205static void Hit_Return(void)
1200{ 1206{
1201 char c; 1207 int c;
1202 1208
1203 standout_start(); 1209 standout_start();
1204 write1("[Hit return to continue]"); 1210 write1("[Hit return to continue]");
@@ -2191,15 +2197,15 @@ static int mysleep(int hund) // sleep for 'h' 1/100 seconds
2191} 2197}
2192 2198
2193//----- IO Routines -------------------------------------------- 2199//----- IO Routines --------------------------------------------
2194static char readit(void) // read (maybe cursor) key from stdin 2200static int readit(void) // read (maybe cursor) key from stdin
2195{ 2201{
2196 char c; 2202 int c;
2197 int n; 2203 int n;
2198 2204
2199 // Known escape sequences for cursor and function keys. 2205 // Known escape sequences for cursor and function keys.
2200 static const struct esc_cmds { 2206 static const struct esc_cmds {
2201 const char seq[4]; 2207 const char seq[4];
2202 char val; //TODO: int? Need to make it at least 8-bit clean! 2208 signed char val;
2203 } esccmds[] = { 2209 } esccmds[] = {
2204 {"OA" , VI_K_UP }, // Cursor Key Up 2210 {"OA" , VI_K_UP }, // Cursor Key Up
2205 {"OB" , VI_K_DOWN }, // Cursor Key Down 2211 {"OB" , VI_K_DOWN }, // Cursor Key Down
@@ -2256,7 +2262,7 @@ static char readit(void) // read (maybe cursor) key from stdin
2256 } 2262 }
2257 2263
2258 // Grab character to return from buffer 2264 // Grab character to return from buffer
2259 c = readbuffer[0]; 2265 c = (unsigned char)readbuffer[0];
2260 // Returning NUL from this routine would be bad. 2266 // Returning NUL from this routine would be bad.
2261 if (c == '\0') 2267 if (c == '\0')
2262 c = ' '; 2268 c = ' ';
@@ -2302,7 +2308,7 @@ static char readit(void) // read (maybe cursor) key from stdin
2302 break; // try next seq 2308 break; // try next seq
2303 i++; 2309 i++;
2304 if (i == 4 || !eindex->seq[i]) { // entire seq matched 2310 if (i == 4 || !eindex->seq[i]) { // entire seq matched
2305 c = eindex->val; 2311 c = eindex->val; // sign extended!
2306 n = 0; 2312 n = 0;
2307 // n -= i; memmove(...); 2313 // n -= i; memmove(...);
2308 // would be more correct, 2314 // would be more correct,
@@ -2322,9 +2328,9 @@ static char readit(void) // read (maybe cursor) key from stdin
2322} 2328}
2323 2329
2324//----- IO Routines -------------------------------------------- 2330//----- IO Routines --------------------------------------------
2325static char get_one_char(void) 2331static int get_one_char(void)
2326{ 2332{
2327 char c; 2333 int c;
2328 2334
2329#if ENABLE_FEATURE_VI_DOT_CMD 2335#if ENABLE_FEATURE_VI_DOT_CMD
2330 if (!adding2q) { 2336 if (!adding2q) {
@@ -2335,7 +2341,8 @@ static char get_one_char(void)
2335 c = readit(); // get the users input 2341 c = readit(); // get the users input
2336 } else { 2342 } else {
2337 // there is a queue to get chars from first 2343 // there is a queue to get chars from first
2338 c = *ioq++; 2344 // careful with correct sign expansion!
2345 c = (unsigned char)*ioq++;
2339 if (c == '\0') { 2346 if (c == '\0') {
2340 // the end of the q, read from STDIN 2347 // the end of the q, read from STDIN
2341 free(ioq_start); 2348 free(ioq_start);
@@ -2365,7 +2372,7 @@ static char *get_input_line(const char *prompt)
2365 // char [MAX_INPUT_LEN] 2372 // char [MAX_INPUT_LEN]
2366#define buf get_input_line__buf 2373#define buf get_input_line__buf
2367 2374
2368 char c; 2375 int c;
2369 int i; 2376 int i;
2370 2377
2371 strcpy(buf, prompt); 2378 strcpy(buf, prompt);
@@ -2384,7 +2391,8 @@ static char *get_input_line(const char *prompt)
2384 write1("\b \b"); // erase char on screen 2391 write1("\b \b"); // erase char on screen
2385 if (i <= 0) // user backs up before b-o-l, exit 2392 if (i <= 0) // user backs up before b-o-l, exit
2386 break; 2393 break;
2387 } else { 2394 } else if (c > 0 && c < 256) { // exclude Unicode
2395 // (TODO: need to handle Unicode)
2388 buf[i] = c; 2396 buf[i] = c;
2389 buf[++i] = '\0'; 2397 buf[++i] = '\0';
2390 bb_putchar(c); 2398 bb_putchar(c);
@@ -2987,13 +2995,14 @@ static void refresh(int full_screen)
2987//--------------------------------------------------------------------- 2995//---------------------------------------------------------------------
2988 2996
2989//----- Execute a Vi Command ----------------------------------- 2997//----- Execute a Vi Command -----------------------------------
2990static void do_cmd(char c) 2998static void do_cmd(int c)
2991{ 2999{
2992 const char *msg = msg; // for compiler 3000 const char *msg = msg; // for compiler
2993 char c1, *p, *q, *save_dot; 3001 char *p, *q, *save_dot;
2994 char buf[12]; 3002 char buf[12];
2995 int dir = dir; // for compiler 3003 int dir = dir; // for compiler
2996 int cnt, i, j; 3004 int cnt, i, j;
3005 int c1;
2997 3006
2998// c1 = c; // quiet the compiler 3007// c1 = c; // quiet the compiler
2999// cnt = yf = 0; // quiet the compiler 3008// cnt = yf = 0; // quiet the compiler
@@ -3173,21 +3182,18 @@ static void do_cmd(char c)
3173 break; 3182 break;
3174#if ENABLE_FEATURE_VI_YANKMARK 3183#if ENABLE_FEATURE_VI_YANKMARK
3175 case '"': // "- name a register to use for Delete/Yank 3184 case '"': // "- name a register to use for Delete/Yank
3176 c1 = get_one_char(); 3185 c1 = (get_one_char() | 0x20) - 'a'; // | 0x20 is tolower()
3177 c1 = tolower(c1); 3186 if ((unsigned)c1 <= 25) { // a-z?
3178 if (islower(c1)) { 3187 YDreg = c1;
3179 YDreg = c1 - 'a';
3180 } else { 3188 } else {
3181 indicate_error(c); 3189 indicate_error(c);
3182 } 3190 }
3183 break; 3191 break;
3184 case '\'': // '- goto a specific mark 3192 case '\'': // '- goto a specific mark
3185 c1 = get_one_char(); 3193 c1 = (get_one_char() | 0x20) - 'a';
3186 c1 = tolower(c1); 3194 if ((unsigned)c1 <= 25) { // a-z?
3187 if (islower(c1)) {
3188 c1 = c1 - 'a';
3189 // get the b-o-l 3195 // get the b-o-l
3190 q = mark[(unsigned char) c1]; 3196 q = mark[c1];
3191 if (text <= q && q < end) { 3197 if (text <= q && q < end) {
3192 dot = q; 3198 dot = q;
3193 dot_begin(); // go to B-o-l 3199 dot_begin(); // go to B-o-l
@@ -3206,12 +3212,10 @@ static void do_cmd(char c)
3206 // between text[0] and dot then this mark will not point to the 3212 // between text[0] and dot then this mark will not point to the
3207 // correct location! It could be off by many lines! 3213 // correct location! It could be off by many lines!
3208 // Well..., at least its quick and dirty. 3214 // Well..., at least its quick and dirty.
3209 c1 = get_one_char(); 3215 c1 = (get_one_char() | 0x20) - 'a';
3210 c1 = tolower(c1); 3216 if ((unsigned)c1 <= 25) { // a-z?
3211 if (islower(c1)) {
3212 c1 = c1 - 'a';
3213 // remember the line 3217 // remember the line
3214 mark[(int) c1] = dot; 3218 mark[c1] = dot;
3215 } else { 3219 } else {
3216 indicate_error(c); 3220 indicate_error(c);
3217 } 3221 }
@@ -3546,12 +3550,11 @@ static void do_cmd(char c)
3546 end_cmd_q(); // stop adding to q 3550 end_cmd_q(); // stop adding to q
3547#endif 3551#endif
3548 break; 3552 break;
3549 case 'g': // 'gg' goto a line number (from vim) 3553 case 'g': // 'gg' goto a line number (vim) (default: very first line)
3550 // (default to first line in file)
3551 c1 = get_one_char(); 3554 c1 = get_one_char();
3552 if (c1 != 'g') { 3555 if (c1 != 'g') {
3553 buf[0] = 'g'; 3556 buf[0] = 'g';
3554 buf[1] = c1; 3557 buf[1] = c1; // TODO: if Unicode?
3555 buf[2] = '\0'; 3558 buf[2] = '\0';
3556 not_implemented(buf); 3559 not_implemented(buf);
3557 break; 3560 break;
@@ -3804,7 +3807,7 @@ static void do_cmd(char c)
3804 do_cmd(';'); 3807 do_cmd(';');
3805 if (*dot == last_forward_char) 3808 if (*dot == last_forward_char)
3806 dot_left(); 3809 dot_left();
3807 last_forward_char= 0; 3810 last_forward_char = 0;
3808 break; 3811 break;
3809 case 'w': // w- forward a word 3812 case 'w': // w- forward a word
3810 if (cmdcnt-- > 1) { 3813 if (cmdcnt-- > 1) {