Skip to content

Commit ad8d68d

Browse files
Make subcommands modify $status, and make builtin_set not modify status unless it fails
fish-shell#547 fish-shell#214
1 parent 0db1b6c commit ad8d68d

21 files changed

+143
-139
lines changed

autoload.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,9 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_
358358
/* If we have a script, either built-in or a file source, then run it */
359359
if (really_load && has_script_source)
360360
{
361-
if (exec_subshell(script_source) == -1)
361+
if (exec_subshell(script_source, false /* do not apply exit status */) == -1)
362362
{
363-
/*
364-
Do nothing on failiure
365-
*/
363+
/* Do nothing on failure */
366364
}
367365

368366
}

builtin.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ wcstring builtin_help_get(parser_t &parser, const wchar_t *name)
215215
wcstring out;
216216
const wcstring name_esc = escape_string(name, 1);
217217
const wcstring cmd = format_string(L"__fish_print_help %ls", name_esc.c_str());
218-
if (exec_subshell(cmd, lst) >= 0)
218+
if (exec_subshell(cmd, lst, false /* don't apply exit status */) >= 0)
219219
{
220220
for (size_t i=0; i<lst.size(); i++)
221221
{

builtin_set.cpp

+21-51
Original file line numberDiff line numberDiff line change
@@ -379,58 +379,21 @@ static void print_variables(int include_values, int esc, bool shorten_ok, int sc
379379
*/
380380
static int builtin_set(parser_t &parser, wchar_t **argv)
381381
{
382-
383-
/**
384-
Variables used for parsing the argument list
385-
*/
386-
static const struct woption
387-
long_options[] =
382+
/** Variables used for parsing the argument list */
383+
const struct woption long_options[] =
388384
{
389-
{
390-
L"export", no_argument, 0, 'x'
391-
}
392-
,
393-
{
394-
L"global", no_argument, 0, 'g'
395-
}
396-
,
397-
{
398-
L"local", no_argument, 0, 'l'
399-
}
400-
,
401-
{
402-
L"erase", no_argument, 0, 'e'
403-
}
404-
,
405-
{
406-
L"names", no_argument, 0, 'n'
407-
}
408-
,
409-
{
410-
L"unexport", no_argument, 0, 'u'
411-
}
412-
,
413-
{
414-
L"universal", no_argument, 0, 'U'
415-
}
416-
,
417-
{
418-
L"long", no_argument, 0, 'L'
419-
}
420-
,
421-
{
422-
L"query", no_argument, 0, 'q'
423-
}
424-
,
425-
{
426-
L"help", no_argument, 0, 'h'
427-
}
428-
,
429-
{
430-
0, 0, 0, 0
431-
}
432-
}
433-
;
385+
{ L"export", no_argument, 0, 'x' },
386+
{ L"global", no_argument, 0, 'g' },
387+
{ L"local", no_argument, 0, 'l' },
388+
{ L"erase", no_argument, 0, 'e' },
389+
{ L"names", no_argument, 0, 'n' },
390+
{ L"unexport", no_argument, 0, 'u' },
391+
{ L"universal", no_argument, 0, 'U' },
392+
{ L"long", no_argument, 0, 'L' },
393+
{ L"query", no_argument, 0, 'q' },
394+
{ L"help", no_argument, 0, 'h' },
395+
{ 0, 0, 0, 0 }
396+
} ;
434397

435398
const wchar_t *short_options = L"+xglenuULqh";
436399

@@ -443,6 +406,8 @@ static int builtin_set(parser_t &parser, wchar_t **argv)
443406
int erase = 0, list = 0, unexport=0;
444407
int universal = 0, query=0;
445408
bool shorten_ok = true;
409+
bool preserve_incoming_failure_exit_status = true;
410+
const int incoming_exit_status = proc_get_last_status();
446411

447412
/*
448413
Variables used for performing the actual work
@@ -474,10 +439,12 @@ static int builtin_set(parser_t &parser, wchar_t **argv)
474439

475440
case 'e':
476441
erase = 1;
442+
preserve_incoming_failure_exit_status = false;
477443
break;
478444

479445
case 'n':
480446
list = 1;
447+
preserve_incoming_failure_exit_status = false;
481448
break;
482449

483450
case 'x':
@@ -506,6 +473,7 @@ static int builtin_set(parser_t &parser, wchar_t **argv)
506473

507474
case 'q':
508475
query = 1;
476+
preserve_incoming_failure_exit_status = false;
509477
break;
510478

511479
case 'h':
@@ -825,6 +793,8 @@ static int builtin_set(parser_t &parser, wchar_t **argv)
825793

826794
free(dest);
827795

796+
if (retcode == STATUS_BUILTIN_OK && preserve_incoming_failure_exit_status)
797+
retcode = incoming_exit_status;
828798
return retcode;
829799

830800
}

color.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class rgb_color_t
135135
/** Returns whether the color is bold */
136136
bool is_bold() const
137137
{
138-
return !! (flags & flag_bold);
138+
return !!(flags & flag_bold);
139139
}
140140

141141
/** Set whether the color is bold */

common.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ extern const wchar_t *program_name;
150150
read( 0, &exit_read_buff, 1 ); \
151151
exit_without_destructors( 1 ); \
152152
} \
153-
153+
154154

155155
/**
156156
Exit program at once, leaving an error message about running out of memory.

complete.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ bool completer_t::condition_test(const wcstring &condition)
465465
if (cached_entry == condition_cache.end())
466466
{
467467
/* Compute new value and reinsert it */
468-
test_res = (0 == exec_subshell(condition));
468+
test_res = (0 == exec_subshell(condition, false /* don't apply exit status */));
469469
condition_cache[condition] = test_res;
470470
}
471471
else
@@ -1007,7 +1007,7 @@ void completer_t::complete_cmd_desc(const wcstring &str)
10071007
since apropos is only called once.
10081008
*/
10091009
wcstring_list_t list;
1010-
if (exec_subshell(lookup_cmd, list) != -1)
1010+
if (exec_subshell(lookup_cmd, list, false /* don't apply exit status */) != -1)
10111011
{
10121012

10131013
/*

doc_src/fish_prompt.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ By defining the \c fish_prompt function, the user can choose a custom
1111
prompt. The \c fish_prompt function is executed when the prompt is to
1212
be shown, and the output is used as a prompt.
1313

14-
Please keep in mind that the function is executed by <a
15-
href='index.html#expand-command-substitution'>command substitution</a>, and so the exit status of commands within fish_prompt will not modify the <a href="index.html#variables-status">$status</a> seen outside of fish_prompt.
14+
The exit status of commands within \c fish_prompt will not modify the <a href="index.html#variables-status">$status</a> seen outside of fish_prompt.
1615

1716
\subsection fish_prompt-example Example
1817

doc_src/index.hdr.in

+2-3
Original file line numberDiff line numberDiff line change
@@ -578,9 +578,8 @@ this list is executed, and substituted by the output. If the output is
578578
more than one line long, each line will be expanded to a new
579579
parameter.
580580

581-
A command substitution will not change the value of the <a
582-
href='#variables-status'>status</a> variable outside of the command
583-
substitution.
581+
The exit status of the last run command substitution is available in the <a
582+
href='#variables-status'>status</a> variable.
584583

585584
Only part of the output can be used, see <a href='#expand-index-range'>index
586585
range expansion</a> for details.

doc_src/set.txt

+14-7
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,14 @@ non-switch arguments. For example, <code>set flags -l</code> will have
6868
the effect of setting the value of the variable <code>flags</code> to
6969
'-l', not making the variable local.
7070

71-
In assignment mode, set exits with an exit status of zero it the
72-
variable assignments where sucessfully performed, with a non-zero exit
73-
status otherwise. In query mode, the exit status is the number of
74-
variables that where not found. In erase mode, set exits with a zero
75-
exit status in case of success, with a non-zero exit status if the
76-
commandline was invalid, if the variable was write-protected or if the
77-
variable did not exist.
71+
In assignment mode, set exits with a non-zero exit status if variable
72+
assignments could not be successfully performed. If the variable assignments
73+
were performed, the exit status is unchanged. This allows simultaneous capture
74+
of the output and exit status of a subcommand, e.g. <code>if set output
75+
(command)</code>. In query mode, the exit status is the number of variables that
76+
were not found. In erase mode, set exits with a zero exit status in case of
77+
success, with a non-zero exit status if the commandline was invalid, if the
78+
variable was write-protected or if the variable did not exist.
7879

7980
\subsection set-example Example
8081

@@ -85,3 +86,9 @@ variable did not exist.
8586
<code>set -e smurf</code> removes the variable \c smurf.
8687

8788
<code>set PATH[4] ~/bin</code> changes the fourth element of the \c PATH array to \c ~/bin
89+
90+
<pre>if set python_path (which python)
91+
echo "Python is at $python_path"
92+
end</pre>
93+
94+
The above outputs the path to Python if \c which returns true.

0 commit comments

Comments
 (0)