xref: /dragonfly/contrib/gdb-7/readline/display.c (revision cfd1aba3)
1 /* display.c -- readline redisplay facility. */
2 
3 /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
4 
5    This file is part of the GNU Readline Library (Readline), a library
6    for reading lines of text with interactive input and history editing.
7 
8    Readline is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12 
13    Readline is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #define READLINE_LIBRARY
23 
24 #if defined (HAVE_CONFIG_H)
25 #  include <config.h>
26 #endif
27 
28 #include <sys/types.h>
29 
30 #if defined (HAVE_UNISTD_H)
31 #  include <unistd.h>
32 #endif /* HAVE_UNISTD_H */
33 
34 #include "posixstat.h"
35 
36 #if defined (HAVE_STDLIB_H)
37 #  include <stdlib.h>
38 #else
39 #  include "ansi_stdlib.h"
40 #endif /* HAVE_STDLIB_H */
41 
42 #include <stdio.h>
43 
44 #ifdef __MSDOS__
45 # include <pc.h>
46 #endif
47 
48 /* System-specific feature definitions and include files. */
49 #include "rldefs.h"
50 #include "rlmbutil.h"
51 
52 /* Termcap library stuff. */
53 #include "tcap.h"
54 
55 /* Some standard library routines. */
56 #include "readline.h"
57 #include "history.h"
58 
59 #include "rlprivate.h"
60 #include "xmalloc.h"
61 
62 #if !defined (strchr) && !defined (__STDC__)
63 extern char *strchr (), *strrchr ();
64 #endif /* !strchr && !__STDC__ */
65 
66 static void update_line PARAMS((char *, char *, int, int, int, int));
67 static void space_to_eol PARAMS((int));
68 static void delete_chars PARAMS((int));
69 static void insert_some_chars PARAMS((char *, int, int));
70 static void cr PARAMS((void));
71 
72 /* State of visible and invisible lines. */
73 struct line_state
74   {
75     char *line;
76     int *lbreaks;
77     int lbsize;
78 #if defined (HANDLE_MULTIBYTE)
79     int *wrapped_line;
80     int wbsize;
81 #endif
82   };
83 
84 /* The line display buffers.  One is the line currently displayed on
85    the screen.  The other is the line about to be displayed. */
86 static struct line_state line_state_array[2];
87 static struct line_state *line_state_visible = &line_state_array[0];
88 static struct line_state *line_state_invisible = &line_state_array[1];
89 static int line_structures_initialized = 0;
90 
91 /* Backwards-compatible names. */
92 #define inv_lbreaks	(line_state_invisible->lbreaks)
93 #define inv_lbsize	(line_state_invisible->lbsize)
94 #define vis_lbreaks	(line_state_visible->lbreaks)
95 #define vis_lbsize	(line_state_visible->lbsize)
96 
97 #define visible_line	(line_state_visible->line)
98 #define invisible_line	(line_state_invisible->line)
99 
100 #if defined (HANDLE_MULTIBYTE)
101 static int _rl_col_width PARAMS((const char *, int, int, int));
102 #else
103 #  define _rl_col_width(l, s, e, f)	(((e) <= (s)) ? 0 : (e) - (s))
104 #endif
105 
106 /* Heuristic used to decide whether it is faster to move from CUR to NEW
107    by backing up or outputting a carriage return and moving forward.  CUR
108    and NEW are either both buffer positions or absolute screen positions. */
109 #define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
110 
111 /* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
112    buffer index in others.  This macro is used when deciding whether the
113    current cursor position is in the middle of a prompt string containing
114    invisible characters.  XXX - might need to take `modmark' into account. */
115 #define PROMPT_ENDING_INDEX \
116   ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
117 
118 
119 /* **************************************************************** */
120 /*								    */
121 /*			Display stuff				    */
122 /*								    */
123 /* **************************************************************** */
124 
125 /* This is the stuff that is hard for me.  I never seem to write good
126    display routines in C.  Let's see how I do this time. */
127 
128 /* (PWP) Well... Good for a simple line updater, but totally ignores
129    the problems of input lines longer than the screen width.
130 
131    update_line and the code that calls it makes a multiple line,
132    automatically wrapping line update.  Careful attention needs
133    to be paid to the vertical position variables. */
134 
135 /* Keep two buffers; one which reflects the current contents of the
136    screen, and the other to draw what we think the new contents should
137    be.  Then compare the buffers, and make whatever changes to the
138    screen itself that we should.  Finally, make the buffer that we
139    just drew into be the one which reflects the current contents of the
140    screen, and place the cursor where it belongs.
141 
142    Commands that want to can fix the display themselves, and then let
143    this function know that the display has been fixed by setting the
144    RL_DISPLAY_FIXED variable.  This is good for efficiency. */
145 
146 /* Application-specific redisplay function. */
147 rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
148 
149 /* Global variables declared here. */
150 /* What YOU turn on when you have handled all redisplay yourself. */
151 int rl_display_fixed = 0;
152 
153 int _rl_suppress_redisplay = 0;
154 int _rl_want_redisplay = 0;
155 
156 /* The stuff that gets printed out before the actual text of the line.
157    This is usually pointing to rl_prompt. */
158 char *rl_display_prompt = (char *)NULL;
159 
160 /* Pseudo-global variables declared here. */
161 
162 /* The visible cursor position.  If you print some text, adjust this. */
163 /* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
164    supporting multibyte characters, and an absolute cursor position when
165    in such a locale.  This is an artifact of the donated multibyte support.
166    Care must be taken when modifying its value. */
167 int _rl_last_c_pos = 0;
168 int _rl_last_v_pos = 0;
169 
170 static int cpos_adjusted;
171 static int cpos_buffer_position;
172 static int prompt_multibyte_chars;
173 
174 /* Number of lines currently on screen minus 1. */
175 int _rl_vis_botlin = 0;
176 
177 /* Variables used only in this file. */
178 /* The last left edge of text that was displayed.  This is used when
179    doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
180 static int last_lmargin;
181 
182 /* A buffer for `modeline' messages. */
183 static char msg_buf[128];
184 
185 /* Non-zero forces the redisplay even if we thought it was unnecessary. */
186 static int forced_display;
187 
188 /* Default and initial buffer size.  Can grow. */
189 static int line_size = 1024;
190 
191 /* Variables to keep track of the expanded prompt string, which may
192    include invisible characters. */
193 
194 static char *local_prompt, *local_prompt_prefix;
195 static int local_prompt_len;
196 static int prompt_visible_length, prompt_prefix_length;
197 
198 /* The number of invisible characters in the line currently being
199    displayed on the screen. */
200 static int visible_wrap_offset;
201 
202 /* The number of invisible characters in the prompt string.  Static so it
203    can be shared between rl_redisplay and update_line */
204 static int wrap_offset;
205 
206 /* The index of the last invisible character in the prompt string. */
207 static int prompt_last_invisible;
208 
209 /* The length (buffer offset) of the first line of the last (possibly
210    multi-line) buffer displayed on the screen. */
211 static int visible_first_line_len;
212 
213 /* Number of invisible characters on the first physical line of the prompt.
214    Only valid when the number of physical characters in the prompt exceeds
215    (or is equal to) _rl_screenwidth. */
216 static int prompt_invis_chars_first_line;
217 
218 static int prompt_last_screen_line;
219 
220 static int prompt_physical_chars;
221 
222 /* set to a non-zero value by rl_redisplay if we are marking modified history
223    lines and the current line is so marked. */
224 static int modmark;
225 
226 /* Variables to save and restore prompt and display information. */
227 
228 /* These are getting numerous enough that it's time to create a struct. */
229 
230 static char *saved_local_prompt;
231 static char *saved_local_prefix;
232 static int saved_last_invisible;
233 static int saved_visible_length;
234 static int saved_prefix_length;
235 static int saved_local_length;
236 static int saved_invis_chars_first_line;
237 static int saved_physical_chars;
238 
239 /* Expand the prompt string S and return the number of visible
240    characters in *LP, if LP is not null.  This is currently more-or-less
241    a placeholder for expansion.  LIP, if non-null is a place to store the
242    index of the last invisible character in the returned string. NIFLP,
243    if non-zero, is a place to store the number of invisible characters in
244    the first prompt line.  The previous are used as byte counts -- indexes
245    into a character buffer. */
246 
247 /* Current implementation:
248 	\001 (^A) start non-visible characters
249 	\002 (^B) end non-visible characters
250    all characters except \001 and \002 (following a \001) are copied to
251    the returned string; all characters except those between \001 and
252    \002 are assumed to be `visible'. */
253 
254 static char *
255 expand_prompt (pmt, lp, lip, niflp, vlp)
256      char *pmt;
257      int *lp, *lip, *niflp, *vlp;
258 {
259   char *r, *ret, *p, *igstart;
260   int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
261 
262   /* Short-circuit if we can. */
263   if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
264     {
265       r = savestring (pmt);
266       if (lp)
267 	*lp = strlen (r);
268       if (lip)
269 	*lip = 0;
270       if (niflp)
271 	*niflp = 0;
272       if (vlp)
273 	*vlp = lp ? *lp : strlen (r);
274       return r;
275     }
276 
277   l = strlen (pmt);
278   r = ret = (char *)xmalloc (l + 1);
279 
280   invfl = 0;	/* invisible chars in first line of prompt */
281   invflset = 0;	/* we only want to set invfl once */
282 
283   igstart = 0;
284   for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
285     {
286       /* This code strips the invisible character string markers
287 	 RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
288       if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE)		/* XXX - check ignoring? */
289 	{
290 	  ignoring = 1;
291 	  igstart = p;
292 	  continue;
293 	}
294       else if (ignoring && *p == RL_PROMPT_END_IGNORE)
295 	{
296 	  ignoring = 0;
297 	  if (p != (igstart + 1))
298 	    last = r - ret - 1;
299 	  continue;
300 	}
301       else
302 	{
303 #if defined (HANDLE_MULTIBYTE)
304 	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
305 	    {
306 	      pind = p - pmt;
307 	      ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
308 	      l = ind - pind;
309 	      while (l--)
310 	        *r++ = *p++;
311 	      if (!ignoring)
312 		{
313 		  /* rl ends up being assigned to prompt_visible_length,
314 		     which is the number of characters in the buffer that
315 		     contribute to characters on the screen, which might
316 		     not be the same as the number of physical characters
317 		     on the screen in the presence of multibyte characters */
318 		  rl += ind - pind;
319 		  physchars += _rl_col_width (pmt, pind, ind, 0);
320 		}
321 	      else
322 		ninvis += ind - pind;
323 	      p--;			/* compensate for later increment */
324 	    }
325 	  else
326 #endif
327 	    {
328 	      *r++ = *p;
329 	      if (!ignoring)
330 		{
331 		  rl++;			/* visible length byte counter */
332 		  physchars++;
333 		}
334 	      else
335 		ninvis++;		/* invisible chars byte counter */
336 	    }
337 
338 	  if (invflset == 0 && rl >= _rl_screenwidth)
339 	    {
340 	      invfl = ninvis;
341 	      invflset = 1;
342 	    }
343 	}
344     }
345 
346   if (rl < _rl_screenwidth)
347     invfl = ninvis;
348 
349   *r = '\0';
350   if (lp)
351     *lp = rl;
352   if (lip)
353     *lip = last;
354   if (niflp)
355     *niflp = invfl;
356   if  (vlp)
357     *vlp = physchars;
358   return ret;
359 }
360 
361 /* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
362    PMT and return the rest of PMT. */
363 char *
364 _rl_strip_prompt (pmt)
365      char *pmt;
366 {
367   char *ret;
368 
369   ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
370   return ret;
371 }
372 
373 /*
374  * Expand the prompt string into the various display components, if
375  * necessary.
376  *
377  * local_prompt = expanded last line of string in rl_display_prompt
378  *		  (portion after the final newline)
379  * local_prompt_prefix = portion before last newline of rl_display_prompt,
380  *			 expanded via expand_prompt
381  * prompt_visible_length = number of visible characters in local_prompt
382  * prompt_prefix_length = number of visible characters in local_prompt_prefix
383  *
384  * This function is called once per call to readline().  It may also be
385  * called arbitrarily to expand the primary prompt.
386  *
387  * The return value is the number of visible characters on the last line
388  * of the (possibly multi-line) prompt.
389  */
390 int
391 rl_expand_prompt (prompt)
392      char *prompt;
393 {
394   char *p, *t;
395   int c;
396 
397   /* Clear out any saved values. */
398   FREE (local_prompt);
399   FREE (local_prompt_prefix);
400 
401   local_prompt = local_prompt_prefix = (char *)0;
402   local_prompt_len = 0;
403   prompt_last_invisible = prompt_invis_chars_first_line = 0;
404   prompt_visible_length = prompt_physical_chars = 0;
405 
406   if (prompt == 0 || *prompt == 0)
407     return (0);
408 
409   p = strrchr (prompt, '\n');
410   if (!p)
411     {
412       /* The prompt is only one logical line, though it might wrap. */
413       local_prompt = expand_prompt (prompt, &prompt_visible_length,
414 					    &prompt_last_invisible,
415 					    &prompt_invis_chars_first_line,
416 					    &prompt_physical_chars);
417       local_prompt_prefix = (char *)0;
418       local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
419       return (prompt_visible_length);
420     }
421   else
422     {
423       /* The prompt spans multiple lines. */
424       t = ++p;
425       local_prompt = expand_prompt (p, &prompt_visible_length,
426 				       &prompt_last_invisible,
427 				       &prompt_invis_chars_first_line,
428 				       &prompt_physical_chars);
429       c = *t; *t = '\0';
430       /* The portion of the prompt string up to and including the
431 	 final newline is now null-terminated. */
432       local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
433 						   (int *)NULL,
434 						   (int *)NULL,
435 						   (int *)NULL);
436       *t = c;
437       local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
438       return (prompt_prefix_length);
439     }
440 }
441 
442 /* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
443    arrays of line break markers.  MINSIZE is the minimum size of VISIBLE_LINE
444    and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
445    increased.  If the lines have already been allocated, this ensures that
446    they can hold at least MINSIZE characters. */
447 static void
448 init_line_structures (minsize)
449       int minsize;
450 {
451   register int n;
452 
453   if (invisible_line == 0)	/* initialize it */
454     {
455       if (line_size < minsize)
456 	line_size = minsize;
457       visible_line = (char *)xmalloc (line_size);
458       invisible_line = (char *)xmalloc (line_size);
459     }
460   else if (line_size < minsize)	/* ensure it can hold MINSIZE chars */
461     {
462       line_size *= 2;
463       if (line_size < minsize)
464 	line_size = minsize;
465       visible_line = (char *)xrealloc (visible_line, line_size);
466       invisible_line = (char *)xrealloc (invisible_line, line_size);
467     }
468 
469   for (n = minsize; n < line_size; n++)
470     {
471       visible_line[n] = 0;
472       invisible_line[n] = 1;
473     }
474 
475   if (vis_lbreaks == 0)
476     {
477       /* should be enough. */
478       inv_lbsize = vis_lbsize = 256;
479 
480 #if defined (HANDLE_MULTIBYTE)
481       line_state_visible->wbsize = vis_lbsize;
482       line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int));
483 
484       line_state_invisible->wbsize = inv_lbsize;
485       line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int));
486 #endif
487 
488       inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
489       vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
490       inv_lbreaks[0] = vis_lbreaks[0] = 0;
491     }
492 
493   line_structures_initialized = 1;
494 }
495 
496 /* Basic redisplay algorithm. */
497 void
498 rl_redisplay ()
499 {
500   register int in, out, c, linenum, cursor_linenum;
501   register char *line;
502   int inv_botlin, lb_botlin, lb_linenum, o_cpos;
503   int newlines, lpos, temp, n0, num, prompt_lines_estimate;
504   char *prompt_this_line;
505 #if defined (HANDLE_MULTIBYTE)
506   wchar_t wc;
507   size_t wc_bytes;
508   int wc_width;
509   mbstate_t ps;
510   int _rl_wrapped_multicolumn = 0;
511 #endif
512 
513   if (_rl_echoing_p == 0)
514     return;
515 
516   /* Block keyboard interrupts because this function manipulates global
517      data structures. */
518   _rl_block_sigint ();
519   RL_SETSTATE (RL_STATE_REDISPLAYING);
520 
521   if (!rl_display_prompt)
522     rl_display_prompt = "";
523 
524   if (line_structures_initialized == 0)
525     {
526       init_line_structures (0);
527       rl_on_new_line ();
528     }
529 
530   /* Draw the line into the buffer. */
531   cpos_buffer_position = -1;
532 
533   prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars;
534 
535   line = invisible_line;
536   out = inv_botlin = 0;
537 
538   /* Mark the line as modified or not.  We only do this for history
539      lines. */
540   modmark = 0;
541   if (_rl_mark_modified_lines && current_history () && rl_undo_list)
542     {
543       line[out++] = '*';
544       line[out] = '\0';
545       modmark = 1;
546     }
547 
548   /* If someone thought that the redisplay was handled, but the currently
549      visible line has a different modification state than the one about
550      to become visible, then correct the caller's misconception. */
551   if (visible_line[0] != invisible_line[0])
552     rl_display_fixed = 0;
553 
554   /* If the prompt to be displayed is the `primary' readline prompt (the
555      one passed to readline()), use the values we have already expanded.
556      If not, use what's already in rl_display_prompt.  WRAP_OFFSET is the
557      number of non-visible characters in the prompt string. */
558   if (rl_display_prompt == rl_prompt || local_prompt)
559     {
560       if (local_prompt_prefix && forced_display)
561 	_rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
562 
563       if (local_prompt_len > 0)
564 	{
565 	  temp = local_prompt_len + out + 2;
566 	  if (temp >= line_size)
567 	    {
568 	      line_size = (temp + 1024) - (temp % 1024);
569 	      visible_line = (char *)xrealloc (visible_line, line_size);
570 	      line = invisible_line = (char *)xrealloc (invisible_line, line_size);
571 	    }
572 	  strncpy (line + out, local_prompt, local_prompt_len);
573 	  out += local_prompt_len;
574 	}
575       line[out] = '\0';
576       wrap_offset = local_prompt_len - prompt_visible_length;
577     }
578   else
579     {
580       int pmtlen;
581       prompt_this_line = strrchr (rl_display_prompt, '\n');
582       if (!prompt_this_line)
583 	prompt_this_line = rl_display_prompt;
584       else
585 	{
586 	  prompt_this_line++;
587 	  pmtlen = prompt_this_line - rl_display_prompt;	/* temp var */
588 	  if (forced_display)
589 	    {
590 	      _rl_output_some_chars (rl_display_prompt, pmtlen);
591 	      /* Make sure we are at column zero even after a newline,
592 		 regardless of the state of terminal output processing. */
593 	      if (pmtlen < 2 || prompt_this_line[-2] != '\r')
594 		cr ();
595 	    }
596 	}
597 
598       prompt_physical_chars = pmtlen = strlen (prompt_this_line);
599       temp = pmtlen + out + 2;
600       if (temp >= line_size)
601 	{
602 	  line_size = (temp + 1024) - (temp % 1024);
603 	  visible_line = (char *)xrealloc (visible_line, line_size);
604 	  line = invisible_line = (char *)xrealloc (invisible_line, line_size);
605 	}
606       strncpy (line + out,  prompt_this_line, pmtlen);
607       out += pmtlen;
608       line[out] = '\0';
609       wrap_offset = prompt_invis_chars_first_line = 0;
610     }
611 
612 #define CHECK_INV_LBREAKS() \
613       do { \
614 	if (newlines >= (inv_lbsize - 2)) \
615 	  { \
616 	    inv_lbsize *= 2; \
617 	    inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
618 	  } \
619       } while (0)
620 
621 #if defined (HANDLE_MULTIBYTE)
622 #define CHECK_LPOS() \
623       do { \
624 	lpos++; \
625 	if (lpos >= _rl_screenwidth) \
626 	  { \
627 	    if (newlines >= (inv_lbsize - 2)) \
628 	      { \
629 		inv_lbsize *= 2; \
630 		inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
631 	      } \
632 	    inv_lbreaks[++newlines] = out; \
633 	    if (newlines >= (line_state_invisible->wbsize - 1)) \
634 	      { \
635 		line_state_invisible->wbsize *= 2; \
636 		line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \
637 	      } \
638 	    line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \
639 	    lpos = 0; \
640 	  } \
641       } while (0)
642 #else
643 #define CHECK_LPOS() \
644       do { \
645 	lpos++; \
646 	if (lpos >= _rl_screenwidth) \
647 	  { \
648 	    if (newlines >= (inv_lbsize - 2)) \
649 	      { \
650 		inv_lbsize *= 2; \
651 		inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
652 	      } \
653 	    inv_lbreaks[++newlines] = out; \
654 	    lpos = 0; \
655 	  } \
656       } while (0)
657 #endif
658 
659   /* inv_lbreaks[i] is where line i starts in the buffer. */
660   inv_lbreaks[newlines = 0] = 0;
661   lpos = prompt_physical_chars + modmark;
662 
663 #if defined (HANDLE_MULTIBYTE)
664   memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
665   num = 0;
666 #endif
667 
668   /* prompt_invis_chars_first_line is the number of invisible characters in
669      the first physical line of the prompt.
670      wrap_offset - prompt_invis_chars_first_line is the number of invis
671      chars on the second (or, more generally, last) line. */
672 
673   /* This is zero-based, used to set the newlines */
674   prompt_lines_estimate = lpos / _rl_screenwidth;
675 
676   /* what if lpos is already >= _rl_screenwidth before we start drawing the
677      contents of the command line? */
678   while (lpos >= _rl_screenwidth)
679     {
680       int z;
681       /* fix from Darin Johnson <darin@acuson.com> for prompt string with
682          invisible characters that is longer than the screen width.  The
683          prompt_invis_chars_first_line variable could be made into an array
684          saying how many invisible characters there are per line, but that's
685          probably too much work for the benefit gained.  How many people have
686          prompts that exceed two physical lines?
687          Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
688 #if defined (HANDLE_MULTIBYTE)
689       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
690 	{
691 	  n0 = num;
692           temp = local_prompt_len;
693           while (num < temp)
694 	    {
695 	      z = _rl_col_width  (local_prompt, n0, num, 1);
696 	      if (z > _rl_screenwidth)
697 		{
698 	          num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
699 	          break;
700 		}
701 	      else if (z == _rl_screenwidth)
702 	        break;
703 	      num++;
704 	    }
705           temp = num;
706 	}
707       else
708 #endif /* !HANDLE_MULTIBYTE */
709 	temp = ((newlines + 1) * _rl_screenwidth);
710 
711       /* Now account for invisible characters in the current line. */
712       /* XXX - this assumes that the invisible characters may be split, but only
713 	 between the first and the last lines. */
714       temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
715 							     : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line))
716 					  : ((newlines == 0) ? wrap_offset : 0));
717 
718       inv_lbreaks[++newlines] = temp;
719 #if defined (HANDLE_MULTIBYTE)
720       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
721 	lpos -= _rl_col_width (local_prompt, n0, num, 1);
722       else
723 #endif
724 	lpos -= _rl_screenwidth;
725     }
726 
727   prompt_last_screen_line = newlines;
728 
729   /* Draw the rest of the line (after the prompt) into invisible_line, keeping
730      track of where the cursor is (cpos_buffer_position), the number of the line containing
731      the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
732      It maintains an array of line breaks for display (inv_lbreaks).
733      This handles expanding tabs for display and displaying meta characters. */
734   lb_linenum = 0;
735 #if defined (HANDLE_MULTIBYTE)
736   in = 0;
737   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
738     {
739       memset (&ps, 0, sizeof (mbstate_t));
740       /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
741       wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
742     }
743   else
744     wc_bytes = 1;
745   while (in < rl_end)
746 #else
747   for (in = 0; in < rl_end; in++)
748 #endif
749     {
750       c = (unsigned char)rl_line_buffer[in];
751 
752 #if defined (HANDLE_MULTIBYTE)
753       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
754 	{
755 	  if (MB_INVALIDCH (wc_bytes))
756 	    {
757 	      /* Byte sequence is invalid or shortened.  Assume that the
758 	         first byte represents a character. */
759 	      wc_bytes = 1;
760 	      /* Assume that a character occupies a single column. */
761 	      wc_width = 1;
762 	      memset (&ps, 0, sizeof (mbstate_t));
763 	    }
764 	  else if (MB_NULLWCH (wc_bytes))
765 	    break;			/* Found '\0' */
766 	  else
767 	    {
768 	      temp = wcwidth (wc);
769 	      wc_width = (temp >= 0) ? temp : 1;
770 	    }
771 	}
772 #endif
773 
774       if (out + 8 >= line_size)		/* XXX - 8 for \t */
775 	{
776 	  line_size *= 2;
777 	  visible_line = (char *)xrealloc (visible_line, line_size);
778 	  invisible_line = (char *)xrealloc (invisible_line, line_size);
779 	  line = invisible_line;
780 	}
781 
782       if (in == rl_point)
783 	{
784 	  cpos_buffer_position = out;
785 	  lb_linenum = newlines;
786 	}
787 
788 #if defined (HANDLE_MULTIBYTE)
789       if (META_CHAR (c) && _rl_output_meta_chars == 0)	/* XXX - clean up */
790 #else
791       if (META_CHAR (c))
792 #endif
793 	{
794 	  if (_rl_output_meta_chars == 0)
795 	    {
796 	      sprintf (line + out, "\\%o", c);
797 
798 	      if (lpos + 4 >= _rl_screenwidth)
799 		{
800 		  temp = _rl_screenwidth - lpos;
801 		  CHECK_INV_LBREAKS ();
802 		  inv_lbreaks[++newlines] = out + temp;
803 		  lpos = 4 - temp;
804 		}
805 	      else
806 		lpos += 4;
807 
808 	      out += 4;
809 	    }
810 	  else
811 	    {
812 	      line[out++] = c;
813 	      CHECK_LPOS();
814 	    }
815 	}
816 #if defined (DISPLAY_TABS)
817       else if (c == '\t')
818 	{
819 	  register int newout;
820 
821 #if 0
822 	  newout = (out | (int)7) + 1;
823 #else
824 	  newout = out + 8 - lpos % 8;
825 #endif
826 	  temp = newout - out;
827 	  if (lpos + temp >= _rl_screenwidth)
828 	    {
829 	      register int temp2;
830 	      temp2 = _rl_screenwidth - lpos;
831 	      CHECK_INV_LBREAKS ();
832 	      inv_lbreaks[++newlines] = out + temp2;
833 	      lpos = temp - temp2;
834 	      while (out < newout)
835 		line[out++] = ' ';
836 	    }
837 	  else
838 	    {
839 	      while (out < newout)
840 		line[out++] = ' ';
841 	      lpos += temp;
842 	    }
843 	}
844 #endif
845       else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
846 	{
847 	  line[out++] = '\0';	/* XXX - sentinel */
848 	  CHECK_INV_LBREAKS ();
849 	  inv_lbreaks[++newlines] = out;
850 	  lpos = 0;
851 	}
852       else if (CTRL_CHAR (c) || c == RUBOUT)
853 	{
854 	  line[out++] = '^';
855 	  CHECK_LPOS();
856 	  line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
857 	  CHECK_LPOS();
858 	}
859       else
860 	{
861 #if defined (HANDLE_MULTIBYTE)
862 	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
863 	    {
864 	      register int i;
865 
866 	      _rl_wrapped_multicolumn = 0;
867 
868 	      if (_rl_screenwidth < lpos + wc_width)
869 		for (i = lpos; i < _rl_screenwidth; i++)
870 		  {
871 		    /* The space will be removed in update_line() */
872 		    line[out++] = ' ';
873 		    _rl_wrapped_multicolumn++;
874 		    CHECK_LPOS();
875 		  }
876 	      if (in == rl_point)
877 		{
878 		  cpos_buffer_position = out;
879 		  lb_linenum = newlines;
880 		}
881 	      for (i = in; i < in+wc_bytes; i++)
882 		line[out++] = rl_line_buffer[i];
883 	      for (i = 0; i < wc_width; i++)
884 		CHECK_LPOS();
885 	    }
886 	  else
887 	    {
888 	      line[out++] = c;
889 	      CHECK_LPOS();
890 	    }
891 #else
892 	  line[out++] = c;
893 	  CHECK_LPOS();
894 #endif
895 	}
896 
897 #if defined (HANDLE_MULTIBYTE)
898       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
899 	{
900 	  in += wc_bytes;
901 	  /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
902 	  wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
903 	}
904       else
905         in++;
906 #endif
907 
908     }
909   line[out] = '\0';
910   if (cpos_buffer_position < 0)
911     {
912       cpos_buffer_position = out;
913       lb_linenum = newlines;
914     }
915 
916   inv_botlin = lb_botlin = newlines;
917   CHECK_INV_LBREAKS ();
918   inv_lbreaks[newlines+1] = out;
919   cursor_linenum = lb_linenum;
920 
921   /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
922      CURSOR_LINENUM == line number where the cursor should be placed. */
923 
924   /* PWP: now is when things get a bit hairy.  The visible and invisible
925      line buffers are really multiple lines, which would wrap every
926      (screenwidth - 1) characters.  Go through each in turn, finding
927      the changed region and updating it.  The line order is top to bottom. */
928 
929   /* If we can move the cursor up and down, then use multiple lines,
930      otherwise, let long lines display in a single terminal line, and
931      horizontally scroll it. */
932 
933   if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
934     {
935       int nleft, pos, changed_screen_line, tx;
936 
937       if (!rl_display_fixed || forced_display)
938 	{
939 	  forced_display = 0;
940 
941 	  /* If we have more than a screenful of material to display, then
942 	     only display a screenful.  We should display the last screen,
943 	     not the first.  */
944 	  if (out >= _rl_screenchars)
945 	    {
946 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
947 		out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
948 	      else
949 		out = _rl_screenchars - 1;
950 	    }
951 
952 	  /* The first line is at character position 0 in the buffer.  The
953 	     second and subsequent lines start at inv_lbreaks[N], offset by
954 	     OFFSET (which has already been calculated above).  */
955 
956 #define INVIS_FIRST()	(prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
957 #define WRAP_OFFSET(line, offset)  ((line == 0) \
958 					? (offset ? INVIS_FIRST() : 0) \
959 					: ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
960 #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
961 #define VIS_LLEN(l)	((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
962 #define INV_LLEN(l)	(inv_lbreaks[l+1] - inv_lbreaks[l])
963 #define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
964 #define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
965 #define INV_LINE(line) (invisible_line + inv_lbreaks[line])
966 
967 #define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
968 			_rl_last_c_pos != o_cpos && \
969 			_rl_last_c_pos > wrap_offset && \
970 			o_cpos < prompt_last_invisible)
971 
972 	  /* For each line in the buffer, do the updating display. */
973 	  for (linenum = 0; linenum <= inv_botlin; linenum++)
974 	    {
975 	      /* This can lead us astray if we execute a program that changes
976 		 the locale from a non-multibyte to a multibyte one. */
977 	      o_cpos = _rl_last_c_pos;
978 	      cpos_adjusted = 0;
979 	      update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
980 			   VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
981 
982 	      /* update_line potentially changes _rl_last_c_pos, but doesn't
983 		 take invisible characters into account, since _rl_last_c_pos
984 		 is an absolute cursor position in a multibyte locale.  See
985 		 if compensating here is the right thing, or if we have to
986 		 change update_line itself.  There are several cases in which
987 		 update_line adjusts _rl_last_c_pos itself (so it can pass
988 		 _rl_move_cursor_relative accurate values); it communicates
989 		 this back by setting cpos_adjusted.  If we assume that
990 		 _rl_last_c_pos is correct (an absolute cursor position) each
991 		 time update_line is called, then we can assume in our
992 		 calculations that o_cpos does not need to be adjusted by
993 		 wrap_offset. */
994 	      if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
995 		_rl_last_c_pos -= prompt_invis_chars_first_line;	/* XXX - was wrap_offset */
996 	      else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
997 			(MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
998 			cpos_adjusted == 0 &&
999 			_rl_last_c_pos != o_cpos &&
1000 			_rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
1001 		_rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
1002 
1003 	      /* If this is the line with the prompt, we might need to
1004 		 compensate for invisible characters in the new line. Do
1005 		 this only if there is not more than one new line (which
1006 		 implies that we completely overwrite the old visible line)
1007 		 and the new line is shorter than the old.  Make sure we are
1008 		 at the end of the new line before clearing. */
1009 	      if (linenum == 0 &&
1010 		  inv_botlin == 0 && _rl_last_c_pos == out &&
1011 		  (wrap_offset > visible_wrap_offset) &&
1012 		  (_rl_last_c_pos < visible_first_line_len))
1013 		{
1014 		  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1015 		    nleft = _rl_screenwidth - _rl_last_c_pos;
1016 		  else
1017 		    nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
1018 		  if (nleft)
1019 		    _rl_clear_to_eol (nleft);
1020 		}
1021 #if 0
1022 	      /* This segment is intended to handle the case where the prompt
1023 		 has invisible characters on the second line and the new line
1024 		 to be displayed needs to clear the rest of the old characters
1025 		 out (e.g., when printing the i-search prompt).  In general,
1026 		 the case of the new line being shorter than the old.
1027 		 Incomplete */
1028 	      else if (linenum == prompt_last_screen_line &&
1029 		       prompt_physical_chars > _rl_screenwidth &&
1030 		       wrap_offset != prompt_invis_chars_first_line &&
1031 		       _rl_last_c_pos == out &&
1032 #endif
1033 
1034 
1035 	      /* Since the new first line is now visible, save its length. */
1036 	      if (linenum == 0)
1037 		visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
1038 	    }
1039 
1040 	  /* We may have deleted some lines.  If so, clear the left over
1041 	     blank ones at the bottom out. */
1042 	  if (_rl_vis_botlin > inv_botlin)
1043 	    {
1044 	      char *tt;
1045 	      for (; linenum <= _rl_vis_botlin; linenum++)
1046 		{
1047 		  tt = VIS_CHARS (linenum);
1048 		  _rl_move_vert (linenum);
1049 		  _rl_move_cursor_relative (0, tt);
1050 		  _rl_clear_to_eol
1051 		    ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
1052 		}
1053 	    }
1054 	  _rl_vis_botlin = inv_botlin;
1055 
1056 	  /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
1057 	     different screen line during this redisplay. */
1058 	  changed_screen_line = _rl_last_v_pos != cursor_linenum;
1059 	  if (changed_screen_line)
1060 	    {
1061 	      _rl_move_vert (cursor_linenum);
1062 	      /* If we moved up to the line with the prompt using _rl_term_up,
1063 		 the physical cursor position on the screen stays the same,
1064 		 but the buffer position needs to be adjusted to account
1065 		 for invisible characters. */
1066 	      if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
1067 		_rl_last_c_pos += wrap_offset;
1068 	    }
1069 
1070 	  /* We have to reprint the prompt if it contains invisible
1071 	     characters, since it's not generally OK to just reprint
1072 	     the characters from the current cursor position.  But we
1073 	     only need to reprint it if the cursor is before the last
1074 	     invisible character in the prompt string. */
1075 	  nleft = prompt_visible_length + wrap_offset;
1076 	  if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
1077 #if 0
1078 	      _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
1079 #else
1080 	      _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
1081 #endif
1082 	    {
1083 #if defined (__MSDOS__)
1084 	      putc ('\r', rl_outstream);
1085 #else
1086 	      if (_rl_term_cr)
1087 		tputs (_rl_term_cr, 1, _rl_output_character_function);
1088 #endif
1089 	      if (modmark)
1090 		_rl_output_some_chars ("*", 1);
1091 
1092 	      _rl_output_some_chars (local_prompt, nleft);
1093 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1094 		_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
1095 	      else
1096 		_rl_last_c_pos = nleft + modmark;
1097 	    }
1098 
1099 	  /* Where on that line?  And where does that line start
1100 	     in the buffer? */
1101 	  pos = inv_lbreaks[cursor_linenum];
1102 	  /* nleft == number of characters in the line buffer between the
1103 	     start of the line and the desired cursor position. */
1104 	  nleft = cpos_buffer_position - pos;
1105 
1106 	  /* NLEFT is now a number of characters in a buffer.  When in a
1107 	     multibyte locale, however, _rl_last_c_pos is an absolute cursor
1108 	     position that doesn't take invisible characters in the prompt
1109 	     into account.  We use a fudge factor to compensate. */
1110 
1111 	  /* Since _rl_backspace() doesn't know about invisible characters in the
1112 	     prompt, and there's no good way to tell it, we compensate for
1113 	     those characters here and call _rl_backspace() directly. */
1114 	  if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
1115 	    {
1116 	      /* TX == new physical cursor position in multibyte locale. */
1117 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1118 		tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset;
1119 	      else
1120 		tx = nleft;
1121 	      if (tx >= 0 && _rl_last_c_pos > tx)
1122 		{
1123 	          _rl_backspace (_rl_last_c_pos - tx);	/* XXX */
1124 	          _rl_last_c_pos = tx;
1125 		}
1126 	    }
1127 
1128 	  /* We need to note that in a multibyte locale we are dealing with
1129 	     _rl_last_c_pos as an absolute cursor position, but moving to a
1130 	     point specified by a buffer position (NLEFT) that doesn't take
1131 	     invisible characters into account. */
1132 	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1133 	    _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1134 	  else if (nleft != _rl_last_c_pos)
1135 	    _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1136 	}
1137     }
1138   else				/* Do horizontal scrolling. */
1139     {
1140 #define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
1141       int lmargin, ndisp, nleft, phys_c_pos, t;
1142 
1143       /* Always at top line. */
1144       _rl_last_v_pos = 0;
1145 
1146       /* Compute where in the buffer the displayed line should start.  This
1147 	 will be LMARGIN. */
1148 
1149       /* The number of characters that will be displayed before the cursor. */
1150       ndisp = cpos_buffer_position - wrap_offset;
1151       nleft  = prompt_visible_length + wrap_offset;
1152       /* Where the new cursor position will be on the screen.  This can be
1153 	 longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
1154       phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
1155       t = _rl_screenwidth / 3;
1156 
1157       /* If the number of characters had already exceeded the screenwidth,
1158 	 last_lmargin will be > 0. */
1159 
1160       /* If the number of characters to be displayed is more than the screen
1161 	 width, compute the starting offset so that the cursor is about
1162 	 two-thirds of the way across the screen. */
1163       if (phys_c_pos > _rl_screenwidth - 2)
1164 	{
1165 	  lmargin = cpos_buffer_position - (2 * t);
1166 	  if (lmargin < 0)
1167 	    lmargin = 0;
1168 	  /* If the left margin would be in the middle of a prompt with
1169 	     invisible characters, don't display the prompt at all. */
1170 	  if (wrap_offset && lmargin > 0 && lmargin < nleft)
1171 	    lmargin = nleft;
1172 	}
1173       else if (ndisp < _rl_screenwidth - 2)		/* XXX - was -1 */
1174 	lmargin = 0;
1175       else if (phys_c_pos < 1)
1176 	{
1177 	  /* If we are moving back towards the beginning of the line and
1178 	     the last margin is no longer correct, compute a new one. */
1179 	  lmargin = ((cpos_buffer_position - 1) / t) * t;	/* XXX */
1180 	  if (wrap_offset && lmargin > 0 && lmargin < nleft)
1181 	    lmargin = nleft;
1182 	}
1183       else
1184 	lmargin = last_lmargin;
1185 
1186       /* If the first character on the screen isn't the first character
1187 	 in the display line, indicate this with a special character. */
1188       if (lmargin > 0)
1189 	line[lmargin] = '<';
1190 
1191       /* If SCREENWIDTH characters starting at LMARGIN do not encompass
1192 	 the whole line, indicate that with a special character at the
1193 	 right edge of the screen.  If LMARGIN is 0, we need to take the
1194 	 wrap offset into account. */
1195       t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
1196       if (t < out)
1197 	line[t - 1] = '>';
1198 
1199       if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
1200 	{
1201 	  forced_display = 0;
1202 	  o_cpos = _rl_last_c_pos;
1203 	  cpos_adjusted = 0;
1204 	  update_line (&visible_line[last_lmargin],
1205 		       &invisible_line[lmargin],
1206 		       0,
1207 		       _rl_screenwidth + visible_wrap_offset,
1208 		       _rl_screenwidth + (lmargin ? 0 : wrap_offset),
1209 		       0);
1210 
1211 	  if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
1212 	    _rl_last_c_pos -= prompt_invis_chars_first_line;	/* XXX - was wrap_offset */
1213 
1214 	  /* If the visible new line is shorter than the old, but the number
1215 	     of invisible characters is greater, and we are at the end of
1216 	     the new line, we need to clear to eol. */
1217 	  t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
1218 	  if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
1219 	      (_rl_last_c_pos == out) &&
1220 	      t < visible_first_line_len)
1221 	    {
1222 	      nleft = _rl_screenwidth - t;
1223 	      _rl_clear_to_eol (nleft);
1224 	    }
1225 	  visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
1226 	  if (visible_first_line_len > _rl_screenwidth)
1227 	    visible_first_line_len = _rl_screenwidth;
1228 
1229 	  _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
1230 	  last_lmargin = lmargin;
1231 	}
1232     }
1233   fflush (rl_outstream);
1234 
1235   /* Swap visible and non-visible lines. */
1236   {
1237     struct line_state *vtemp = line_state_visible;
1238 
1239     line_state_visible = line_state_invisible;
1240     line_state_invisible = vtemp;
1241 
1242     rl_display_fixed = 0;
1243     /* If we are displaying on a single line, and last_lmargin is > 0, we
1244        are not displaying any invisible characters, so set visible_wrap_offset
1245        to 0. */
1246     if (_rl_horizontal_scroll_mode && last_lmargin)
1247       visible_wrap_offset = 0;
1248     else
1249       visible_wrap_offset = wrap_offset;
1250   }
1251 
1252   RL_UNSETSTATE (RL_STATE_REDISPLAYING);
1253   _rl_release_sigint ();
1254 }
1255 
1256 /* PWP: update_line() is based on finding the middle difference of each
1257    line on the screen; vis:
1258 
1259 			     /old first difference
1260 	/beginning of line   |	      /old last same       /old EOL
1261 	v		     v	      v		    v
1262 old:	eddie> Oh, my little gruntle-buggy is to me, as lurgid as
1263 new:	eddie> Oh, my little buggy says to me, as lurgid as
1264 	^		     ^	^			   ^
1265 	\beginning of line   |	\new last same	   \new end of line
1266 			     \new first difference
1267 
1268    All are character pointers for the sake of speed.  Special cases for
1269    no differences, as well as for end of line additions must be handled.
1270 
1271    Could be made even smarter, but this works well enough */
1272 static void
1273 update_line (old, new, current_line, omax, nmax, inv_botlin)
1274      register char *old, *new;
1275      int current_line, omax, nmax, inv_botlin;
1276 {
1277   register char *ofd, *ols, *oe, *nfd, *nls, *ne;
1278   int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
1279   int current_invis_chars;
1280   int col_lendiff, col_temp;
1281 #if defined (HANDLE_MULTIBYTE)
1282   mbstate_t ps_new, ps_old;
1283   int new_offset, old_offset;
1284 #endif
1285 
1286   /* If we're at the right edge of a terminal that supports xn, we're
1287      ready to wrap around, so do so.  This fixes problems with knowing
1288      the exact cursor position and cut-and-paste with certain terminal
1289      emulators.  In this calculation, TEMP is the physical screen
1290      position of the cursor. */
1291   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1292     temp = _rl_last_c_pos;
1293   else
1294     temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
1295   if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
1296 	&& _rl_last_v_pos == current_line - 1)
1297     {
1298 #if defined (HANDLE_MULTIBYTE)
1299       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1300 	{
1301 	  wchar_t wc;
1302 	  mbstate_t ps;
1303 	  int tempwidth, bytes;
1304 	  size_t ret;
1305 
1306 	  /* This fixes only double-column characters, but if the wrapped
1307 	     character comsumes more than three columns, spaces will be
1308 	     inserted in the string buffer. */
1309 	  if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0)
1310 	    _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]);
1311 
1312 	  memset (&ps, 0, sizeof (mbstate_t));
1313 	  ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
1314 	  if (MB_INVALIDCH (ret))
1315 	    {
1316 	      tempwidth = 1;
1317 	      ret = 1;
1318 	    }
1319 	  else if (MB_NULLWCH (ret))
1320 	    tempwidth = 0;
1321 	  else
1322 	    tempwidth = wcwidth (wc);
1323 
1324 	  if (tempwidth > 0)
1325 	    {
1326 	      int count, i;
1327 	      bytes = ret;
1328 	      for (count = 0; count < bytes; count++)
1329 		putc (new[count], rl_outstream);
1330 	      _rl_last_c_pos = tempwidth;
1331 	      _rl_last_v_pos++;
1332 	      memset (&ps, 0, sizeof (mbstate_t));
1333 	      ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
1334 	      if (ret != 0 && bytes != 0)
1335 		{
1336 		  if (MB_INVALIDCH (ret))
1337 		    ret = 1;
1338 		  memmove (old+bytes, old+ret, strlen (old+ret));
1339 		  memcpy (old, new, bytes);
1340 		  /* Fix up indices if we copy data from one line to another */
1341 		  omax += bytes - ret;
1342 		  for (i = current_line+1; i < inv_botlin+1; i++)
1343 		    vis_lbreaks[i] += bytes - ret;
1344 		}
1345 	    }
1346 	  else
1347 	    {
1348 	      putc (' ', rl_outstream);
1349 	      _rl_last_c_pos = 1;
1350 	      _rl_last_v_pos++;
1351 	      if (old[0] && new[0])
1352 		old[0] = new[0];
1353 	    }
1354 	}
1355       else
1356 #endif
1357 	{
1358 	  if (new[0])
1359 	    putc (new[0], rl_outstream);
1360 	  else
1361 	    putc (' ', rl_outstream);
1362 	  _rl_last_c_pos = 1;
1363 	  _rl_last_v_pos++;
1364 	  if (old[0] && new[0])
1365 	    old[0] = new[0];
1366 	}
1367     }
1368 
1369 
1370   /* Find first difference. */
1371 #if defined (HANDLE_MULTIBYTE)
1372   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1373     {
1374       /* See if the old line is a subset of the new line, so that the
1375 	 only change is adding characters. */
1376       temp = (omax < nmax) ? omax : nmax;
1377       if (memcmp (old, new, temp) == 0)		/* adding at the end */
1378 	{
1379 	  ofd = old + temp;
1380 	  nfd = new + temp;
1381 	}
1382       else
1383 	{
1384 	  memset (&ps_new, 0, sizeof(mbstate_t));
1385 	  memset (&ps_old, 0, sizeof(mbstate_t));
1386 
1387 	  if (omax == nmax && STREQN (new, old, omax))
1388 	    {
1389 	      ofd = old + omax;
1390 	      nfd = new + nmax;
1391 	    }
1392 	  else
1393 	    {
1394 	      new_offset = old_offset = 0;
1395 	      for (ofd = old, nfd = new;
1396 		    (ofd - old < omax) && *ofd &&
1397 		    _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
1398 		{
1399 		  old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
1400 		  new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
1401 		  ofd = old + old_offset;
1402 		  nfd = new + new_offset;
1403 		}
1404 	    }
1405 	}
1406     }
1407   else
1408 #endif
1409   for (ofd = old, nfd = new;
1410        (ofd - old < omax) && *ofd && (*ofd == *nfd);
1411        ofd++, nfd++)
1412     ;
1413 
1414   /* Move to the end of the screen line.  ND and OD are used to keep track
1415      of the distance between ne and new and oe and old, respectively, to
1416      move a subtraction out of each loop. */
1417   for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
1418   for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
1419 
1420   /* If no difference, continue to next line. */
1421   if (ofd == oe && nfd == ne)
1422     return;
1423 
1424   wsatend = 1;			/* flag for trailing whitespace */
1425 
1426 #if defined (HANDLE_MULTIBYTE)
1427   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1428     {
1429       ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
1430       nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
1431       while ((ols > ofd) && (nls > nfd))
1432 	{
1433 	  memset (&ps_old, 0, sizeof (mbstate_t));
1434 	  memset (&ps_new, 0, sizeof (mbstate_t));
1435 
1436 #if 0
1437 	  /* On advice from jir@yamato.ibm.com */
1438 	  _rl_adjust_point (old, ols - old, &ps_old);
1439 	  _rl_adjust_point (new, nls - new, &ps_new);
1440 #endif
1441 
1442 	  if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
1443 	    break;
1444 
1445 	  if (*ols == ' ')
1446 	    wsatend = 0;
1447 
1448 	  ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
1449 	  nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
1450 	}
1451     }
1452   else
1453     {
1454 #endif /* HANDLE_MULTIBYTE */
1455   ols = oe - 1;			/* find last same */
1456   nls = ne - 1;
1457   while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
1458     {
1459       if (*ols != ' ')
1460 	wsatend = 0;
1461       ols--;
1462       nls--;
1463     }
1464 #if defined (HANDLE_MULTIBYTE)
1465     }
1466 #endif
1467 
1468   if (wsatend)
1469     {
1470       ols = oe;
1471       nls = ne;
1472     }
1473 #if defined (HANDLE_MULTIBYTE)
1474   /* This may not work for stateful encoding, but who cares?  To handle
1475      stateful encoding properly, we have to scan each string from the
1476      beginning and compare. */
1477   else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
1478 #else
1479   else if (*ols != *nls)
1480 #endif
1481     {
1482       if (*ols)			/* don't step past the NUL */
1483 	{
1484 	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1485 	    ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
1486 	  else
1487 	    ols++;
1488 	}
1489       if (*nls)
1490 	{
1491 	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1492 	    nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
1493 	  else
1494 	    nls++;
1495 	}
1496     }
1497 
1498   /* count of invisible characters in the current invisible line. */
1499   current_invis_chars = W_OFFSET (current_line, wrap_offset);
1500   if (_rl_last_v_pos != current_line)
1501     {
1502       _rl_move_vert (current_line);
1503       if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
1504 	_rl_last_c_pos += visible_wrap_offset;
1505     }
1506 
1507   /* If this is the first line and there are invisible characters in the
1508      prompt string, and the prompt string has not changed, and the current
1509      cursor position is before the last invisible character in the prompt,
1510      and the index of the character to move to is past the end of the prompt
1511      string, then redraw the entire prompt string.  We can only do this
1512      reliably if the terminal supports a `cr' capability.
1513 
1514      This is not an efficiency hack -- there is a problem with redrawing
1515      portions of the prompt string if they contain terminal escape
1516      sequences (like drawing the `unbold' sequence without a corresponding
1517      `bold') that manifests itself on certain terminals. */
1518 
1519   lendiff = local_prompt_len;
1520   od = ofd - old;	/* index of first difference in visible line */
1521   if (current_line == 0 && !_rl_horizontal_scroll_mode &&
1522       _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
1523       od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
1524     {
1525 #if defined (__MSDOS__)
1526       putc ('\r', rl_outstream);
1527 #else
1528       tputs (_rl_term_cr, 1, _rl_output_character_function);
1529 #endif
1530       if (modmark)
1531 	_rl_output_some_chars ("*", 1);
1532       _rl_output_some_chars (local_prompt, lendiff);
1533       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1534 	{
1535 	  /* We take wrap_offset into account here so we can pass correct
1536 	     information to _rl_move_cursor_relative. */
1537 	  _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark;
1538 	  cpos_adjusted = 1;
1539 	}
1540       else
1541 	_rl_last_c_pos = lendiff + modmark;
1542     }
1543 
1544   o_cpos = _rl_last_c_pos;
1545 
1546   /* When this function returns, _rl_last_c_pos is correct, and an absolute
1547      cursor postion in multibyte mode, but a buffer index when not in a
1548      multibyte locale. */
1549   _rl_move_cursor_relative (od, old);
1550 #if 1
1551 #if defined (HANDLE_MULTIBYTE)
1552   /* We need to indicate that the cursor position is correct in the presence of
1553      invisible characters in the prompt string.  Let's see if setting this when
1554      we make sure we're at the end of the drawn prompt string works. */
1555   if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
1556       (_rl_last_c_pos > 0 || o_cpos > 0) &&
1557       _rl_last_c_pos == prompt_physical_chars)
1558     cpos_adjusted = 1;
1559 #endif
1560 #endif
1561 
1562   /* if (len (new) > len (old))
1563      lendiff == difference in buffer
1564      col_lendiff == difference on screen
1565      When not using multibyte characters, these are equal */
1566   lendiff = (nls - nfd) - (ols - ofd);
1567   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1568     col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1);
1569   else
1570     col_lendiff = lendiff;
1571 
1572   /* If we are changing the number of invisible characters in a line, and
1573      the spot of first difference is before the end of the invisible chars,
1574      lendiff needs to be adjusted. */
1575   if (current_line == 0 && !_rl_horizontal_scroll_mode &&
1576       current_invis_chars != visible_wrap_offset)
1577     {
1578       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1579 	{
1580 	  lendiff += visible_wrap_offset - current_invis_chars;
1581 	  col_lendiff += visible_wrap_offset - current_invis_chars;
1582 	}
1583       else
1584 	{
1585 	  lendiff += visible_wrap_offset - current_invis_chars;
1586 	  col_lendiff = lendiff;
1587 	}
1588     }
1589 
1590   /* Insert (diff (len (old), len (new)) ch. */
1591   temp = ne - nfd;
1592   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1593     col_temp = _rl_col_width (new, nfd - new, ne - new, 1);
1594   else
1595     col_temp = temp;
1596 
1597   if (col_lendiff > 0)	/* XXX - was lendiff */
1598     {
1599       /* Non-zero if we're increasing the number of lines. */
1600       int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
1601       /* If col_lendiff is > 0, implying that the new string takes up more
1602 	 screen real estate than the old, but lendiff is < 0, meaning that it
1603 	 takes fewer bytes, we need to just output the characters starting
1604 	 from the first difference.  These will overwrite what is on the
1605 	 display, so there's no reason to do a smart update.  This can really
1606 	 only happen in a multibyte environment. */
1607       if (lendiff < 0)
1608 	{
1609 	  _rl_output_some_chars (nfd, temp);
1610 	  _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1);
1611 	  /* If nfd begins before any invisible characters in the prompt,
1612 	     adjust _rl_last_c_pos to account for wrap_offset and set
1613 	     cpos_adjusted to let the caller know. */
1614 	  if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
1615 	    {
1616 	      _rl_last_c_pos -= wrap_offset;
1617 	      cpos_adjusted = 1;
1618 	    }
1619 	  return;
1620 	}
1621       /* Sometimes it is cheaper to print the characters rather than
1622 	 use the terminal's capabilities.  If we're growing the number
1623 	 of lines, make sure we actually cause the new line to wrap
1624 	 around on auto-wrapping terminals. */
1625       else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
1626 	{
1627 	  /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
1628 	     _rl_horizontal_scroll_mode == 1, inserting the characters with
1629 	     _rl_term_IC or _rl_term_ic will screw up the screen because of the
1630 	     invisible characters.  We need to just draw them. */
1631 	  /* The same thing happens if we're trying to draw before the last
1632 	     invisible character in the prompt string or we're increasing the
1633 	     number of invisible characters in the line and we're not drawing
1634 	     the entire prompt string. */
1635 	  if (*ols && ((_rl_horizontal_scroll_mode &&
1636 			_rl_last_c_pos == 0 &&
1637 			lendiff > prompt_visible_length &&
1638 			current_invis_chars > 0) == 0) &&
1639 		      (((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1640 		        current_line == 0 && wrap_offset &&
1641 		        ((nfd - new) <= prompt_last_invisible) &&
1642 		        (col_lendiff < prompt_visible_length)) == 0) &&
1643 		      (visible_wrap_offset >= current_invis_chars))
1644 	    {
1645 	      insert_some_chars (nfd, lendiff, col_lendiff);
1646 	      _rl_last_c_pos += col_lendiff;
1647 	    }
1648 #if 0		/* XXX - for now */
1649 	  else if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && _rl_last_c_pos == 0 && wrap_offset && (nfd-new) <= prompt_last_invisible && col_lendiff < prompt_visible_length && visible_wrap_offset >= current_invis_chars)
1650 	    {
1651 	      _rl_output_some_chars (nfd, lendiff);
1652 	      _rl_last_c_pos += col_lendiff;
1653 	    }
1654 #endif
1655 	  else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
1656 	    {
1657 	      /* At the end of a line the characters do not have to
1658 		 be "inserted".  They can just be placed on the screen. */
1659 	      /* However, this screws up the rest of this block, which
1660 		 assumes you've done the insert because you can. */
1661 	      _rl_output_some_chars (nfd, lendiff);
1662 	      _rl_last_c_pos += col_lendiff;
1663 	    }
1664 	  else
1665 	    {
1666 	      _rl_output_some_chars (nfd, temp);
1667 	      _rl_last_c_pos += col_temp;
1668 	      /* If nfd begins before the last invisible character in the
1669 		 prompt, adjust _rl_last_c_pos to account for wrap_offset
1670 		 and set cpos_adjusted to let the caller know. */
1671 	      if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
1672 		{
1673 		  _rl_last_c_pos -= wrap_offset;
1674 		  cpos_adjusted = 1;
1675 		}
1676 	      return;
1677 	    }
1678 	  /* Copy (new) chars to screen from first diff to last match. */
1679 	  temp = nls - nfd;
1680 	  if ((temp - lendiff) > 0)
1681 	    {
1682 	      _rl_output_some_chars (nfd + lendiff, temp - lendiff);
1683 	     /* XXX -- this bears closer inspection.  Fixes a redisplay bug
1684 		reported against bash-3.0-alpha by Andreas Schwab involving
1685 		multibyte characters and prompt strings with invisible
1686 		characters, but was previously disabled. */
1687 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1688 		twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff, 1);
1689 	      else
1690 		twidth = temp - lendiff;
1691 	      _rl_last_c_pos += twidth;
1692 	      /* If nfd begins before the last invisible character in the
1693 		 prompt, adjust _rl_last_c_pos to account for wrap_offset
1694 		 and set cpos_adjusted to let the caller know. */
1695 	      if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
1696 		{
1697 		  _rl_last_c_pos -= wrap_offset;
1698 		  cpos_adjusted = 1;
1699 		}
1700 	    }
1701 	}
1702       else
1703 	{
1704 	  /* cannot insert chars, write to EOL */
1705 	  _rl_output_some_chars (nfd, temp);
1706 	  _rl_last_c_pos += col_temp;
1707 	  /* If we're in a multibyte locale and were before the last invisible
1708 	     char in the current line (which implies we just output some invisible
1709 	     characters) we need to adjust _rl_last_c_pos, since it represents
1710 	     a physical character position. */
1711 	  if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1712 		current_line == prompt_last_screen_line && wrap_offset &&
1713 		wrap_offset != prompt_invis_chars_first_line &&
1714 		((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
1715 	    {
1716 	      _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
1717 	      cpos_adjusted = 1;
1718 	    }
1719 	}
1720     }
1721   else				/* Delete characters from line. */
1722     {
1723       /* If possible and inexpensive to use terminal deletion, then do so. */
1724       if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
1725 	{
1726 	  /* If all we're doing is erasing the invisible characters in the
1727 	     prompt string, don't bother.  It screws up the assumptions
1728 	     about what's on the screen. */
1729 	  if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
1730 	      -lendiff == visible_wrap_offset)
1731 	    col_lendiff = 0;
1732 
1733 	  if (col_lendiff)
1734 	    delete_chars (-col_lendiff); /* delete (diff) characters */
1735 
1736 	  /* Copy (new) chars to screen from first diff to last match */
1737 	  temp = nls - nfd;
1738 	  if (temp > 0)
1739 	    {
1740 	      /* If nfd begins at the prompt, or before the invisible
1741 		 characters in the prompt, we need to adjust _rl_last_c_pos
1742 		 in a multibyte locale to account for the wrap offset and
1743 		 set cpos_adjusted accordingly. */
1744 	      _rl_output_some_chars (nfd, temp);
1745 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1746 		{
1747 		  _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1);
1748 		  if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
1749 		    {
1750 		      _rl_last_c_pos -= wrap_offset;
1751 		      cpos_adjusted = 1;
1752 		    }
1753 		}
1754 	      else
1755 		_rl_last_c_pos += temp;
1756 	    }
1757 	}
1758       /* Otherwise, print over the existing material. */
1759       else
1760 	{
1761 	  if (temp > 0)
1762 	    {
1763 	      /* If nfd begins at the prompt, or before the invisible
1764 		 characters in the prompt, we need to adjust _rl_last_c_pos
1765 		 in a multibyte locale to account for the wrap offset and
1766 		 set cpos_adjusted accordingly. */
1767 	      _rl_output_some_chars (nfd, temp);
1768 	      _rl_last_c_pos += col_temp;		/* XXX */
1769 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1770 		{
1771 		  if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible))
1772 		    {
1773 		      _rl_last_c_pos -= wrap_offset;
1774 		      cpos_adjusted = 1;
1775 		    }
1776 		}
1777 	    }
1778 	  lendiff = (oe - old) - (ne - new);
1779 	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1780 	    col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1);
1781 	  else
1782 	    col_lendiff = lendiff;
1783 
1784 #if 0
1785 	  if (col_lendiff)
1786 #else
1787 	  /* If we've already printed over the entire width of the screen,
1788 	     including the old material, then col_lendiff doesn't matter and
1789 	     space_to_eol will insert too many spaces.  XXX - maybe we should
1790 	     adjust col_lendiff based on the difference between _rl_last_c_pos
1791 	     and _rl_screenwidth */
1792 	  if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
1793 #endif
1794 	    {
1795 	      if (_rl_term_autowrap && current_line < inv_botlin)
1796 		space_to_eol (col_lendiff);
1797 	      else
1798 		_rl_clear_to_eol (col_lendiff);
1799 	    }
1800 	}
1801     }
1802 }
1803 
1804 /* Tell the update routines that we have moved onto a new (empty) line. */
1805 int
1806 rl_on_new_line ()
1807 {
1808   if (visible_line)
1809     visible_line[0] = '\0';
1810 
1811   _rl_last_c_pos = _rl_last_v_pos = 0;
1812   _rl_vis_botlin = last_lmargin = 0;
1813   if (vis_lbreaks)
1814     vis_lbreaks[0] = vis_lbreaks[1] = 0;
1815   visible_wrap_offset = 0;
1816   return 0;
1817 }
1818 
1819 /* Tell the update routines that we have moved onto a new line with the
1820    prompt already displayed.  Code originally from the version of readline
1821    distributed with CLISP.  rl_expand_prompt must have already been called
1822    (explicitly or implicitly).  This still doesn't work exactly right. */
1823 int
1824 rl_on_new_line_with_prompt ()
1825 {
1826   int prompt_size, i, l, real_screenwidth, newlines;
1827   char *prompt_last_line, *lprompt;
1828 
1829   /* Initialize visible_line and invisible_line to ensure that they can hold
1830      the already-displayed prompt. */
1831   prompt_size = strlen (rl_prompt) + 1;
1832   init_line_structures (prompt_size);
1833 
1834   /* Make sure the line structures hold the already-displayed prompt for
1835      redisplay. */
1836   lprompt = local_prompt ? local_prompt : rl_prompt;
1837   strcpy (visible_line, lprompt);
1838   strcpy (invisible_line, lprompt);
1839 
1840   /* If the prompt contains newlines, take the last tail. */
1841   prompt_last_line = strrchr (rl_prompt, '\n');
1842   if (!prompt_last_line)
1843     prompt_last_line = rl_prompt;
1844 
1845   l = strlen (prompt_last_line);
1846   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1847     _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1);	/* XXX */
1848   else
1849     _rl_last_c_pos = l;
1850 
1851   /* Dissect prompt_last_line into screen lines. Note that here we have
1852      to use the real screenwidth. Readline's notion of screenwidth might be
1853      one less, see terminal.c. */
1854   real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
1855   _rl_last_v_pos = l / real_screenwidth;
1856   /* If the prompt length is a multiple of real_screenwidth, we don't know
1857      whether the cursor is at the end of the last line, or already at the
1858      beginning of the next line. Output a newline just to be safe. */
1859   if (l > 0 && (l % real_screenwidth) == 0)
1860     _rl_output_some_chars ("\n", 1);
1861   last_lmargin = 0;
1862 
1863   newlines = 0; i = 0;
1864   while (i <= l)
1865     {
1866       _rl_vis_botlin = newlines;
1867       vis_lbreaks[newlines++] = i;
1868       i += real_screenwidth;
1869     }
1870   vis_lbreaks[newlines] = l;
1871   visible_wrap_offset = 0;
1872 
1873   rl_display_prompt = rl_prompt;	/* XXX - make sure it's set */
1874 
1875   return 0;
1876 }
1877 
1878 /* Actually update the display, period. */
1879 int
1880 rl_forced_update_display ()
1881 {
1882   register char *temp;
1883 
1884   if (visible_line)
1885     {
1886       temp = visible_line;
1887       while (*temp)
1888 	*temp++ = '\0';
1889     }
1890   rl_on_new_line ();
1891   forced_display++;
1892   (*rl_redisplay_function) ();
1893   return 0;
1894 }
1895 
1896 /* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
1897    (Well, when we don't have multibyte characters, _rl_last_c_pos is a
1898    buffer index.)
1899    DATA is the contents of the screen line of interest; i.e., where
1900    the movement is being done. */
1901 void
1902 _rl_move_cursor_relative (new, data)
1903      int new;
1904      const char *data;
1905 {
1906   register int i;
1907   int woff;			/* number of invisible chars on current line */
1908   int cpos, dpos;		/* current and desired cursor positions */
1909   int adjust;
1910 
1911   woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
1912   cpos = _rl_last_c_pos;
1913 
1914   if (cpos == 0 && cpos == new)
1915     return;
1916 
1917 #if defined (HANDLE_MULTIBYTE)
1918   /* If we have multibyte characters, NEW is indexed by the buffer point in
1919      a multibyte string, but _rl_last_c_pos is the display position.  In
1920      this case, NEW's display position is not obvious and must be
1921      calculated.  We need to account for invisible characters in this line,
1922      as long as we are past them and they are counted by _rl_col_width. */
1923   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1924     {
1925       adjust = 1;
1926       /* Try to short-circuit common cases and eliminate a bunch of multibyte
1927 	 character function calls. */
1928       /* 1.  prompt string */
1929       if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
1930 	{
1931 	  dpos = prompt_physical_chars;
1932 	  cpos_adjusted = 1;
1933 	  adjust = 0;
1934 	}
1935       /* 2.  prompt_string + line contents */
1936       else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0)
1937 	{
1938 	  dpos = prompt_physical_chars + _rl_col_width (data, local_prompt_len, new, 1);
1939 	  cpos_adjusted = 1;
1940 	  adjust = 0;
1941 	}
1942       else
1943         dpos = _rl_col_width (data, 0, new, 1);
1944 
1945       /* Use NEW when comparing against the last invisible character in the
1946 	 prompt string, since they're both buffer indices and DPOS is a
1947 	 desired display position. */
1948       if (adjust && ((new > prompt_last_invisible) ||		/* XXX - don't use woff here */
1949 	  (prompt_physical_chars >= _rl_screenwidth &&
1950 	   _rl_last_v_pos == prompt_last_screen_line &&
1951 	   wrap_offset >= woff && dpos >= woff &&
1952 	   new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))))
1953 	   /* XXX last comparison might need to be >= */
1954 	{
1955 	  dpos -= woff;
1956 	  /* Since this will be assigned to _rl_last_c_pos at the end (more
1957 	     precisely, _rl_last_c_pos == dpos when this function returns),
1958 	     let the caller know. */
1959 	  cpos_adjusted = 1;
1960 	}
1961     }
1962   else
1963 #endif
1964     dpos = new;
1965 
1966   /* If we don't have to do anything, then return. */
1967   if (cpos == dpos)
1968     return;
1969 
1970   /* It may be faster to output a CR, and then move forwards instead
1971      of moving backwards. */
1972   /* i == current physical cursor position. */
1973 #if defined (HANDLE_MULTIBYTE)
1974   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1975     i = _rl_last_c_pos;
1976   else
1977 #endif
1978   i = _rl_last_c_pos - woff;
1979   if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
1980       (_rl_term_autowrap && i == _rl_screenwidth))
1981     {
1982 #if defined (__MSDOS__)
1983       putc ('\r', rl_outstream);
1984 #else
1985       tputs (_rl_term_cr, 1, _rl_output_character_function);
1986 #endif /* !__MSDOS__ */
1987       cpos = _rl_last_c_pos = 0;
1988     }
1989 
1990   if (cpos < dpos)
1991     {
1992       /* Move the cursor forward.  We do it by printing the command
1993 	 to move the cursor forward if there is one, else print that
1994 	 portion of the output buffer again.  Which is cheaper? */
1995 
1996       /* The above comment is left here for posterity.  It is faster
1997 	 to print one character (non-control) than to print a control
1998 	 sequence telling the terminal to move forward one character.
1999 	 That kind of control is for people who don't know what the
2000 	 data is underneath the cursor. */
2001 
2002       /* However, we need a handle on where the current display position is
2003 	 in the buffer for the immediately preceding comment to be true.
2004 	 In multibyte locales, we don't currently have that info available.
2005 	 Without it, we don't know where the data we have to display begins
2006 	 in the buffer and we have to go back to the beginning of the screen
2007 	 line.  In this case, we can use the terminal sequence to move forward
2008 	 if it's available. */
2009       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2010 	{
2011 	  if (_rl_term_forward_char)
2012 	    {
2013 	      for (i = cpos; i < dpos; i++)
2014 	        tputs (_rl_term_forward_char, 1, _rl_output_character_function);
2015 	    }
2016 	  else
2017 	    {
2018 	      tputs (_rl_term_cr, 1, _rl_output_character_function);
2019 	      for (i = 0; i < new; i++)
2020 		putc (data[i], rl_outstream);
2021 	    }
2022 	}
2023       else
2024 	for (i = cpos; i < new; i++)
2025 	  putc (data[i], rl_outstream);
2026     }
2027 
2028 #if defined (HANDLE_MULTIBYTE)
2029   /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
2030      The byte length of the string is probably bigger than the column width
2031      of the string, which means that if NEW == _rl_last_c_pos, then NEW's
2032      display point is less than _rl_last_c_pos. */
2033 #endif
2034   else if (cpos > dpos)
2035     _rl_backspace (cpos - dpos);
2036 
2037   _rl_last_c_pos = dpos;
2038 }
2039 
2040 /* PWP: move the cursor up or down. */
2041 void
2042 _rl_move_vert (to)
2043      int to;
2044 {
2045   register int delta, i;
2046 
2047   if (_rl_last_v_pos == to || to > _rl_screenheight)
2048     return;
2049 
2050   if ((delta = to - _rl_last_v_pos) > 0)
2051     {
2052       for (i = 0; i < delta; i++)
2053 	putc ('\n', rl_outstream);
2054 #if defined (__MSDOS__)
2055       putc ('\r', rl_outstream);
2056 #else
2057       tputs (_rl_term_cr, 1, _rl_output_character_function);
2058 #endif
2059       _rl_last_c_pos = 0;
2060     }
2061   else
2062     {			/* delta < 0 */
2063 #ifdef __MSDOS__
2064       int row, col;
2065 
2066       fflush (rl_outstream); /* make sure the cursor pos is current! */
2067       ScreenGetCursor (&row, &col);
2068       ScreenSetCursor (row + delta, col);
2069       i = -delta;    /* in case someone wants to use it after the loop */
2070 #else /* !__MSDOS__ */
2071       if (_rl_term_up && *_rl_term_up)
2072 	for (i = 0; i < -delta; i++)
2073 	  tputs (_rl_term_up, 1, _rl_output_character_function);
2074 #endif /* !__MSDOS__ */
2075     }
2076 
2077   _rl_last_v_pos = to;		/* Now TO is here */
2078 }
2079 
2080 /* Physically print C on rl_outstream.  This is for functions which know
2081    how to optimize the display.  Return the number of characters output. */
2082 int
2083 rl_show_char (c)
2084      int c;
2085 {
2086   int n = 1;
2087   if (META_CHAR (c) && (_rl_output_meta_chars == 0))
2088     {
2089       fprintf (rl_outstream, "M-");
2090       n += 2;
2091       c = UNMETA (c);
2092     }
2093 
2094 #if defined (DISPLAY_TABS)
2095   if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
2096 #else
2097   if (CTRL_CHAR (c) || c == RUBOUT)
2098 #endif /* !DISPLAY_TABS */
2099     {
2100       fprintf (rl_outstream, "C-");
2101       n += 2;
2102       c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
2103     }
2104 
2105   putc (c, rl_outstream);
2106   fflush (rl_outstream);
2107   return n;
2108 }
2109 
2110 int
2111 rl_character_len (c, pos)
2112      register int c, pos;
2113 {
2114   unsigned char uc;
2115 
2116   uc = (unsigned char)c;
2117 
2118   if (META_CHAR (uc))
2119     return ((_rl_output_meta_chars == 0) ? 4 : 1);
2120 
2121   if (uc == '\t')
2122     {
2123 #if defined (DISPLAY_TABS)
2124       return (((pos | 7) + 1) - pos);
2125 #else
2126       return (2);
2127 #endif /* !DISPLAY_TABS */
2128     }
2129 
2130   if (CTRL_CHAR (c) || c == RUBOUT)
2131     return (2);
2132 
2133   return ((ISPRINT (uc)) ? 1 : 2);
2134 }
2135 /* How to print things in the "echo-area".  The prompt is treated as a
2136    mini-modeline. */
2137 static int msg_saved_prompt = 0;
2138 
2139 #if defined (USE_VARARGS)
2140 int
2141 #if defined (PREFER_STDARG)
2142 rl_message (const char *format, ...)
2143 #else
2144 rl_message (va_alist)
2145      va_dcl
2146 #endif
2147 {
2148   va_list args;
2149 #if defined (PREFER_VARARGS)
2150   char *format;
2151 #endif
2152 
2153 #if defined (PREFER_STDARG)
2154   va_start (args, format);
2155 #else
2156   va_start (args);
2157   format = va_arg (args, char *);
2158 #endif
2159 
2160 #if defined (HAVE_VSNPRINTF)
2161   vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args);
2162 #else
2163   vsprintf (msg_buf, format, args);
2164   msg_buf[sizeof(msg_buf) - 1] = '\0';	/* overflow? */
2165 #endif
2166   va_end (args);
2167 
2168   if (saved_local_prompt == 0)
2169     {
2170       rl_save_prompt ();
2171       msg_saved_prompt = 1;
2172     }
2173   rl_display_prompt = msg_buf;
2174   local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
2175 					 &prompt_last_invisible,
2176 					 &prompt_invis_chars_first_line,
2177 					 &prompt_physical_chars);
2178   local_prompt_prefix = (char *)NULL;
2179   local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
2180   (*rl_redisplay_function) ();
2181 
2182   return 0;
2183 }
2184 #else /* !USE_VARARGS */
2185 int
2186 rl_message (format, arg1, arg2)
2187      char *format;
2188 {
2189   sprintf (msg_buf, format, arg1, arg2);
2190   msg_buf[sizeof(msg_buf) - 1] = '\0';	/* overflow? */
2191 
2192   rl_display_prompt = msg_buf;
2193   if (saved_local_prompt == 0)
2194     {
2195       rl_save_prompt ();
2196       msg_saved_prompt = 1;
2197     }
2198   local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
2199 					 &prompt_last_invisible,
2200 					 &prompt_invis_chars_first_line,
2201 					 &prompt_physical_chars);
2202   local_prompt_prefix = (char *)NULL;
2203   local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
2204   (*rl_redisplay_function) ();
2205 
2206   return 0;
2207 }
2208 #endif /* !USE_VARARGS */
2209 
2210 /* How to clear things from the "echo-area". */
2211 int
2212 rl_clear_message ()
2213 {
2214   rl_display_prompt = rl_prompt;
2215   if (msg_saved_prompt)
2216     {
2217       rl_restore_prompt ();
2218       msg_saved_prompt = 0;
2219     }
2220   (*rl_redisplay_function) ();
2221   return 0;
2222 }
2223 
2224 int
2225 rl_reset_line_state ()
2226 {
2227   rl_on_new_line ();
2228 
2229   rl_display_prompt = rl_prompt ? rl_prompt : "";
2230   forced_display = 1;
2231   return 0;
2232 }
2233 
2234 void
2235 rl_save_prompt ()
2236 {
2237   saved_local_prompt = local_prompt;
2238   saved_local_prefix = local_prompt_prefix;
2239   saved_prefix_length = prompt_prefix_length;
2240   saved_local_length = local_prompt_len;
2241   saved_last_invisible = prompt_last_invisible;
2242   saved_visible_length = prompt_visible_length;
2243   saved_invis_chars_first_line = prompt_invis_chars_first_line;
2244   saved_physical_chars = prompt_physical_chars;
2245 
2246   local_prompt = local_prompt_prefix = (char *)0;
2247   local_prompt_len = 0;
2248   prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
2249   prompt_invis_chars_first_line = prompt_physical_chars = 0;
2250 }
2251 
2252 void
2253 rl_restore_prompt ()
2254 {
2255   FREE (local_prompt);
2256   FREE (local_prompt_prefix);
2257 
2258   local_prompt = saved_local_prompt;
2259   local_prompt_prefix = saved_local_prefix;
2260   local_prompt_len = saved_local_length;
2261   prompt_prefix_length = saved_prefix_length;
2262   prompt_last_invisible = saved_last_invisible;
2263   prompt_visible_length = saved_visible_length;
2264   prompt_invis_chars_first_line = saved_invis_chars_first_line;
2265   prompt_physical_chars = saved_physical_chars;
2266 
2267   /* can test saved_local_prompt to see if prompt info has been saved. */
2268   saved_local_prompt = saved_local_prefix = (char *)0;
2269   saved_local_length = 0;
2270   saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
2271   saved_invis_chars_first_line = saved_physical_chars = 0;
2272 }
2273 
2274 char *
2275 _rl_make_prompt_for_search (pchar)
2276      int pchar;
2277 {
2278   int len;
2279   char *pmt, *p;
2280 
2281   rl_save_prompt ();
2282 
2283   /* We've saved the prompt, and can do anything with the various prompt
2284      strings we need before they're restored.  We want the unexpanded
2285      portion of the prompt string after any final newline. */
2286   p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
2287   if (p == 0)
2288     {
2289       len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
2290       pmt = (char *)xmalloc (len + 2);
2291       if (len)
2292 	strcpy (pmt, rl_prompt);
2293       pmt[len] = pchar;
2294       pmt[len+1] = '\0';
2295     }
2296   else
2297     {
2298       p++;
2299       len = strlen (p);
2300       pmt = (char *)xmalloc (len + 2);
2301       if (len)
2302 	strcpy (pmt, p);
2303       pmt[len] = pchar;
2304       pmt[len+1] = '\0';
2305     }
2306 
2307   /* will be overwritten by expand_prompt, called from rl_message */
2308   prompt_physical_chars = saved_physical_chars + 1;
2309   return pmt;
2310 }
2311 
2312 /* Quick redisplay hack when erasing characters at the end of the line. */
2313 void
2314 _rl_erase_at_end_of_line (l)
2315      int l;
2316 {
2317   register int i;
2318 
2319   _rl_backspace (l);
2320   for (i = 0; i < l; i++)
2321     putc (' ', rl_outstream);
2322   _rl_backspace (l);
2323   for (i = 0; i < l; i++)
2324     visible_line[--_rl_last_c_pos] = '\0';
2325   rl_display_fixed++;
2326 }
2327 
2328 /* Clear to the end of the line.  COUNT is the minimum
2329    number of character spaces to clear, */
2330 void
2331 _rl_clear_to_eol (count)
2332      int count;
2333 {
2334 #ifndef __MSDOS__
2335   if (_rl_term_clreol)
2336     tputs (_rl_term_clreol, 1, _rl_output_character_function);
2337   else
2338 #endif
2339   if (count)
2340     space_to_eol (count);
2341 }
2342 
2343 /* Clear to the end of the line using spaces.  COUNT is the minimum
2344    number of character spaces to clear, */
2345 static void
2346 space_to_eol (count)
2347      int count;
2348 {
2349   register int i;
2350 
2351   for (i = 0; i < count; i++)
2352    putc (' ', rl_outstream);
2353 
2354   _rl_last_c_pos += count;
2355 }
2356 
2357 void
2358 _rl_clear_screen ()
2359 {
2360 #if defined (__GO32__)
2361   ScreenClear ();	/* FIXME: only works in text modes */
2362   ScreenSetCursor (0, 0);  /* term_clrpag is "cl" which homes the cursor */
2363 #else
2364   if (_rl_term_clrpag)
2365     tputs (_rl_term_clrpag, 1, _rl_output_character_function);
2366   else
2367     rl_crlf ();
2368 #endif
2369 }
2370 
2371 /* Insert COUNT characters from STRING to the output stream at column COL. */
2372 static void
2373 insert_some_chars (string, count, col)
2374      char *string;
2375      int count, col;
2376 {
2377 #if defined (__MSDOS__) || defined (__MINGW32__)
2378   _rl_output_some_chars (string, count);
2379 #else
2380   /* DEBUGGING */
2381   if (MB_CUR_MAX == 1 || rl_byte_oriented)
2382     if (count != col)
2383       _rl_ttymsg ("debug: insert_some_chars: count (%d) != col (%d)", count, col);
2384 
2385   /* If IC is defined, then we do not have to "enter" insert mode. */
2386   if (_rl_term_IC)
2387     {
2388       char *buffer;
2389 
2390       buffer = tgoto (_rl_term_IC, 0, col);
2391       tputs (buffer, 1, _rl_output_character_function);
2392       _rl_output_some_chars (string, count);
2393     }
2394   else
2395     {
2396       register int i;
2397 
2398       /* If we have to turn on insert-mode, then do so. */
2399       if (_rl_term_im && *_rl_term_im)
2400 	tputs (_rl_term_im, 1, _rl_output_character_function);
2401 
2402       /* If there is a special command for inserting characters, then
2403 	 use that first to open up the space. */
2404       if (_rl_term_ic && *_rl_term_ic)
2405 	{
2406 	  for (i = col; i--; )
2407 	    tputs (_rl_term_ic, 1, _rl_output_character_function);
2408 	}
2409 
2410       /* Print the text. */
2411       _rl_output_some_chars (string, count);
2412 
2413       /* If there is a string to turn off insert mode, we had best use
2414 	 it now. */
2415       if (_rl_term_ei && *_rl_term_ei)
2416 	tputs (_rl_term_ei, 1, _rl_output_character_function);
2417     }
2418 #endif /* __MSDOS__ || __MINGW32__ */
2419 }
2420 
2421 /* Delete COUNT characters from the display line. */
2422 static void
2423 delete_chars (count)
2424      int count;
2425 {
2426   if (count > _rl_screenwidth)	/* XXX */
2427     return;
2428 
2429 #if !defined (__MSDOS__) && !defined (__MINGW32__)
2430   if (_rl_term_DC && *_rl_term_DC)
2431     {
2432       char *buffer;
2433       buffer = tgoto (_rl_term_DC, count, count);
2434       tputs (buffer, count, _rl_output_character_function);
2435     }
2436   else
2437     {
2438       if (_rl_term_dc && *_rl_term_dc)
2439 	while (count--)
2440 	  tputs (_rl_term_dc, 1, _rl_output_character_function);
2441     }
2442 #endif /* !__MSDOS__ && !__MINGW32__ */
2443 }
2444 
2445 void
2446 _rl_update_final ()
2447 {
2448   int full_lines;
2449 
2450   full_lines = 0;
2451   /* If the cursor is the only thing on an otherwise-blank last line,
2452      compensate so we don't print an extra CRLF. */
2453   if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
2454 	visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
2455     {
2456       _rl_vis_botlin--;
2457       full_lines = 1;
2458     }
2459   _rl_move_vert (_rl_vis_botlin);
2460   /* If we've wrapped lines, remove the final xterm line-wrap flag. */
2461   if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
2462     {
2463       char *last_line;
2464 
2465       last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
2466       cpos_buffer_position = -1;	/* don't know where we are in buffer */
2467       _rl_move_cursor_relative (_rl_screenwidth - 1, last_line);	/* XXX */
2468       _rl_clear_to_eol (0);
2469       putc (last_line[_rl_screenwidth - 1], rl_outstream);
2470     }
2471   _rl_vis_botlin = 0;
2472   rl_crlf ();
2473   fflush (rl_outstream);
2474   rl_display_fixed++;
2475 }
2476 
2477 /* Move to the start of the current line. */
2478 static void
2479 cr ()
2480 {
2481   if (_rl_term_cr)
2482     {
2483 #if defined (__MSDOS__)
2484       putc ('\r', rl_outstream);
2485 #else
2486       tputs (_rl_term_cr, 1, _rl_output_character_function);
2487 #endif
2488       _rl_last_c_pos = 0;
2489     }
2490 }
2491 
2492 /* Redraw the last line of a multi-line prompt that may possibly contain
2493    terminal escape sequences.  Called with the cursor at column 0 of the
2494    line to draw the prompt on. */
2495 static void
2496 redraw_prompt (t)
2497      char *t;
2498 {
2499   char *oldp;
2500 
2501   oldp = rl_display_prompt;
2502   rl_save_prompt ();
2503 
2504   rl_display_prompt = t;
2505   local_prompt = expand_prompt (t, &prompt_visible_length,
2506 				   &prompt_last_invisible,
2507 				   &prompt_invis_chars_first_line,
2508 				   &prompt_physical_chars);
2509   local_prompt_prefix = (char *)NULL;
2510   local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
2511 
2512   rl_forced_update_display ();
2513 
2514   rl_display_prompt = oldp;
2515   rl_restore_prompt();
2516 }
2517 
2518 /* Redisplay the current line after a SIGWINCH is received. */
2519 void
2520 _rl_redisplay_after_sigwinch ()
2521 {
2522   char *t;
2523 
2524   /* Clear the last line (assuming that the screen size change will result in
2525      either more or fewer characters on that line only) and put the cursor at
2526      column 0.  Make sure the right thing happens if we have wrapped to a new
2527      screen line. */
2528   if (_rl_term_cr)
2529     {
2530       _rl_move_vert (_rl_vis_botlin);
2531 
2532 #if defined (__MSDOS__)
2533       putc ('\r', rl_outstream);
2534 #else
2535       tputs (_rl_term_cr, 1, _rl_output_character_function);
2536 #endif
2537       _rl_last_c_pos = 0;
2538 #if defined (__MSDOS__)
2539       space_to_eol (_rl_screenwidth);
2540       putc ('\r', rl_outstream);
2541 #else
2542       if (_rl_term_clreol)
2543 	tputs (_rl_term_clreol, 1, _rl_output_character_function);
2544       else
2545 	{
2546 	  space_to_eol (_rl_screenwidth);
2547 	  tputs (_rl_term_cr, 1, _rl_output_character_function);
2548 	}
2549 #endif
2550       if (_rl_last_v_pos > 0)
2551 	_rl_move_vert (0);
2552     }
2553   else
2554     rl_crlf ();
2555 
2556   /* Redraw only the last line of a multi-line prompt. */
2557   t = strrchr (rl_display_prompt, '\n');
2558   if (t)
2559     redraw_prompt (++t);
2560   else
2561     rl_forced_update_display ();
2562 }
2563 
2564 void
2565 _rl_clean_up_for_exit ()
2566 {
2567   if (_rl_echoing_p)
2568     {
2569       _rl_move_vert (_rl_vis_botlin);
2570       _rl_vis_botlin = 0;
2571       fflush (rl_outstream);
2572       rl_restart_output (1, 0);
2573     }
2574 }
2575 
2576 void
2577 _rl_erase_entire_line ()
2578 {
2579   cr ();
2580   _rl_clear_to_eol (0);
2581   cr ();
2582   fflush (rl_outstream);
2583 }
2584 
2585 /* return the `current display line' of the cursor -- the number of lines to
2586    move up to get to the first screen line of the current readline line. */
2587 int
2588 _rl_current_display_line ()
2589 {
2590   int ret, nleft;
2591 
2592   /* Find out whether or not there might be invisible characters in the
2593      editing buffer. */
2594   if (rl_display_prompt == rl_prompt)
2595     nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
2596   else
2597     nleft = _rl_last_c_pos - _rl_screenwidth;
2598 
2599   if (nleft > 0)
2600     ret = 1 + nleft / _rl_screenwidth;
2601   else
2602     ret = 0;
2603 
2604   return ret;
2605 }
2606 
2607 #if defined (HANDLE_MULTIBYTE)
2608 /* Calculate the number of screen columns occupied by STR from START to END.
2609    In the case of multibyte characters with stateful encoding, we have to
2610    scan from the beginning of the string to take the state into account. */
2611 static int
2612 _rl_col_width (str, start, end, flags)
2613      const char *str;
2614      int start, end, flags;
2615 {
2616   wchar_t wc;
2617   mbstate_t ps;
2618   int tmp, point, width, max;
2619 
2620   if (end <= start)
2621     return 0;
2622   if (MB_CUR_MAX == 1 || rl_byte_oriented)
2623 {
2624 _rl_ttymsg ("_rl_col_width: called with MB_CUR_MAX == 1");
2625     return (end - start);
2626 }
2627 
2628   memset (&ps, 0, sizeof (mbstate_t));
2629 
2630   point = 0;
2631   max = end;
2632 
2633   /* Try to short-circuit common cases.  The adjustment to remove wrap_offset
2634      is done by the caller. */
2635   /* 1.  prompt string */
2636   if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
2637     return (prompt_physical_chars + wrap_offset);
2638   /* 2.  prompt string + line contents */
2639   else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
2640     {
2641       tmp = prompt_physical_chars + wrap_offset;
2642       /* XXX - try to call ourselves recursively with non-prompt portion */
2643       tmp += _rl_col_width (str, local_prompt_len, end, flags);
2644       return (tmp);
2645     }
2646 
2647   while (point < start)
2648     {
2649       tmp = mbrlen (str + point, max, &ps);
2650       if (MB_INVALIDCH ((size_t)tmp))
2651 	{
2652 	  /* In this case, the bytes are invalid or too short to compose a
2653 	     multibyte character, so we assume that the first byte represents
2654 	     a single character. */
2655 	  point++;
2656 	  max--;
2657 
2658 	  /* Clear the state of the byte sequence, because in this case the
2659 	     effect of mbstate is undefined. */
2660 	  memset (&ps, 0, sizeof (mbstate_t));
2661 	}
2662       else if (MB_NULLWCH (tmp))
2663 	break;		/* Found '\0' */
2664       else
2665 	{
2666 	  point += tmp;
2667 	  max -= tmp;
2668 	}
2669     }
2670 
2671   /* If START is not a byte that starts a character, then POINT will be
2672      greater than START.  In this case, assume that (POINT - START) gives
2673      a byte count that is the number of columns of difference. */
2674   width = point - start;
2675 
2676   while (point < end)
2677     {
2678       tmp = mbrtowc (&wc, str + point, max, &ps);
2679       if (MB_INVALIDCH ((size_t)tmp))
2680 	{
2681 	  /* In this case, the bytes are invalid or too short to compose a
2682 	     multibyte character, so we assume that the first byte represents
2683 	     a single character. */
2684 	  point++;
2685 	  max--;
2686 
2687 	  /* and assume that the byte occupies a single column. */
2688 	  width++;
2689 
2690 	  /* Clear the state of the byte sequence, because in this case the
2691 	     effect of mbstate is undefined. */
2692 	  memset (&ps, 0, sizeof (mbstate_t));
2693 	}
2694       else if (MB_NULLWCH (tmp))
2695 	break;			/* Found '\0' */
2696       else
2697 	{
2698 	  point += tmp;
2699 	  max -= tmp;
2700 	  tmp = wcwidth(wc);
2701 	  width += (tmp >= 0) ? tmp : 1;
2702 	}
2703     }
2704 
2705   width += point - end;
2706 
2707   return width;
2708 }
2709 #endif /* HANDLE_MULTIBYTE */
2710