2016-08-17 13:14:38 -04:00
|
|
|
#include <algorithm>
|
2016-08-16 16:47:20 -04:00
|
|
|
|
|
|
|
#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;
|
|
|
|
|
2016-08-30 12:25:43 -04:00
|
|
|
|
2016-08-16 16:47:20 -04:00
|
|
|
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()) {
|
2016-08-30 12:25:43 -04:00
|
|
|
if (ex.status()) fprintf(stderr, "### %s\n", ex.what());
|
2016-08-16 16:47:20 -04:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_abort = true;
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|