libzypp 17.31.23
HelixHelpers.h
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#ifndef ZYPP_MISC_HELIXHELPERS_H
13#define ZYPP_MISC_HELIXHELPERS_H
14
15#include <zypp/AutoDispose.h>
16#include <zypp/base/LogControl.h>
19
20#include <libxml/parser.h>
21#include <libxml/xmlmemory.h>
22
23#include <string>
24#include <map>
25#include <string_view>
26#include <optional>
27
28
29namespace helix::detail {
30
31 template <typename Tp>
32 struct AutoXmlFree : public zypp::AutoDispose<Tp*>
33 {
34 AutoXmlFree( Tp* ptr_r = nullptr ) : zypp::AutoDispose<Tp*>( ptr_r, [] ( Tp* ptr_r ) { if ( ptr_r ) ::xmlFree( ptr_r ); } ) {}
35 };
36
37 class XmlNode
38 {
39
40 private:
41 xmlNodePtr _node;
42
43 public:
44 XmlNode (const xmlNodePtr node) : _node(node){};
45 virtual ~XmlNode (){};
46
47 // ---------------------------------- accessors
48
49 std::string_view name() const { return (std::string_view((const char *)_node->name)); }
50 xmlElementType type() const { return (_node->type); }
51
52 xmlNodePtr node() const { return (_node); }
53 std::optional<XmlNode> next() const { return (_node->next == NULL ? std::optional<XmlNode>() : XmlNode (_node->next)); }
54 std::optional<XmlNode> children() const { return (_node->xmlChildrenNode == NULL ? std::optional<XmlNode>() : XmlNode (_node->xmlChildrenNode)); }
55
56 // ---------------------------------- methods
57
58 bool equals (const std::string_view & n) const { return (strncasecmp ( name().data(), n.data(), n.length() ) == 0); }
59 bool isElement (void) const { return (type() == XML_ELEMENT_NODE); }
60
61 std::map<std::string, std::string> getAllProps () const {
62 std::map<std::string, std::string> res;
63 for( xmlAttrPtr attr = _node->properties; NULL != attr; attr = attr->next ) {
64 if ( !attr->children )
65 continue;
66 AutoXmlFree<xmlChar> value( xmlNodeListGetString( _node->doc, attr->children, 1 ) );
67 res.insert( std::make_pair( std::string((char *)attr->name), std::string( (char *)value.value() ) ) );
68 }
69 return res;
70 }
71
72 std::string getContent (void) const {
74 std::string ret;
75
76 *buf = xmlNodeGetContent (_node);
77
78 ret = std::string ((const char *)buf.value());
79
80 return (ret);
81 }
82
83 std::string getProp (const std::string & name, const std::string & deflt = "") const {
85 std::string gs;
86
87 *ret = xmlGetProp (_node, (const xmlChar *)name.c_str());
88
89 if (ret) {
90 gs = std::string ((const char *)ret.value());
91 return gs;
92 }
93 return deflt;
94 }
95
96
97 template<typename T>
98 T getValue ( const std::string & name, const T& deflt ) const;
99
100 template<typename T>
101 bool getValue ( const std::string & name, T& target ) const;
102 };
103
104 template<>
105 bool XmlNode::getValue ( const std::string & name, std::string& target ) const {
107 xmlNode *child;
108
109 *xml_s = xmlGetProp(_node, (const xmlChar *)name.c_str());
110 if (xml_s) {
111 target = std::string ((const char *)xml_s.value());
112 return true;
113 }
114
115 child = _node->xmlChildrenNode;
116
117 while (child) {
118 if (strcasecmp((const char *)(child->name), name.c_str()) == 0) {
119 xml_s = xmlNodeGetContent(child);
120 if (xml_s) {
121 target = std::string ((const char *)xml_s.value());
122 return true;
123 }
124 }
125 child = child->next;
126 }
127 return false;
128 }
129
130 template<>
131 std::string XmlNode::getValue ( const std::string & name, const std::string& deflt ) const {
132 std::string res;
133 if ( !getValue( name, res ) )
134 return deflt;
135 return res;
136 }
137
138 bool parseSetup ( const XmlNode &setup, zypp::misc::testcase::TestcaseSetup &t, std::string *err )
139 {
140 auto &target = t.data();
141 auto architecture = setup.getProp( "arch" );
142 if ( !architecture.empty() )
143 {
144 try {
145 target.architecture = ( zypp::Arch(architecture) );
146 }
147 catch( const zypp::Exception & excpt_r ) {
148 ZYPP_CAUGHT( excpt_r );
149 if ( err ) *err = zypp::str::Str() << "Bad architecture '" << architecture << "' in <setup...>";
150 return false;
151 }
152 }
153
154 auto node = setup.children();
155 while ( node )
156 {
157 if ( !node->isElement() ) {
158 node = node->next();
159 continue;
160 }
161
162#define if_SolverFlag( N ) if ( node->equals( #N ) ) { target.N = true; }
163 if_SolverFlag( ignorealreadyrecommended ) else if ( node->equals( "ignorealready" ) ) { target.ignorealreadyrecommended = true; }
164 else if_SolverFlag( onlyRequires ) else if ( node->equals( "ignorerecommended" ) ) { target.onlyRequires = true; }
165 else if_SolverFlag( forceResolve )
166
167 else if_SolverFlag( cleandepsOnRemove )
168
169 else if_SolverFlag( allowDowngrade )
170 else if_SolverFlag( allowNameChange )
171 else if_SolverFlag( allowArchChange )
172 else if_SolverFlag( allowVendorChange )
173
174 else if_SolverFlag( dupAllowDowngrade )
175 else if_SolverFlag( dupAllowNameChange )
176 else if_SolverFlag( dupAllowArchChange )
177 else if_SolverFlag( dupAllowVendorChange )
178#undef if_SolverFlag
179 else if ( node->equals("focus") ) {
180 target.resolverFocus = zypp::resolverFocusFromString( node->getProp("value") );
181 }
182 else if ( node->equals("system") ) {
183 target.systemRepo = zypp::misc::testcase::RepoDataImpl {
185 "@System",
186 99,
187 node->getProp("file")
188 };
189 }
190 else if ( node->equals("hardwareInfo") ) {
191 target.hardwareInfoFile = target.globalPath / node->getProp("path");
192 }
193 else if ( node->equals("modalias") ) {
194 target.modaliasList.push_back( node->getProp("name") );
195 }
196 else if ( node->equals("multiversion") ) {
197 target.multiversionSpec.insert( node->getProp("name") );
198 }
199 else if (node->equals ("channel")) {
200 std::string name = node->getProp("name");
201 std::string file = node->getProp("file");
202 std::string type = node->getProp("type");
203
204 unsigned prio = 99;
205 std::string priority = node->getProp("priority");
206 if ( !priority.empty() ) {
207 prio = zypp::str::strtonum<unsigned>( priority );
208 }
209
210 target.repos.push_back( zypp::misc::testcase::RepoDataImpl{
212 name,
213 prio,
214 file
215 });
216 }
217 else if ( node->equals("source") )
218 {
219 std::string url = node->getProp("url");
220 std::string alias = node->getProp("name");
221 target.repos.push_back( zypp::misc::testcase::RepoDataImpl{
223 alias,
224 99,
225 url
226 });
227 }
228 else if ( node->equals("force-install") )
229 {
230 target.forceInstallTasks.push_back( zypp::misc::testcase::ForceInstallImpl{
231 node->getProp("channel"),
232 node->getProp("package"),
233 node->getProp("kind")
234 });
235 }
236 else if ( node->equals("mediaid") )
237 {
238 target.show_mediaid = true;
239 }
240 else if ( node->equals("arch") ) {
241 MIL << "<arch...> deprecated, use <setup arch=\"...\"> instead" << std::endl;
242 std::string architecture = node->getProp("name");
243 if ( architecture.empty() ) {
244 ERR << "Property 'name=' in <arch.../> missing or empty" << std::endl;
245 }
246 else {
247 MIL << "Setting architecture to '" << architecture << "'" << std::endl;
248 target.architecture = zypp::Arch( architecture );
249 }
250 }
251 else if ( node->equals("locale") )
252 {
253 zypp::Locale loc( node->getProp("name") );
254 std::string fate = node->getProp("fate");
255 if ( !loc ) {
256 ERR << "Bad or missing name in <locale...>" << std::endl;
257 }
258 else if ( fate == "added" ) {
259 target.localesTracker.added().insert( loc );
260 }
261 else if ( fate == "removed" ) {
262 target.localesTracker.removed().insert( loc );
263 }
264 else {
265 target.localesTracker.current().insert( loc );
266 }
267 }
268 else if ( node->equals("autoinst") ) {
269 target.autoinstalled.push( zypp::IdString( node->getProp("name") ).id() );
270 }
271 else if ( node->equals("systemCheck") ) {
272 target.systemCheck = target.globalPath / node->getProp("path");
273 }
274 else if ( node->equals("setlicencebit") ) {
275 target.set_licence = true;
276 }
277 else {
278 ERR << "Unrecognized tag '" << node->name() << "' in setup" << std::endl;
279 }
280 node = node->next();
281 }
282 return true;
283 }
284
286 {
287 testcaseNode.name() = node.name();
288 const auto & content = node.getContent();
289 if ( !content.empty() ) {
290 testcaseNode.value() = content;
291 }
292 testcaseNode.properties() = node.getAllProps();
293
294 for ( auto childNode = node.children(); childNode; childNode = childNode->next() ) {
295 auto testNode = std::make_shared<zypp::misc::testcase::TestcaseTrial::Node>();
296 if ( !parseTrialNode( *childNode, *testNode ) )
297 return false;
298 testcaseNode.children().push_back( testNode );
299 }
300 return true;
301 }
302
303 bool parseTrial ( const XmlNode &trial, zypp::misc::testcase::TestcaseTrial &target, std::string * )
304 {
305 auto node = trial.children();
306 while (node) {
307 if (!node->isElement()) {
308 node = node->next();
309 continue;
310 }
311
313 parseTrialNode( *node, testcaseNode );
314 target.nodes().push_back( testcaseNode );
315 node = node->next();
316 }
317 return true;
318 }
319}
320
321#endif
#define if_SolverFlag(N)
sat::SolvAttr attr
Definition: PoolQuery.cc:311
xmlElementType type() const
Definition: HelixHelpers.h:50
std::string getContent(void) const
Definition: HelixHelpers.h:72
bool getValue(const std::string &name, T &target) const
std::map< std::string, std::string > getAllProps() const
Definition: HelixHelpers.h:61
std::optional< XmlNode > next() const
Definition: HelixHelpers.h:53
XmlNode(const xmlNodePtr node)
Definition: HelixHelpers.h:44
std::string getProp(const std::string &name, const std::string &deflt="") const
Definition: HelixHelpers.h:83
bool equals(const std::string_view &n) const
Definition: HelixHelpers.h:58
xmlNodePtr node() const
Definition: HelixHelpers.h:52
std::string_view name() const
Definition: HelixHelpers.h:49
bool isElement(void) const
Definition: HelixHelpers.h:59
T getValue(const std::string &name, const T &deflt) const
std::optional< XmlNode > children() const
Definition: HelixHelpers.h:54
Architecture.
Definition: Arch.h:37
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:94
reference value() const
Reference to the Tp object.
Definition: AutoDispose.h:147
AutoDispose()
Default Ctor using default constructed value and no dispose function.
Definition: AutoDispose.h:111
Base class for Exception.
Definition: Exception.h:146
Access to the sat-pools string space.
Definition: IdString.h:43
IdType id() const
Expert backdoor.
Definition: IdString.h:122
'Language[_Country]' codes.
Definition: Locale.h:50
bool parseTrial(const XmlNode &trial, zypp::misc::testcase::TestcaseTrial &target, std::string *)
Definition: HelixHelpers.h:303
bool parseTrialNode(const XmlNode &node, zypp::misc::testcase::TestcaseTrial::Node &testcaseNode)
Definition: HelixHelpers.h:285
bool parseSetup(const XmlNode &setup, zypp::misc::testcase::TestcaseSetup &t, std::string *err)
Definition: HelixHelpers.h:138
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
AutoXmlFree(Tp *ptr_r=nullptr)
Definition: HelixHelpers.h:34
const std::vector< std::shared_ptr< Node > > & children() const
Definition: LoadTestcase.cc:90
const std::string & name() const
Definition: LoadTestcase.cc:66
const std::map< std::string, std::string > & properties() const
Definition: LoadTestcase.cc:84
const std::string & value() const
Definition: LoadTestcase.cc:72
const std::vector< Node > & nodes() const
Definition: LoadTestcase.cc:54
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:436
#define MIL
Definition: Logger.h:96
#define ERR
Definition: Logger.h:98