mirror of
https://github.com/ksherlock/mpw-shell.git
synced 2024-12-27 18:30:39 +00:00
f125b533f7
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.
106 lines
1.7 KiB
C++
106 lines
1.7 KiB
C++
#include <algorithm>
|
|
|
|
#include "mpw_parser.h"
|
|
#include "phase3_parser.h"
|
|
|
|
#include "command.h"
|
|
#include "error.h"
|
|
|
|
mpw_parser::mpw_parser(Environment &e, fdmask fds, bool interactive) : _env(e), _fds(fds), _interactive(interactive)
|
|
{
|
|
|
|
_p3 = phase3::make();
|
|
_p2.set_next([this](int type, std::string &&s){
|
|
_p3->parse(type, std::move(s));
|
|
});
|
|
|
|
_p1.set_next([this](std::string &&s){
|
|
_p2.parse(std::move(s));
|
|
});
|
|
}
|
|
|
|
|
|
mpw_parser::~mpw_parser() {
|
|
|
|
}
|
|
|
|
|
|
bool mpw_parser::continuation() const {
|
|
if (_p1.continuation()) return true;
|
|
if (_p2.continuation()) return true;
|
|
if (_p3->continuation()) return true;
|
|
return false;
|
|
}
|
|
|
|
void mpw_parser::finish() {
|
|
_p1.finish();
|
|
_p2.finish();
|
|
_p3->parse(0, "");
|
|
|
|
// and now execute the commands...
|
|
execute();
|
|
}
|
|
|
|
|
|
void mpw_parser::reset() {
|
|
_p1.reset();
|
|
_p2.reset();
|
|
_p3->reset();
|
|
_abort = false;
|
|
}
|
|
|
|
void mpw_parser::abort() {
|
|
_p1.abort();
|
|
_p2.abort();
|
|
//_p3->abort();
|
|
_p3->reset();
|
|
_abort = true;
|
|
}
|
|
|
|
|
|
void mpw_parser::parse(const void *begin, const void *end) {
|
|
if (_abort) return;
|
|
_p1.parse((const unsigned char *)begin, (const unsigned char *)end);
|
|
|
|
// and execute...
|
|
execute();
|
|
}
|
|
|
|
|
|
void mpw_parser::execute() {
|
|
if (_abort) {
|
|
_p3->command_queue.clear();
|
|
return;
|
|
}
|
|
|
|
auto commands = std::move(_p3->command_queue);
|
|
_p3->command_queue.clear();
|
|
|
|
|
|
std::reverse(commands.begin(), commands.end());
|
|
|
|
command_ptr cmd;
|
|
|
|
|
|
try {
|
|
while (!commands.empty()) {
|
|
cmd = std::move(commands.back());
|
|
commands.pop_back();
|
|
cmd->execute(_env, _fds);
|
|
}
|
|
|
|
} catch (execution_of_input_terminated &ex) {
|
|
|
|
_env.status(ex.status(), false);
|
|
|
|
if (_interactive) {
|
|
if (!cmd->terminal() || !commands.empty()) {
|
|
if (ex.status()) fprintf(stderr, "### %s\n", ex.what());
|
|
}
|
|
return;
|
|
}
|
|
_abort = true;
|
|
throw;
|
|
}
|
|
|
|
} |