From 1044af5f824271d6e69f1b102dc39a37a718aa91 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Thu, 21 Jan 2010 12:35:09 +0100
Subject: [PATCH] S60: Support command line arguments when running on devices.

Add command line arguments to trklauncher. Add input field
to S60DeviceRunConfiguration and pass on to RunControl and debugger.
---
 src/plugins/debugger/gdb/trkgdbadapter.cpp       | 13 ++++---------
 src/plugins/debugger/gdb/trkgdbadapter.h         |  2 ++
 .../qt-s60/s60devicerunconfiguration.cpp         | 16 ++++++++++++++++
 .../qt-s60/s60devicerunconfiguration.h           |  5 +++++
 .../qt-s60/s60devicerunconfigurationwidget.cpp   | 15 +++++++++++++++
 .../qt-s60/s60devicerunconfigurationwidget.h     |  2 ++
 tests/manual/trklauncher/main.cpp                | 15 +++++++++++++--
 7 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp
index 7ae20251021..2093d1b2b4e 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp
@@ -1666,11 +1666,13 @@ void TrkGdbAdapter::startAdapter()
     m_overrideTrkDevice = parameters.remoteChannel;
     m_overrideTrkDeviceType = parameters.remoteChannelType;
     m_remoteExecutable = parameters.executable;
+    m_remoteArguments = parameters.processArgs;
     m_symbolFile = parameters.symbolFileName;
     // FIXME: testing hack, remove!
     if (parameters.processArgs.size() == 3 && parameters.processArgs.at(0) == _("@sym@")) {
         m_remoteExecutable = parameters.processArgs.at(1);
         m_symbolFile = parameters.processArgs.at(2);
+        m_remoteArguments.clear();
     }
     // Unixish gdbs accept only forward slashes
     m_symbolFile.replace(QLatin1Char('\\'), QLatin1Char('/'));
@@ -1727,15 +1729,8 @@ void TrkGdbAdapter::startAdapter()
 void TrkGdbAdapter::startInferior()
 {
     QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
-
-    QByteArray ba;
-    appendByte(&ba, 0); // ?
-    appendByte(&ba, 0); // ?
-    appendByte(&ba, 0); // ?
-
-    appendString(&ba, m_remoteExecutable.toLatin1(), TargetByteOrder);
-    sendTrkMessage(0x40, TrkCB(handleCreateProcess), ba); // Create Item
-    //sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, TrkCB(startGdbServer));
+    sendTrkMessage(0x40, TrkCB(handleCreateProcess),
+                   trk::Launcher::startProcessMessage(m_remoteExecutable, m_remoteArguments));
 }
 
 void TrkGdbAdapter::handleCreateProcess(const TrkResult &result)
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h
index 7ef9ac4f442..2aeb696c720 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.h
+++ b/src/plugins/debugger/gdb/trkgdbadapter.h
@@ -35,6 +35,7 @@
 #include "trkutils.h"
 #include "trkdevice.h"
 #include "trkoptions.h"
+#include "launcher.h"
 
 #include <QtCore/QHash>
 #include <QtCore/QPointer>
@@ -299,6 +300,7 @@ private:
     trk::Session m_session; // global-ish data (process id, target information)
     Snapshot m_snapshot; // local-ish data (memory and registers)
     QString m_remoteExecutable;
+    QStringList m_remoteArguments;
     QString m_symbolFile;
     int m_verbose;
     bool m_bufferedMemoryRead;
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 1557225c930..52756861a63 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -160,6 +160,7 @@ void S60DeviceRunConfiguration::save(PersistentSettingsWriter &writer) const
     writer.saveValue("CustomKeyPath", m_customKeyPath);
     writer.saveValue("SerialPortName", m_serialPortName);
     writer.saveValue("CommunicationType", m_communicationType);
+    writer.saveValue("CommandLineArguments", m_commandLineArguments);
     RunConfiguration::save(writer);
 }
 
@@ -173,6 +174,7 @@ void S60DeviceRunConfiguration::restore(const PersistentSettingsReader &reader)
     m_customKeyPath = reader.restoreValue("CustomKeyPath").toString();
     m_serialPortName = reader.restoreValue("SerialPortName").toString().trimmed();
     m_communicationType = reader.restoreValue("CommunicationType").toInt();
+    m_commandLineArguments = reader.restoreValue("CommandLineArguments").toStringList();
 }
 
 QString S60DeviceRunConfiguration::serialPortName() const
@@ -275,6 +277,16 @@ QString S60DeviceRunConfiguration::localExecutableFileName() const
     return QDir::toNativeSeparators(localExecutable);
 }
 
+QStringList S60DeviceRunConfiguration::commandLineArguments() const
+{
+    return m_commandLineArguments;
+}
+
+void S60DeviceRunConfiguration::setCommandLineArguments(const QStringList &args)
+{
+    m_commandLineArguments = args;
+}
+
 void S60DeviceRunConfiguration::updateTarget()
 {
     if (m_cachedTargetInformationValid)
@@ -414,6 +426,7 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(RunConfiguration *runConfigurat
     m_communicationType = s60runConfig->communicationType();
     m_targetName = s60runConfig->targetName();
     m_baseFileName = s60runConfig->basePackageFilePath();
+    m_commandLineArguments = s60runConfig->commandLineArguments();
     m_symbianPlatform = s60runConfig->symbianPlatform();
     m_symbianTarget = s60runConfig->symbianTarget();
     m_packageTemplateFile = s60runConfig->packageTemplateFileName();
@@ -660,6 +673,8 @@ void S60DeviceRunControlBase::startDeployment()
     //TODO sisx destination and file path user definable
     m_launcher->setTrkServerName(m_serialPortName);
     m_launcher->setSerialFrame(m_communicationType == SerialPortCommunication);
+    if (!m_commandLineArguments.isEmpty())
+        m_launcher->setCommandLineArgs(m_commandLineArguments);
     const QString copySrc(m_baseFileName + ".sisx");
     const QString copyDst = QString("C:\\Data\\%1.sisx").arg(QFileInfo(m_baseFileName).fileName());
     const QString runFileName = QString("C:\\sys\\bin\\%1.exe").arg(m_targetName);
@@ -874,6 +889,7 @@ S60DeviceDebugRunControl::S60DeviceDebugRunControl(S60DeviceRunConfiguration *ru
             Qt::QueuedConnection);
 
     m_startParams->remoteChannel = rc->serialPortName();
+    m_startParams->processArgs = rc->commandLineArguments();
     m_startParams->remoteChannelType = rc->communicationType();
     m_startParams->startMode = Debugger::StartInternal;
     m_startParams->toolChainType = rc->toolChainType();
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index 11b3db05b7a..1dd9228488a 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -94,6 +94,9 @@ public:
     QString packageFileName() const;
     QString localExecutableFileName() const;
 
+    QStringList commandLineArguments() const;
+    void setCommandLineArguments(const QStringList &args);
+
     ProjectExplorer::ToolChain::ToolChainType toolChainType() const;
 
 signals:
@@ -119,6 +122,7 @@ private:
     SigningMode m_signingMode;    
     QString m_customSignaturePath;
     QString m_customKeyPath;
+    QStringList m_commandLineArguments;
 };
 
 class S60DeviceRunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory
@@ -196,6 +200,7 @@ private:
     int     m_communicationType;
     QString m_targetName;
     QString m_baseFileName;
+    QStringList m_commandLineArguments;
     QString m_symbianPlatform;
     QString m_symbianTarget;
     QString m_packageTemplateFile;
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp
index d43048111e7..e55d0b46aef 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp
@@ -69,6 +69,7 @@ S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(
     m_detailsWidget(new Utils::DetailsWidget),
     m_serialPortsCombo(new QComboBox),
     m_nameLineEdit(new QLineEdit(m_runConfiguration->displayName())),
+    m_argumentsLineEdit(new QLineEdit(m_runConfiguration->commandLineArguments().join(QString(QLatin1Char(' '))))),
     m_sisxFileLabel(new QLabel),
     m_deviceInfoButton(new QToolButton),
     m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))),
@@ -94,6 +95,7 @@ S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(
     QLabel *nameLabel = new QLabel(tr("Name:"));
     nameLabel->setBuddy(m_nameLineEdit);
     formLayout->addRow(nameLabel, m_nameLineEdit);
+    formLayout->addRow(tr("Arguments:"), m_argumentsLineEdit);
     formLayout->addRow(tr("Install File:"), m_sisxFileLabel);
 
     updateSerialDevices();    
@@ -162,6 +164,8 @@ S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(
 
     connect(m_nameLineEdit, SIGNAL(textEdited(QString)),
             this, SLOT(displayNameEdited(QString)));
+    connect(m_argumentsLineEdit, SIGNAL(textEdited(QString)),
+            this, SLOT(argumentsEdited(QString)));
     connect(m_runConfiguration, SIGNAL(targetInformationChanged()),
             this, SLOT(updateTargetInformation()));
     connect(selfSign, SIGNAL(toggled(bool)), this, SLOT(selfSignToggled(bool)));
@@ -220,6 +224,17 @@ void S60DeviceRunConfigurationWidget::displayNameEdited(const QString &text)
     m_runConfiguration->setDisplayName(text);
 }
 
+void S60DeviceRunConfigurationWidget::argumentsEdited(const QString &text)
+{
+    const QString trimmed = text.trimmed();
+    if (trimmed.isEmpty()) {
+        m_runConfiguration->setCommandLineArguments(QStringList());
+    } else {
+        m_runConfiguration->setCommandLineArguments(trimmed.split(QLatin1Char(' '),
+                                                                  QString::SkipEmptyParts));
+    }
+}
+
 void S60DeviceRunConfigurationWidget::updateTargetInformation()
 {
     m_sisxFileLabel->setText(QDir::toNativeSeparators(m_runConfiguration->basePackageFilePath()
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h
index 83de31aa4a2..b76136a95d8 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h
@@ -67,6 +67,7 @@ public:
 
 private slots:
     void displayNameEdited(const QString &text);
+    void argumentsEdited(const QString &text);
     void updateTargetInformation();
     void updateSerialDevices();
     void setSerialPort(int index);
@@ -90,6 +91,7 @@ private:
     Utils::DetailsWidget *m_detailsWidget;
     QComboBox *m_serialPortsCombo;
     QLineEdit *m_nameLineEdit;
+    QLineEdit *m_argumentsLineEdit;
     QLabel *m_sisxFileLabel;
     QToolButton *m_deviceInfoButton;
     QLabel *m_deviceInfoDescriptionLabel;
diff --git a/tests/manual/trklauncher/main.cpp b/tests/manual/trklauncher/main.cpp
index 9938f847931..f35c49b9311 100644
--- a/tests/manual/trklauncher/main.cpp
+++ b/tests/manual/trklauncher/main.cpp
@@ -9,8 +9,9 @@
 static const char *usageC =
 "\n"
 "Usage: %1 [options] <trk_port_name>\n"
+"       %1 [options] <trk_port_name> <remote_executable_name> [-- args]\n"
 "       %1 [options] -i <trk_port_name> remote_sis_file\n"
-"       %1 [options] -I local_sis_file remote_sis_file] [<remote_executable_name>]\n"
+"       %1 [options] -I local_sis_file remote_sis_file] [<remote_executable_name>] [-- args]\n"
 "\nOptions:\n    -v verbose\n"
             "    -b Prompt for Bluetooth connect (Linux only)\n"
             "    -f turn serial message frame off (Bluetooth)\n"
@@ -58,6 +59,7 @@ static TrkLauncherPtr parseArguments(const QStringList &arguments, bool *bluetoo
     const int argCount = arguments.size();
     int verbosity = 0;
     *bluetooth = false;
+    QStringList remoteArguments;
     trk::Launcher::Actions actions = trk::Launcher::ActionPingOnly;
     int a = 1;
     for ( ; a < argCount; a++) {
@@ -88,8 +90,14 @@ static TrkLauncherPtr parseArguments(const QStringList &arguments, bool *bluetoo
             return TrkLauncherPtr();
         }
     }
+    // Parse for '--' delimiter for remote executable argunment
+    int pastArguments = a;
+    for ( ; pastArguments < argCount && arguments.at(pastArguments) != QLatin1String("--"); pastArguments++) ;
+    if (pastArguments != argCount)
+        for (int ra = pastArguments + 1; ra < argCount; ra++)
+            remoteArguments.push_back(arguments.at(ra));
     // Evaluate arguments
-    const int remainingArgsCount = argCount - a;
+    const int remainingArgsCount = pastArguments -a ;
     if (remainingArgsCount == 1 && !install && !customInstall) { // Ping
         return createLauncher(actions, arguments.at(a), serialFrame, verbosity);
     }
@@ -98,6 +106,7 @@ static TrkLauncherPtr parseArguments(const QStringList &arguments, bool *bluetoo
         TrkLauncherPtr launcher = createLauncher(actions, arguments.at(a), serialFrame, verbosity);
         launcher->addStartupActions(trk::Launcher::ActionRun);
         launcher->setFileName(arguments.at(a + 1));
+        launcher->setCommandLineArgs(remoteArguments);
         return launcher;
     }
     if ((remainingArgsCount == 3 || remainingArgsCount == 2) && install && !customInstall) {
@@ -106,6 +115,7 @@ static TrkLauncherPtr parseArguments(const QStringList &arguments, bool *bluetoo
         if (remainingArgsCount == 3) {
             launcher->addStartupActions(trk::Launcher::ActionRun);
             launcher->setFileName(arguments.at(a + 2));
+            launcher->setCommandLineArgs(remoteArguments);
         }
         return launcher;
     }
@@ -117,6 +127,7 @@ static TrkLauncherPtr parseArguments(const QStringList &arguments, bool *bluetoo
         if (remainingArgsCount == 4) {
             launcher->addStartupActions(trk::Launcher::ActionRun);
             launcher->setFileName(arguments.at(a + 3));
+            launcher->setCommandLineArgs(remoteArguments);
         }
         return launcher;
     }
-- 
GitLab