aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/debugger/watchutils.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <[email protected]>2009-09-18 16:55:17 +0200
committerFriedemann Kleint <[email protected]>2009-09-18 16:55:17 +0200
commit603630fad6201c931cd903fd638b07dafae9c24e (patch)
tree550ab65ef33ef562660c014276a701044ae661d0 /src/plugins/debugger/watchutils.cpp
parent5b182196f93195462f4c544b2c07363ada2a0426 (diff)
Debugger: Use Gdbmi parser in CDB for parsing of protocol 1
Change dumper protocol 1 output not to contain type names as hash keys (might contain blanks), use lists instead. Start fixing autotests for 4.6.
Diffstat (limited to 'src/plugins/debugger/watchutils.cpp')
-rw-r--r--src/plugins/debugger/watchutils.cpp229
1 files changed, 59 insertions, 170 deletions
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index 7b70b5845d3..27c3ef20746 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -29,6 +29,7 @@
#include "watchutils.h"
#include "watchhandler.h"
+#include "gdb/gdbmi.h"
#include <utils/qtcassert.h>
#include <texteditor/basetexteditor.h>
@@ -725,6 +726,10 @@ QString QtDumperHelper::toString(bool debug) const
for (SizeCache::const_iterator it = m_sizeCache.constBegin(); it != scend; ++it) {
str << ' ' << it.key() << '=' << it.value();
}
+ str << "\nExpression cache: (" << m_expressionCache.size() << ")\n";
+ const QMap<QString, QString>::const_iterator excend = m_expressionCache.constEnd();
+ for (QMap<QString, QString>::const_iterator it = m_expressionCache.constBegin(); it != excend; ++it)
+ str << " " << it.key() << ' ' << it.value() << '\n';
return rc;
}
const QString nameSpace = m_qtNamespace.isEmpty() ? QCoreApplication::translate("QtDumperHelper", "<none>") : m_qtNamespace;
@@ -749,11 +754,6 @@ QString QtDumperHelper::qtNamespace() const
return m_qtNamespace;
}
-void QtDumperHelper::setQtNamespace(const QString &qtNamespace)
-{
- m_qtNamespace = qtNamespace;
-}
-
int QtDumperHelper::typeCount() const
{
return m_nameTypeMap.size();
@@ -842,23 +842,6 @@ QString QtDumperHelper::qtVersionString() const
return rc;
}
-void QtDumperHelper::setQtVersion(int v)
-{
- m_qtVersion = v;
-}
-
-void QtDumperHelper::setQtVersion(const QString &v)
-{
- m_qtVersion = 0;
- const QStringList vl = v.split(QLatin1Char('.'));
- if (vl.size() == 3) {
- const int major = vl.at(0).toInt();
- const int minor = vl.at(1).toInt();
- const int patch = vl.at(2).toInt();
- m_qtVersion = (major << 16) | (minor << 8) | patch;
- }
-}
-
// Parse a list of types.
void QtDumperHelper::parseQueryTypes(const QStringList &l, Debugger debugger)
{
@@ -1049,134 +1032,6 @@ bool DumperParser::handleValue(const char *k, int size)
return true;
}
-/* Parse 'query' (1) protocol response of the custom dumpers:
- * "'dumpers=["QByteArray","QDateTime",..."std::basic_string",],
- * qtversion=["4","5","1"],namespace="""' */
-
-class QueryDumperParser : public DumperParser {
-public:
- typedef QPair<QString, int> SizeEntry;
- explicit QueryDumperParser(const char *s);
-
- struct Data {
- QString qtNameSpace;
- QString qtVersion;
- QString dumperVersion;
- QStringList types;
- QList<SizeEntry> sizes;
- QMap<QString, QString> expressionCache;
- };
-
- inline Data data() const { return m_data; }
-
-protected:
- virtual bool handleKeyword(const char *k, int size);
- virtual bool handleListStart();
- virtual bool handleListEnd();
- virtual bool handleHashEnd();
- virtual bool handleValue(const char *k, int size);
-
-private:
- enum Mode { None, ExpectingDumpers, ExpectingQtVersion, ExpectingDumperVersion,
- ExpectingNameSpace, ExpectingSizes, ExpectingExpressionCache };
- Mode m_mode;
- Data m_data;
- QString m_lastSizeType;
- QString m_lastExpression;
-};
-
-QueryDumperParser::QueryDumperParser(const char *s) :
- DumperParser(s),
- m_mode(None)
-{
-}
-
-bool QueryDumperParser::handleKeyword(const char *k, int size)
-{
- switch (m_mode) {
- case ExpectingSizes:
- m_lastSizeType = QString::fromLatin1(k, size);
- return true;
- case ExpectingExpressionCache:
- m_lastExpression = QString::fromLatin1(k, size);
- return true;
- default:
- break;
- }
- if (!qstrncmp(k, "dumpers", size)) {
- m_mode = ExpectingDumpers;
- return true;
- }
- if (!qstrncmp(k, "qtversion", size)) {
- m_mode = ExpectingQtVersion;
- return true;
- }
- if (!qstrncmp(k, "dumperversion", size)) {
- m_mode = ExpectingDumperVersion;
- return true;
- }
- if (!qstrncmp(k, "namespace", size)) {
- m_mode = ExpectingNameSpace;
- return true;
- }
- if (!qstrncmp(k, "sizes", size)) {
- m_mode = ExpectingSizes;
- return true;
- }
- if (!qstrncmp(k, "expressions", size)) {
- m_mode = ExpectingExpressionCache;
- return true;
- }
- qWarning("%s Unexpected keyword %s.\n", Q_FUNC_INFO, QByteArray(k, size).constData());
- return false;
-}
-
-bool QueryDumperParser::handleListStart()
-{
- return m_mode == ExpectingDumpers || m_mode == ExpectingQtVersion;
-}
-
-bool QueryDumperParser::handleListEnd()
-{
- m_mode = None;
- return true;
-}
-
-bool QueryDumperParser::handleHashEnd()
-{
- m_mode = None; // Size hash
- return true;
-}
-
-bool QueryDumperParser::handleValue(const char *k, int size)
-{
- switch (m_mode) {
- case None:
- return false;
- case ExpectingDumpers:
- m_data.types.push_back(QString::fromLatin1(k, size));
- break;
- case ExpectingNameSpace:
- m_data.qtNameSpace = QString::fromLatin1(k, size);
- break;
- case ExpectingDumperVersion:
- m_data.dumperVersion = QString::fromLatin1(k, size);
- break;
- case ExpectingQtVersion: // ["4","1","5"]
- if (!m_data.qtVersion.isEmpty())
- m_data.qtVersion += QLatin1Char('.');
- m_data.qtVersion += QString::fromLatin1(k, size);
- break;
- case ExpectingSizes:
- m_data.sizes.push_back(SizeEntry(m_lastSizeType, QString::fromLatin1(k, size).toInt()));
- break;
- case ExpectingExpressionCache:
- m_data.expressionCache.insert(m_lastExpression, QString::fromLatin1(k, size));
- break;
- }
- return true;
-}
-
static inline QString qClassName(const QString &qtNamespace, const char *className)
{
if (qtNamespace.isEmpty())
@@ -1196,34 +1051,68 @@ void QtDumperHelper::setQClassPrefixes(const QString &qNamespace)
m_qWeakPointerPrefix = qClassName(qNamespace, "QWeakPointer");
}
-// parse a query
-bool QtDumperHelper::parseQuery(const char *data, Debugger debugger)
+static inline double getDumperVersion(const GdbMi &contents)
{
- QueryDumperParser parser(data);
- if (!parser.run())
- return false;
- clear();
- m_qtNamespace = parser.data().qtNameSpace;
- setQtVersion(parser.data().qtVersion);
- setQClassPrefixes(m_qtNamespace);
- parseQueryTypes(parser.data().types, debugger);
- foreach (const QueryDumperParser::SizeEntry &se, parser.data().sizes)
- addSize(se.first, se.second);
- m_expressionCache = parser.data().expressionCache;
- // Version
- if (!parser.data().dumperVersion.isEmpty()) {
- double dumperVersion;
+ const GdbMi dumperVersionG = contents.findChild("dumperversion");
+ if (dumperVersionG.type() != GdbMi::Invalid) {
bool ok;
- dumperVersion = parser.data().dumperVersion.toDouble(&ok);
+ const double v = QString::fromAscii(dumperVersionG.data()).toDouble(&ok);
if (ok)
- m_dumperVersion = dumperVersion;
+ return v;
}
+ return 1.0;
+}
+
+bool QtDumperHelper::parseQuery(const GdbMi &contents, Debugger debugger)
+{
+ clear();
+ if (debug > 1)
+ qDebug() << "parseQuery" << contents.toString(true, 2);
+
+ // Common info, dumper version, etc
+ m_qtNamespace = QLatin1String(contents.findChild("namespace").data());
+ int qtv = 0;
+ const GdbMi qtversion = contents.findChild("qtversion");
+ if (qtversion.children().size() == 3) {
+ qtv = (qtversion.childAt(0).data().toInt() << 16)
+ + (qtversion.childAt(1).data().toInt() << 8)
+ + qtversion.childAt(2).data().toInt();
+ }
+ m_qtVersion = qtv;
+ // Get list of helpers
+ QStringList availableSimpleDebuggingHelpers;
+ foreach (const GdbMi &item, contents.findChild("dumpers").children())
+ availableSimpleDebuggingHelpers.append(QLatin1String(item.data()));
+ parseQueryTypes(availableSimpleDebuggingHelpers, debugger);
+ m_dumperVersion = getDumperVersion(contents);
+ // Parse sizes
+ foreach (const GdbMi &sizesList, contents.findChild("sizes").children()) {
+ const int childCount = sizesList.childCount();
+ if (childCount > 1) {
+ const int size = sizesList.childAt(0).data().toInt();
+ for (int c = 1; c < childCount; c++)
+ addSize(QLatin1String(sizesList.childAt(c).data()), size);
+ }
+ }
+ // Parse expressions
+ foreach (const GdbMi &exprList, contents.findChild("expressions").children())
+ if (exprList.childCount() == 2)
+ m_expressionCache.insert(QLatin1String(exprList.childAt(0).data()),
+ QLatin1String(exprList.childAt(1).data()));
return true;
}
-void QtDumperHelper::addExpression(const QString &expression, const QString &value)
+// parse a query
+bool QtDumperHelper::parseQuery(const char *data, Debugger debugger)
{
- m_expressionCache.insert(expression, value);
+ QByteArray fullData = data;
+ fullData.insert(0, '{');
+ fullData.append(data);
+ fullData.append('}');
+ GdbMi root(fullData);
+ if (!root.isValid())
+ return false;
+ return parseQuery(root, debugger);
}
void QtDumperHelper::addSize(const QString &name, int size)