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