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