mirror of
https://github.com/ksherlock/mpw-shell.git
synced 2026-01-23 09:16:32 +00:00
Squashed commit of the following:
commit f0944a89f27e44b1764988806e655f09764e80df Author: Kelvin Sherlock <ksherlock@gmail.com> Date: Tue Aug 30 12:24:08 2016 -0400 exit throws execution of input error w/ possible 0 value. catch it. commit 9e7f9c1ae049aa26513413f4767268b47ee22e98 Author: Kelvin Sherlock <ksherlock@gmail.com> Date: Tue Aug 30 12:23:21 2016 -0400 builtins - more consistent argument handling. commit be4c1c902f5a3a3f01e92ae52c7d6cc5d8731b65 Author: Kelvin Sherlock <ksherlock@gmail.com> Date: Tue Aug 30 12:23:01 2016 -0400 . commit 68d0c29fec112c6e7bc3a672b41eb7eb758a8941 Author: Kelvin Sherlock <ksherlock@gmail.com> Date: Tue Aug 30 12:22:51 2016 -0400 exit command. commit 25b0a7f7da9220b03026123bb5072c2da1d73fde Author: Kelvin Sherlock <ksherlock@gmail.com> Date: Tue Aug 30 12:21:16 2016 -0400 builtin quit command.
This commit is contained in:
53
command.cpp
53
command.cpp
@@ -5,6 +5,7 @@
|
||||
#include "builtins.h"
|
||||
#include "mpw-shell.h"
|
||||
#include "error.h"
|
||||
#include "value.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
@@ -17,6 +18,7 @@
|
||||
#include "cxx/filesystem.h"
|
||||
#include "cxx/string_splitter.h"
|
||||
|
||||
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
@@ -40,8 +42,7 @@ typedef std::vector<token> token_vector;
|
||||
|
||||
namespace {
|
||||
|
||||
struct break_command_t {};
|
||||
struct continue_command_t {};
|
||||
|
||||
|
||||
/*
|
||||
* returns:
|
||||
@@ -56,6 +57,12 @@ namespace {
|
||||
return -3;
|
||||
}
|
||||
|
||||
int bad_exit() {
|
||||
fprintf(stderr, "### Exit - Missing if keyword.\n");
|
||||
fprintf(stderr, "# Usage - Exit [Number] [if expression...]\n");
|
||||
return -3;
|
||||
}
|
||||
|
||||
int evaluate(int type, token_vector &&tokens, Environment &env) {
|
||||
std::reverse(tokens.begin(), tokens.end());
|
||||
|
||||
@@ -64,6 +71,8 @@ namespace {
|
||||
switch(type) {
|
||||
default: return 0;
|
||||
|
||||
// exit [number] [if expr] ([number has been removed])
|
||||
case EXIT:
|
||||
case BREAK:
|
||||
case CONTINUE:
|
||||
case ELSE:
|
||||
@@ -77,10 +86,12 @@ namespace {
|
||||
case BREAK: name = "Break"; break;
|
||||
case CONTINUE: name = "Continue"; break;
|
||||
case ELSE: name = "Else"; break;
|
||||
case EXIT: name = "Exit"; return bad_exit(); break;
|
||||
}
|
||||
return bad_if(name);
|
||||
}
|
||||
// fall through.
|
||||
|
||||
case IF:
|
||||
tokens.pop_back();
|
||||
try {
|
||||
@@ -202,6 +213,7 @@ namespace {
|
||||
{"exists", builtin_exists},
|
||||
{"export", builtin_export},
|
||||
{"parameters", builtin_parameters},
|
||||
{"quit", builtin_quit},
|
||||
{"quote", builtin_quote},
|
||||
{"set", builtin_set},
|
||||
{"shift", builtin_shift},
|
||||
@@ -388,6 +400,10 @@ int eval_exec(std::string command, Environment &env, const fdmask &fds, bool thr
|
||||
|
||||
rv = fx(tokens);
|
||||
}
|
||||
catch (const exit_command_t &ex) {
|
||||
// convert to execution of input terminated.
|
||||
throw execution_of_input_terminated(ex.value);
|
||||
}
|
||||
|
||||
catch (mpw_error &e) {
|
||||
if (echo) env.echo("%s", command.c_str());
|
||||
@@ -442,6 +458,39 @@ int continue_command::execute(Environment &env, const fdmask &fds, bool throwup)
|
||||
|
||||
}
|
||||
|
||||
|
||||
int exit_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||
|
||||
// exit
|
||||
// exit [number] [if expr ]]
|
||||
// todo --
|
||||
|
||||
return eval_exec(text, env, fds, throwup, [&](token_vector &tokens){
|
||||
env.set("command", "exit");
|
||||
env.status(0);
|
||||
|
||||
if (tokens.size() <= 1) {
|
||||
throw exit_command_t{};
|
||||
}
|
||||
|
||||
|
||||
int status = 0;
|
||||
value v(tokens[1]);
|
||||
// remove the return value to make processing easier.
|
||||
if (v.is_number()) {
|
||||
tokens.erase(tokens.begin() + 1);
|
||||
}
|
||||
status = evaluate(EXIT, std::move(tokens), env);
|
||||
|
||||
if (status) {
|
||||
int ok = v.to_number(0);
|
||||
throw exit_command_t{ok};
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int or_command::execute(Environment &e, const fdmask &fds, bool throwup) {
|
||||
|
||||
int rv = 0;
|
||||
|
||||
Reference in New Issue
Block a user