lib/readline/{input.c,rlprivate.h}
- fixes for compiling on w64-mingw32
+
+ 10/5
+ ----
+parse.y
+ - xparse_dolparen: save and restore extended_glob using local_extglob
+ in the same way that parse_comsub does. Fixes compat issue reported in
+ https://bugs.gentoo.org/873931 and by Kerin Millar <kfm@plushkava.net>
+
+ 10/6
+ ----
+subst.c
+ - extract_dollar_brace_string: keep a stack of dolbrace_state values
+ to handle nested expansions. Report from
+ Antoine <bug-bash@glitchimini.net>
+
+ 10/7
+ ----
+builtins/{shopt.def,common.h}
+ - extglob_flag: new variable to hold the state of the `extglob' option;
+ initialized to EXTGLOB_DEFAULT like extended_glob
+ - shopt_set_extglob: new function to set extended_glob to the right
+ value for the rest of the shell
+
+parse.y
+ - reset_parser: set extended_glob to extglob_flag, which is only
+ changed by shopt, remove global_extglob
+ - parse_comsub,parse_cond_command,xparse_dolparen: no longer use
+ global_extglob
+
+execute_cmd.c
+ - execute_cond_node: reset extended_glob to the value of extglob_flag,
+ since we're executing a command here
tests/extglob5.sub f
tests/extglob6.sub f
tests/extglob7.sub f
+tests/extglob8.sub f
tests/func.tests f
tests/func.right f
tests/func1.sub f
extern int expand_once_flag;
#endif
+#if defined (EXTENDED_GLOB)
+extern int extglob_flag;
+#endif
+
/* variables from source.def */
extern int source_searches_cwd;
extern int source_uses_path;
This file is shopt.def, from which is created shopt.c.
It implements the Bash `shopt' builtin.
-Copyright (C) 1994-2021 Free Software Foundation, Inc.
+Copyright (C) 1994-2022 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
static int set_assoc_expand PARAMS((char *, int));
#endif
+#if defined (EXTENDED_GLOB)
+int extglob_flag = EXTGLOB_DEFAULT;
+static int shopt_set_extglob PARAMS((char *, int));
+#endif
+
static int shopt_set_debug_mode PARAMS((char *, int));
static int shopt_login_shell;
{ "extdebug", &debugging_mode, shopt_set_debug_mode },
#endif
#if defined (EXTENDED_GLOB)
- { "extglob", &extended_glob, (shopt_set_func_t *)NULL },
+ { "extglob", &extglob_flag, shopt_set_extglob },
#endif
{ "extquote", &extended_quote, (shopt_set_func_t *)NULL },
{ "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
#endif
#if defined (EXTENDED_GLOB)
- extended_glob = EXTGLOB_DEFAULT;
+ extended_glob = extglob_flag = EXTGLOB_DEFAULT;
#endif
#if defined (ARRAY_VARS)
return (0);
}
+#if defined (EXTENDED_GLOB)
+static int
+shopt_set_extglob (option_name, mode)
+ char *option_name;
+ int mode;
+{
+ extended_glob = extglob_flag;
+ return 0;
+}
+#endif
+
#if defined (READLINE)
static int
shopt_enable_hostname_completion (option_name, mode)
char *option_name;
int mode;
+
+
{
return (enable_hostname_completion (mode));
}
else
#endif /* COND_REGEXP */
{
- int oe;
- oe = extended_glob;
extended_glob = 1;
result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE)
? EXECUTION_SUCCESS
: EXECUTION_FAILURE;
- extended_glob = oe;
+ extended_glob = extglob_flag;
}
if (arg1 != nullstr)
free (arg1);
lspec = "";
ret = setlocale (LC_CTYPE, lspec); /* ok, since it does not change locale */
if (ret == 0 || *ret == 0)
- ret = setlocale (LC_CTYPE, NULL);
+ ret = setlocale (LC_CTYPE, (char *)NULL);
if (ret == 0 || *ret == 0)
ret = RL_DEFAULT_LOCALE;
#else
} while (0)
#if defined (EXTENDED_GLOB)
-extern int extended_glob;
+extern int extended_glob, extglob_flag;
#endif
#if defined (TRANSLATABLE_STRINGS)
/* The token read prior to token_before_that. */
static int two_tokens_ago;
-static int global_extglob;
-
/* The line number in a script where the word in a `case WORD', `select WORD'
or `for WORD' begins. This is a nested command maximum, since the array
index is decremented after a case, select, or for command is parsed. */
#if defined (EXTENDED_GLOB)
/* Reset to global value of extended glob */
if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
- extended_glob = global_extglob;
+ extended_glob = extglob_flag;
#endif
parser_state = 0;
expand_aliases = posixly_correct != 0;
#if defined (EXTENDED_GLOB)
/* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a
- conditional command and have already set global_extglob appropriately. */
+ conditional command and have already set extended_glob appropriately. */
if (shell_compatibility_level <= 51 && was_extpat == 0)
{
- local_extglob = global_extglob = extended_glob;
+ local_extglob = extended_glob;
extended_glob = 1;
}
#endif
{
sh_parser_state_t ps;
sh_input_line_state_t ls;
- int orig_ind, nc, sflags, start_lineno;
+ int orig_ind, nc, sflags, start_lineno, local_extglob;
char *ret, *ep, *ostring;
/*debug_parser(1);*/
old value will be restored by restore_parser_state(). */
expand_aliases = 0;
#if defined (EXTENDED_GLOB)
- global_extglob = extended_glob; /* for reset_parser() */
+ local_extglob = extended_glob;
#endif
token_to_read = DOLPAREN; /* let's trick the parser */
restore_input_line_state (&ls);
restore_parser_state (&ps);
+#if defined (EXTENDED_GLOB)
+ extended_glob = local_extglob;
+#endif
token_to_read = 0;
/* If parse_string returns < 0, we need to jump to top level with the
}
/* rhs */
+#if defined (EXTENDED_GLOB)
local_extglob = extended_glob;
if (parser_state & PST_EXTPAT)
extended_glob = 1;
+#endif
tok = read_token (READ);
+#if defined (EXTENDED_GLOB)
if (parser_state & PST_EXTPAT)
extended_glob = local_extglob;
+#endif
parser_state &= ~(PST_REGEXP|PST_EXTPAT);
if (tok == WORD)
{
COND_COM *cexp;
- global_extglob = extended_glob;
cexp = cond_expr ();
return (make_cond_command (cexp));
}
/* patchlevel.h -- current bash patch level */
-/* Copyright (C) 2001-2021 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2022 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 0
+#define PATCHLEVEL 2
#endif /* _PATCHLEVEL_H_ */
return (result);
}
+#define PARAMEXPNEST_MAX 32 // for now
+static int dbstate[PARAMEXPNEST_MAX];
+
/* Extract a parameter expansion expression within ${ and } from STRING.
Obey the Posix.2 rules for finding the ending `}': count braces while
skipping over enclosed quoted strings and command substitutions.
if (quoted == Q_HERE_DOCUMENT && dolbrace_state == DOLBRACE_QUOTE && (flags & SX_NOALLOC) == 0)
return (extract_heredoc_dolbrace_string (string, sindex, quoted, flags));
+ dbstate[0] = dolbrace_state;
+
pass_character = 0;
nesting_level = 1;
slen = strlen (string + *sindex) + *sindex;
if (string[i] == '$' && string[i+1] == LBRACE)
{
+ if (nesting_level < PARAMEXPNEST_MAX)
+ dbstate[nesting_level] = dolbrace_state;
nesting_level++;
i += 2;
if (dolbrace_state == DOLBRACE_QUOTE || dolbrace_state == DOLBRACE_WORD)
nesting_level--;
if (nesting_level == 0)
break;
+ dolbrace_state = (nesting_level < PARAMEXPNEST_MAX) ? dbstate[nesting_level] : dbstate[0]; /* Guess using initial state */
i++;
continue;
}
? . .. .a .foo
*
bar
+extglob off
+x
+extglob off
+extglob off
+extglob off
+extglob off
+extglob off
${THIS_SH} ./extglob5.sub
${THIS_SH} ./extglob6.sub
${THIS_SH} ./extglob7.sub
+${THIS_SH} ./extglob8.sub
exit 0
--- /dev/null
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# extglob option interaction with other parts of the shell that force
+# extended_glob on; only an issue in compatibility mode
+
+shopt -u extglob
+
+BASH_COMPAT=50
+shopt extglob
+
+echo $(echo $(echo $(echo $(echo $(echo x) ) ) ) )
+shopt extglob
+
+shopt -u extglob
+
+[[ '' = $(shopt extglob >&2) ]]
+shopt extglob
+
+shopt -u extglob
+
+[[ foo = $(: $(shopt extglob >&2)) ]]
+shopt extglob
PATH=$PATH:`pwd`
export PATH
-${THIS_SH} ./extglob.tests | grep -v '^expect' > ${BASH_TSTOUT}
+${THIS_SH} ./extglob.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
diff ${BASH_TSTOUT} extglob.right && rm -f ${BASH_TSTOUT}