OSDN Git Service

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