summaryrefslogtreecommitdiff
path: root/icetray/tool/icetraySql.cpp
blob: 5817ca844ec1f7927cbb6b3421de236c7154b991 (plain)
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;
}