diff --git a/builtin.cpp b/builtin.cpp index bd41923ed..c70880457 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -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) { + /* This won't ever work if no_exec is set */ + if (no_exec) + return wcstring(); + wcstring_list_t lst; wcstring out; 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 variables in the current loop scope won't die between laps. */ - int kill_block = 1; + bool kill_block = true; 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->skip = 0; - kill_block = 0; + kill_block = false; parser.set_pos(parser.current_block->tok_pos); while_block_t *blk = static_cast(parser.current_block); 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->skip = 0; - kill_block = 0; + kill_block = false; parser.set_pos(parser.current_block->tok_pos); } break; diff --git a/exec.cpp b/exec.cpp index 7a8d92a63..633a16e43 100644 --- a/exec.cpp +++ b/exec.cpp @@ -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; diff --git a/tests/top.err b/tests/top.err index 73a623c41..e69de29bb 100644 --- a/tests/top.err +++ b/tests/top.err @@ -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 - ^ diff --git a/tests/top.out b/tests/top.out index 0c7b1103a..768526c66 100644 --- a/tests/top.out +++ b/tests/top.out @@ -1,4 +1,5 @@ Testing high level script functionality +File printf.in tested ok File test1.in tested ok File test2.in tested ok File test3.in tested ok @@ -7,3 +8,4 @@ File test5.in tested ok File test6.in tested ok File test7.in tested ok File test8.in tested ok +File test9.in tested ok