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(
216 QCoreApplication::translate(
"main",
"Force software OpenGL."));
217 (void) parser.addOption(swrastOpt);
222 const QCommandLineOption quietWinAssertOpt(
223 QString(kOptNoWinAssertUI),
224 QCoreApplication::translate(
"main",
"Disable Windows assert dialog boxes."));
225 (void) parser.addOption(quietWinAssertOpt);
229 const QStringList normalizedArgs =
normalizeArgs(QCoreApplication::arguments());
230 parser.process(normalizedArgs);
233 out.unknownOptions = parser.unknownOptionNames();
236 if (!out.unknownOptions.isEmpty()) {
238 if (out.unknownOptions.contains(QLatin1String(
"unittest")) ||
239 out.unknownOptions.contains(QLatin1String(
"unittest-stress")) ||
240 out.unknownOptions.contains(QLatin1String(
"unittest-output")) ||
241 out.unknownOptions.contains(QLatin1String(
"list-tests"))) {
242#ifndef QGC_UNITTEST_BUILD
243 out.statusCode = CommandLineParseResult::Status::Error;
244 out.errorString = QCoreApplication::translate(
"main",
245 "--unittest/--unittest-stress/--unittest-output/--list-tests options are only available in unittest builds.");
246 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
251#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
253 if (out.unknownOptions.contains(QLatin1String(
"fake-mobile")) ||
254 out.unknownOptions.contains(QLatin1String(
"allow-multiple"))) {
255 out.statusCode = CommandLineParseResult::Status::Error;
256 out.errorString = QCoreApplication::translate(
"main",
257 "--fake-mobile/--allow-multiple are not supported on mobile platforms.");
258 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
265 if (out.unknownOptions.contains(QLatin1String(
"no-windows-assert-ui"))) {
266 out.statusCode = CommandLineParseResult::Status::Error;
267 out.errorString = QCoreApplication::translate(
"main",
268 "--no-windows-assert-ui is only supported on Windows.");
269 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
274#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
276 if (out.unknownOptions.contains(QLatin1String(
"swrast"))) {
277 out.statusCode = CommandLineParseResult::Status::Error;
278 out.errorString = QCoreApplication::translate(
"main",
279 "--swrast is only supported on Windows and macOS.");
280 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
286 out.statusCode = CommandLineParseResult::Status::Error;
287 out.errorString = QCoreApplication::translate(
"main",
"Unknown options: %1")
288 .arg(out.unknownOptions.join(QLatin1String(
", ")));
289 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
294 out.positional = parser.positionalArguments();
295 if (!out.positional.isEmpty()) {
296 out.statusCode = CommandLineParseResult::Status::Error;
297 out.errorString = QCoreApplication::translate(
"main",
"Unexpected positional arguments: %1")
298 .arg(out.positional.join(QLatin1String(
", ")));
299 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
304 if (parser.isSet(helpOption)) {
305 out.statusCode = CommandLineParseResult::Status::HelpRequested;
306 out.helpText = parser.helpText();
310 if (parser.isSet(versionOption)) {
311 out.statusCode = CommandLineParseResult::Status::VersionRequested;
312 out.versionText = QCoreApplication::applicationVersion();
317 if (parser.isSet(systemIdOpt)) {
318 const QString systemIdStr = parser.value(systemIdOpt);
320 const uint systemId = systemIdStr.toUInt(&ok);
321 if (!ok || (systemId < 1) || (systemId > 255)) {
322 out.statusCode = CommandLineParseResult::Status::Error;
323 out.errorString = QCoreApplication::translate(
"main",
"Invalid System ID (must be 1-255): %1")
325 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
328 out.systemId =
static_cast<quint8
>(systemId);
329 qCDebug(QGCCommandLineParserLog) <<
"System ID:" << systemId;
332 out.clearSettingsOptions = parser.isSet(clearSettingsOpt);
333 out.clearCache = parser.isSet(clearCacheOpt);
334 if (parser.isSet(loggingOpt)) {
335 out.loggingOptions = parser.value(loggingOpt);
336 qCDebug(QGCCommandLineParserLog) <<
"Logging options:" << out.loggingOptions.value();
338 out.logOutput = parser.isSet(logOutputOpt);
339 out.simpleBootTest = parser.isSet(simpleBootOpt);
341#ifdef QGC_UNITTEST_BUILD
343 if (parser.isSet(unittestOpt)) {
344 out.runningUnitTests =
true;
345 const QStringList vals = parser.values(unittestOpt);
347 for (
const QString& val : vals) {
348 if (!val.isEmpty()) {
349 out.unitTests.append(val);
352 qCDebug(QGCCommandLineParserLog) <<
"Unit tests:" << (out.unitTests.isEmpty() ? QStringLiteral(
"all") : out.unitTests.join(QLatin1String(
", ")));
355 if (parser.isSet(unittestStressOpt)) {
356 out.runningUnitTests =
true;
357 out.stressUnitTests =
true;
358 const QString stress = parser.value(unittestStressOpt);
359 if (stress.isEmpty()) {
360 out.stressUnitTestsCount = 20;
363 const uint count = stress.toUInt(&ok);
364 if (!ok || (count == 0)) {
365 out.statusCode = CommandLineParseResult::Status::Error;
366 out.errorString = QCoreApplication::translate(
"main",
"Invalid stress test count (must be > 0): %1")
368 qCWarning(QGCCommandLineParserLog) << out.errorString.value();
371 out.stressUnitTestsCount = count;
373 qCDebug(QGCCommandLineParserLog) <<
"Stress test iterations:" << out.stressUnitTestsCount;
376 if (parser.isSet(unittestOutputOpt)) {
377 out.unitTestOutput = parser.value(unittestOutputOpt);
378 qCDebug(QGCCommandLineParserLog) <<
"Test output file:" << out.unitTestOutput.value();
381 if (parser.isSet(unittestLabelOpt)) {
382 out.labelFilter = parser.value(unittestLabelOpt);
383 qCDebug(QGCCommandLineParserLog) <<
"Label filter:" << out.labelFilter.value();
386 out.listTests = parser.isSet(listTestsOpt);
388 qCDebug(QGCCommandLineParserLog) <<
"List tests requested";
391 out.onscreen = parser.isSet(onscreenOpt);
395#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
396 out.fakeMobile = parser.isSet(fakeMobileOpt);
397 out.allowMultiple = parser.isSet(allowMultipleOpt);
399 out.fakeMobile =
false;
400 out.allowMultiple =
false;
405 out.quietWindowsAsserts = parser.isSet(quietWinAssertOpt);
407 out.quietWindowsAsserts =
false;
410#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
411 out.useSwRast = parser.isSet(swrastOpt);
413 out.useSwRast =
false;
416 out.statusCode = CommandLineParseResult::Status::Ok;
417 qCDebug(QGCCommandLineParserLog) <<
"Command line parsing completed successfully";