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