mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
Trim trailing newline on cmdsubst when IFS=''
When $IFS is empty, command substitution no longer splits on newlines. However we still want to trim off a single trailing newline, as most commands will emit a trailing newline and it makes it harder to work with their output.
This commit is contained in:
parent
cc52a59e1a
commit
7fce9e2411
3 changed files with 43 additions and 16 deletions
19
exec.cpp
19
exec.cpp
|
@ -1540,7 +1540,7 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst, boo
|
||||||
ASSERT_IS_MAIN_THREAD();
|
ASSERT_IS_MAIN_THREAD();
|
||||||
int prev_subshell = is_subshell;
|
int prev_subshell = is_subshell;
|
||||||
const int prev_status = proc_get_last_status();
|
const int prev_status = proc_get_last_status();
|
||||||
char sep=0;
|
bool split_output=false;
|
||||||
|
|
||||||
//fprintf(stderr, "subcmd %ls\n", cmd.c_str());
|
//fprintf(stderr, "subcmd %ls\n", cmd.c_str());
|
||||||
|
|
||||||
|
@ -1548,7 +1548,7 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst, boo
|
||||||
|
|
||||||
if (! ifs.missing_or_empty())
|
if (! ifs.missing_or_empty())
|
||||||
{
|
{
|
||||||
sep = '\n';
|
split_output=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_subshell=1;
|
is_subshell=1;
|
||||||
|
@ -1580,11 +1580,13 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst, boo
|
||||||
{
|
{
|
||||||
const char *begin = io_buffer->out_buffer_ptr();
|
const char *begin = io_buffer->out_buffer_ptr();
|
||||||
const char *end = begin + io_buffer->out_buffer_size();
|
const char *end = begin + io_buffer->out_buffer_size();
|
||||||
|
if (split_output)
|
||||||
|
{
|
||||||
const char *cursor = begin;
|
const char *cursor = begin;
|
||||||
while (cursor < end)
|
while (cursor < end)
|
||||||
{
|
{
|
||||||
// Look for the next separator
|
// Look for the next separator
|
||||||
const char *stop = (const char *)memchr(cursor, sep, end - cursor);
|
const char *stop = (const char *)memchr(cursor, '\n', end - cursor);
|
||||||
const bool hit_separator = (stop != NULL);
|
const bool hit_separator = (stop != NULL);
|
||||||
if (! hit_separator)
|
if (! hit_separator)
|
||||||
{
|
{
|
||||||
|
@ -1599,6 +1601,17 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst, boo
|
||||||
cursor = stop + (hit_separator ? 1 : 0);
|
cursor = stop + (hit_separator ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we're not splitting output, but we still want to trim off a trailing newline
|
||||||
|
if (end != begin && end[-1] == '\n')
|
||||||
|
{
|
||||||
|
--end;
|
||||||
|
}
|
||||||
|
const wcstring wc = str2wcstring(begin, end - begin);
|
||||||
|
lst->push_back(wc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return subcommand_status;
|
return subcommand_status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,11 @@ set -l IFS \t
|
||||||
count (echo one\ntwo)
|
count (echo one\ntwo)
|
||||||
set -l IFS
|
set -l IFS
|
||||||
count (echo one\ntwo)
|
count (echo one\ntwo)
|
||||||
|
echo [(echo -n one\ntwo)]
|
||||||
|
count (echo one\ntwo\n)
|
||||||
|
echo [(echo -n one\ntwo\n)]
|
||||||
|
count (echo one\ntwo\n\n)
|
||||||
|
echo [(echo -n one\ntwo\n\n)]
|
||||||
set -le IFS
|
set -le IFS
|
||||||
|
|
||||||
function print_vars --no-scope-shadowing
|
function print_vars --no-scope-shadowing
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
2
|
2
|
||||||
2
|
2
|
||||||
1
|
1
|
||||||
|
[one
|
||||||
|
two]
|
||||||
|
1
|
||||||
|
[one
|
||||||
|
two]
|
||||||
|
1
|
||||||
|
[one
|
||||||
|
two
|
||||||
|
]
|
||||||
|
|
||||||
1 'hello' 1 'there'
|
1 'hello' 1 'there'
|
||||||
1 'hello there'
|
1 'hello there'
|
||||||
|
|
Loading…
Reference in a new issue