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-d3aeb78583b8master
parent
eb711b034b
commit
95a0224820
|
@ -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
|
||||||
|
|
118
src/winio.c
118
src/winio.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue