23int main(
int argc,
char *argv[])
26 CMD_UTILS_CONVERT_ARGS_TO_UTF8;
29 ArgumentParser parser;
30 OperationArgument generateArg(
"generate",
'\0',
"runs the code generator");
31 generateArg.setImplicit(
true);
32 ConfigValueArgument inputFileArg(
"input-file",
'\0',
"specifies the input file", {
"path" });
33 inputFileArg.setRequired(
true);
34 ConfigValueArgument outputFileArg(
"output-file",
'\0',
"specifies the output file", {
"path" });
35 Argument generatorsArg(
"generators",
'\0',
"specifies the generators (by default all generators are enabled)");
36 generatorsArg.setValueNames({
"json",
"binary" });
37 generatorsArg.setPreDefinedCompletionValues(
"json binary");
38 generatorsArg.setRequiredValueCount(Argument::varValueCount);
39 generatorsArg.setCombinable(
true);
40 ConfigValueArgument clangOptionsArg(
"clang-opt",
'\0',
"specifies arguments/options to be passed to Clang", {
"option" });
41 clangOptionsArg.setRequiredValueCount(Argument::varValueCount);
42 ConfigValueArgument logClangOptions(
"log-clang-opt",
'\0',
"logs the options passed to Clang");
43 ConfigValueArgument errorResilientArg(
"error-resilient",
'\0',
"turns most errors into warnings");
44 HelpArgument helpArg(parser);
45 NoColorArgument noColorArg;
46 generateArg.setSubArguments({ &inputFileArg, &outputFileArg, &generatorsArg, &clangOptionsArg, &logClangOptions, &errorResilientArg });
50 binaryOptions.
appendTo(&generateArg);
51 parser.setMainArguments({ &generateArg, &noColorArg, &helpArg });
54 parser.parseArgs(argc, argv);
55 if (helpArg.isPresent() || !generateArg.isPresent()) {
60 ostream *os =
nullptr;
63 if (outputFileArg.isPresent()) {
64 outputFile.exceptions(ios_base::badbit | ios_base::failbit);
65 outputFile.open(outputFileArg.values(0).front(), ios_base::out | ios_base::trunc | ios_base::binary);
72 auto clangOptions = std::vector<std::string_view>();
73 if (clangOptionsArg.isPresent()) {
75 for (
const auto *
const value : clangOptionsArg.values(0)) {
77 const auto splittedValues = splitStringSimple<std::vector<std::string_view>>(value,
";");
78 for (
const auto &splittedValue : splittedValues) {
79 if (!splittedValue.empty()) {
80 clangOptions.emplace_back(splittedValue);
85 if (logClangOptions.isPresent()) {
86 cerr << Phrases::Info <<
"Options passed to clang:" << Phrases::End;
87 for (
const auto &opt : clangOptions) {
93 auto factory =
CodeFactory(parser.executable(), inputFileArg.values(0), clangOptions, *os);
94 factory.setErrorResilient(errorResilientArg.isPresent());
96 if (generatorsArg.isPresent()) {
99 const std::unordered_map<std::string, std::function<void()>> generatorsByName{
106 for (
const char *generatorName : generatorsArg.values(0)) {
108 generatorsByName.at(generatorName)();
109 }
catch (
const out_of_range &) {
110 cerr << Phrases::Error <<
"The specified generator \"" << generatorName <<
"\" does not exist." << Phrases::End;
111 cerr <<
"Available generators:";
112 for (
const auto &generators : generatorsByName) {
113 cerr <<
' ' << generators.first;
125 if (!factory.run()) {
126 cerr << Phrases::Error <<
"Errors occurred." << Phrases::EndFlush;
130 }
catch (
const std::ios_base::failure &failure) {
131 const char *errorMessage = failure.what();
133 errorMessage = os->fail() || os->bad() ?
"An IO error occurred when writing to the output stream." :
"An IO error occurred.";
135 errorMessage =
"An IO error when opening output stream.";
137 cerr << Phrases::Error << errorMessage << Phrases::EndFlush;
int main(int argc, char *argv[])