Make generators to run configurable
Currently only the generator for JSON serialization is provided
This commit is contained in:
parent
4a8ebc99a3
commit
14428c8890
|
@ -131,8 +131,6 @@ CodeFactory::CodeFactory(const char *applicationPath, const std::vector<const ch
|
|||
, m_sourceFiles(sourceFiles)
|
||||
, m_os(os)
|
||||
{
|
||||
// for now, add the code generator for JSON (de)serialization by default
|
||||
m_generators.emplace_back(std::make_unique<JSONSerializationCodeGenerator>());
|
||||
}
|
||||
|
||||
CodeFactory::~CodeFactory()
|
||||
|
|
|
@ -78,6 +78,9 @@ public:
|
|||
CodeFactory(const char *applicationPath, const std::vector<const char *> &sourceFiles, std::ostream &os);
|
||||
~CodeFactory();
|
||||
|
||||
std::vector<std::unique_ptr<CodeGenerator>> &generators();
|
||||
const std::vector<std::unique_ptr<CodeGenerator>> &generators() const;
|
||||
|
||||
void addDeclaration(clang::Decl *decl);
|
||||
bool readAST();
|
||||
bool generate() const;
|
||||
|
@ -94,6 +97,16 @@ private:
|
|||
std::unique_ptr<ToolInvocation> m_toolInvocation;
|
||||
};
|
||||
|
||||
inline std::vector<std::unique_ptr<CodeGenerator>> &CodeFactory::generators()
|
||||
{
|
||||
return m_generators;
|
||||
}
|
||||
|
||||
inline const std::vector<std::unique_ptr<CodeGenerator>> &CodeFactory::generators() const
|
||||
{
|
||||
return m_generators;
|
||||
}
|
||||
|
||||
} // namespace ReflectiveRapidJSON
|
||||
|
||||
#endif // REFLECTIVE_RAPIDJSON_GENERATOR_H
|
||||
|
|
201
moc/main.cpp
201
moc/main.cpp
|
@ -1,91 +1,110 @@
|
|||
#include "./generator.h"
|
||||
|
||||
#include "resources/config.h"
|
||||
|
||||
#include <c++utilities/application/argumentparser.h>
|
||||
#include <c++utilities/application/commandlineutils.h>
|
||||
#include <c++utilities/application/failure.h>
|
||||
#include <c++utilities/io/ansiescapecodes.h>
|
||||
#include <c++utilities/io/catchiofailure.h>
|
||||
#include <c++utilities/io/misc.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace ApplicationUtilities;
|
||||
using namespace EscapeCodes;
|
||||
using namespace IoUtilities;
|
||||
using namespace ReflectiveRapidJSON;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SET_APPLICATION_INFO;
|
||||
CMD_UTILS_CONVERT_ARGS_TO_UTF8;
|
||||
|
||||
// setup argument parser
|
||||
ArgumentParser parser;
|
||||
Argument inputFilesArg("input-files", 'i', "specifies the input files");
|
||||
inputFilesArg.setValueNames({ "path" });
|
||||
inputFilesArg.setRequiredValueCount(Argument::varValueCount);
|
||||
Argument outputFileArg("output-file", 'o', "specifies the output file");
|
||||
outputFileArg.setValueNames({ "path" });
|
||||
outputFileArg.setRequiredValueCount(1);
|
||||
outputFileArg.setCombinable(true);
|
||||
HelpArgument helpArg(parser);
|
||||
NoColorArgument noColorArg;
|
||||
parser.setMainArguments({ &inputFilesArg, &outputFileArg, &noColorArg, &helpArg });
|
||||
|
||||
// parse arguments
|
||||
parser.parseArgsOrExit(argc, argv);
|
||||
if (helpArg.isPresent()) {
|
||||
return 0;
|
||||
}
|
||||
if (!inputFilesArg.isPresent()) {
|
||||
cerr << Phrases::Error << "No input file specified." << Phrases::EndFlush;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// setup output stream
|
||||
ostream *os = nullptr;
|
||||
try {
|
||||
ofstream outputFile;
|
||||
if (outputFileArg.isPresent()) {
|
||||
outputFile.exceptions(ios_base::badbit | ios_base::failbit);
|
||||
outputFile.open(outputFileArg.values(0).front(), ios_base::out | ios_base::binary);
|
||||
os = &outputFile;
|
||||
} else {
|
||||
os = &cout;
|
||||
}
|
||||
|
||||
// configure code generator
|
||||
CodeFactory factory(parser.executable(), inputFilesArg.values(0), *os);
|
||||
// TODO: make code generator configurable, eg.
|
||||
// factory.addGenerator(...);
|
||||
|
||||
// read AST elements from input files
|
||||
if (!factory.readAST()) {
|
||||
cerr << Phrases::Error << "Errors occured when parsing the input files." << Phrases::EndFlush;
|
||||
return -2;
|
||||
}
|
||||
|
||||
// run the code generator
|
||||
if (!factory.generate()) {
|
||||
cerr << Phrases::Error << "Errors occured when during code generation." << Phrases::EndFlush;
|
||||
return -3;
|
||||
}
|
||||
|
||||
} catch (...) {
|
||||
catchIoFailure();
|
||||
const char *errorMessage;
|
||||
if (os) {
|
||||
errorMessage = os->fail() || os->bad() ? "An IO error occured when writing to the output stream." : "An IO error occured.";
|
||||
} else {
|
||||
errorMessage = "An IO error when opening output stream.";
|
||||
}
|
||||
cerr << Phrases::Error << errorMessage << Phrases::EndFlush;
|
||||
return -4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include "./generator.h"
|
||||
|
||||
#include "resources/config.h"
|
||||
|
||||
#include <c++utilities/application/argumentparser.h>
|
||||
#include <c++utilities/application/commandlineutils.h>
|
||||
#include <c++utilities/application/failure.h>
|
||||
#include <c++utilities/io/ansiescapecodes.h>
|
||||
#include <c++utilities/io/catchiofailure.h>
|
||||
#include <c++utilities/io/misc.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace ApplicationUtilities;
|
||||
using namespace EscapeCodes;
|
||||
using namespace IoUtilities;
|
||||
using namespace ReflectiveRapidJSON;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SET_APPLICATION_INFO;
|
||||
CMD_UTILS_CONVERT_ARGS_TO_UTF8;
|
||||
|
||||
// setup argument parser
|
||||
ArgumentParser parser;
|
||||
Argument inputFilesArg("input-files", 'i', "specifies the input files");
|
||||
inputFilesArg.setValueNames({ "path" });
|
||||
inputFilesArg.setRequiredValueCount(Argument::varValueCount);
|
||||
Argument outputFileArg("output-file", 'o', "specifies the output file");
|
||||
outputFileArg.setValueNames({ "path" });
|
||||
outputFileArg.setRequiredValueCount(1);
|
||||
outputFileArg.setCombinable(true);
|
||||
Argument generatorsArgs("generators", 'g', "specifies the generators (by default all generators are enabled)");
|
||||
generatorsArgs.setValueNames({ "json" });
|
||||
generatorsArgs.setRequiredValueCount(Argument::varValueCount);
|
||||
generatorsArgs.setCombinable(true);
|
||||
HelpArgument helpArg(parser);
|
||||
NoColorArgument noColorArg;
|
||||
parser.setMainArguments({ &inputFilesArg, &outputFileArg, &noColorArg, &helpArg });
|
||||
|
||||
// parse arguments
|
||||
parser.parseArgsOrExit(argc, argv);
|
||||
if (helpArg.isPresent()) {
|
||||
return 0;
|
||||
}
|
||||
if (!inputFilesArg.isPresent()) {
|
||||
cerr << Phrases::Error << "No input file specified." << Phrases::EndFlush;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// setup output stream
|
||||
ostream *os = nullptr;
|
||||
try {
|
||||
ofstream outputFile;
|
||||
if (outputFileArg.isPresent()) {
|
||||
outputFile.exceptions(ios_base::badbit | ios_base::failbit);
|
||||
outputFile.open(outputFileArg.values(0).front(), ios_base::out | ios_base::binary);
|
||||
os = &outputFile;
|
||||
} else {
|
||||
os = &cout;
|
||||
}
|
||||
|
||||
// configure code generator
|
||||
CodeFactory factory(parser.executable(), inputFilesArg.values(0), *os);
|
||||
auto &generators(factory.generators());
|
||||
// add only specified generators if the --generator argument is present
|
||||
if (generatorsArgs.isPresent()) {
|
||||
// find and construct generators by name
|
||||
for (vector<const char *> generatorName : generatorsArgs.values(0)) {
|
||||
if (!strcmp(generatorName, "json")) {
|
||||
generators.emplace_back(std::make_unique<JSONSerializationCodeGenerator>());
|
||||
} else {
|
||||
cerr << Phrases::Error << "The specified generator \"" << generatorName << "\" does not exist." << Phrases::EndFlush;
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// add default generators
|
||||
generators.emplace_back(std::make_unique<JSONSerializationCodeGenerator>());
|
||||
}
|
||||
|
||||
// read AST elements from input files
|
||||
if (!factory.readAST()) {
|
||||
cerr << Phrases::Error << "Errors occured when parsing the input files." << Phrases::EndFlush;
|
||||
return -2;
|
||||
}
|
||||
|
||||
// run the code generator
|
||||
if (!factory.generate()) {
|
||||
cerr << Phrases::Error << "Errors occured when during code generation." << Phrases::EndFlush;
|
||||
return -3;
|
||||
}
|
||||
|
||||
} catch (...) {
|
||||
catchIoFailure();
|
||||
const char *errorMessage;
|
||||
if (os) {
|
||||
errorMessage = os->fail() || os->bad() ? "An IO error occured when writing to the output stream." : "An IO error occured.";
|
||||
} else {
|
||||
errorMessage = "An IO error when opening output stream.";
|
||||
}
|
||||
cerr << Phrases::Error << errorMessage << Phrases::EndFlush;
|
||||
return -4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ void OverallTests::testGeneratorItself()
|
|||
|
||||
stringstream buffer;
|
||||
CodeFactory factory(TestApplication::appPath(), inputFiles, buffer);
|
||||
factory.generators().emplace_back(make_unique<JSONSerializationCodeGenerator>());
|
||||
CPPUNIT_ASSERT(factory.readAST());
|
||||
CPPUNIT_ASSERT(factory.generate());
|
||||
assertEqualityLinewise(m_expectedCode, toArrayOfLines(buffer.str()));
|
||||
|
|
Loading…
Reference in New Issue