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