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