miscellaneous fixes for the buffered inout and output routines and their

associated UTF-8 handling: have unget_input() filter out invalid wide
characters, put back the result of a word sequence instead of returning
it directly, don't erroneously filter out keystrokes if they're neither
extended keypad values nor ASCII characters, and add a few comment
tweaks


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2166 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
David Lawrence Ramsey 2004-12-06 04:14:42 +00:00
parent eb711b034b
commit 95a0224820
2 changed files with 86 additions and 46 deletions

View File

@ -3590,9 +3590,9 @@ void do_output(int *kbinput, size_t kbinput_len)
if (key_len == -1) if (key_len == -1)
continue; continue;
/* Interpret the character as a single-byte sequence. */
} else { } else {
#endif #endif
/* Interpret the character as a single-byte sequence. */
key_len = 1; key_len = 1;
key[0] = (char)kbinput[i]; key[0] = (char)kbinput[i];
#ifdef NANO_WIDE #ifdef NANO_WIDE

View File

@ -130,12 +130,7 @@ void reset_kbinput(void)
void get_buffer(WINDOW *win) void get_buffer(WINDOW *win)
{ {
int input; int input;
size_t i = 0; size_t i;
#ifdef NANO_WIDE
size_t wide_key_buffer_len = 0;
buffer *wide_key_buffer = NULL;
#endif
/* If the keystroke buffer isn't empty, get out. */ /* If the keystroke buffer isn't empty, get out. */
if (key_buffer != NULL) if (key_buffer != NULL)
@ -193,16 +188,20 @@ void get_buffer(WINDOW *win)
#ifdef NANO_WIDE #ifdef NANO_WIDE
if (!ISSET(NO_UTF8)) { if (!ISSET(NO_UTF8)) {
buffer *clean_key_buffer = NULL;
size_t clean_key_buffer_len = 0;
/* Change all incomplete or invalid multibyte keystrokes to -1, /* Change all incomplete or invalid multibyte keystrokes to -1,
* and change all complete and valid multibyte keystrokes to * and change all complete and valid multibyte keystrokes to
* their wide character value. */ * their wide character values. */
for (i = 0; i < key_buffer_len; i++) { for (i = 0; i < key_buffer_len; i++) {
wchar_t wide_key; wchar_t wide_key;
if (!key_buffer[i].key_code) { if (!key_buffer[i].key_code) {
key_buffer[i].key = mbtowc(&wide_key, if (mbtowc(&wide_key,
(const char *)&key_buffer[i].key, 1); (const char *)&key_buffer[i].key, 1) == -1)
if (key_buffer[i].key != -1) key_buffer[i].key = -1;
else
key_buffer[i].key = wide_key; key_buffer[i].key = wide_key;
} }
} }
@ -210,22 +209,22 @@ void get_buffer(WINDOW *win)
/* Save all of the non-(-1) keystrokes in another buffer. */ /* Save all of the non-(-1) keystrokes in another buffer. */
for (i = 0; i < key_buffer_len; i++) { for (i = 0; i < key_buffer_len; i++) {
if (key_buffer[i].key != -1) { if (key_buffer[i].key != -1) {
wide_key_buffer_len++; clean_key_buffer_len++;
wide_key_buffer = (buffer *)nrealloc(wide_key_buffer, clean_key_buffer = (buffer *)nrealloc(clean_key_buffer,
wide_key_buffer_len * sizeof(buffer)); clean_key_buffer_len * sizeof(buffer));
wide_key_buffer[wide_key_buffer_len - 1].key = clean_key_buffer[clean_key_buffer_len - 1].key =
key_buffer[i].key; key_buffer[i].key;
wide_key_buffer[wide_key_buffer_len - 1].key_code = clean_key_buffer[clean_key_buffer_len - 1].key_code =
key_buffer[i].key_code; key_buffer[i].key_code;
} }
} }
/* Replace the default keystroke buffer with the non-(-1) /* Replace the default keystroke buffer with the non-(-1)
* keystroke buffer. */ * keystroke buffer. */
key_buffer_len = wide_key_buffer_len; key_buffer_len = clean_key_buffer_len;
free(key_buffer); free(key_buffer);
key_buffer = wide_key_buffer; key_buffer = clean_key_buffer;
} }
#endif #endif
} }
@ -253,37 +252,74 @@ int *buffer_to_keys(buffer *input, size_t input_len)
* keystroke buffer. */ * keystroke buffer. */
void unget_input(buffer *input, size_t input_len) void unget_input(buffer *input, size_t input_len)
{ {
size_t i;
buffer *clean_input = NULL;
size_t clean_input_len = 0;
#ifndef NANO_SMALL #ifndef NANO_SMALL
allow_pending_sigwinch(TRUE); allow_pending_sigwinch(TRUE);
allow_pending_sigwinch(FALSE); allow_pending_sigwinch(FALSE);
#endif #endif
#ifdef NANO_WIDE
if (!ISSET(NO_UTF8)) {
/* Change all invalid wide character values to -1. */
for (i = 0; i < input_len; i++) {
char key[MB_LEN_MAX];
if (!input[i].key_code) {
if (wctomb(key, input[i].key) == -1)
input[i].key = -1;
}
}
/* Save all of the non-(-1) wide characters in another
* buffer. */
for (i = 0; i < input_len; i++) {
if (input[i].key != -1) {
clean_input_len++;
clean_input = (buffer *)nrealloc(clean_input,
clean_input_len * sizeof(buffer));
clean_input[clean_input_len - 1].key = input[i].key;
clean_input[clean_input_len - 1].key_code =
input[i].key_code;
}
}
} else {
#endif
clean_input = input;
clean_input_len = input_len;
#ifdef NANO_WIDE
}
#endif
/* If input is empty, get out. */ /* If input is empty, get out. */
if (input_len == 0) if (clean_input_len == 0)
return; return;
/* If adding input would put the default keystroke buffer beyond /* If adding input would put the default keystroke buffer beyond
* maximum capacity, only add enough of input to put it at maximum * maximum capacity, only add enough of input to put it at maximum
* capacity. */ * capacity. */
if (key_buffer_len + input_len < key_buffer_len) if (key_buffer_len + clean_input_len < key_buffer_len)
input_len = (size_t)-1 - key_buffer_len; clean_input_len = (size_t)-1 - key_buffer_len;
/* Add the length of input to the length of the default keystroke /* Add the length of input to the length of the default keystroke
* buffer, and reallocate the default keystroke buffer so that it * buffer, and reallocate the default keystroke buffer so that it
* has enough room for input. */ * has enough room for input. */
key_buffer_len += input_len; key_buffer_len += clean_input_len;
key_buffer = (buffer *)nrealloc(key_buffer, key_buffer_len * key_buffer = (buffer *)nrealloc(key_buffer, key_buffer_len *
sizeof(buffer)); sizeof(buffer));
/* If the default keystroke buffer wasn't empty before, move its /* If the default keystroke buffer wasn't empty before, move its
* beginning forward far enough so that we can add input to its * beginning forward far enough so that we can add input to its
* beginning. */ * beginning. */
if (key_buffer_len > input_len) if (key_buffer_len > clean_input_len)
memmove(key_buffer + input_len, key_buffer, memmove(key_buffer + clean_input_len, key_buffer,
(key_buffer_len - input_len) * sizeof(buffer)); (key_buffer_len - clean_input_len) * sizeof(buffer));
/* Copy input to the beginning of the default keystroke buffer. */ /* Copy input to the beginning of the default keystroke buffer. */
memcpy(key_buffer, input, input_len * sizeof(buffer)); memcpy(key_buffer, clean_input, clean_input_len * sizeof(buffer));
} }
/* Put back the character stored in kbinput. If func_key is TRUE and /* Put back the character stored in kbinput. If func_key is TRUE and
@ -400,7 +436,6 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
static int word_digits = 0; static int word_digits = 0;
buffer *kbinput; buffer *kbinput;
int retval = ERR; int retval = ERR;
bool no_func_key = FALSE;
if (reset) { if (reset) {
escapes = 0; escapes = 0;
@ -414,9 +449,9 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
/* Read in a character. */ /* Read in a character. */
while ((kbinput = get_input(win, 1)) == NULL); while ((kbinput = get_input(win, 1)) == NULL);
if (kbinput->key_code || is_byte_char(kbinput->key)) {
/* If we got an extended keypad value or an ASCII character, /* If we got an extended keypad value or an ASCII character,
* translate it. */ * translate it. */
if (kbinput->key_code || is_byte_char(kbinput->key)) {
switch (kbinput->key) { switch (kbinput->key) {
case ERR: case ERR:
break; break;
@ -608,31 +643,33 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
* first digit is in the '0' to '6' range and * first digit is in the '0' to '6' range and
* it's the first digit, or it's in the '0' to * it's the first digit, or it's in the '0' to
* '9' range and it's not the first digit), * '9' range and it's not the first digit),
* increment the word sequence counter, * increment the word sequence counter and
* interpret the digit, and save the * interpret the digit. If the word sequence's
* corresponding word value as the result. If * range is not limited to 6XXXX, fall
* the word sequence's range is not limited to * through. */
* 6XXXX, fall through. */
if (('0' <= kbinput->key && kbinput->key <= '6' if (('0' <= kbinput->key && kbinput->key <= '6'
&& word_digits == 0) || && word_digits == 0) ||
('0' <= kbinput->key && kbinput->key <= '9' ('0' <= kbinput->key && kbinput->key <= '9'
&& word_digits > 0)) { && word_digits > 0)) {
int word_kbinput;
word_digits++; word_digits++;
retval = get_word_kbinput(kbinput->key word_kbinput = get_word_kbinput(kbinput->key
#ifndef NANO_SMALL #ifndef NANO_SMALL
, FALSE , FALSE
#endif #endif
); );
if (retval != ERR) { if (word_kbinput != ERR) {
/* If we've read in a complete word /* If we've read in a complete word
* sequence, reset the word sequence * sequence, reset the word sequence
* counter and the escape counter, and * counter and the escape counter,
* mark it so that it isn't interpreted * and put back the corresponding word
* as an extended keypad value. */ * value. */
word_digits = 0; word_digits = 0;
escapes = 0; escapes = 0;
no_func_key = TRUE; unget_kbinput(word_kbinput, FALSE,
FALSE);
} }
} else { } else {
/* Reset the escape counter. */ /* Reset the escape counter. */
@ -659,12 +696,15 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
break; break;
} }
} }
}
/* If we have a result and it's an extended keypad value, set /* If we have a result and it's an extended keypad value, set
* func_key to TRUE. */ * func_key to TRUE. */
if (retval != ERR) if (retval != ERR)
*func_key = !is_byte_char(retval); *func_key = !is_byte_char(retval);
} else
/* If we didn't get an extended keypad value or an ASCII
* character, leave it as-is. */
retval = kbinput->key;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "parse_kbinput(): kbinput->key = %d, meta_key = %d, func_key = %d, escapes = %d, word_digits = %d, retval = %d\n", kbinput->key, (int)*meta_key, (int)*func_key, escapes, word_digits, retval); fprintf(stderr, "parse_kbinput(): kbinput->key = %d, meta_key = %d, func_key = %d, escapes = %d, word_digits = %d, retval = %d\n", kbinput->key, (int)*meta_key, (int)*func_key, escapes, word_digits, retval);