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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [readline/] [display.c] - Blame information for rev 866

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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