]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/StructuredData.cpp
Copy ^/vendor/NetBSD/tests/dist to contrib/netbsd-tests
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / StructuredData.cpp
1 //===---------------------StructuredData.cpp ---------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Core/StructuredData.h"
11
12 #include <errno.h>
13 #include <stdlib.h>
14 #include <inttypes.h>
15
16 #include "lldb/Core/StreamString.h"
17 #include "lldb/Host/StringConvert.h"
18 #include "lldb/Utility/JSON.h"
19
20 using namespace lldb_private;
21
22
23 //----------------------------------------------------------------------
24 // Functions that use a JSONParser to parse JSON into StructuredData
25 //----------------------------------------------------------------------
26 static StructuredData::ObjectSP ParseJSONValue (JSONParser &json_parser);
27 static StructuredData::ObjectSP ParseJSONObject (JSONParser &json_parser);
28 static StructuredData::ObjectSP ParseJSONArray (JSONParser &json_parser);
29
30 static StructuredData::ObjectSP
31 ParseJSONObject (JSONParser &json_parser)
32 {
33     // The "JSONParser::Token::ObjectStart" token should have already been consumed
34     // by the time this function is called
35     std::unique_ptr<StructuredData::Dictionary> dict_up(new StructuredData::Dictionary());
36
37     std::string value;
38     std::string key;
39     while (1)
40     {
41         JSONParser::Token token = json_parser.GetToken(value);
42
43         if (token == JSONParser::Token::String)
44         {
45             key.swap(value);
46             token = json_parser.GetToken(value);
47             if (token == JSONParser::Token::Colon)
48             {
49                 StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
50                 if (value_sp)
51                     dict_up->AddItem(key, value_sp);
52                 else
53                     break;
54             }
55         }
56         else if (token == JSONParser::Token::ObjectEnd)
57         {
58             return StructuredData::ObjectSP(dict_up.release());
59         }
60         else if (token == JSONParser::Token::Comma)
61         {
62             continue;
63         }
64         else
65         {
66             break;
67         }
68     }
69     return StructuredData::ObjectSP();
70 }
71
72 static StructuredData::ObjectSP
73 ParseJSONArray (JSONParser &json_parser)
74 {
75     // The "JSONParser::Token::ObjectStart" token should have already been consumed
76     // by the time this function is called
77     std::unique_ptr<StructuredData::Array> array_up(new StructuredData::Array());
78
79     std::string value;
80     std::string key;
81     while (1)
82     {
83         StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
84         if (value_sp)
85             array_up->AddItem(value_sp);
86         else
87             break;
88
89         JSONParser::Token token = json_parser.GetToken(value);
90         if (token == JSONParser::Token::Comma)
91         {
92             continue;
93         }
94         else if (token == JSONParser::Token::ArrayEnd)
95         {
96             return StructuredData::ObjectSP(array_up.release());
97         }
98         else
99         {
100             break;
101         }
102     }
103     return StructuredData::ObjectSP();
104 }
105
106 static StructuredData::ObjectSP
107 ParseJSONValue (JSONParser &json_parser)
108 {
109     std::string value;
110     const JSONParser::Token token = json_parser.GetToken(value);
111     switch (token)
112     {
113         case JSONParser::Token::ObjectStart:
114             return ParseJSONObject(json_parser);
115
116         case JSONParser::Token::ArrayStart:
117             return ParseJSONArray(json_parser);
118
119         case JSONParser::Token::Integer:
120             {
121                 bool success = false;
122                 uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
123                 if (success)
124                     return StructuredData::ObjectSP(new StructuredData::Integer(uval));
125             }
126             break;
127
128         case JSONParser::Token::Float:
129             {
130                 bool success = false;
131                 double val = StringConvert::ToDouble(value.c_str(), 0.0, &success);
132                 if (success)
133                     return StructuredData::ObjectSP(new StructuredData::Float(val));
134             }
135             break;
136
137         case JSONParser::Token::String:
138             return StructuredData::ObjectSP(new StructuredData::String(value));
139
140         case JSONParser::Token::True:
141         case JSONParser::Token::False:
142             return StructuredData::ObjectSP(new StructuredData::Boolean(token == JSONParser::Token::True));
143
144         case JSONParser::Token::Null:
145             return StructuredData::ObjectSP(new StructuredData::Null());
146
147         default:
148             break;
149     }
150     return StructuredData::ObjectSP();
151
152 }
153
154 StructuredData::ObjectSP
155 StructuredData::ParseJSON (std::string json_text)
156 {
157     JSONParser json_parser(json_text.c_str());
158     StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser);
159     return object_sp;
160 }
161
162 StructuredData::ObjectSP
163 StructuredData::Object::GetObjectForDotSeparatedPath (llvm::StringRef path)
164 {
165     if (this->GetType() == Type::eTypeDictionary)
166     {
167         std::pair<llvm::StringRef, llvm::StringRef> match = path.split('.');
168         std::string key = match.first.str();
169         ObjectSP value = this->GetAsDictionary()->GetValueForKey (key.c_str());
170         if (value.get())
171         {
172             // Do we have additional words to descend?  If not, return the
173             // value we're at right now.
174             if (match.second.empty())
175             {
176                 return value;
177             }
178             else
179             {
180                 return value->GetObjectForDotSeparatedPath (match.second);
181             }
182         }
183         return ObjectSP();
184     }
185
186     if (this->GetType() == Type::eTypeArray)
187     {
188         std::pair<llvm::StringRef, llvm::StringRef> match = path.split('[');
189         if (match.second.size() == 0)
190         {
191             return this->shared_from_this();
192         }
193         errno = 0;
194         uint64_t val = strtoul (match.second.str().c_str(), NULL, 10);
195         if (errno == 0)
196         {
197             return this->GetAsArray()->GetItemAtIndex(val);
198         }
199         return ObjectSP();
200     }
201
202     return this->shared_from_this();
203 }
204
205 void
206 StructuredData::Object::DumpToStdout() const
207 {
208     StreamString stream;
209     Dump(stream);
210     printf("%s\n", stream.GetString().c_str());
211 }
212
213 void
214 StructuredData::Array::Dump(Stream &s) const
215 {
216     bool first = true;
217     s << "[\n";
218     s.IndentMore();
219     for (const auto &item_sp : m_items)
220     {
221         if (first)
222             first = false;
223         else
224             s << ",\n";
225
226         s.Indent();
227         item_sp->Dump(s);
228     }
229     s.IndentLess();
230     s.EOL();
231     s.Indent();
232     s << "]";
233 }
234
235 void
236 StructuredData::Integer::Dump (Stream &s) const
237 {
238     s.Printf ("%" PRIu64, m_value);
239 }
240
241
242 void
243 StructuredData::Float::Dump (Stream &s) const
244 {
245     s.Printf ("%lg", m_value);
246 }
247
248 void
249 StructuredData::Boolean::Dump (Stream &s) const
250 {
251     if (m_value == true)
252         s.PutCString ("true");
253     else
254         s.PutCString ("false");
255 }
256
257
258 void
259 StructuredData::String::Dump (Stream &s) const
260 {
261     std::string quoted;
262     const size_t strsize = m_value.size();
263     for (size_t i = 0; i < strsize ; ++i)
264     {
265         char ch = m_value[i];
266         if (ch == '"')
267             quoted.push_back ('\\');
268         quoted.push_back (ch);
269     }
270     s.Printf ("\"%s\"", quoted.c_str());
271 }
272
273 void
274 StructuredData::Dictionary::Dump (Stream &s) const
275 {
276     bool first = true;
277     s << "{\n";
278     s.IndentMore();
279     for (const auto &pair : m_dict)
280     {
281         if (first)
282             first = false;
283         else
284             s << ",\n";
285         s.Indent();
286         s << "\"" << pair.first.AsCString() << "\" : ";
287         pair.second->Dump(s);
288     }
289     s.IndentLess();
290     s.EOL();
291     s.Indent();
292     s << "}";
293 }
294
295 void
296 StructuredData::Null::Dump (Stream &s) const
297 {
298     s << "null";
299 }
300
301 void
302 StructuredData::Generic::Dump(Stream &s) const
303 {
304     s << "0x" << m_object;
305 }