mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-11 20:48:49 +00:00
Convert $IFS to a read-specific thing
This removes $IFS globally (which prevents fish internals from breaking when IFS is manipulated) but keeps it as a legacy/deprecated mode of specifying `read`'s `--delimiter` value for compatibility with (ba)sh and legacy fish scripts.
This commit is contained in:
parent
ee19759da1
commit
b3ea21e7bc
2 changed files with 71 additions and 4 deletions
|
@ -9,6 +9,7 @@ use crate::common::unescape_string;
|
|||
use crate::common::valid_var_name;
|
||||
use crate::common::UnescapeStringStyle;
|
||||
use crate::env::EnvMode;
|
||||
use crate::env::Environment;
|
||||
use crate::env::READ_BYTE_LIMIT;
|
||||
use crate::env::{EnvVar, EnvVarFlags};
|
||||
use crate::input_common::terminal_protocols_disable_ifn;
|
||||
|
@ -688,11 +689,18 @@ pub fn read(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Opt
|
|||
continue;
|
||||
}
|
||||
|
||||
// todo!("don't clone")
|
||||
// Order of precedence: --delimiter, an explicitly set $IFS, the default IFS constant above.
|
||||
// An empty --delimiter or $IFS is a special mode that splits by character (i.e. does not
|
||||
// fall back to the next candidate).
|
||||
let mut ifs_var = None;
|
||||
let delimiter = opts
|
||||
.delimiter
|
||||
.as_ref()
|
||||
.map(|delim| delim.as_utfstr())
|
||||
.or_else(|| {
|
||||
ifs_var = Some(parser.vars().get(L!("IFS")).map(|ifs| ifs.as_string()));
|
||||
ifs_var.as_ref().unwrap().as_ref()
|
||||
})
|
||||
.map(|s| s.as_utfstr())
|
||||
.unwrap_or(IFS);
|
||||
|
||||
if delimiter.is_empty() {
|
||||
|
|
|
@ -43,6 +43,31 @@ echo -n a | read -l one
|
|||
echo "$status $one"
|
||||
#CHECK: 0 a
|
||||
|
||||
# Test splitting input with IFS empty
|
||||
set -l IFS
|
||||
echo hello | read -l one
|
||||
print_vars one
|
||||
#CHECK: 1 'hello'
|
||||
echo hello | read -l one two
|
||||
print_vars one two
|
||||
#CHECK: 1 'h' 1 'ello'
|
||||
echo hello | read -l one two three
|
||||
print_vars one two three
|
||||
#CHECK: 1 'h' 1 'e' 1 'llo'
|
||||
echo '' | read -l one
|
||||
print_vars one
|
||||
#CHECK: 0
|
||||
echo t | read -l one two
|
||||
print_vars one two
|
||||
#CHECK: 1 't' 0
|
||||
echo t | read -l one two three
|
||||
print_vars one two three
|
||||
#CHECK: 1 't' 0 0
|
||||
echo ' t' | read -l one two
|
||||
print_vars one two
|
||||
#CHECK: 1 ' ' 1 't'
|
||||
set -le IFS
|
||||
|
||||
echo 'hello there' | read -la ary
|
||||
print_vars ary
|
||||
#CHECK: 2 'hello' 'there'
|
||||
|
@ -59,6 +84,18 @@ echo '' | read -la ary
|
|||
print_vars ary
|
||||
#CHECK: 0
|
||||
|
||||
set -l IFS
|
||||
echo hello | read -la ary
|
||||
print_vars ary
|
||||
#CHECK: 5 'h' 'e' 'l' 'l' 'o'
|
||||
echo h | read -la ary
|
||||
print_vars ary
|
||||
#CHECK: 1 'h'
|
||||
echo '' | read -la ary
|
||||
print_vars ary
|
||||
#CHECK: 0
|
||||
set -le IFS
|
||||
|
||||
# read -n tests
|
||||
echo testing | read -n 3 foo
|
||||
echo $foo
|
||||
|
@ -190,7 +227,7 @@ echo abc\ndef | $fish -i -c 'read a; read b; set --show a; set --show b' | $filt
|
|||
#CHECK: $b: set in global scope, unexported, with 1 elements
|
||||
#CHECK: $b[1]: |def|
|
||||
|
||||
# Test --delimiter
|
||||
# Test --delimiter (and $IFS, for now)
|
||||
echo a=b | read -l foo bar
|
||||
echo $foo
|
||||
echo $bar
|
||||
|
@ -212,7 +249,18 @@ echo $bar
|
|||
echo $baz
|
||||
#CHECK: b
|
||||
|
||||
# Default behavior
|
||||
# IFS empty string
|
||||
set -l IFS ''
|
||||
echo a=b | read -l foo bar baz
|
||||
echo $foo
|
||||
#CHECK: a
|
||||
echo $bar
|
||||
#CHECK: =
|
||||
echo $baz
|
||||
#CHECK: b
|
||||
|
||||
# IFS unset
|
||||
set -e IFS
|
||||
echo a=b | read -l foo bar baz
|
||||
echo $foo
|
||||
#CHECK: a=b
|
||||
|
@ -238,6 +286,17 @@ echo $b
|
|||
#CHECK: b
|
||||
echo $c
|
||||
#CHECK: c
|
||||
# Multi-char delimiters with IFS
|
||||
begin
|
||||
set -l IFS "..."
|
||||
echo a...b...c | read -l a b c
|
||||
echo $a
|
||||
echo $b
|
||||
echo $c
|
||||
end
|
||||
#CHECK: a
|
||||
#CHECK: b
|
||||
#CHECK: ..c
|
||||
|
||||
# At one point, whatever was read was printed _before_ banana
|
||||
echo banana (echo sausage | read)
|
||||
|
|
Loading…
Reference in a new issue