libzypp  17.28.5
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>
17 #include <zypp/misc/LoadTestcase.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 
29 namespace 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 {
106  AutoXmlFree<xmlChar> xml_s;
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 )
173 
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
bool parseTrialNode(const XmlNode &node, zypp::misc::testcase::TestcaseTrial::Node &testcaseNode)
Definition: HelixHelpers.h:285
std::string_view name() const
Definition: HelixHelpers.h:49
std::ostream & node(std::ostream &out_r, const std::string &name_r, Node::Attr attr_r)
Definition: Xml.h:203
#define MIL
Definition: Logger.h:96
bool parseTrial(const XmlNode &trial, zypp::misc::testcase::TestcaseTrial &target, std::string *)
Definition: HelixHelpers.h:303
AutoXmlFree(Tp *ptr_r=nullptr)
Definition: HelixHelpers.h:34
std::optional< XmlNode > next() const
Definition: HelixHelpers.h:53
Architecture.
Definition: Arch.h:36
sat::SolvAttr attr
Definition: PoolQuery.cc:311
xmlElementType type() const
Definition: HelixHelpers.h:50
Access to the sat-pools string space.
Definition: IdString.h:42
bool parseSetup(const XmlNode &setup, zypp::misc::testcase::TestcaseSetup &t, std::string *err)
Definition: HelixHelpers.h:138
const std::map< std::string, std::string > & properties() const
Definition: LoadTestcase.cc:85
const std::string & value() const
Definition: LoadTestcase.cc:72
#define ERR
Definition: Logger.h:98
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:211
#define if_SolverFlag(N)
xmlNodePtr node() const
Definition: HelixHelpers.h:52
std::string getProp(const std::string &name, const std::string &deflt="") const
Definition: HelixHelpers.h:83
const std::vector< Node > & nodes() const
Definition: LoadTestcase.cc:54
AutoDispose()
Default Ctor using default constructed value and no dispose function.
Definition: AutoDispose.h:107
&#39;Language[_Country]&#39; codes.
Definition: Locale.h:49
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
const std::vector< std::shared_ptr< Node > > & children() const
Definition: LoadTestcase.cc:91
Base class for Exception.
Definition: Exception.h:145
reference value() const
Reference to the Tp object.
Definition: AutoDispose.h:133
const std::string & name() const
Definition: LoadTestcase.cc:66
std::optional< XmlNode > children() const
Definition: HelixHelpers.h:54
bool equals(const std::string_view &n) const
Definition: HelixHelpers.h:58
std::map< std::string, std::string > getAllProps() const
Definition: HelixHelpers.h:61
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:92
T getValue(const std::string &name, const T &deflt) const
bool isElement(void) const
Definition: HelixHelpers.h:59
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
std::string getContent(void) const
Definition: HelixHelpers.h:72
XmlNode(const xmlNodePtr node)
Definition: HelixHelpers.h:44