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