66 lines
2.2 KiB
C++
66 lines
2.2 KiB
C++
#include "Parsodus/driver.h"
|
|
#include "Parsodus/inputparser.h"
|
|
#include "Parsodus/config.h"
|
|
#include <fstream>
|
|
#include <sys/stat.h>
|
|
|
|
|
|
#if defined(_WIN32)
|
|
#include <direct.h>
|
|
#endif
|
|
|
|
namespace {
|
|
/**
|
|
* Filter only valid identifier chars: alphanumeric, and not starting with a digit
|
|
*/
|
|
std::string clean(std::string in) {
|
|
std::string s;
|
|
for (char c : in) {
|
|
if ((s.length() && std::isalnum(c)) || std::isalpha(c) || c == '_')
|
|
s += c;
|
|
}
|
|
return s;
|
|
}
|
|
}
|
|
|
|
|
|
namespace pds {
|
|
|
|
Driver::Driver(std::unique_ptr<BackendManager> backends, std::istream& inputfile, std::string outputdir, std::string language, std::string parsername):
|
|
m_backends(std::move(backends)), m_inputfile(inputfile), m_outputdir(outputdir), m_language(language), m_parsername(clean(parsername)) {
|
|
}
|
|
|
|
Driver::~Driver(){}
|
|
|
|
int Driver::run() {
|
|
if (!m_parsername.length()) throw DriverException("no valid parser name possible");
|
|
Config config = InputParser::parseInput(m_inputfile);
|
|
Backend* back = m_backends->findBackend(m_language, config.parserType);
|
|
if (!back) throw DriverException("Could not find a valid backend for language " + m_language + " and parser type: " + config.parserType);
|
|
back->generateParser([this](std::string filename) -> std::unique_ptr<std::ostream> {
|
|
struct stat sb;
|
|
if(stat(m_outputdir.c_str(), &sb) != 0) {
|
|
int status;
|
|
#if defined(_WIN32)
|
|
status = _mkdir(m_outputdir.c_str());
|
|
#else
|
|
status = mkdir(m_outputdir.c_str(), 0755);
|
|
#endif
|
|
if(status !=0 && errno != EEXIST){
|
|
throw DriverException("The folder " + m_outputdir + " does not exist and we're unable to create it.");
|
|
}
|
|
}
|
|
return std::unique_ptr<std::ostream>(new std::ofstream(m_outputdir + "/" + filename));
|
|
}, m_parsername, config);
|
|
|
|
return 0;
|
|
}
|
|
|
|
DriverException::DriverException(std::string what): m_what(what) {}
|
|
const char* DriverException::what() const throw() {
|
|
return m_what.c_str();
|
|
}
|
|
|
|
}
|
|
|