This repository has been archived by the owner on Oct 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 123
/
kconfig.cpp
176 lines (145 loc) · 4.97 KB
/
kconfig.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/**
* @file
*
* @brief Source for kconfig plugin
*
* @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
*
*/
#include "kconfig.hpp"
#include "kconfig_delegate.hpp"
#include "kconfig_serializer.hpp"
#include <fstream>
#include <kdberrors.h>
#include <kdbhelper.h>
using ckdb::keyNew;
using std::exception;
using elektra::KconfigDelegate;
using CppKey = kdb::Key;
using CppKeySet = kdb::KeySet;
namespace
{
/**
* @brief This function returns a key set containing the plugin contract.
*
* @return A key set specifying the capabilities of the plugin
*/
CppKeySet getContract ()
{
return CppKeySet{ 30,
keyNew ("system:/elektra/modules/kconfig", KEY_VALUE, "kconfig plugin waits for your orders", KEY_END),
keyNew ("system:/elektra/modules/kconfig/exports", KEY_END),
keyNew ("system:/elektra/modules/kconfig/exports/open", KEY_FUNC, elektraKconfigOpen, KEY_END),
keyNew ("system:/elektra/modules/kconfig/exports/close", KEY_FUNC, elektraKconfigClose, KEY_END),
keyNew ("system:/elektra/modules/kconfig/exports/get", KEY_FUNC, elektraKconfigGet, KEY_END),
keyNew ("system:/elektra/modules/kconfig/exports/set", KEY_FUNC, elektraKconfigSet, KEY_END),
keyNew ("system:/elektra/modules/kconfig/exports/error", KEY_FUNC, elektraKconfigError, KEY_END),
keyNew ("system:/elektra/modules/kconfig/exports/checkconf", KEY_FUNC, elektraKconfigCheckConf, KEY_END),
#include ELEKTRA_README
keyNew ("system:/elektra/modules/kconfig/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END),
KS_END };
}
} // end namespace
extern "C" {
typedef Delegator<KconfigDelegate> delegator;
/** @see elektraDocOpen */
int elektraKconfigOpen (Plugin * handle, Key * key)
{
int status = ELEKTRA_PLUGIN_STATUS_ERROR;
try
{
// - The function below calls the constructor `KconfigDelegate(config)`.
// - After the call to `delegator::open` you can retrieve a pointer to the delegate via `delegator::get (handle)`.
status = delegator::open (handle, key);
}
catch (exception const & error)
{
ELEKTRA_SET_PLUGIN_MISBEHAVIOR_ERRORF (key, "Uncaught Exception: %s", error.what ());
}
return status;
}
/** @see elektraDocClose */
int elektraKconfigClose (Plugin * handle, Key * key)
{
// The function `delegator::close` calls the destructor of `KconfigDelegate`.
return delegator::close (handle, key);
}
/** @see elektraDocGet */
int elektraKconfigGet (Plugin * handle, KeySet * returned, Key * parentKey)
{
CppKeySet keys{ returned };
CppKey parent{ parentKey };
if (parent.getName () == "system:/elektra/modules/kconfig")
{
keys.append (getContract ());
parent.release ();
keys.release ();
return ELEKTRA_PLUGIN_STATUS_SUCCESS;
}
int status = ELEKTRA_PLUGIN_STATUS_ERROR;
try
{
keys.append (delegator::get (handle)->getConfig (parent));
status = ELEKTRA_PLUGIN_STATUS_SUCCESS;
}
catch (std::overflow_error const & exception)
{
ELEKTRA_SET_RESOURCE_ERRORF (parent.getKey (), "Unable to read data from file '%s'. Reason: %s",
parent.getString ().c_str (), exception.what ());
}
catch (std::runtime_error const & exception)
{
ELEKTRA_SET_VALIDATION_SYNTACTIC_ERRORF (parent.getKey (), "Unable to parse file '%s'. Reason: %s",
parent.getString ().c_str (), exception.what ());
}
parent.release ();
keys.release ();
return status;
}
/** @see elektraDocSet */
int elektraKconfigSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
{
CppKeySet keys{ returned };
CppKey parent{ parentKey };
ELEKTRA_LOG_DEBUG ("Save `%s` using the kconfig plugin", parent.getName ().c_str ());
auto filePtr = new std::ofstream{ parent.getString () };
bool isFileOpen = filePtr->is_open ();
std::unique_ptr<std::ostream> file{ filePtr };
if (!isFileOpen)
{
ELEKTRA_SET_RESOURCE_ERRORF (parent.getKey (), "Unable to save data to file '%s'. Reason: %s", parent.getString ().c_str (),
"Could not open the file.");
parent.release ();
keys.release ();
return ELEKTRA_PLUGIN_STATUS_ERROR;
}
ELEKTRA_LOG_DEBUG ("File opened successfully, start saving the data.");
KConfigSerializer serializer{ keys, parent, std::move (file) };
serializer.save ();
ELEKTRA_LOG_DEBUG ("Data succesfully stored into `%s`.", parent.getName ().c_str ());
parent.release ();
keys.release ();
return ELEKTRA_PLUGIN_STATUS_SUCCESS;
}
/** @see elektraDocError */
int elektraKconfigError (Plugin * handle ELEKTRA_UNUSED, KeySet * returned ELEKTRA_UNUSED, Key * parentKey ELEKTRA_UNUSED)
{
return ELEKTRA_PLUGIN_STATUS_SUCCESS;
}
/** @see elektraDocCheckConf */
int elektraKconfigCheckConf (Key * errorKey ELEKTRA_UNUSED, KeySet * conf ELEKTRA_UNUSED)
{
return ELEKTRA_PLUGIN_STATUS_NO_UPDATE;
}
Plugin * ELEKTRA_PLUGIN_EXPORT
{
// clang-format off
return elektraPluginExport ("kconfig",
ELEKTRA_PLUGIN_OPEN, &elektraKconfigOpen,
ELEKTRA_PLUGIN_CLOSE, &elektraKconfigClose,
ELEKTRA_PLUGIN_GET, &elektraKconfigGet,
ELEKTRA_PLUGIN_SET, &elektraKconfigSet,
ELEKTRA_PLUGIN_ERROR, &elektraKconfigError,
ELEKTRA_PLUGIN_END);
}
} // end extern "C"