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