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