builtins/colon.def
- add the right includes so colon_builtin and false_builtin can take
a WORD_LIST * argument like the prototype says they do
+
+ 7/29
+ ----
+lib/readline/kill.c
+ - _rl_read_bracketed_paste_prefix: read the character prefix that
+ indicates a pasted string in bracketed paste mode. If we don't
+ read a valid bracketed paste prefix, push the other characters
+ back onto the input stack with _rl_unget_char
+ - _rl_bracketed_read_key: handle reading pasted input when bracketed
+ paste mode is enabled, including reading multibyte characters; push
+ anything beyond a single byte back onto the input stack where it
+ can be read by _rl_read_mbstring or subsequent input
+ - _rl_bracketed_read_mbstring: handle reading pasted input in bracketed
+ paste mode, using _rl_bracketed_read_key to get the pasted text,
+ then call _rl_read_mbstring to get the rest of any multibyte char
+
+
+lib/readline/vi_mode.c
+ - _rl_vi_callback_getchar: call _rl_bracketed_read_mbstring to handle
+ bracketed paste mode input. Fixes issue with vi-change-char reported
+ by <vampyrebat@gmail.com>
+ - rl_vi_domove_getchar: just call _rl_bracketed_read_key and return
+ the result -- we're not interested in multibyte-character input here
+ yet
+ - rl_vi_replace: bind BRACK_PASTE_PREF key sequence if bracketed paste
+ mode has been enabled
+ - _rl_overstrike_bracketed_paste: key binding function for the bracketed
+ paste prefix key sequence in overwrite mode; reads the pasted text
+ and uses rl_vi_overstrike to add each character in overwrite mode.
+ Fixes issue reported by <vampyrebat@gmail.com>
+
+ 7/31
+ ----
+lib/readline/input.c
+ - _rl_read_mbchar: the first time through the loop (mb_len == 0), call
+ _rl_bracketed_read_key to process any bracketed paste characters
+
+lib/readline/text.c
+ - _rl_char_search: use _rl_bracketed_read_key in the non-multibyte
+ character case
+
+lib/readline/misc.c
+ - _rl_arg_dispatch: use _rl_bracketed_read_key in place of rl_read_key
+
+subst.c
+ - list_string: if string_extract_verbatim returns something, just make
+ a WORD_DESC * and add current_word directly to it, noting that we
+ don't want to free current_word (free_word = 0)
+ - string_extract_verbatim: if the separator string is the empty
+ string, don't bother with the loop -- just savestring the string,
+ update *sindex, and return the copy
+ - read_comsub: make the string we use to save the output from the pipe
+ 512 bytes instead of 128 (same size as the buffer used to read from
+ the pipe); fewer calls to xrealloc in the worst case
+ - parameter_brace_expand_length: optimize the common case (non-dynamic
+ scalar variable without `set -u' in effect) and just call MB_STRLEN
+ on the variable value in that case. From a report from
+ Alkis Georgopoulos <alkisg@gmail.com>
ac_cv_c_long_long=yes
else
AC_TRY_RUN([
-#include "bashansi.h"
+#include <stdlib.h>
int
main()
{
ac_cv_c_long_double=yes
else
AC_TRY_RUN([
-#include "bashansi.h"
+#include <stdlib.h>
int
main()
{
#else
typedef int (*_bashfunc)();
#endif
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
_bashfunc pf;
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
#ifndef UNDER_SYS_SIGLIST_DECLARED
extern char *_sys_siglist[];
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
#if !HAVE_DECL_SYS_SIGLIST
extern char *sys_siglist[];
#endif
[AC_TRY_RUN([
#include <sys/types.h>
#include <fcntl.h>
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
int fd1, fd2, fl;
# include <ndir.h>
# endif
#endif /* HAVE_DIRENT_H */
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
DIR *dir;
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
#ifdef HAVE_QUAD_T
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
#ifndef __STDC__
# ifndef const
# define const
#include <sys/types.h>
#include <signal.h>
#include <setjmp.h>
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
[AC_TRY_RUN([
#include <stdio.h>
#include <string.h>
-#include "bashansi.h"
+#include <stdlib.h>
int
main()
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
# ifdef GETPGRP_VOID
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
typedef RETSIGTYPE sigfunc();
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
/* Add more tests in here as appropriate. */
main()
[AC_TRY_RUN([
#include <sys/types.h>
#include <signal.h>
-#include "bashansi.h"
+#include <stdlib.h>
#ifndef NSIG
# define NSIG 64
[AC_TRY_RUN([
#include <stdio.h>
#include <readline/readline.h>
-#include "bashansi.h"
+#include <stdlib.h>
extern int rl_gnu_readline_p;
AC_CACHE_CHECK([for standard-conformant snprintf], [bash_cv_func_snprintf],
[AC_TRY_RUN([
#include <stdio.h>
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
#include <stdio.h>
#include <readline/readline.h>
-#include "bashansi.h"
+#include <stdlib.h>
extern int rl_gnu_readline_p;
#include <sys/types.h>
#include <fcntl.h>
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
int fd1, fd2, fl;
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
# ifdef GETPGRP_VOID
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
#if !HAVE_DECL_SYS_SIGLIST
extern char *sys_siglist[];
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
#ifndef UNDER_SYS_SIGLIST_DECLARED
extern char *_sys_siglist[];
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
#ifdef HAVE_QUAD_T
# include <ndir.h>
# endif
#endif /* HAVE_DIRENT_H */
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
DIR *dir;
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
#ifndef __STDC__
# ifndef const
# define const
#include <sys/types.h>
#include <signal.h>
#include <setjmp.h>
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
/* end confdefs.h. */
#include <stdio.h>
-#include "bashansi.h"
+#include <stdlib.h>
main()
{
#include <stdio.h>
#include <string.h>
-#include "bashansi.h"
+#include <stdlib.h>
int
main()
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
typedef RETSIGTYPE sigfunc();
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include "bashansi.h"
+#include <stdlib.h>
/* Add more tests in here as appropriate. */
main()
#include <sys/types.h>
#include <signal.h>
-#include "bashansi.h"
+#include <stdlib.h>
#ifndef NSIG
# define NSIG 64
mb_len = 0;
while (mb_len < size)
{
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ c = (mb_len == 0) ? _rl_bracketed_read_key () : rl_read_key ();
if (c < 0)
break;
rl_clear_message ();
}
+/* XXX - we could use _rl_bracketed_read_mbstring () here. */
int
_rl_search_getchar (_rl_search_cxt *cxt)
{
/* kill.c -- kill ring management. */
-/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2019 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
/* Having read the special escape sequence denoting the beginning of a
`bracketed paste' sequence, read the rest of the pasted input until the
- closing sequence and insert the pasted text as a single unit without
- interpretation. */
+ closing sequence and return the pasted text. */
char *
_rl_bracketed_text (size_t *lenp)
{
return (buf);
}
+/* Having read the special escape sequence denoting the beginning of a
+ `bracketed paste' sequence, read the rest of the pasted input until the
+ closing sequence and insert the pasted text as a single unit without
+ interpretation. */
int
rl_bracketed_paste_begin (int count, int key)
{
return (retval);
}
+int
+_rl_read_bracketed_paste_prefix (int c)
+{
+ char pbuf[BRACK_PASTE_SLEN+1], *pbpref;
+ int key, ind, j;
+
+ pbpref = BRACK_PASTE_PREF; /* XXX - debugging */
+ if (c != pbpref[0])
+ return (0);
+ pbuf[ind = 0] = c;
+ while (ind < BRACK_PASTE_SLEN-1 &&
+ (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
+ _rl_pushed_input_available () == 0 &&
+ _rl_input_queued (0))
+ {
+ key = rl_read_key (); /* XXX - for now */
+ if (key < 0)
+ break;
+ pbuf[++ind] = key;
+ if (pbuf[ind] != pbpref[ind])
+ break;
+ }
+
+ if (ind < BRACK_PASTE_SLEN-1) /* read incomplete sequence */
+ {
+ while (ind >= 0)
+ _rl_unget_char (pbuf[ind--]);
+ return (key < 0 ? key : 0);
+ }
+ return (key < 0 ? key : 1);
+}
+
+/* Get a character from wherever we read input, handling input in bracketed
+ paste mode. If we don't have or use bracketed paste mode, this can be
+ used in place of rl_read_key(). */
+int
+_rl_bracketed_read_key ()
+{
+ int c, r;
+ char *pbuf;
+ size_t pblen;
+
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ if (c < 0)
+ return -1;
+
+ /* read pasted data with bracketed-paste mode enabled. */
+ if (_rl_enable_bracketed_paste && c == ESC && (r = _rl_read_bracketed_paste_prefix (c)) == 1)
+ {
+ pbuf = _rl_bracketed_text (&pblen);
+ if (pblen == 0)
+ {
+ xfree (pbuf);
+ return 0; /* XXX */
+ }
+ c = (unsigned char)pbuf[0];
+ if (pblen > 1)
+ {
+ while (--pblen > 0)
+ _rl_unget_char ((unsigned char)pbuf[pblen]);
+ }
+ xfree (pbuf);
+ }
+
+ return c;
+}
+
+/* Get a character from wherever we read input, handling input in bracketed
+ paste mode. If we don't have or use bracketed paste mode, this can be
+ used in place of rl_read_key(). */
+int
+_rl_bracketed_read_mbstring (char *mb, int mlen)
+{
+ int c, r;
+
+ c = _rl_bracketed_read_key ();
+ if (c < 0)
+ return -1;
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ c = _rl_read_mbstring (c, mb, mlen);
+#endif
+
+ return c;
+}
+
/* A special paste command for Windows users. */
#if defined (_WIN32)
#include <windows.h>
}
else
{
- RL_SETSTATE(RL_STATE_MOREINPUT);
- key = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ key = _rl_bracketed_read_key ();
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
#define BRACK_PASTE_INIT "\033[?2004h"
#define BRACK_PASTE_FINI "\033[?2004l\r"
+extern int _rl_read_bracketed_paste_prefix PARAMS((int));
extern char *_rl_bracketed_text PARAMS((size_t *));
+extern int _rl_bracketed_read_key PARAMS((void));
+extern int _rl_bracketed_read_mbstring PARAMS((char *, int));
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
/* text.c -- text handling commands for readline. */
-/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
{
int c;
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
+ c = _rl_bracketed_read_key ();
if (c < 0)
return 1;
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
-/* Copyright (C) 1987-2018 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
static int
rl_vi_domove_getchar (_rl_vimotion_cxt *m)
{
- int c;
-
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- return c;
+ return (_rl_bracketed_read_key ());
}
#if defined (READLINE_CALLBACKS)
static int
_rl_vi_callback_getchar (char *mb, int mlen)
{
- int c;
-
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- if (c < 0)
- return -1;
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- c = _rl_read_mbstring (c, mb, mlen);
-#endif
-
- return c;
+ return (_rl_bracketed_read_mbstring (mb, mlen));
}
#if defined (READLINE_CALLBACKS)
return (0);
}
+/* Read bracketed paste mode pasted text and insert it in overwrite mode */
+static int
+rl_vi_overstrike_bracketed_paste (int count, int key)
+{
+ int r;
+ char *pbuf;
+ size_t pblen;
+
+ pbuf = _rl_bracketed_text (&pblen);
+ if (pblen == 0)
+ {
+ xfree (pbuf);
+ return 0;
+ }
+ r = pblen;
+ while (--r >= 0)
+ _rl_unget_char ((unsigned char)pbuf[r]);
+ xfree (pbuf);
+
+ while (_rl_pushed_input_available ())
+ {
+ key = rl_read_key ();
+ r = rl_vi_overstrike (1, key);
+ }
+
+ return r;
+}
+
int
rl_vi_replace (int count, int key)
{
_rl_vi_last_key_before_insert = key;
_rl_keymap = vi_replace_map;
+ if (_rl_enable_bracketed_paste)
+ rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_vi_overstrike_bracketed_paste);
+
return (0);
}
return temp;
}
+ /* This can never be called with charlist == NULL. If *charlist == NULL,
+ we can skip the loop and just return a copy of the string, updating
+ *sindex */
+ if (*charlist == 0)
+ {
+ temp = string + *sindex;
+ c = (*sindex == 0) ? slen : STRLEN (temp);
+ temp = savestring (temp);
+ *sindex += c;
+ return temp;
+ }
+
i = *sindex;
#if defined (HANDLE_MULTIBYTE)
wcharlist = 0;
token = substring (string, ts, te);
- ret = add_string_to_list (token, ret);
+ ret = add_string_to_list (token, ret); /* XXX */
free (token);
nw++;
WORD_LIST *result;
WORD_DESC *t;
char *current_word, *s;
- int sindex, sh_style_split, whitesep, xflags;
+ int sindex, sh_style_split, whitesep, xflags, free_word;
size_t slen;
if (!string || !*string)
STRING is quoted or if there are no separator characters. We use the
Posix definition of whitespace as a member of the space character
class in the current locale. */
+#if 0
if (!quoted || !separators || !*separators)
+#else
+ /* issep() requires that separators be non-null, and always returns 0 if
+ separator is the empty string, so don't bother if we get an empty string
+ for separators. We already returned NULL above if STRING is empty. */
+ if (!quoted && separators && *separators)
+#endif
{
for (s = string; *s && issep (*s) && ifs_whitespace (*s); s++);
if (current_word == 0)
break;
+ free_word = 1; /* If non-zero, we free current_word */
+
/* If we have a quoted empty string, add a quoted null argument. We
want to preserve the quoted null character iff this is a quoted
empty string; otherwise the quoted null characters are removed
/* If we have something, then add it regardless. However,
perform quoted null character removal on the current word. */
remove_quoted_nulls (current_word);
- result = add_string_to_list (current_word, result);
+
+ /* We don't want to set the word flags based on the string contents
+ here -- that's mostly for the parser -- so we just allocate a
+ WORD_DESC *, assign current_word (noting that we don't want to
+ free it), and skip all of make_word. */
+ t = alloc_word_desc ();
+ t->word = current_word;
+ result = make_word_list (t, result);
+ free_word = 0;
result->word->flags &= ~W_HASQUOTEDNULL; /* just to be sure */
if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
result->word->flags |= W_QUOTED;
result = make_word_list (t, result);
}
- free (current_word);
+ if (free_word)
+ free (current_word);
/* Note whether or not the separator is IFS whitespace, used later. */
whitesep = string[sindex] && ifs_whitesep (string[sindex]);
}
/* Add the character to ISTRING, possibly after resizing it. */
- RESIZE_MALLOCED_BUFFER (istring, istring_index, mb_cur_max+1, istring_size, DEFAULT_ARRAY_SIZE);
+ RESIZE_MALLOCED_BUFFER (istring, istring_index, mb_cur_max+1, istring_size, 512);
/* This is essentially quote_string inline */
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
char *t, *newname;
intmax_t number, arg_index;
WORD_LIST *list;
-#if defined (ARRAY_VARS)
SHELL_VAR *var;
-#endif
+
+ var = (SHELL_VAR *)NULL;
if (name[1] == '\0') /* ${#} */
number = number_of_args ();
number = MB_STRLEN (t);
}
#endif
+ /* Fast path for the common case of taking the length of a non-dynamic
+ scalar variable value. */
+ else if ((var || (var = find_variable (name + 1))) &&
+ invisible_p (var) == 0 &&
+ array_p (var) == 0 && assoc_p (var) == 0 &&
+ var->dynamic_value == 0)
+ number = value_cell (var) ? MB_STRLEN (value_cell (var)) : 0;
+ else if (var == 0 && unbound_vars_is_error == 0)
+ number = 0;
else /* ${#PS1} */
{
newname = savestring (name);