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