Add function scope to read as well

Fixes #8295.
This commit is contained in:
Fabian Homborg 2021-09-23 17:12:37 +02:00
parent 8b093e2651
commit 45714eb29d
3 changed files with 29 additions and 3 deletions

View file

@ -25,7 +25,9 @@ The following options are available:
- ``-s`` or ``--silent`` masks characters written to the terminal, replacing them with asterisks. This is useful for reading things like passwords or other sensitive information.
- ``-l`` or ``--local`` makes the variables local.
- ``-f`` or ``--function`` scopes the variable to the currently executing function. It is erased when the function ends.
- ``-l`` or ``--local`` scopes the variable to the currently executing block. It is erased when the block ends. Outside of a block, this is the same as ``--function``.
- ``-n NCHARS`` or ``--nchars=NCHARS`` makes ``read`` return after reading NCHARS characters or the end of
the line, whichever comes first.

View file

@ -57,11 +57,12 @@ struct read_cmd_opts_t {
bool one_line = false;
};
static const wchar_t *const short_options = L":ac:d:ghiLln:p:sStuxzP:UR:L";
static const wchar_t *const short_options = L":ac:d:fghiLln:p:sStuxzP:UR:L";
static const struct woption long_options[] = {{L"array", no_argument, nullptr, 'a'},
{L"command", required_argument, nullptr, 'c'},
{L"delimiter", required_argument, nullptr, 'd'},
{L"export", no_argument, nullptr, 'x'},
{L"function", no_argument, nullptr, 'f'},
{L"global", no_argument, nullptr, 'g'},
{L"help", no_argument, nullptr, 'h'},
{L"line", no_argument, nullptr, 'L'},
@ -105,6 +106,10 @@ static int parse_cmd_opts(read_cmd_opts_t &opts, int *optind, //!OCLINT(high nc
cmd);
return STATUS_INVALID_ARGS;
}
case L'f': {
opts.place |= ENV_FUNCTION;
break;
}
case L'g': {
opts.place |= ENV_GLOBAL;
break;
@ -385,7 +390,7 @@ static int validate_read_args(const wchar_t *cmd, read_cmd_opts_t &opts, int arg
return STATUS_INVALID_ARGS;
}
if ((opts.place & ENV_LOCAL ? 1 : 0) + (opts.place & ENV_GLOBAL ? 1 : 0) +
if ((opts.place & ENV_LOCAL ? 1 : 0) + (opts.place & ENV_FUNCTION ? 1 : 0) + (opts.place & ENV_GLOBAL ? 1 : 0) +
(opts.place & ENV_UNIVERSAL ? 1 : 0) >
1) {
streams.err.append_format(BUILTIN_ERR_GLOCAL, cmd);

View file

@ -345,3 +345,22 @@ echo c $c
# CHECK: a 'afoo barb'
# CHECK: b
# CHECK: c
function function-scoped-read
echo foo | read --function skamtebord
set -S skamtebord
begin
echo bar | read skamtebord
echo baz | read -f craaab
end
set -S skamtebord
set -S craaab
end
function-scoped-read
# CHECK: $skamtebord: set in local scope, unexported, with 1 elements
# CHECK: $skamtebord[1]: |foo|
# CHECK: $skamtebord: set in local scope, unexported, with 1 elements
# CHECK: $skamtebord[1]: |bar|
# CHECK: $craaab: set in local scope, unexported, with 1 elements
# CHECK: $craaab[1]: |baz|