refactor: new Classes CoreArg and CoreArgParser to use to create and parse core options

This commit is contained in:
sithlord48 2025-08-22 16:22:56 -04:00 committed by Chris Rizzitello
parent 6f574a3076
commit 10f34f214f
5 changed files with 185 additions and 50 deletions

View file

@ -6,12 +6,12 @@
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#include "VersionInfo.h"
#include "arch/Arch.h"
#include "base/EventQueue.h"
#include "base/Log.h"
#include "common/ExitCodes.h"
#include "deskflow/ClientApp.h"
#include "deskflow/CoreArgParser.h"
#include "deskflow/ServerApp.h"
#if SYSAPI_WIN32
@ -20,17 +20,12 @@
#endif
#include <QSharedMemory>
#include <QTextStream>
#include <iostream>
const static auto kHeader = QStringLiteral("%1-core: %2\n").arg(kAppId, kDisplayVersion);
void showHelp()
void showHelp(const CoreArgParser &parser)
{
std::cout << qPrintable(kHeader) << qPrintable(kAppDescription) << "\n\n";
std::cout << "Usage: deskflow-core <server | client> [...options]" << std::endl;
std::cout << "server - start as a server (deskflow-server)" << std::endl;
std::cout << "client - start as a client (deskflow-client)" << std::endl;
QTextStream(stdout) << parser.helpText() << "\n";
ServerApp sApp(nullptr);
sApp.help();
@ -38,39 +33,6 @@ void showHelp()
cApp.help();
}
bool isHelp(int argc, char **argv)
{
for (int i = 0; i < argc; ++i) {
if (argv[i] == std::string("--help") || argv[i] == std::string("-h"))
return true;
}
return false;
}
void showVersion()
{
std::cout << qPrintable(kHeader) << qPrintable(kCopyright) << std::endl;
}
bool isVersion(int argc, char **argv)
{
for (int i = 0; i < argc; ++i) {
if (argv[i] == std::string("--version") || argv[i] == std::string("-v"))
return true;
}
return false;
}
bool isServer(int argc, char **argv)
{
return (argc > 1 && argv[1] == std::string("server"));
}
bool isClient(int argc, char **argv)
{
return (argc > 1 && argv[1] == std::string("client"));
}
int main(int argc, char **argv)
{
Arch arch;
@ -78,16 +40,29 @@ int main(int argc, char **argv)
Log log;
if (isHelp(argc, argv)) {
showHelp();
QStringList args;
for (int i = 0; i < argc; i++)
args.append(argv[i]);
CoreArgParser parser(args);
// Comment below until we are ready use only this parser
// if (!parser.errorText().isEmpty()) {
// QTextStream(stdout) << parser.errorText() << "\nUse --help for more information.";
// return s_exitFailed;
// }
if (parser.help()) {
showHelp(parser);
return s_exitSuccess;
}
if (isVersion(argc, argv)) {
showVersion();
if (parser.version()) {
QTextStream(stdout) << parser.versionText();
return s_exitSuccess;
}
// Before we check any more args we need to check for a duplicate process.
// Create a shared memory segment with a unique key
// This is to prevent a new instance from running if one is already running
QSharedMemory sharedMemory("deskflow-core");
@ -102,6 +77,9 @@ int main(int argc, char **argv)
LOG_WARN("an instance of deskflow core is already running");
return s_exitDuplicate;
}
parser.parse();
#if SYSAPI_WIN32
// HACK to make sure settings gets the correct qApp path
QCoreApplication m(argc, argv);
@ -112,14 +90,12 @@ int main(int argc, char **argv)
EventQueue events;
if (isServer(argc, argv)) {
if (parser.serverMode()) {
ServerApp app(&events);
return app.run(argc, argv);
} else if (isClient(argc, argv)) {
} else if (parser.clientMode()) {
ClientApp app(&events);
return app.run(argc, argv);
} else {
showHelp();
}
return s_exitSuccess;

View file

@ -83,6 +83,9 @@ add_library(${lib_name} STATIC ${PLATFORM_CODE}
ClipboardChunk.h
Config.cpp
Config.h
CoreArgParser.cpp
CoreArgParser.h
CoreArgs.h
DaemonApp.cpp
DaemonApp.h
DeskflowException.cpp

View file

@ -0,0 +1,90 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#include "CoreArgParser.h"
#include "CoreArgs.h"
#include "VersionInfo.h"
#include "common/Constants.h"
#include "common/ExitCodes.h"
#include "common/Settings.h"
const QString CoreArgParser::s_headerText = QStringLiteral("%1-core: %2\n").arg(kAppId, kDisplayVersion);
CoreArgParser::CoreArgParser(const QStringList &args)
{
m_parser.addPositionalArgument("coremode", "The mode to start in either: server or client", "coremode");
m_parser.addOptions(CoreArgs::options);
m_parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
m_parser.parse(args);
m_parser.setApplicationDescription(kAppDescription);
m_helpText = m_parser.helpText().replace("<executable_name>", QString("%1-core").arg(kAppId));
m_helpText.replace("[options] coremode", "coremode [options]");
}
void CoreArgParser::parse()
{
auto posArgs = m_parser.positionalArguments();
if (posArgs.isEmpty()) {
showHelpText();
exit(s_exitSuccess);
}
const QString mode = posArgs.takeFirst();
m_serverMode = (mode.compare("server", Qt::CaseInsensitive) == 0);
m_clientMode = (mode.compare("client", Qt::CaseInsensitive) == 0);
if ((!m_clientMode && !m_serverMode) || mode.isEmpty()) {
showHelpText();
exit(s_exitSuccess);
}
if (m_parser.isSet(CoreArgs::configOption)) {
Settings::setSettingFile(m_parser.value(CoreArgs::configOption));
}
}
[[noreturn]] void CoreArgParser::showHelpText() const
{
QTextStream(stdout) << helpText();
exit(s_exitSuccess);
}
QString CoreArgParser::helpText() const
{
return QStringLiteral("%1%2").arg(s_headerText, m_helpText);
}
QString CoreArgParser::versionText() const
{
return QStringLiteral("%1%2\n").arg(s_headerText, kCopyright);
}
QString CoreArgParser::errorText() const
{
return m_parser.errorText();
}
bool CoreArgParser::help() const
{
return m_parser.isSet(CoreArgs::helpOption);
}
bool CoreArgParser::version() const
{
return m_parser.isSet(CoreArgs::versionOption);
}
bool CoreArgParser::serverMode() const
{
return m_serverMode;
}
bool CoreArgParser::clientMode() const
{
return m_clientMode;
}

View file

@ -0,0 +1,44 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#pragma once
#include <QCommandLineParser>
/**
* @brief The CoreArgParser class
* This class processes the argments for the "core" app
*/
class CoreArgParser
{
public:
/**
* @brief CoreArgParser calling this funciton will parse apps and set the setting and version options
* For any other settings to be set you must call parse();
* @sa parse();
* @param args List of args to parse
*/
explicit CoreArgParser(const QStringList &args = {});
/**
* @brief parse
* This method will parse all options other then help and version
*/
void parse();
QString helpText() const;
QString versionText() const;
QString errorText() const;
bool help() const;
bool version() const;
bool serverMode() const;
bool clientMode() const;
private:
[[noreturn]] void showHelpText() const;
QCommandLineParser m_parser;
QString m_helpText;
bool m_clientMode = false;
bool m_serverMode = false;
static const QString s_headerText;
};

View file

@ -0,0 +1,22 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#pragma once
#include <QCommandLineOption>
/**
* @brief The CoreArgs class
* This class contains args for the CoreArgParser
*/
struct CoreArgs
{
inline static const auto helpOption = QCommandLineOption({"h", "help"}, "Display Help on the command line");
inline static const auto versionOption = QCommandLineOption({"v", "version"}, "Display version information");
inline static const auto configOption = QCommandLineOption(
{"s", "settings"}, "override configuration file to use", "configFile"
); // use -c later, now avoid breaking the serverApp args.
inline static const auto options = {helpOption, versionOption, configOption};
};