Index: lldb/trunk/include/lldb/Breakpoint/Breakpoint.h =================================================================== --- lldb/trunk/include/lldb/Breakpoint/Breakpoint.h +++ lldb/trunk/include/lldb/Breakpoint/Breakpoint.h @@ -26,8 +26,8 @@ #include "lldb/Breakpoint/Stoppoint.h" #include "lldb/Core/Event.h" #include "lldb/Core/SearchFilter.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Utility/StringList.h" +#include "lldb/Utility/StructuredData.h" namespace lldb_private { Index: lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h =================================================================== --- lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h +++ lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h @@ -17,9 +17,9 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Utility/Baton.h" #include "lldb/Utility/StringList.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" namespace lldb_private { Index: lldb/trunk/include/lldb/Core/Event.h =================================================================== --- lldb/trunk/include/lldb/Core/Event.h +++ lldb/trunk/include/lldb/Core/Event.h @@ -11,9 +11,9 @@ #define liblldb_Event_h_ #include "lldb/Core/Broadcaster.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Host/Predicate.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN #include "lldb/lldb-forward.h" // for EventDataSP, ProcessSP, Struct... Index: lldb/trunk/include/lldb/Core/SearchFilter.h =================================================================== --- lldb/trunk/include/lldb/Core/SearchFilter.h +++ lldb/trunk/include/lldb/Core/SearchFilter.h @@ -11,7 +11,7 @@ #define liblldb_SearchFilter_h_ #include "lldb/Core/FileSpecList.h" -#include "lldb/Core/StructuredData.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/FileSpec.h" // for FileSpec #include "lldb/lldb-forward.h" // for SearchFilterSP, TargetSP, Modu... Index: lldb/trunk/include/lldb/Core/StructuredData.h =================================================================== --- lldb/trunk/include/lldb/Core/StructuredData.h +++ lldb/trunk/include/lldb/Core/StructuredData.h @@ -1,560 +0,0 @@ -//===-- StructuredData.h ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_StructuredData_h_ -#define liblldb_StructuredData_h_ - -#include "llvm/ADT/StringRef.h" - -#include "lldb/Utility/ConstString.h" -#include "lldb/Utility/FileSpec.h" // for FileSpec -#include "lldb/lldb-enumerations.h" // for StructuredDataType - -#include -#include -#include -#include -#include // for move -#include -#include - -#include // for assert -#include // for size_t -#include // for uint64_t - -namespace lldb_private { -class Status; -} -namespace lldb_private { -class Stream; -} - -namespace lldb_private { - -//---------------------------------------------------------------------- -/// @class StructuredData StructuredData.h "lldb/Core/StructuredData.h" -/// @brief A class which can hold structured data -/// -/// The StructuredData class is designed to hold the data from a JSON -/// or plist style file -- a serialized data structure with dictionaries -/// (maps, hashes), arrays, and concrete values like integers, floating -/// point numbers, strings, booleans. -/// -/// StructuredData does not presuppose any knowledge of the schema for -/// the data it is holding; it can parse JSON data, for instance, and -/// other parts of lldb can iterate through the parsed data set to find -/// keys and values that may be present. -//---------------------------------------------------------------------- - -class StructuredData { -public: - class Object; - class Array; - class Integer; - class Float; - class Boolean; - class String; - class Dictionary; - class Generic; - - typedef std::shared_ptr ObjectSP; - typedef std::shared_ptr ArraySP; - typedef std::shared_ptr IntegerSP; - typedef std::shared_ptr FloatSP; - typedef std::shared_ptr BooleanSP; - typedef std::shared_ptr StringSP; - typedef std::shared_ptr DictionarySP; - typedef std::shared_ptr GenericSP; - - class Object : public std::enable_shared_from_this { - public: - Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid) - : m_type(t) {} - - virtual ~Object() = default; - - virtual bool IsValid() const { return true; } - - virtual void Clear() { m_type = lldb::eStructuredDataTypeInvalid; } - - lldb::StructuredDataType GetType() const { return m_type; } - - void SetType(lldb::StructuredDataType t) { m_type = t; } - - Array *GetAsArray() { - return ((m_type == lldb::eStructuredDataTypeArray) - ? static_cast(this) - : nullptr); - } - - Dictionary *GetAsDictionary() { - return ( - (m_type == lldb::eStructuredDataTypeDictionary) - ? static_cast(this) - : nullptr); - } - - Integer *GetAsInteger() { - return ((m_type == lldb::eStructuredDataTypeInteger) - ? static_cast(this) - : nullptr); - } - - uint64_t GetIntegerValue(uint64_t fail_value = 0) { - Integer *integer = GetAsInteger(); - return ((integer != nullptr) ? integer->GetValue() : fail_value); - } - - Float *GetAsFloat() { - return ((m_type == lldb::eStructuredDataTypeFloat) - ? static_cast(this) - : nullptr); - } - - double GetFloatValue(double fail_value = 0.0) { - Float *f = GetAsFloat(); - return ((f != nullptr) ? f->GetValue() : fail_value); - } - - Boolean *GetAsBoolean() { - return ((m_type == lldb::eStructuredDataTypeBoolean) - ? static_cast(this) - : nullptr); - } - - bool GetBooleanValue(bool fail_value = false) { - Boolean *b = GetAsBoolean(); - return ((b != nullptr) ? b->GetValue() : fail_value); - } - - String *GetAsString() { - return ((m_type == lldb::eStructuredDataTypeString) - ? static_cast(this) - : nullptr); - } - - llvm::StringRef GetStringValue(const char *fail_value = nullptr) { - String *s = GetAsString(); - if (s) - return s->GetValue(); - - return fail_value; - } - - Generic *GetAsGeneric() { - return ((m_type == lldb::eStructuredDataTypeGeneric) - ? static_cast(this) - : nullptr); - } - - ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path); - - void DumpToStdout(bool pretty_print = true) const; - - virtual void Dump(Stream &s, bool pretty_print = true) const = 0; - - private: - lldb::StructuredDataType m_type; - }; - - class Array : public Object { - public: - Array() : Object(lldb::eStructuredDataTypeArray) {} - - ~Array() override = default; - - bool - ForEach(std::function const &foreach_callback) const { - for (const auto &object_sp : m_items) { - if (foreach_callback(object_sp.get()) == false) - return false; - } - return true; - } - - size_t GetSize() const { return m_items.size(); } - - ObjectSP operator[](size_t idx) { - if (idx < m_items.size()) - return m_items[idx]; - return ObjectSP(); - } - - ObjectSP GetItemAtIndex(size_t idx) const { - assert(idx < GetSize()); - if (idx < m_items.size()) - return m_items[idx]; - return ObjectSP(); - } - - template - bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const { - ObjectSP value_sp = GetItemAtIndex(idx); - if (value_sp.get()) { - if (auto int_value = value_sp->GetAsInteger()) { - result = static_cast(int_value->GetValue()); - return true; - } - } - return false; - } - - template - bool GetItemAtIndexAsInteger(size_t idx, IntType &result, - IntType default_val) const { - bool success = GetItemAtIndexAsInteger(idx, result); - if (!success) - result = default_val; - return success; - } - - bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const { - ObjectSP value_sp = GetItemAtIndex(idx); - if (value_sp.get()) { - if (auto string_value = value_sp->GetAsString()) { - result = string_value->GetValue(); - return true; - } - } - return false; - } - - bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result, - llvm::StringRef default_val) const { - bool success = GetItemAtIndexAsString(idx, result); - if (!success) - result = default_val; - return success; - } - - bool GetItemAtIndexAsString(size_t idx, ConstString &result) const { - ObjectSP value_sp = GetItemAtIndex(idx); - if (value_sp.get()) { - if (auto string_value = value_sp->GetAsString()) { - result = ConstString(string_value->GetValue()); - return true; - } - } - return false; - } - - bool GetItemAtIndexAsString(size_t idx, ConstString &result, - const char *default_val) const { - bool success = GetItemAtIndexAsString(idx, result); - if (!success) - result.SetCString(default_val); - return success; - } - - bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const { - result = nullptr; - ObjectSP value_sp = GetItemAtIndex(idx); - if (value_sp.get()) { - result = value_sp->GetAsDictionary(); - return (result != nullptr); - } - return false; - } - - bool GetItemAtIndexAsArray(size_t idx, Array *&result) const { - result = nullptr; - ObjectSP value_sp = GetItemAtIndex(idx); - if (value_sp.get()) { - result = value_sp->GetAsArray(); - return (result != nullptr); - } - return false; - } - - void Push(ObjectSP item) { m_items.push_back(item); } - - void AddItem(ObjectSP item) { m_items.push_back(item); } - - void Dump(Stream &s, bool pretty_print = true) const override; - - protected: - typedef std::vector collection; - collection m_items; - }; - - class Integer : public Object { - public: - Integer(uint64_t i = 0) - : Object(lldb::eStructuredDataTypeInteger), m_value(i) {} - - ~Integer() override = default; - - void SetValue(uint64_t value) { m_value = value; } - - uint64_t GetValue() { return m_value; } - - void Dump(Stream &s, bool pretty_print = true) const override; - - protected: - uint64_t m_value; - }; - - class Float : public Object { - public: - Float(double d = 0.0) : Object(lldb::eStructuredDataTypeFloat), - m_value(d) {} - - ~Float() override = default; - - void SetValue(double value) { m_value = value; } - - double GetValue() { return m_value; } - - void Dump(Stream &s, bool pretty_print = true) const override; - - protected: - double m_value; - }; - - class Boolean : public Object { - public: - Boolean(bool b = false) : Object(lldb::eStructuredDataTypeBoolean), - m_value(b) {} - - ~Boolean() override = default; - - void SetValue(bool value) { m_value = value; } - - bool GetValue() { return m_value; } - - void Dump(Stream &s, bool pretty_print = true) const override; - - protected: - bool m_value; - }; - - class String : public Object { - public: - String() : Object(lldb::eStructuredDataTypeString) {} - explicit String(llvm::StringRef S) - : Object(lldb::eStructuredDataTypeString), - m_value(S) {} - - void SetValue(llvm::StringRef S) { m_value = S; } - - llvm::StringRef GetValue() { return m_value; } - - void Dump(Stream &s, bool pretty_print = true) const override; - - protected: - std::string m_value; - }; - - class Dictionary : public Object { - public: - Dictionary() : Object(lldb::eStructuredDataTypeDictionary), - m_dict() {} - - ~Dictionary() override = default; - - size_t GetSize() const { return m_dict.size(); } - - void ForEach(std::function const - &callback) const { - for (const auto &pair : m_dict) { - if (callback(pair.first, pair.second.get()) == false) - break; - } - } - - ObjectSP GetKeys() const { - auto object_sp = std::make_shared(); - collection::const_iterator iter; - for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) { - auto key_object_sp = std::make_shared(); - key_object_sp->SetValue(iter->first.AsCString()); - object_sp->Push(key_object_sp); - } - return object_sp; - } - - ObjectSP GetValueForKey(llvm::StringRef key) const { - ObjectSP value_sp; - if (!key.empty()) { - ConstString key_cs(key); - collection::const_iterator iter = m_dict.find(key_cs); - if (iter != m_dict.end()) - value_sp = iter->second; - } - return value_sp; - } - - bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const { - bool success = false; - ObjectSP value_sp = GetValueForKey(key); - if (value_sp.get()) { - Boolean *result_ptr = value_sp->GetAsBoolean(); - if (result_ptr) { - result = result_ptr->GetValue(); - success = true; - } - } - return success; - } - template - bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const { - ObjectSP value_sp = GetValueForKey(key); - if (value_sp) { - if (auto int_value = value_sp->GetAsInteger()) { - result = static_cast(int_value->GetValue()); - return true; - } - } - return false; - } - - template - bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result, - IntType default_val) const { - bool success = GetValueForKeyAsInteger(key, result); - if (!success) - result = default_val; - return success; - } - - bool GetValueForKeyAsString(llvm::StringRef key, - llvm::StringRef &result) const { - ObjectSP value_sp = GetValueForKey(key); - if (value_sp.get()) { - if (auto string_value = value_sp->GetAsString()) { - result = string_value->GetValue(); - return true; - } - } - return false; - } - - bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result, - const char *default_val) const { - bool success = GetValueForKeyAsString(key, result); - if (!success) { - if (default_val) - result = default_val; - else - result = llvm::StringRef(); - } - return success; - } - - bool GetValueForKeyAsString(llvm::StringRef key, - ConstString &result) const { - ObjectSP value_sp = GetValueForKey(key); - if (value_sp.get()) { - if (auto string_value = value_sp->GetAsString()) { - result = ConstString(string_value->GetValue()); - return true; - } - } - return false; - } - - bool GetValueForKeyAsString(llvm::StringRef key, ConstString &result, - const char *default_val) const { - bool success = GetValueForKeyAsString(key, result); - if (!success) - result.SetCString(default_val); - return success; - } - - bool GetValueForKeyAsDictionary(llvm::StringRef key, - Dictionary *&result) const { - result = nullptr; - ObjectSP value_sp = GetValueForKey(key); - if (value_sp.get()) { - result = value_sp->GetAsDictionary(); - return (result != nullptr); - } - return false; - } - - bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const { - result = nullptr; - ObjectSP value_sp = GetValueForKey(key); - if (value_sp.get()) { - result = value_sp->GetAsArray(); - return (result != nullptr); - } - return false; - } - - bool HasKey(llvm::StringRef key) const { - ConstString key_cs(key); - collection::const_iterator search = m_dict.find(key_cs); - return search != m_dict.end(); - } - - void AddItem(llvm::StringRef key, ObjectSP value_sp) { - ConstString key_cs(key); - m_dict[key_cs] = value_sp; - } - - void AddIntegerItem(llvm::StringRef key, uint64_t value) { - AddItem(key, std::make_shared(value)); - } - - void AddFloatItem(llvm::StringRef key, double value) { - AddItem(key, std::make_shared(value)); - } - - void AddStringItem(llvm::StringRef key, llvm::StringRef value) { - AddItem(key, std::make_shared(std::move(value))); - } - - void AddBooleanItem(llvm::StringRef key, bool value) { - AddItem(key, std::make_shared(value)); - } - - void Dump(Stream &s, bool pretty_print = true) const override; - - protected: - typedef std::map collection; - collection m_dict; - }; - - class Null : public Object { - public: - Null() : Object(lldb::eStructuredDataTypeNull) {} - - ~Null() override = default; - - bool IsValid() const override { return false; } - - void Dump(Stream &s, bool pretty_print = true) const override; - }; - - class Generic : public Object { - public: - explicit Generic(void *object = nullptr) - : Object(lldb::eStructuredDataTypeGeneric), m_object(object) {} - - void SetValue(void *value) { m_object = value; } - - void *GetValue() const { return m_object; } - - bool IsValid() const override { return m_object != nullptr; } - - void Dump(Stream &s, bool pretty_print = true) const override; - - private: - void *m_object; - }; - - static ObjectSP ParseJSON(std::string json_text); - - static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error); -}; - -} // namespace lldb_private - -#endif // liblldb_StructuredData_h_ Index: lldb/trunk/include/lldb/Core/StructuredDataImpl.h =================================================================== --- lldb/trunk/include/lldb/Core/StructuredDataImpl.h +++ lldb/trunk/include/lldb/Core/StructuredDataImpl.h @@ -11,10 +11,10 @@ #define liblldb_StructuredDataImpl_h_ #include "lldb/Core/Event.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Target/StructuredDataPlugin.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" #include "llvm/ADT/StringRef.h" Index: lldb/trunk/include/lldb/Core/TraceOptions.h =================================================================== --- lldb/trunk/include/lldb/Core/TraceOptions.h +++ lldb/trunk/include/lldb/Core/TraceOptions.h @@ -13,7 +13,7 @@ #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" -#include "lldb/Core/StructuredData.h" +#include "lldb/Utility/StructuredData.h" namespace lldb_private { class TraceOptions { Index: lldb/trunk/include/lldb/DataFormatters/TypeSummary.h =================================================================== --- lldb/trunk/include/lldb/DataFormatters/TypeSummary.h +++ lldb/trunk/include/lldb/DataFormatters/TypeSummary.h @@ -24,8 +24,8 @@ #include "lldb/lldb-public.h" #include "lldb/Core/FormatEntity.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Utility/Status.h" +#include "lldb/Utility/StructuredData.h" namespace lldb_private { class TypeSummaryOptions { Index: lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h =================================================================== --- lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h +++ lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h @@ -25,8 +25,8 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Core/ValueObject.h" +#include "lldb/Utility/StructuredData.h" namespace lldb_private { class SyntheticChildrenFrontEnd { Index: lldb/trunk/include/lldb/Host/XML.h =================================================================== --- lldb/trunk/include/lldb/Host/XML.h +++ lldb/trunk/include/lldb/Host/XML.h @@ -24,8 +24,8 @@ #include "llvm/ADT/StringRef.h" // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" namespace lldb_private { Index: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h +++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h @@ -19,8 +19,8 @@ #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/PluginInterface.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Utility/Status.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Host/PseudoTerminal.h" Index: lldb/trunk/include/lldb/Target/InstrumentationRuntime.h =================================================================== --- lldb/trunk/include/lldb/Target/InstrumentationRuntime.h +++ lldb/trunk/include/lldb/Target/InstrumentationRuntime.h @@ -18,7 +18,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/PluginInterface.h" -#include "lldb/Core/StructuredData.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" #include "lldb/lldb-types.h" Index: lldb/trunk/include/lldb/Target/InstrumentationRuntimeStopInfo.h =================================================================== --- lldb/trunk/include/lldb/Target/InstrumentationRuntimeStopInfo.h +++ lldb/trunk/include/lldb/Target/InstrumentationRuntimeStopInfo.h @@ -16,8 +16,8 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/StopInfo.h" +#include "lldb/Utility/StructuredData.h" namespace lldb_private { Index: lldb/trunk/include/lldb/Target/Process.h =================================================================== --- lldb/trunk/include/lldb/Target/Process.h +++ lldb/trunk/include/lldb/Target/Process.h @@ -34,7 +34,6 @@ #include "lldb/Core/Listener.h" #include "lldb/Core/LoadedModuleInfoList.h" #include "lldb/Core/PluginInterface.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Core/TraceOptions.h" #include "lldb/Core/UserSettingsController.h" @@ -50,6 +49,7 @@ #include "lldb/Target/ThreadList.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/Status.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" #include "llvm/ADT/ArrayRef.h" Index: lldb/trunk/include/lldb/Target/StopInfo.h =================================================================== --- lldb/trunk/include/lldb/Target/StopInfo.h +++ lldb/trunk/include/lldb/Target/StopInfo.h @@ -16,8 +16,8 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-public.h" namespace lldb_private { Index: lldb/trunk/include/lldb/Target/StructuredDataPlugin.h =================================================================== --- lldb/trunk/include/lldb/Target/StructuredDataPlugin.h +++ lldb/trunk/include/lldb/Target/StructuredDataPlugin.h @@ -11,7 +11,7 @@ #define StructuredDataPlugin_h #include "lldb/Core/PluginInterface.h" -#include "lldb/Core/StructuredData.h" +#include "lldb/Utility/StructuredData.h" namespace lldb_private { Index: lldb/trunk/include/lldb/Target/SystemRuntime.h =================================================================== --- lldb/trunk/include/lldb/Target/SystemRuntime.h +++ lldb/trunk/include/lldb/Target/SystemRuntime.h @@ -18,10 +18,10 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginInterface.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Target/QueueItem.h" #include "lldb/Target/QueueList.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" #include "lldb/lldb-public.h" Index: lldb/trunk/include/lldb/Target/Thread.h =================================================================== --- lldb/trunk/include/lldb/Target/Thread.h +++ lldb/trunk/include/lldb/Target/Thread.h @@ -21,11 +21,11 @@ // Project includes #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Event.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/RegisterCheckpoint.h" #include "lldb/Target/StackFrameList.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" Index: lldb/trunk/include/lldb/Target/ThreadPlanPython.h =================================================================== --- lldb/trunk/include/lldb/Target/ThreadPlanPython.h +++ lldb/trunk/include/lldb/Target/ThreadPlanPython.h @@ -17,13 +17,13 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/Process.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanTracer.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" Index: lldb/trunk/include/lldb/Target/ThreadSpec.h =================================================================== --- lldb/trunk/include/lldb/Target/ThreadSpec.h +++ lldb/trunk/include/lldb/Target/ThreadSpec.h @@ -10,13 +10,9 @@ #ifndef liblldb_ThreadSpec_h_ #define liblldb_ThreadSpec_h_ -// C Includes -// C++ Includes -#include - -// Other libraries and framework includes -// Project includes +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" +#include namespace lldb_private { Index: lldb/trunk/include/lldb/Utility/JSON.h =================================================================== --- lldb/trunk/include/lldb/Utility/JSON.h +++ lldb/trunk/include/lldb/Utility/JSON.h @@ -269,7 +269,7 @@ EndOfFile }; - JSONParser(const char *cstr); + JSONParser(llvm::StringRef data); int GetEscapedChar(bool &was_escaped); Index: lldb/trunk/include/lldb/Utility/StructuredData.h =================================================================== --- lldb/trunk/include/lldb/Utility/StructuredData.h +++ lldb/trunk/include/lldb/Utility/StructuredData.h @@ -0,0 +1,556 @@ +//===-- StructuredData.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StructuredData_h_ +#define liblldb_StructuredData_h_ + +#include "llvm/ADT/StringRef.h" + +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/lldb-enumerations.h" // for StructuredDataType + +#include // for assert +#include // for size_t +#include // for uint64_t +#include +#include +#include +#include +#include // for move +#include +#include + +namespace lldb_private { +class Status; +} +namespace lldb_private { +class Stream; +} + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class StructuredData StructuredData.h "lldb/Utility/StructuredData.h" +/// @brief A class which can hold structured data +/// +/// The StructuredData class is designed to hold the data from a JSON +/// or plist style file -- a serialized data structure with dictionaries +/// (maps, hashes), arrays, and concrete values like integers, floating +/// point numbers, strings, booleans. +/// +/// StructuredData does not presuppose any knowledge of the schema for +/// the data it is holding; it can parse JSON data, for instance, and +/// other parts of lldb can iterate through the parsed data set to find +/// keys and values that may be present. +//---------------------------------------------------------------------- + +class StructuredData { +public: + class Object; + class Array; + class Integer; + class Float; + class Boolean; + class String; + class Dictionary; + class Generic; + + typedef std::shared_ptr ObjectSP; + typedef std::shared_ptr ArraySP; + typedef std::shared_ptr IntegerSP; + typedef std::shared_ptr FloatSP; + typedef std::shared_ptr BooleanSP; + typedef std::shared_ptr StringSP; + typedef std::shared_ptr DictionarySP; + typedef std::shared_ptr GenericSP; + + class Object : public std::enable_shared_from_this { + public: + Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid) + : m_type(t) {} + + virtual ~Object() = default; + + virtual bool IsValid() const { return true; } + + virtual void Clear() { m_type = lldb::eStructuredDataTypeInvalid; } + + lldb::StructuredDataType GetType() const { return m_type; } + + void SetType(lldb::StructuredDataType t) { m_type = t; } + + Array *GetAsArray() { + return ((m_type == lldb::eStructuredDataTypeArray) + ? static_cast(this) + : nullptr); + } + + Dictionary *GetAsDictionary() { + return ((m_type == lldb::eStructuredDataTypeDictionary) + ? static_cast(this) + : nullptr); + } + + Integer *GetAsInteger() { + return ((m_type == lldb::eStructuredDataTypeInteger) + ? static_cast(this) + : nullptr); + } + + uint64_t GetIntegerValue(uint64_t fail_value = 0) { + Integer *integer = GetAsInteger(); + return ((integer != nullptr) ? integer->GetValue() : fail_value); + } + + Float *GetAsFloat() { + return ((m_type == lldb::eStructuredDataTypeFloat) + ? static_cast(this) + : nullptr); + } + + double GetFloatValue(double fail_value = 0.0) { + Float *f = GetAsFloat(); + return ((f != nullptr) ? f->GetValue() : fail_value); + } + + Boolean *GetAsBoolean() { + return ((m_type == lldb::eStructuredDataTypeBoolean) + ? static_cast(this) + : nullptr); + } + + bool GetBooleanValue(bool fail_value = false) { + Boolean *b = GetAsBoolean(); + return ((b != nullptr) ? b->GetValue() : fail_value); + } + + String *GetAsString() { + return ((m_type == lldb::eStructuredDataTypeString) + ? static_cast(this) + : nullptr); + } + + llvm::StringRef GetStringValue(const char *fail_value = nullptr) { + String *s = GetAsString(); + if (s) + return s->GetValue(); + + return fail_value; + } + + Generic *GetAsGeneric() { + return ((m_type == lldb::eStructuredDataTypeGeneric) + ? static_cast(this) + : nullptr); + } + + ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path); + + void DumpToStdout(bool pretty_print = true) const; + + virtual void Dump(Stream &s, bool pretty_print = true) const = 0; + + private: + lldb::StructuredDataType m_type; + }; + + class Array : public Object { + public: + Array() : Object(lldb::eStructuredDataTypeArray) {} + + ~Array() override = default; + + bool + ForEach(std::function const &foreach_callback) const { + for (const auto &object_sp : m_items) { + if (foreach_callback(object_sp.get()) == false) + return false; + } + return true; + } + + size_t GetSize() const { return m_items.size(); } + + ObjectSP operator[](size_t idx) { + if (idx < m_items.size()) + return m_items[idx]; + return ObjectSP(); + } + + ObjectSP GetItemAtIndex(size_t idx) const { + assert(idx < GetSize()); + if (idx < m_items.size()) + return m_items[idx]; + return ObjectSP(); + } + + template + bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const { + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + if (auto int_value = value_sp->GetAsInteger()) { + result = static_cast(int_value->GetValue()); + return true; + } + } + return false; + } + + template + bool GetItemAtIndexAsInteger(size_t idx, IntType &result, + IntType default_val) const { + bool success = GetItemAtIndexAsInteger(idx, result); + if (!success) + result = default_val; + return success; + } + + bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const { + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + if (auto string_value = value_sp->GetAsString()) { + result = string_value->GetValue(); + return true; + } + } + return false; + } + + bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result, + llvm::StringRef default_val) const { + bool success = GetItemAtIndexAsString(idx, result); + if (!success) + result = default_val; + return success; + } + + bool GetItemAtIndexAsString(size_t idx, ConstString &result) const { + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + if (auto string_value = value_sp->GetAsString()) { + result = ConstString(string_value->GetValue()); + return true; + } + } + return false; + } + + bool GetItemAtIndexAsString(size_t idx, ConstString &result, + const char *default_val) const { + bool success = GetItemAtIndexAsString(idx, result); + if (!success) + result.SetCString(default_val); + return success; + } + + bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const { + result = nullptr; + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + result = value_sp->GetAsDictionary(); + return (result != nullptr); + } + return false; + } + + bool GetItemAtIndexAsArray(size_t idx, Array *&result) const { + result = nullptr; + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + result = value_sp->GetAsArray(); + return (result != nullptr); + } + return false; + } + + void Push(ObjectSP item) { m_items.push_back(item); } + + void AddItem(ObjectSP item) { m_items.push_back(item); } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + typedef std::vector collection; + collection m_items; + }; + + class Integer : public Object { + public: + Integer(uint64_t i = 0) + : Object(lldb::eStructuredDataTypeInteger), m_value(i) {} + + ~Integer() override = default; + + void SetValue(uint64_t value) { m_value = value; } + + uint64_t GetValue() { return m_value; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + uint64_t m_value; + }; + + class Float : public Object { + public: + Float(double d = 0.0) + : Object(lldb::eStructuredDataTypeFloat), m_value(d) {} + + ~Float() override = default; + + void SetValue(double value) { m_value = value; } + + double GetValue() { return m_value; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + double m_value; + }; + + class Boolean : public Object { + public: + Boolean(bool b = false) + : Object(lldb::eStructuredDataTypeBoolean), m_value(b) {} + + ~Boolean() override = default; + + void SetValue(bool value) { m_value = value; } + + bool GetValue() { return m_value; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + bool m_value; + }; + + class String : public Object { + public: + String() : Object(lldb::eStructuredDataTypeString) {} + explicit String(llvm::StringRef S) + : Object(lldb::eStructuredDataTypeString), m_value(S) {} + + void SetValue(llvm::StringRef S) { m_value = S; } + + llvm::StringRef GetValue() { return m_value; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + std::string m_value; + }; + + class Dictionary : public Object { + public: + Dictionary() : Object(lldb::eStructuredDataTypeDictionary), m_dict() {} + + ~Dictionary() override = default; + + size_t GetSize() const { return m_dict.size(); } + + void ForEach(std::function const + &callback) const { + for (const auto &pair : m_dict) { + if (callback(pair.first, pair.second.get()) == false) + break; + } + } + + ObjectSP GetKeys() const { + auto object_sp = std::make_shared(); + collection::const_iterator iter; + for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) { + auto key_object_sp = std::make_shared(); + key_object_sp->SetValue(iter->first.AsCString()); + object_sp->Push(key_object_sp); + } + return object_sp; + } + + ObjectSP GetValueForKey(llvm::StringRef key) const { + ObjectSP value_sp; + if (!key.empty()) { + ConstString key_cs(key); + collection::const_iterator iter = m_dict.find(key_cs); + if (iter != m_dict.end()) + value_sp = iter->second; + } + return value_sp; + } + + bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const { + bool success = false; + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + Boolean *result_ptr = value_sp->GetAsBoolean(); + if (result_ptr) { + result = result_ptr->GetValue(); + success = true; + } + } + return success; + } + template + bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const { + ObjectSP value_sp = GetValueForKey(key); + if (value_sp) { + if (auto int_value = value_sp->GetAsInteger()) { + result = static_cast(int_value->GetValue()); + return true; + } + } + return false; + } + + template + bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result, + IntType default_val) const { + bool success = GetValueForKeyAsInteger(key, result); + if (!success) + result = default_val; + return success; + } + + bool GetValueForKeyAsString(llvm::StringRef key, + llvm::StringRef &result) const { + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + if (auto string_value = value_sp->GetAsString()) { + result = string_value->GetValue(); + return true; + } + } + return false; + } + + bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result, + const char *default_val) const { + bool success = GetValueForKeyAsString(key, result); + if (!success) { + if (default_val) + result = default_val; + else + result = llvm::StringRef(); + } + return success; + } + + bool GetValueForKeyAsString(llvm::StringRef key, + ConstString &result) const { + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + if (auto string_value = value_sp->GetAsString()) { + result = ConstString(string_value->GetValue()); + return true; + } + } + return false; + } + + bool GetValueForKeyAsString(llvm::StringRef key, ConstString &result, + const char *default_val) const { + bool success = GetValueForKeyAsString(key, result); + if (!success) + result.SetCString(default_val); + return success; + } + + bool GetValueForKeyAsDictionary(llvm::StringRef key, + Dictionary *&result) const { + result = nullptr; + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + result = value_sp->GetAsDictionary(); + return (result != nullptr); + } + return false; + } + + bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const { + result = nullptr; + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + result = value_sp->GetAsArray(); + return (result != nullptr); + } + return false; + } + + bool HasKey(llvm::StringRef key) const { + ConstString key_cs(key); + collection::const_iterator search = m_dict.find(key_cs); + return search != m_dict.end(); + } + + void AddItem(llvm::StringRef key, ObjectSP value_sp) { + ConstString key_cs(key); + m_dict[key_cs] = value_sp; + } + + void AddIntegerItem(llvm::StringRef key, uint64_t value) { + AddItem(key, std::make_shared(value)); + } + + void AddFloatItem(llvm::StringRef key, double value) { + AddItem(key, std::make_shared(value)); + } + + void AddStringItem(llvm::StringRef key, llvm::StringRef value) { + AddItem(key, std::make_shared(std::move(value))); + } + + void AddBooleanItem(llvm::StringRef key, bool value) { + AddItem(key, std::make_shared(value)); + } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + typedef std::map collection; + collection m_dict; + }; + + class Null : public Object { + public: + Null() : Object(lldb::eStructuredDataTypeNull) {} + + ~Null() override = default; + + bool IsValid() const override { return false; } + + void Dump(Stream &s, bool pretty_print = true) const override; + }; + + class Generic : public Object { + public: + explicit Generic(void *object = nullptr) + : Object(lldb::eStructuredDataTypeGeneric), m_object(object) {} + + void SetValue(void *value) { m_object = value; } + + void *GetValue() const { return m_object; } + + bool IsValid() const override { return m_object != nullptr; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + private: + void *m_object; + }; + + static ObjectSP ParseJSON(std::string json_text); + + static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error); +}; + +} // namespace lldb_private + +#endif // liblldb_StructuredData_h_ Index: lldb/trunk/source/API/SBStructuredData.cpp =================================================================== --- lldb/trunk/source/API/SBStructuredData.cpp +++ lldb/trunk/source/API/SBStructuredData.cpp @@ -11,11 +11,11 @@ #include "lldb/API/SBStream.h" #include "lldb/Core/Event.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/StructuredDataPlugin.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/Utility/StructuredData.h" using namespace lldb; using namespace lldb_private; Index: lldb/trunk/source/API/SBThread.cpp =================================================================== --- lldb/trunk/source/API/SBThread.cpp +++ lldb/trunk/source/API/SBThread.cpp @@ -16,7 +16,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Core/ValueObject.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/CompileUnit.h" @@ -34,6 +33,7 @@ #include "lldb/Target/ThreadPlanStepRange.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Stream.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/API/SBAddress.h" #include "lldb/API/SBDebugger.h" Index: lldb/trunk/source/API/SBThreadPlan.cpp =================================================================== --- lldb/trunk/source/API/SBThreadPlan.cpp +++ lldb/trunk/source/API/SBThreadPlan.cpp @@ -16,7 +16,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/SymbolContext.h" @@ -33,6 +32,7 @@ #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepRange.h" #include "lldb/Utility/Stream.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/API/SBAddress.h" #include "lldb/API/SBDebugger.h" Index: lldb/trunk/source/Core/CMakeLists.txt =================================================================== --- lldb/trunk/source/Core/CMakeLists.txt +++ lldb/trunk/source/Core/CMakeLists.txt @@ -32,7 +32,6 @@ State.cpp StreamAsynchronousIO.cpp StreamFile.cpp - StructuredData.cpp Timer.cpp UserSettingsController.cpp Value.cpp Index: lldb/trunk/source/Core/FormatEntity.cpp =================================================================== --- lldb/trunk/source/Core/FormatEntity.cpp +++ lldb/trunk/source/Core/FormatEntity.cpp @@ -14,8 +14,7 @@ #include "lldb/Core/ArchSpec.h" // for ArchSpec #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" // for RegisterValue -#include "lldb/Core/StructuredData.h" // for StructuredData::O... +#include "lldb/Core/RegisterValue.h" // for RegisterValue #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DataVisualization.h" @@ -50,9 +49,10 @@ #include "lldb/Utility/SharingPtr.h" // for SharingPtr #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" -#include "lldb/Utility/StringList.h" // for StringList -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS -#include "lldb/lldb-forward.h" // for ValueObjectSP +#include "lldb/Utility/StringList.h" // for StringList +#include "lldb/Utility/StructuredData.h" // for StructuredData::O... +#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS +#include "lldb/lldb-forward.h" // for ValueObjectSP #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" // for Triple, Triple::O... Index: lldb/trunk/source/Core/StructuredData.cpp =================================================================== --- lldb/trunk/source/Core/StructuredData.cpp +++ lldb/trunk/source/Core/StructuredData.cpp @@ -1,314 +0,0 @@ -//===---------------------StructuredData.cpp ---------------------*- C++-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Core/StructuredData.h" - -#include "lldb/Host/File.h" -#include "lldb/Host/StringConvert.h" -#include "lldb/Utility/DataBuffer.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/JSON.h" -#include "lldb/Utility/Status.h" -#include "lldb/Utility/Stream.h" // for Stream -#include "lldb/Utility/StreamString.h" -#include "lldb/lldb-enumerations.h" // for FilePermissions::eFilePermiss... -#include "lldb/lldb-forward.h" // for DataBufferSP - -#include "llvm/ADT/STLExtras.h" // for make_unique - -#include // for numeric_limits - -#include -#include -#include // for printf -#include -#include // for off_t - -using namespace lldb_private; - -//---------------------------------------------------------------------- -// Functions that use a JSONParser to parse JSON into StructuredData -//---------------------------------------------------------------------- -static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser); -static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser); -static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser); - -StructuredData::ObjectSP -StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) { - StructuredData::ObjectSP return_sp; - if (!input_spec.Exists()) { - error.SetErrorStringWithFormat("input file %s does not exist.", - input_spec.GetPath().c_str()); - return return_sp; - } - - File input_file(nullptr, File::OpenOptions::eOpenOptionRead, - lldb::eFilePermissionsUserRead); - std::string input_path = input_spec.GetPath(); - error = - input_file.Open(input_path.c_str(), File::OpenOptions::eOpenOptionRead, - lldb::eFilePermissionsUserRead); - - if (!error.Success()) { - error.SetErrorStringWithFormat("could not open input file: %s - %s.", - input_spec.GetPath().c_str(), - error.AsCString()); - return return_sp; - } - - lldb::DataBufferSP input_data; - size_t num_bytes = std::numeric_limits::max(); - off_t offset = 0; - error = input_file.Read(num_bytes, offset, true, input_data); - if (!error.Success()) { - error.SetErrorStringWithFormat("could not read input file: %s - %s.", - input_spec.GetPath().c_str(), - error.AsCString()); - return return_sp; - } - JSONParser json_parser((char *)input_data->GetBytes()); - return_sp = ParseJSONValue(json_parser); - return return_sp; -} - -static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser) { - // The "JSONParser::Token::ObjectStart" token should have already been - // consumed by the time this function is called - auto dict_up = llvm::make_unique(); - - std::string value; - std::string key; - while (1) { - JSONParser::Token token = json_parser.GetToken(value); - - if (token == JSONParser::Token::String) { - key.swap(value); - token = json_parser.GetToken(value); - if (token == JSONParser::Token::Colon) { - StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser); - if (value_sp) - dict_up->AddItem(key, value_sp); - else - break; - } - } else if (token == JSONParser::Token::ObjectEnd) { - return StructuredData::ObjectSP(dict_up.release()); - } else if (token == JSONParser::Token::Comma) { - continue; - } else { - break; - } - } - return StructuredData::ObjectSP(); -} - -static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser) { - // The "JSONParser::Token::ObjectStart" token should have already been - // consumed - // by the time this function is called - auto array_up = llvm::make_unique(); - - std::string value; - std::string key; - while (1) { - StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser); - if (value_sp) - array_up->AddItem(value_sp); - else - break; - - JSONParser::Token token = json_parser.GetToken(value); - if (token == JSONParser::Token::Comma) { - continue; - } else if (token == JSONParser::Token::ArrayEnd) { - return StructuredData::ObjectSP(array_up.release()); - } else { - break; - } - } - return StructuredData::ObjectSP(); -} - -static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser) { - std::string value; - const JSONParser::Token token = json_parser.GetToken(value); - switch (token) { - case JSONParser::Token::ObjectStart: - return ParseJSONObject(json_parser); - - case JSONParser::Token::ArrayStart: - return ParseJSONArray(json_parser); - - case JSONParser::Token::Integer: { - bool success = false; - uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success); - if (success) - return std::make_shared(uval); - } break; - - case JSONParser::Token::Float: { - bool success = false; - double val = StringConvert::ToDouble(value.c_str(), 0.0, &success); - if (success) - return std::make_shared(val); - } break; - - case JSONParser::Token::String: - return std::make_shared(value); - - case JSONParser::Token::True: - case JSONParser::Token::False: - return std::make_shared(token == - JSONParser::Token::True); - - case JSONParser::Token::Null: - return std::make_shared(); - - default: - break; - } - return StructuredData::ObjectSP(); -} - -StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) { - JSONParser json_parser(json_text.c_str()); - StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser); - return object_sp; -} - -StructuredData::ObjectSP -StructuredData::Object::GetObjectForDotSeparatedPath(llvm::StringRef path) { - if (this->GetType() == lldb::eStructuredDataTypeDictionary) { - std::pair match = path.split('.'); - std::string key = match.first.str(); - ObjectSP value = this->GetAsDictionary()->GetValueForKey(key); - if (value.get()) { - // Do we have additional words to descend? If not, return the - // value we're at right now. - if (match.second.empty()) { - return value; - } else { - return value->GetObjectForDotSeparatedPath(match.second); - } - } - return ObjectSP(); - } - - if (this->GetType() == lldb::eStructuredDataTypeArray) { - std::pair match = path.split('['); - if (match.second.size() == 0) { - return this->shared_from_this(); - } - errno = 0; - uint64_t val = strtoul(match.second.str().c_str(), NULL, 10); - if (errno == 0) { - return this->GetAsArray()->GetItemAtIndex(val); - } - return ObjectSP(); - } - - return this->shared_from_this(); -} - -void StructuredData::Object::DumpToStdout(bool pretty_print) const { - StreamString stream; - Dump(stream, pretty_print); - printf("%s\n", stream.GetData()); -} - -void StructuredData::Array::Dump(Stream &s, bool pretty_print) const { - bool first = true; - s << "["; - if (pretty_print) { - s << "\n"; - s.IndentMore(); - } - for (const auto &item_sp : m_items) { - if (first) { - first = false; - } else { - s << ","; - if (pretty_print) - s << "\n"; - } - - if (pretty_print) - s.Indent(); - item_sp->Dump(s, pretty_print); - } - if (pretty_print) { - s.IndentLess(); - s.EOL(); - s.Indent(); - } - s << "]"; -} - -void StructuredData::Integer::Dump(Stream &s, bool pretty_print) const { - s.Printf("%" PRIu64, m_value); -} - -void StructuredData::Float::Dump(Stream &s, bool pretty_print) const { - s.Printf("%lg", m_value); -} - -void StructuredData::Boolean::Dump(Stream &s, bool pretty_print) const { - if (m_value == true) - s.PutCString("true"); - else - s.PutCString("false"); -} - -void StructuredData::String::Dump(Stream &s, bool pretty_print) const { - std::string quoted; - const size_t strsize = m_value.size(); - for (size_t i = 0; i < strsize; ++i) { - char ch = m_value[i]; - if (ch == '"' || ch == '\\') - quoted.push_back('\\'); - quoted.push_back(ch); - } - s.Printf("\"%s\"", quoted.c_str()); -} - -void StructuredData::Dictionary::Dump(Stream &s, bool pretty_print) const { - bool first = true; - s << "{"; - if (pretty_print) { - s << "\n"; - s.IndentMore(); - } - for (const auto &pair : m_dict) { - if (first) - first = false; - else { - s << ","; - if (pretty_print) - s << "\n"; - } - if (pretty_print) - s.Indent(); - s << "\"" << pair.first.AsCString() << "\" : "; - pair.second->Dump(s, pretty_print); - } - if (pretty_print) { - s.IndentLess(); - s.EOL(); - s.Indent(); - } - s << "}"; -} - -void StructuredData::Null::Dump(Stream &s, bool pretty_print) const { - s << "null"; -} - -void StructuredData::Generic::Dump(Stream &s, bool pretty_print) const { - s << "0x" << m_object; -} Index: lldb/trunk/source/Host/macosx/Host.mm =================================================================== --- lldb/trunk/source/Host/macosx/Host.mm +++ lldb/trunk/source/Host/macosx/Host.mm @@ -59,7 +59,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/ThreadLauncher.h" @@ -73,6 +72,7 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StructuredData.h" #include "llvm/Support/FileSystem.h" Index: lldb/trunk/source/Host/windows/Host.cpp =================================================================== --- lldb/trunk/source/Host/windows/Host.cpp +++ lldb/trunk/source/Host/windows/Host.cpp @@ -20,11 +20,11 @@ #include "lldb/Utility/Status.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/StructuredData.h" #include "llvm/Support/ConvertUTF.h" Index: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h =================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h +++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h @@ -18,11 +18,11 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Process.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/SafeMachO.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UUID.h" #include "llvm/ADT/Triple.h" Index: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h =================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h +++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h @@ -25,11 +25,11 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Process.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/SafeMachO.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UUID.h" #include "DynamicLoaderDarwin.h" Index: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h =================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h +++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h @@ -28,11 +28,11 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Process.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/SafeMachO.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UUID.h" #include "DynamicLoaderDarwin.h" Index: lldb/trunk/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h =================================================================== --- lldb/trunk/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h +++ lldb/trunk/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h @@ -14,9 +14,9 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/InstrumentationRuntime.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" namespace lldb_private { Index: lldb/trunk/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h =================================================================== --- lldb/trunk/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h +++ lldb/trunk/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h @@ -10,9 +10,9 @@ #ifndef liblldb_MainThreadCheckerRuntime_h_ #define liblldb_MainThreadCheckerRuntime_h_ -#include "lldb/Core/StructuredData.h" #include "lldb/Target/ABI.h" #include "lldb/Target/InstrumentationRuntime.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" namespace lldb_private { Index: lldb/trunk/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h =================================================================== --- lldb/trunk/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h +++ lldb/trunk/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h @@ -14,9 +14,9 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/ABI.h" #include "lldb/Target/InstrumentationRuntime.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" namespace lldb_private { Index: lldb/trunk/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h =================================================================== --- lldb/trunk/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h +++ lldb/trunk/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h @@ -10,9 +10,9 @@ #ifndef liblldb_UndefinedBehaviorSanitizerRuntime_h_ #define liblldb_UndefinedBehaviorSanitizerRuntime_h_ -#include "lldb/Core/StructuredData.h" #include "lldb/Target/ABI.h" #include "lldb/Target/InstrumentationRuntime.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" namespace lldb_private { Index: lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h =================================================================== --- lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h +++ lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h @@ -16,8 +16,8 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/OperatingSystem.h" +#include "lldb/Utility/StructuredData.h" class DynamicRegisterInfo; Index: lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp =================================================================== --- lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -22,7 +22,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/RegisterValue.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" @@ -35,6 +34,7 @@ #include "lldb/Target/ThreadList.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StructuredData.h" using namespace lldb; using namespace lldb_private; Index: lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt =================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt +++ lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt @@ -7,7 +7,6 @@ ProcessPOSIXLog.cpp LINK_LIBS - lldbCore lldbInterpreter LINK_COMPONENTS Support Index: lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -17,8 +17,8 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" class DynamicRegisterInfo { Index: lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -15,11 +15,11 @@ // Project includes #include "lldb/Core/ArchSpec.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StructuredData.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Host/StringConvert.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/StringExtractor.h" +#include "lldb/Utility/StructuredData.h" using namespace lldb; using namespace lldb_private; Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -23,9 +23,9 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/ArchSpec.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Target/Process.h" #include "lldb/Utility/StreamGDBRemote.h" +#include "lldb/Utility/StructuredData.h" #include "llvm/ADT/Optional.h" Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -22,7 +22,6 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Threading.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Host/Config.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Host.h" @@ -35,6 +34,7 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamGDBRemote.h" #include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UriParser.h" // Project includes Index: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -24,7 +24,6 @@ #include "lldb/Core/Broadcaster.h" #include "lldb/Core/LoadedModuleInfoList.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Host/HostThread.h" #include "lldb/Target/Process.h" @@ -35,6 +34,7 @@ #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringExtractor.h" #include "lldb/Utility/StringList.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private-forward.h" #include "GDBRemoteCommunicationClient.h" Index: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -16,9 +16,9 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/StructuredData.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/StructuredData.h" class StringExtractor; Index: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h =================================================================== --- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -21,10 +21,10 @@ // Project includes #include "lldb/Utility/Flags.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Host/File.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-defines.h" #include "llvm/ADT/ArrayRef.h" Index: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h =================================================================== --- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h +++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h @@ -19,12 +19,12 @@ // Other libraries and framework include // Project includes #include "lldb/Core/ModuleList.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Target/Process.h" #include "lldb/Target/QueueItem.h" #include "lldb/Target/SystemRuntime.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UUID.h" #include "AppleGetItemInfoHandler.h" Index: lldb/trunk/source/Target/Platform.cpp =================================================================== --- lldb/trunk/source/Target/Platform.cpp +++ lldb/trunk/source/Target/Platform.cpp @@ -25,7 +25,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" @@ -42,6 +41,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" +#include "lldb/Utility/StructuredData.h" #include "llvm/Support/FileSystem.h" Index: lldb/trunk/source/Target/ThreadSpec.cpp =================================================================== --- lldb/trunk/source/Target/ThreadSpec.cpp +++ lldb/trunk/source/Target/ThreadSpec.cpp @@ -11,9 +11,9 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Target/Thread.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/StructuredData.h" using namespace lldb; using namespace lldb_private; Index: lldb/trunk/source/Utility/CMakeLists.txt =================================================================== --- lldb/trunk/source/Utility/CMakeLists.txt +++ lldb/trunk/source/Utility/CMakeLists.txt @@ -28,6 +28,7 @@ StringExtractorGDBRemote.cpp StringLexer.cpp StringList.cpp + StructuredData.cpp TaskPool.cpp TildeExpressionResolver.cpp UserID.cpp Index: lldb/trunk/source/Utility/JSON.cpp =================================================================== --- lldb/trunk/source/Utility/JSON.cpp +++ lldb/trunk/source/Utility/JSON.cpp @@ -191,7 +191,7 @@ JSONArray::Size JSONArray::GetNumElements() { return m_elements.size(); } -JSONParser::JSONParser(const char *cstr) : StringExtractor(cstr) {} +JSONParser::JSONParser(llvm::StringRef data) : StringExtractor(data) {} JSONParser::Token JSONParser::GetToken(std::string &value) { StreamString error; Index: lldb/trunk/source/Utility/StructuredData.cpp =================================================================== --- lldb/trunk/source/Utility/StructuredData.cpp +++ lldb/trunk/source/Utility/StructuredData.cpp @@ -0,0 +1,286 @@ +//===---------------------StructuredData.cpp ---------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/StructuredData.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/JSON.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StreamString.h" +#include "llvm/ADT/STLExtras.h" // for make_unique +#include +#include +#include +#include // for numeric_limits + +using namespace lldb_private; + +//---------------------------------------------------------------------- +// Functions that use a JSONParser to parse JSON into StructuredData +//---------------------------------------------------------------------- +static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser); +static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser); +static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser); + +StructuredData::ObjectSP +StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) { + StructuredData::ObjectSP return_sp; + if (!input_spec.Exists()) { + error.SetErrorStringWithFormatv("input file {0} does not exist.", + input_spec); + return return_sp; + } + + auto buffer_or_error = llvm::MemoryBuffer::getFile(input_spec.GetPath()); + if (!buffer_or_error) { + error.SetErrorStringWithFormatv("could not open input file: {0} - {1}.", + input_spec.GetPath(), + buffer_or_error.getError().message()); + return return_sp; + } + + JSONParser json_parser(buffer_or_error.get()->getBuffer()); + return_sp = ParseJSONValue(json_parser); + return return_sp; +} + +static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser) { + // The "JSONParser::Token::ObjectStart" token should have already been + // consumed by the time this function is called + auto dict_up = llvm::make_unique(); + + std::string value; + std::string key; + while (1) { + JSONParser::Token token = json_parser.GetToken(value); + + if (token == JSONParser::Token::String) { + key.swap(value); + token = json_parser.GetToken(value); + if (token == JSONParser::Token::Colon) { + StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser); + if (value_sp) + dict_up->AddItem(key, value_sp); + else + break; + } + } else if (token == JSONParser::Token::ObjectEnd) { + return StructuredData::ObjectSP(dict_up.release()); + } else if (token == JSONParser::Token::Comma) { + continue; + } else { + break; + } + } + return StructuredData::ObjectSP(); +} + +static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser) { + // The "JSONParser::Token::ObjectStart" token should have already been + // consumed + // by the time this function is called + auto array_up = llvm::make_unique(); + + std::string value; + std::string key; + while (1) { + StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser); + if (value_sp) + array_up->AddItem(value_sp); + else + break; + + JSONParser::Token token = json_parser.GetToken(value); + if (token == JSONParser::Token::Comma) { + continue; + } else if (token == JSONParser::Token::ArrayEnd) { + return StructuredData::ObjectSP(array_up.release()); + } else { + break; + } + } + return StructuredData::ObjectSP(); +} + +static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser) { + std::string value; + const JSONParser::Token token = json_parser.GetToken(value); + switch (token) { + case JSONParser::Token::ObjectStart: + return ParseJSONObject(json_parser); + + case JSONParser::Token::ArrayStart: + return ParseJSONArray(json_parser); + + case JSONParser::Token::Integer: { + uint64_t uval; + if (llvm::to_integer(value, uval, 0)) + return std::make_shared(uval); + } break; + + case JSONParser::Token::Float: { + double val; + if (llvm::to_float(value, val)) + return std::make_shared(val); + } break; + + case JSONParser::Token::String: + return std::make_shared(value); + + case JSONParser::Token::True: + case JSONParser::Token::False: + return std::make_shared(token == + JSONParser::Token::True); + + case JSONParser::Token::Null: + return std::make_shared(); + + default: + break; + } + return StructuredData::ObjectSP(); +} + +StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) { + JSONParser json_parser(json_text.c_str()); + StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser); + return object_sp; +} + +StructuredData::ObjectSP +StructuredData::Object::GetObjectForDotSeparatedPath(llvm::StringRef path) { + if (this->GetType() == lldb::eStructuredDataTypeDictionary) { + std::pair match = path.split('.'); + std::string key = match.first.str(); + ObjectSP value = this->GetAsDictionary()->GetValueForKey(key); + if (value.get()) { + // Do we have additional words to descend? If not, return the + // value we're at right now. + if (match.second.empty()) { + return value; + } else { + return value->GetObjectForDotSeparatedPath(match.second); + } + } + return ObjectSP(); + } + + if (this->GetType() == lldb::eStructuredDataTypeArray) { + std::pair match = path.split('['); + if (match.second.size() == 0) { + return this->shared_from_this(); + } + errno = 0; + uint64_t val = strtoul(match.second.str().c_str(), NULL, 10); + if (errno == 0) { + return this->GetAsArray()->GetItemAtIndex(val); + } + return ObjectSP(); + } + + return this->shared_from_this(); +} + +void StructuredData::Object::DumpToStdout(bool pretty_print) const { + StreamString stream; + Dump(stream, pretty_print); + llvm::outs() << stream.GetString(); +} + +void StructuredData::Array::Dump(Stream &s, bool pretty_print) const { + bool first = true; + s << "["; + if (pretty_print) { + s << "\n"; + s.IndentMore(); + } + for (const auto &item_sp : m_items) { + if (first) { + first = false; + } else { + s << ","; + if (pretty_print) + s << "\n"; + } + + if (pretty_print) + s.Indent(); + item_sp->Dump(s, pretty_print); + } + if (pretty_print) { + s.IndentLess(); + s.EOL(); + s.Indent(); + } + s << "]"; +} + +void StructuredData::Integer::Dump(Stream &s, bool pretty_print) const { + s.Printf("%" PRIu64, m_value); +} + +void StructuredData::Float::Dump(Stream &s, bool pretty_print) const { + s.Printf("%lg", m_value); +} + +void StructuredData::Boolean::Dump(Stream &s, bool pretty_print) const { + if (m_value == true) + s.PutCString("true"); + else + s.PutCString("false"); +} + +void StructuredData::String::Dump(Stream &s, bool pretty_print) const { + std::string quoted; + const size_t strsize = m_value.size(); + for (size_t i = 0; i < strsize; ++i) { + char ch = m_value[i]; + if (ch == '"' || ch == '\\') + quoted.push_back('\\'); + quoted.push_back(ch); + } + s.Printf("\"%s\"", quoted.c_str()); +} + +void StructuredData::Dictionary::Dump(Stream &s, bool pretty_print) const { + bool first = true; + s << "{"; + if (pretty_print) { + s << "\n"; + s.IndentMore(); + } + for (const auto &pair : m_dict) { + if (first) + first = false; + else { + s << ","; + if (pretty_print) + s << "\n"; + } + if (pretty_print) + s.Indent(); + s << "\"" << pair.first.AsCString() << "\" : "; + pair.second->Dump(s, pretty_print); + } + if (pretty_print) { + s.IndentLess(); + s.EOL(); + s.Indent(); + } + s << "}"; +} + +void StructuredData::Null::Dump(Stream &s, bool pretty_print) const { + s << "null"; +} + +void StructuredData::Generic::Dump(Stream &s, bool pretty_print) const { + s << "0x" << m_object; +} Index: lldb/trunk/unittests/Core/CMakeLists.txt =================================================================== --- lldb/trunk/unittests/Core/CMakeLists.txt +++ lldb/trunk/unittests/Core/CMakeLists.txt @@ -6,7 +6,6 @@ ScalarTest.cpp StateTest.cpp StreamCallbackTest.cpp - StructuredDataTest.cpp TimerTest.cpp LINK_LIBS Index: lldb/trunk/unittests/Core/StructuredDataTest.cpp =================================================================== --- lldb/trunk/unittests/Core/StructuredDataTest.cpp +++ lldb/trunk/unittests/Core/StructuredDataTest.cpp @@ -1,32 +0,0 @@ -//===-- StructuredDataTest.cpp ----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "gtest/gtest.h" - -#include "lldb/Core/StructuredData.h" -#include "lldb/Utility/StreamString.h" - -#include "llvm/BinaryFormat/MachO.h" - -using namespace lldb; -using namespace lldb_private; - -TEST(StructuredDataTest, StringDump) { - std::pair TestCases[] = { - { R"(asdfg)", R"("asdfg")" }, - { R"(as"df)", R"("as\"df")" }, - { R"(as\df)", R"("as\\df")" }, - }; - for(auto P : TestCases) { - StreamString S; - const bool pretty_print = false; - StructuredData::String(P.first).Dump(S, pretty_print); - EXPECT_EQ(P.second, S.GetString()); - } -} Index: lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp =================================================================== --- lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp @@ -12,10 +12,10 @@ #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Core/TraceOptions.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-enumerations.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Testing/Support/Error.h" Index: lldb/trunk/unittests/Utility/CMakeLists.txt =================================================================== --- lldb/trunk/unittests/Utility/CMakeLists.txt +++ lldb/trunk/unittests/Utility/CMakeLists.txt @@ -6,6 +6,7 @@ NameMatchesTest.cpp StatusTest.cpp StringExtractorTest.cpp + StructuredDataTest.cpp TaskPoolTest.cpp TildeExpressionResolverTest.cpp TimeoutTest.cpp @@ -18,3 +19,7 @@ LINK_COMPONENTS Support ) + +add_unittest_inputs(UtilityTests + StructuredData-basic.json + ) Index: lldb/trunk/unittests/Utility/Inputs/StructuredData-basic.json =================================================================== --- lldb/trunk/unittests/Utility/Inputs/StructuredData-basic.json +++ lldb/trunk/unittests/Utility/Inputs/StructuredData-basic.json @@ -0,0 +1 @@ +[1, 2, 3] Index: lldb/trunk/unittests/Utility/StructuredDataTest.cpp =================================================================== --- lldb/trunk/unittests/Utility/StructuredDataTest.cpp +++ lldb/trunk/unittests/Utility/StructuredDataTest.cpp @@ -0,0 +1,66 @@ +//===-- StructuredDataTest.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "lldb/Utility/Status.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StructuredData.h" +#include "llvm/Support/Path.h" + +extern const char *TestMainArgv0; + +using namespace lldb; +using namespace lldb_private; + +namespace { + +class StructuredDataTest : public testing::Test { +public: + static void SetUpTestCase() { + s_inputs_folder = llvm::sys::path::parent_path(TestMainArgv0); + llvm::sys::path::append(s_inputs_folder, "Inputs"); + } + +protected: + static llvm::SmallString<128> s_inputs_folder; +}; +} // namespace + +llvm::SmallString<128> StructuredDataTest::s_inputs_folder; + +TEST_F(StructuredDataTest, StringDump) { + std::pair TestCases[] = { + {R"(asdfg)", R"("asdfg")"}, + {R"(as"df)", R"("as\"df")"}, + {R"(as\df)", R"("as\\df")"}, + }; + for (auto P : TestCases) { + StreamString S; + const bool pretty_print = false; + StructuredData::String(P.first).Dump(S, pretty_print); + EXPECT_EQ(P.second, S.GetString()); + } +} + +TEST_F(StructuredDataTest, ParseJSONFromFile) { + Status status; + auto object_sp = StructuredData::ParseJSONFromFile( + FileSpec("non-existing-file.json", false), status); + EXPECT_EQ(nullptr, object_sp); + + llvm::SmallString<128> input = s_inputs_folder; + llvm::sys::path::append(input, "StructuredData-basic.json"); + object_sp = StructuredData::ParseJSONFromFile(FileSpec(input, false), status); + ASSERT_NE(nullptr, object_sp); + + StreamString S; + object_sp->Dump(S, false); + EXPECT_EQ("[1,2,3]", S.GetString()); +} Index: lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.cpp =================================================================== --- lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.cpp +++ lldb/trunk/unittests/tools/lldb-server/tests/MessageObjects.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// #include "MessageObjects.h" -#include "lldb/Core/StructuredData.h" +#include "lldb/Utility/StructuredData.h" #include "llvm/ADT/StringExtras.h" #include "gtest/gtest.h"