Index: include/lldb/Utility/UUID.h =================================================================== --- include/lldb/Utility/UUID.h +++ include/lldb/Utility/UUID.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace llvm { class StringRef; @@ -24,78 +25,85 @@ class Stream; +// An arbitrary-size UUID representation +// NOTE: Most UUIDs are 16 bytes, but some Linux build-ids (SHA1) are 20 bytes class UUID { public: - // Most UUIDs are 16 bytes, but some Linux build-ids (SHA1) are 20. - typedef uint8_t ValueType[20]; - //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - UUID(); - UUID(const UUID &rhs); + UUID() = default; UUID(const void *uuid_bytes, uint32_t num_uuid_bytes); - ~UUID(); - - const UUID &operator=(const UUID &rhs); - - void Clear(); + void Clear() { m_uuid.clear(); } void Dump(Stream *s) const; - const void *GetBytes() const; + const uint8_t *GetBytes() const; - size_t GetByteSize() const; + size_t GetByteSize() const { return m_uuid.size(); } bool IsValid() const; - bool SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes = 16); + void SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes = 16); - std::string GetAsString(const char *separator = nullptr) const; + // Returns a string representation of the UUID + // + // In order to preserve the compatibility with common UUID formats, + // the first 16 bytes of the UUID are using the following format: + // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx[-xxxxxxxx]* + // + // After the first 16 bytes the UUID values are separated in groups of 4. + std::string GetAsString(const char *separator = "-") const; - size_t SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes = 16); - size_t SetFromCString(const char *c_str, uint32_t num_uuid_bytes = 16); + bool SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes = 16); + bool SetFromCString(const char *c_str, uint32_t num_uuid_bytes = 16); // Decode as many UUID bytes (up to 16) as possible from the C string "cstr" // This is used for auto completion where a partial UUID might have been - // typed in. It - //------------------------------------------------------------------ - /// Decode as many UUID bytes (up to 16) as possible from the C - /// string \a cstr. + // typed in. /// - /// @param[in] cstr - /// A NULL terminate C string that points at a UUID string value + /// @param[in] str + /// A StringRef that points at a UUID string value /// (no leading spaces). The string must contain only hex /// characters and optionally can contain the '-' sepearators. /// - /// @param[in] uuid_bytes - /// A buffer of bytes that will contain a full or patially - /// decoded UUID. - /// /// @return - /// The original string, with all decoded bytes removed. + /// The partially decoded UUID prefix //------------------------------------------------------------------ - static llvm::StringRef - DecodeUUIDBytesFromString(llvm::StringRef str, ValueType &uuid_bytes, - uint32_t &bytes_decoded, - uint32_t num_uuid_bytes = 16); + static UUID DecodeUUIDBytesFromString(llvm::StringRef str); + + friend bool operator==(const UUID &lhs, const UUID &rhs) { + return lhs.m_uuid == rhs.m_uuid; + } + + friend bool operator!=(const UUID &lhs, const UUID &rhs) { + return lhs.m_uuid != rhs.m_uuid; + } + + friend bool operator<(const UUID &lhs, const UUID &rhs) { + return lhs.m_uuid < rhs.m_uuid; + } + + friend bool operator<=(const UUID &lhs, const UUID &rhs) { + return lhs.m_uuid <= rhs.m_uuid; + } + + friend bool operator>(const UUID &lhs, const UUID &rhs) { + return lhs.m_uuid > rhs.m_uuid; + } + + friend bool operator>=(const UUID &lhs, const UUID &rhs) { + return lhs.m_uuid >= rhs.m_uuid; + } protected: //------------------------------------------------------------------ // Classes that inherit from UUID can see and modify these //------------------------------------------------------------------ - uint32_t m_num_uuid_bytes; // Should be 16 or 20 - ValueType m_uuid; + std::vector m_uuid; }; -bool operator==(const UUID &lhs, const UUID &rhs); -bool operator!=(const UUID &lhs, const UUID &rhs); -bool operator<(const UUID &lhs, const UUID &rhs); -bool operator<=(const UUID &lhs, const UUID &rhs); -bool operator>(const UUID &lhs, const UUID &rhs); -bool operator>=(const UUID &lhs, const UUID &rhs); - } // namespace lldb_private #endif // LLDB_UTILITY_UUID_H Index: source/API/SBModuleSpec.cpp =================================================================== --- source/API/SBModuleSpec.cpp +++ source/API/SBModuleSpec.cpp @@ -90,7 +90,8 @@ } bool SBModuleSpec::SetUUIDBytes(const uint8_t *uuid, size_t uuid_len) { - return m_opaque_ap->GetUUID().SetBytes(uuid, uuid_len); + m_opaque_ap->GetUUID().SetBytes(uuid, uuid_len); + return true; } bool SBModuleSpec::GetDescription(lldb::SBStream &description) { Index: source/Interpreter/OptionValueUUID.cpp =================================================================== --- source/Interpreter/OptionValueUUID.cpp +++ source/Interpreter/OptionValueUUID.cpp @@ -43,7 +43,7 @@ case eVarSetOperationReplace: case eVarSetOperationAssign: { - if (m_uuid.SetFromCString(value.str().c_str()) == 0) + if (!m_uuid.SetFromCString(value.str().c_str())) error.SetErrorStringWithFormat("invalid uuid string value '%s'", value.str().c_str()); else { @@ -78,20 +78,18 @@ if (target) { const size_t num_modules = target->GetImages().GetSize(); if (num_modules > 0) { - UUID::ValueType uuid_bytes; - uint32_t num_bytes_decoded = 0; - UUID::DecodeUUIDBytesFromString(s, uuid_bytes, num_bytes_decoded); + UUID uuid = UUID::DecodeUUIDBytesFromString(s); for (size_t i = 0; i < num_modules; ++i) { ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i)); if (module_sp) { const UUID &module_uuid = module_sp->GetUUID(); if (module_uuid.IsValid()) { bool add_uuid = false; - if (num_bytes_decoded == 0) + if (!uuid.IsValid()) add_uuid = true; else - add_uuid = ::memcmp(module_uuid.GetBytes(), uuid_bytes, - num_bytes_decoded) == 0; + add_uuid = ::memcmp(module_uuid.GetBytes(), uuid.GetBytes(), + uuid.GetByteSize()) == 0; if (add_uuid) { std::string uuid_str; uuid_str = module_uuid.GetAsString(); Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp =================================================================== --- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -2094,7 +2094,7 @@ } Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); if (log && dsc_uuid.IsValid()) { - log->Printf("Shared cache %s has UUID %s", dyld_shared_cache.GetPath().c_str(), + log->Printf("Shared cache %s has UUID %s", dyld_shared_cache.GetPath().c_str(), dsc_uuid.GetAsString().c_str()); } return dsc_uuid; @@ -5012,9 +5012,9 @@ if (path[0] == '@') { if (strncmp(path, "@rpath", strlen("@rpath")) == 0) rpath_relative_paths.push_back(path + strlen("@rpath")); - else if (strncmp(path, "@executable_path", + else if (strncmp(path, "@executable_path", strlen("@executable_path")) == 0) - at_exec_relative_paths.push_back(path + at_exec_relative_paths.push_back(path + strlen("@executable_path")); } else { FileSpec file_spec(path, resolve_path); @@ -5033,7 +5033,7 @@ FileSpec this_file_spec(m_file); this_file_spec.ResolvePath(); - + if (!rpath_paths.empty()) { // Fixup all LC_RPATH values to be absolute paths std::string loader_path("@loader_path"); @@ -5070,7 +5070,7 @@ if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) { FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent(); for (const auto &at_exec_relative_path : at_exec_relative_paths) { - FileSpec file_spec = + FileSpec file_spec = exec_dir.CopyByAppendingPathComponent(at_exec_relative_path); if (file_spec.Exists() && files.AppendIfUnique(file_spec)) count++; @@ -5338,7 +5338,7 @@ break; if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) { char *buf = (char *) malloc (ident_command.cmdsize); - if (buf != nullptr + if (buf != nullptr && m_data.CopyData (offset, ident_command.cmdsize, buf) == ident_command.cmdsize) { buf[ident_command.cmdsize - 1] = '\0'; result = buf; @@ -5394,9 +5394,9 @@ if (m_data.GetU32 (&offset, &type, 1) && m_data.GetU64 (&offset, &address, 1) - && m_data.CopyData (offset, sizeof (uuid_t), raw_uuid) != 0 - && uuid.SetBytes (raw_uuid, sizeof (uuid_t))) + && m_data.CopyData (offset, sizeof (uuid_t), raw_uuid) != 0) { + uuid.SetBytes (raw_uuid, sizeof (uuid_t)); return true; } } Index: source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp =================================================================== --- source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp @@ -205,7 +205,7 @@ : std::chrono::microseconds(timeout_usec), status, &error); - LLDB_LOGV(log, + LLDB_LOGV(log, "Read (buffer, sizeof(buffer), timeout_usec = 0x{0:x}, " "status = {1}, error = {2}) => bytes_read = {4}", timeout_usec, @@ -456,7 +456,7 @@ if (uuid_str.size() < 32) return uuid; - if (uuid.SetFromCString(uuid_str.c_str()) == 0) { + if (!uuid.SetFromCString(uuid_str.c_str())) { UUID invalid_uuid; return invalid_uuid; } @@ -820,11 +820,11 @@ const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (error = 0x%8.8x:\n", error); if (count > 0) - DumpDataExtractor(packet, + DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatBytesWithASCII, // Format to use - 1, // Size of each item + 1, // Size of each item // in bytes count, // Number of items 16, // Number per line @@ -838,16 +838,16 @@ const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (error = 0x%8.8x regs:\n", error); if (count > 0) - DumpDataExtractor(packet, + DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use - m_addr_byte_size, // Size of each item + m_addr_byte_size, // Size of each item // in bytes count / m_addr_byte_size, // Number of items 16 / m_addr_byte_size, // Number per line - LLDB_INVALID_ADDRESS, - // Don't + LLDB_INVALID_ADDRESS, + // Don't // show addresses before // each line 0, 0); // No bitfields @@ -873,14 +873,14 @@ const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (error = 0x%8.8x io:\n", error); if (count > 0) - DumpDataExtractor(packet, + DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use 1, // Size of each item in bytes count, // Number of items 16, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses + LLDB_INVALID_ADDRESS, // Don't show addresses // before each line 0, 0); // No bitfields } break; @@ -888,15 +888,15 @@ const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (count = %u, bytes = \n", count); if (count > 0) - DumpDataExtractor(packet, + DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use - 1, // Size of each item in + 1, // Size of each item in // bytes count, // Number of items 16, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses + LLDB_INVALID_ADDRESS, // Don't show addresses // before each line 0, 0); // No bitfields @@ -996,12 +996,12 @@ const uint32_t nbytes = packet.GetByteSize() - offset; s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor); if (nbytes > 0) - DumpDataExtractor(packet, + DumpDataExtractor(packet, &s, // Stream to dump to - offset, // Offset within + offset, // Offset within // "packet" eFormatHex, // Format to use - m_addr_byte_size, // Size of each item in + m_addr_byte_size, // Size of each item in // bytes nbytes / m_addr_byte_size, // Number of items 16 / m_addr_byte_size, // Number per line @@ -1102,15 +1102,15 @@ s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, address, nbytes); if (nbytes > 0) - DumpDataExtractor(packet, + DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use - 1, // Size of each item in + 1, // Size of each item in // bytes nbytes, // Number of items 16, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses + LLDB_INVALID_ADDRESS, // Don't show addresses // before each line 0, 0); // No bitfields } break; @@ -1130,15 +1130,15 @@ s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, address, nbytes); if (nbytes > 0) - DumpDataExtractor(packet, + DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use - 1, // Size of each item in + 1, // Size of each item in // bytes nbytes, // Number of items 16, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses + LLDB_INVALID_ADDRESS, // Don't show addresses // before each line 0, 0); // No bitfields } break; @@ -1147,7 +1147,7 @@ const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (count = %u, bytes = \n", count); if (count > 0) - DumpDataExtractor(packet, + DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use @@ -1172,12 +1172,12 @@ &s, // Stream to dump to 0, // Offset into "packet" eFormatBytes, // Dump as hex bytes - 1, // Size of each item is 1 for + 1, // Size of each item is 1 for // single bytes packet.GetByteSize(), // Number of bytes UINT32_MAX, // Num bytes per line LLDB_INVALID_ADDRESS, // Base address - 0, 0); // Bitfield info set to not do + 0, 0); // Bitfield info set to not do // anything bitfield related } } Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -3577,8 +3577,7 @@ if (!dict->GetValueForKeyAsString("uuid", string)) return llvm::None; - if (result.GetUUID().SetFromStringRef(string, string.size() / 2) != - string.size()) + if (!result.GetUUID().SetFromStringRef(string, string.size() / 2)) return llvm::None; if (!dict->GetValueForKeyAsInteger("file_offset", integer)) Index: source/Utility/UUID.cpp =================================================================== --- source/Utility/UUID.cpp +++ source/Utility/UUID.cpp @@ -12,131 +12,87 @@ // Other libraries and framework includes // Project includes #include "lldb/Utility/Stream.h" +#include "lldb/Utility/LLDBAssert.h" #include "llvm/ADT/StringRef.h" // C Includes #include #include #include +#include +#include +#include namespace lldb_private { -UUID::UUID() { Clear(); } - -UUID::UUID(const UUID &rhs) { - SetBytes(rhs.m_uuid, rhs.m_num_uuid_bytes); -} - UUID::UUID(const void *uuid_bytes, uint32_t num_uuid_bytes) { SetBytes(uuid_bytes, num_uuid_bytes); } -const UUID &UUID::operator=(const UUID &rhs) { - if (this != &rhs) { - m_num_uuid_bytes = rhs.m_num_uuid_bytes; - ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid)); - } - return *this; -} - -UUID::~UUID() {} - -void UUID::Clear() { - m_num_uuid_bytes = 16; - ::memset(m_uuid, 0, sizeof(m_uuid)); +const uint8_t *UUID::GetBytes() const { + return m_uuid.empty() ? nullptr : m_uuid.data(); } -const void *UUID::GetBytes() const { return m_uuid; } - std::string UUID::GetAsString(const char *separator) const { - std::string result; - char buf[256]; - if (!separator) - separator = "-"; - const uint8_t *u = (const uint8_t *)GetBytes(); - if (sizeof(buf) > - (size_t)snprintf(buf, sizeof(buf), "%2.2X%2.2X%2.2X%2.2X%s%2.2X%2.2X%s%2." - "2X%2.2X%s%2.2X%2.2X%s%2.2X%2.2X%2.2X%" - "2.2X%2.2X%2.2X", - u[0], u[1], u[2], u[3], separator, u[4], u[5], separator, - u[6], u[7], separator, u[8], u[9], separator, u[10], - u[11], u[12], u[13], u[14], u[15])) { - result.append(buf); - if (m_num_uuid_bytes == 20) { - if (sizeof(buf) > (size_t)snprintf(buf, sizeof(buf), - "%s%2.2X%2.2X%2.2X%2.2X", separator, - u[16], u[17], u[18], u[19])) - result.append(buf); + lldbassert(IsValid()); + + // The initial fixed position separators: + // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + constexpr int kFixedSeparators = 5; + constexpr std::array separators_list = + { 4, 6, 8, 10, 16 }; + + int next_separator = 0; + int byte_index = 0; + + std::stringstream ss; + ss << std::hex << std::setfill('0') << std::uppercase; + for (unsigned int byte : m_uuid) { + // Do we need to insert a separator? + if ((next_separator >= kFixedSeparators && (byte_index % 4) == 0) || + (byte_index == separators_list[next_separator])) { + ss << separator; + ++next_separator; } + // Output one byte value + ss << std::setw(2) << byte; + ++byte_index; } - return result; + return ss.str(); } void UUID::Dump(Stream *s) const { s->PutCString(GetAsString().c_str()); } -bool UUID::SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes) { - if (uuid_bytes) { - switch (num_uuid_bytes) { - case 20: - m_num_uuid_bytes = 20; - break; - case 16: - m_num_uuid_bytes = 16; - m_uuid[16] = m_uuid[17] = m_uuid[18] = m_uuid[19] = 0; - break; - default: - // Unsupported UUID byte size - m_num_uuid_bytes = 0; - break; - } - - if (m_num_uuid_bytes > 0) { - ::memcpy(m_uuid, uuid_bytes, m_num_uuid_bytes); - return true; - } - } - ::memset(m_uuid, 0, sizeof(m_uuid)); - return false; +void UUID::SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes) { + lldbassert(num_uuid_bytes > 0); + m_uuid.resize(num_uuid_bytes); + ::memcpy(m_uuid.data(), uuid_bytes, num_uuid_bytes); } -size_t UUID::GetByteSize() const { return m_num_uuid_bytes; } - bool UUID::IsValid() const { - return m_uuid[0] || m_uuid[1] || m_uuid[2] || m_uuid[3] || m_uuid[4] || - m_uuid[5] || m_uuid[6] || m_uuid[7] || m_uuid[8] || m_uuid[9] || - m_uuid[10] || m_uuid[11] || m_uuid[12] || m_uuid[13] || m_uuid[14] || - m_uuid[15] || m_uuid[16] || m_uuid[17] || m_uuid[18] || m_uuid[19]; + return !m_uuid.empty(); } -static inline int xdigit_to_int(char ch) { +static int xdigit_to_int(char ch) { ch = tolower(ch); if (ch >= 'a' && ch <= 'f') return 10 + ch - 'a'; return ch - '0'; } -llvm::StringRef UUID::DecodeUUIDBytesFromString(llvm::StringRef p, - ValueType &uuid_bytes, - uint32_t &bytes_decoded, - uint32_t num_uuid_bytes) { - ::memset(uuid_bytes, 0, sizeof(uuid_bytes)); - size_t uuid_byte_idx = 0; +UUID UUID::DecodeUUIDBytesFromString(llvm::StringRef p) { + UUID result; while (!p.empty()) { if (isxdigit(p[0]) && isxdigit(p[1])) { int hi_nibble = xdigit_to_int(p[0]); int lo_nibble = xdigit_to_int(p[1]); // Translate the two hex nibble characters into a byte - uuid_bytes[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble; - + result.m_uuid.push_back((hi_nibble << 4) + lo_nibble); // Skip both hex digits p = p.drop_front(2); - - // Increment the byte that we are decoding within the UUID value and - // break out if we are done - if (++uuid_byte_idx == num_uuid_bytes) - break; + } else if (p.front() == '-') { } else if (p.front() == '-') { // Skip dashes p = p.drop_front(); @@ -145,71 +101,24 @@ break; } } - - // Clear trailing bytes to 0. - for (uint32_t i = uuid_byte_idx; i < sizeof(ValueType); i++) - uuid_bytes[i] = 0; - bytes_decoded = uuid_byte_idx; - return p; + return result; } -size_t UUID::SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes) { +bool UUID::SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes) { llvm::StringRef p = str; // Skip leading whitespace characters p = p.ltrim(); - uint32_t bytes_decoded = 0; - llvm::StringRef rest = - UUID::DecodeUUIDBytesFromString(p, m_uuid, bytes_decoded, num_uuid_bytes); - - // If we successfully decoded a UUID, return the amount of characters that - // were consumed - if (bytes_decoded == num_uuid_bytes) { - m_num_uuid_bytes = num_uuid_bytes; - return str.size() - rest.size(); - } - - // Else return zero to indicate we were not able to parse a UUID value - return 0; + *this = DecodeUUIDBytesFromString(p); + return GetByteSize() == num_uuid_bytes; } -size_t UUID::SetFromCString(const char *cstr, uint32_t num_uuid_bytes) { - if (cstr == NULL) - return 0; +bool UUID::SetFromCString(const char *cstr, uint32_t num_uuid_bytes) { + if (cstr == nullptr) + return false; return SetFromStringRef(cstr, num_uuid_bytes); } -} - -bool lldb_private::operator==(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return ::memcmp(lhs.GetBytes(), rhs.GetBytes(), - sizeof(lldb_private::UUID::ValueType)) == 0; -} -bool lldb_private::operator!=(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return !(lhs == rhs); -} - -bool lldb_private::operator<(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return ::memcmp(lhs.GetBytes(), rhs.GetBytes(), - sizeof(lldb_private::UUID::ValueType)) < 0; -} - -bool lldb_private::operator<=(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return !(lhs > rhs); -} - -bool lldb_private::operator>(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return rhs < lhs; -} - -bool lldb_private::operator>=(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return !(lhs < rhs); -} +} // namespace lldb_private Index: unittests/Utility/CMakeLists.txt =================================================================== --- unittests/Utility/CMakeLists.txt +++ unittests/Utility/CMakeLists.txt @@ -15,6 +15,7 @@ TimeoutTest.cpp TimerTest.cpp UriParserTest.cpp + UuidTest.cpp VASprintfTest.cpp LINK_LIBS