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