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