svn commit: trunk/busybox/editors

vda at busybox.net vda at busybox.net
Mon Oct 20 08:59:04 UTC 2008


Author: vda
Date: 2008-10-20 01:59:03 -0700 (Mon, 20 Oct 2008)
New Revision: 23734

Log:
vi: handle chars 0x80, 0x81... correctly



Modified:
   trunk/busybox/editors/vi.c


Changeset:
Modified: trunk/busybox/editors/vi.c
===================================================================
--- trunk/busybox/editors/vi.c	2008-10-20 08:43:10 UTC (rev 23733)
+++ trunk/busybox/editors/vi.c	2008-10-20 08:59:03 UTC (rev 23734)
@@ -57,29 +57,33 @@
 	MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN,
 };
 
-// Misc. non-Ascii keys that report an escape sequence
-#define VI_K_UP			(char)128	// cursor key Up
-#define VI_K_DOWN		(char)129	// cursor key Down
-#define VI_K_RIGHT		(char)130	// Cursor Key Right
-#define VI_K_LEFT		(char)131	// cursor key Left
-#define VI_K_HOME		(char)132	// Cursor Key Home
-#define VI_K_END		(char)133	// Cursor Key End
-#define VI_K_INSERT		(char)134	// Cursor Key Insert
-#define VI_K_DELETE		(char)135	// Cursor Key Insert
-#define VI_K_PAGEUP		(char)136	// Cursor Key Page Up
-#define VI_K_PAGEDOWN		(char)137	// Cursor Key Page Down
-#define VI_K_FUN1		(char)138	// Function Key F1
-#define VI_K_FUN2		(char)139	// Function Key F2
-#define VI_K_FUN3		(char)140	// Function Key F3
-#define VI_K_FUN4		(char)141	// Function Key F4
-#define VI_K_FUN5		(char)142	// Function Key F5
-#define VI_K_FUN6		(char)143	// Function Key F6
-#define VI_K_FUN7		(char)144	// Function Key F7
-#define VI_K_FUN8		(char)145	// Function Key F8
-#define VI_K_FUN9		(char)146	// Function Key F9
-#define VI_K_FUN10		(char)147	// Function Key F10
-#define VI_K_FUN11		(char)148	// Function Key F11
-#define VI_K_FUN12		(char)149	// Function Key F12
+// "Keycodes" that report an escape sequence.
+// We use something which fits into signed char,
+// yet doesn't represent any valid Unicode characher.
+enum {
+	VI_K_UP       = -1,     // cursor key Up
+	VI_K_DOWN     = -2,     // cursor key Down
+	VI_K_RIGHT    = -3,     // Cursor Key Right
+	VI_K_LEFT     = -4,     // cursor key Left
+	VI_K_HOME     = -5,     // Cursor Key Home
+	VI_K_END      = -6,     // Cursor Key End
+	VI_K_INSERT   = -7,     // Cursor Key Insert
+	VI_K_DELETE   = -8,     // Cursor Key Insert
+	VI_K_PAGEUP   = -9,     // Cursor Key Page Up
+	VI_K_PAGEDOWN = -10,    // Cursor Key Page Down
+	VI_K_FUN1     = -11,    // Function Key F1
+	VI_K_FUN2     = -12,    // Function Key F2
+	VI_K_FUN3     = -13,    // Function Key F3
+	VI_K_FUN4     = -14,    // Function Key F4
+	VI_K_FUN5     = -15,    // Function Key F5
+	VI_K_FUN6     = -16,    // Function Key F6
+	VI_K_FUN7     = -17,    // Function Key F7
+	VI_K_FUN8     = -18,    // Function Key F8
+	VI_K_FUN9     = -19,    // Function Key F9
+	VI_K_FUN10    = -20,    // Function Key F10
+	VI_K_FUN11    = -21,    // Function Key F11
+	VI_K_FUN12    = -22,    // Function Key F12
+};
 
 /* vt102 typical ESC sequence */
 /* terminal standout start/normal ESC sequence */
@@ -171,9 +175,9 @@
 	char *screen;            // pointer to the virtual screen buffer
 	int screensize;          //            and its size
 	int tabstop;
+	int last_forward_char;   // last char searched for with 'f' (int because of Unicode)
 	char erase_char;         // the users erase character
 	char last_input_char;    // last char read from user
-	char last_forward_char;  // last char searched for with 'f'
 
 #if ENABLE_FEATURE_VI_DOT_CMD
 	smallint adding2q;	 // are we currently adding user input to q
@@ -298,7 +302,7 @@
 
 static int init_text_buffer(char *); // init from file or create new
 static void edit_file(char *);	// edit one file
-static void do_cmd(char);	// execute a command
+static void do_cmd(int);	// execute a command
 static int next_tabstop(int);
 static void sync_cursor(char *, int *, int *);	// synchronize the screen cursor to dot
 static char *begin_line(char *);	// return pointer to cur line B-o-l
@@ -334,8 +338,8 @@
 static void cookmode(void);	// return to "cooked" mode on tty
 // sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready)
 static int mysleep(int);
-static char readit(void);	// read (maybe cursor) key from stdin
-static char get_one_char(void);	// read 1 char from stdin
+static int readit(void);	// read (maybe cursor) key from stdin
+static int get_one_char(void);	// read 1 char from stdin
 static int file_size(const char *);   // what is the byte size of "fn"
 #if ENABLE_FEATURE_VI_READONLY
 static int file_insert(const char *, char *, int);
@@ -524,7 +528,7 @@
 #if ENABLE_FEATURE_VI_YANKMARK
 #define cur_line edit_file__cur_line
 #endif
-	char c;
+	int c;
 	int size;
 #if ENABLE_FEATURE_VI_USE_SIGNALS
 	int sig;
@@ -622,8 +626,10 @@
 		// These are commands that change text[].
 		// Remember the input for the "." command
 		if (!adding2q && ioq_start == NULL
-		 && cmd_mode == 0 /* command mode */
-		 && c != '\0' && strchr(modifying_cmds, c)
+		 && cmd_mode == 0 // command mode
+		 && c > '\0' // exclude NUL and non-ASCII chars
+		 && c < 0x7f // (Unicode and such)
+		 && strchr(modifying_cmds, c)
 		) {
 			start_new_cmd_q(c);
 		}
@@ -1198,7 +1204,7 @@
 
 static void Hit_Return(void)
 {
-	char c;
+	int c;
 
 	standout_start();
 	write1("[Hit return to continue]");
@@ -2191,15 +2197,15 @@
 }
 
 //----- IO Routines --------------------------------------------
-static char readit(void)	// read (maybe cursor) key from stdin
+static int readit(void) // read (maybe cursor) key from stdin
 {
-	char c;
+	int c;
 	int n;
 
 	// Known escape sequences for cursor and function keys.
 	static const struct esc_cmds {
 		const char seq[4];
-		char val; //TODO: int? Need to make it at least 8-bit clean!
+		signed char val;
 	} esccmds[] = {
 		{"OA"  , VI_K_UP      },   // Cursor Key Up
 		{"OB"  , VI_K_DOWN    },   // Cursor Key Down
@@ -2256,7 +2262,7 @@
 	}
 
 	// Grab character to return from buffer
-	c = readbuffer[0];
+	c = (unsigned char)readbuffer[0];
 	// Returning NUL from this routine would be bad.
 	if (c == '\0')
 		c = ' ';
@@ -2302,7 +2308,7 @@
 					break; // try next seq
 				i++;
 				if (i == 4 || !eindex->seq[i]) { // entire seq matched
-					c = eindex->val;
+					c = eindex->val; // sign extended!
 					n = 0;
 					// n -= i; memmove(...);
 					// would be more correct,
@@ -2322,9 +2328,9 @@
 }
 
 //----- IO Routines --------------------------------------------
-static char get_one_char(void)
+static int get_one_char(void)
 {
-	char c;
+	int c;
 
 #if ENABLE_FEATURE_VI_DOT_CMD
 	if (!adding2q) {
@@ -2335,7 +2341,8 @@
 			c = readit();	// get the users input
 		} else {
 			// there is a queue to get chars from first
-			c = *ioq++;
+			// careful with correct sign expansion!
+			c = (unsigned char)*ioq++;
 			if (c == '\0') {
 				// the end of the q, read from STDIN
 				free(ioq_start);
@@ -2365,7 +2372,7 @@
 	// char [MAX_INPUT_LEN]
 #define buf get_input_line__buf
 
-	char c;
+	int c;
 	int i;
 
 	strcpy(buf, prompt);
@@ -2384,7 +2391,8 @@
 			write1("\b \b"); // erase char on screen
 			if (i <= 0) // user backs up before b-o-l, exit
 				break;
-		} else {
+		} else if (c > 0 && c < 256) { // exclude Unicode
+			// (TODO: need to handle Unicode)
 			buf[i] = c;
 			buf[++i] = '\0';
 			bb_putchar(c);
@@ -2987,13 +2995,14 @@
 //---------------------------------------------------------------------
 
 //----- Execute a Vi Command -----------------------------------
-static void do_cmd(char c)
+static void do_cmd(int c)
 {
 	const char *msg = msg; // for compiler
-	char c1, *p, *q, *save_dot;
+	char *p, *q, *save_dot;
 	char buf[12];
 	int dir = dir; // for compiler
 	int cnt, i, j;
+	int c1;
 
 //	c1 = c; // quiet the compiler
 //	cnt = yf = 0; // quiet the compiler
@@ -3173,21 +3182,18 @@
 		break;
 #if ENABLE_FEATURE_VI_YANKMARK
 	case '"':			// "- name a register to use for Delete/Yank
-		c1 = get_one_char();
-		c1 = tolower(c1);
-		if (islower(c1)) {
-			YDreg = c1 - 'a';
+		c1 = (get_one_char() | 0x20) - 'a'; // | 0x20 is tolower()
+		if ((unsigned)c1 <= 25) { // a-z?
+			YDreg = c1;
 		} else {
 			indicate_error(c);
 		}
 		break;
 	case '\'':			// '- goto a specific mark
-		c1 = get_one_char();
-		c1 = tolower(c1);
-		if (islower(c1)) {
-			c1 = c1 - 'a';
+		c1 = (get_one_char() | 0x20) - 'a';
+		if ((unsigned)c1 <= 25) { // a-z?
 			// get the b-o-l
-			q = mark[(unsigned char) c1];
+			q = mark[c1];
 			if (text <= q && q < end) {
 				dot = q;
 				dot_begin();	// go to B-o-l
@@ -3206,12 +3212,10 @@
 		// between text[0] and dot then this mark will not point to the
 		// correct location! It could be off by many lines!
 		// Well..., at least its quick and dirty.
-		c1 = get_one_char();
-		c1 = tolower(c1);
-		if (islower(c1)) {
-			c1 = c1 - 'a';
+		c1 = (get_one_char() | 0x20) - 'a';
+		if ((unsigned)c1 <= 25) { // a-z?
 			// remember the line
-			mark[(int) c1] = dot;
+			mark[c1] = dot;
 		} else {
 			indicate_error(c);
 		}
@@ -3546,12 +3550,11 @@
 			end_cmd_q();	// stop adding to q
 #endif
 		break;
-	case 'g':                       // 'gg' goto a line number (from vim)
-					// (default to first line in file)
+	case 'g': // 'gg' goto a line number (vim) (default: very first line)
 		c1 = get_one_char();
 		if (c1 != 'g') {
 			buf[0] = 'g';
-			buf[1] = c1;
+			buf[1] = c1; // TODO: if Unicode?
 			buf[2] = '\0';
 			not_implemented(buf);
 			break;
@@ -3804,7 +3807,7 @@
 		do_cmd(';');
 		if (*dot == last_forward_char)
 			dot_left();
-		last_forward_char= 0;
+		last_forward_char = 0;
 		break;
 	case 'w':			// w- forward a word
 		if (cmdcnt-- > 1) {




More information about the busybox-cvs mailing list