forked from ElektraInitiative/libelektra
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgen.cpp
123 lines (100 loc) · 3 KB
/
gen.cpp
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* @file
*
* @brief
*
* @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
*/
#include <gen.hpp>
#include "gen/template.hpp"
#include <cmdline.hpp>
#include <kdb.hpp>
#include <fstream>
#include <kdbplugin.h>
#include <modules.hpp>
using namespace kdb;
using namespace kdb::tools;
using namespace std;
int GenCommand::execute (Cmdline const & cl)
{
if (cl.arguments.size () < 3)
{
throw invalid_argument ("need at least 3 arguments");
}
auto templateName = cl.arguments[0];
auto parentKey = cl.arguments[1];
auto outputName = cl.arguments[2];
std::unordered_map<std::string, std::string> parameters;
if (cl.arguments.size () > 3)
{
std::transform (cl.arguments.begin () + 3, cl.arguments.end (), std::inserter (parameters, parameters.end ()),
[] (const std::string & param) {
auto search = param.find ('=');
if (search == std::string::npos)
{
throw invalid_argument ("parameters have to be of format name=value");
}
return std::make_pair (std::string (param.begin (), param.begin () + search),
std::string (param.begin () + search + 1, param.end ()));
});
}
const auto & templates = GenTemplateList::getInstance ();
const auto tmpl = templates.getTemplate (templateName, parameters);
if (tmpl->isEmpty ())
{
// empty template -> correct one not found
throw invalid_argument ("couldn't find template '" + templateName + "'");
}
if (parentKey == "-")
{
for (const auto & part : tmpl->getParts ())
{
std::cout << outputName + part << std::endl;
}
return 0;
}
KeySet ks;
if (cl.inputFile.empty ())
{
Key getKey (parentKey, KEY_END);
KDB kdb;
kdb.get (ks, getKey);
printWarnings (cerr, getKey, cl.verbose, cl.debug);
printError (cerr, getKey, cl.verbose, cl.debug);
if (getKey.hasMeta ("error"))
{
throw CommandAbortException ("Error loading from KDB");
}
}
else
{
auto pos = cl.inputFile.find ('=');
if (pos == std::string::npos)
{
throw invalid_argument ("-F/--input-file argument must be given as <plugin>=<file>");
}
std::string pluginName (cl.inputFile.begin (), cl.inputFile.begin () + pos);
std::string file (cl.inputFile.begin () + pos + 1, cl.inputFile.end ());
Modules modules;
PluginPtr plugin = modules.load (pluginName, cl.getPluginsConfig ());
if (plugin == nullptr)
{
throw invalid_argument ("plugin '" + pluginName + "' given to -F/--input-file could not be loaded");
}
Key getKey (parentKey, KEY_VALUE, file.c_str (), KEY_END);
if (plugin->get (ks, getKey) == ELEKTRA_PLUGIN_STATUS_ERROR)
{
printWarnings (cerr, getKey, cl.verbose, cl.debug);
printError (cerr, getKey, cl.verbose, cl.debug);
throw invalid_argument ("file '" + file + "' given to -F/--input-file could not be loaded with plugin '" +
pluginName + "'");
}
}
auto inputKs = ks.cut (Key (parentKey, KEY_END));
for (const auto & part : tmpl->getParts ())
{
std::ofstream output (outputName + part);
tmpl->render (output, outputName, part, inputKs, parentKey);
}
return 0;
}