summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFawzi Mohamed <fawzi.mohamed@digia.com>2014-01-09 15:47:05 +0100
committerFawzi Mohamed <fawzi.mohamed@digia.com>2014-01-21 13:43:19 +0100
commit1ce5b1273a0c14cb4bb19f8a6c2ce206c8af318d (patch)
treec1ec5918273481deca10eba1121c58fbcd2fe1cb
parent9f81e79c8f095b4755719cb8f7a8c5e8d9e6b4b6 (diff)
downloadqt-creator-1ce5b1273a0c14cb4bb19f8a6c2ce206c8af318d.tar.gz
ios: fix handling of command characters in run
Xml does not support control characters (even if encoded), thus QXmlStreamWriter does not encode them, and QXmlStreamReader gives an error with them. Thus outputting a control char would stop the application. Now we send them with a special tag and decode them. Note that the Output pane does some emulation of terminal behavior when receiving them. Sending app output as block because otherwise the stange logic within the OutputPane inserts spurious newlines (a string not containing a newline always gets a newline prepended) . Task-number: QTCREATORBUG-11219 Change-Id: I3557ffbb23ca2ea4eec9a97335a95580c9c4482b Reviewed-by: Eike Ziller <eike.ziller@digia.com> Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
-rw-r--r--src/plugins/ios/iosdebugsupport.cpp4
-rw-r--r--src/plugins/ios/iostoolhandler.cpp18
-rw-r--r--src/tools/iostool/main.cpp36
3 files changed, 44 insertions, 14 deletions
diff --git a/src/plugins/ios/iosdebugsupport.cpp b/src/plugins/ios/iosdebugsupport.cpp
index 174ea9bd9c..d698c9e438 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 e00e13754d..7a4ffe9f50 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<char>(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 bfec66e07a..0d2c4cdf92 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()