OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [readline/] [display.c] - Blame information for rev 227

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.