diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2013-03-25 16:06:12 -0700 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2013-03-25 16:06:12 -0700 |
commit | b04e874e432fddb603aa023f39433a4be0387d89 (patch) | |
tree | 236aa67b79e6934a227672ebe6e94b1082f63d11 /exec.cpp | |
parent | d146f578a49ad4164662a6b1bb9db474c3a1b269 (diff) |
Teach fish how to push and pop blocks even in the face of no_exec. All tests finally pass.
Diffstat (limited to 'exec.cpp')
-rw-r--r-- | exec.cpp | 36 |
1 files changed, 34 insertions, 2 deletions
@@ -538,6 +538,37 @@ static bool can_use_posix_spawn_for_job(const job_t *job, const process_t *proce 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) { @@ -559,8 +590,10 @@ void exec(parser_t &parser, job_t *j) CHECK(j,); CHECK_BLOCK(); - if (no_exec) + if (no_exec) { + exec_no_exec(parser, j); return; + } sigemptyset(&chldset); sigaddset(&chldset, SIGCHLD); @@ -1269,7 +1302,6 @@ void exec(parser_t &parser, job_t *j) p->pid = pid; set_child_group(j, p, 0); - } break; |