Skip to content

Commit

Permalink
An option to load config file from command line (#401)
Browse files Browse the repository at this point in the history
* Added an option to load config file in command line. This give flexibility to load config file in any location, not just the hardcoded file path.
  • Loading branch information
aregtech authored Oct 19, 2024
1 parent 34bb738 commit 253a379
Show file tree
Hide file tree
Showing 17 changed files with 227 additions and 118 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ jobs:
run: |
mkdir ./${{matrix.config.name}}/
cp -R ./${{env.BUILD_DEST}}/bin/ ./${{matrix.config.name}}/
cp -R {{env.INSTALL_DEST}} ./${{matrix.config.name}}/
cp -R ./${{env.INSTALL_DEST}}/ ./${{matrix.config.name}}/
- name: Upload artifacts if tests fail. Ignore if unit tests are not compiled
if: failure() && matrix.config.test == 'ON'
Expand Down
12 changes: 11 additions & 1 deletion framework/aregextend/console/OptionParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ class OptionParser
* \return Returns true if succeeded to parse without error.
* Otherwise, returns false.
**/
bool parseCommandLine( const char ** cmdLine, uint32_t count);
bool parseCommandLine( const char ** cmdLine, uint32_t count );
bool parseCommandLine( const wchar_t ** cmdLine, uint32_t count );
bool parseCommandLine( char** IN cmdLine, uint32_t count);
bool parseCommandLine( wchar_t** IN cmdLine, uint32_t count);
Expand All @@ -430,6 +430,16 @@ class OptionParser
**/
bool parseOptions( StrList & optList );

/**
* \brief Searches in the command list the option of specified ID.
* Returns valid index if found the option.
* Otherwise, returns invalid index (NECommon::INVALID_POSITION).
* \param optId The ID of an option to search in list.
* \return Returns valid index if found an option with specified ID.
* Otherwise, returns invalid index (NECommon::INVALID_POSITION).
**/
uint32_t findOption(int optId) const;

/**
* \ brief Returns the list of parsed options.
**/
Expand Down
17 changes: 16 additions & 1 deletion framework/aregextend/console/private/OptionParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ namespace
optList.push_back( str );
}
}
}
} // namespace

const OptionParser::sOptionSetup OptionParser::getDefaultOptionSetup( void )
{
Expand Down Expand Up @@ -389,6 +389,21 @@ bool OptionParser::parseOptions( StrList & optList )
return result;
}

uint32_t OptionParser::findOption(int optId) const
{
uint32_t result{ NECommon::INVALID_POSITION };
for (uint32_t i = 0; i < mInputOptions.getSize(); ++i)
{
if (mInputOptions.getAt(i).inCommand == optId)
{
result = i;
break;
}
}

return result;
}

OptionParser::sOption OptionParser::_setupInput( bool isShort, String cmdLine, uint32_t refSetup )
{
ASSERT( (refSetup >= 0) && (refSetup < mSetupOptions.getSize()) );
Expand Down
59 changes: 33 additions & 26 deletions framework/aregextend/service/NESystemService.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,18 @@ namespace NESystemService
* \brief NESystemService::eServiceOption
* Message routing service options.
**/
enum class eServiceOption
enum class eServiceOption : int32_t
{
CMD_Undefined //!< Option is undefined.
, CMD_Console //!< Option is to execute process as console application.
, CMD_Help //!< Option is to display help on console.
, CMD_Load //!< Option is to start the process and load configuration from specified file
, CMD_Install //!< Option is to install (register) service in the system.
, CMD_Uninstall //!< Option is to uninstall (unregister) service in the system.
, CMD_Service //!< Option is to execute process as a system service (in background).
, CMD_Console //!< Option is to execute process as console application.
, CMD_Uninstall //!< Option is to uninstall (unregister) service in the system.
, CMD_Verbose //!< Option is to display the data rate when execute process as console application.
, CMD_Help //!< Option is to display help on console.

, CMD_Custom //!< No option, reserved for the custom options.
};

/**
Expand All @@ -54,27 +57,29 @@ namespace NESystemService
**/
const OptionParser::sOptionSetup ServiceOptionSetup[ ]
{
//!< Default command.
{ "" , "" , static_cast<int>(eServiceOption::CMD_Console) , OptionParser::NO_DATA, {}, {}, {} }
//!< Command to install service. Valid for Windows OS, ignored in other cases.
, { "-i", "--install" , static_cast<int>(eServiceOption::CMD_Install) , OptionParser::NO_DATA, {}, {}, {} }
//!< Command to uninstall service. Valid for Windows OS, ignored in other cases.
, { "-u", "--uninstall", static_cast<int>(eServiceOption::CMD_Uninstall) , OptionParser::NO_DATA, {}, {}, {} }
//!< Command to run process as a system service process.
, { "-s", "--service" , static_cast<int>(eServiceOption::CMD_Service) , OptionParser::NO_DATA, {}, {}, {} }
//!< Command to run process as a console application.
, { "-c", "--console" , static_cast<int>(eServiceOption::CMD_Console) , OptionParser::NO_DATA, {}, {}, {} }
//!< Command to display data rate when run as console application.
, { "-v", "--verbose" , static_cast<int>(eServiceOption::CMD_Verbose) , OptionParser::NO_DATA, {}, {}, {} }
//!< Command to display help on console.
, { "-h", "--help" , static_cast<int>(eServiceOption::CMD_Help) , OptionParser::NO_DATA, {}, {}, {} }
//!< Default command.
{ "" , "" , static_cast<int>(eServiceOption::CMD_Console) , OptionParser::NO_DATA , {}, {}, {} }
//!< Command to run process as a console application.
, { "-c", "--console" , static_cast<int>(eServiceOption::CMD_Console) , OptionParser::NO_DATA , {}, {}, {} }
//!< Command to display help on console.
, { "-h", "--help" , static_cast<int>(eServiceOption::CMD_Help) , OptionParser::NO_DATA , {}, {}, {} }
//!< Command to display the error message.
, { "-l", "--load" , static_cast<int>(eServiceOption::CMD_Load) , OptionParser::STRING_NO_RANGE , {}, {}, {} }
//!< Command to install service. Valid for Windows OS, ignored in other cases.
, { "-i", "--install" , static_cast<int>(eServiceOption::CMD_Install) , OptionParser::NO_DATA , {}, {}, {} }
//!< Command to run process as a system service process.
, { "-s", "--service" , static_cast<int>(eServiceOption::CMD_Service) , OptionParser::NO_DATA , {}, {}, {} }
//!< Command to uninstall service. Valid for Windows OS, ignored in other cases.
, { "-u", "--uninstall" , static_cast<int>(eServiceOption::CMD_Uninstall) , OptionParser::NO_DATA , {}, {}, {} }
//!< Command to display data rate when run as console application.
, { "-v", "--verbose" , static_cast<int>(eServiceOption::CMD_Verbose) , OptionParser::NO_DATA , {}, {}, {} }
};

/**
* \brief NESystemService::eSystemServiceState
* Describes the system service state.
**/
enum class eSystemServiceState
enum class eSystemServiceState : int32_t
{
ServiceStopped //!< Service is stopped.
, ServiceStarting //!< Service is in starting process.
Expand Down Expand Up @@ -189,18 +194,20 @@ inline const char * NESystemService::getString( NESystemService::eServiceOption
{
case NESystemService::eServiceOption::CMD_Undefined:
return "NESystemService::CMD_Undefined";
case NESystemService::eServiceOption::CMD_Console:
return "NESystemService::CMD_Console";
case NESystemService::eServiceOption::CMD_Help:
return "NESystemService::CMD_Help";
case NESystemService::eServiceOption::CMD_Load:
return "NESystemService::CMD_Load";
case NESystemService::eServiceOption::CMD_Install:
return "NESystemService::CMD_Install";
case NESystemService::eServiceOption::CMD_Uninstall:
return "NESystemService::CMD_Uninstall";
case NESystemService::eServiceOption::CMD_Service:
return "NESystemService::CMD_Service";
case NESystemService::eServiceOption::CMD_Console:
return "NESystemService::CMD_Console";
case NESystemService::eServiceOption::CMD_Uninstall:
return "NESystemService::eServiceOption::CMD_Uninstall";
case NESystemService::eServiceOption::CMD_Verbose:
return "NESystemService::CMD_Verbose";
case NESystemService::eServiceOption::CMD_Help:
return "NESystemService::eServiceOption::CMD_Help";
return "NESystemService::eServiceOption::CMD_Verbose";
default:
ASSERT( false );
return "ERR: Unexpected NESystemService::eServiceOption value!";
Expand Down
5 changes: 4 additions & 1 deletion framework/aregextend/service/ServiceApplicationBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ class ServiceApplicationBase : public SystemServiceBase
private:

/**
* \brief OS specific validity check of logger service.
* \brief OS specific validity check of the service.
**/
bool _osIsValid( void ) const;

Expand All @@ -270,6 +270,9 @@ class ServiceApplicationBase : public SystemServiceBase
**/
void _osFreeResources( void );

/**
* \brief OS specific initialization of the service.
**/
bool _osInitializeService( void );

/**
Expand Down
4 changes: 4 additions & 0 deletions framework/aregextend/service/SystemServiceBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,10 @@ class SystemServiceBase
* \brief OS specific service manager handle.
**/
void * mSeMHandle;
/**
* \brief The relative or full path to the configuration file. By default, NEApplication::DEFAULT_CONFIG_FILE
**/
String mFileConfig;

//////////////////////////////////////////////////////////////////////////
// Forbidden calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ ServiceApplicationBase::ServiceApplicationBase(ServiceCommunicatonBase& commBase
int ServiceApplicationBase::serviceMain(int argc, char** argv)
{
int result{ RESULT_SUCCEEDED };
Application::setWorkingDirectory(nullptr);
if (parseOptions(argc, argv, NESystemService::ServiceOptionSetup, MACRO_ARRAYLEN(NESystemService::ServiceOptionSetup)) == false)
{
resetDefaultOptions();
Expand All @@ -56,6 +57,7 @@ int ServiceApplicationBase::serviceMain(int argc, char** argv)
break;

case NESystemService::eServiceOption::CMD_Service: // fall through
case NESystemService::eServiceOption::CMD_Load: // fall through
case NESystemService::eServiceOption::CMD_Console:
result = SystemServiceBase::serviceMain(static_cast<int>(argc), argv);
mCommunication.waitToComplete();
Expand All @@ -82,7 +84,7 @@ bool ServiceApplicationBase::serviceInitialize(int /* argc */, char** /* argv */
, false
, true
, false
, NEApplication::DEFAULT_CONFIG_FILE.data()
, mFileConfig.isEmpty() ? NEApplication::DEFAULT_CONFIG_FILE.data() : mFileConfig.getString()
, static_cast<IEConfigurationListener*>(this));
return _osInitializeService();
}
Expand Down
50 changes: 42 additions & 8 deletions framework/aregextend/service/private/SystemServiceBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
************************************************************************/
#include "aregextend/service/SystemServiceBase.hpp"

#include "areg/appbase/Application.hpp"
#include "areg/base/File.hpp"
#include "areg/trace/GETrace.h"
#include "aregextend/console/Console.hpp"

Expand All @@ -33,12 +35,14 @@ SystemServiceBase::SystemServiceBase( ServiceCommunicatonBase & commBase )
, mSystemServiceOption ( NESystemService::DEFAULT_OPTION )
, mSvcHandle ( nullptr )
, mSeMHandle ( nullptr )
, mFileConfig ( NEApplication::DEFAULT_CONFIG_FILE )
{
}

void SystemServiceBase::resetDefaultOptions(void)
{
mSystemServiceOption = NESystemService::DEFAULT_OPTION;
mFileConfig = NEApplication::DEFAULT_CONFIG_FILE;
mCommunication.enableCalculateDataRate(NESystemService::DEFAULT_VERBOSE);
}

Expand All @@ -49,7 +53,7 @@ bool SystemServiceBase::parseOptions( int argc, const char ** argv, const Option
if (argc > 1)
{
OptionParser parser(optSetup, optCount);
if (parser.parseCommandLine(static_cast<const char**>(argv), argc > 1 ? static_cast<uint32_t>(argc) : 0))
if (parser.parseCommandLine(argv, argc > 1 ? static_cast<uint32_t>(argc) : 0))
{
result = prepareOptions(parser.getOptions());
}
Expand All @@ -70,8 +74,28 @@ bool SystemServiceBase::parseOptions( int argc, const char ** argv, const Option

bool SystemServiceBase::parseOptions(int argc, char** argv, const OptionParser::sOptionSetup* optSetup, uint32_t optCount)
{
const char* temp{ argv != nullptr ? static_cast<const char*>(*argv) : nullptr };
return (temp != nullptr ? parseOptions(argc, &temp, optSetup, optCount) : false);
bool result{ false };

if (argc > 1)
{
OptionParser parser(optSetup, optCount);
if (parser.parseCommandLine(argv, argc > 1 ? static_cast<uint32_t>(argc) : 0))
{
result = prepareOptions(parser.getOptions());
}
else
{
printHelp(true);
result = false;
}
}
else if (argc == 1)
{
resetDefaultOptions();
result = true;
}

return result;
}

bool SystemServiceBase::prepareOptions(const OptionParser::InputOptionList& opts)
Expand All @@ -84,14 +108,25 @@ bool SystemServiceBase::prepareOptions(const OptionParser::InputOptionList& opts
const OptionParser::sOption& opt = opts[i];
switch (static_cast<NESystemService::eServiceOption>(opt.inCommand))
{
case NESystemService::eServiceOption::CMD_Install:
case NESystemService::eServiceOption::CMD_Uninstall:
case NESystemService::eServiceOption::CMD_Service:
case NESystemService::eServiceOption::CMD_Console:
case NESystemService::eServiceOption::CMD_Install: // fall through
case NESystemService::eServiceOption::CMD_Uninstall:// fall through
case NESystemService::eServiceOption::CMD_Service: // fall through
case NESystemService::eServiceOption::CMD_Console: // fall through
result = true;
setCurrentOption(static_cast<NESystemService::eServiceOption>(opt.inCommand));
break;

case NESystemService::eServiceOption::CMD_Load:
{
result = true;
String filePath(opt.inString[0]);
if (File::existFile(filePath))
{
mFileConfig = filePath;
}
}
break;

case NESystemService::eServiceOption::CMD_Verbose:
mCommunication.enableCalculateDataRate(true);
setCurrentOption(NESystemService::eServiceOption::CMD_Console);
Expand Down Expand Up @@ -122,7 +157,6 @@ bool SystemServiceBase::prepareOptions(const OptionParser::InputOptionList& opts
int SystemServiceBase::serviceMain( int argc, char ** argv )
{
int result{ RESULT_SUCCEEDED };

if (serviceInitialize(argc, argv))
{
TRACE_SCOPE( utilities_service_base_SystemServiceBase_serviceMain );
Expand Down
5 changes: 3 additions & 2 deletions framework/areglogger.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>areglogger/resources/areglogger.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(ConfigShortName)'=='Release'">
Expand All @@ -51,10 +52,10 @@
<Text Include="areglogger\client\private\CMakeLists.txt" />
</ItemGroup>
<ItemGroup>
<None Include="areglogger\resources\areglogger.def" />
<ResourceCompile Include="areglogger\resources\areglogger.rc" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="areglogger\resources\areglogger.rc" />
<None Include="areglogger\resources\areglogger.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down
10 changes: 5 additions & 5 deletions framework/areglogger.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@
</Text>
<Text Include="areglogger\CMakeLists.txt" />
</ItemGroup>
<ItemGroup>
<None Include="areglogger\resources\areglogger.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="areglogger\resources\areglogger.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="areglogger\resources\areglogger.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>
6 changes: 3 additions & 3 deletions framework/areglogger/client/private/LogObserverApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@

// Use these options if compile for Windows with MSVC
#ifdef WINDOWS
#pragma comment(lib, "areg")
#pragma comment(lib, "aregextend")
#pragma comment(lib, "areg.lib")
#pragma comment(lib, "aregextend.lib")

#if defined(USE_SQLITE_PACKAGE) && (USE_SQLITE_PACKAGE != 0)
#pragma comment(lib, "sqlite3")
#else // defined(USE_SQLITE_PACKAGE) && (USE_SQLITE_PACKAGE != 0)
#pragma comment(lib, "aregsqlite3")
#pragma comment(lib, "aregsqlite3.lib")
#endif //defined(USE_SQLITE_PACKAGE) && (USE_SQLITE_PACKAGE != 0)
#endif // WINDOWS

Expand Down
Loading

0 comments on commit 253a379

Please sign in to comment.