From f58e33c7cf73e0f80f22b695978695a4542bb9ea Mon Sep 17 00:00:00 2001 From: Christian Bourgeois Date: Sat, 29 Jun 2024 01:06:43 +0200 Subject: [PATCH 1/2] fixed -p and -o to behave like bash and sh -o, space aligned + 1 tab --- builtin/pure_osh.py | 12 ++++++------ core/shell.py | 5 +++-- core/state.py | 19 ++++++++++++------- spec/builtin-shopt-bash.test.sh | 24 ++++++++++++++++++++++++ test/spec.sh | 4 ++++ 5 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 spec/builtin-shopt-bash.test.sh diff --git a/builtin/pure_osh.py b/builtin/pure_osh.py index 99ce17bc04..f82b813142 100644 --- a/builtin/pure_osh.py +++ b/builtin/pure_osh.py @@ -169,7 +169,7 @@ def Run(self, cmd_val): # 'set -o' shows options. This is actually used by autoconf-generated # scripts! if arg.show_options: - self.exec_opts.ShowOptions([]) + self.exec_opts.ShowOptions([], False) return 0 # Note: set -o nullglob is not valid. The 'shopt' builtin is preferred in @@ -193,12 +193,12 @@ def __init__(self, mutable_opts, cmd_ev): self.mutable_opts = mutable_opts self.cmd_ev = cmd_ev - def _PrintOptions(self, use_set_opts, opt_names): + def _PrintOptions(self, use_set_opts, as_command, opt_names): # type: (bool, List[str]) -> None if use_set_opts: - self.mutable_opts.ShowOptions(opt_names) + self.mutable_opts.ShowOptions(opt_names, as_command) else: - self.mutable_opts.ShowShoptOptions(opt_names) + self.mutable_opts.ShowShoptOptions(opt_names, as_command) def Run(self, cmd_val): # type: (cmd_value.Argv) -> int @@ -223,10 +223,10 @@ def Run(self, cmd_val): elif arg.u: b = False elif arg.p: # explicit -p - self._PrintOptions(arg.o, opt_names) + self._PrintOptions(arg.o, arg.p, opt_names) return 0 else: # otherwise -p is implicit - self._PrintOptions(arg.o, opt_names) + self._PrintOptions(arg.o, arg.p, opt_names) return 0 # shopt --set x { my-block } diff --git a/core/shell.py b/core/shell.py index 21c6298e64..5ee546bfaf 100644 --- a/core/shell.py +++ b/core/shell.py @@ -357,8 +357,9 @@ def Main( state.InitMem(mem, environ, version_str) if attrs.show_options: # special case: sh -o - mutable_opts.ShowOptions([]) - return 0 + mutable_opts.ShowOptions([], False) + # removed return as sh -o does not return + # return 0 # Set these BEFORE processing flags, so they can be overridden. if lang == 'ysh': diff --git a/core/state.py b/core/state.py index 5ea1852311..08be00cc7b 100644 --- a/core/state.py +++ b/core/state.py @@ -670,9 +670,9 @@ def SetAnyOption(self, opt_name, b): self._SetArrayByNum(opt_num, b) - def ShowOptions(self, opt_names): - # type: (List[str]) -> None - """For 'set -o' and 'shopt -p -o'.""" + def ShowOptions(self, opt_names, as_command): + # type: (List[str], bool) -> None + """For 'set -o' and 'shopt -p -o' and 'shopt -o'.""" # TODO: Maybe sort them differently? if len(opt_names) == 0: # if none, supplied, show all @@ -681,9 +681,12 @@ def ShowOptions(self, opt_names): for opt_name in opt_names: opt_num = _SetOptionNum(opt_name) b = self.Get(opt_num) - print('set %so %s' % ('-' if b else '+', opt_name)) + if as_command: + print('set %so %s' % ('-' if b else '+', opt_name)) + else: + print('%-16s\t%s' % (opt_name, 'on' if b else 'off')) - def ShowShoptOptions(self, opt_names): + def ShowShoptOptions(self, opt_names, as_command): # type: (List[str]) -> None """For 'shopt -p'.""" @@ -712,8 +715,10 @@ def ShowShoptOptions(self, opt_names): for opt_num in opt_nums: b = self.Get(opt_num) - print('shopt -%s %s' % - ('s' if b else 'u', consts.OptionName(opt_num))) + if as_command: + print('shopt -%s %s' % ('s' if b else 'u', consts.OptionName(opt_num))) + else: + print('%-20s\t%s' % (consts.OptionName(opt_num), 'on' if b else 'off', )) class _ArgFrame(object): diff --git a/spec/builtin-shopt-bash.test.sh b/spec/builtin-shopt-bash.test.sh new file mode 100644 index 0000000000..0c7b6f437f --- /dev/null +++ b/spec/builtin-shopt-bash.test.sh @@ -0,0 +1,24 @@ +## compare_shells: bash +## oils_failures_allowed: 0 + +# builtin-shopt-bash.test.sh + +#### shopt +shopt | grep inherit_errexit | tr -d ' ' +## stdout-json: "inherit_errexit\toff\n" + +#### shopt -p +shopt -p | grep inherit_errexit +## STDOUT: +shopt -u inherit_errexit +## END + +#### shopt -o +shopt -o | grep errexit | tr -d ' ' +## stdout-json: "errexit\toff\n" + +#### shopt -p -o +shopt -p -o | grep errexit +## STDOUT: +set +o errexit +## END diff --git a/test/spec.sh b/test/spec.sh index da8fbe7994..fe3bdcf641 100755 --- a/test/spec.sh +++ b/test/spec.sh @@ -251,6 +251,10 @@ builtin-trap-bash() { run-file builtin-trap-bash "$@" } +builtin-shopt-bash() { + run-file builtin-shopt-bash "$@" +} + # Bash implements type -t, but no other shell does. For Nix. # zsh/mksh/dash don't have the 'help' builtin. builtin-bash() { From 3c4111f8c6500bb1350b77e474ac75ec654ae627 Mon Sep 17 00:00:00 2001 From: Christian Bourgeois Date: Sat, 29 Jun 2024 01:15:03 +0200 Subject: [PATCH 2/2] fix invalid c++ signature --- builtin/pure_osh.py | 2 +- core/state.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin/pure_osh.py b/builtin/pure_osh.py index f82b813142..1dc9ac855f 100644 --- a/builtin/pure_osh.py +++ b/builtin/pure_osh.py @@ -194,7 +194,7 @@ def __init__(self, mutable_opts, cmd_ev): self.cmd_ev = cmd_ev def _PrintOptions(self, use_set_opts, as_command, opt_names): - # type: (bool, List[str]) -> None + # type: (bool, bool, List[str]) -> None if use_set_opts: self.mutable_opts.ShowOptions(opt_names, as_command) else: diff --git a/core/state.py b/core/state.py index 08be00cc7b..e17f22655f 100644 --- a/core/state.py +++ b/core/state.py @@ -687,7 +687,7 @@ def ShowOptions(self, opt_names, as_command): print('%-16s\t%s' % (opt_name, 'on' if b else 'off')) def ShowShoptOptions(self, opt_names, as_command): - # type: (List[str]) -> None + # type: (List[str], bool) -> None """For 'shopt -p'.""" # Respect option groups.