mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-30 22:34:29 +08:00
800f2414fb
If there's no more separator we break early but dont update pos, so we go into the code path that asserts we have reached the limit.
396 lines
9.0 KiB
Fish
396 lines
9.0 KiB
Fish
# RUN: %fish -C "set fish %fish" %s
|
|
# Set term again explicitly to ensure behavior.
|
|
set -gx TERM xterm
|
|
# Read with no vars is not an error
|
|
read
|
|
|
|
# Read with -a and anything other than exactly on var name is an error
|
|
read -a
|
|
#CHECKERR: read: expected 1 arguments; got 0
|
|
read --array v1 v2
|
|
#CHECKERR: read: expected 1 arguments; got 2
|
|
read --list v1
|
|
|
|
# Verify correct behavior of subcommands and splitting of input.
|
|
begin
|
|
count (echo one\ntwo)
|
|
#CHECK: 2
|
|
set -l IFS \t
|
|
count (echo one\ntwo)
|
|
#CHECK: 2
|
|
set -l IFS
|
|
count (echo one\ntwo)
|
|
#CHECK: 1
|
|
echo [(echo -n one\ntwo)]
|
|
#CHECK: [one
|
|
#CHECK: two]
|
|
count (echo one\ntwo\n)
|
|
#CHECK: 1
|
|
echo [(echo -n one\ntwo\n)]
|
|
#CHECK: [one
|
|
#CHECK: two]
|
|
count (echo one\ntwo\n\n)
|
|
#CHECK: 1
|
|
echo [(echo -n one\ntwo\n\n)]
|
|
#CHECK: [one
|
|
#CHECK: two
|
|
#CHECK: ]
|
|
end
|
|
|
|
function print_vars --no-scope-shadowing
|
|
set -l space
|
|
set -l IFS \n # ensure our command substitution works right
|
|
for var in $argv
|
|
echo -n $space (count $$var) \'$$var\'
|
|
set space ''
|
|
end
|
|
echo
|
|
end
|
|
|
|
# Test splitting input
|
|
echo 'hello there' | read -l one two
|
|
print_vars one two
|
|
#CHECK: 1 'hello' 1 'there'
|
|
echo 'hello there' | read -l one
|
|
print_vars one
|
|
#CHECK: 1 'hello there'
|
|
echo '' | read -l one
|
|
print_vars one
|
|
#CHECK: 1 ''
|
|
echo '' | read -l one two
|
|
print_vars one two
|
|
#CHECK: 1 '' 1 ''
|
|
echo test | read -l one two three
|
|
print_vars one two three
|
|
#CHECK: 1 'test' 1 '' 1 ''
|
|
echo 'foo bar baz' | read -l one two three
|
|
print_vars one two three
|
|
#CHECK: 1 'foo' 1 'bar' 1 ' baz'
|
|
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'
|
|
echo hello | read -la ary
|
|
print_vars ary
|
|
#CHECK: 1 'hello'
|
|
echo 'this is a bunch of words' | read -la ary
|
|
print_vars ary
|
|
#CHECK: 6 'this' 'is' 'a' 'bunch' 'of' 'words'
|
|
echo ' one two three' | read -la ary
|
|
print_vars ary
|
|
#CHECK: 3 'one' 'two' 'three'
|
|
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
|
|
#CHECK: tes
|
|
echo test | read -n 10 foo
|
|
echo $foo
|
|
#CHECK: test
|
|
echo test | read -n 0 foo
|
|
echo $foo
|
|
#CHECK: test
|
|
echo testing | begin
|
|
read -n 3 foo
|
|
read -n 3 bar
|
|
end
|
|
echo $foo
|
|
#CHECK: tes
|
|
echo $bar
|
|
#CHECK: tin
|
|
echo test | read -n 1 foo
|
|
echo $foo
|
|
#CHECK: t
|
|
|
|
# read -z tests
|
|
echo -n testing | read -lz foo
|
|
echo $foo
|
|
#CHECK: testing
|
|
echo -n 'test ing' | read -lz foo
|
|
echo $foo
|
|
#CHECK: test ing
|
|
echo newline | read -lz foo
|
|
echo $foo
|
|
#CHECK: newline
|
|
#CHECK:
|
|
echo -n 'test ing' | read -lz foo bar
|
|
print_vars foo bar
|
|
#CHECK: 1 'test' 1 'ing'
|
|
echo -ne 'test\0ing' | read -lz foo bar
|
|
print_vars foo bar
|
|
#CHECK: 1 'test' 1 ''
|
|
echo -ne 'foo\nbar' | read -lz foo bar
|
|
print_vars foo bar
|
|
#CHECK: 1 'foo' 1 'bar'
|
|
echo -ne 'foo\nbar\0baz\nquux' | while read -lza foo
|
|
print_vars foo
|
|
end
|
|
#CHECK: 2 'foo' 'bar'
|
|
#CHECK: 2 'baz' 'quux'
|
|
|
|
# Chunked read tests
|
|
set -l path /tmp/fish_chunked_read_test.txt
|
|
set -l longstr (seq 1024 | string join ',')
|
|
echo -n $longstr >$path
|
|
read -l longstr2 <$path
|
|
test "$longstr" = "$longstr2"
|
|
and echo "Chunked reads test pass"
|
|
or echo "Chunked reads test failure: long strings don't match!"
|
|
rm $path
|
|
#CHECK: Chunked reads test pass
|
|
|
|
# ==========
|
|
# The following tests verify that `read` correctly handles the limit on the
|
|
# number of bytes consumed.
|
|
#
|
|
set fish_read_limit 8192
|
|
set line abcdefghijklmnopqrstuvwxyz
|
|
|
|
# Ensure the `read` command terminates if asked to read too much data. The var
|
|
# should be empty. We throw away any data we read if it exceeds the limit on
|
|
# what we consider reasonable.
|
|
yes $line | head -c (math "1 + $fish_read_limit") | read --null x
|
|
if test $status -ne 122
|
|
echo reading too much data did not terminate with failure status
|
|
end
|
|
# The read var should be defined but not have any elements when the read
|
|
# aborts due to too much data.
|
|
set -q x
|
|
or echo reading too much data did not define the var
|
|
set -q x[1]
|
|
and echo reading too much data resulted in a var with unexpected data
|
|
|
|
# Ensure the `read` command terminates if asked to read too much data even if
|
|
# given an explicit limit. The var should be empty. We throw away any data we
|
|
# read if it exceeds the limit on what we consider reasonable.
|
|
yes $line | read --null --nchars=(math "$fish_read_limit + 1") x
|
|
if test $status -ne 122
|
|
echo reading too much data did not terminate with failure status
|
|
end
|
|
set -q x
|
|
or echo reading too much data with --nchars did not define the var
|
|
set -q x[1]
|
|
and echo reading too much data with --nchars resulted in a var with unexpected data
|
|
|
|
# Now do the opposite of the previous test and confirm we can read reasonable
|
|
# amounts of data.
|
|
echo $line | read x
|
|
if test $status -ne 0
|
|
echo the read of a reasonable amount of data failed unexpectedly
|
|
end
|
|
set exp_length (string length $x)
|
|
set act_length (string length $line)
|
|
if test $exp_length -ne $act_length
|
|
echo reading a reasonable amount of data failed the length test
|
|
echo expected length $exp_length, actual length $act_length
|
|
end
|
|
|
|
# Confirm we can read exactly up to the limit.
|
|
yes $line | read --null --nchars $fish_read_limit x
|
|
if test $status -ne 0
|
|
echo the read of the max amount of data with --nchars failed unexpectedly
|
|
end
|
|
if test (string length "$x") -ne $fish_read_limit
|
|
echo reading the max amount of data with --nchars failed the length test
|
|
end
|
|
|
|
# Same as previous test but limit the amount of data fed to `read` rather than
|
|
# using the `--nchars` flag.
|
|
yes $line | head -c $fish_read_limit | read --null x
|
|
if test $status -ne 0
|
|
echo the read of the max amount of data failed unexpectedly
|
|
end
|
|
if test (string length "$x") -ne $fish_read_limit
|
|
echo reading with a limited amount of input data failed the length test
|
|
end
|
|
|
|
# Confirm reading non-interactively works -- \#4206 regression
|
|
echo abc\ndef | $fish -i -c 'read a; read b; set --show a; set --show b'
|
|
#CHECK: $a: set in global scope, unexported, with 1 elements
|
|
#CHECK: $a[1]: |abc|
|
|
#CHECK: $b: set in global scope, unexported, with 1 elements
|
|
#CHECK: $b[1]: |def|
|
|
|
|
# Test --delimiter (and $IFS, for now)
|
|
echo a=b | read -l foo bar
|
|
echo $foo
|
|
echo $bar
|
|
#CHECK: a=b
|
|
|
|
# Delimiter =
|
|
echo a=b | read -l -d = foo bar
|
|
echo $foo
|
|
#CHECK: a
|
|
echo $bar
|
|
#CHECK: b
|
|
|
|
# Delimiter empty
|
|
echo a=b | read -l -d '' foo bar baz
|
|
echo $foo
|
|
#CHECK: a
|
|
echo $bar
|
|
#CHECK: =
|
|
echo $baz
|
|
#CHECK: b
|
|
|
|
# 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
|
|
echo $bar
|
|
#CHECK:
|
|
echo $baz
|
|
#CHECK:
|
|
|
|
# Delimiter =
|
|
echo a=b | read -l -d = foo bar baz
|
|
echo $foo
|
|
#CHECK: a
|
|
echo $bar
|
|
#CHECK: b
|
|
echo $baz
|
|
#CHECK:
|
|
|
|
# Multi-char delimiters with -d
|
|
echo a...b...c | read -l -d "..." a b c
|
|
echo $a
|
|
#CHECK: a
|
|
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)
|
|
echo 'a | b' | read -lt a b c
|
|
#CHECK: banana sausage
|
|
|
|
echo a $a
|
|
echo b $b
|
|
echo c $c
|
|
# CHECK: a a
|
|
# CHECK: b |
|
|
# CHECK: c b
|
|
|
|
echo 'a"foo bar"b' | read -lt a b c
|
|
|
|
echo a \'$a\'
|
|
echo b $b
|
|
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|
|
|
|
|
echo foo\nbar\nbaz | begin
|
|
read -l foo
|
|
read -l bar
|
|
cat
|
|
# CHECK: baz
|
|
echo $bar
|
|
# CHECK: bar
|
|
end
|
|
|
|
begin
|
|
echo 1
|
|
echo 2
|
|
end | read -l --line foo bar
|
|
echo $foo $bar
|
|
# CHECK: 1 2
|
|
|
|
echo foo | read status
|
|
# CHECKERR: read: status: cannot overwrite read-only variable
|
|
# CHECKERR: {{.*}}read.fish (line {{\d+}}):
|
|
# CHECKERR: echo foo | read status
|
|
# CHECKERR: ^
|
|
# CHECKERR: (Type 'help read' for related documentation)
|
|
echo read $status
|
|
# CHECK: read 2
|
|
|
|
echo ' foo' | read -n 1 -la var
|
|
set -S var
|
|
#CHECK: $var: set in local scope, unexported, with 0 elements
|