better command line argument parsing, added command line argument to specify init file location

This commit is contained in:
Volker Fischer 2007-09-09 09:50:22 +00:00
parent d49a2b2731
commit aedf6202bd
4 changed files with 205 additions and 61 deletions

View file

@ -161,6 +161,12 @@ public:
/* Prototypes for global functions ********************************************/ /* Prototypes for global functions ********************************************/
// command line parsing, TODO do not declare functions globally but in a class
std::string UsageArguments ( char **argv );
bool GetFlagArgument ( int, char **argv, int &i, std::string strShortOpt, std::string strLongOpt );
bool GetStringArgument ( int argc, char **argv, int &i, std::string strShortOpt, std::string strLongOpt, std::string & strArg );
bool GetNumericArgument ( int argc, char **argv, int &i, std::string strShortOpt, std::string strLongOpt, double rRangeStart, double rRangeStop, double & rValue);
// posting a window message // posting a window message
void PostWinMessage ( const _MESSAGE_IDENT MessID, const int iMessageParam = 0, void PostWinMessage ( const _MESSAGE_IDENT MessID, const int iMessageParam = 0,
const int iChanNum = 0 ); const int iChanNum = 0 );

View file

@ -23,6 +23,7 @@
\******************************************************************************/ \******************************************************************************/
#include <qapplication.h> #include <qapplication.h>
#include <iostream>
#include "global.h" #include "global.h"
#include "llconclientdlg.h" #include "llconclientdlg.h"
#include "llconserverdlg.h" #include "llconserverdlg.h"
@ -36,72 +37,103 @@ QApplication* pApp = NULL;
int main ( int argc, char** argv ) int main ( int argc, char** argv )
{ {
std::string strArgument;
/* check if server or client application shall be started */ /* check if server or client application shall be started */
bool bIsClient = true; bool bIsClient = true;
bool bUseGUI = true; bool bUseGUI = true;
bool bUseServerLogging = false; bool bUseServerLogging = false;
std::string strIniFileName = "";
/* QT docu: argv()[0] is the program name, argv()[1] is the first /* QT docu: argv()[0] is the program name, argv()[1] is the first
argument and argv()[argc()-1] is the last argument */ argument and argv()[argc()-1] is the last argument.
if ( argc > 1 ) Start with first argument, therefore "i = 1" */
{ for ( int i = 1; i < argc; i++ )
std::string strShortOpt; {
/* Server mode flag ------------------------------------------------------- */
if ( GetFlagArgument ( argc, argv, i, "-s", "--server" ) == TRUE )
{
bIsClient = false;
/* "-s": start server with GUI enabled */ cerr << "server ";
strShortOpt = "-s";
if ( !strShortOpt.compare ( argv[1] ) )
{
bIsClient = false;
}
/* "-sn": start server with GUI disabled (no GUI used) */ continue;
strShortOpt = "-sn"; }
if ( !strShortOpt.compare ( argv[1] ) )
{
bIsClient = false;
bUseGUI = false;
}
/* "-sln": start server with GUI disabled and logging enabled */ /* Use GUI flag ----------------------------------------------------------- */
strShortOpt = "-sln"; if ( GetFlagArgument ( argc, argv, i, "-n", "--nogui" ) == TRUE )
if ( !strShortOpt.compare ( argv[1] ) ) {
{ bUseGUI = false;
bIsClient = false;
bUseGUI = false; cerr << "nogui ";
bUseServerLogging = true;
} continue;
} }
/* Use logging flag ------------------------------------------------------- */
if ( GetFlagArgument ( argc, argv, i, "-l", "--log" ) == TRUE )
{
bUseServerLogging = true;
cerr << "logging ";
continue;
}
/* Initialization file ---------------------------------------------------- */
if ( GetStringArgument ( argc, argv, i, "-i", "--inifile", strArgument ) == TRUE )
{
strIniFileName = strArgument;
continue;
}
/* Help (usage) flag ------------------------------------------------------ */
if ( ( !strcmp ( argv[i], "--help" ) ) ||
( !strcmp ( argv[i], "-h" ) ) || ( !strcmp ( argv[i], "-?" ) ) )
{
const std::string strHelp = UsageArguments(argv);
cerr << strHelp;
exit ( 1 );
}
/* Unknown option --------------------------------------------------------- */
cerr << argv[0] << ": ";
cerr << "Unknown option '" << argv[i] << "' -- use '--help' for help"
<< endl;
exit ( 1 );
}
/* Application object */ /* Application object */
QApplication app ( argc, argv, bUseGUI ); QApplication app ( argc, argv, bUseGUI );
if ( bIsClient ) if ( bIsClient )
{ {
/* client */ // client
// actual client object // actual client object
CClient Client; CClient Client;
// load settings from init-file // load settings from init-file
CSettings Settings ( &Client ); CSettings Settings ( &Client );
Settings.Load (); Settings.Load ( strIniFileName );
// GUI object // GUI object
CLlconClientDlg ClientDlg ( &Client, 0, 0, FALSE, Qt::WStyle_MinMax ); CLlconClientDlg ClientDlg ( &Client, 0, 0, FALSE, Qt::WStyle_MinMax );
/* Set main window */ // set main window
app.setMainWidget ( &ClientDlg ); app.setMainWidget ( &ClientDlg );
pApp = &app; /* Needed for post-event routine */ pApp = &app; // Needed for post-event routine
/* Show dialog */ // show dialog
ClientDlg.show(); ClientDlg.show();
app.exec(); app.exec();
/* Save settings to init-file */ // save settings to init-file
Settings.Save(); Settings.Save ( strIniFileName );
} }
else else
{ {
/* server */ // server
// actual server object // actual server object
CServer Server ( bUseServerLogging ); CServer Server ( bUseServerLogging );
@ -111,11 +143,11 @@ int main ( int argc, char** argv )
CLlconServerDlg ServerDlg ( &Server, 0, 0, FALSE, CLlconServerDlg ServerDlg ( &Server, 0, 0, FALSE,
Qt::WStyle_MinMax ); Qt::WStyle_MinMax );
/* Set main window */ // set main window
app.setMainWidget ( &ServerDlg ); app.setMainWidget ( &ServerDlg );
pApp = &app; /* Needed for post-event routine */ pApp = &app; // needed for post-event routine
/* Show dialog */ // show dialog
ServerDlg.show(); ServerDlg.show();
app.exec(); app.exec();
} }
@ -130,16 +162,106 @@ int main ( int argc, char** argv )
return 0; return 0;
} }
/******************************************************************************\
* Command Line Argument Parsing *
\******************************************************************************/
std::string UsageArguments ( char **argv )
{
return
"Usage: " + std::string ( argv[0] ) + " [option] [argument]\n"
"Recognized options:\n"
" -s, --server start server\n"
" -n, --nogui disable GUI (only avaiable for server)\n"
" -l, --log enable logging\n"
" -i, --inifile initialization file name (only available for client)\n"
" -h, -?, --help this help text\n"
"Example: " + std::string ( argv[0] ) + " -l -inifile myinifile.ini\n";
}
bool GetFlagArgument ( int, char **argv, int &i,
std::string strShortOpt, std::string strLongOpt )
{
if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) )
{
return true;
}
else
{
return false;
}
}
bool GetStringArgument ( int argc, char **argv, int &i,
std::string strShortOpt, std::string strLongOpt,
std::string & strArg )
{
if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) )
{
if ( ++i >= argc )
{
cerr << argv[0] << ": ";
cerr << "'" << strLongOpt << "' needs a string argument" << endl;
exit ( 1 );
}
strArg = argv[i];
return true;
}
else
{
return false;
}
}
bool GetNumericArgument ( int argc, char **argv, int &i,
std::string strShortOpt, std::string strLongOpt,
double rRangeStart, double rRangeStop,
double & rValue)
{
if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) )
{
if ( ++i >= argc )
{
cerr << argv[0] << ": ";
cerr << "'" << strLongOpt << "' needs a numeric argument between "
<< rRangeStart << " and " << rRangeStop << endl;
exit ( 1 );
}
char *p;
rValue = strtod ( argv[i], &p );
if ( *p || rValue < rRangeStart || rValue > rRangeStop )
{
cerr << argv[0] << ": ";
cerr << "'" << strLongOpt << "' needs a numeric argument between "
<< rRangeStart << " and " << rRangeStop << endl;
exit ( 1 );
}
return true;
}
else
{
return false;
}
}
/******************************************************************************\
* Window Message System *
\******************************************************************************/
void PostWinMessage ( const _MESSAGE_IDENT MessID, const int iMessageParam, void PostWinMessage ( const _MESSAGE_IDENT MessID, const int iMessageParam,
const int iChanNum ) const int iChanNum )
{ {
/* In case of simulation no events should be generated */ // first check if application is initialized
if ( pApp != NULL ) if ( pApp != NULL )
{ {
CLlconEvent* LlconEv = CLlconEvent* LlconEv =
new CLlconEvent ( MessID, iMessageParam, iChanNum ); new CLlconEvent ( MessID, iMessageParam, iChanNum );
/* Qt will delete the event object when done */ // Qt will delete the event object when done
QThread::postEvent ( pApp->mainWidget(), LlconEv ); QThread::postEvent ( pApp->mainWidget(), LlconEv );
} }
} }

View file

@ -26,28 +26,36 @@
/* Implementation *************************************************************/ /* Implementation *************************************************************/
void CSettings::Load() void CSettings::Load ( std::string sFileName )
{ {
/* load settings from init-file */ /* load settings from init-file */
ReadIniFile(); ReadIniFile ( sFileName );
} }
void CSettings::Save() void CSettings::Save ( std::string sFileName )
{ {
/* write settings in init-file */ /* write settings in init-file */
WriteIniFile(); WriteIniFile ( sFileName );
} }
/* Read and write init-file ***************************************************/ /* Read and write init-file ***************************************************/
void CSettings::ReadIniFile() void CSettings::ReadIniFile ( std::string sFileName )
{ {
int iValue; int iValue;
bool bValue; bool bValue;
INIFile ini;
/* Load data from init-file */ // load data from init-file
INIFile ini = LoadIni ( LLCON_INIT_FILE_NAME ); if ( !sFileName.empty() )
{
ini = LoadIni ( sFileName.c_str() );
}
else
{
// use default file name
ini = LoadIni ( LLCON_INIT_FILE_NAME );
}
// IP address // IP address
pClient->strIPAddress = GetIniSetting ( ini, "Client", "ipaddress" ); pClient->strIPAddress = GetIniSetting ( ini, "Client", "ipaddress" );
@ -104,7 +112,7 @@ void CSettings::ReadIniFile()
} }
} }
void CSettings::WriteIniFile() void CSettings::WriteIniFile ( std::string sFileName )
{ {
INIFile ini; INIFile ini;
@ -139,8 +147,16 @@ void CSettings::WriteIniFile()
SetNumericIniSet ( ini, "Client", "netwbusifactout", pClient->GetNetwBufSizeFactOut() ); SetNumericIniSet ( ini, "Client", "netwbusifactout", pClient->GetNetwBufSizeFactOut() );
/* Save settings in init-file */ // save settings in init-file
SaveIni ( ini, LLCON_INIT_FILE_NAME ); if ( !sFileName.empty() )
{
SaveIni ( ini, sFileName.c_str() );
}
else
{
// use default file name
SaveIni ( ini, LLCON_INIT_FILE_NAME );
}
} }
bool CSettings::GetNumericIniSet ( INIFile& theINI, string strSection, bool CSettings::GetNumericIniSet ( INIFile& theINI, string strSection,

View file

@ -47,12 +47,12 @@ class CSettings
public: public:
CSettings ( CClient* pNCliP ) : pClient ( pNCliP ) {} CSettings ( CClient* pNCliP ) : pClient ( pNCliP ) {}
void Load(); void Load ( std::string sFileName = "" );
void Save(); void Save ( std::string sFileName = "" );
protected: protected:
void ReadIniFile(); void ReadIniFile ( std::string sFileName );
void WriteIniFile(); void WriteIniFile ( std::string sFileName );
// function declarations for stlini code written by Robert Kesterson // function declarations for stlini code written by Robert Kesterson
struct StlIniCompareStringNoCase struct StlIniCompareStringNoCase