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