114 QCoreApplication::setApplicationName(QLatin1String(QGC_APP_NAME));
115 QCoreApplication::setApplicationVersion(QLatin1String(QGC_APP_VERSION_STR));
118 out.
parser = std::make_unique<QCommandLineParser>();
120 QCommandLineParser& parser = *out.parser;
121 parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
122 parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsOptions);
123 parser.setApplicationDescription(QStringLiteral(QGC_APP_DESCRIPTION));
126 const QCommandLineOption helpOption = parser.addHelpOption();
127 const QCommandLineOption versionOption = parser.addVersionOption();
130 const QCommandLineOption systemIdOpt(
131 QString(kOptSystemId),
132 QCoreApplication::translate(
"main",
"MAVLink GCS system id."),
133 QCoreApplication::translate(
"main",
"id"));
134 (void) parser.addOption(systemIdOpt);
136 const QCommandLineOption clearSettingsOpt(
137 QString(kOptClearSettings),
138 QCoreApplication::translate(
"main",
"Clear stored application settings."));
139 (void) parser.addOption(clearSettingsOpt);
141 const QCommandLineOption clearCacheOpt(
142 QString(kOptClearCache),
143 QCoreApplication::translate(
"main",
"Clear parameter and airframe caches."));
144 (void) parser.addOption(clearCacheOpt);
146 const QCommandLineOption loggingOpt(
147 QString(kOptLogging),
148 QCoreApplication::translate(
"main",
"Enable logging with optional rules string."),
149 QCoreApplication::translate(
"main",
"rules"));
150 (void) parser.addOption(loggingOpt);
152 const QCommandLineOption logOutputOpt(
153 QString(kOptLogOutput),
154 QCoreApplication::translate(
"main",
"Log to console."));
155 (void) parser.addOption(logOutputOpt);
157 const QCommandLineOption simpleBootOpt(
158 QString(kOptSimpleBoot),
159 QCoreApplication::translate(
"main",
"Initialize subsystems and exit."));
160 (void) parser.addOption(simpleBootOpt);
162#ifdef QGC_UNITTEST_BUILD
164 const QCommandLineOption unittestOpt(
165 QString(kOptUnittest),
166 QCoreApplication::translate(
"main",
"Run unit tests (optional filter value)."),
167 QCoreApplication::translate(
"main",
"filter"));
168 (void) parser.addOption(unittestOpt);
170 const QCommandLineOption unittestStressOpt(
171 QString(kOptUnittestStress),
172 QCoreApplication::translate(
"main",
"Stress unit tests."),
173 QCoreApplication::translate(
"main",
"count"));
174 (void) parser.addOption(unittestStressOpt);
176 const QCommandLineOption unittestOutputOpt(
177 QString(kOptUnittestOutput),
178 QCoreApplication::translate(
"main",
"Output test results to file (JUnit XML format)."),
179 QCoreApplication::translate(
"main",
"file"));
180 (void) parser.addOption(unittestOutputOpt);
182 const QCommandLineOption unittestLabelOpt(
183 QString(kOptUnittestLabel),
184 QCoreApplication::translate(
"main",
"Filter tests by label (unit, integration, vehicle, missionmanager, etc.)."),
185 QCoreApplication::translate(
"main",
"labels"));
186 (void) parser.addOption(unittestLabelOpt);
188 const QCommandLineOption listTestsOpt(
189 QString(kOptListTests),
190 QCoreApplication::translate(
"main",
"List available unit tests and exit."));
191 (void) parser.addOption(listTestsOpt);
193 const QCommandLineOption onscreenOpt(
194 QString(kOptOnscreen),
195 QCoreApplication::translate(
"main",
"Show test windows on screen instead of running offscreen."));
196 (void) parser.addOption(onscreenOpt);
199#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
201 const QCommandLineOption fakeMobileOpt(
202 QString(kOptFakeMobile),
203 QCoreApplication::translate(
"main",
"Run with mobile-style UI."));
204 (void) parser.addOption(fakeMobileOpt);
206 const QCommandLineOption allowMultipleOpt(
207 QString(kOptAllowMultiple),
208 QCoreApplication::translate(
"main",
"Bypass single-instance guard."));
209 (void) parser.addOption(allowMultipleOpt);
212#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
214 const QCommandLineOption swrastOpt(QString(kOptSwrast),
215 QCoreApplication::translate(
"main",
"Force software rendering."));
216 (void) parser.addOption(swrastOpt);
221 const QCommandLineOption quietWinAssertOpt(
222 QString(kOptNoWinAssertUI),
223 QCoreApplication::translate(
"main",
"Disable Windows assert dialog boxes."));
224 (void) parser.addOption(quietWinAssertOpt);
228 const QStringList normalizedArgs =
normalizeArgs(QCoreApplication::arguments());
229 parser.process(normalizedArgs);
232 out.unknownOptions = parser.unknownOptionNames();
235 if (!out.unknownOptions.isEmpty()) {
237 if (out.unknownOptions.contains(QLatin1String(
"unittest")) ||
238 out.unknownOptions.contains(QLatin1String(
"unittest-stress")) ||
239 out.unknownOptions.contains(QLatin1String(
"unittest-output")) ||
240 out.unknownOptions.contains(QLatin1String(
"list-tests"))) {
241#ifndef QGC_UNITTEST_BUILD
242 out.statusCode = CommandLineParseResult::Status::Error;
243 out.errorString = QCoreApplication::translate(
"main",
244 "--unittest/--unittest-stress/--unittest-output/--list-tests options are only available in unittest builds.");
245 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
250#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
252 if (out.unknownOptions.contains(QLatin1String(
"fake-mobile")) ||
253 out.unknownOptions.contains(QLatin1String(
"allow-multiple"))) {
254 out.statusCode = CommandLineParseResult::Status::Error;
255 out.errorString = QCoreApplication::translate(
"main",
256 "--fake-mobile/--allow-multiple are not supported on mobile platforms.");
257 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
264 if (out.unknownOptions.contains(QLatin1String(
"no-windows-assert-ui"))) {
265 out.statusCode = CommandLineParseResult::Status::Error;
266 out.errorString = QCoreApplication::translate(
"main",
267 "--no-windows-assert-ui is only supported on Windows.");
268 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
273#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
275 if (out.unknownOptions.contains(QLatin1String(
"swrast"))) {
276 out.statusCode = CommandLineParseResult::Status::Error;
277 out.errorString = QCoreApplication::translate(
"main",
278 "--swrast is only supported on Windows and macOS.");
279 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
285 out.statusCode = CommandLineParseResult::Status::Error;
286 out.errorString = QCoreApplication::translate(
"main",
"Unknown options: %1")
287 .arg(out.unknownOptions.join(QLatin1String(
", ")));
288 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
293 out.positional = parser.positionalArguments();
294 if (!out.positional.isEmpty()) {
295 out.statusCode = CommandLineParseResult::Status::Error;
296 out.errorString = QCoreApplication::translate(
"main",
"Unexpected positional arguments: %1")
297 .arg(out.positional.join(QLatin1String(
", ")));
298 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
303 if (parser.isSet(helpOption)) {
304 out.statusCode = CommandLineParseResult::Status::HelpRequested;
305 out.helpText = parser.helpText();
309 if (parser.isSet(versionOption)) {
310 out.statusCode = CommandLineParseResult::Status::VersionRequested;
311 out.versionText = QCoreApplication::applicationVersion();
316 if (parser.isSet(systemIdOpt)) {
317 const QString systemIdStr = parser.value(systemIdOpt);
319 const uint systemId = systemIdStr.toUInt(&ok);
320 if (!ok || (systemId < 1) || (systemId > 255)) {
321 out.statusCode = CommandLineParseResult::Status::Error;
322 out.errorString = QCoreApplication::translate(
"main",
"Invalid System ID (must be 1-255): %1")
324 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
327 out.systemId =
static_cast<quint8
>(systemId);
328 qCDebug(QGCCommandLineParserLog) <<
"System ID:" << systemId;
331 out.clearSettingsOptions = parser.isSet(clearSettingsOpt);
332 out.clearCache = parser.isSet(clearCacheOpt);
333 if (parser.isSet(loggingOpt)) {
334 out.loggingOptions = parser.value(loggingOpt);
335 qCDebug(QGCCommandLineParserLog) <<
"Logging options:" << out.loggingOptions.value();
337 out.logOutput = parser.isSet(logOutputOpt);
338 out.simpleBootTest = parser.isSet(simpleBootOpt);
340#ifdef QGC_UNITTEST_BUILD
342 if (parser.isSet(unittestOpt)) {
343 out.runningUnitTests =
true;
344 const QStringList vals = parser.values(unittestOpt);
346 for (
const QString& val : vals) {
347 if (!val.isEmpty()) {
348 out.unitTests.append(val);
351 qCDebug(QGCCommandLineParserLog) <<
"Unit tests:" << (out.unitTests.isEmpty() ? QStringLiteral(
"all") : out.unitTests.join(QLatin1String(
", ")));
354 if (parser.isSet(unittestStressOpt)) {
355 out.runningUnitTests =
true;
356 out.stressUnitTests =
true;
357 const QString stress = parser.value(unittestStressOpt);
358 if (stress.isEmpty()) {
359 out.stressUnitTestsCount = 20;
362 const uint count = stress.toUInt(&ok);
363 if (!ok || (count == 0)) {
364 out.statusCode = CommandLineParseResult::Status::Error;
365 out.errorString = QCoreApplication::translate(
"main",
"Invalid stress test count (must be > 0): %1")
367 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
370 out.stressUnitTestsCount = count;
372 qCDebug(QGCCommandLineParserLog) <<
"Stress test iterations:" << out.stressUnitTestsCount;
375 if (parser.isSet(unittestOutputOpt)) {
376 out.unitTestOutput = parser.value(unittestOutputOpt);
377 qCDebug(QGCCommandLineParserLog) <<
"Test output file:" << out.unitTestOutput.value();
380 if (parser.isSet(unittestLabelOpt)) {
381 out.labelFilter = parser.value(unittestLabelOpt);
382 qCDebug(QGCCommandLineParserLog) <<
"Label filter:" << out.labelFilter.value();
385 out.listTests = parser.isSet(listTestsOpt);
387 qCDebug(QGCCommandLineParserLog) <<
"List tests requested";
390 out.onscreen = parser.isSet(onscreenOpt);
394#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
395 out.fakeMobile = parser.isSet(fakeMobileOpt);
396 out.allowMultiple = parser.isSet(allowMultipleOpt);
398 out.fakeMobile =
false;
399 out.allowMultiple =
false;
404 out.quietWindowsAsserts = parser.isSet(quietWinAssertOpt);
406 out.quietWindowsAsserts =
false;
409#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
410 out.useSwRast = parser.isSet(swrastOpt);
412 out.useSwRast =
false;
415 out.statusCode = CommandLineParseResult::Status::Ok;
416 qCDebug(QGCCommandLineParserLog) <<
"Command line parsing completed successfully";