aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile.in2
-rw-r--r--builtin.cpp164
-rw-r--r--doc_src/command.txt14
-rw-r--r--doc_src/read.txt6
-rw-r--r--doc_src/type.txt5
-rw-r--r--share/functions/__fish_complete_cabal.fish2
-rw-r--r--share/functions/__fish_complete_vi.fish2
-rw-r--r--share/functions/__fish_config_interactive.fish4
-rw-r--r--share/functions/__fish_print_packages.fish14
-rw-r--r--share/functions/funced.fish2
-rw-r--r--share/functions/help.fish14
-rw-r--r--share/functions/ls.fish2
-rw-r--r--share/functions/open.fish4
-rw-r--r--share/functions/seq.fish2
-rw-r--r--share/functions/type.fish178
-rw-r--r--tests/read.err0
-rw-r--r--tests/read.in72
-rw-r--r--tests/read.out27
-rw-r--r--tests/read.status1
-rw-r--r--tests/test7.in4
-rw-r--r--tests/top.out1
21 files changed, 389 insertions, 131 deletions
diff --git a/Makefile.in b/Makefile.in
index 9fe0f8e0..4995dddc 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -284,7 +284,7 @@ doc/refman.pdf: doc
test: $(PROGRAMS) fish_tests
./fish_tests
- cd tests; ../fish <test.fish;
+ cd tests; ../fish -c 'set -x fish_function_path "$$PWD"/../share/functions dummy; source' <test.fish;
.PHONY: test
diff --git a/builtin.cpp b/builtin.cpp
index 0213f5cb..efe28f90 100644
--- a/builtin.cpp
+++ b/builtin.cpp
@@ -1054,6 +1054,87 @@ static int builtin_emit(parser_t &parser, wchar_t **argv)
/**
+ Implementation of the builtin 'command'. Actual command running is handled by
+ the parser, this just processes the flags.
+*/
+static int builtin_command(parser_t &parser, wchar_t **argv)
+{
+ int argc=builtin_count_args(argv);
+ int print_path=0;
+
+ woptind=0;
+
+ static const struct woption
+ long_options[] =
+ {
+ { L"search", no_argument, 0, 's' },
+ { L"help", no_argument, 0, 'h' },
+ { 0, 0, 0, 0 }
+ };
+
+ while (1)
+ {
+ int opt_index = 0;
+
+ int opt = wgetopt_long(argc,
+ argv,
+ L"svh",
+ long_options,
+ &opt_index);
+ if (opt == -1)
+ break;
+
+ switch (opt)
+ {
+ case 0:
+ if (long_options[opt_index].flag != 0)
+ break;
+ append_format(stderr_buffer,
+ BUILTIN_ERR_UNKNOWN,
+ argv[0],
+ long_options[opt_index].name);
+ builtin_print_help(parser, argv[0], stderr_buffer);
+ return STATUS_BUILTIN_ERROR;
+
+ case 'h':
+ builtin_print_help(parser, argv[0], stdout_buffer);
+ return STATUS_BUILTIN_OK;
+
+ case 's':
+ case 'v':
+ print_path=1;
+ break;
+
+ case '?':
+ builtin_unknown_option(parser, argv[0], argv[woptind-1]);
+ return STATUS_BUILTIN_ERROR;
+
+ }
+
+ }
+
+ if (!print_path)
+ {
+ builtin_print_help(parser, argv[0], stdout_buffer);
+ return STATUS_BUILTIN_ERROR;
+ }
+
+ int found=0;
+
+ for (int idx = woptind; argv[idx]; ++idx)
+ {
+ const wchar_t *command_name = argv[idx];
+ wcstring path;
+ if (path_get_path(command_name, &path))
+ {
+ append_format(stdout_buffer, L"%ls\n", path.c_str());
+ ++found;
+ }
+ }
+ return found ? STATUS_BUILTIN_OK : STATUS_BUILTIN_ERROR;
+}
+
+/**
A generic bultin that only supports showing a help message. This is
only a placeholder that prints the help message. Useful for
commands that live in the parser.
@@ -2233,6 +2314,7 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
int exit_res=STATUS_BUILTIN_OK;
const wchar_t *mode_name = READ_MODE_NAME;
int shell = 0;
+ int array = 0;
woptind=0;
@@ -2278,6 +2360,10 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
}
,
{
+ L"array", no_argument, 0, 'a'
+ }
+ ,
+ {
L"help", no_argument, 0, 'h'
}
,
@@ -2291,7 +2377,7 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
int opt = wgetopt_long(argc,
argv,
- L"xglUup:c:hm:s",
+ L"xglUup:c:hm:sa",
long_options,
&opt_index);
if (opt == -1)
@@ -2346,6 +2432,10 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
shell = 1;
break;
+ case 'a':
+ array = 1;
+ break;
+
case 'h':
builtin_print_help(parser, argv[0], stdout_buffer);
return STATUS_BUILTIN_OK;
@@ -2378,6 +2468,14 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
return STATUS_BUILTIN_ERROR;
}
+ if (array && woptind+1 != argc)
+ {
+ append_format(stderr_buffer, _(L"%ls: --array option requires a single variable name.\n"), argv[0]);
+ builtin_print_help(parser, argv[0], stderr_buffer);
+
+ return STATUS_BUILTIN_ERROR;
+ }
+
/*
Verify all variable names
*/
@@ -2512,18 +2610,64 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
wchar_t *state;
env_var_t ifs = env_get_string(L"IFS");
- if (ifs.missing())
- ifs = L"";
- nxt = wcstok(buff, (i<argc-1)?ifs.c_str():L"", &state);
+ if (ifs.missing_or_empty())
+ {
+ /* Every character is a separate token */
+ size_t bufflen = wcslen(buff);
+ if (array)
+ {
+ if (bufflen > 0)
+ {
+ wcstring chars(bufflen+(bufflen-1), ARRAY_SEP);
+ for (size_t j=0; j<bufflen; ++j)
+ {
+ chars[j*2] = buff[j];
+ }
+ env_set(argv[i], chars.c_str(), place);
+ }
+ else
+ {
+ env_set(argv[i], NULL, place);
+ }
+ }
+ else
+ {
+ size_t j = 0;
+ for (; i+1 < argc; ++i)
+ {
+ env_set(argv[i], j < bufflen ? (wchar_t[2]){buff[j], 0} : L"", place);
+ if (j < bufflen) ++j;
+ }
+ if (i < argc) env_set(argv[i], &buff[j], place);
+ }
+ }
+ else if (array)
+ {
+ wcstring tokens;
+ tokens.reserve(wcslen(buff));
+ bool empty = true;
- while (i<argc)
+ for (nxt = wcstok(buff, ifs.c_str(), &state); nxt != 0; nxt = wcstok(0, ifs.c_str(), &state))
+ {
+ if (! tokens.empty()) tokens.push_back(ARRAY_SEP);
+ tokens.append(nxt);
+ empty = false;
+ }
+ env_set(argv[i], empty ? NULL : tokens.c_str(), place);
+ }
+ else
{
- env_set(argv[i], nxt != 0 ? nxt: L"", place);
+ nxt = wcstok(buff, (i<argc-1)?ifs.c_str():L"", &state);
+
+ while (i<argc)
+ {
+ env_set(argv[i], nxt != 0 ? nxt: L"", place);
- i++;
- if (nxt != 0)
- nxt = wcstok(0, (i<argc-1)?ifs.c_str():L"", &state);
+ i++;
+ if (nxt != 0)
+ nxt = wcstok(0, (i<argc-1)?ifs.c_str():L"", &state);
+ }
}
}
@@ -3726,7 +3870,7 @@ static const builtin_data_t builtin_datas[]=
{ L"builtin", &builtin_builtin, N_(L"Run a builtin command instead of a function") },
{ L"case", &builtin_generic, N_(L"Conditionally execute a block of commands") },
{ L"cd", &builtin_cd, N_(L"Change working directory") },
- { L"command", &builtin_generic, N_(L"Run a program instead of a function or builtin") },
+ { L"command", &builtin_command, N_(L"Run a program instead of a function or builtin") },
{ L"commandline", &builtin_commandline, N_(L"Set or get the commandline") },
{ L"complete", &builtin_complete, N_(L"Edit command specific completions") },
{ L"contains", &builtin_contains, N_(L"Search for a specified string in a list") },
diff --git a/doc_src/command.txt b/doc_src/command.txt
index 19baccd4..cef08fdc 100644
--- a/doc_src/command.txt
+++ b/doc_src/command.txt
@@ -1,12 +1,22 @@
\section command command - run a program
\subsection command-synopsis Synopsis
-<tt>command COMMANDNAME [OPTIONS...]</tt>
+<tt>command [OPTIONS] COMMANDNAME [ARGS...]</tt>
\subsection command-description Description
\c command forces the shell to execute the program \c COMMANDNAME and ignore any functions or builtins with the same name.
-\subsection command-example Example
+The following options are available:
+- \c -h or \c --help prints help and then exits.
+- \c -s or \c --search returns the name of the disk file that would be executed, or nothing if no file with the specified name could be found in the <tt>$PATH</tt>.
+
+With the \c -s option, \c command treats every argument as a separate command to look up and sets the exit status to 0 if any of the specified commands were found, or 1 if no commands could be found.
+
+For basic compatibility with POSIX <tt>command</tt>, the \c -v flag is recognized as an alias for <tt>-s</tt>.
+
+\subsection command-example Examples
<tt>command ls</tt> causes fish to execute the \c ls program, even if an 'ls' function exists.
+
+<tt>command -s ls</tt> returns the path to the \c ls program.
diff --git a/doc_src/read.txt b/doc_src/read.txt
index ca7a4d14..4f1760a5 100644
--- a/doc_src/read.txt
+++ b/doc_src/read.txt
@@ -19,11 +19,17 @@ The following options are available:
- <code>-u</code> or <code>--unexport</code> prevents the variables from being exported to child processes (default behaviour).
- <code>-U</code> or <code>--universal</code> causes the specified shell variable to be made universal.
- <code>-x</code> or <code>--export</code> exports the variables to child processes.
+- <code>-a</code> or <code>--array</code> stores the result as an array.
\c read reads a single line of input from stdin, breaks it into tokens
based on the <tt>IFS</tt> shell variable, and then assigns one
token to each variable specified in <tt>VARIABLES</tt>. If there are more
tokens than variables, the complete remainder is assigned to the last variable.
+As a special case, if \c IFS is set to the empty string, each character of the
+input is considered a separate token.
+
+If \c -a or \c --array is provided, only one variable name is allowed and the
+tokens are stored as an array in this variable.
See the documentation for \c set for more details on the scoping rules for
variables.
diff --git a/doc_src/type.txt b/doc_src/type.txt
index 9b5699f3..8945102c 100644
--- a/doc_src/type.txt
+++ b/doc_src/type.txt
@@ -12,9 +12,10 @@ The following options are available:
- \c -h or \c --help prints help and then exits.
- \c -a or \c --all prints all of possible definitions of the specified names.
- \c -f or \c --no-functions suppresses function and builtin lookup.
-- \c -t or \c --type prints <tt>keyword</tt>, <tt>function</tt>, <tt>builtin</tt>, or <tt>file</tt> if \c NAME is a shell reserved word, function, builtin, or disk file, respectively.
+- \c -t or \c --type prints <tt>function</tt>, <tt>builtin</tt>, or <tt>file</tt> if \c NAME is a shell function, builtin, or disk file, respectively.
- \c -p or \c --path returns the name of the disk file that would be executed, or nothing if 'type -t name' would not return 'file'.
-- \c -P or \c --force-path returns the name of the disk file that would be executed, or nothing no file with the specified name could be found in the <tt>$PATH</tt>.
+- \c -P or \c --force-path returns the name of the disk file that would be executed, or nothing if no file with the specified name could be found in the <tt>$PATH</tt>.
+- \c -q or \c --quiet suppresses all output; this is useful when testing the exit status.
\c type sets the exit status to 0 if the specified command was found,
and 1 if it could not be found.
diff --git a/share/functions/__fish_complete_cabal.fish b/share/functions/__fish_complete_cabal.fish
index b5b8c0c0..484710a8 100644
--- a/share/functions/__fish_complete_cabal.fish
+++ b/share/functions/__fish_complete_cabal.fish
@@ -1,5 +1,5 @@
function __fish_complete_cabal
- if type -f cabal >/dev/null
+ if type -q -f cabal
set cmd (commandline -poc)
if test (count $cmd) -gt 1
cabal $cmd[2..-1] --list-options
diff --git a/share/functions/__fish_complete_vi.fish b/share/functions/__fish_complete_vi.fish
index 8a07ffd2..51009d8b 100644
--- a/share/functions/__fish_complete_vi.fish
+++ b/share/functions/__fish_complete_vi.fish
@@ -2,7 +2,7 @@
function __fish_complete_vi -d "Compleletions for vi and its aliases" --argument-names cmd
set -l is_vim
- if type $cmd > /dev/null
+ if type -q $cmd
eval command $cmd --version >/dev/null ^/dev/null; and set -l is_vim vim
end
diff --git a/share/functions/__fish_config_interactive.fish b/share/functions/__fish_config_interactive.fish
index 46b6ca24..1d3a1bea 100644
--- a/share/functions/__fish_config_interactive.fish
+++ b/share/functions/__fish_config_interactive.fish
@@ -248,7 +248,7 @@ function __fish_config_interactive -d "Initializations that should be performed
# First check if we are on OpenSUSE since SUSE's handler has no options
# and expects first argument to be a command and second database
# also check if there is command-not-found command.
- if begin; test -f /etc/SuSE-release; and type -p command-not-found > /dev/null 2> /dev/null; end
+ if begin; test -f /etc/SuSE-release; and type -q -p command-not-found; end
function __fish_command_not_found_handler --on-event fish_command_not_found
/usr/bin/command-not-found $argv
end
@@ -263,7 +263,7 @@ function __fish_config_interactive -d "Initializations that should be performed
/usr/lib/command-not-found -- $argv
end
# Ubuntu Feisty places this command in the regular path instead
- else if type -p command-not-found > /dev/null 2> /dev/null
+ else if type -q -p command-not-found
function __fish_command_not_found_handler --on-event fish_command_not_found
command-not-found -- $argv
end
diff --git a/share/functions/__fish_print_packages.fish b/share/functions/__fish_print_packages.fish
index 6755dd6a..050fcac2 100644
--- a/share/functions/__fish_print_packages.fish
+++ b/share/functions/__fish_print_packages.fish
@@ -18,7 +18,7 @@ function __fish_print_packages
end
mkdir -m 700 -p $XDG_CACHE_HOME
- if type -f apt-cache >/dev/null
+ if type -q -f apt-cache
# Do not generate the cache as apparently sometimes this is slow.
# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=547550
apt-cache --no-generate pkgnames (commandline -tc) ^/dev/null | sed -e 's/$/'\t$package'/'
@@ -28,7 +28,7 @@ function __fish_print_packages
# Pkg is fast on FreeBSD and provides versioning info which we want for
# installed packages
if begin
- type -f pkg > /dev/null
+ type -q -f pkg
and test (uname) = "FreeBSD"
end
pkg query "%n-%v"
@@ -36,7 +36,7 @@ function __fish_print_packages
end
# Caches for 5 minutes
- if type -f pacman >/dev/null
+ if type -q -f pacman
set cache_file $XDG_CACHE_HOME/.pac-cache.$USER
if test -f $cache_file
cat $cache_file
@@ -53,7 +53,7 @@ function __fish_print_packages
end
# yum is slow, just like rpm, so go to the background
- if type -f /usr/share/yum-cli/completion-helper.py >/dev/null
+ if type -q -f /usr/share/yum-cli/completion-helper.py
# If the cache is less than six hours old, we do not recalculate it
@@ -75,7 +75,7 @@ function __fish_print_packages
# Rpm is too slow for this job, so we set it up to do completions
# as a background job and cache the results.
- if type -f rpm >/dev/null
+ if type -q -f rpm
# If the cache is less than five minutes old, we do not recalculate it
@@ -99,12 +99,12 @@ function __fish_print_packages
# installed on the system packages is in completions/emerge.fish
# eix is MUCH faster than emerge so use it if it is available
- if type -f eix > /dev/null
+ if type -q -f eix
eix --only-names "^"(commandline -tc) | cut -d/ -f2
return
else
# FIXME? Seems to be broken
- if type -f emerge >/dev/null
+ if type -q -f emerge
emerge -s \^(commandline -tc) |sgrep "^*" |cut -d\ -f3 |cut -d/ -f2
return
end
diff --git a/share/functions/funced.fish b/share/functions/funced.fish
index ca2e2772..074e3c43 100644
--- a/share/functions/funced.fish
+++ b/share/functions/funced.fish
@@ -51,7 +51,7 @@ function funced --description 'Edit function definition'
if test -n "$editor"
set -l editor_cmd
eval set editor_cmd $editor
- if not type -f "$editor_cmd[1]" >/dev/null
+ if not type -q -f "$editor_cmd[1]"
_ "funced: The value for \$EDITOR '$editor' could not be used because the command '$editor_cmd[1]' could not be found
"
set editor fish
diff --git a/share/functions/help.fish b/share/functions/help.fish
index 04992e35..a04add53 100644
--- a/share/functions/help.fish
+++ b/share/functions/help.fish
@@ -25,7 +25,7 @@ function help --description 'Show help for the fish shell'
set -l graphical_browsers htmlview x-www-browser firefox galeon mozilla konqueror epiphany opera netscape rekonq google-chrome chromium-browser
set -l text_browsers htmlview www-browser links elinks lynx w3m
- if type "$BROWSER" >/dev/null
+ if type -q "$BROWSER"
# User has manually set a preferred browser, so we respect that
set fish_browser $BROWSER
@@ -36,7 +36,7 @@ function help --description 'Show help for the fish shell'
else
# Check for a text-based browser.
for i in $text_browsers
- if type -f $i >/dev/null
+ if type -q -f $i
set fish_browser $i
break
end
@@ -46,7 +46,7 @@ function help --description 'Show help for the fish shell'
# browser to use instead.
if test "$DISPLAY" -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \)
for i in $graphical_browsers
- if type -f $i >/dev/null
+ if type -q -f $i
set fish_browser $i
set fish_browser_bg 1
break
@@ -55,17 +55,17 @@ function help --description 'Show help for the fish shell'
end
# If the OS appears to be Windows (graphical), try to use cygstart
- if type cygstart > /dev/null
+ if type -q cygstart
set fish_browser cygstart
# If xdg-open is available, just use that
- else if type xdg-open > /dev/null
+ else if type -q xdg-open
set fish_browser xdg-open
end
# On OS X, we go through osascript by default
if test (uname) = Darwin
- if type osascript >/dev/null
+ if type -q osascript
set fish_browser osascript
end
end
@@ -92,7 +92,7 @@ function help --description 'Show help for the fish shell'
case $help_topics
set fish_help_page "index.html\#$fish_help_item"
case "*"
- if type -f $fish_help_item >/dev/null
+ if type -q -f $fish_help_item
# Prefer to use fish's man pages, to avoid
# the annoying useless "builtin" man page bash
# installs on OS X
diff --git a/share/functions/ls.fish b/share/functions/ls.fish
index dd4fb3a6..4824e1c1 100644
--- a/share/functions/ls.fish
+++ b/share/functions/ls.fish
@@ -13,7 +13,7 @@ if command ls --version 1>/dev/null 2>/dev/null
end
if not set -q LS_COLORS
- if type -f dircolors >/dev/null
+ if type -q -f dircolors
eval (dircolors -c | sed 's/>&\/dev\/null$//')
end
end
diff --git a/share/functions/open.fish b/share/functions/open.fish
index 63d56237..7a1e7bce 100644
--- a/share/functions/open.fish
+++ b/share/functions/open.fish
@@ -14,11 +14,11 @@ if not test (uname) = Darwin
end
end
- if type -f cygstart >/dev/null
+ if type -q -f cygstart
for i in $argv
cygstart $i
end
- else if type -f xdg-open >/dev/null
+ else if type -q -f xdg-open
for i in $argv
xdg-open $i
end
diff --git a/share/functions/seq.fish b/share/functions/seq.fish
index 0f5f8534..4229f0c5 100644
--- a/share/functions/seq.fish
+++ b/share/functions/seq.fish
@@ -2,7 +2,7 @@
# test -x in /usr/bin/seq because that's where it usually is and
# that's substantially cheaper than the type function
-if begin ; not test -x /usr/bin/seq ; and not type -f seq > /dev/null; end
+if begin ; not test -x /usr/bin/seq ; and not type -q -f seq; end
# No seq command
function seq --description "Print sequences of numbers"
__fish_fallback_seq $argv
diff --git a/share/functions/type.fish b/share/functions/type.fish
index 4a4c7703..e7bc7b28 100644
--- a/share/functions/type.fish
+++ b/share/functions/type.fish
@@ -4,79 +4,84 @@ function type --description "Print the type of a command"
# Initialize
set -l res 1
set -l mode normal
+ set -l multi no
set -l selection all
-
- #
- # Get options
- #
- set -l options
- set -l shortopt tpPafh
- if not getopt -T > /dev/null
- # GNU getopt
- set -l longopt type,path,force-path,all,no-functions,help
- set options -o $shortopt -l $longopt --
- # Verify options
- if not getopt -n type $options $argv >/dev/null
- return 1
- end
- else
- # Old getopt, used on OS X
- set options $shortopt
- # Verify options
- if not getopt $options $argv >/dev/null
- return 1
- end
- end
-
- # Do the real getopt invocation
- set -l tmp (getopt $options $argv)
-
- # Break tmp up into an array
- set -l opt
- eval set opt $tmp
-
- for i in $opt
- switch $i
- case -t --type
- set mode type
-
- case -p --path
- set mode path
-
- case -P --force-path
- set mode path
- set selection files
-
- case -a --all
- set selection multi
-
- case -f --no-functions
- set selection files
-
- case -h --help
- __fish_print_help type
- return 0
-
- case --
- break
+ # Parse options
+ set -l names
+ if test (count $argv) -gt 0
+ for i in (seq (count $argv))
+ set -l arg $argv[$i]
+ set -l needbreak 0
+ while test -n $arg
+ set -l flag $arg
+ set arg ''
+ switch $flag
+ case '--*'
+ # do nothing; this just prevents it matching the next case
+ case '-??*'
+ # combined flags
+ set -l IFS
+ echo -n $flag | read _ flag arg
+ set flag -$flag
+ set arg -$arg
+ end
+ switch $flag
+ case -t --type
+ if test $mode != quiet
+ set mode type
+ end
+
+ case -p --path
+ if test $mode != quiet
+ set mode path
+ end
+
+ case -P --force-path
+ if test $mode != quiet
+ set mode path
+ end
+ set selection files
+
+ case -a --all
+ set multi yes
+
+ case -f --no-functions
+ set selection files
+
+ case -q --quiet
+ set mode quiet
+
+ case -h --help
+ __fish_print_help type
+ return 0
+
+ case --
+ set names $argv[$i..-1]
+ set -e names[1]
+ set needbreak 1
+ break
+
+ case '*'
+ set names $argv[$i..-1]
+ set needbreak 1
+ break
+ end
+ end
+ if test $needbreak -eq 1
+ break
+ end
end
end
# Check all possible types for the remaining arguments
- for i in $argv
-
- switch $i
- case '-*'
- continue
- end
-
+ for i in $names
# Found will be set to 1 if a match is found
- set found 0
+ set -l found 0
if test $selection != files
- if contains -- $i (functions -na)
+ if functions -q -- $i
set res 0
set found 1
switch $mode
@@ -86,12 +91,8 @@ function type --description "Print the type of a command"
case type
echo (_ 'function')
-
- case path
- echo
-
end
- if test $selection != multi
+ if test $multi != yes
continue
end
end
@@ -106,11 +107,8 @@ function type --description "Print the type of a command"
case type
echo (_ 'builtin')
-
- case path
- echo
end
- if test $selection != multi
+ if test $multi != yes
continue
end
end
@@ -118,33 +116,31 @@ function type --description "Print the type of a command"
end
set -l paths
- if test $selection != multi
- set paths (which $i ^/dev/null)
+ if test $multi != yes
+ set paths (command -s -- $i)
else
- set paths (which -a $i ^/dev/null)
+ set paths (which -a -- $i ^/dev/null)
end
for path in $paths
- if test -x (echo $path)
- set res 0
- set found 1
- switch $mode
- case normal
- printf (_ '%s is %s\n') $i $path
+ set res 0
+ set found 1
+ switch $mode
+ case normal
+ printf (_ '%s is %s\n') $i $path
- case type
- echo (_ 'file')
+ case type
+ echo (_ 'file')
- case path
- echo $path
- end
- if test $selection != multi
- continue
- end
+ case path
+ echo $path
+ end
+ if test $multi != yes
+ continue
end
end
- if test $found = 0
- printf (_ "%s: Could not find '%s'\n") type $i
+ if begin; test $found = 0; and test $mode != quiet; end
+ printf (_ "%s: Could not find '%s'\n") type $i >&2
end
end
diff --git a/tests/read.err b/tests/read.err
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/read.err
diff --git a/tests/read.in b/tests/read.in
new file mode 100644
index 00000000..53f9873b
--- /dev/null
+++ b/tests/read.in
@@ -0,0 +1,72 @@
+#
+# Test read builtin and IFS
+#
+
+count (echo one\ntwo)
+set -l IFS \t
+count (echo one\ntwo)
+set -l IFS
+count (echo one\ntwo)
+set -le IFS
+
+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
+
+echo
+echo 'hello there' | read -l one two
+print_vars one two
+echo 'hello there' | read -l one
+print_vars one
+echo '' | read -l one
+print_vars one
+echo '' | read -l one two
+print_vars one two
+echo 'test' | read -l one two three
+print_vars one two three
+
+echo
+set -l IFS
+echo 'hello' | read -l one
+print_vars one
+echo 'hello' | read -l one two
+print_vars one two
+echo 'hello' | read -l one two three
+print_vars one two three
+echo '' | read -l one
+print_vars one
+echo 't' | read -l one two
+print_vars one two
+echo 't' | read -l one two three
+print_vars one two three
+echo ' t' | read -l one two
+print_vars one two
+set -le IFS
+
+echo
+echo 'hello there' | read -la ary
+print_vars ary
+echo 'hello' | read -la ary
+print_vars ary
+echo 'this is a bunch of words' | read -la ary
+print_vars ary
+echo ' one two three' | read -la ary
+print_vars ary
+echo '' | read -la ary
+print_vars ary
+
+echo
+set -l IFS
+echo 'hello' | read -la ary
+print_vars ary
+echo 'h' | read -la ary
+print_vars ary
+echo '' | read -la ary
+print_vars ary
+set -le IFS
diff --git a/tests/read.out b/tests/read.out
new file mode 100644
index 00000000..6d90fc0e
--- /dev/null
+++ b/tests/read.out
@@ -0,0 +1,27 @@
+2
+2
+1
+
+1 'hello' 1 'there'
+1 'hello there'
+1 ''
+1 '' 1 ''
+1 'test' 1 '' 1 ''
+
+1 'hello'
+1 'h' 1 'ello'
+1 'h' 1 'e' 1 'llo'
+1 ''
+1 't' 1 ''
+1 't' 1 '' 1 ''
+1 ' ' 1 't'
+
+2 'hello' 'there'
+1 'hello'
+6 'this' 'is' 'a' 'bunch' 'of' 'words'
+3 'one' 'two' 'three'
+0
+
+5 'h' 'e' 'l' 'l' 'o'
+1 'h'
+0
diff --git a/tests/read.status b/tests/read.status
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/tests/read.status
@@ -0,0 +1 @@
+0
diff --git a/tests/test7.in b/tests/test7.in
index a3ae8360..32298275 100644
--- a/tests/test7.in
+++ b/tests/test7.in
@@ -110,6 +110,6 @@ function fish_test_type_zzz
true
end
# Should succeed
-type fish_test_type_zzz >/dev/null ; echo $status
+type -q fish_test_type_zzz ; echo $status
# Should fail
-type -f fish_test_type_zzz >/dev/null ; echo $status
+type -q -f fish_test_type_zzz ; echo $status
diff --git a/tests/top.out b/tests/top.out
index 768526c6..f2873b15 100644
--- a/tests/top.out
+++ b/tests/top.out
@@ -1,5 +1,6 @@
Testing high level script functionality
File printf.in tested ok
+File read.in tested ok
File test1.in tested ok
File test2.in tested ok
File test3.in tested ok