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