+ ret = mbrtowc (&wc, new+newbytes, mb_cur_max, &ps);
+ if (MB_INVALIDCH (ret))
+ {
+ newwidth += 1;
+ newbytes += 1;
+ }
+ else if (MB_NULLWCH (ret))
+ break;
+ else
+ {
+ t = WCWIDTH (wc);
+ newwidth += (t >= 0) ? t : 1;
+ newbytes += ret;
+ }
+ }
+ /* 4. If the new width is more than the old width, keep going in old
+ until we have consumed exactly that many screen positions, and
+ 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))
+ {
+ oldwidth += 1;
+ oldbytes += 1;
+ }
+ else if (MB_NULLWCH (ret))
+ break;
+ else
+ {
+ t = WCWIDTH (wc);
+ oldwidth += (t >= 0) ? t : 1;
+ oldbytes += ret;
+ }
+ }
+ /* 5. write the first newbytes of new, which takes newwidth. This is
+ where the screen wrapping takes place, and we are now writing
+ characters onto the new line. We need to fix up old so it
+ accurately reflects what is on the screen after the
+ _rl_output_some_chars below. */
+ if (newwidth > 0)
+ {
+ int count, i, j;
+ char *optr;
+
+ _rl_output_some_chars (new, newbytes);
+ _rl_last_c_pos = newwidth;
+ _rl_last_v_pos++;
+
+ /* 5a. If the number of screen positions doesn't match, punt
+ and do a dumb update. */
+ if (newwidth != oldwidth)
+ {
+ ne = new + nmax;
+ nd = newbytes;
+ nfd = new + nd;
+ goto dumb_update;
+ }
+ if (oldbytes != 0 && newbytes != 0)
+ {
+ /* 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. 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;
+
+ omax += j;
+ /* Fix up indices if we copy data from one line to another */
+ for (i = current_line+1; i <= inv_botlin+1; i++)
+ vis_lbreaks[i] += j;
+ }
+ }
+ else
+ {
+ putc (' ', rl_outstream);
+ _rl_last_c_pos = 1;
+ _rl_last_v_pos++;
+ if (old[0] && new[0])
+ old[0] = new[0];
+ }
+ }
+ else
+#endif
+ {
+ if (new[0])
+ putc (new[0], rl_outstream);
+ else
+ putc (' ', rl_outstream);
+ _rl_last_c_pos = 1;
+ _rl_last_v_pos++;
+ if (old[0] && new[0])
+ old[0] = new[0];
+ }
+ }
+
+ /* Find first difference. */
+#if defined (HANDLE_MULTIBYTE)
+ if (mb_cur_max > 1 && rl_byte_oriented == 0)
+ {
+ /* See if the old line is a subset of the new line, so that the
+ only change is adding characters. */
+ temp = (omax < nmax) ? omax : nmax;
+ if (memcmp (old, new, temp) == 0) /* adding at the end */
+ {
+ new_offset = old_offset = temp;
+ ofd = old + temp;
+ nfd = new + temp;
+ }
+ else
+ {
+ memset (&ps_new, 0, sizeof(mbstate_t));
+ memset (&ps_old, 0, sizeof(mbstate_t));
+
+ /* Are the old and new lines the same? */
+ if (omax == nmax && STREQN (new, old, omax))
+ {
+ old_offset = omax;
+ new_offset = nmax;
+ ofd = old + omax;
+ nfd = new + nmax;
+ }
+ else
+ {
+ /* Go through the line from the beginning and find the first
+ difference. */
+ new_offset = old_offset = 0;
+ for (ofd = old, nfd = new;
+ (ofd - old < omax) && *ofd &&
+ _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
+ {
+ old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
+ new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
+
+ ofd = old + old_offset;
+ nfd = new + new_offset;
+ }
+ }
+ }
+ }
+ else
+#endif
+ for (ofd = old, nfd = new;
+ (ofd - old < omax) && *ofd && (*ofd == *nfd);
+ ofd++, nfd++)
+ ;
+
+ /* Move to the end of the screen line. ND and OD are used to keep track
+ of the distance between ne and new and oe and old, respectively, to