Base status -b off the parser execution stack

Instead of globally marking the state as "in block" when evaluating
blocks/functions, update the "in block" status when pushing/popping
blocks on the parser stack.

Fixes #1729.

On a side note, `status -b` is actually pretty useless, because it
always returns 0 inside of a function (even without this patch).
This commit is contained in:
Kevin Ballard 2014-09-30 20:58:45 -07:00
parent 489fb7ec3f
commit 3616dd5889
4 changed files with 30 additions and 5 deletions

View file

@ -525,9 +525,6 @@ static void internal_exec_helper(parser_t &parser,
return; return;
} }
int is_block_old=is_block;
is_block=1;
signal_unblock(); signal_unblock();
if (node_offset == NODE_OFFSET_INVALID) if (node_offset == NODE_OFFSET_INVALID)
@ -544,7 +541,6 @@ static void internal_exec_helper(parser_t &parser,
morphed_chain.clear(); morphed_chain.clear();
io_cleanup_fds(opened_fds); io_cleanup_fds(opened_fds);
job_reap(0); job_reap(0);
is_block=is_block_old;
} }
/* Returns whether we can use posix spawn for a given process in a given job. /* Returns whether we can use posix spawn for a given process in a given job.

View file

@ -278,6 +278,12 @@ void parser_t::push_block(block_t *new_current)
this->block_stack.push_back(new_current); this->block_stack.push_back(new_current);
// Types TOP and SUBST are not considered blocks for the purposes of `status -b`
if (type != TOP && type != SUBST)
{
is_block = 1;
}
if ((new_current->type() != FUNCTION_DEF) && if ((new_current->type() != FUNCTION_DEF) &&
(new_current->type() != FAKE) && (new_current->type() != FAKE) &&
(new_current->type() != TOP)) (new_current->type() != TOP))
@ -305,6 +311,19 @@ void parser_t::pop_block()
env_pop(); env_pop();
delete old; delete old;
// Figure out if `status -b` should consider us to be in a block now
int new_is_block=0;
for (std::vector<block_t*>::const_iterator it = block_stack.begin(), end = block_stack.end(); it != end; ++it)
{
const enum block_type_t type = (*it)->type();
if (type != TOP && type != SUBST)
{
new_is_block = 1;
break;
}
}
is_block = new_is_block;
} }
void parser_t::pop_block(const block_t *expected) void parser_t::pop_block(const block_t *expected)

View file

@ -1,9 +1,17 @@
# vim: set filetype=fish: # vim: set filetype=fish:
status -b
or echo 'top level'
begin
status -b
end
and echo 'block'
# Issue #1728 # Issue #1728
# Bad file redirection on a block causes `status --is-block` to return 0 forever. # Bad file redirection on a block causes `status --is-block` to return 0 forever.
begin; end >/ # / is a directory, it can't be opened for writing begin; end >/ # / is a directory, it can't be opened for writing
status -b status -b
and echo 'block' and echo 'unexpected block'
true true

View file

@ -0,0 +1,2 @@
top level
block