Teach fish how to push and pop blocks even in the face of no_exec. All tests finally pass.

https://github.com/fish-shell/fish-shell/issues/624
This commit is contained in:
ridiculousfish 2013-03-25 16:06:12 -07:00
parent d146f578a4
commit b04e874e43
4 changed files with 43 additions and 11 deletions

View file

@ -211,6 +211,10 @@ static int count_char(const wchar_t *str, wchar_t c)
wcstring builtin_help_get(parser_t &parser, const wchar_t *name) wcstring builtin_help_get(parser_t &parser, const wchar_t *name)
{ {
/* This won't ever work if no_exec is set */
if (no_exec)
return wcstring();
wcstring_list_t lst; wcstring_list_t lst;
wcstring out; wcstring out;
const wcstring name_esc = escape_string(name, 1); const wcstring name_esc = escape_string(name, 1);
@ -3481,7 +3485,7 @@ static int builtin_end(parser_t &parser, wchar_t **argv)
are rewinding a loop, this should be set to false, so that are rewinding a loop, this should be set to false, so that
variables in the current loop scope won't die between laps. variables in the current loop scope won't die between laps.
*/ */
int kill_block = 1; bool kill_block = true;
switch (parser.current_block->type()) switch (parser.current_block->type())
{ {
@ -3495,7 +3499,7 @@ static int builtin_end(parser_t &parser, wchar_t **argv)
{ {
parser.current_block->loop_status = LOOP_NORMAL; parser.current_block->loop_status = LOOP_NORMAL;
parser.current_block->skip = 0; parser.current_block->skip = 0;
kill_block = 0; kill_block = false;
parser.set_pos(parser.current_block->tok_pos); parser.set_pos(parser.current_block->tok_pos);
while_block_t *blk = static_cast<while_block_t *>(parser.current_block); while_block_t *blk = static_cast<while_block_t *>(parser.current_block);
blk->status = WHILE_TEST_AGAIN; blk->status = WHILE_TEST_AGAIN;
@ -3536,7 +3540,7 @@ static int builtin_end(parser_t &parser, wchar_t **argv)
parser.current_block->loop_status = LOOP_NORMAL; parser.current_block->loop_status = LOOP_NORMAL;
parser.current_block->skip = 0; parser.current_block->skip = 0;
kill_block = 0; kill_block = false;
parser.set_pos(parser.current_block->tok_pos); parser.set_pos(parser.current_block->tok_pos);
} }
break; break;

View file

@ -538,6 +538,37 @@ static bool can_use_posix_spawn_for_job(const job_t *job, const process_t *proce
return result; return result;
} }
/* What exec does if no_exec is set. This only has to handle block pushing and popping. See #624. */
static void exec_no_exec(parser_t &parser, const job_t *job)
{
/* Hack hack hack. If this is an 'end' job, then trigger a pop. If this is a job that would create a block, trigger a push. See #624 */
const process_t *p = job->first_process;
if (p && p->type == INTERNAL_BUILTIN)
{
const wchar_t *builtin_name_cstr = p->argv0();
if (builtin_name_cstr != NULL)
{
const wcstring builtin_name = builtin_name_cstr;
if (contains(builtin_name, L"for", L"function", L"begin", L"switch"))
{
// The above builtins are the ones that produce an unbalanced block from within their function implementation
// This list should be maintained somewhere else
parser.push_block(new fake_block_t());
}
else if (builtin_name == L"end")
{
if (parser.current_block == NULL || parser.current_block->type() == TOP)
{
fprintf(stderr, "Warning: not popping the root block\n");
}
else
{
parser.pop_block();
}
}
}
}
}
void exec(parser_t &parser, job_t *j) void exec(parser_t &parser, job_t *j)
{ {
@ -559,8 +590,10 @@ void exec(parser_t &parser, job_t *j)
CHECK(j,); CHECK(j,);
CHECK_BLOCK(); CHECK_BLOCK();
if (no_exec) if (no_exec) {
exec_no_exec(parser, j);
return; return;
}
sigemptyset(&chldset); sigemptyset(&chldset);
sigaddset(&chldset, SIGCHLD); sigaddset(&chldset, SIGCHLD);
@ -1269,7 +1302,6 @@ void exec(parser_t &parser, job_t *j)
p->pid = pid; p->pid = pid;
set_child_group(j, p, 0); set_child_group(j, p, 0);
} }
break; break;

View file

@ -1,6 +0,0 @@
fish: Expected redirection specification, got token of type '$i'
/usr/local/src/grissioms-fish-shell/tests/test.fish (line 51): ../fish <$i >tmp.out ^tmp.err
^
fish: Expected redirection specification, got token of type '$i'
/usr/local/src/grissioms-fish-shell/tests/test.fish (line 51): ../fish <$i >tmp.out ^tmp.err
^

View file

@ -1,4 +1,5 @@
Testing high level script functionality Testing high level script functionality
File printf.in tested ok
File test1.in tested ok File test1.in tested ok
File test2.in tested ok File test2.in tested ok
File test3.in tested ok File test3.in tested ok
@ -7,3 +8,4 @@ File test5.in tested ok
File test6.in tested ok File test6.in tested ok
File test7.in tested ok File test7.in tested ok
File test8.in tested ok File test8.in tested ok
File test9.in tested ok