mirror of
https://github.com/ksherlock/mpw-shell.git
synced 2024-06-25 04:29:28 +00:00
rewrite command execution to be more consistent with real mpw.
This commit is contained in:
parent
413b9a805b
commit
c2c41f3a52
434
command.cpp
434
command.cpp
|
@ -53,8 +53,8 @@ namespace {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
int evaluate(int type, const std::string &s, Environment &env) {
|
int evaluate(int type, const std::string &s, Environment &env) {
|
||||||
|
std::string tmp(s);
|
||||||
auto tokens = tokenize(s, true);
|
auto tokens = tokenize(tmp, true);
|
||||||
std::reverse(tokens.begin(), tokens.end());
|
std::reverse(tokens.begin(), tokens.end());
|
||||||
|
|
||||||
int32_t e;
|
int32_t e;
|
||||||
|
@ -92,6 +92,47 @@ namespace {
|
||||||
}
|
}
|
||||||
return !!e;
|
return !!e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int evaluate(int type, std::vector<token> &&tokens, Environment &env) {
|
||||||
|
std::reverse(tokens.begin(), tokens.end());
|
||||||
|
|
||||||
|
int32_t e;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
default: return 0;
|
||||||
|
|
||||||
|
case BREAK:
|
||||||
|
case CONTINUE:
|
||||||
|
case ELSE:
|
||||||
|
tokens.pop_back();
|
||||||
|
|
||||||
|
if (tokens.empty()) return 1;
|
||||||
|
|
||||||
|
if (strcasecmp(tokens.back().string.c_str(), "if") != 0) {
|
||||||
|
const char *name = "";
|
||||||
|
switch(type) {
|
||||||
|
case BREAK: name = "Break"; break;
|
||||||
|
case CONTINUE: name = "Continue"; break;
|
||||||
|
case ELSE: name = "Else"; break;
|
||||||
|
}
|
||||||
|
return bad_if(name);
|
||||||
|
}
|
||||||
|
// fall through.
|
||||||
|
case IF:
|
||||||
|
tokens.pop_back();
|
||||||
|
try {
|
||||||
|
e = evaluate_expression("If", std::move(tokens));
|
||||||
|
}
|
||||||
|
catch (std::exception &ex) {
|
||||||
|
fprintf(stderr, "%s\n", ex.what());
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return !!e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -285,61 +326,115 @@ command::~command()
|
||||||
* echo and error should respect the active fdmask.
|
* echo and error should respect the active fdmask.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int simple_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
int exec(std::string command, Environment &env, bool throwup, F &&fx) {
|
||||||
|
|
||||||
if (control_c) throw execution_of_input_terminated();
|
if (control_c) throw execution_of_input_terminated();
|
||||||
|
bool echo = true;
|
||||||
std::string s = expand_vars(text, env);
|
|
||||||
|
|
||||||
|
|
||||||
process p;
|
|
||||||
try {
|
try {
|
||||||
auto tokens = tokenize(s, false);
|
process p;
|
||||||
|
command = expand_vars(command, env);
|
||||||
|
auto tokens = tokenize(command, false);
|
||||||
if (tokens.empty()) return 0;
|
if (tokens.empty()) return 0;
|
||||||
parse_tokens(std::move(tokens), p);
|
parse_tokens(std::move(tokens), p);
|
||||||
} catch(std::exception &e) {
|
env.echo("%s", command.c_str());
|
||||||
|
echo = false;
|
||||||
|
|
||||||
|
if (p.arguments.empty()) return env.status(0);
|
||||||
|
|
||||||
|
return env.status(fx(p), throwup);
|
||||||
|
}
|
||||||
|
catch (mpw_error &e) {
|
||||||
|
if (echo) env.echo("%s", command.c_str());
|
||||||
fprintf(stderr, "%s\n", e.what());
|
fprintf(stderr, "%s\n", e.what());
|
||||||
|
return env.status(e.status(), throwup);
|
||||||
|
}
|
||||||
|
catch (std::exception &e) {
|
||||||
|
if (echo) env.echo("%s", command.c_str());
|
||||||
|
fprintf(stderr, "### %s\n", e.what());
|
||||||
return env.status(-4, throwup);
|
return env.status(-4, throwup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.arguments.empty()) return 0;
|
|
||||||
|
|
||||||
env.echo("%s", s.c_str());
|
|
||||||
|
|
||||||
fdmask newfds = p.fds | fds;
|
|
||||||
|
|
||||||
std::string name = p.arguments.front();
|
|
||||||
lowercase(name);
|
|
||||||
|
|
||||||
auto iter = builtins.find(name);
|
|
||||||
if (iter != builtins.end()) {
|
|
||||||
env.set("command", name);
|
|
||||||
int status = iter->second(env, p.arguments, newfds);
|
|
||||||
return env.status(status, throwup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (env.test()) return env.status(0);
|
|
||||||
if (env.startup()) {
|
|
||||||
fprintf(stderr, "### MPW Shell - startup file may not contain external commands.\n");
|
|
||||||
return env.status(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
name = p.arguments.front();
|
|
||||||
fs::path path = which(env, name);
|
|
||||||
if (path.empty()) {
|
|
||||||
fprintf(stderr, "### MPW Shell - Command \"%s\" was not found.\n", name.c_str());
|
|
||||||
return env.status(-1, throwup);
|
|
||||||
}
|
|
||||||
env.set("command", path);
|
|
||||||
p.arguments[0] = path;
|
|
||||||
|
|
||||||
int status = execute_external(env, p.arguments, newfds);
|
|
||||||
|
|
||||||
return env.status(status, throwup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int simple_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
|
|
||||||
|
|
||||||
|
return exec(text, env, throwup, [&](process &p){
|
||||||
|
|
||||||
|
fdmask newfds = p.fds | fds;
|
||||||
|
|
||||||
|
std::string name = p.arguments.front();
|
||||||
|
lowercase(name);
|
||||||
|
|
||||||
|
auto iter = builtins.find(name);
|
||||||
|
if (iter != builtins.end()) {
|
||||||
|
env.set("command", name);
|
||||||
|
int status = iter->second(env, p.arguments, newfds);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env.test()) return 0;
|
||||||
|
|
||||||
|
if (env.startup()) {
|
||||||
|
fprintf(stderr, "### MPW Shell - startup file may not contain external commands.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = p.arguments.front();
|
||||||
|
fs::path path = which(env, name);
|
||||||
|
if (path.empty()) {
|
||||||
|
fprintf(stderr, "### MPW Shell - Command \"%s\" was not found.\n", name.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
env.set("command", path);
|
||||||
|
p.arguments[0] = path;
|
||||||
|
|
||||||
|
return execute_external(env, p.arguments, newfds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
int eval_exec(std::string command, Environment &env, bool throwup, F &&fx){
|
||||||
|
|
||||||
|
bool echo = true;
|
||||||
|
if (control_c) throw execution_of_input_terminated();
|
||||||
|
std::string name;
|
||||||
|
try {
|
||||||
|
command = expand_vars(command, env);
|
||||||
|
auto tokens = tokenize(command, true);
|
||||||
|
|
||||||
|
if (tokens.empty()) return 0;
|
||||||
|
env.echo("%s", command.c_str());
|
||||||
|
echo = false;
|
||||||
|
name = tokens[0].string;
|
||||||
|
|
||||||
|
int ok = fx(tokens);
|
||||||
|
return env.status(ok, throwup);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (mpw_error &e) {
|
||||||
|
if (echo) env.echo("%s", command.c_str());
|
||||||
|
fprintf(stderr, "### %s\n", e.what());
|
||||||
|
return env.status(e.status(), throwup);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(std::exception &e) {
|
||||||
|
// these should include the argv0 name.
|
||||||
|
if (echo) env.echo("%s", command.c_str());
|
||||||
|
fprintf(stderr, "### %s - %s\n", name.c_str(), e.what());
|
||||||
|
return env.status(-4, throwup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typedef std::vector<token> token_vector;
|
||||||
|
|
||||||
int evaluate_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
int evaluate_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (control_c) throw execution_of_input_terminated();
|
if (control_c) throw execution_of_input_terminated();
|
||||||
|
|
||||||
std::string s = expand_vars(text, env);
|
std::string s = expand_vars(text, env);
|
||||||
|
@ -359,11 +454,28 @@ int evaluate_command::execute(Environment &env, const fdmask &fds, bool throwup)
|
||||||
fprintf(stderr, "%s\n", e.what());
|
fprintf(stderr, "%s\n", e.what());
|
||||||
return env.status(1, throwup);
|
return env.status(1, throwup);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return eval_exec(text, env, throwup, [&](token_vector &tokens){
|
||||||
|
env.set("command", "evaluate");
|
||||||
|
return builtin_evaluate(env, std::move(tokens), fds);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int break_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
int break_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
|
|
||||||
|
return eval_exec(text, env, throwup, [&](token_vector &tokens){
|
||||||
|
env.set("command", "break");
|
||||||
|
if (!env.loop()) throw break_error();
|
||||||
|
int status = evaluate(BREAK, std::move(tokens), env);
|
||||||
|
if (status > 0) throw break_command_t();
|
||||||
|
return status;
|
||||||
|
});
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (control_c) throw execution_of_input_terminated();
|
if (control_c) throw execution_of_input_terminated();
|
||||||
|
|
||||||
std::string s = expand_vars(text, env);
|
std::string s = expand_vars(text, env);
|
||||||
|
@ -381,11 +493,20 @@ int break_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
if (status > 0)
|
if (status > 0)
|
||||||
throw break_command_t();
|
throw break_command_t();
|
||||||
return env.status(status, throwup);
|
return env.status(status, throwup);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int continue_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
int continue_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
|
|
||||||
|
return eval_exec(text, env, throwup, [&](token_vector &tokens){
|
||||||
|
env.set("command", "continue");
|
||||||
|
if (!env.loop()) throw continue_error();
|
||||||
|
int status = evaluate(CONTINUE, std::move(tokens), env);
|
||||||
|
if (status > 0) throw continue_command_t();
|
||||||
|
return status;
|
||||||
|
});
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (control_c) throw execution_of_input_terminated();
|
if (control_c) throw execution_of_input_terminated();
|
||||||
|
|
||||||
std::string s = expand_vars(text, env);
|
std::string s = expand_vars(text, env);
|
||||||
|
@ -404,7 +525,7 @@ int continue_command::execute(Environment &env, const fdmask &fds, bool throwup)
|
||||||
if (status > 0)
|
if (status > 0)
|
||||||
throw continue_command_t();
|
throw continue_command_t();
|
||||||
return env.status(status, throwup);
|
return env.status(status, throwup);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int or_command::execute(Environment &e, const fdmask &fds, bool throwup) {
|
int or_command::execute(Environment &e, const fdmask &fds, bool throwup) {
|
||||||
|
@ -447,22 +568,17 @@ int pipe_command::execute(Environment &e, const fdmask &fds, bool throwup) {
|
||||||
fdset pipe_fd;
|
fdset pipe_fd;
|
||||||
|
|
||||||
fd = mkstemp(temp);
|
fd = mkstemp(temp);
|
||||||
|
unlink(temp);
|
||||||
pipe_fd.set(1, fd);
|
pipe_fd.set(1, fd);
|
||||||
|
|
||||||
try {
|
rv = children[0]->execute(e, pipe_fd | fds, throwup);
|
||||||
|
|
||||||
rv = children[0]->execute(e, pipe_fd | fds, throwup);
|
// fdset will close the fd ...
|
||||||
|
pipe_fd.swap_in_out();
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
// fdset will close the fd ...
|
rv = children[1]->execute(e, pipe_fd | fds, throwup);
|
||||||
pipe_fd.swap_in_out();
|
|
||||||
lseek(fd, 0, SEEK_SET);
|
|
||||||
|
|
||||||
rv = children[1]->execute(e, pipe_fd | fds, throwup);
|
|
||||||
|
|
||||||
} catch(std::exception &ex) {
|
|
||||||
unlink(temp);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (children[0]) return children[0]->execute(e, fds, throwup);
|
if (children[0]) return children[0]->execute(e, fds, throwup);
|
||||||
if (children[1]) return children[1]->execute(e, fds, throwup);
|
if (children[1]) return children[1]->execute(e, fds, throwup);
|
||||||
|
@ -518,7 +634,8 @@ namespace {
|
||||||
// MPW ignores any END tokens other than redirection.
|
// MPW ignores any END tokens other than redirection.
|
||||||
process p;
|
process p;
|
||||||
try {
|
try {
|
||||||
auto tokens = tokenize(s, false);
|
std::string tmp(s);
|
||||||
|
auto tokens = tokenize(tmp, false);
|
||||||
parse_tokens(std::move(tokens), p);
|
parse_tokens(std::move(tokens), p);
|
||||||
}
|
}
|
||||||
catch (std::exception &e) {
|
catch (std::exception &e) {
|
||||||
|
@ -530,8 +647,68 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
int begin_end_exec(std::string begin, std::string end, Environment &env, bool throwup, F &&fx) {
|
||||||
|
|
||||||
|
if (control_c) throw execution_of_input_terminated();
|
||||||
|
|
||||||
|
bool echo = true;
|
||||||
|
try {
|
||||||
|
process p;
|
||||||
|
begin = expand_vars(begin, env);
|
||||||
|
end = expand_vars(end, env);
|
||||||
|
|
||||||
|
auto b = tokenize(begin, true);
|
||||||
|
auto e = tokenize(end, false);
|
||||||
|
|
||||||
|
parse_tokens(std::move(e), p);
|
||||||
|
|
||||||
|
if (echo) env.echo("%s ... %s", begin.c_str(), end.c_str() );
|
||||||
|
|
||||||
|
int ok = fx(b, p);
|
||||||
|
return env.status(ok, throwup);
|
||||||
|
}
|
||||||
|
catch (execution_of_input_terminated &e) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (mpw_error &e) {
|
||||||
|
if (echo) env.echo("%s ... %s", begin.c_str(), end.c_str() );
|
||||||
|
fprintf(stderr, "%s\n", e.what());
|
||||||
|
return env.status(e.status(), throwup);
|
||||||
|
}
|
||||||
|
catch (std::exception &e) {
|
||||||
|
if (echo) env.echo("%s ... %s", begin.c_str(), end.c_str() );
|
||||||
|
fprintf(stderr, "### %s\n", e.what());
|
||||||
|
return env.status(-4, throwup);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int begin_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
int begin_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
// todo -- parse end for redirection.
|
|
||||||
|
return begin_end_exec(begin, end, env, throwup, [&](token_vector &b, process &p){
|
||||||
|
|
||||||
|
env.set("command", type == BEGIN ? "end" : ")");
|
||||||
|
if (b.size() != 1) {
|
||||||
|
fprintf(stderr, "### Begin - Too many parameters were specified.\n");
|
||||||
|
fprintf(stderr, "Usage - Begin\n");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
fdmask newfds = p.fds | fds;
|
||||||
|
|
||||||
|
int rv;
|
||||||
|
env.indent_and([&]{
|
||||||
|
rv = vector_command::execute(env, newfds);
|
||||||
|
});
|
||||||
|
|
||||||
|
env.echo("%s", type == BEGIN ? "end" : ")");
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
});
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
std::string b = expand_vars(begin, env);
|
std::string b = expand_vars(begin, env);
|
||||||
std::string e = expand_vars(end, env);
|
std::string e = expand_vars(end, env);
|
||||||
|
@ -570,11 +747,47 @@ int begin_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
env.echo("%s", type == BEGIN ? "end" : ")");
|
env.echo("%s", type == BEGIN ? "end" : ")");
|
||||||
|
|
||||||
return env.status(rv);
|
return env.status(rv);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int loop_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
int loop_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
|
|
||||||
|
return begin_end_exec(begin, end, env, throwup, [&](token_vector &b, process &p){
|
||||||
|
|
||||||
|
env.set("command", "end");
|
||||||
|
if (b.size() != 1) {
|
||||||
|
fprintf(stderr, "### Loop - Too many parameters were specified.\n");
|
||||||
|
fprintf(stderr, "Usage - Loop\n");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
fdmask newfds = p.fds | fds;
|
||||||
|
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
|
||||||
|
if (control_c) throw execution_of_input_terminated();
|
||||||
|
|
||||||
|
try {
|
||||||
|
env.indent_and([&]{
|
||||||
|
rv = vector_command::execute(env, newfds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (break_command_t &ex) {
|
||||||
|
env.echo("end");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (continue_command_t &ex) {}
|
||||||
|
env.echo("end");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
std::string b = expand_vars(begin, env);
|
std::string b = expand_vars(begin, env);
|
||||||
std::string e = expand_vars(end, env);
|
std::string e = expand_vars(end, env);
|
||||||
|
|
||||||
|
@ -618,10 +831,47 @@ int loop_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
env.echo("end");
|
env.echo("end");
|
||||||
}
|
}
|
||||||
return env.status(rv);
|
return env.status(rv);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int for_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
int for_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
|
|
||||||
|
return begin_end_exec(begin, end, env, throwup, [&](token_vector &b, process &p){
|
||||||
|
|
||||||
|
env.set("command", "end");
|
||||||
|
|
||||||
|
if (b.size() < 3 || strcasecmp(b[2].string.c_str(), "in")) {
|
||||||
|
fprintf(stderr, "### For - Missing in keyword.\n");
|
||||||
|
fprintf(stderr, "Usage - For name in [word...]\n");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
fdmask newfds = p.fds | fds;
|
||||||
|
|
||||||
|
int rv = 0;
|
||||||
|
for (int i = 3; i < b.size(); ++i ) {
|
||||||
|
|
||||||
|
if (control_c) throw execution_of_input_terminated();
|
||||||
|
|
||||||
|
env.set(b[1].string, b[i].string);
|
||||||
|
|
||||||
|
try {
|
||||||
|
env.loop_indent_and([&]{
|
||||||
|
rv = vector_command::execute(env, newfds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (break_command_t &ex) {
|
||||||
|
env.echo("end");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (continue_command_t &ex) {}
|
||||||
|
env.echo("end");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
});
|
||||||
|
|
||||||
|
#if 0
|
||||||
std::string b = expand_vars(begin, env);
|
std::string b = expand_vars(begin, env);
|
||||||
std::string e = expand_vars(end, env);
|
std::string e = expand_vars(end, env);
|
||||||
|
|
||||||
|
@ -668,16 +918,83 @@ int for_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return env.status(rv);
|
return env.status(rv);
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the entire command prints even if there is an error with the expression.
|
* the entire command prints even if there is an error with the expression.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int if_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
int if_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
|
|
||||||
|
|
||||||
|
int rv = 0;
|
||||||
|
int error = 0;
|
||||||
|
bool skip = false;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
fdmask newfds;
|
||||||
|
for (auto &c : clauses) {
|
||||||
|
|
||||||
|
int tmp;
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
tmp = begin_end_exec(c->clause, end, env, false, [&](token_vector &b, process &p){
|
||||||
|
|
||||||
|
newfds = p.fds | fds;
|
||||||
|
|
||||||
|
int status = evaluate(c->type, std::move(b), env);
|
||||||
|
if (status < 0) {
|
||||||
|
error = status;
|
||||||
|
}
|
||||||
|
if (status > 0) {
|
||||||
|
skip = true;
|
||||||
|
|
||||||
|
env.indent_and([&](){
|
||||||
|
rv = c->execute(env, newfds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
if (tmp != 0) error = tmp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// second...
|
||||||
|
tmp = eval_exec(c->clause, env, false, [&](token_vector &b){
|
||||||
|
if (skip || error) return 0;
|
||||||
|
|
||||||
|
int status = evaluate(c->type, std::move(b), env);
|
||||||
|
if (status < 0) {
|
||||||
|
error = status;
|
||||||
|
}
|
||||||
|
if (status > 0) {
|
||||||
|
skip = true;
|
||||||
|
|
||||||
|
env.indent_and([&](){
|
||||||
|
rv = c->execute(env, newfds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
});
|
||||||
|
if (tmp != 0 && !skip) error = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env.echo("end");
|
||||||
|
if (error) return env.status(error, throwup);
|
||||||
|
return env.status(rv, throwup);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
|
@ -715,5 +1032,6 @@ int if_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
|
|
||||||
env.echo("end");
|
env.echo("end");
|
||||||
return env.status(rv);
|
return env.status(rv);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user