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