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