mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 15:14:44 +00:00
Let "return" exit a script (#8148)
Currently, if a "return" is given outside of a function, we'd just throw an error. That always struck me as a bit weird, given that scripts can also return a value. So simply let "return" outside also exit the script, kinda like "exit" does. However, unlike "exit" it doesn't quit an interactive shell - it seems weird to have "return" do that as well. It sets $status, so it can be used to quickly set that, in case you want to test something.
This commit is contained in:
parent
a32248277f
commit
3359e5d2e9
5 changed files with 29 additions and 25 deletions
|
@ -17,6 +17,7 @@ Description
|
|||
|
||||
It is usually added inside of a conditional block such as an :ref:`if <cmd-if>` statement or a :ref:`switch <cmd-switch>` statement to conditionally stop the executing function and return to the caller, but it can also be used to specify the exit status of a function.
|
||||
|
||||
If run at the top level of a script, it exits that script and returns the given status, like :ref:`exit <cmd-exit>`. If run at the top level in an interactive session, it will set ``$status``, but not exit the shell.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
|
|
@ -97,10 +97,13 @@ maybe_t<int> builtin_return(parser_t &parser, io_streams_t &streams, const wchar
|
|||
}
|
||||
}
|
||||
|
||||
// If we're not in a function, exit the current script,
|
||||
// but not an interactive shell.
|
||||
if (!has_function_block) {
|
||||
streams.err.append_format(_(L"%ls: Not inside of function\n"), cmd);
|
||||
builtin_print_error_trailer(parser, streams.err, cmd);
|
||||
return STATUS_CMD_ERROR;
|
||||
if (!parser.libdata().is_interactive) {
|
||||
parser.libdata().exit_current_script = true;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Mark a return in the libdata.
|
||||
|
|
|
@ -235,9 +235,6 @@ enum class pipeline_position_t {
|
|||
/// Error when using continue outside of loop.
|
||||
#define INVALID_CONTINUE_ERR_MSG _(L"'continue' while not inside of loop")
|
||||
|
||||
/// Error when using return builtin outside of function definition.
|
||||
#define INVALID_RETURN_ERR_MSG _(L"'return' outside of function definition")
|
||||
|
||||
// Error messages. The number is a reminder of how many format specifiers are contained.
|
||||
|
||||
/// Error for $^.
|
||||
|
|
|
@ -1141,25 +1141,6 @@ static bool detect_errors_in_decorated_statement(const wcstring &buff_src,
|
|||
append_syntax_error(parse_errors, source_start, EXEC_ERR_MSG, command.c_str());
|
||||
}
|
||||
|
||||
// Check that we don't return from outside a function. But we allow it if it's
|
||||
// 'return --help'.
|
||||
if (!errored && command == L"return" && !first_arg_is_help) {
|
||||
// See if we are in a function.
|
||||
bool found_function = false;
|
||||
for (const node_t *cursor = &dst; cursor != nullptr; cursor = cursor->parent) {
|
||||
if (const auto *bs = cursor->try_as<block_statement_t>()) {
|
||||
if (bs->header->type == type_t::function_header) {
|
||||
found_function = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_function) {
|
||||
errored = append_syntax_error(parse_errors, source_start, INVALID_RETURN_ERR_MSG);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that we don't break or continue from outside a loop.
|
||||
if (!errored && (command == L"break" || command == L"continue") && !first_arg_is_help) {
|
||||
// Walk up until we hit a 'for' or 'while' loop. If we hit a function first,
|
||||
|
|
22
tests/checks/return.fish
Normal file
22
tests/checks/return.fish
Normal file
|
@ -0,0 +1,22 @@
|
|||
#RUN: %fish -C 'set -l fish %fish' %s
|
||||
# Some tests of the "return" builtin.
|
||||
|
||||
$fish -c 'return 5'
|
||||
echo $status
|
||||
# CHECK: 5
|
||||
|
||||
$fish -c 'exit 5'
|
||||
echo $status
|
||||
# CHECK: 5
|
||||
|
||||
$fish -c 'echo foo; return 2; echo bar'
|
||||
# CHECK: foo
|
||||
# but not bar
|
||||
echo $status
|
||||
# CHECK: 2
|
||||
|
||||
$fish -ic 'echo interactive-foo; return 69; echo interactive-bar'
|
||||
# CHECK: interactive-foo
|
||||
# but not bar
|
||||
echo $status
|
||||
# CHECK: 69
|
Loading…
Reference in a new issue