-
Notifications
You must be signed in to change notification settings - Fork 225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding global commandline parameters #2599
Conversation
|
||
/* 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 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From now on include "cmdline.h" to access commandline parameters via the CCommandline class
void OnFatalError ( QString errMsg ) | ||
{ | ||
qCritical() << qUtf8Printable ( errMsg ); | ||
exit ( 1 ); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that OnFatalError could be used on many places in main.cpp.
qCritical() << qUtf8Printable ( ... );
exit ( 1 );
Is used in many places...
|
||
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; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions are now implemented in CCommandline.
Note that in the new implementation the
qCritical() << qUtf8Printable ( ... );
exit ( 1 );
parts are replaced by the CCommandline::onArgumentError function which can, optionally, be passed in the CCommandLine constructor, since we probably don't want the program to exit on parsing wrong (--special?) parameters.
// clicking on the Mac application bundle, the actual application | ||
// is called with weird command line args -> do not exit on these |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is true, how about all other places in main using almost the same code ?
qCritical() << qUtf8Printable ( QString (...) );
exit (1);
OnFatalError uses this code now too.
@pljones and others of the Jamulus team Could we please have some reviews here? Also my new settings implementation is now waiting on this one. |
I also have a CCommandlineOptions class ready that reads all commandline options, and checks client/server validity and ranges, |
@pljones could you review these PRs please, (I think we're missing a C++ developer/reviewer at the moment) |
Commandline parsing is now implemented in a separate class Commandline parameters now accessible anywhere in the code.
NOTE: These are needed for the upcomming CCmdlnOptions class that will read and check all commandline parameters.
47a6c66
to
3f47e54
Compare
Not sure how to deal with this. I think this is still valid. NOT closing for now. |
My view remains that settings and command line handling need to be unified and that all the handling for client and server properties (i.e. the values configured either by settings or command line) should be handled through calls to the client or server instances. This approach enables a consistent, UI-independent, development basis going forward. The CLI and GUI - and RPC interface - would be sharing common code for client and server. Where client and server needed common code, that would be separated out. It does mean a lot more work rearchitecting Jamulus, however. |
I still think that this PR is a good starting point. We'd include the config file parsing in the provided class. |
I must disagree, since the inifile is read before any module is initialized there should be no calls to the modules from reading the inifile but the modules should request the inifile values at their initialization! |
oops accidentally closed... |
This requires the client and server to know about the inifile, if you're explaining yourself correctly. I'm suggesting that the client and server know about settings and they "own" their own settings in the sense that any read or update goes through a client or server call. The implementation details (getting those changes to backing store) should, naturally, be independent. Naming the inifile would come from parsing the command line. Loading the inifile would come next. Instantiating the client or server would come next, passing the settings (the combined inifile and command line values). Updates to settings would not immediately trigger an update to the inifile, because we don't want interupts when in real time flows, so any disruption should be minimized. We should honour any request to save state from Qt and make sure that's definitely happened on exit. (This remains subject to:
|
I suggest we have a commandline class that reads commandline values and an inifile class containing 3 classes: app_settings, server_settings and client_settings. First the commandline class parses the commandline and store these values. This comnandline class is passed to the inifile class which then reads the inifile values Then the app is initialised using app_settings and client/server is initialised using their setting classes app, client and server retrieve their settings by calls to their settings class, which will apply any commandline overrides. app, client and server can update their settings by calls to the matching settings class during runtime. At app closing the settings class writes out the new inifile using the stored settings if there where any changes. |
I'd rename the commandline class to config as it's not just saving the CLI. |
It should just parse the CLI! And config is way more than the commandline so it would be more logical if "inifile" was named config as it should contain all configurable settings (inifile as well as commandline). The commandline can also contain commandline only (i.e. server/client, gui/nogui, logging, debugging) parameters and, as so, it should be a separate class accessible anywhere. |
Hmm. I mean in the end having one class serving the whole configuration state/providing access to CLI/GUI/Commandline would be beneficial as this allows logical separation. Do you think that's an issue? |
Why putting everything in one class? I think separate classes are the perfect way to keep things organised, also they can be defined at different, logical locations. Though I still think "commandline" and "inifile" should be different instances since the commandline should be parsed before the other instances are created, but even then "config" could be a class containing commandline and inifile... P.S. Shouldn't we discuss this in another topic ? |
Yes. Probably in #609 |
Setting to draft as branch needs conflict resolution. |
|
||
bool CCommandline::GetStringArgument ( const QString& strShortOpt, const QString& strLongOpt, QString& strArg ) | ||
{ | ||
for ( int i = 1; i < argc; i++ ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Best case would be some kind of hash table/set to have a match in O(1). But that's just thinking out loudly
Closing for now. The ideas are still present. |
Short description of changes
Commandline parsing is now implemented in a separate class
Commandline parameters now accessible anywhere in the code.
CHANGELOG: Refactoring: Commandline parameters are now accessible anywhere in the code via the CCommandline class.
Context: Fixes an issue?
General improvement and preparation for sound-redesign.
Does this change need documentation? What needs to be documented and how?
No documentation changes required.
Status of this Pull Request
What is missing until this pull request can be merged?
Checklist