commit bash-20081125 snapshot

This commit is contained in:
Chet Ramey
2011-12-07 09:33:06 -05:00
parent a9fac3b2a8
commit 57a3f68923
20 changed files with 11391 additions and 108 deletions
+37
View File
@@ -7179,3 +7179,40 @@ redir.c
close-on-exec when the fd is restored. Set flag in add_undo_redirect,
check in do_redirection_internal. Fixes problem reported by Andreas
Schwab <schwab@suse.de>
11/26
-----
subst.c
- fix param_expand to have expansions of $@ and $* exit the shell if
there are no positional parameters and `set -u' is enabled. Fixes
bug reported by Dan Jacobson <jidanni@jidanni.org>
11/27
-----
lib/readline/display.c
- fix update_line to not call space_to_eol if current cursor position
(_rl_last_c_pos) indicates that we're already at end of line.
Partial fix for bug reported by Mike Frysinger <vapier@gentoo.org>
- in update_line, don't call insert_some_chars if that will start
before the last invisible character in the prompt string and not
draw the entire prompt string. More of the partial fix for bug
reported by Mike Frysinger <vapier@gentoo.org>
- fix update_line to adjust _rl_last_c_pos by wrap_offset when adding
characters beginning before the last invisible character in the
prompt. New code is same as previously existed in a different code
path. Rest of fix for bug from Mike Frysinger <vapier@gentoo.org>
- fix assignment of newline breaks (inv_lbreaks) to correctly account
for prompts longer than two screen lines containing invisible
characters. The assumption is that part of the invisible characters
are on the first line (prompt_invis_chars_first_line) and the
remainder are on the last (wrap_offset - prompt_invis_chars_first_line).
Fix is in rl_redisplay. part of fix for bug reported by
"Wesley J. Landaker" <wjl@icecavern.net> in
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=265182
[TENTATIVE]
- fix _rl_move_cursor_relative to correctly offset `dpos' by `woff'
when there are invisible characters on lines after the second by
using (_rl_screenwidth*_rl_last_v_pos) when seeing whether or not
we just wrote some invisible characters. Rest of fix for bug
reported in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=265182
[TENTATIVE]
+40 -2
View File
@@ -7175,6 +7175,44 @@ bashhist.c
redir.c
- When undoing saving of non-standard file descriptors (>=3) using
file descriptors >= SHELL_FD_BASE, we set the saving fd to be
close-on-exec and use a flag to decide how to set close-on-exec
when the fd is restored. Fixes problem reported by Andreas
close-on-exec and use a flag (RX_SAVCLEXEC) to decide how to set
close-on-exec when the fd is restored. Set flag in add_undo_redirect,
check in do_redirection_internal. Fixes problem reported by Andreas
Schwab <schwab@suse.de>
11/26
-----
subst.c
- fix param_expand to have expansions of $@ and $* exit the shell if
there are no positional parameters and `set -u' is enabled. Fixes
bug reported by Dan Jacobson <jidanni@jidanni.org>
11/27
-----
lib/readline/display.c
- fix update_line to not call space_to_eol if current cursor position
(_rl_last_c_pos) indicates that we're already at end of line.
Partial fix for bug reported by Mike Frysinger <vapier@gentoo.org>
- in update_line, don't call insert_some_chars if that will start
before the last invisible character in the prompt string and not
draw the entire prompt string. More of the partial fix for bug
reported by Mike Frysinger <vapier@gentoo.org>
- fix update_line to adjust _rl_last_c_pos by wrap_offset when adding
characters beginning before the first invisible character in the
prompt. New code is same as previously existed in a different code
path. Rest of fix for bug from Mike Frysinger <vapier@gentoo.org>
- fix assignment of newline breaks (inv_lbreaks) to correctly account
for prompts longer than two screen lines containing invisible
characters. The assumption is that part of the invisible characters
are on the first line (prompt_invis_chars_first_line) and the
remainder are on the last (wrap_offset - prompt_invis_chars_first_line).
Fix is in rl_redisplay. part of fix for bug reported by
"Wesley J. Landaker" <wjl@icecavern.net> in
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=265182
[TENTATIVE]
- fix _rl_move_cursor_relative to correctly offset `dpos' by `woff'
when there are invisible characters on lines after the second by
using (_rl_screenwidth*_rl_last_v_pos) when seeing whether or not
we just wrote some invisible characters. Rest of fix for bug
reported in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=265182
[TENTATIVE]
+1 -1
View File
@@ -48,7 +48,7 @@ If not supplied with an explicit origin, mapfile will clear ARRAY before
assigning to it.
Exit Status:
Returns success unless an invald option is given or ARRAY is readonly.
Returns success unless an invalid option is given or ARRAY is readonly.
$END
#include <config.h>
+317
View File
@@ -0,0 +1,317 @@
This file is mapfile.def, from which is created mapfile.c.
It implements the builtin "mapfile" in Bash.
Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
Copyright (C) 2008 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES mapfile.c
$BUILTIN mapfile
$FUNCTION mapfile_builtin
$SHORT_DOC mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
Read lines from a file into an array variable.
Read lines from the standard input into the array variable ARRAY, or from
file descriptor FD if the -u option is supplied. The variable MAPFILE is
the default ARRAY.
Options:
-n count Copy at most COUNT lines. If COUNT is 0, all lines are copied.
-O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0.
-s count Discard the first COUNT lines read.
-t Remove a trailing newline from each line read.
-u fd Read lines from file descriptor FD instead of the standard input.
-C callback Evaluate CALLBACK each time QUANTUM lines are read.
-c quantum Specify the number of lines read between each call to CALLBACK.
Arguments:
ARRAY Array variable name to use for file data.
If -C is supplied without -c, the default quantum is 5000.
If not supplied with an explicit origin, mapfile will clear ARRAY before
assigning to it.
Exit Status:
Returns success unless an invald option is given or ARRAY is readonly.
$END
#include <config.h>
#include "builtins.h"
#include "posixstat.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include <stdio.h>
#include <errno.h>
#include "../bashintl.h"
#include "../shell.h"
#include "common.h"
#include "bashgetopt.h"
#if !defined (errno)
extern int errno;
#endif
#if defined (ARRAY_VARS)
#define DEFAULT_ARRAY_NAME "MAPFILE"
/* The value specifying how frequently `mapfile' calls the callback. */
#define DEFAULT_QUANTUM 5000
/* Values for FLAGS */
#define MAPF_CLEARARRAY 0x01
#define MAPF_CHOP 0x02
static int
run_callback(callback, current_index)
const char *callback;
unsigned int current_index;
{
unsigned int execlen;
char *execstr;
execlen = strlen (callback) + 10;
/* 1 for space between %s and %d,
another 1 for the last nul char for C string. */
execlen += 2;
execstr = xmalloc (execlen);
snprintf (execstr, execlen, "%s %d", callback, current_index);
return parse_and_execute(execstr, NULL, 0);
}
static void
do_chop(line)
char * line;
{
int length;
length = strlen (line);
if (length && line[length-1] == '\n')
line[length-1] = '\0';
}
static int
mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, flags)
int fd;
long line_count_goal, origin, nskip, callback_quantum;
char *callback, *array_name;
int flags;
{
char *line;
size_t line_length;
unsigned int array_index, line_count;
SHELL_VAR *entry;
int unbuffered_read;
line = NULL;
line_length = 0;
unbuffered_read = 0;
/* The following check should be done before reading any lines. Doing it
here allows us to call bind_array_element instead of bind_array_variable
and skip the variable lookup on every call. */
entry = find_or_make_array_variable (array_name, 1);
if (entry == 0)
return (EXECUTION_FAILURE);
if (flags & MAPF_CLEARARRAY)
array_flush (array_cell (entry));
#ifndef __CYGWIN__
unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
#else
unbuffered_read = 1;
#endif
/* Skip any lines at beginning of file? */
for (line_count = 0; line_count < nskip; line_count++)
zgetline(fd, &line, &line_length, unbuffered_read);
line = 0;
line_length = 0;
/* Reset the buffer for bash own stream */
for (array_index = origin, line_count = 0;
zgetline(fd, &line, &line_length, unbuffered_read) != -1;
array_index++, line_count++)
{
/* Have we exceeded # of lines to store? */
if (line_count_goal != 0 && line_count >= line_count_goal)
break;
/* Remove trailing newlines? */
if (flags & MAPF_CHOP)
do_chop (line);
/* Has a callback been registered and if so is it time to call it? */
if (callback && line_count && (line_count % callback_quantum) == 0)
{
run_callback (callback, array_index);
/* Reset the buffer for bash own stream. */
if (unbuffered_read == 0)
zsyncfd (fd);
}
bind_array_element (entry, array_index, line, 0);
}
xfree (line);
if (unbuffered_read == 0)
zsyncfd (fd);
return EXECUTION_SUCCESS;
}
int
mapfile_builtin (list)
WORD_LIST *list;
{
int opt, code, fd, clear_array, flags;
intmax_t intval;
long lines, origin, nskip, callback_quantum;
char *array_name, *callback;
clear_array = 1;
fd = 0;
lines = origin = nskip = 0;
flags = MAPF_CLEARARRAY;
callback_quantum = DEFAULT_QUANTUM;
callback = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "u:n:O:tC:c:s:")) != -1)
{
switch (opt)
{
case 'u':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval < 0 || intval != (int)intval)
{
builtin_error (_("%s: invalid file descriptor specification"), list_optarg);
return (EXECUTION_FAILURE);
}
else
fd = intval;
if (sh_validfd (fd) == 0)
{
builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno));
return (EXECUTION_FAILURE);
}
break;
case 'n':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval < 0 || intval != (unsigned)intval)
{
builtin_error (_("%s: invalid line count"), list_optarg);
return (EXECUTION_FAILURE);
}
else
lines = intval;
break;
case 'O':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval < 0 || intval != (unsigned)intval)
{
builtin_error (_("%s: invalid array origin"), list_optarg);
return (EXECUTION_FAILURE);
}
else
origin = intval;
flags &= ~MAPF_CLEARARRAY;
break;
case 't':
flags |= MAPF_CHOP;
break;
case 'C':
callback = list_optarg;
break;
case 'c':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval < 0 || intval != (unsigned)intval)
{
builtin_error (_("%s: invalid callback quantum"), list_optarg);
return (EXECUTION_FAILURE);
}
else
callback_quantum = intval;
break;
case 's':
code = legal_number (list_optarg, &intval);
if (code == 0 || intval < 0 || intval != (unsigned)intval)
{
builtin_error (_("%s: invalid line count"), list_optarg);
return (EXECUTION_FAILURE);
}
else
nskip = intval;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list == 0)
array_name = DEFAULT_ARRAY_NAME;
else if (list->word == 0 || list->word->word == 0)
{
builtin_error ("internal error: getting variable name");
return (EXECUTION_FAILURE);
}
else if (list->word->word[0] == '\0')
{
builtin_error (_("empty array variable name"));
return (EX_USAGE);
}
else
array_name = list->word->word;
if (legal_identifier (array_name) == 0 && valid_array_reference (array_name) == 0)
{
sh_invalidid (array_name);
return (EXECUTION_FAILURE);
}
return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, flags);
}
#else
int
mapfile_builtin (list)
WORD_LIST *list;
{
builtin_error (_("array variable support required"));
return (EXECUTION_FAILURE);
}
#endif /* ARRAY_VARS */
+1 -1
View File
@@ -182,7 +182,7 @@ extern int errno;
otherwise. */
#define POSIXBLK -2
#define BLOCKSIZE(x) (((x) == POSIXBLK && posixly_correct) ? 512 : 1024)
#define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x))
extern int posixly_correct;
+1 -1
View File
@@ -104,7 +104,7 @@ extern int errno;
# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
# undef _KERNEL
# endif
#else
#elif defined (HAVE_SYS_TIMES_H)
# include <sys/times.h>
#endif
+2 -1
View File
@@ -2922,7 +2922,7 @@ file names matching the pattern.
If no matching file names are found,
and the shell option
.B nullglob
is disabled, the word is left unchanged.
is not enabled, the word is left unchanged.
If the
.B nullglob
option is set, and no matches are found,
@@ -8144,6 +8144,7 @@ Same as
.B noglob
Same as
.BR \-f .
.TP 8
.B nolog
Currently ignored.
.TP 8
+163
View File
@@ -0,0 +1,163 @@
*** ../../../bash-20081120/lib/readline/display.c 2008-11-13 09:55:19.000000000 -0500
--- display.c 2008-11-28 23:37:26.000000000 -0500
***************
*** 497,501 ****
register char *line;
int inv_botlin, lb_botlin, lb_linenum, o_cpos;
! int newlines, lpos, temp, n0, num;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
--- 497,501 ----
register char *line;
int inv_botlin, lb_botlin, lb_linenum, o_cpos;
! int newlines, lpos, temp, n0, num, prompt_lines_estimate;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
***************
*** 664,668 ****
the first physical line of the prompt.
wrap_offset - prompt_invis_chars_first_line is the number of invis
! chars on the second line. */
/* what if lpos is already >= _rl_screenwidth before we start drawing the
--- 664,671 ----
the first physical line of the prompt.
wrap_offset - prompt_invis_chars_first_line is the number of invis
! chars on the second (or, more generally, last) line. */
!
! /* This is zero-based, used to set the newlines */
! prompt_lines_estimate = lpos / _rl_screenwidth;
/* what if lpos is already >= _rl_screenwidth before we start drawing the
***************
*** 702,710 ****
/* Now account for invisible characters in the current line. */
! /* XXX - this assumes that all of the invisible characters are before
! the line wrap. */
temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
! : ((newlines == 1) ? wrap_offset : 0))
! : ((newlines == 0) ? wrap_offset :0));
inv_lbreaks[++newlines] = temp;
--- 705,713 ----
/* Now account for invisible characters in the current line. */
! /* XXX - this assumes that the invisible characters may be split, but only
! between the first and the last lines. */
temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
! : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line))
! : ((newlines == 0) ? wrap_offset : 0));
inv_lbreaks[++newlines] = temp;
***************
*** 969,973 ****
is an absolute cursor position in a multibyte locale. See
if compensating here is the right thing, or if we have to
! change update_line itself. There is one case in which
update_line adjusts _rl_last_c_pos itself (so it can pass
_rl_move_cursor_relative accurate values); it communicates
--- 972,976 ----
is an absolute cursor position in a multibyte locale. See
if compensating here is the right thing, or if we have to
! change update_line itself. There are several cases in which
update_line adjusts _rl_last_c_pos itself (so it can pass
_rl_move_cursor_relative accurate values); it communicates
***************
*** 1609,1614 ****
_rl_term_IC or _rl_term_ic will screw up the screen because of the
invisible characters. We need to just draw them. */
! if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
! lendiff <= prompt_visible_length || !current_invis_chars))
{
insert_some_chars (nfd, lendiff, col_lendiff);
--- 1612,1626 ----
_rl_term_IC or _rl_term_ic will screw up the screen because of the
invisible characters. We need to just draw them. */
! /* The same thing happens if we're trying to draw before the last
! invisible character in the prompt string and we're not drawing
! the entire prompt string. */
! if (*ols && ((_rl_horizontal_scroll_mode &&
! _rl_last_c_pos == 0 &&
! lendiff > prompt_visible_length &&
! current_invis_chars > 0) == 0) &&
! (((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
! current_line == 0 && wrap_offset &&
! ((nfd - new) <= prompt_last_invisible) &&
! (col_lendiff < prompt_visible_length)) == 0))
{
insert_some_chars (nfd, lendiff, col_lendiff);
***************
*** 1631,1635 ****
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
! if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
--- 1643,1647 ----
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
! if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
***************
*** 1652,1655 ****
--- 1664,1675 ----
twidth = temp - lendiff;
_rl_last_c_pos += twidth;
+ /* If nfd begins before any invisible characters in the prompt,
+ adjust _rl_last_c_pos to account for wrap_offset and set
+ cpos_adjusted to let the caller know. */
+ if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
+ {
+ _rl_last_c_pos -= wrap_offset;
+ cpos_adjusted = 1;
+ }
}
}
***************
*** 1663,1666 ****
--- 1683,1694 ----
characters) we need to adjust _rl_last_c_pos, since it represents
a physical character position. */
+ if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
+ current_line == prompt_last_screen_line && wrap_offset &&
+ wrap_offset != prompt_invis_chars_first_line &&
+ ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
+ {
+ _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
+ cpos_adjusted = 1;
+ }
}
}
***************
*** 1728,1732 ****
--- 1756,1769 ----
col_lendiff = lendiff;
+ #if 0
if (col_lendiff)
+ #else
+ /* If we've already printed over the entire width of the screen,
+ including the old material, then col_lendiff doesn't matter and
+ space_to_eol will insert too many spaces. XXX - maybe we should
+ adjust col_lendiff based on the difference between _rl_last_c_pos
+ and _rl_screenwidth */
+ if (col_lendiff && (_rl_last_c_pos < _rl_screenwidth))
+ #endif
{
if (_rl_term_autowrap && current_line < inv_botlin)
***************
*** 1863,1867 ****
_rl_last_v_pos == prompt_last_screen_line &&
wrap_offset != woff &&
! new > (prompt_last_invisible-_rl_screenwidth-wrap_offset)))
{
dpos -= woff;
--- 1900,1905 ----
_rl_last_v_pos == prompt_last_screen_line &&
wrap_offset != woff &&
! new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset)))
! /* XXX last comparison might need to be >= */
{
dpos -= woff;
+61 -14
View File
@@ -496,7 +496,7 @@ rl_redisplay ()
register int in, out, c, linenum, cursor_linenum;
register char *line;
int inv_botlin, lb_botlin, lb_linenum, o_cpos;
int newlines, lpos, temp, n0, num;
int newlines, lpos, temp, n0, num, prompt_lines_estimate;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc;
@@ -663,7 +663,10 @@ rl_redisplay ()
/* prompt_invis_chars_first_line is the number of invisible characters in
the first physical line of the prompt.
wrap_offset - prompt_invis_chars_first_line is the number of invis
chars on the second line. */
chars on the second (or, more generally, last) line. */
/* This is zero-based, used to set the newlines */
prompt_lines_estimate = lpos / _rl_screenwidth;
/* what if lpos is already >= _rl_screenwidth before we start drawing the
contents of the command line? */
@@ -701,11 +704,11 @@ rl_redisplay ()
temp = ((newlines + 1) * _rl_screenwidth);
/* Now account for invisible characters in the current line. */
/* XXX - this assumes that all of the invisible characters are before
the line wrap. */
/* XXX - this assumes that the invisible characters may be split, but only
between the first and the last lines. */
temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
: ((newlines == 1) ? wrap_offset : 0))
: ((newlines == 0) ? wrap_offset :0));
: ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line))
: ((newlines == 0) ? wrap_offset : 0));
inv_lbreaks[++newlines] = temp;
#if defined (HANDLE_MULTIBYTE)
@@ -968,7 +971,7 @@ rl_redisplay ()
take invisible characters into account, since _rl_last_c_pos
is an absolute cursor position in a multibyte locale. See
if compensating here is the right thing, or if we have to
change update_line itself. There is one case in which
change update_line itself. There are several cases in which
update_line adjusts _rl_last_c_pos itself (so it can pass
_rl_move_cursor_relative accurate values); it communicates
this back by setting cpos_adjusted. If we assume that
@@ -1608,12 +1611,30 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
_rl_horizontal_scroll_mode == 1, inserting the characters with
_rl_term_IC or _rl_term_ic will screw up the screen because of the
invisible characters. We need to just draw them. */
if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
lendiff <= prompt_visible_length || !current_invis_chars))
/* The same thing happens if we're trying to draw before the last
invisible character in the prompt string or we're increasing the
number of invisible characters in the line and we're not drawing
the entire prompt string. */
if (*ols && ((_rl_horizontal_scroll_mode &&
_rl_last_c_pos == 0 &&
lendiff > prompt_visible_length &&
current_invis_chars > 0) == 0) &&
(((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
current_line == 0 && wrap_offset &&
((nfd - new) <= prompt_last_invisible) &&
(col_lendiff < prompt_visible_length)) == 0) &&
(visible_wrap_offset >= current_invis_chars))
{
insert_some_chars (nfd, lendiff, col_lendiff);
_rl_last_c_pos += col_lendiff;
}
#if 0 /* XXX - for now */
else if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && _rl_last_c_pos == 0 && wrap_offset && (nfd-new) <= prompt_last_invisible && col_lendiff < prompt_visible_length && visible_wrap_offset >= current_invis_chars)
{
_rl_output_some_chars (nfd, lendiff);
_rl_last_c_pos += col_lendiff;
}
#endif
else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
{
/* At the end of a line the characters do not have to
@@ -1627,10 +1648,10 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += col_temp;
/* If nfd begins before any invisible characters in the prompt,
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
/* If nfd begins before the last invisible character in the
prompt, adjust _rl_last_c_pos to account for wrap_offset
and set cpos_adjusted to let the caller know. */
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
@@ -1651,6 +1672,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
else
twidth = temp - lendiff;
_rl_last_c_pos += twidth;
/* If nfd begins before the last invisible character in the
prompt, adjust _rl_last_c_pos to account for wrap_offset
and set cpos_adjusted to let the caller know. */
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
}
}
}
else
@@ -1662,6 +1691,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
char in the current line (which implies we just output some invisible
characters) we need to adjust _rl_last_c_pos, since it represents
a physical character position. */
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
current_line == prompt_last_screen_line && wrap_offset &&
wrap_offset != prompt_invis_chars_first_line &&
((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
{
_rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
cpos_adjusted = 1;
}
}
}
else /* Delete characters from line. */
@@ -1727,7 +1764,16 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
else
col_lendiff = lendiff;
#if 0
if (col_lendiff)
#else
/* If we've already printed over the entire width of the screen,
including the old material, then col_lendiff doesn't matter and
space_to_eol will insert too many spaces. XXX - maybe we should
adjust col_lendiff based on the difference between _rl_last_c_pos
and _rl_screenwidth */
if (col_lendiff && (_rl_last_c_pos < _rl_screenwidth))
#endif
{
if (_rl_term_autowrap && current_line < inv_botlin)
space_to_eol (col_lendiff);
@@ -1862,7 +1908,8 @@ _rl_move_cursor_relative (new, data)
(prompt_physical_chars > _rl_screenwidth &&
_rl_last_v_pos == prompt_last_screen_line &&
wrap_offset != woff &&
new > (prompt_last_invisible-_rl_screenwidth-wrap_offset)))
new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset)))
/* XXX last comparison might need to be >= */
{
dpos -= woff;
/* Since this will be assigned to _rl_last_c_pos at the end (more
File diff suppressed because it is too large Load Diff
+175 -49
View File
@@ -1,24 +1,24 @@
/* display.c -- readline redisplay facility. */
/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
/* Copyright (C) 1987-2008 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
@@ -82,6 +82,7 @@ struct line_state
static struct line_state line_state_array[2];
static struct line_state *line_state_visible = &line_state_array[0];
static struct line_state *line_state_invisible = &line_state_array[1];
static int line_structures_initialized = 0;
/* Backwards-compatible names. */
#define inv_lbreaks (line_state_invisible->lbreaks)
@@ -106,7 +107,7 @@ static int _rl_col_width PARAMS((const char *, int, int));
/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
buffer index in others. This macro is used when deciding whether the
current cursor position is in the middle of a prompt string containing
invisible characters. */
invisible characters. XXX - might need to take `modmark' into account. */
#define PROMPT_ENDING_INDEX \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
@@ -164,6 +165,7 @@ int _rl_last_v_pos = 0;
static int cpos_adjusted;
static int cpos_buffer_position;
static int prompt_multibyte_chars;
/* Number of lines currently on screen minus 1. */
int _rl_vis_botlin = 0;
@@ -213,6 +215,10 @@ static int prompt_last_screen_line;
static int prompt_physical_chars;
/* set to a non-zero value by rl_redisplay if we are marking modified history
lines and the current line is so marked. */
static int modmark;
/* Variables to save and restore prompt and display information. */
/* These are getting numerous enough that it's time to create a struct. */
@@ -300,6 +306,11 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
*r++ = *p++;
if (!ignoring)
{
/* rl ends up being assigned to prompt_visible_length,
which is the number of characters in the buffer that
contribute to characters on the screen, which might
not be the same as the number of physical characters
on the screen in the presence of multibyte characters */
rl += ind - pind;
physchars += _rl_col_width (pmt, pind, ind);
}
@@ -409,14 +420,14 @@ rl_expand_prompt (prompt)
t = ++p;
local_prompt = expand_prompt (p, &prompt_visible_length,
&prompt_last_invisible,
(int *)NULL,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
c = *t; *t = '\0';
/* The portion of the prompt string up to and including the
final newline is now null-terminated. */
local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
(int *)NULL,
&prompt_invis_chars_first_line,
(int *)NULL,
(int *)NULL);
*t = c;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
@@ -461,8 +472,7 @@ init_line_structures (minsize)
{
/* should be enough. */
inv_lbsize = vis_lbsize = 256;
inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
#if defined (HANDLE_MULTIBYTE)
line_state_visible->wbsize = vis_lbsize;
line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int));
@@ -470,8 +480,13 @@ init_line_structures (minsize)
line_state_invisible->wbsize = inv_lbsize;
line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int));
#endif
inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
inv_lbreaks[0] = vis_lbreaks[0] = 0;
}
line_structures_initialized = 1;
}
/* Basic redisplay algorithm. */
@@ -481,7 +496,7 @@ rl_redisplay ()
register int in, out, c, linenum, cursor_linenum;
register char *line;
int inv_botlin, lb_botlin, lb_linenum, o_cpos;
int newlines, lpos, temp, modmark, n0, num;
int newlines, lpos, temp, n0, num, prompt_lines_estimate;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc;
@@ -491,13 +506,17 @@ rl_redisplay ()
int _rl_wrapped_multicolumn = 0;
#endif
if (!readline_echoing_p)
if (_rl_echoing_p == 0)
return;
/* Block keyboard interrupts because this function manipulates global
data structures. */
_rl_block_sigint ();
if (!rl_display_prompt)
rl_display_prompt = "";
if (invisible_line == 0 || vis_lbreaks == 0)
if (line_structures_initialized == 0)
{
init_line_structures (0);
rl_on_new_line ();
@@ -506,6 +525,8 @@ rl_redisplay ()
/* Draw the line into the buffer. */
cpos_buffer_position = -1;
prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars;
line = invisible_line;
out = inv_botlin = 0;
@@ -632,11 +653,7 @@ rl_redisplay ()
/* inv_lbreaks[i] is where line i starts in the buffer. */
inv_lbreaks[newlines = 0] = 0;
#if 0
lpos = out - wrap_offset;
#else
lpos = prompt_physical_chars + modmark;
#endif
#if defined (HANDLE_MULTIBYTE)
memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
@@ -646,7 +663,10 @@ rl_redisplay ()
/* prompt_invis_chars_first_line is the number of invisible characters in
the first physical line of the prompt.
wrap_offset - prompt_invis_chars_first_line is the number of invis
chars on the second line. */
chars on the second (or, more generally, last) line. */
/* This is zero-based, used to set the newlines */
prompt_lines_estimate = lpos / _rl_screenwidth;
/* what if lpos is already >= _rl_screenwidth before we start drawing the
contents of the command line? */
@@ -661,7 +681,7 @@ rl_redisplay ()
prompts that exceed two physical lines?
Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
{
n0 = num;
temp = local_prompt_len;
@@ -684,15 +704,15 @@ rl_redisplay ()
temp = ((newlines + 1) * _rl_screenwidth);
/* Now account for invisible characters in the current line. */
/* XXX - this assumes that all of the invisible characters are before
the line wrap. */
/* XXX - this assumes that the invisible characters may be split, but only
between the first and the last lines. */
temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
: ((newlines == 1) ? wrap_offset : 0))
: ((newlines == 0) ? wrap_offset :0));
: ((newlines == 0) ? wrap_offset : 0));
inv_lbreaks[++newlines] = temp;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
lpos -= _rl_col_width (local_prompt, n0, num);
else
#endif
@@ -926,6 +946,10 @@ rl_redisplay ()
second and subsequent lines start at inv_lbreaks[N], offset by
OFFSET (which has already been calculated above). */
#define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
#define WRAP_OFFSET(line, offset) ((line == 0) \
? (offset ? INVIS_FIRST() : 0) \
: ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
@@ -960,7 +984,13 @@ rl_redisplay ()
_rl_last_c_pos != o_cpos &&
_rl_last_c_pos > wrap_offset &&
o_cpos < prompt_last_invisible)
_rl_last_c_pos -= wrap_offset;
_rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
(MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
cpos_adjusted == 0 &&
_rl_last_c_pos != o_cpos &&
_rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
_rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
/* If this is the line with the prompt, we might need to
compensate for invisible characters in the new line. Do
@@ -980,6 +1010,19 @@ rl_redisplay ()
if (nleft)
_rl_clear_to_eol (nleft);
}
#if 0
/* This segment is intended to handle the case where the prompt
has invisible characters on the second line and the new line
to be displayed needs to clear the rest of the old characters
out (e.g., when printing the i-search prompt). In general,
the case of the new line being shorter than the old.
Incomplete */
else if (linenum == prompt_last_screen_line &&
prompt_physical_chars > _rl_screenwidth &&
wrap_offset != prompt_invis_chars_first_line &&
_rl_last_c_pos == out &&
#endif
/* Since the new first line is now visible, save its length. */
if (linenum == 0)
@@ -1035,11 +1078,14 @@ rl_redisplay ()
if (_rl_term_cr)
tputs (_rl_term_cr, 1, _rl_output_character_function);
#endif
if (modmark)
_rl_output_some_chars ("*", 1);
_rl_output_some_chars (local_prompt, nleft);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset;
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset + modmark;
else
_rl_last_c_pos = nleft;
_rl_last_c_pos = nleft + modmark;
}
/* Where on that line? And where does that line start
@@ -1064,7 +1110,7 @@ rl_redisplay ()
tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
else
tx = nleft;
if (_rl_last_c_pos > tx)
if (tx >= 0 && _rl_last_c_pos > tx)
{
_rl_backspace (_rl_last_c_pos - tx); /* XXX */
_rl_last_c_pos = tx;
@@ -1189,6 +1235,8 @@ rl_redisplay ()
else
visible_wrap_offset = wrap_offset;
}
_rl_release_sigint ();
}
/* PWP: update_line() is based on finding the middle difference of each
@@ -1213,7 +1261,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
int current_line, omax, nmax, inv_botlin;
{
register char *ofd, *ols, *oe, *nfd, *nls, *ne;
int temp, lendiff, wsatend, od, nd, twidth;
int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
int current_invis_chars;
int col_lendiff, col_temp;
#if defined (HANDLE_MULTIBYTE)
@@ -1229,7 +1277,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
temp = _rl_last_c_pos;
else
temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
&& _rl_last_v_pos == current_line - 1)
{
@@ -1309,7 +1357,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
/* See if the old line is a subset of the new line, so that the
only change is adding characters. */
temp = (omax < nmax) ? omax : nmax;
if (memcmp (old, new, temp) == 0)
if (memcmp (old, new, temp) == 0) /* adding at the end */
{
ofd = old + temp;
nfd = new + temp;
@@ -1462,18 +1510,22 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
#else
tputs (_rl_term_cr, 1, _rl_output_character_function);
#endif
if (modmark)
_rl_output_some_chars ("*", 1);
_rl_output_some_chars (local_prompt, lendiff);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
/* We take wrap_offset into account here so we can pass correct
information to _rl_move_cursor_relative. */
_rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset;
_rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset + modmark;
cpos_adjusted = 1;
}
else
_rl_last_c_pos = lendiff;
_rl_last_c_pos = lendiff + modmark;
}
o_cpos = _rl_last_c_pos;
/* When this function returns, _rl_last_c_pos is correct, and an absolute
cursor postion in multibyte mode, but a buffer index when not in a
multibyte locale. */
@@ -1483,7 +1535,9 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
/* We need to indicate that the cursor position is correct in the presence of
invisible characters in the prompt string. Let's see if setting this when
we make sure we're at the end of the drawn prompt string works. */
if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_last_c_pos == prompt_physical_chars)
if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
(_rl_last_c_pos > 0 || o_cpos > 0) &&
_rl_last_c_pos == prompt_physical_chars)
cpos_adjusted = 1;
#endif
#endif
@@ -1527,11 +1581,31 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
{
/* Non-zero if we're increasing the number of lines. */
int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
/* If col_lendiff is > 0, implying that the new string takes up more
screen real estate than the old, but lendiff is < 0, meaning that it
takes fewer bytes, we need to just output the characters starting
from the first difference. These will overwrite what is on the
display, so there's no reason to do a smart update. This can really
only happen in a multibyte environment. */
if (lendiff < 0)
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += _rl_col_width (nfd, 0, temp);
/* If nfd begins before any invisible characters in the prompt,
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
}
return;
}
/* Sometimes it is cheaper to print the characters rather than
use the terminal's capabilities. If we're growing the number
of lines, make sure we actually cause the new line to wrap
around on auto-wrapping terminals. */
if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
{
/* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
_rl_horizontal_scroll_mode == 1, inserting the characters with
@@ -1554,11 +1628,16 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
}
else
{
/* We have horizontal scrolling and we are not inserting at
the end. We have invisible characters in this line. This
is a dumb update. */
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += col_temp;
/* If nfd begins before any invisible characters in the prompt,
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
}
return;
}
/* Copy (new) chars to screen from first diff to last match. */
@@ -1575,6 +1654,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
else
twidth = temp - lendiff;
_rl_last_c_pos += twidth;
/* If nfd begins before any invisible characters in the prompt,
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
}
}
}
else
@@ -1607,9 +1694,20 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
temp = nls - nfd;
if (temp > 0)
{
/* If nfd begins at the prompt, or before the invisible
characters in the prompt, we need to adjust _rl_last_c_pos
in a multibyte locale to account for the wrap offset and
set cpos_adjusted accordingly. */
_rl_output_some_chars (nfd, temp);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_last_c_pos += _rl_col_width (nfd, 0, temp);
{
_rl_last_c_pos += _rl_col_width (nfd, 0, temp);
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
}
}
else
_rl_last_c_pos += temp;
}
@@ -1619,8 +1717,20 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
{
if (temp > 0)
{
/* If nfd begins at the prompt, or before the invisible
characters in the prompt, we need to adjust _rl_last_c_pos
in a multibyte locale to account for the wrap offset and
set cpos_adjusted accordingly. */
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += col_temp; /* XXX */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
}
}
}
lendiff = (oe - old) - (ne - new);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
@@ -1628,7 +1738,16 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
else
col_lendiff = lendiff;
#if 0
if (col_lendiff)
#else
/* If we've already printed over the entire width of the screen,
including the old material, then col_lendiff doesn't matter and
space_to_eol will insert too many spaces. XXX - maybe we should
adjust col_lendiff based on the difference between _rl_last_c_pos
and _rl_screenwidth */
if (col_lendiff && (_rl_last_c_pos < _rl_screenwidth))
#endif
{
if (_rl_term_autowrap && current_line < inv_botlin)
space_to_eol (col_lendiff);
@@ -1745,7 +1864,7 @@ _rl_move_cursor_relative (new, data)
int woff; /* number of invisible chars on current line */
int cpos, dpos; /* current and desired cursor positions */
woff = W_OFFSET (_rl_last_v_pos, wrap_offset);
woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
cpos = _rl_last_c_pos;
#if defined (HANDLE_MULTIBYTE)
/* If we have multibyte characters, NEW is indexed by the buffer point in
@@ -1756,7 +1875,14 @@ _rl_move_cursor_relative (new, data)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
dpos = _rl_col_width (data, 0, new);
if (dpos > prompt_last_invisible) /* XXX - don't use woff here */
/* Use NEW when comparing against the last invisible character in the
prompt string, since they're both buffer indices and DPOS is a
desired display position. */
if ((new > prompt_last_invisible) || /* XXX - don't use woff here */
(prompt_physical_chars > _rl_screenwidth &&
_rl_last_v_pos == prompt_last_screen_line &&
wrap_offset != woff &&
new > (prompt_last_invisible-_rl_screenwidth-wrap_offset)))
{
dpos -= woff;
/* Since this will be assigned to _rl_last_c_pos at the end (more
@@ -2353,7 +2479,7 @@ _rl_redisplay_after_sigwinch ()
void
_rl_clean_up_for_exit ()
{
if (readline_echoing_p)
if (_rl_echoing_p)
{
_rl_move_vert (_rl_vis_botlin);
_rl_vis_botlin = 0;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+75 -37
View File
@@ -1,24 +1,24 @@
/* display.c -- readline redisplay facility. */
/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
/* Copyright (C) 1987-2008 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
@@ -496,7 +496,7 @@ rl_redisplay ()
register int in, out, c, linenum, cursor_linenum;
register char *line;
int inv_botlin, lb_botlin, lb_linenum, o_cpos;
int newlines, lpos, temp, n0, num;
int newlines, lpos, temp, n0, num, prompt_lines_estimate;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc;
@@ -653,11 +653,7 @@ rl_redisplay ()
/* inv_lbreaks[i] is where line i starts in the buffer. */
inv_lbreaks[newlines = 0] = 0;
#if 0
lpos = out - wrap_offset;
#else
lpos = prompt_physical_chars + modmark;
#endif
#if defined (HANDLE_MULTIBYTE)
memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
@@ -667,7 +663,10 @@ rl_redisplay ()
/* prompt_invis_chars_first_line is the number of invisible characters in
the first physical line of the prompt.
wrap_offset - prompt_invis_chars_first_line is the number of invis
chars on the second line. */
chars on the second (or, more generally, last) line. */
/* This is zero-based, used to set the newlines */
prompt_lines_estimate = lpos / _rl_screenwidth;
/* what if lpos is already >= _rl_screenwidth before we start drawing the
contents of the command line? */
@@ -705,11 +704,11 @@ rl_redisplay ()
temp = ((newlines + 1) * _rl_screenwidth);
/* Now account for invisible characters in the current line. */
/* XXX - this assumes that all of the invisible characters are before
the line wrap. */
/* XXX - this assumes that the invisible characters may be split, but only
between the first and the last lines. */
temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
: ((newlines == 1) ? wrap_offset : 0))
: ((newlines == 0) ? wrap_offset :0));
: ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line))
: ((newlines == 0) ? wrap_offset : 0));
inv_lbreaks[++newlines] = temp;
#if defined (HANDLE_MULTIBYTE)
@@ -972,7 +971,7 @@ rl_redisplay ()
take invisible characters into account, since _rl_last_c_pos
is an absolute cursor position in a multibyte locale. See
if compensating here is the right thing, or if we have to
change update_line itself. There is one case in which
change update_line itself. There are several cases in which
update_line adjusts _rl_last_c_pos itself (so it can pass
_rl_move_cursor_relative accurate values); it communicates
this back by setting cpos_adjusted. If we assume that
@@ -986,16 +985,11 @@ rl_redisplay ()
_rl_last_c_pos > wrap_offset &&
o_cpos < prompt_last_invisible)
_rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
(MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
cpos_adjusted == 0 &&
_rl_last_c_pos != o_cpos &&
#if 0
_rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - (wrap_offset-prompt_invis_chars_first_line)))
#else
_rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
#endif
_rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
_rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
/* If this is the line with the prompt, we might need to
@@ -1617,12 +1611,30 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
_rl_horizontal_scroll_mode == 1, inserting the characters with
_rl_term_IC or _rl_term_ic will screw up the screen because of the
invisible characters. We need to just draw them. */
if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
lendiff <= prompt_visible_length || !current_invis_chars))
/* The same thing happens if we're trying to draw before the last
invisible character in the prompt string or we're increasing the
number of invisible characters in the line and we're not drawing
the entire prompt string. */
if (*ols && ((_rl_horizontal_scroll_mode &&
_rl_last_c_pos == 0 &&
lendiff > prompt_visible_length &&
current_invis_chars > 0) == 0) &&
(((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
current_line == 0 && wrap_offset &&
((nfd - new) <= prompt_last_invisible) &&
(col_lendiff < prompt_visible_length)) == 0) &&
(visible_wrap_offset >= current_invis_chars))
{
insert_some_chars (nfd, lendiff, col_lendiff);
_rl_last_c_pos += col_lendiff;
}
#if 1
else if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && _rl_last_c_pos == 0 && wrap_offset && (nfd-new) <= prompt_last_invisible && col_lendiff < prompt_visible_length && visible_wrap_offset >= current_invis_chars)
{
_rl_output_some_chars (nfd, lendiff);
_rl_last_c_pos += col_lendiff;
}
#endif
else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
{
/* At the end of a line the characters do not have to
@@ -1636,10 +1648,10 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += col_temp;
/* If nfd begins before any invisible characters in the prompt,
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
/* If nfd begins before the last invisible character in the
prompt, adjust _rl_last_c_pos to account for wrap_offset
and set cpos_adjusted to let the caller know. */
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
@@ -1660,6 +1672,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
else
twidth = temp - lendiff;
_rl_last_c_pos += twidth;
/* If nfd begins before the last invisible character in the
prompt, adjust _rl_last_c_pos to account for wrap_offset
and set cpos_adjusted to let the caller know. */
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
}
}
}
else
@@ -1671,6 +1691,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
char in the current line (which implies we just output some invisible
characters) we need to adjust _rl_last_c_pos, since it represents
a physical character position. */
if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
current_line == prompt_last_screen_line && wrap_offset &&
wrap_offset != prompt_invis_chars_first_line &&
((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
{
_rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
cpos_adjusted = 1;
}
}
}
else /* Delete characters from line. */
@@ -1736,7 +1764,16 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
else
col_lendiff = lendiff;
#if 0
if (col_lendiff)
#else
/* If we've already printed over the entire width of the screen,
including the old material, then col_lendiff doesn't matter and
space_to_eol will insert too many spaces. XXX - maybe we should
adjust col_lendiff based on the difference between _rl_last_c_pos
and _rl_screenwidth */
if (col_lendiff && (_rl_last_c_pos < _rl_screenwidth))
#endif
{
if (_rl_term_autowrap && current_line < inv_botlin)
space_to_eol (col_lendiff);
@@ -1871,7 +1908,8 @@ _rl_move_cursor_relative (new, data)
(prompt_physical_chars > _rl_screenwidth &&
_rl_last_v_pos == prompt_last_screen_line &&
wrap_offset != woff &&
new > (prompt_last_invisible-_rl_screenwidth-wrap_offset)))
new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset)))
/* XXX last comparison might need to be >= */
{
dpos -= woff;
/* Since this will be assigned to _rl_last_c_pos at the end (more
+1 -1
View File
@@ -1434,7 +1434,7 @@ call @code{rl_resize_terminal()} or @code{rl_set_screen_size()} to force
Readline to update its idea of the terminal size when a @code{SIGWINCH}
is received.
@deftypefun rl_echo_signal_char (int sig)
@deftypefun void rl_echo_signal_char (int sig)
If an application wishes to install its own signal handlers, but still
have readline display characters that generate signals, calling this
function with @var{sig} set to @code{SIGINT}, @code{SIGQUIT}, or
+7
View File
@@ -1434,6 +1434,13 @@ call @code{rl_resize_terminal()} or @code{rl_set_screen_size()} to force
Readline to update its idea of the terminal size when a @code{SIGWINCH}
is received.
@deftypefun rl_echo_signal_char (int sig)
If an application wishes to install its own signal handlers, but still
have readline display characters that generate signals, calling this
function with @var{sig} set to @code{SIGINT}, @code{SIGQUIT}, or
@code{SIGTSTP} will display the character generating that signal.
@end deftypefun
@deftypefun void rl_resize_terminal (void)
Update Readline's internal screen size by reading values from the kernel.
@end deftypefun
+2
View File
@@ -1874,6 +1874,7 @@ read_secondary_line (remove_quoted_newline)
if (SHOULD_PROMPT())
prompt_again ();
ret = read_a_line (remove_quoted_newline);
#if defined (HISTORY)
if (remember_on_history && (parser_state & PST_HEREDOC))
{
/* To make adding the the here-document body right, we need to rely
@@ -1885,6 +1886,7 @@ read_secondary_line (remove_quoted_newline)
current_command_line_count++;
maybe_add_history (ret);
}
#endif /* HISTORY */
return ret;
}
+20
View File
@@ -6887,6 +6887,16 @@ param_expand (string, sindex, quoted, expanded_something,
case '*': /* `$*' */
list = list_rest_of_args ();
if (list == 0 && unbound_vars_is_error)
{
uerror[0] = '$';
uerror[1] = '*';
uerror[2] = '\0';
err_unboundvar (uerror);
last_command_exit_value = EXECUTION_FAILURE;
return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
}
/* If there are no command-line arguments, this should just
disappear if there are other characters in the expansion,
even if it's quoted. */
@@ -6939,6 +6949,16 @@ param_expand (string, sindex, quoted, expanded_something,
case '@': /* `$@' */
list = list_rest_of_args ();
if (list == 0 && unbound_vars_is_error)
{
uerror[0] = '$';
uerror[1] = '@';
uerror[2] = '\0';
err_unboundvar (uerror);
last_command_exit_value = EXECUTION_FAILURE;
return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
}
/* We want to flag the fact that we saw this. We can't turn
off quoting entirely, because other characters in the
string might need it (consider "\"$@\""), but we need some
+10 -1
View File
@@ -3943,7 +3943,6 @@ match_pattern (string, pat, mtype, sp, ep)
free (wstring);
free (indices);
itrace("match_pattern: pat = `%s' string = `%s' -> %d", pat, string, ret);
return (ret);
}
else
@@ -6888,6 +6887,16 @@ param_expand (string, sindex, quoted, expanded_something,
case '*': /* `$*' */
list = list_rest_of_args ();
if (list == 0 && unbound_vars_is_error)
{
uerror[0] = '$';
uerror[1] = '*';
uerror[2] = '\0';
err_unboundvar (uerror);
last_command_exit_value = EXECUTION_FAILURE;
return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
}
/* If there are no command-line arguments, this should just
disappear if there are other characters in the expansion,
even if it's quoted. */