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