diff --git a/Jamulus.pro b/Jamulus.pro index 13206c8113..0a163307d3 100644 --- a/Jamulus.pro +++ b/Jamulus.pro @@ -380,7 +380,9 @@ HEADERS += src/buffer.h \ src/recorder/jamrecorder.h \ src/recorder/creaperproject.h \ src/recorder/cwavestream.h \ - src/signalhandler.h + src/signalhandler.h \ + src/cmdline.h + !contains(CONFIG, "serveronly") { HEADERS += src/client.h \ @@ -490,7 +492,8 @@ SOURCES += src/buffer.cpp \ src/util.cpp \ src/recorder/jamrecorder.cpp \ src/recorder/creaperproject.cpp \ - src/recorder/cwavestream.cpp + src/recorder/cwavestream.cpp \ + src/cmdline.cpp !contains(CONFIG, "serveronly") { SOURCES += src/client.cpp \ diff --git a/src/cmdline.cpp b/src/cmdline.cpp new file mode 100644 index 0000000000..2414ec6ebd --- /dev/null +++ b/src/cmdline.cpp @@ -0,0 +1,226 @@ +/******************************************************************************\ + * Copyright (c) 2022 + * + * Author(s): + * Peter Goderie (pgScorpio) + * + ****************************************************************************** + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * +\******************************************************************************/ + +#include "cmdline.h" +#include + +/************************************************ + Statics to be assigned from main () + ************************************************/ + +int CCommandline::argc = 0; +char** CCommandline::argv = NULL; + +CCommandline::CCommandline ( tOnArgumentError* onArgumentErrorFunc ) : onArgumentError ( onArgumentErrorFunc ) +{ + if ( ( argc == 0 ) || ( argv == NULL ) ) + { + QString errmsg ( "CCommandline::argc and CCommandline::argv are not initialized from main() !" ); + + if ( onArgumentErrorFunc ) + { + onArgumentErrorFunc ( errmsg ); + } + else + { + qCritical() << errmsg; + exit ( 1 ); + } + } + + reset(); +} + +int CCommandline::GetArgumentList ( QStringList& argumentList ) +{ + argumentList.clear(); + + for ( int i = 1; i < argc; i++ ) + { + argumentList.append ( argv[i] ); + } + + return argumentList.size(); +} + +/************************************************ + Get full command line as a single string + ************************************************/ + +QString CCommandline::Commandline() +{ + QString cmdline = argv[0]; + + for ( int i = 1; i < argc; i++ ) + { + cmdline += " "; + cmdline += argv[i]; + } + + return cmdline; +} + +QString CCommandline::Argument ( int i ) // i = 1..ArgumentCount() +{ + if ( ( i >= 0 ) && ( i < argc ) ) + { + return QString ( argv[i] ); + } + + return QString(); +} + +/************************************************ + sequencial parse functions + using the argument index: 1 <= i < argc + ************************************************/ + +bool CCommandline::GetFlagArgument ( int& i, const QString& strShortOpt, const QString& strLongOpt ) +{ + if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) + { + return true; + } + else + { + return false; + } +} + +bool CCommandline::GetStringArgument ( int& i, const QString& strShortOpt, const QString& strLongOpt, QString& strArg ) +{ + if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) + { + if ( ++i >= argc ) + { + if ( onArgumentError ) + { + onArgumentError ( QString ( "%1: '%2' needs a string argument." ).arg ( argv[0] ).arg ( argv[i - 1] ) ); + } + + return false; + } + + strArg = argv[i]; + + return true; + } + else + { + return false; + } +} + +bool CCommandline::GetNumericArgument ( int& i, + const QString& strShortOpt, + const QString& strLongOpt, + double rRangeStart, + double rRangeStop, + double& rValue ) +{ + if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) + { + QString errmsg = "%1: '%2' needs a numeric argument from '%3' to '%4'."; + + if ( ++i >= argc ) + { + if ( onArgumentError ) + { + onArgumentError ( errmsg.arg ( argv[0] ).arg ( argv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); + } + + return false; + } + + char* p; + rValue = strtod ( argv[i], &p ); + if ( *p || ( rValue < rRangeStart ) || ( rValue > rRangeStop ) ) + { + if ( onArgumentError ) + { + onArgumentError ( errmsg.arg ( argv[0] ).arg ( argv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); + } + + if ( rValue < rRangeStart ) + { + rValue = rRangeStart; + } + else if ( rValue > rRangeStop ) + { + rValue = rRangeStop; + } + + return true; + } + + return true; + } + else + { + return false; + } +} + +/************************************************ + find and get a specific argument: + ************************************************/ + +bool CCommandline::GetFlagArgument ( const QString& strShortOpt, const QString& strLongOpt ) +{ + for ( int i = 1; i < argc; i++ ) + { + if ( GetFlagArgument ( i, strShortOpt, strLongOpt ) ) + { + return true; + } + } + + return false; +} + +bool CCommandline::GetStringArgument ( const QString& strShortOpt, const QString& strLongOpt, QString& strArg ) +{ + for ( int i = 1; i < argc; i++ ) + { + if ( GetStringArgument ( i, strShortOpt, strLongOpt, strArg ) ) + { + return true; + } + } + + return false; +} + +bool CCommandline::GetNumericArgument ( const QString& strShortOpt, const QString& strLongOpt, double rRangeStart, double rRangeStop, double& rValue ) +{ + for ( int i = 1; i < argc; i++ ) + { + if ( GetNumericArgument ( i, strShortOpt, strLongOpt, rRangeStart, rRangeStop, rValue ) ) + { + return true; + } + } + + return false; +} diff --git a/src/cmdline.h b/src/cmdline.h new file mode 100644 index 0000000000..42278ebf99 --- /dev/null +++ b/src/cmdline.h @@ -0,0 +1,177 @@ +#pragma once + +/******************************************************************************\ + * Copyright (c) 2022 + * + * Author(s): + * Peter Goderie (pgScorpio) + * + ****************************************************************************** + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * +\******************************************************************************/ + +#include + +/****************************************************************************** + CCommandline class: + Note that passing commandline arguments to classes is no longer required, + since via this class we can get commandline options anywhere. + ******************************************************************************/ + +class CCommandline +{ +public: + typedef void tOnArgumentError ( QString errMsg ); + + CCommandline ( tOnArgumentError* onArgumentErrorFunc = NULL ); + +private: + friend int main ( int argc, char** argv ); + + /************************************************ + Statics to be assigned in main () + ************************************************/ + static int argc; + static char** argv; + +protected: + tOnArgumentError* onArgumentError; + +public: + static QString GetProgramPath() { return QString ( *argv ); } + + static int ArgumentCount() { return ( argc - 1 ); } // excludes program path + static QString Argument ( int i ); // i = 1..ArgumentCount() + + static QString Commandline(); + static int GetArgumentList ( QStringList& argumentList ); + +public: + // sequencial parse functions using the argument index: + + bool GetFlagArgument ( int& i, const QString& strShortOpt, const QString& strLongOpt ); + + bool GetStringArgument ( int& i, const QString& strShortOpt, const QString& strLongOpt, QString& strArg ); + + bool GetNumericArgument ( int& i, const QString& strShortOpt, const QString& strLongOpt, double rRangeStart, double rRangeStop, double& rValue ); + +public: + // find and get a specific argument: + bool GetFlagArgument ( const QString& strShortOpt, const QString& strLongOpt ); + bool GetStringArgument ( const QString& strShortOpt, const QString& strLongOpt, QString& strArg ); + bool GetNumericArgument ( const QString& strShortOpt, const QString& strLongOpt, double rRangeStart, double rRangeStop, double& rValue ); + + /************************************************ + parse bare arguments + ************************************************/ +protected: + int currentIndex; + char** currentArgv; + + void reset() + { + currentArgv = argv; + currentIndex = 0; + } + +public: + QString GetFirstArgument() + { + reset(); + // Skipping program path + return GetNextArgument(); + } + + QString GetNextArgument() + { + if ( currentIndex < argc ) + { + currentArgv++; + currentIndex++; + + if ( currentIndex < argc ) + { + return QString ( *currentArgv ); + } + } + + return QString(); + } +}; + +/******************************************************************** + defines for commandline options in the style "shortopt", "longopt" + Name is standard CMDLN_LONGOPTNAME + These defines can be used for strShortOpt, strLongOpt parameters + of the CCommandline functions. + ********************************************************************/ + +// clang-format off + +#define CMDLN_HELP "-h", "--help" +#define CMDLN_HELP2 "-?", "--help" +#define CMDLN_VERSION "-v", "--version" + +#define CMDLN_INIFILE "-i", "--inifile" +#define CMDLN_NOGUI "-n", "--nogui" +#define CMDLN_PORT "-p", "--port" +#define CMDLN_JSONRPCPORT "--jsonrpcport", "--jsonrpcport" +#define CMDLN_JSONRPCSECRETFILE "--jsonrpcsecretfile", "--jsonrpcsecretfile" +#define CMDLN_QOS "-Q", "--qos" +#define CMDLN_NOTRANSLATION "-t", "--notranslation" +#define CMDLN_ENABLEIPV6 "-6", "--enableipv6" +#define CMDLN_DISCONONQUIT "-d", "--discononquit" +#define CMDLN_DIRECTORYSERVER "-e", "--directoryserver" +#define CMDLN_DIRECTORYFILE "--directoryfile", "--directoryfile" +#define CMDLN_LISTFILTER "-f", "--listfilter" +#define CMDLN_FASTUPDATE "-F", "--fastupdate" +#define CMDLN_LOG "-l", "--log" +#define CMDLN_LICENCE "-L", "--licence" +#define CMDLN_HTMLSTATUS "-m", "--htmlstatus" +#define CMDLN_SERVERINFO "-o", "--serverinfo" +#define CMDLN_SERVERPUBLICIP "--serverpublicip", "--serverpublicip" +#define CMDLN_DELAYPAN "-P", "--delaypan" +#define CMDLN_RECORDING "-R", "--recording" +#define CMDLN_NORECORD "--norecord", "--norecord" +#define CMDLN_SERVER "-s", "--server" +#define CMDLN_SERVERBINDIP "--serverbindip", "--serverbindip" +#define CMDLN_MULTITHREADING "-T", "--multithreading" +#define CMDLN_NUMCHANNELS "-u", "--numchannels" +#define CMDLN_WELCOMEMESSAGE "-w", "--welcomemessage" +#define CMDLN_STARTMINIMIZED "-z", "--startminimized" +#define CMDLN_CONNECT "-c", "--connect" +#define CMDLN_NOJACKCONNECT "-j", "--nojackconnect" +#define CMDLN_MUTESTREAM "-M", "--mutestream" +#define CMDLN_MUTEMYOWN "--mutemyown", "--mutemyown" +#define CMDLN_CLIENTNAME "--clientname", "--clientname" +#define CMDLN_CTRLMIDICH "--ctrlmidich", "--ctrlmidich" + +// Backwards compatibility options: +#define CMDLN_CENTRALSERVER "--centralserver", "--centralserver" + +// Debug options: (not in help) +#define CMDLN_SHOWALLSERVERS "--showallservers", "--showallservers" +#define CMDLN_SHOWANALYZERCONSOLE "--showanalyzerconsole", "--showanalyzerconsole" + +// CMDLN_SPECIAL: Used for debugging, should NOT be in help, nor documented elsewhere! +// any option after --special is accepted +#define CMDLN_SPECIAL "--special", "--special" + +// Special options for sound-redesign testing +#define CMDLN_JACKINPUTS "--jackinputs", "--jackinputs" + +// clang-format on diff --git a/src/global.h b/src/global.h index 22ae0c52bf..f3d3d3860e 100644 --- a/src/global.h +++ b/src/global.h @@ -357,20 +357,3 @@ class CCustomEvent : public QEvent int iStatus; int iChanNum; }; - -/* Prototypes for global functions ********************************************/ -// command line parsing, TODO do not declare functions globally but in a class -QString UsageArguments ( char** argv ); - -bool GetFlagArgument ( char** argv, int& i, QString strShortOpt, QString strLongOpt ); - -bool GetStringArgument ( int argc, char** argv, int& i, QString strShortOpt, QString strLongOpt, QString& strArg ); - -bool GetNumericArgument ( int argc, - char** argv, - int& i, - QString strShortOpt, - QString strLongOpt, - double rRangeStart, - double rRangeStop, - double& rValue ); diff --git a/src/main.cpp b/src/main.cpp index 86a37e40e3..4988340dbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,9 +52,18 @@ extern void qt_set_sequence_auto_mnemonic ( bool bEnable ); #ifndef SERVER_ONLY # include "clientrpc.h" #endif +#include "cmdline.h" // Implementation ************************************************************** +QString UsageArguments ( char* argv ); + +void OnFatalError ( QString errMsg ) +{ + qCritical() << qUtf8Printable ( errMsg ); + exit ( 1 ); +} + int main ( int argc, char** argv ) { @@ -63,6 +72,10 @@ int main ( int argc, char** argv ) // Qt will not show these with underline characters in the GUI on MacOS. (#1873) qt_set_sequence_auto_mnemonic ( true ); #endif + CCommandline::argc = argc; + CCommandline::argv = argv; + + CCommandline cmdLine ( OnFatalError ); QString strArgument; double rDbleArgument; @@ -79,6 +92,7 @@ int main ( int argc, char** argv ) #else bool bIsClient = true; #endif + bool bSpecialOptions = false; // Any options after this option will be accepted ! (mostly used for debugging purpouses) bool bUseGUI = true; bool bStartMinimized = false; bool bShowComplRegConnList = false; @@ -134,7 +148,7 @@ int main ( int argc, char** argv ) // Help (usage) flag --------------------------------------------------- if ( ( !strcmp ( argv[i], "--help" ) ) || ( !strcmp ( argv[i], "-h" ) ) || ( !strcmp ( argv[i], "-?" ) ) ) { - const QString strHelp = UsageArguments ( argv ); + const QString strHelp = UsageArguments ( argv[0] ); std::cout << qUtf8Printable ( strHelp ); exit ( 0 ); } @@ -149,7 +163,7 @@ int main ( int argc, char** argv ) // Common options: // Initialization file ------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-i", "--inifile", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_INIFILE, strArgument ) ) { strIniFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- initialization file name: %1" ).arg ( strIniFileName ) ); @@ -158,7 +172,7 @@ int main ( int argc, char** argv ) } // Disable GUI flag ---------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-n", "--nogui" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_NOGUI ) ) { bUseGUI = false; qInfo() << "- no GUI mode chosen"; @@ -167,7 +181,7 @@ int main ( int argc, char** argv ) } // Port number --------------------------------------------------------- - if ( GetNumericArgument ( argc, argv, i, "-p", "--port", 0, 65535, rDbleArgument ) ) + if ( cmdLine.GetNumericArgument ( i, CMDLN_PORT, 0, 65535, rDbleArgument ) ) { iPortNumber = static_cast ( rDbleArgument ); bCustomPortNumberGiven = true; @@ -177,7 +191,7 @@ int main ( int argc, char** argv ) } // JSON-RPC port number ------------------------------------------------ - if ( GetNumericArgument ( argc, argv, i, "--jsonrpcport", "--jsonrpcport", 0, 65535, rDbleArgument ) ) + if ( cmdLine.GetNumericArgument ( i, CMDLN_JSONRPCPORT, 0, 65535, rDbleArgument ) ) { iJsonRpcPortNumber = static_cast ( rDbleArgument ); qInfo() << qUtf8Printable ( QString ( "- JSON-RPC port number: %1" ).arg ( iJsonRpcPortNumber ) ); @@ -186,7 +200,7 @@ int main ( int argc, char** argv ) } // JSON-RPC secret file name ------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "--jsonrpcsecretfile", "--jsonrpcsecretfile", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_JSONRPCSECRETFILE, strArgument ) ) { strJsonRpcSecretFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- JSON-RPC secret file: %1" ).arg ( strJsonRpcSecretFileName ) ); @@ -195,7 +209,7 @@ int main ( int argc, char** argv ) } // Quality of Service -------------------------------------------------- - if ( GetNumericArgument ( argc, argv, i, "-Q", "--qos", 0, 255, rDbleArgument ) ) + if ( cmdLine.GetNumericArgument ( i, CMDLN_QOS, 0, 255, rDbleArgument ) ) { iQosNumber = static_cast ( rDbleArgument ); qInfo() << qUtf8Printable ( QString ( "- selected QoS value: %1" ).arg ( iQosNumber ) ); @@ -204,7 +218,7 @@ int main ( int argc, char** argv ) } // Disable translations ------------------------------------------------ - if ( GetFlagArgument ( argv, i, "-t", "--notranslation" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_NOTRANSLATION ) ) { bUseTranslation = false; qInfo() << "- translations disabled"; @@ -213,7 +227,7 @@ int main ( int argc, char** argv ) } // Enable IPv6 --------------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-6", "--enableipv6" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_ENABLEIPV6 ) ) { bEnableIPv6 = true; qInfo() << "- IPv6 enabled"; @@ -224,7 +238,7 @@ int main ( int argc, char** argv ) // Server only: // Disconnect all clients on quit -------------------------------------- - if ( GetFlagArgument ( argv, i, "-d", "--discononquit" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_DISCONONQUIT ) ) { bDisconnectAllClientsOnQuit = true; qInfo() << "- disconnect all clients on quit"; @@ -234,7 +248,7 @@ int main ( int argc, char** argv ) } // Directory server ---------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-e", "--directoryserver", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_DIRECTORYSERVER, strArgument ) ) { strDirectoryServer = strArgument; qInfo() << qUtf8Printable ( QString ( "- directory server: %1" ).arg ( strDirectoryServer ) ); @@ -244,12 +258,7 @@ int main ( int argc, char** argv ) } // Central server ** D E P R E C A T E D ** ---------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--centralserver", // no short form - "--centralserver", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_CENTRALSERVER, strArgument ) ) { strDirectoryServer = strArgument; qInfo() << qUtf8Printable ( QString ( "- directory server: %1" ).arg ( strDirectoryServer ) ); @@ -259,12 +268,7 @@ int main ( int argc, char** argv ) } // Directory file ------------------------------------------------------ - if ( GetStringArgument ( argc, - argv, - i, - "--directoryfile", // no short form - "--directoryfile", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_DIRECTORYFILE, strArgument ) ) { strServerListFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- directory server persistence file: %1" ).arg ( strServerListFileName ) ); @@ -274,7 +278,7 @@ int main ( int argc, char** argv ) } // Server list filter -------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-f", "--listfilter", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_LISTFILTER, strArgument ) ) { strServerListFilter = strArgument; qInfo() << qUtf8Printable ( QString ( "- server list filter: %1" ).arg ( strServerListFilter ) ); @@ -284,7 +288,7 @@ int main ( int argc, char** argv ) } // Use 64 samples frame size mode -------------------------------------- - if ( GetFlagArgument ( argv, i, "-F", "--fastupdate" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_FASTUPDATE ) ) { bUseDoubleSystemFrameSize = false; // 64 samples frame size qInfo() << qUtf8Printable ( QString ( "- using %1 samples frame size mode" ).arg ( SYSTEM_FRAME_SIZE_SAMPLES ) ); @@ -294,7 +298,7 @@ int main ( int argc, char** argv ) } // Use logging --------------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-l", "--log", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_LOG, strArgument ) ) { strLoggingFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- logging file name: %1" ).arg ( strLoggingFileName ) ); @@ -304,7 +308,7 @@ int main ( int argc, char** argv ) } // Use licence flag ---------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-L", "--licence" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_LICENCE ) ) { // LT_CREATIVECOMMONS is now used just to enable the pop up eLicenceType = LT_CREATIVECOMMONS; @@ -315,7 +319,7 @@ int main ( int argc, char** argv ) } // HTML status file ---------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-m", "--htmlstatus", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_HTMLSTATUS, strArgument ) ) { strHTMLStatusFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- HTML status file name: %1" ).arg ( strHTMLStatusFileName ) ); @@ -325,7 +329,7 @@ int main ( int argc, char** argv ) } // Server info --------------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-o", "--serverinfo", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_SERVERINFO, strArgument ) ) { strServerInfo = strArgument; qInfo() << qUtf8Printable ( QString ( "- server info: %1" ).arg ( strServerInfo ) ); @@ -335,12 +339,7 @@ int main ( int argc, char** argv ) } // Server Public IP ---------------------------------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--serverpublicip", // no short form - "--serverpublicip", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_SERVERPUBLICIP, strArgument ) ) { strServerPublicIP = strArgument; qInfo() << qUtf8Printable ( QString ( "- server public IP: %1" ).arg ( strServerPublicIP ) ); @@ -350,7 +349,7 @@ int main ( int argc, char** argv ) } // Enable delay panning on startup ------------------------------------- - if ( GetFlagArgument ( argv, i, "-P", "--delaypan" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_DELAYPAN ) ) { bDelayPan = true; qInfo() << "- starting with delay panning"; @@ -360,7 +359,7 @@ int main ( int argc, char** argv ) } // Recording directory ------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-R", "--recording", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_RECORDING, strArgument ) ) { strRecordingDirName = strArgument; qInfo() << qUtf8Printable ( QString ( "- recording directory name: %1" ).arg ( strRecordingDirName ) ); @@ -370,10 +369,7 @@ int main ( int argc, char** argv ) } // Disable recording on startup ---------------------------------------- - if ( GetFlagArgument ( argv, - i, - "--norecord", // no short form - "--norecord" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_NORECORD ) ) { bDisableRecording = true; qInfo() << "- recording will not take place until enabled"; @@ -383,7 +379,7 @@ int main ( int argc, char** argv ) } // Server mode flag ---------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-s", "--server" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_SERVER ) ) { bIsClient = false; qInfo() << "- server mode chosen"; @@ -393,12 +389,7 @@ int main ( int argc, char** argv ) } // Server Bind IP -------------------------------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--serverbindip", // no short form - "--serverbindip", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_SERVERBINDIP, strArgument ) ) { strServerBindIP = strArgument; qInfo() << qUtf8Printable ( QString ( "- server bind IP: %1" ).arg ( strServerBindIP ) ); @@ -408,7 +399,7 @@ int main ( int argc, char** argv ) } // Use multithreading -------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-T", "--multithreading" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_MULTITHREADING ) ) { bUseMultithreading = true; qInfo() << "- using multithreading"; @@ -418,7 +409,7 @@ int main ( int argc, char** argv ) } // Maximum number of channels ------------------------------------------ - if ( GetNumericArgument ( argc, argv, i, "-u", "--numchannels", 1, MAX_NUM_CHANNELS, rDbleArgument ) ) + if ( cmdLine.GetNumericArgument ( i, CMDLN_NUMCHANNELS, 1, MAX_NUM_CHANNELS, rDbleArgument ) ) { iNumServerChannels = static_cast ( rDbleArgument ); @@ -430,7 +421,7 @@ int main ( int argc, char** argv ) } // Server welcome message ---------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-w", "--welcomemessage", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_WELCOMEMESSAGE, strArgument ) ) { strWelcomeMessage = strArgument; qInfo() << qUtf8Printable ( QString ( "- welcome message: %1" ).arg ( strWelcomeMessage ) ); @@ -440,7 +431,7 @@ int main ( int argc, char** argv ) } // Start minimized ----------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-z", "--startminimized" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_STARTMINIMIZED ) ) { bStartMinimized = true; qInfo() << "- start minimized enabled"; @@ -452,7 +443,7 @@ int main ( int argc, char** argv ) // Client only: // Connect on startup -------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-c", "--connect", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_CONNECT, strArgument ) ) { strConnOnStartupAddress = NetworkUtil::FixAddress ( strArgument ); qInfo() << qUtf8Printable ( QString ( "- connect on startup to address: %1" ).arg ( strConnOnStartupAddress ) ); @@ -462,7 +453,7 @@ int main ( int argc, char** argv ) } // Disabling auto Jack connections ------------------------------------- - if ( GetFlagArgument ( argv, i, "-j", "--nojackconnect" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_NOJACKCONNECT ) ) { bNoAutoJackConnect = true; qInfo() << "- disable auto Jack connections"; @@ -472,7 +463,7 @@ int main ( int argc, char** argv ) } // Mute stream on startup ---------------------------------------------- - if ( GetFlagArgument ( argv, i, "-M", "--mutestream" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_MUTESTREAM ) ) { bMuteStream = true; qInfo() << "- mute stream activated"; @@ -482,10 +473,7 @@ int main ( int argc, char** argv ) } // For headless client mute my own signal in personal mix -------------- - if ( GetFlagArgument ( argv, - i, - "--mutemyown", // no short form - "--mutemyown" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_MUTEMYOWN ) ) { bMuteMeInPersonalMix = true; qInfo() << "- mute me in my personal mix"; @@ -495,12 +483,7 @@ int main ( int argc, char** argv ) } // Client Name --------------------------------------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--clientname", // no short form - "--clientname", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_CLIENTNAME, strArgument ) ) { strClientName = strArgument; qInfo() << qUtf8Printable ( QString ( "- client name: %1" ).arg ( strClientName ) ); @@ -510,12 +493,7 @@ int main ( int argc, char** argv ) } // Controller MIDI channel --------------------------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--ctrlmidich", // no short form - "--ctrlmidich", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_CTRLMIDICH, strArgument ) ) { strMIDISetup = strArgument; qInfo() << qUtf8Printable ( QString ( "- MIDI controller settings: %1" ).arg ( strMIDISetup ) ); @@ -530,10 +508,7 @@ int main ( int argc, char** argv ) // Undocumented debugging command line argument: Show all registered // servers in the server list regardless if a ping to the server is // possible or not. - if ( GetFlagArgument ( argv, - i, - "--showallservers", // no short form - "--showallservers" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_SHOWALLSERVERS ) ) { bShowComplRegConnList = true; qInfo() << "- show all registered servers in server list"; @@ -545,10 +520,7 @@ int main ( int argc, char** argv ) // Show analyzer console ----------------------------------------------- // Undocumented debugging command line argument: Show the analyzer // console to debug network buffer properties. - if ( GetFlagArgument ( argv, - i, - "--showanalyzerconsole", // no short form - "--showanalyzerconsole" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_SHOWANALYZERCONSOLE ) ) { bShowAnalyzerConsole = true; qInfo() << "- show analyzer console"; @@ -557,14 +529,28 @@ int main ( int argc, char** argv ) continue; } + // Enable Special Options ---------------------------------------------- + if ( cmdLine.GetFlagArgument ( i, CMDLN_SPECIAL ) ) + { + bSpecialOptions = true; + qInfo() << "- Special options enabled !"; + continue; + } + // Unknown option ------------------------------------------------------ - qCritical() << qUtf8Printable ( QString ( "%1: Unknown option '%2' -- use '--help' for help" ).arg ( argv[0] ).arg ( argv[i] ) ); + // No exit for options after the "--special" option. + // Used for debugging and testing new options... + if ( !bSpecialOptions ) + { + // Unknown option ------------------------------------------------------ + qCritical() << qUtf8Printable ( QString ( "%1: Unknown option '%2' -- use '--help' for help" ).arg ( argv[0] ).arg ( argv[i] ) ); // clicking on the Mac application bundle, the actual application // is called with weird command line args -> do not exit on these #if !( defined( Q_OS_MACX ) ) - exit ( 1 ); + exit ( 1 ); #endif + } } // Dependencies ------------------------------------------------------------ @@ -1013,7 +999,7 @@ int main ( int argc, char** argv ) /******************************************************************************\ * Command Line Argument Parsing * \******************************************************************************/ -QString UsageArguments ( char** argv ) +QString UsageArguments ( char* argv ) { // clang-format off return QString ( @@ -1082,69 +1068,3 @@ QString UsageArguments ( char** argv ) ).arg( argv[0] ); // clang-format on } - -bool GetFlagArgument ( char** argv, int& i, QString strShortOpt, QString strLongOpt ) -{ - if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) - { - return true; - } - else - { - return false; - } -} - -bool GetStringArgument ( int argc, char** argv, int& i, QString strShortOpt, QString strLongOpt, QString& strArg ) -{ - if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) - { - if ( ++i >= argc ) - { - qCritical() << qUtf8Printable ( QString ( "%1: '%2' needs a string argument." ).arg ( argv[0] ).arg ( argv[i - 1] ) ); - exit ( 1 ); - } - - strArg = argv[i]; - - return true; - } - else - { - return false; - } -} - -bool GetNumericArgument ( int argc, - char** argv, - int& i, - QString strShortOpt, - QString strLongOpt, - double rRangeStart, - double rRangeStop, - double& rValue ) -{ - if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) - { - QString errmsg = "%1: '%2' needs a numeric argument from '%3' to '%4'."; - if ( ++i >= argc ) - { - qCritical() << qUtf8Printable ( errmsg.arg ( argv[0] ).arg ( argv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); - exit ( 1 ); - } - - char* p; - rValue = strtod ( argv[i], &p ); - if ( *p || ( rValue < rRangeStart ) || ( rValue > rRangeStop ) ) - { - qCritical() << qUtf8Printable ( errmsg.arg ( argv[0] ).arg ( argv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); - exit ( 1 ); - } - - return true; - } - else - { - return false; - } -}