From f6571786f5a82683d566832da19614888093bfa2 Mon Sep 17 00:00:00 2001 From: Hugues Morisset Date: Mon, 27 Mar 2023 16:45:03 +0200 Subject: [PATCH] Shopt func-default-connector-and-and --- builtins/shopt.def | 35 ++++++++++++ config.h.in | 4 ++ configure.ac | 6 ++ doc/bashref.texi | 5 ++ parse.y | 7 ++- tests/func-default-connector-and-and.right | 39 +++++++++++++ tests/func-default-connector-and-and.tests | 65 ++++++++++++++++++++++ tests/run-func-default-connector-and-and | 2 + 8 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 tests/func-default-connector-and-and.right create mode 100644 tests/func-default-connector-and-and.tests create mode 100644 tests/run-func-default-connector-and-and diff --git builtins/shopt.def builtins/shopt.def index f94116ea..4987de8f 100644 --- builtins/shopt.def +++ builtins/shopt.def @@ -69,6 +69,10 @@ $END # include "../bashhist.h" #endif +#if defined (FUNC_DEFAULT_COMMAND_CONNECTOR) +# include +#endif + #define UNSETOPT 0 #define SETOPT 1 @@ -131,6 +135,10 @@ int expand_once_flag; extern int syslog_history; #endif +#if defined (FUNC_DEFAULT_COMMAND_CONNECTOR) +extern int func_default_connector; +#endif + static void shopt_error (char *); static int set_shellopts_after_change (char *, int); @@ -154,6 +162,11 @@ int extglob_flag = EXTGLOB_DEFAULT; static int shopt_set_extglob (char *, int); #endif +#if defined (FUNC_DEFAULT_COMMAND_CONNECTOR) +static int connector_and_and; +static int set_func_default_connector PARAMS((char *, int)); +#endif + int expaliases_flag = 0; static int shopt_set_expaliases (char *, int); @@ -201,6 +214,9 @@ static struct { { "compat44", &shopt_compat44, set_compatibility_level }, #if defined (READLINE) { "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL}, +#if defined (FUNC_DEFAULT_COMMAND_CONNECTOR) + { "func_default_connector_and_and", &connector_and_and, set_func_default_connector }, +#endif { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand }, { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL }, #endif @@ -430,6 +446,10 @@ reset_shopt_options (void) xpg_echo = 0; #endif /* DEFAULT_ECHO_TO_XPG */ +#if defined (FUNC_DEFAULT_COMMAND_CONNECTOR) + connector_and_and = 0; +#endif + shopt_login_shell = login_shell; } @@ -923,3 +943,18 @@ set_assoc_expand (char *option_name, int mode) return 0; } #endif + +#if defined (FUNC_DEFAULT_COMMAND_CONNECTOR) +static int +set_func_default_connector (option_name, mode) + char *option_name; + int mode; +{ + if (mode) { + func_default_connector = AND_AND; /* set commands connector to AND_AND */ + } else { + func_default_connector = ';'; /* reset to default ; */ + } + return 0; +} +#endif diff --git config.h.in config.h.in index 1681f8c3..f66e5d4f 100644 --- config.h.in +++ config.h.in @@ -106,6 +106,10 @@ the ability to time pipelines, functions, and builtins. */ #undef COMMAND_TIMING +/* Define FUNC_DEFAULT_COMMAND_CONNECTOR if you want the ability to choose + functions default command connector for newlines. */ +#undef FUNC_DEFAULT_COMMAND_CONNECTOR + /* Define ARRAY_VARS if you want ksh-style one-dimensional array variables. */ #undef ARRAY_VARS diff --git configure.ac configure.ac index a933af90..b09a843f 100644 --- configure.ac +++ configure.ac @@ -184,6 +184,7 @@ opt_function_import=yes opt_dev_fd_stat_broken=no opt_alt_array_impl=no opt_translatable_strings=yes +opt_func_default_command_connector=yes dnl modified by alternate array implementation option ARRAY_O=array.o @@ -208,6 +209,7 @@ if test $opt_minimal_config = yes; then opt_multibyte=yes opt_cond_regexp=no opt_coproc=no opt_casemod_attrs=no opt_casemod_expansions=no opt_extglob_default=no opt_translatable_strings=no + opt_func_default_command_connector=no opt_globascii_default=yes fi @@ -224,6 +226,7 @@ AC_ARG_ENABLE(cond-command, AS_HELP_STRING([--enable-cond-command], [enable the AC_ARG_ENABLE(cond-regexp, AS_HELP_STRING([--enable-cond-regexp], [enable extended regular expression matching in conditional commands]), opt_cond_regexp=$enableval) AC_ARG_ENABLE(coprocesses, AS_HELP_STRING([--enable-coprocesses], [enable coprocess support and the coproc reserved word]), opt_coproc=$enableval) AC_ARG_ENABLE(debugger, AS_HELP_STRING([--enable-debugger], [enable support for bash debugger]), opt_debugger=$enableval) +AC_ARG_ENABLE(func-default-command-connector, AC_HELP_STRING([--enable-func-default-command-connector], [enable func default command connector features]), opt_func_default_command_connector=$enableval) AC_ARG_ENABLE(dev-fd-stat-broken, AS_HELP_STRING([--enable-dev-fd-stat-broken], [enable this option if stat on /dev/fd/N and fstat on file descriptor N don't return the same results]), opt_dev_fd_stat_broken=$enableval) AC_ARG_ENABLE(direxpand-default, AS_HELP_STRING([--enable-direxpand-default], [enable the direxpand shell option by default]), opt_dircomplete_expand_default=$enableval) AC_ARG_ENABLE(directory-stack, AS_HELP_STRING([--enable-directory-stack], [enable builtins pushd/popd/dirs]), opt_dirstack=$enableval) @@ -369,6 +372,9 @@ fi if test $opt_translatable_strings = yes; then AC_DEFINE(TRANSLATABLE_STRINGS) fi +if test $opt_func_default_command_connector = yes; then +AC_DEFINE(FUNC_DEFAULT_COMMAND_CONNECTOR) +fi if test $opt_memscramble = yes; then AC_DEFINE(MEMSCRAMBLE) diff --git doc/bashref.texi doc/bashref.texi index 57a2915c..184ea852 100644 --- doc/bashref.texi +++ doc/bashref.texi @@ -5668,6 +5668,11 @@ easy re-editing of multi-line commands. This option is enabled by default, but only has an effect if command history is enabled (@pxref{Bash History Facilities}). +@item func_default_connector_and_and +If set, Bash +will use '&&' as a command separator instead +of ';' in place of newlines in functions. + @item compat31 @itemx compat32 @itemx compat40 diff --git parse.y parse.y index a4c4c07c..71cadbb6 100644 --- parse.y +++ parse.y @@ -264,6 +264,9 @@ char *current_prompt_string; /* Non-zero means we expand aliases in commands. */ int expand_aliases = 0; +/* Token used to connect commands separated by a newline */ +int func_default_connector = ';'; + /* If non-zero, the decoded prompt string undergoes parameter and variable substitution, command substitution, arithmetic substitution, string expansion, process substitution, and quote removal in @@ -1168,7 +1171,7 @@ pattern: WORD ; /* A list allows leading or trailing newlines and - newlines as operators (equivalent to semicolons). + newlines as operators (transformed into func_default_connector for func). It must end with a newline or semicolon. Lists are used within commands such as if, for, while. */ @@ -1214,7 +1217,7 @@ list1: list1 AND_AND newline_list list1 if (parser_state & PST_CMDSUBST) $$ = command_connect ($1, $4, '\n'); else - $$ = command_connect ($1, $4, ';'); + $$ = command_connect ($1, $4, func_default_connector); } | pipeline_command { $$ = $1; } diff --git tests/func-default-connector-and-and.right tests/func-default-connector-and-and.right new file mode 100644 index 00000000..5fa34f8d --- /dev/null +++ tests/func-default-connector-and-and.right @@ -0,0 +1,39 @@ +a () +{ + echo a0 && ( exit 5 ) && echo a1 +} +a0 +a ret 5 +b () +{ + echo b0 && ( exit 7 ); + echo b1 +} +b0 +b1 +b ret 0 +c () +{ + echo b0 && ( exit 9 ) || echo b1 +} +b0 +b1 +c ret 0 +d () +{ + echo tl0 && ( exit 2 ) && echo tl1; + echo tl10 && ( exit 2 ); + echo tl11 && ( exit 3 ) || ( exit 4 ) || echo $?; + ( exit 3 ) && ( exit 4 ) || echo $?; + echo tl20 && echo x && ( exit 5 ) || echo $?; + echo tl30 +} +tl0 +tl10 +tl11 +4 +tl20 +x +5 +tl30 +d ret 0 diff --git tests/func-default-connector-and-and.tests tests/func-default-connector-and-and.tests new file mode 100644 index 00000000..8a3bd458 --- /dev/null +++ tests/func-default-connector-and-and.tests @@ -0,0 +1,65 @@ +# 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 . +# + +print_exec_func() { + declare -f "$1" + "$1" + echo "$1 ret $?" +} + +shopt -s func_default_connector_and_and + + +a() { + echo a0 + (exit 5) + echo a1 +} + +b() { + echo b0 + (exit 7); + echo b1 +} + +c() { + echo b0 && (exit 9) || echo b1 +} + +d() { + echo tl0 + (exit 2) + echo tl1; + + echo tl10 + (exit 2); + echo tl11 + + (exit 3) || (exit 4) || echo $?; + + (exit 3) + (exit 4) || echo $?; + echo tl20 + + echo x + (exit 5) || echo $?; + echo tl30 +} + +print_exec_func a +print_exec_func b +print_exec_func c +print_exec_func d + +exit 0 diff --git tests/run-func-default-connector-and-and tests/run-func-default-connector-and-and new file mode 100644 index 00000000..bc96b1b1 --- /dev/null +++ tests/run-func-default-connector-and-and @@ -0,0 +1,2 @@ +${THIS_SH} ./func-default-connector-and-and.tests > ${BASH_TSTOUT} 2>&1 +diff ${BASH_TSTOUT} func-default-connector-and-and.right && rm -f ${BASH_TSTOUT} -- 2.39.2