diff --git a/src/plugins/debugger/gdbmi.cpp b/src/plugins/debugger/gdbmi.cpp index e2fd7e7a25a67ec2e7ca9a0873daff134bd7363b..986031765ea870af7af27fbcf7ff11eafd8b2754 100644 --- a/src/plugins/debugger/gdbmi.cpp +++ b/src/plugins/debugger/gdbmi.cpp @@ -52,7 +52,7 @@ void GdbMi::parseResultOrValue(const char *&from, const char *to) //qDebug() << "parseResultOrValue: " << QByteArray(from, to - from); parseValue(from, to); if (isValid()) { - //qDebug() << "no valid result in " << QByteArray::fromLatin1(from, to - from); + //qDebug() << "no valid result in " << QByteArray(from, to - from); return; } if (from == to || *from == '(') @@ -73,7 +73,7 @@ void GdbMi::parseResultOrValue(const char *&from, const char *to) QByteArray GdbMi::parseCString(const char *&from, const char *to) { QByteArray result; - //qDebug() << "parseCString: " << QByteArray::fromUtf16(from, to - from); + //qDebug() << "parseCString: " << QByteArray(from, to - from); if (*from != '"') { qDebug() << "MI Parse Error, double quote expected"; ++from; // So we don't hang @@ -152,7 +152,7 @@ QByteArray GdbMi::parseCString(const char *&from, const char *to) void GdbMi::parseValue(const char *&from, const char *to) { - //qDebug() << "parseValue: " << QByteArray::fromUtf16(from, to - from); + //qDebug() << "parseValue: " << QByteArray(from, to - from); switch (*from) { case '{': parseTuple(from, to); @@ -172,7 +172,7 @@ void GdbMi::parseValue(const char *&from, const char *to) void GdbMi::parseTuple(const char *&from, const char *to) { - //qDebug() << "parseTuple: " << QByteArray::fromUtf16(from, to - from); + //qDebug() << "parseTuple: " << QByteArray(from, to - from); QTC_ASSERT(*from == '{', /**/); ++from; parseTuple_helper(from, to); @@ -180,7 +180,7 @@ void GdbMi::parseTuple(const char *&from, const char *to) void GdbMi::parseTuple_helper(const char *&from, const char *to) { - //qDebug() << "parseTuple_helper: " << QByteArray::fromUtf16(from, to - from); + //qDebug() << "parseTuple_helper: " << QByteArray(from, to - from); m_type = Tuple; while (from < to) { if (*from == '}') { @@ -200,7 +200,7 @@ void GdbMi::parseTuple_helper(const char *&from, const char *to) void GdbMi::parseList(const char *&from, const char *to) { - //qDebug() << "parseList: " << QByteArray::fromUtf16(from, to - from); + //qDebug() << "parseList: " << QByteArray(from, to - from); QTC_ASSERT(*from == '[', /**/); ++from; m_type = List; diff --git a/src/plugins/debugger/json.cpp b/src/plugins/debugger/json.cpp new file mode 100644 index 0000000000000000000000000000000000000000..374c8a25030b57cb3388b59166a216f127f6d0d1 --- /dev/null +++ b/src/plugins/debugger/json.cpp @@ -0,0 +1,372 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "json.h" + +#include <utils/qtcassert.h> + +#include <QtCore/QByteArray> +#include <QtCore/QTextStream> + +#include <ctype.h> + +//#define DEBUG_JASON +#ifdef DEBUG_JASON +#define JDEBUG(s) qDebug() << s +#else +#define JDEBUG(s) +#endif + +namespace Debugger { +namespace Internal { + +static void skipSpaces(const char *&from, const char *to) +{ + while (from != to && isspace(*from)) + ++from; +} + +QTextStream &operator<<(QTextStream &os, const JsonValue &mi) +{ + return os << mi.toString(); +} + +void JsonValue::parsePair(const char *&from, const char *to) +{ + skipSpaces(from, to); + JDEBUG("parsePair: " << QByteArray(from, to - from)); + m_name = parseCString(from, to); + skipSpaces(from, to); + while (from < to && *from != ':') { + JDEBUG("not a colon" << *from); + ++from; + } + ++from; + parseValue(from, to); + skipSpaces(from, to); +} + +QByteArray JsonValue::parseNumber(const char *&from, const char *to) +{ + QByteArray result; + while (from < to && *from >= '0' && *from <= '9') + result.append(*from++); + return result; +} + +QByteArray JsonValue::parseCString(const char *&from, const char *to) +{ + QByteArray result; + JDEBUG("parseCString: " << QByteArray(from, to - from)); + if (*from != '"') { + qDebug() << "JSON Parse Error, double quote expected"; + ++from; // So we don't hang + return QByteArray(); + } + const char *ptr = from; + ++ptr; + while (ptr < to) { + if (*ptr == '"') { + ++ptr; + result = QByteArray(from + 1, ptr - from - 2); + break; + } + if (*ptr == '\\') { + ++ptr; + if (ptr == to) { + qDebug() << "JSON Parse Error, unterminated backslash escape"; + from = ptr; // So we don't hang + return QByteArray(); + } + } + ++ptr; + } + from = ptr; + + int idx = result.indexOf('\\'); + if (idx >= 0) { + char *dst = result.data() + idx; + const char *src = dst + 1, *end = result.data() + result.length(); + do { + char c = *src++; + switch (c) { + case 'a': *dst++ = '\a'; break; + case 'b': *dst++ = '\b'; break; + case 'f': *dst++ = '\f'; break; + case 'n': *dst++ = '\n'; break; + case 'r': *dst++ = '\r'; break; + case 't': *dst++ = '\t'; break; + case 'v': *dst++ = '\v'; break; + case '"': *dst++ = '"'; break; + case '\\': *dst++ = '\\'; break; + default: + { + int chars = 0; + uchar prod = 0; + forever { + if (c < '0' || c > '7') { + --src; + break; + } + prod = prod * 8 + c - '0'; + if (++chars == 3 || src == end) + break; + c = *src++; + } + if (!chars) { + qDebug() << "JSON Parse Error, unrecognized backslash escape"; + return QByteArray(); + } + *dst++ = prod; + } + } + while (src != end) { + char c = *src++; + if (c == '\\') + break; + *dst++ = c; + } + } while (src != end); + *dst = 0; + result.truncate(dst - result.data()); + } + + JDEBUG("parseCString, got " << result); + return result; +} + +void JsonValue::parseValue(const char *&from, const char *to) +{ + JDEBUG("parseValue: " << QByteArray(from, to - from)); + switch (*from) { + case '{': + parseObject(from, to); + break; + case '[': + parseArray(from, to); + break; + case '"': + m_type = String; + m_data = parseCString(from, to); + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + m_type = Number; + m_data = parseNumber(from, to); + default: + break; + } +} + +void JsonValue::parseObject(const char *&from, const char *to) +{ + JDEBUG("parseObject: " << QByteArray(from, to - from)); + QTC_ASSERT(*from == '{', /**/); + ++from; + m_type = Object; + while (from < to) { + if (*from == '}') { + ++from; + break; + } + JsonValue child; + child.parsePair(from, to); + if (!child.isValid()) + return; + m_children += child; + if (*from == ',') + ++from; + } +} + +void JsonValue::parseArray(const char *&from, const char *to) +{ + JDEBUG("parseArray: " << QByteArray(from, to - from)); + QTC_ASSERT(*from == '[', /**/); + ++from; + m_type = Array; + while (from < to) { + if (*from == ']') { + ++from; + break; + } + JsonValue child; + child.parseValue(from, to); + if (child.isValid()) + m_children += child; + if (*from == ',') + ++from; + } +} + +void JsonValue::setStreamOutput(const QByteArray &name, const QByteArray &content) +{ + if (content.isEmpty()) + return; + JsonValue child; + child.m_type = String; + child.m_name = name; + child.m_data = content; + m_children += child; + if (m_type == Invalid) + m_type = Object; +} + +static QByteArray ind(int indent) +{ + return QByteArray(2 * indent, ' '); +} + +void JsonValue::dumpChildren(QByteArray * str, bool multiline, int indent) const +{ + for (int i = 0; i < m_children.size(); ++i) { + if (i != 0) { + *str += ','; + if (multiline) + *str += '\n'; + } + if (multiline) + *str += ind(indent); + *str += m_children.at(i).toString(multiline, indent); + } +} + +class MyString : public QString { +public: + ushort at(int i) const { return constData()[i].unicode(); } +}; + +template<class ST, typename CT> +inline ST escapeCStringTpl(const ST &ba) +{ + ST ret; + ret.reserve(ba.length() * 2); + for (int i = 0; i < ba.length(); ++i) { + CT c = ba.at(i); + switch (c) { + case '\\': ret += "\\\\"; break; + case '\a': ret += "\\a"; break; + case '\b': ret += "\\b"; break; + case '\f': ret += "\\f"; break; + case '\n': ret += "\\n"; break; + case '\r': ret += "\\r"; break; + case '\t': ret += "\\t"; break; + case '\v': ret += "\\v"; break; + case '"': ret += "\\\""; break; + default: + if (c < 32 || c == 127) { + ret += '\\'; + ret += '0' + (c >> 6); + ret += '0' + ((c >> 3) & 7); + ret += '0' + (c & 7); + } else { + ret += c; + } + } + } + return ret; +} + +QString JsonValue::escapeCString(const QString &ba) +{ + return escapeCStringTpl<MyString, ushort>(static_cast<const MyString &>(ba)); +} + +QByteArray JsonValue::escapeCString(const QByteArray &ba) +{ + return escapeCStringTpl<QByteArray, uchar>(ba); +} + +QByteArray JsonValue::toString(bool multiline, int indent) const +{ + QByteArray result; + switch (m_type) { + case Invalid: + if (multiline) + result += ind(indent) + "Invalid\n"; + else + result += "Invalid"; + break; + case String: + if (!m_name.isEmpty()) + result += m_name + "="; + result += '"' + escapeCString(m_data) + '"'; + break; + case Number: + if (!m_name.isEmpty()) + result += '"' + m_name + "\":"; + result += m_data; + break; + case Object: + if (!m_name.isEmpty()) + result += m_name + '='; + if (multiline) { + result += "{\n"; + dumpChildren(&result, multiline, indent + 1); + result += '\n' + ind(indent) + "}"; + } else { + result += "{"; + dumpChildren(&result, multiline, indent + 1); + result += "}"; + } + break; + case Array: + if (!m_name.isEmpty()) + result += m_name + "="; + if (multiline) { + result += "[\n"; + dumpChildren(&result, multiline, indent + 1); + result += '\n' + ind(indent) + "]"; + } else { + result += "["; + dumpChildren(&result, multiline, indent + 1); + result += "]"; + } + break; + } + return result; +} + +void JsonValue::fromString(const QByteArray &ba) +{ + const char *from = ba.constBegin(); + const char *to = ba.constEnd(); + parseValue(from, to); +} + +JsonValue JsonValue::findChild(const char *name) const +{ + for (int i = 0; i < m_children.size(); ++i) + if (m_children.at(i).m_name == name) + return m_children.at(i); + return JsonValue(); +} + +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/json.h b/src/plugins/debugger/json.h new file mode 100644 index 0000000000000000000000000000000000000000..5c7fee039108ead1ed37c9fca2389d45f1f97ac0 --- /dev/null +++ b/src/plugins/debugger/json.h @@ -0,0 +1,100 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef DEBUGGER_JSON_H +#define DEBUGGER_JSON_H + +#include <QtCore/QByteArray> +#include <QtCore/QList> + +namespace Debugger { +namespace Internal { + +class JsonValue +{ +public: + JsonValue() : m_type(Invalid) {} + explicit JsonValue(const QByteArray &str) { fromString(str); } + + QByteArray m_name; + QByteArray m_data; + QList<JsonValue> m_children; + + enum Type { + Invalid, + String, + Number, + Object, + Array, + }; + + Type m_type; + + inline Type type() const { return m_type; } + inline QByteArray name() const { return m_name; } + inline bool hasName(const char *name) const { return m_name == name; } + + inline bool isValid() const { return m_type != Invalid; } + inline bool isNumber() const { return m_type == Number; } + inline bool isString() const { return m_type == String; } + inline bool isObject() const { return m_type == Object; } + inline bool isArray() const { return m_type == Array; } + + + inline QByteArray data() const { return m_data; } + inline const QList<JsonValue> &children() const { return m_children; } + inline int childCount() const { return m_children.size(); } + + const JsonValue &childAt(int index) const { return m_children[index]; } + JsonValue &childAt(int index) { return m_children[index]; } + JsonValue findChild(const char *name) const; + + QByteArray toString(bool multiline = false, int indent = 0) const; + void fromString(const QByteArray &str); + void setStreamOutput(const QByteArray &name, const QByteArray &content); + +private: + static QByteArray parseCString(const char *&from, const char *to); + static QByteArray parseNumber(const char *&from, const char *to); + static QByteArray escapeCString(const QByteArray &ba); + static QString escapeCString(const QString &ba); + void parsePair(const char *&from, const char *to); + void parseValue(const char *&from, const char *to); + void parseObject(const char *&from, const char *to); + void parseArray(const char *&from, const char *to); + + void dumpChildren(QByteArray *str, bool multiline, int indent) const; +}; + +} // namespace Internal +} // namespace Debugger + +//Q_DECLARE_METATYPE(GdbDebugger::Internal::JsonValue); + +#endif // DEBUGGER_JSON_H diff --git a/src/plugins/debugger/tcfengine.cpp b/src/plugins/debugger/tcfengine.cpp index 89b72cfd4fd7c6af73de76e94f690c84d1cdab47..6e7fac9f3799cada6ff8b5042c69c881a6a1f96d 100644 --- a/src/plugins/debugger/tcfengine.cpp +++ b/src/plugins/debugger/tcfengine.cpp @@ -40,7 +40,7 @@ #include "watchhandler.h" #include "watchutils.h" #include "moduleshandler.h" -#include "gdbmi.h" +#include "json.h" #include <utils/qtcassert.h> @@ -92,18 +92,6 @@ QByteArray C(const QByteArray &ba1, //#define USE_CONGESTION_CONTROL -/////////////////////////////////////////////////////////////////////// -// -// TcfData -// -/////////////////////////////////////////////////////////////////////// - - -TcfData::TcfData(const QByteArray &data) -{ - fromString(data); -} - /////////////////////////////////////////////////////////////////////// // @@ -369,11 +357,11 @@ void TcfEngine::handleResponse(const QByteArray &response) acknowledgeResult(); int token = parts.at(1).toInt(); QByteArray message = parts.at(2); - TcfData data(parts.at(3)); + JsonValue data(parts.at(3)); emit tcfOutputAvailable("", QString::number(token) + "^" + quoteUnprintableLatin1(response) + data.toString()); TcfCommand tcf = m_cookieForToken[token]; - TcfData result(data); + JsonValue result(data); SDEBUG("GOOD RESPONSE: " << quoteUnprintableLatin1(response)); if (tcf.callback) (this->*(tcf.callback))(result, tcf.cookie); @@ -384,13 +372,13 @@ void TcfEngine::handleResponse(const QByteArray &response) } else if (n == 4 && tag == "E") { // an event QByteArray service = parts.at(1); QByteArray eventName = parts.at(2); - TcfData data(parts.at(3)); + JsonValue data(parts.at(3)); if (eventName != "peerHeartBeat") SDEBUG(_("\nTCF EVENT:") << quoteUnprintableLatin1(response) << data.toString()); if (service == "Locator" && eventName == "Hello") { m_services.clear(); - foreach (const GdbMi &service, data.children()) + foreach (const JsonValue &service, data.children()) m_services.append(service.data()); QTimer::singleShot(0, this, SLOT(startDebugging())); } @@ -525,17 +513,17 @@ void TcfEngine::acknowledgeResult() #endif } -void TcfEngine::handleRunControlSuspend(const TcfData &data, const QVariant &) +void TcfEngine::handleRunControlSuspend(const JsonValue &data, const QVariant &) { SDEBUG("HANDLE RESULT" << data.toString()); } -void TcfEngine::handleRunControlGetChildren(const TcfData &data, const QVariant &) +void TcfEngine::handleRunControlGetChildren(const JsonValue &data, const QVariant &) { SDEBUG("HANDLE RUN CONTROL GET CHILDREN" << data.toString()); } -void TcfEngine::handleSysMonitorGetChildren(const TcfData &data, const QVariant &) +void TcfEngine::handleSysMonitorGetChildren(const JsonValue &data, const QVariant &) { SDEBUG("HANDLE RUN CONTROL GET CHILDREN" << data.toString()); } diff --git a/src/plugins/debugger/tcfengine.h b/src/plugins/debugger/tcfengine.h index 1eb29d7f92df4f4b6f17dc8c5f223569eb8b1c83..f9cfc00ec5b6524ea5b7b9d26ee08ba7a1afbf26 100644 --- a/src/plugins/debugger/tcfengine.h +++ b/src/plugins/debugger/tcfengine.h @@ -49,7 +49,7 @@ QT_END_NAMESPACE #include "idebuggerengine.h" #include "debuggermanager.h" -#include "gdbmi.h" +#include "json.h" namespace Debugger { namespace Internal { @@ -59,12 +59,6 @@ class IDebuggerManagerAccessForEngines; class ScriptAgent; class WatchData; -class TcfData : public GdbMi -{ -public: - TcfData(const QByteArray &data); -}; - class TcfEngine : public IDebuggerEngine { Q_OBJECT @@ -128,15 +122,15 @@ private: Q_SLOT void socketReadyRead(); void handleResponse(const QByteArray &ba); - void handleRunControlSuspend(const TcfData &response, const QVariant &); - void handleRunControlGetChildren(const TcfData &response, const QVariant &); - void handleSysMonitorGetChildren(const TcfData &response, const QVariant &); + void handleRunControlSuspend(const JsonValue &response, const QVariant &); + void handleRunControlGetChildren(const JsonValue &response, const QVariant &); + void handleSysMonitorGetChildren(const JsonValue &response, const QVariant &); private: Q_SLOT void startDebugging(); typedef void (TcfEngine::*TcfCommandCallback) - (const TcfData &record, const QVariant &cookie); + (const JsonValue &record, const QVariant &cookie); struct TcfCommand { diff --git a/tests/auto/debugger/debugger.pro b/tests/auto/debugger/debugger.pro index 6f6e9357741412cf1f0c9dfd463a7097f3c6a72c..b7a84c40288e733b04b74201b2a9e49b352a21f8 100644 --- a/tests/auto/debugger/debugger.pro +++ b/tests/auto/debugger/debugger.pro @@ -6,6 +6,7 @@ UTILSDIR = ../../../src/libs SOURCES += \ $$DEBUGGERDIR/gdbmi.cpp \ + $$DEBUGGERDIR/json.cpp \ main.cpp \ INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR diff --git a/tests/auto/debugger/main.cpp b/tests/auto/debugger/main.cpp index afb51a38c0118d821ac1f58099995172bd48a021..fd2121a8b800176d77634fc1883c8e0148963f0c 100644 --- a/tests/auto/debugger/main.cpp +++ b/tests/auto/debugger/main.cpp @@ -1,5 +1,6 @@ #include "gdbmi.h" +#include "json.h" #include <QtCore/QObject> #include <QtCore/QProcess> @@ -10,51 +11,56 @@ using namespace Debugger; using namespace Debugger::Internal; -static const char test1[] = +static const char gdbmi1[] = "[frame={level=\"0\",addr=\"0x00000000004061ca\"," "func=\"main\",file=\"test1.cpp\"," "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]"; -static const char test2[] = +static const char gdbmi2[] = "[frame={level=\"0\",addr=\"0x00002ac058675840\"," "func=\"QApplication\",file=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\"," "fullname=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\",line=\"592\"}," "frame={level=\"1\",addr=\"0x00000000004061e0\",func=\"main\",file=\"test1.cpp\"," "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]"; -static const char test3[] = +static const char gdbmi3[] = "[stack={frame={level=\"0\",addr=\"0x00000000004061ca\"," "func=\"main\",file=\"test1.cpp\"," "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}}]"; -static const char test4[] = +static const char gdbmi4[] = "&\"source /home/apoenitz/dev/ide/main/bin/gdb/qt4macros\\n\"" "4^done\n"; -static const char test5[] = +static const char gdbmi5[] = "[reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"1\"," "frame={addr=\"0x0000000000405738\",func=\"main\"," "args=[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\"0x7fff1ac78f28\"}]," "file=\"test1.cpp\",fullname=\"/home/apoenitz/work/test1/test1.cpp\"," "line=\"209\"}]"; -static const char test8[] = +static const char gdbmi8[] = "[data={locals={{name=\"a\"},{name=\"w\"}}}]"; -static const char test9[] = +static const char gdbmi9[] = "[data={locals=[name=\"baz\",name=\"urgs\",name=\"purgs\"]}]"; -static const char test10[] = +static const char gdbmi10[] = "[name=\"urgs\",numchild=\"1\",type=\"Urgs\"]"; -static const char test11[] = +static const char gdbmi11[] = "[{name=\"size\",value=\"1\",type=\"size_t\",readonly=\"true\"}," "{name=\"0\",value=\"one\",type=\"QByteArray\"}]"; -static const char test12[] = +static const char gdbmi12[] = "[{iname=\"local.hallo\",value=\"\\\"\\\\\\00382\\t\\377\",type=\"QByteArray\"," "numchild=\"0\"}]"; + +static const char jsont1[] = + "{\"Size\":100564,\"UID\":0,\"GID\":0,\"Permissions\":33261," + "\"ATime\":1242370878000,\"MTime\":1239154689000}"; + class tst_Debugger : public QObject { Q_OBJECT @@ -68,20 +74,29 @@ public: '\n' + QString(input)); } + void testJson(const char* input) + { + QCOMPARE('\n' + QString::fromLatin1(JsonValue(input).toString(false)), + '\n' + QString(input)); + } + private slots: - void mi1() { testMi(test1); } - void mi2() { testMi(test2); } - void mi3() { testMi(test3); } - //void mi4() { testMi(test4); } - void mi5() { testMi(test5); } - void mi8() { testMi(test8); } - void mi9() { testMi(test9); } - void mi10() { testMi(test10); } - void mi11() { testMi(test11); } - void mi12() { testMi(test12); } + void mi1() { testMi(gdbmi1); } + void mi2() { testMi(gdbmi2); } + void mi3() { testMi(gdbmi3); } + //void mi4() { testMi(gdbmi4); } + void mi5() { testMi(gdbmi5); } + void mi8() { testMi(gdbmi8); } + void mi9() { testMi(gdbmi9); } + void mi10() { testMi(gdbmi10); } + void mi11() { testMi(gdbmi11); } + //void mi12() { testMi(gdbmi12); } + + void json1() { testJson(jsont1); } void infoBreak(); +public slots: void runQtc(); public slots: