From bb085ff9272acd1ee8cb52d0c7b1e2d2a9116878 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 18 May 2015 17:43:25 +0200 Subject: qmlprofiler: Add some sanity to command line parsing. Use QCommandLineParser to allow for double-dash options and improve the help text. Task-number: QTBUG-43066 Change-Id: Iac772cbbf750016a9058658c9b4b275faf8fb62f Reviewed-by: Joerg Bornemann --- tools/qmlprofiler/main.cpp | 6 +- tools/qmlprofiler/qmlprofilerapplication.cpp | 163 ++++++++++++++------------- tools/qmlprofiler/qmlprofilerapplication.h | 3 +- 3 files changed, 87 insertions(+), 85 deletions(-) diff --git a/tools/qmlprofiler/main.cpp b/tools/qmlprofiler/main.cpp index a1bd1b38b4..b16706c3a9 100644 --- a/tools/qmlprofiler/main.cpp +++ b/tools/qmlprofiler/main.cpp @@ -38,10 +38,7 @@ int main(int argc, char *argv[]) { QmlProfilerApplication app(argc, argv); - if (!app.parseArguments()) { - app.printUsage(); - return 1; - } + app.parseArguments(); CommandListener listener; QObject::connect(&listener, SIGNAL(command(QString)), &app, SLOT(userCommand(QString))); @@ -51,6 +48,5 @@ int main(int argc, char *argv[]) // wait for listener to exit listener.wait(); - return exitValue; } diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp index a51f67164f..d3097c267c 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.cpp +++ b/tools/qmlprofiler/qmlprofilerapplication.cpp @@ -40,35 +40,15 @@ #include #include #include - -static const char usageTextC[] = -"Usage:\n" -" qmlprofiler [options] [program] [program-options]\n" -" qmlprofiler [options] -attach [hostname]\n" -"\n" -"QML Profiler retrieves QML tracing data from a running application.\n" -"The data collected can then be visualized in Qt Creator.\n" -"\n" -"The application to be profiled has to enable QML debugging. See the Qt Creator\n" -"documentation on how to do this for different Qt versions.\n" -"\n" -"Options:\n" -" -help Show this information and exit.\n" -" -fromStart\n" -" Record as soon as the engine is started, default is false.\n" -" -p , -port \n" -" TCP/IP port to use, default is 3768.\n" -" -v, -verbose\n" -" Print debugging output.\n" -" -version\n" -" Show the version of qmlprofiler and exit.\n"; +#include static const char commandTextC[] = -"Commands:\n" -" r, record\n" -" Switch recording on or off.\n" -" q, quit\n" -" Terminate program."; + "You can control the recoding interactively with the " + "following commands:\n" + " r, record\n" + " Switch recording on or off.\n" + " q, quit\n" + " Terminate program."; static const char TraceFileExtension[] = ".qtd"; @@ -140,63 +120,90 @@ QmlProfilerApplication::~QmlProfilerApplication() delete m_process; } -bool QmlProfilerApplication::parseArguments() +void QmlProfilerApplication::parseArguments() { - for (int argPos = 1; argPos < arguments().size(); ++argPos) { - const QString arg = arguments().at(argPos); - if (arg == QLatin1String("-attach") || arg == QLatin1String("-a")) { - if (argPos + 1 == arguments().size()) { - return false; - } - m_hostName = arguments().at(++argPos); - m_runMode = AttachMode; - } else if (arg == QLatin1String("-port") || arg == QLatin1String("-p")) { - if (argPos + 1 == arguments().size()) { - return false; - } - const QString portStr = arguments().at(++argPos); - bool isNumber; - m_port = portStr.toUShort(&isNumber); - if (!isNumber) { - logError(QString("'%1' is not a valid port").arg(portStr)); - return false; - } - } else if (arg == QLatin1String("-fromStart")) { - m_qmlProfilerClient.setRecording(true); - m_v8profilerClient.setRecording(true); - } else if (arg == QLatin1String("-help") || arg == QLatin1String("-h") || arg == QLatin1String("/h") || arg == QLatin1String("/?")) { - return false; - } else if (arg == QLatin1String("-verbose") || arg == QLatin1String("-v")) { - m_verbose = true; - } else if (arg == QLatin1String("-version")) { - print(QString("QML Profiler based on Qt %1.").arg(qVersion())); - ::exit(1); - return false; - } else { - if (m_programPath.isEmpty()) { - m_programPath = arg; - m_tracePrefix = QFileInfo(m_programPath).fileName(); - } else { - m_programArguments << arg; - } + setApplicationName(QLatin1String("qmlprofiler")); + setApplicationVersion(QLatin1String(qVersion())); + + QCommandLineParser parser; + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments); + + parser.setApplicationDescription(QChar::LineFeed + tr( + "The QML Profiler retrieves QML tracing data from an application. The data\n" + "collected can then be visualized in Qt Creator. The application to be profiled\n" + "has to enable QML debugging. See the Qt Creator documentation on how to do\n" + "this for different Qt versions.") + QChar::LineFeed + QChar::LineFeed + tr(commandTextC)); + + QCommandLineOption attach(QStringList() << QLatin1String("a") << QLatin1String("attach"), + tr("Attach to an application already running on , " + "instead of starting it locally."), + QLatin1String("hostname")); + parser.addOption(attach); + + QCommandLineOption port(QStringList() << QLatin1String("p") << QLatin1String("port"), + tr("Connect to the TCP port . The default is 3768."), + QLatin1String("port"), QLatin1String("3768")); + parser.addOption(port); + + QCommandLineOption fromStart(QLatin1String("fromStart"), + tr("Record as soon as the engine is started. " + "The default is false.")); + parser.addOption(fromStart); + + QCommandLineOption verbose(QStringList() << QLatin1String("verbose"), + tr("Print debugging output.")); + parser.addOption(verbose); + + parser.addHelpOption(); + parser.addVersionOption(); + + parser.addPositionalArgument(QLatin1String("program"), + tr("The program to be started and profiled."), + QLatin1String("[program]")); + parser.addPositionalArgument(QLatin1String("parameters"), + tr("Parameters for the program to be started."), + QLatin1String("[parameters...]")); + + parser.process(*this); + + if (parser.isSet(attach)) { + m_hostName = parser.value(attach); + m_runMode = AttachMode; + } + + if (parser.isSet(port)) { + bool isNumber; + m_port = parser.value(port).toUShort(&isNumber); + if (!isNumber) { + logError(tr("'%1' is not a valid port.").arg(parser.value(port))); + parser.showHelp(1); } } - if (m_runMode == LaunchMode - && m_programPath.isEmpty()) - return false; + if (parser.isSet(fromStart)) { + m_qmlProfilerClient.setRecording(true); + m_v8profilerClient.setRecording(true); + } - if (m_runMode == AttachMode - && !m_programPath.isEmpty()) - return false; + if (parser.isSet(verbose)) + m_verbose = true; - return true; -} + m_programArguments = parser.positionalArguments(); + if (!m_programArguments.isEmpty()) { + m_programPath = m_programArguments.takeFirst(); + m_tracePrefix = QFileInfo(m_programPath).fileName(); + } -void QmlProfilerApplication::printUsage() -{ - print(QLatin1String(usageTextC)); - print(QLatin1String(commandTextC)); + if (m_runMode == LaunchMode && m_programPath.isEmpty()) { + logError(tr("You have to specify either --attach or a program to start.")); + parser.showHelp(2); + } + + if (m_runMode == AttachMode && !m_programPath.isEmpty()) { + logError(tr("--attach cannot be used when starting a program.")); + parser.showHelp(3); + } } int QmlProfilerApplication::exec() @@ -207,7 +214,7 @@ int QmlProfilerApplication::exec() void QmlProfilerApplication::printCommands() { - print(QLatin1String(commandTextC)); + print(tr(commandTextC)); } QString QmlProfilerApplication::traceFileName() const diff --git a/tools/qmlprofiler/qmlprofilerapplication.h b/tools/qmlprofiler/qmlprofilerapplication.h index 7e7cebfcf1..aa63f54dc3 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.h +++ b/tools/qmlprofiler/qmlprofilerapplication.h @@ -48,8 +48,7 @@ public: QmlProfilerApplication(int &argc, char **argv); ~QmlProfilerApplication(); - bool parseArguments(); - void printUsage(); + void parseArguments(); int exec(); public slots: -- cgit v1.2.3