lines and the current line is so marked. */
static int modmark;
+static int line_totbytes;
+
/* Variables to save and restore prompt and display information. */
/* These are getting numerous enough that it's time to create a struct. */
if (physchars > bound) /* should rarely happen */
{
#if defined (HANDLE_MULTIBYTE)
+ *r = '\0'; /* need null-termination for strlen */
if (mb_cur_max > 1 && rl_byte_oriented == 0)
new = _rl_find_prev_mbchar (ret, r - ret, MB_FIND_ANY);
else
#endif
}
line[out] = '\0';
+ line_totbytes = out;
if (cpos_buffer_position < 0)
{
cpos_buffer_position = out;
the screen and dealing with changes to what's visible by modifying
OLD to match it. Complicated by the presence of multi-width
characters at the end of the line or beginning of the new one. */
+ /* old is always somewhere in visible_line; new is always somewhere in
+ invisible_line. These should always be null-terminated. */
#if defined (HANDLE_MULTIBYTE)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
oldwidth = 0;
else
oldwidth = WCWIDTH (wc);
+ if (oldwidth < 0)
+ oldwidth = 1;
/* 2. how many screen positions does the first char in new consume? */
memset (&ps, 0, sizeof (mbstate_t));
newwidth = 0;
else
newwidth = WCWIDTH (wc);
+ if (newwidth < 0)
+ newwidth = 1;
/* 3. if the new width is less than the old width, we need to keep
going in new until we have consumed at least that many screen
positions, and figure out how many bytes that will take */
while (newbytes < nmax && newwidth < oldwidth)
{
+ int t;
+
ret = mbrtowc (&wc, new+newbytes, mb_cur_max, &ps);
if (MB_INVALIDCH (ret))
{
break;
else
{
- newwidth += WCWIDTH (wc);
+ t = WCWIDTH (wc);
+ newwidth += (t >= 0) ? t : 1;
newbytes += ret;
}
}
figure out how many bytes that will take. This is an optimization */
while (oldbytes < omax && oldwidth < newwidth)
{
+ int t;
+
ret = mbrtowc (&wc, old+oldbytes, mb_cur_max, &ps);
if (MB_INVALIDCH (ret))
{
break;
else
{
- oldwidth += WCWIDTH (wc);
+ t = WCWIDTH (wc);
+ oldwidth += (t >= 0) ? t : 1;
oldbytes += ret;
}
}
{
/* We have written as many bytes from new as we need to
consume the first character of old. Fix up `old' so it
- reflects the new screen contents */
- memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes));
+ reflects the new screen contents. We use +1 in the
+ memmove call to copy the trailing NUL. */
+ memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1);
memcpy (old, new, newbytes);
j = newbytes - oldbytes;
}
}
-
/* Find first difference. */
#if defined (HANDLE_MULTIBYTE)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
}
#if 1
+#ifdef HANDLE_MULTIBYTE
/* If we write a non-space into the last screen column,
remove the note that we added a space to compensate for
a multibyte double-width character that didn't fit, since
line_state_invisible->wrapped_line[current_line+1] &&
nfd[bytes_to_insert-1] != ' ')
line_state_invisible->wrapped_line[current_line+1] = 0;
+#endif
#endif
}
else
#endif
#ifndef member
-# ifndef strchr
+# if !defined (strchr) && !defined (__STDC__)
extern char *strchr ();
-# endif
+# endif /* !strchr && !__STDC__ */
#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
#endif
int
_rl_read_mbstring (int first, char *mb, int mlen)
{
- int i, c;
+ int i, c, n;
mbstate_t ps;
c = first;
{
mb[i] = (char)c;
memset (&ps, 0, sizeof (mbstate_t));
- if (_rl_get_char_len (mb, &ps) == -2)
+ n = _rl_get_char_len (mb, &ps);
+ if (n == -2)
{
/* Read more for multibyte character */
RL_SETSTATE (RL_STATE_MOREINPUT);
_rl_isearch_fini (_rl_search_cxt *cxt)
{
/* First put back the original state. */
- strcpy (rl_line_buffer, cxt->lines[cxt->save_line]);
+ rl_replace_line (cxt->lines[cxt->save_line], 0);
rl_restore_prompt ();
rl_point = cxt->sline_index;
/* Don't worry about where to put the mark here; rl_get_previous_history
and rl_get_next_history take care of it. */
+ _rl_fix_point (0);
rl_clear_message ();
}
}
return (1);
}
- else if (cxt->sflags & SF_REVERSE)
+ else if (cxt->sflags & SF_REVERSE && cxt->sline_index > 0)
cxt->sline_index--;
else if (cxt->sline_index != cxt->sline_len)
cxt->sline_index++;
}
else
cxt->sline_index += cxt->direction;
+ if (cxt->sline_index < 0)
+ {
+ cxt->sline_index = 0;
+ break;
+ }
}
if (cxt->sflags & SF_FOUND)
break;
else
{
slot = rl_kill_ring_length += 1;
- rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
+ rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *));
}
rl_kill_ring[--slot] = (char *)NULL;
}
return seed;
point = seed + _rl_adjust_point (string, seed, &ps);
+ /* if _rl_adjust_point returns -1, the character or string is invalid.
+ treat as a byte. */
+ if (point == seed - 1) /* invalid */
+ return seed + 1;
+
/* if this is true, means that seed was not pointing to a byte indicating
the beginning of a multibyte character. Correct the point and consume
one char. */
int
_rl_get_char_len (char *src, mbstate_t *ps)
{
- size_t tmp;
+ size_t tmp, l;
+ int mb_cur_max;
- tmp = mbrlen((const char *)src, (size_t)strlen (src), ps);
+ /* Look at no more than MB_CUR_MAX characters */
+ l = (size_t)strlen (src);
+ mb_cur_max = MB_CUR_MAX;
+ tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps);
if (tmp == (size_t)(-2))
{
/* shorted to compose multibyte char */
/* adjust pointed byte and find mbstate of the point of string.
adjusted point will be point <= adjusted_point, and returns
differences of the byte(adjusted_point - point).
- if point is invalied (point < 0 || more than string length),
+ if point is invalid (point < 0 || more than string length),
it returns -1 */
int
_rl_adjust_point (char *string, int point, mbstate_t *ps)
l = strlen (buf);
if (ind >= l - 1)
return ((wchar_t) buf[ind]);
+ if (l < ind) /* Sanity check */
+ l = strlen (buf+ind);
memset (&ps, 0, sizeof (mbstate_t));
tmp = mbrtowc (&wc, buf + ind, l - ind, &ps);
if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))
}
else if (start >= 0 && rl_line_buffer[start] != '~')
{
- for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
+ for (; start >= 0 && !whitespace (rl_line_buffer[start]); start--)
;
start++;
}
#else
static int _rl_vi_last_search_char;
#endif
-static int _rl_vi_last_replacement;
+static char _rl_vi_last_replacement[MB_LEN_MAX+1]; /* reserve for trailing NULL */
static int _rl_vi_last_key_before_insert;
else
{
point = rl_point;
-#if 0
- rl_forward_char (1, key);
-#else
rl_point = _rl_forward_char_internal (1);
-#endif
if (point == rl_point)
rl_point = rl_end;
}
p = rl_point;
rl_vi_delete (1, c);
if (rl_point < p) /* Did we retreat at EOL? */
- rl_point++;
+ _rl_vi_append_forward (c);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (mb);
_rl_vi_callback_change_char (_rl_callback_generic_arg *data)
{
int c;
- char mb[MB_LEN_MAX];
+ char mb[MB_LEN_MAX+1];
- _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+ c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+#if defined (HANDLE_MULTIBYTE)
+ strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
+#else
+ _rl_vi_last_replacement[0] = c;
+#endif
+ _rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* XXX */
if (c < 0)
return -1;
rl_vi_change_char (int count, int key)
{
int c;
- char mb[MB_LEN_MAX];
+ char mb[MB_LEN_MAX+1];
if (_rl_vi_redoing)
{
- c = _rl_vi_last_replacement;
- mb[0] = c;
- mb[1] = '\0';
+ strncpy (mb, _rl_vi_last_replacement, MB_LEN_MAX);
+ c = (unsigned char)_rl_vi_last_replacement[0]; /* XXX */
+ mb[MB_LEN_MAX] = '\0';
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
}
#endif
else
- _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+ {
+ c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+#ifdef HANDLE_MULTIBYTE
+ strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
+#else
+ _rl_vi_last_replacement[0] = c;
+#endif
+ _rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* just in case */
+ }
if (c < 0)
return -1;