diff --git a/src/plugins/ios/iosdebugsupport.cpp b/src/plugins/ios/iosdebugsupport.cpp index 174ea9bd9cc..d698c9e438a 100644 --- a/src/plugins/ios/iosdebugsupport.cpp +++ b/src/plugins/ios/iosdebugsupport.cpp @@ -222,9 +222,9 @@ void IosDebugSupport::handleRemoteErrorOutput(const QString &output) { if (m_runControl) { if (m_runControl->engine()) - m_runControl->engine()->showMessage(output + QLatin1Char('\n'), AppError); + m_runControl->engine()->showMessage(output, AppError); else - m_runControl->showMessage(output + QLatin1Char('\n'), AppError); + m_runControl->showMessage(output, AppError); } } diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp index e00e13754dd..7a4ffe9f50d 100644 --- a/src/plugins/ios/iostoolhandler.cpp +++ b/src/plugins/ios/iostoolhandler.cpp @@ -62,6 +62,7 @@ struct ParserState { Value, QueryResult, AppOutput, + ControlChar, AppStarted, InferiorPid, GdbServerPort, @@ -87,9 +88,10 @@ struct ParserState { case Status: case InferiorPid: case GdbServerPort: + case AppOutput: return true; case QueryResult: - case AppOutput: + case ControlChar: case AppStarted: case AppTransfer: case Item: @@ -398,6 +400,13 @@ void IosToolHandlerPrivate::processXml() stack.append(ParserState(ParserState::QueryResult)); } else if (elName == QLatin1String("app_output")) { stack.append(ParserState(ParserState::AppOutput)); + } else if (elName == QLatin1String("control_char")) { + QXmlStreamAttributes attributes = outputParser.attributes(); + QChar c[1] = { QChar::fromLatin1(static_cast(attributes.value(QLatin1String("code")).toString().toInt())) }; + if (stack.size() > 0 && stack.last().collectChars()) + stack.last().chars.append(c[0]); + stack.append(ParserState(ParserState::ControlChar)); + break; } else if (elName == QLatin1String("item")) { stack.append(ParserState(ParserState::Item)); } else if (elName == QLatin1String("status")) { @@ -466,6 +475,9 @@ void IosToolHandlerPrivate::processXml() stop(0); return; case ParserState::AppOutput: + appOutput(p.chars); + break; + case ParserState::ControlChar: break; case ParserState::AppStarted: break; @@ -494,9 +506,7 @@ void IosToolHandlerPrivate::processXml() // isCDATA() returns true. if (stack.isEmpty()) break; - if (stack.last().kind == ParserState::AppOutput) - emit appOutput(outputParser.text().toString()); - else if (stack.last().collectChars()) + if (stack.last().collectChars()) stack.last().chars.append(outputParser.text()); break; case QXmlStreamReader::Comment: diff --git a/src/tools/iostool/main.cpp b/src/tools/iostool/main.cpp index bfec66e07ac..0d2c4cdf929 100644 --- a/src/tools/iostool/main.cpp +++ b/src/tools/iostool/main.cpp @@ -65,6 +65,7 @@ public: void writeMsg(const char *msg); void writeMsg(const QString &msg); void stopXml(int errorCode); + void writeTextInElement(const QString &output); private slots: void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress, const QString &info); @@ -338,13 +339,15 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId, void IosTool::writeMsg(const char *msg) { - out.writeTextElement(QLatin1String("msg"), QLatin1String(msg)); - outFile.flush(); + writeMsg(QString::fromLatin1(msg)); } void IosTool::writeMsg(const QString &msg) { - out.writeTextElement(QLatin1String("msg"), msg); + out.writeStartElement(QLatin1String("msg")); + writeTextInElement(msg); + out.writeCharacters(QLatin1String("\n")); + out.writeEndElement(); outFile.flush(); } @@ -366,18 +369,35 @@ void IosTool::deviceInfo(const QString &deviceId, const Ios::IosDeviceManager::D doExit(); } +void IosTool::writeTextInElement(const QString &output) +{ + QRegExp controlCharRe(QLatin1String("[\x01-\x08]|\x0B|\x0C|[\x0E-\x1F]|\\0000")); + int pos = 0; + int oldPos = 0; + + while ((pos = controlCharRe.indexIn(output, pos)) != -1) { + out.writeCharacters(output.mid(oldPos, pos - oldPos)); + out.writeEmptyElement(QLatin1String("control_char")); + out.writeAttribute(QLatin1String("code"), QString::number(output.at(pos).toLatin1())); + pos += 1; + oldPos = pos; + } + out.writeCharacters(output.mid(oldPos, output.length() - oldPos)); +} + void IosTool::appOutput(const QString &output) { - if (inAppOutput) - out.writeCharacters(output); - else - out.writeTextElement(QLatin1String("app_output"), output); + if (!inAppOutput) + out.writeStartElement(QLatin1String("app_output")); + writeTextInElement(output); + if (!inAppOutput) + out.writeEndElement(); outFile.flush(); } void IosTool::errorMsg(const QString &msg) { - writeMsg(msg + QLatin1Char('\n')); + writeMsg(msg); } void IosTool::handleNewConnection() diff --git a/tests/system/shared/hook_utils.py b/tests/system/shared/hook_utils.py index 82e00bd9f0b..bc1a81b9fe2 100644 --- a/tests/system/shared/hook_utils.py +++ b/tests/system/shared/hook_utils.py @@ -230,13 +230,14 @@ def __configureCustomExecutable__(projectName, port, mkspec, qmakeVersion): test.warning("Configured Squish directory seems to be missing - using fallback without hooking into subprocess.", "Failed to find '%s'" % startAUT) return False + progressBarWait() addButton = waitForObject("{container={window=':Qt Creator_Core::Internal::MainWindow' " "type='ProjectExplorer::Internal::RunSettingsWidget' unnamed='1' " "visible='1'} occurrence='2' text='Add' type='QPushButton' " "unnamed='1' visible='1'}") clickButton(addButton) addMenu = addButton.menu() - activateItem(waitForObjectItem(objectMap.realName(addMenu), 'Custom Executable')) + activateItem(waitForObjectItem(addMenu, 'Custom Executable')) exePathChooser = waitForObject(":Executable:_Utils::PathChooser", 2000) exeLineEd = getChildByClass(exePathChooser, "Utils::BaseValidatingLineEdit") argLineEd = waitForObject("{buddy={window=':Qt Creator_Core::Internal::MainWindow' "