xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Host/XML.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- XML.h ---------------------------------------------------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #ifndef liblldb_XML_h_
10*0b57cec5SDimitry Andric #define liblldb_XML_h_
11*0b57cec5SDimitry Andric 
12*0b57cec5SDimitry Andric #if defined(LIBXML2_DEFINED)
13*0b57cec5SDimitry Andric #include <libxml/xmlreader.h>
14*0b57cec5SDimitry Andric #endif
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #include <functional>
17*0b57cec5SDimitry Andric #include <string>
18*0b57cec5SDimitry Andric #include <vector>
19*0b57cec5SDimitry Andric 
20*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
21*0b57cec5SDimitry Andric 
22*0b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
23*0b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h"
24*0b57cec5SDimitry Andric #include "lldb/lldb-private.h"
25*0b57cec5SDimitry Andric 
26*0b57cec5SDimitry Andric namespace lldb_private {
27*0b57cec5SDimitry Andric 
28*0b57cec5SDimitry Andric #if defined(LIBXML2_DEFINED)
29*0b57cec5SDimitry Andric typedef xmlNodePtr XMLNodeImpl;
30*0b57cec5SDimitry Andric typedef xmlDocPtr XMLDocumentImpl;
31*0b57cec5SDimitry Andric #else
32*0b57cec5SDimitry Andric typedef void *XMLNodeImpl;
33*0b57cec5SDimitry Andric typedef void *XMLDocumentImpl;
34*0b57cec5SDimitry Andric #endif
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric class XMLNode;
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric typedef std::vector<std::string> NamePath;
39*0b57cec5SDimitry Andric typedef std::function<bool(const XMLNode &node)> NodeCallback;
40*0b57cec5SDimitry Andric typedef std::function<bool(const llvm::StringRef &name,
41*0b57cec5SDimitry Andric                            const llvm::StringRef &value)>
42*0b57cec5SDimitry Andric     AttributeCallback;
43*0b57cec5SDimitry Andric 
44*0b57cec5SDimitry Andric class XMLNode {
45*0b57cec5SDimitry Andric public:
46*0b57cec5SDimitry Andric   XMLNode();
47*0b57cec5SDimitry Andric 
48*0b57cec5SDimitry Andric   XMLNode(XMLNodeImpl node);
49*0b57cec5SDimitry Andric 
50*0b57cec5SDimitry Andric   ~XMLNode();
51*0b57cec5SDimitry Andric 
52*0b57cec5SDimitry Andric   explicit operator bool() const { return IsValid(); }
53*0b57cec5SDimitry Andric 
54*0b57cec5SDimitry Andric   void Clear();
55*0b57cec5SDimitry Andric 
56*0b57cec5SDimitry Andric   bool IsValid() const;
57*0b57cec5SDimitry Andric 
58*0b57cec5SDimitry Andric   bool IsElement() const;
59*0b57cec5SDimitry Andric 
60*0b57cec5SDimitry Andric   llvm::StringRef GetName() const;
61*0b57cec5SDimitry Andric 
62*0b57cec5SDimitry Andric   bool GetElementText(std::string &text) const;
63*0b57cec5SDimitry Andric 
64*0b57cec5SDimitry Andric   bool GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value = 0,
65*0b57cec5SDimitry Andric                                 int base = 0) const;
66*0b57cec5SDimitry Andric 
67*0b57cec5SDimitry Andric   bool GetElementTextAsFloat(double &value, double fail_value = 0.0) const;
68*0b57cec5SDimitry Andric 
69*0b57cec5SDimitry Andric   bool NameIs(const char *name) const;
70*0b57cec5SDimitry Andric 
71*0b57cec5SDimitry Andric   XMLNode GetParent() const;
72*0b57cec5SDimitry Andric 
73*0b57cec5SDimitry Andric   XMLNode GetSibling() const;
74*0b57cec5SDimitry Andric 
75*0b57cec5SDimitry Andric   XMLNode GetChild() const;
76*0b57cec5SDimitry Andric 
77*0b57cec5SDimitry Andric   llvm::StringRef GetAttributeValue(const char *name,
78*0b57cec5SDimitry Andric                                     const char *fail_value = nullptr) const;
79*0b57cec5SDimitry Andric 
80*0b57cec5SDimitry Andric   bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value,
81*0b57cec5SDimitry Andric                                    uint64_t fail_value = 0, int base = 0) const;
82*0b57cec5SDimitry Andric 
83*0b57cec5SDimitry Andric   XMLNode FindFirstChildElementWithName(const char *name) const;
84*0b57cec5SDimitry Andric 
85*0b57cec5SDimitry Andric   XMLNode GetElementForPath(const NamePath &path);
86*0b57cec5SDimitry Andric 
87*0b57cec5SDimitry Andric   // Iterate through all sibling nodes of any type
88*0b57cec5SDimitry Andric   void ForEachSiblingNode(NodeCallback const &callback) const;
89*0b57cec5SDimitry Andric 
90*0b57cec5SDimitry Andric   // Iterate through only the sibling nodes that are elements
91*0b57cec5SDimitry Andric   void ForEachSiblingElement(NodeCallback const &callback) const;
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric   // Iterate through only the sibling nodes that are elements and whose name
94*0b57cec5SDimitry Andric   // matches \a name.
95*0b57cec5SDimitry Andric   void ForEachSiblingElementWithName(const char *name,
96*0b57cec5SDimitry Andric                                      NodeCallback const &callback) const;
97*0b57cec5SDimitry Andric 
98*0b57cec5SDimitry Andric   void ForEachChildNode(NodeCallback const &callback) const;
99*0b57cec5SDimitry Andric 
100*0b57cec5SDimitry Andric   void ForEachChildElement(NodeCallback const &callback) const;
101*0b57cec5SDimitry Andric 
102*0b57cec5SDimitry Andric   void ForEachChildElementWithName(const char *name,
103*0b57cec5SDimitry Andric                                    NodeCallback const &callback) const;
104*0b57cec5SDimitry Andric 
105*0b57cec5SDimitry Andric   void ForEachAttribute(AttributeCallback const &callback) const;
106*0b57cec5SDimitry Andric 
107*0b57cec5SDimitry Andric protected:
108*0b57cec5SDimitry Andric   XMLNodeImpl m_node;
109*0b57cec5SDimitry Andric };
110*0b57cec5SDimitry Andric 
111*0b57cec5SDimitry Andric class XMLDocument {
112*0b57cec5SDimitry Andric public:
113*0b57cec5SDimitry Andric   XMLDocument();
114*0b57cec5SDimitry Andric 
115*0b57cec5SDimitry Andric   ~XMLDocument();
116*0b57cec5SDimitry Andric 
117*0b57cec5SDimitry Andric   explicit operator bool() const { return IsValid(); }
118*0b57cec5SDimitry Andric 
119*0b57cec5SDimitry Andric   bool IsValid() const;
120*0b57cec5SDimitry Andric 
121*0b57cec5SDimitry Andric   void Clear();
122*0b57cec5SDimitry Andric 
123*0b57cec5SDimitry Andric   bool ParseFile(const char *path);
124*0b57cec5SDimitry Andric 
125*0b57cec5SDimitry Andric   bool ParseMemory(const char *xml, size_t xml_length,
126*0b57cec5SDimitry Andric                    const char *url = "untitled.xml");
127*0b57cec5SDimitry Andric 
128*0b57cec5SDimitry Andric   // If \a name is nullptr, just get the root element node, else only return a
129*0b57cec5SDimitry Andric   // value XMLNode if the name of the root element matches \a name.
130*0b57cec5SDimitry Andric   XMLNode GetRootElement(const char *required_name = nullptr);
131*0b57cec5SDimitry Andric 
132*0b57cec5SDimitry Andric   llvm::StringRef GetErrors() const;
133*0b57cec5SDimitry Andric 
134*0b57cec5SDimitry Andric   static void ErrorCallback(void *ctx, const char *format, ...);
135*0b57cec5SDimitry Andric 
136*0b57cec5SDimitry Andric   static bool XMLEnabled();
137*0b57cec5SDimitry Andric 
138*0b57cec5SDimitry Andric protected:
139*0b57cec5SDimitry Andric   XMLDocumentImpl m_document;
140*0b57cec5SDimitry Andric   StreamString m_errors;
141*0b57cec5SDimitry Andric };
142*0b57cec5SDimitry Andric 
143*0b57cec5SDimitry Andric class ApplePropertyList {
144*0b57cec5SDimitry Andric public:
145*0b57cec5SDimitry Andric   ApplePropertyList();
146*0b57cec5SDimitry Andric 
147*0b57cec5SDimitry Andric   ApplePropertyList(const char *path);
148*0b57cec5SDimitry Andric 
149*0b57cec5SDimitry Andric   ~ApplePropertyList();
150*0b57cec5SDimitry Andric 
151*0b57cec5SDimitry Andric   bool ParseFile(const char *path);
152*0b57cec5SDimitry Andric 
153*0b57cec5SDimitry Andric   llvm::StringRef GetErrors() const;
154*0b57cec5SDimitry Andric 
155*0b57cec5SDimitry Andric   explicit operator bool() const { return IsValid(); }
156*0b57cec5SDimitry Andric 
157*0b57cec5SDimitry Andric   bool IsValid() const;
158*0b57cec5SDimitry Andric 
159*0b57cec5SDimitry Andric   XMLNode GetValueNode(const char *key) const;
160*0b57cec5SDimitry Andric 
161*0b57cec5SDimitry Andric   bool GetValueAsString(const char *key, std::string &value) const;
162*0b57cec5SDimitry Andric 
163*0b57cec5SDimitry Andric   StructuredData::ObjectSP GetStructuredData();
164*0b57cec5SDimitry Andric 
165*0b57cec5SDimitry Andric protected:
166*0b57cec5SDimitry Andric   // Using a node returned from GetValueNode() extract its value as a string
167*0b57cec5SDimitry Andric   // (if possible). Array and dictionary nodes will return false as they have
168*0b57cec5SDimitry Andric   // no string value. Boolean nodes will return true and \a value will be
169*0b57cec5SDimitry Andric   // "true" or "false" as the string value comes from the element name itself.
170*0b57cec5SDimitry Andric   // All other nodes will return the text content of the XMLNode.
171*0b57cec5SDimitry Andric   static bool ExtractStringFromValueNode(const XMLNode &node,
172*0b57cec5SDimitry Andric                                          std::string &value);
173*0b57cec5SDimitry Andric 
174*0b57cec5SDimitry Andric   XMLDocument m_xml_doc;
175*0b57cec5SDimitry Andric   XMLNode m_dict_node;
176*0b57cec5SDimitry Andric };
177*0b57cec5SDimitry Andric 
178*0b57cec5SDimitry Andric } // namespace lldb_private
179*0b57cec5SDimitry Andric 
180*0b57cec5SDimitry Andric #endif // liblldb_XML_h_
181