parse.y,make_cmd.c
- read_a_line,make_here_document: if we're using shell_getc to read
the body of a here-document, let it manage line_number
+
+ 12/8
+ ----
+bashline.c
+ - bash_dequote_filename: fix an off-by-one error that didn't remove a
+ closing single quote in a filename if it was backslash-escaped.
+ Report by Ole Tange <ota@prosa.dk>, fix from Grisha Levit <grishalevit@gmail.com>
+
+lib/readline/terminal.c
+ - _rl_check_ansi_terminal: check whether or not rl_terminal_name
+ appears to be an ANSI/ECMA-48 terminal. Check some common terminal
+ types and then check whether some common terminal capabilities
+ (ce, nd, ho, up) begin with CSI (ESC-[) and then have a correct
+ subsequent character
+ - _rl_term_isansi: new variable, holds readline's idea about whether
+ the value of rl_terminal_name is an ANSI/ECMA-48 terminal. Initialized
+ to RL_ANSI_TERM_DEFAULT; set to the result of _rl_check_ansi_terminal
+ if initialized to 0 and on a `non-dumb' terminal
+ From an idea by John Tsiombikas <nuclear@mutantstargoat.com> in 11/2023
+
+lib/readline/rlconf.h
+ - RL_ANSI_TERM_DEFAULT: define to 1 (yes) or 0 (no) to tell readline
+ whether or not to assume it's running on an ANSI/ECMA-48 terminal.
+ The default is 1 (yes)
+
+ 12/11
+ -----
+print_cmd.c
+ - make_command_string_internal: when printing a coproc, print the
+ coproc name only if the coproc command is not a simple command.
+ Report from Albert Akchurin <ackbeat@gmail.com>
ret = (char *)xmalloc (l + 1);
for (quoted = quote_char, p = text, r = ret; p && *p; p++)
{
- /* Allow backslash-escaped characters to pass through unscathed. */
- if (*p == '\\')
+ /* Allow backslash-escaped characters to pass through unscathed. Backslashes
+ aren't special in single quotes. */
+ if (quoted != '\'' && *p == '\\')
{
- /* Backslashes are preserved within single quotes. */
- if (quoted == '\'')
- *r++ = *p;
/* Backslashes are preserved within double quotes unless the
character is one that is defined to be escaped */
- else if (quoted == '"' && ((sh_syntaxtab[(unsigned char)p[1]] & CBSDQUOTE) == 0))
+ if (quoted == '"' && ((sh_syntaxtab[(unsigned char)p[1]] & CBSDQUOTE) == 0))
*r++ = *p;
*r++ = *++p;
/* terminal.c -- controlling the terminal with termcap. */
-/* Copyright (C) 1996-2022 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2023 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.
char *_rl_term_clreol;
char *_rl_term_clrpag;
char *_rl_term_clrscroll;
+char *_rl_term_ho;
char *_rl_term_cr;
char *_rl_term_backspace;
char *_rl_term_goto;
/* Non-zero means the user wants to enable a meta key. */
int _rl_enable_meta = 1;
+/* Non-zero means this is an ANSI-compatible terminal; assume it is. */
+int _rl_term_isansi = RL_ANSI_TERM_DEFAULT;
+
#if defined (__EMX__)
static void
_emx_get_screensize (int *swp, int *shp)
{ "cr", &_rl_term_cr },
{ "dc", &_rl_term_dc },
{ "ei", &_rl_term_ei },
+ { "ho", &_rl_term_ho },
{ "ic", &_rl_term_ic },
{ "im", &_rl_term_im },
{ "kD", &_rl_term_kD }, /* delete */
tcap_initialized = 1;
}
+struct _term_name {
+ const char * const name;
+ size_t len;
+};
+
+/* Non-exhaustive list of ANSI/ECMA terminals. */
+static const struct _term_name ansiterms[] =
+{
+ { "xterm", 5 },
+ { "rxvt", 4 },
+ { "eterm", 5 },
+ { "screen", 6 },
+ { "tmux", 4 },
+ { "vt100", 5 },
+ { "vt102", 5 },
+ { "vt220", 5 },
+ { "vt320", 5 },
+ { "ansi", 4 },
+ { "scoansi", 7 },
+ { "cygwin", 6 },
+ { "linux", 5 },
+ { "konsole", 7 },
+ { "bvterm", 6 },
+ { 0, 0 }
+};
+
+static inline int
+iscsi (const char *s)
+{
+ return ((s[0] == ESC && s[1] == '[') ? 2
+ : ((unsigned char)s[0] == 0x9b) ? 1 : 0);
+}
+
+static int
+_rl_check_ansi_terminal (const char *terminal_name)
+{
+ int i;
+ size_t len;
+
+ for (i = 0; ansiterms[i].name; i++)
+ if (STREQN (terminal_name, ansiterms[i].name, ansiterms[i].len))
+ return 1;
+
+ if (_rl_term_clreol == 0 || _rl_term_forward_char == 0 ||
+ _rl_term_ho == 0 || _rl_term_up == 0)
+ return 0;
+
+ /* check some common capabilities */
+ if (((len = iscsi (_rl_term_clreol)) && _rl_term_clreol[len] == 'K') && /* ce */
+ ((len = iscsi (_rl_term_forward_char)) && _rl_term_forward_char[len] == 'C') && /* nd */
+ ((len = iscsi (_rl_term_ho)) && _rl_term_ho[len] == 'H') && /* ho */
+ ((len = iscsi (_rl_term_up)) && _rl_term_up[len] == 'A')) /* up */
+ return 1;
+
+ return 0;
+}
+
int
_rl_init_terminal_io (const char *terminal_name)
{
if (term == 0)
term = "dumb";
- dumbterm = STREQ (term, "dumb");
+ _rl_term_isansi = RL_ANSI_TERM_DEFAULT;
+ dumbterm = STREQ (term, "dumb") || STREQ (term, "vt52") || STREQ (term, "adm3a");
+ if (dumbterm)
+ _rl_term_isansi = 0;
reset_region_colors = 1;
_rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0;
_rl_term_cr = "\r";
_rl_term_backspace = (char *)NULL;
+ _rl_term_ho = (char *)NULL;
_rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL;
_rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL;
_rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL;
/* Everything below here is used by the redisplay code (tputs). */
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
_rl_term_cr = "\r";
+ _rl_term_ho = (char *)NULL;
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
_rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
_rl_term_so = _rl_term_se = (char *)NULL;
_rl_terminal_can_insert = term_has_meta = 0;
+ _rl_term_isansi = 0; /* not an ANSI terminal */
+
/* Assume generic unknown terminal can't handle the enable/disable
escape sequences */
_rl_term_BD = _rl_term_BE = _rl_term_PE = _rl_term_PS = (char *)NULL;
bind_termcap_arrow_keys (vi_insertion_keymap);
#endif /* VI_MODE */
+ if (dumbterm == 0 && _rl_term_isansi == 0)
+ _rl_term_isansi = _rl_check_ansi_terminal (terminal_name);
+
/* There's no way to determine whether or not a given terminal supports
- bracketed paste mode, so we assume a terminal named "dumb" does not. */
- if (dumbterm)
+ bracketed paste mode, so we assume a non-ANSI terminal (as best as we
+ can determine) does not. */
+ if (_rl_term_isansi == 0)
_rl_enable_bracketed_paste = _rl_enable_active_region = 0;
if (reset_region_colors)