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