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