Improve cxxopts usage to avoid segfaults
This commit is contained in:
@@ -10,7 +10,26 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
std::optional<cxxopts::ParseResult> ExtractArgs(int argc, char ** argv)
|
||||
struct CommandlineParameters
|
||||
{
|
||||
CommandlineParameters(std::string const & serialDevicePath, std::string const & databaseConnectionString)
|
||||
: DeviceType(serialDevicePath), DatabaseConnectionString(databaseConnectionString) { };
|
||||
|
||||
std::string DeviceType;
|
||||
std::string DatabaseConnectionString;
|
||||
};
|
||||
|
||||
std::optional<std::string> TryGetStringArgument(cxxopts::ParseResult const & parseResult, std::string const & name)
|
||||
{
|
||||
if(!parseResult.contains(name))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return parseResult[name].as_optional<std::string>();
|
||||
}
|
||||
|
||||
std::optional<CommandlineParameters> TryGetCommandlineArguments(int argc, char ** argv)
|
||||
{
|
||||
cxxopts::Options options(
|
||||
"electricity-logger",
|
||||
@@ -24,22 +43,25 @@ std::optional<cxxopts::ParseResult> ExtractArgs(int argc, char ** argv)
|
||||
"Path to the sqlite3 database file",
|
||||
cxxopts::value<std::string>());
|
||||
|
||||
if(argc == 1)
|
||||
{
|
||||
std::cout << options.help() << std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto const parsed = options.parse(argc, argv);
|
||||
return parsed;
|
||||
auto const parseResult = options.parse(argc, argv);
|
||||
auto const serialDevicePath = TryGetStringArgument(parseResult, "serial-device");
|
||||
auto const databaseConnectionString = TryGetStringArgument(parseResult, "connection-string");
|
||||
|
||||
if(serialDevicePath.has_value() && databaseConnectionString.has_value())
|
||||
{
|
||||
return CommandlineParameters(serialDevicePath.value(), databaseConnectionString.value());
|
||||
}
|
||||
}
|
||||
catch(cxxopts::exceptions::exception const & e)
|
||||
{
|
||||
spdlog::error(e.what());
|
||||
return {};
|
||||
}
|
||||
|
||||
std::cout << options.help() << std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
DSMR::Data ReadData(std::string const & devicePath)
|
||||
@@ -100,18 +122,15 @@ DSMR::Data ReadData(std::string const & devicePath)
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
auto const maybeArgs = ExtractArgs(argc, argv);
|
||||
if(!maybeArgs.has_value())
|
||||
auto const parameters = TryGetCommandlineArguments(argc, argv);
|
||||
if(!parameters.has_value())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto const & args = maybeArgs.value();
|
||||
auto const data = ReadData(parameters->DeviceType);
|
||||
|
||||
auto const data = ReadData(args["serial-device"].as<std::string>());
|
||||
|
||||
auto const connectionStringValue = args["connection-string"].as<std::string>();
|
||||
Database db(connectionStringValue);
|
||||
Database db(parameters->DatabaseConnectionString);
|
||||
db.Insert(data, std::time(nullptr));
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -21,7 +21,43 @@ namespace detail
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<cxxopts::ParseResult> ExtractArgs(int argc, char ** argv)
|
||||
struct CommandlineParameters
|
||||
{
|
||||
CommandlineParameters(
|
||||
std::string const & deviceType,
|
||||
std::string const & deviceUrl,
|
||||
unsigned const deviceFetchTimeOut,
|
||||
std::string const & databaseConnectionString)
|
||||
: DeviceType(deviceType), DeviceUrl(deviceUrl), DeviceFetchTimeOut(deviceFetchTimeOut),
|
||||
DatabaseConnectionString(databaseConnectionString) { };
|
||||
|
||||
std::string DeviceType;
|
||||
std::string DeviceUrl;
|
||||
unsigned DeviceFetchTimeOut;
|
||||
std::string DatabaseConnectionString;
|
||||
};
|
||||
|
||||
std::optional<std::string> TryGetStringArgument(cxxopts::ParseResult const & parseResult, std::string const & name)
|
||||
{
|
||||
if(!parseResult.contains(name))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return parseResult[name].as_optional<std::string>();
|
||||
}
|
||||
|
||||
std::optional<unsigned> TryGetUnsignedArgument(cxxopts::ParseResult const & parseResult, std::string const & name)
|
||||
{
|
||||
if(!parseResult.contains(name))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return parseResult[name].as_optional<unsigned>();
|
||||
}
|
||||
|
||||
std::optional<CommandlineParameters> TryGetCommandlineArguments(int argc, char ** argv)
|
||||
{
|
||||
cxxopts::Options options(
|
||||
"solar-logger",
|
||||
@@ -49,14 +85,30 @@ std::optional<cxxopts::ParseResult> ExtractArgs(int argc, char ** argv)
|
||||
|
||||
try
|
||||
{
|
||||
auto const parsed = options.parse(argc, argv);
|
||||
return parsed;
|
||||
auto const parseResult = options.parse(argc, argv);
|
||||
auto const deviceType = TryGetStringArgument(parseResult, "type");
|
||||
auto const deviceUrl = TryGetStringArgument(parseResult, "url");
|
||||
auto const deviceFetchTimeOut = TryGetUnsignedArgument(parseResult, "timeout");
|
||||
auto const databaseConnectionString = TryGetStringArgument(parseResult, "connection-string");
|
||||
|
||||
if(deviceType.has_value() && deviceUrl.has_value() && deviceFetchTimeOut.has_value()
|
||||
&& databaseConnectionString.has_value())
|
||||
{
|
||||
return CommandlineParameters(
|
||||
deviceType.value(),
|
||||
deviceUrl.value(),
|
||||
deviceFetchTimeOut.value(),
|
||||
databaseConnectionString.value());
|
||||
}
|
||||
}
|
||||
catch(cxxopts::exceptions::exception const & e)
|
||||
{
|
||||
spdlog::error(e.what());
|
||||
return {};
|
||||
}
|
||||
|
||||
std::cout << options.help() << std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::string> FetchDataFromURL(const std::string & url, const unsigned int timeout)
|
||||
@@ -97,21 +149,19 @@ std::optional<std::string> FetchDataFromURL(const std::string & url, const unsig
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
auto const maybeArgs = ExtractArgs(argc, argv);
|
||||
if(!maybeArgs.has_value())
|
||||
auto const parameters = TryGetCommandlineArguments(argc, argv);
|
||||
if(!parameters.has_value())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto const & args = maybeArgs.value();
|
||||
|
||||
Database db(args["connection-string"].as<std::string>());
|
||||
Database db(parameters->DatabaseConnectionString);
|
||||
auto const now = std::time(nullptr);
|
||||
auto const resourceType = args["type"].as<std::string>();
|
||||
auto const resourceType = parameters->DeviceType;
|
||||
|
||||
if(resourceType == "Zeverlution")
|
||||
{
|
||||
auto const webResource = FetchDataFromURL(args["url"].as<std::string>(), args["timeout"].as<unsigned>());
|
||||
auto const webResource = FetchDataFromURL(parameters->DeviceUrl, parameters->DeviceFetchTimeOut);
|
||||
if(!webResource.has_value())
|
||||
{
|
||||
return -1;
|
||||
@@ -136,7 +186,7 @@ int main(int argc, char ** argv)
|
||||
}
|
||||
else if(resourceType == "Envoy")
|
||||
{
|
||||
auto const webResource = FetchDataFromURL(args["url"].as<std::string>(), args["timeout"].as<unsigned>());
|
||||
auto const webResource = FetchDataFromURL(parameters->DeviceUrl, parameters->DeviceFetchTimeOut);
|
||||
if(!webResource.has_value())
|
||||
{
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user