fix the NANO_WIDE #ifdefs again, and put display_string_len() back in
now that it doesn't corrupt memory anymore (as far as I can tell) git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2202 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Этот коммит содержится в:
родитель
a35bdd1f03
Коммит
6a643cd596
12
ChangeLog
12
ChangeLog
@ -52,12 +52,12 @@ CVS code -
|
|||||||
Movement and cursor display in the edit window should now work
|
Movement and cursor display in the edit window should now work
|
||||||
properly with files containing multibyte characters, and text
|
properly with files containing multibyte characters, and text
|
||||||
display of such files should work properly some of the time.
|
display of such files should work properly some of the time.
|
||||||
New functions control_rep(), parse_char(), move_left(), and
|
New functions control_rep(), parse_char(), move_left(),
|
||||||
move_right(); changes to do_left(), do_right(), do_delete(),
|
move_right(), and display_string_len(); changes to do_left(),
|
||||||
breakable(), break_line(), do_output(), get_buffer(),
|
do_right(), do_delete(), breakable(), break_line(),
|
||||||
unget_input(), actual_x(), strnlenpt(), display_string(),
|
do_output(), get_buffer(), unget_input(), actual_x(),
|
||||||
titlebar(), statusbar(), onekey(), and do_credits(). (David
|
strnlenpt(), display_string(), titlebar(), statusbar(),
|
||||||
Benbennick and DLR)
|
onekey(), and do_credits(). (David Benbennick and DLR)
|
||||||
- cut.c:
|
- cut.c:
|
||||||
do_cut_text()
|
do_cut_text()
|
||||||
- If keep_cutbuffer is FALSE, only blow away the text in the
|
- If keep_cutbuffer is FALSE, only blow away the text in the
|
||||||
|
187
src/winio.c
187
src/winio.c
@ -1720,6 +1720,109 @@ void blank_bottombars(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* buf is a multibyte string to be displayed. We need to expand tabs
|
||||||
|
* and control characters. How many bytes do we need to display?
|
||||||
|
* start_col is the column of *buf (usually 0). We display to
|
||||||
|
* (end_col - 1). */
|
||||||
|
size_t display_string_len(const char *buf, size_t start_col, size_t
|
||||||
|
end_col)
|
||||||
|
{
|
||||||
|
size_t retval = 0;
|
||||||
|
|
||||||
|
assert(buf != NULL);
|
||||||
|
|
||||||
|
/* Throughout the loop, we maintain the fact that *buf displays at
|
||||||
|
* column start_col. */
|
||||||
|
while (start_col <= end_col && *buf != '\0') {
|
||||||
|
int wide_buf, wide_buf_len;
|
||||||
|
size_t old_col = start_col;
|
||||||
|
#ifdef NANO_WIDE
|
||||||
|
bool bad_char;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wide_buf_len = parse_char(buf, &wide_buf, &start_col
|
||||||
|
#ifdef NANO_WIDE
|
||||||
|
, &bad_char
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef NANO_WIDE
|
||||||
|
/* If buf contains a null byte or an invalid multibyte
|
||||||
|
* character, interpret that character as though it's a wide
|
||||||
|
* character. */
|
||||||
|
if (!ISSET(NO_UTF8) && bad_char) {
|
||||||
|
char *bad_wide_buf = charalloc(MB_CUR_MAX);
|
||||||
|
int bad_wide_buf_len;
|
||||||
|
|
||||||
|
/* If we have a control character, add one byte to account
|
||||||
|
* for the "^" that will be displayed in front of it, and
|
||||||
|
* translate the character to its visible equivalent as
|
||||||
|
* returned by control_rep(). */
|
||||||
|
if (is_cntrl_char(wide_buf)) {
|
||||||
|
retval++;
|
||||||
|
wide_buf = control_rep((unsigned char)wide_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Translate the wide character to its multibyte
|
||||||
|
* equivalent. */
|
||||||
|
bad_wide_buf_len = wctomb(bad_wide_buf, (wchar_t)wide_buf);
|
||||||
|
|
||||||
|
if (bad_wide_buf_len != -1)
|
||||||
|
retval += bad_wide_buf_len;
|
||||||
|
|
||||||
|
free(bad_wide_buf);
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
/* If we have a tab, get its width in bytes using the
|
||||||
|
* current value of col. */
|
||||||
|
if (wide_buf == '\t')
|
||||||
|
retval += start_col - old_col;
|
||||||
|
/* If we have a control character, add one byte to account
|
||||||
|
* for the "^" that will be displayed in front of it, and
|
||||||
|
* then add the number of bytes for its visible equivalent
|
||||||
|
* as returned by control_rep(). If we have an invalid
|
||||||
|
* multibyte control character, interpret that character as
|
||||||
|
* though it's a normal control character. */
|
||||||
|
else if (is_cntrl_char(wide_buf)) {
|
||||||
|
char ctrl_wide_buf =
|
||||||
|
control_rep((unsigned char)wide_buf);
|
||||||
|
|
||||||
|
retval++;
|
||||||
|
retval += parse_char(&ctrl_wide_buf, NULL, NULL
|
||||||
|
#ifdef NANO_WIDE
|
||||||
|
, NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
/* If we have a normal character, add its width in bytes
|
||||||
|
* normally. */
|
||||||
|
} else
|
||||||
|
#ifdef NANO_WIDE
|
||||||
|
/* If buf contains an invalid multibyte non-control
|
||||||
|
* character, interpret that character as though it's a
|
||||||
|
* normal non-control character. */
|
||||||
|
if (!ISSET(NO_UTF8) && bad_char) {
|
||||||
|
char *bad_wide_buf = charalloc(MB_CUR_MAX);
|
||||||
|
int bad_wide_buf_len;
|
||||||
|
|
||||||
|
bad_wide_buf_len = wctomb(bad_wide_buf,
|
||||||
|
(wchar_t)wide_buf);
|
||||||
|
|
||||||
|
free(bad_wide_buf);
|
||||||
|
|
||||||
|
retval += bad_wide_buf_len;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
retval += wide_buf_len;
|
||||||
|
#ifdef NANO_WIDE
|
||||||
|
}
|
||||||
|
|
||||||
|
buf += wide_buf_len;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert buf into a string that can be displayed on screen. The
|
/* Convert buf into a string that can be displayed on screen. The
|
||||||
* caller wants to display buf starting with column start_col, and
|
* caller wants to display buf starting with column start_col, and
|
||||||
* extending for at most len columns. start_col is zero-based. len is
|
* extending for at most len columns. start_col is zero-based. len is
|
||||||
@ -1755,13 +1858,8 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
|
|||||||
|
|
||||||
assert(column <= start_col);
|
assert(column <= start_col);
|
||||||
|
|
||||||
#ifdef NANO_WIDE
|
alloc_len = display_string_len(buf + start_index, start_col,
|
||||||
if (!ISSET(NO_UTF8))
|
start_col + COLS);
|
||||||
alloc_len = len * MB_CUR_MAX;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
alloc_len = len;
|
|
||||||
|
|
||||||
converted = charalloc(alloc_len + 1);
|
converted = charalloc(alloc_len + 1);
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
@ -1787,12 +1885,18 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
|
|||||||
int ctrl_wide_buf_len, i;
|
int ctrl_wide_buf_len, i;
|
||||||
|
|
||||||
wide_buf = control_rep((unsigned char)wide_buf);
|
wide_buf = control_rep((unsigned char)wide_buf);
|
||||||
ctrl_wide_buf_len =
|
|
||||||
#ifdef NANO_WIDE
|
#ifdef NANO_WIDE
|
||||||
!ISSET(NO_UTF8) ? wctomb(ctrl_wide_buf,
|
if (!ISSET(NO_UTF8))
|
||||||
(wchar_t)wide_buf) :
|
ctrl_wide_buf_len = wctomb(ctrl_wide_buf,
|
||||||
|
(wchar_t)wide_buf);
|
||||||
|
else {
|
||||||
|
#endif
|
||||||
|
ctrl_wide_buf_len = 1;
|
||||||
|
ctrl_wide_buf[0] = (unsigned char)wide_buf;
|
||||||
|
#ifdef NANO_WIDE
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
1;
|
|
||||||
|
|
||||||
for (i = 0; i < ctrl_wide_buf_len; i++)
|
for (i = 0; i < ctrl_wide_buf_len; i++)
|
||||||
converted[index++] = ctrl_wide_buf[i];
|
converted[index++] = ctrl_wide_buf[i];
|
||||||
@ -1826,27 +1930,6 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
|
|||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef NANO_WIDE
|
|
||||||
if (!ISSET(NO_UTF8) && bad_char) {
|
|
||||||
char *bad_wide_buf = charalloc(MB_CUR_MAX);
|
|
||||||
int bad_wide_buf_len, i;
|
|
||||||
|
|
||||||
if (is_cntrl_char(wide_buf)) {
|
|
||||||
converted[index++] = '^';
|
|
||||||
start_col++;
|
|
||||||
wide_buf = control_rep((unsigned char)wide_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
bad_wide_buf_len = wctomb(bad_wide_buf, (wchar_t)wide_buf);
|
|
||||||
|
|
||||||
for (i = 0; i < bad_wide_buf_len; i++)
|
|
||||||
converted[index++] = bad_wide_buf[i];
|
|
||||||
|
|
||||||
free(bad_wide_buf);
|
|
||||||
|
|
||||||
start_col += wcwidth((wchar_t)wide_buf);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
if (wide_buf == '\t') {
|
if (wide_buf == '\t') {
|
||||||
converted[index++] =
|
converted[index++] =
|
||||||
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
|
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
|
||||||
@ -1858,6 +1941,9 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
|
|||||||
converted[index++] = ' ';
|
converted[index++] = ' ';
|
||||||
start_col++;
|
start_col++;
|
||||||
}
|
}
|
||||||
|
/* If buf contains a control character, interpret it. If it
|
||||||
|
* contains an invalid multibyte control character, interpret
|
||||||
|
* that character as though it's a normal control character. */
|
||||||
} else if (is_cntrl_char(wide_buf)) {
|
} else if (is_cntrl_char(wide_buf)) {
|
||||||
char *ctrl_wide_buf =
|
char *ctrl_wide_buf =
|
||||||
#ifdef NANO_WIDE
|
#ifdef NANO_WIDE
|
||||||
@ -1870,12 +1956,17 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
|
|||||||
start_col++;
|
start_col++;
|
||||||
wide_buf = control_rep((unsigned char)wide_buf);
|
wide_buf = control_rep((unsigned char)wide_buf);
|
||||||
|
|
||||||
ctrl_wide_buf_len =
|
|
||||||
#ifdef NANO_WIDE
|
#ifdef NANO_WIDE
|
||||||
!ISSET(NO_UTF8) ? wctomb(ctrl_wide_buf,
|
if (!ISSET(NO_UTF8))
|
||||||
(wchar_t)wide_buf) :
|
ctrl_wide_buf_len = wctomb(ctrl_wide_buf,
|
||||||
|
(wchar_t)wide_buf);
|
||||||
|
else {
|
||||||
|
#endif
|
||||||
|
ctrl_wide_buf_len = 1;
|
||||||
|
ctrl_wide_buf[0] = (unsigned char)wide_buf;
|
||||||
|
#ifdef NANO_WIDE
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
1;
|
|
||||||
|
|
||||||
for (i = 0; i < ctrl_wide_buf_len; i++)
|
for (i = 0; i < ctrl_wide_buf_len; i++)
|
||||||
converted[index++] = ctrl_wide_buf[i];
|
converted[index++] = ctrl_wide_buf[i];
|
||||||
@ -1897,10 +1988,28 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
|
|||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < wide_buf_len; i++)
|
|
||||||
converted[index++] = buf[start_index + i];
|
|
||||||
|
|
||||||
#ifdef NANO_WIDE
|
#ifdef NANO_WIDE
|
||||||
|
/* If buf contains an invalid multibyte non-control
|
||||||
|
* character, interpret that character as though it's a
|
||||||
|
* normal non-control character. */
|
||||||
|
if (!ISSET(NO_UTF8) && bad_char) {
|
||||||
|
char *bad_wide_buf = charalloc(MB_CUR_MAX);
|
||||||
|
int bad_wide_buf_len;
|
||||||
|
|
||||||
|
bad_wide_buf_len = wctomb(bad_wide_buf,
|
||||||
|
(wchar_t)wide_buf);
|
||||||
|
|
||||||
|
for (i = 0; i < bad_wide_buf_len; i++)
|
||||||
|
converted[index++] = bad_wide_buf[i];
|
||||||
|
|
||||||
|
free(bad_wide_buf);
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < wide_buf_len; i++)
|
||||||
|
converted[index++] = buf[start_index + i];
|
||||||
|
#ifdef NANO_WIDE
|
||||||
|
}
|
||||||
|
|
||||||
if (!ISSET(NO_UTF8))
|
if (!ISSET(NO_UTF8))
|
||||||
start_col += wcwidth((wchar_t)wide_buf);
|
start_col += wcwidth((wchar_t)wide_buf);
|
||||||
else
|
else
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user