diff --git a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp index 3aed3e34f214d29d91dd33e5fc35fcc028699510..accd42bf44e28a4489aac982454908076f203310 100644 --- a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp +++ b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp @@ -386,13 +386,15 @@ DumpCommandParameters::ParseOptionResult DumpCommandParameters::parseOption(Stri options->pop_front(); if (options->front().empty()) return Error; - dumpParameters.typeFormats = DumpParameters::decodeFormatArgument(options->front()); + dumpParameters.typeFormats = + DumpParameters::decodeFormatArgument(options->front(), true); break; - case 'I': // individual formats: 'hex'ed name = formatnumber,...' + case 'I': // individual formats: iname= formatnumber,...' if (options->size() < 2) return Error; options->pop_front(); - dumpParameters.individualFormats = DumpParameters::decodeFormatArgument(options->front()); + dumpParameters.individualFormats = + DumpParameters::decodeFormatArgument(options->front(), false); break; default: knownOption = false; diff --git a/src/libs/qtcreatorcdbext/stringutils.cpp b/src/libs/qtcreatorcdbext/stringutils.cpp index d4afe3e0525eb6945af52f7e10ccf443dc7bf813..9bfe0206525e248b6b682848e558d78704cfb6b7 100644 --- a/src/libs/qtcreatorcdbext/stringutils.cpp +++ b/src/libs/qtcreatorcdbext/stringutils.cpp @@ -35,6 +35,7 @@ #include <cctype> #include <iostream> #include <sstream> +#include <iomanip> static const char whiteSpace[] = " \t\r\n"; @@ -239,7 +240,7 @@ std::string stringFromHex(const char *p, const char *end) std::string rc; rc.reserve((end - p) / 2); - for ( ; p < end; p++) { + for ( ; p < end; ++p) { unsigned c = 16 * hexDigit(*p); c += hexDigit(*++p); rc.push_back(char(c)); @@ -247,9 +248,40 @@ std::string stringFromHex(const char *p, const char *end) return rc; } +// Helper for dumping memory +std::string dumpMemory(const unsigned char *p, size_t size, + bool wantQuotes) +{ + std::ostringstream str; + str << std::oct << std::setfill('0'); + if (wantQuotes) + str << '"'; + const unsigned char *end = p + size; + for ( ; p < end; ++p) { + const unsigned char u = *p; + switch (u) { + case '\t': + str << "\\t"; + case '\r': + str << "\\r"; + case '\n': + str << "\\n"; + default: + if (u >= 32 && u < 128) { + str << (char(u)); + } else { + str << '\\' << std::setw(3) << unsigned(u); + } + } + } + if (wantQuotes) + str << '"'; + return str.str(); +} + void decodeHex(const char *p, const char *end, unsigned char *target) { - for ( ; p < end; p++) { + for ( ; p < end; ++p) { unsigned c = 16 * hexDigit(*p); c += hexDigit(*++p); *target++ = c; @@ -263,7 +295,7 @@ std::wstring dataToHexW(const unsigned char *p, const unsigned char *end) std::wstring rc; rc.reserve(2 * (end - p)); - for ( ; p < end ; p++) { + for ( ; p < end ; ++p) { const unsigned c = *p; rc.push_back(toHexDigit(c / 16)); rc.push_back(toHexDigit(c &0xF)); @@ -279,7 +311,7 @@ std::wstring dataToReadableHexW(const unsigned char *begin, const unsigned char std::wstring rc; rc.reserve(5 * (end - begin)); - for (const unsigned char *p = begin; p < end ; p++) { + for (const unsigned char *p = begin; p < end ; ++p) { rc.append(p == begin ? L"0x" : L" 0x"); const unsigned c = *p; rc.push_back(toHexDigit(c / 16)); diff --git a/src/libs/qtcreatorcdbext/stringutils.h b/src/libs/qtcreatorcdbext/stringutils.h index f79ab951337d4091e678f65205ee79d708d18cc6..abbd0098fb69dba4473860a767ab70023c0ad04b 100644 --- a/src/libs/qtcreatorcdbext/stringutils.h +++ b/src/libs/qtcreatorcdbext/stringutils.h @@ -182,6 +182,9 @@ std::wstring stringToWString(const std::string &w); std::wstring quotedWStringFromCharData(const unsigned char *data, size_t size); std::wstring quotedWStringFromWCharData(const unsigned char *data, size_t size); +// Helper for dumping memory +std::string dumpMemory(const unsigned char *data, size_t size, bool wantQuotes = true); + // String from hex "414A" -> "AJ". std::string stringFromHex(const char *begin, const char *end); // Decode hex to a memory area. diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp index 92508b28d98ef21d5cc06d47a6c76c2259da1e0a..2f38c84943375ee523dc09d1b52ffb923aae2d15 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp @@ -294,7 +294,8 @@ DumpParameters::DumpParameters() : dumpFlags(0) // typeformats: decode hex-encoded name, value pairs: // '414A=2,...' -> map of "AB:2". -DumpParameters::FormatMap DumpParameters::decodeFormatArgument(const std::string &f) +DumpParameters::FormatMap DumpParameters::decodeFormatArgument(const std::string &f, + bool isHex) { FormatMap rc; const std::string::size_type size = f.size(); @@ -304,7 +305,9 @@ DumpParameters::FormatMap DumpParameters::decodeFormatArgument(const std::string const std::string::size_type equalsPos = f.find('=', pos); if (equalsPos == std::string::npos) return rc; - const std::string name = stringFromHex(f.c_str() + pos, f.c_str() + equalsPos); + const std::string name = isHex ? + stringFromHex(f.c_str() + pos, f.c_str() + equalsPos) : + f.substr(pos, equalsPos - pos); // Search for number const std::string::size_type numberPos = equalsPos + 1; std::string::size_type nextPos = f.find(',', numberPos); @@ -383,6 +386,12 @@ DumpParameters::checkRecode(const std::string &type, enum ReformatType { ReformatNone, ReformatPointer, ReformatArray }; DumpParameterRecodeResult result; + if (SymbolGroupValue::verbose > 2) { + DebugPrint debugPrint; + debugPrint << '>' << __FUNCTION__ << ' ' << iname << '/' << iname; + if (dp) + debugPrint << " option format: " << dp->format(type, iname); + } // We basically handle char formats for 'char *', '0x834478 "hallo.."' // and 'wchar_t *', '0x834478 "hallo.."' // Determine address and length from the pointer value output, @@ -467,6 +476,11 @@ DumpParameters::checkRecode(const std::string &type, delete [] result.buffer; result = DumpParameterRecodeResult(); } + if (SymbolGroupValue::verbose > 2) + DebugPrint() + << '<' << __FUNCTION__ << ' ' << iname << " format=" + << result.recommendedFormat << " size=" + << result.size << " data=" << dumpMemory(result.buffer, result.size); return result; } diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.h b/src/libs/qtcreatorcdbext/symbolgroupnode.h index 1f99b0e48145b78ae5c2c16c821b85cd83d115b2..26185ba91e248da791147e3ed60bbfa7b0219629 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupnode.h +++ b/src/libs/qtcreatorcdbext/symbolgroupnode.h @@ -72,8 +72,7 @@ struct DumpParameters DumpParameters(); bool humanReadable() const { return dumpFlags & DumpHumanReadable; } // Helper to decode format option arguments. - static FormatMap decodeFormatArgument(const std::string &f); - + static FormatMap decodeFormatArgument(const std::string &f, bool isHex); static DumpParameterRecodeResult checkRecode(const std::string &type, const std::string &iname,