1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#include <iostream>
#include <fstream>
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <compileTimeFormatter.h>
namespace po = boost::program_options;
namespace fs = boost::filesystem;
AdHocFormatter(CPPHeader,
R"C(#include "%?.h"
const IceTray::StaticSqlSource )C");
AdHocFormatter(CPPNS, "%?::");
AdHocFormatter(CPPOpen, R"C(%? (
R"SQL()C");
AdHocFormatter(CPPFooter, R"C()SQL");
)C");
AdHocFormatter(HHeader,
R"H(#include <staticSqlSource.h>
)H");
AdHocFormatter(HDeclartion, "extern const IceTray::StaticSqlSource %?;\n");
AdHocFormatter(HFooter, "\n");
AdHocFormatter(OpenNamespace, "namespace %? {\n");
AdHocFormatter(CloseNamespace, "} // %?\n");
int
main(int argc, char ** argv)
{
po::options_description opts("IceTray SQL-to-C++ precompiler");
fs::path sql, cpp, h, base;
std::string sqlns;
opts.add_options()
("help,h", "Show this help message")
("sql", po::value(&sql)->required(), "Path of SQL script")
("cpp", po::value(&cpp)->required(), "Path of C++ file to write")
("h", po::value(&h)->required(), "Path of header file to write")
("basedir,d", po::value(&base)->default_value(fs::current_path()), "Base directory of SQL scripts (namespaces are created relative to here)")
("namespace", po::value(&sqlns), "Namespace to create SqlSource in")
;
po::positional_options_description p;
p.add("sql", 1);
p.add("cpp", 1);
p.add("h", 1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(opts).positional(p).run(), vm);
if (vm.count("help")) {
std::cout << opts << std::endl;
return 1;
}
po::notify(vm);
std::vector<std::string> sqlnsparts;
boost::algorithm::split(sqlnsparts, sqlns, boost::algorithm::is_any_of(":"), boost::algorithm::token_compress_on);
auto r = fs::canonical(sql).lexically_relative(fs::canonical(base)).parent_path();
if (!r.empty()) {
std::transform(r.begin(), r.end(), std::back_inserter(sqlnsparts), [](const auto & p) { return p.string(); });
}
std::ifstream sqlin(sql.string());
std::ofstream cppout(cpp.string());
std::ofstream hout(h.string());
CPPHeader::write(cppout, sql.leaf().string());
std::for_each(sqlnsparts.begin(), sqlnsparts.end(), [&cppout](const auto & nsp) {
CPPNS::write(cppout, nsp);
});
CPPOpen::write(cppout, sql.stem().string());
std::copy(std::istreambuf_iterator<char>(sqlin),
std::istreambuf_iterator<char>(),
std::ostreambuf_iterator<char>(cppout));
CPPFooter::write(cppout);
HHeader::write(hout);
std::for_each(sqlnsparts.begin(), sqlnsparts.end(), [&hout](const auto & nsp) {
OpenNamespace::write(hout, nsp);
});
HDeclartion::write(hout, sql.stem().string());
std::for_each(sqlnsparts.begin(), sqlnsparts.end(), [&hout](const auto & nsp) {
CloseNamespace::write(hout, nsp);
});
HFooter::write(hout);
return 0;
}
|