Subversion Repositories Open64

[/] [sim/] [fsim/] [shell/] [tclsh/] [readline/] [display.c] - Blame information for rev 2072

Details | Compare with Previous | View Log

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