add support for reading in UTF-8 sequences to some of the low-level

input functions


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1989 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
David Lawrence Ramsey 2004-10-14 21:59:45 +00:00
parent a870ca2d72
commit 4e8e495301
4 changed files with 84 additions and 48 deletions

View File

@ -71,6 +71,9 @@ CVS code -
suggested by Bill Soudan) suggested by Bill Soudan)
- Remove the -D/--dos and -M/--mac command line options, as they - Remove the -D/--dos and -M/--mac command line options, as they
aren't much use with the new file format autodetection. (DLR) aren't much use with the new file format autodetection. (DLR)
- Add support for reading in UTF-8 sequences to some of the
low-level input routines. Changes to get_kbinput() and
get_translated_kbinput(). (DLR)
- files.c: - files.c:
do_insertfile() do_insertfile()
- Readd the NANO_SMALL #ifdef around the start_again: label to - Readd the NANO_SMALL #ifdef around the start_again: label to

View File

@ -492,6 +492,10 @@ typedef enum {
TOP, CENTER, NONE TOP, CENTER, NONE
} topmidnone; } topmidnone;
typedef enum {
NO_SEQ, ESCAPE_SEQ, UTF8_SEQ
} seq_type;
/* Minimum editor window rows required for nano to work correctly. */ /* Minimum editor window rows required for nano to work correctly. */
#define MIN_EDITOR_ROWS 3 #define MIN_EDITOR_ROWS 3

View File

@ -505,7 +505,7 @@ void reset_kbinput(void);
#endif #endif
void unget_kbinput(int kbinput, bool meta_key); void unget_kbinput(int kbinput, bool meta_key);
int get_kbinput(WINDOW *win, bool *meta_key, bool *func_key); int get_kbinput(WINDOW *win, bool *meta_key, bool *func_key);
int get_translated_kbinput(int kbinput, bool *func_key, bool *es int get_translated_kbinput(int kbinput, seq_type *seq
#ifndef NANO_SMALL #ifndef NANO_SMALL
, bool reset , bool reset
#endif #endif

View File

@ -96,7 +96,7 @@ static bool resetstatuspos = FALSE;
/* Reset all the input routines that rely on character sequences. */ /* Reset all the input routines that rely on character sequences. */
void reset_kbinput(void) void reset_kbinput(void)
{ {
get_translated_kbinput(0, NULL, NULL, TRUE); get_translated_kbinput(0, NULL, TRUE);
get_ascii_kbinput(0, 0, TRUE); get_ascii_kbinput(0, 0, TRUE);
get_untranslated_kbinput(0, 0, FALSE, TRUE); get_untranslated_kbinput(0, 0, FALSE, TRUE);
} }
@ -123,7 +123,7 @@ void unget_kbinput(int kbinput, bool meta_key)
int get_kbinput(WINDOW *win, bool *meta_key, bool *func_key) int get_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
{ {
int kbinput, retval = ERR; int kbinput, retval = ERR;
bool es; seq_type seq;
#ifndef NANO_SMALL #ifndef NANO_SMALL
allow_pending_sigwinch(TRUE); allow_pending_sigwinch(TRUE);
@ -138,49 +138,77 @@ int get_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
* to get_translated_kbinput(). Continue until we get a * to get_translated_kbinput(). Continue until we get a
* complete sequence. */ * complete sequence. */
kbinput = wgetch(win); kbinput = wgetch(win);
retval = get_translated_kbinput(kbinput, func_key, &es retval = get_translated_kbinput(kbinput, &seq
#ifndef NANO_SMALL #ifndef NANO_SMALL
, FALSE , FALSE
#endif #endif
); );
/* If we got an escape sequence, read it in, including the /* If we got a one-character sequence and it's outside the ASCII
* initial non-escape, as verbatim input. */ * range, set func_key to TRUE. */
if (es) { if (seq == NO_SEQ) {
int *escape_seq = NULL; if (retval > 255)
size_t es_len; *func_key = TRUE;
/* If we got a multi-character sequence, read it in, including
* the initial character, as verbatim input. */
} else {
int *sequence = NULL;
size_t seq_len;
/* Read in the complete escape sequence, putting the initial sequence = get_verbatim_kbinput(win, kbinput, sequence,
* non-escape at the beginning of it. */ &seq_len, FALSE);
escape_seq = get_verbatim_kbinput(win, kbinput, escape_seq,
&es_len, FALSE);
/* Handle escape sequences. */
if (seq == ESCAPE_SEQ) {
/* If the escape sequence is one character long, set /* If the escape sequence is one character long, set
* meta_key to TRUE, make the non-escape character * meta_key to TRUE, make the sequence character
* lowercase, and save that as the result. */ * lowercase, and save that as the result. */
if (es_len == 1) { if (seq_len == 1) {
*meta_key = TRUE; *meta_key = TRUE;
retval = tolower(kbinput); retval = tolower(kbinput);
/* If the escape sequence is more than one character /* If the escape sequence is more than one character
* long, set meta_key to FALSE, translate the escape * long, set meta_key to FALSE, translate the escape
* sequence into the corresponding key value, and save * sequence into the corresponding key value, and save
* that as the result. */ * that as the result. */
} else if (es_len > 1) { } else if (seq_len > 1) {
bool ignore_seq; bool ignore_seq;
*meta_key = FALSE; *meta_key = FALSE;
retval = get_escape_seq_kbinput(escape_seq, es_len, retval = get_escape_seq_kbinput(sequence, seq_len,
&ignore_seq); &ignore_seq);
if (retval == ERR && !ignore_seq) { if (retval == ERR && !ignore_seq) {
/* This escape sequence is unrecognized. Send it /* This escape sequence is unrecognized. Send
* it back. */
for (; seq_len > 1; seq_len--)
unget_kbinput(sequence[seq_len - 1], FALSE);
retval = sequence[0];
}
}
/* Handle UTF-8 sequences. */
} else if (seq == UTF8_SEQ) {
/* If we have a UTF-8 sequence, set func_key to FALSE,
* translate the UTF-8 sequence into the corresponding
* wide character value, and save that as the result. */
int i = 0;
char *s = charalloc(seq_len + 1);
wchar_t wc;
for (; i < seq_len; i++)
s[i] = (char)sequence[i];
s[seq_len] = '\0';
*func_key = FALSE;
if (mbtowc(&wc, s, MB_CUR_MAX) == -1) {
/* This UTF-8 sequence is unrecognized. Send it
* back. */ * back. */
for (; es_len > 1; es_len--) for (; seq_len > 1; seq_len--)
unget_kbinput(escape_seq[es_len - 1], FALSE); unget_kbinput(sequence[seq_len - 1], FALSE);
retval = escape_seq[0]; retval = sequence[0];
} else
retval = wc;
} }
} free(sequence);
free(escape_seq);
} }
} }
@ -195,11 +223,11 @@ int get_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
return retval; return retval;
} }
/* Translate acceptable ASCII, extended keypad values, and escape /* Translate acceptable ASCII, extended keypad values, and escape and
* sequences into their corresponding key values. Set func_key to TRUE * UTF-8 sequences into their corresponding key values. Set seq to
* when we get an extended keypad value, and set es to TRUE when we get * ESCAPE_SEQ when we get an escape sequence, or UTF8_SEQ when we get a
* an escape sequence. Assume nodelay(win) is FALSE. */ * UTF-8 sequence. Assume nodelay(win) is FALSE. */
int get_translated_kbinput(int kbinput, bool *func_key, bool *es int get_translated_kbinput(int kbinput, seq_type *seq
#ifndef NANO_SMALL #ifndef NANO_SMALL
, bool reset , bool reset
#endif #endif
@ -217,8 +245,7 @@ int get_translated_kbinput(int kbinput, bool *func_key, bool *es
} }
#endif #endif
*func_key = FALSE; *seq = NO_SEQ;
*es = FALSE;
switch (kbinput) { switch (kbinput) {
case ERR: case ERR:
@ -349,6 +376,12 @@ int get_translated_kbinput(int kbinput, bool *func_key, bool *es
break; break;
#endif #endif
default: default:
/* A character with its high bit set: UTF-8
* sequence mode. Set seq to UTF8_SEQ. */
if ((-128 <= kbinput && kbinput < 0) ||
(127 < kbinput && kbinput <= 255))
*seq = UTF8_SEQ;
retval = kbinput; retval = kbinput;
break; break;
} }
@ -356,9 +389,9 @@ int get_translated_kbinput(int kbinput, bool *func_key, bool *es
case 1: case 1:
/* One escape followed by a non-escape: escape /* One escape followed by a non-escape: escape
* sequence mode. Reset the escape counter and set * sequence mode. Reset the escape counter and set
* es to TRUE. */ * seq to ESCAPE_SEQ. */
escapes = 0; escapes = 0;
*es = TRUE; *seq = ESCAPE_SEQ;
break; break;
case 2: case 2:
switch (kbinput) { switch (kbinput) {
@ -428,12 +461,8 @@ int get_translated_kbinput(int kbinput, bool *func_key, bool *es
} }
} }
/* If the result is outside the ASCII range, set func_key to TRUE. */
if (retval > 255)
*func_key = TRUE;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "get_translated_kbinput(): kbinput = %d, func_key = %d, es = %d, escapes = %d, ascii_digits = %lu, retval = %d\n", kbinput, (int)*func_key, (int)*es, escapes, (unsigned long)ascii_digits, retval); fprintf(stderr, "get_translated_kbinput(): kbinput = %d, seq = %d, escapes = %d, ascii_digits = %lu, retval = %d\n", kbinput, (int)*seq, escapes, (unsigned long)ascii_digits, retval);
#endif #endif
/* Return the result. */ /* Return the result. */