Use FairMQProgOptions for Sink and BenchmarkSampler

This commit is contained in:
Alexey Rybalchenko
2015-06-15 16:50:03 +02:00
parent 7fda980710
commit a3d919b763
14 changed files with 432 additions and 736 deletions

View File

@@ -1,143 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* FairMQChannel.cxx
*
* @since 2015-06-02
* @author A. Rybalchenko
*/
#include <set>
#include "FairMQChannel.h"
#include "FairMQLogger.h"
using namespace std;
FairMQChannel::FairMQChannel()
: fType("unspecified")
, fMethod("unspecified")
, fProtocol("unspecified")
, fAddress("unspecified")
, fPort("unspecified")
, fSndBufSize(1000)
, fRcvBufSize(1000)
, fRateLogging(1)
, fSocket()
, fIsValid(false)
, fChannelName("")
{
}
FairMQChannel::FairMQChannel(string type, string method, string protocol, string address, string port)
: fType(type)
, fMethod(method)
, fProtocol(protocol)
, fAddress(address)
, fPort(port)
, fSndBufSize(1000)
, fRcvBufSize(1000)
, fRateLogging(1)
, fSocket()
, fIsValid(false)
, fChannelName("")
{
}
bool FairMQChannel::ValidateChannel()
{
LOG(DEBUG) << "Validating channel " << fChannelName << "... ";
if (fIsValid)
{
LOG(DEBUG) << "Channel is already valid";
return true;
}
const string socketTypeNames[] = { "sub", "pub", "pull", "push", "req", "rep", "xsub", "xpub", "dealer", "router", "pair" };
const set<string> socketTypes(socketTypeNames, socketTypeNames + sizeof(socketTypeNames) / sizeof(string));
if (socketTypes.find(fType) == socketTypes.end())
{
LOG(DEBUG) << "Invalid channel type: " << fType;
fIsValid = false;
return false;
}
const string socketMethodNames[] = { "bind", "connect" };
const set<string> socketMethods(socketMethodNames, socketMethodNames + sizeof(socketMethodNames) / sizeof(string));
if (socketMethods.find(fMethod) == socketMethods.end())
{
LOG(DEBUG) << "Invalid channel method: " << fMethod;
fIsValid = false;
return false;
}
const string socketProtocolNames[] = { "tcp", "ipc", "inproc" };
const set<string> socketProtocols(socketProtocolNames, socketProtocolNames + sizeof(socketProtocolNames) / sizeof(string));
if (socketProtocols.find(fProtocol) == socketProtocols.end())
{
LOG(DEBUG) << "Invalid channel protocol: " << fProtocol;
fIsValid = false;
return false;
}
if (fAddress == "unspecified" && fAddress == "")
{
LOG(DEBUG) << "invalid channel address: " << fAddress;
fIsValid = false;
return false;
}
if (fPort == "unspecified" && fPort == "")
{
LOG(DEBUG) << "invalid channel port: " << fPort;
fIsValid = false;
return false;
}
if (fSndBufSize < 0)
{
LOG(DEBUG) << "invalid channel send buffer size: " << fSndBufSize;
fIsValid = false;
return false;
}
if (fRcvBufSize < 0)
{
LOG(DEBUG) << "invalid channel receive buffer size: " << fRcvBufSize;
fIsValid = false;
return false;
}
LOG(DEBUG) << "Channel is valid";
fIsValid = true;
return true;
}
int FairMQChannel::Send(FairMQMessage* msg, const string& flag)
{
return fSocket->Send(msg, flag);
}
int FairMQChannel::Send(FairMQMessage* msg, const int flags)
{
return fSocket->Send(msg, flags);
}
int FairMQChannel::Receive(FairMQMessage* msg, const string& flag)
{
return fSocket->Receive(msg, flag);
}
int FairMQChannel::Receive(FairMQMessage* msg, const int flags)
{
return fSocket->Receive(msg, flags);
}
FairMQChannel::~FairMQChannel()
{
}

View File

@@ -1,54 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* FairMQChannel.h
*
* @since 2015-06-02
* @author A. Rybalchenko
*/
#ifndef FAIRMQCHANNEL_H_
#define FAIRMQCHANNEL_H_
#include <string>
#include "FairMQSocket.h"
class FairMQChannel
{
friend class FairMQDevice;
public:
FairMQChannel();
FairMQChannel(std::string type, std::string method, std::string protocol, std::string address, std::string port);
virtual ~FairMQChannel();
bool ValidateChannel();
// Wrappers for the socket methods to simplify the usage of channels
int Send(FairMQMessage* msg, const std::string& flag="");
int Send(FairMQMessage* msg, const int flags);
int Receive(FairMQMessage* msg, const std::string& flag="");
int Receive(FairMQMessage* msg, const int flags);
std::string fType;
std::string fMethod;
std::string fProtocol;
std::string fAddress;
std::string fPort;
int fSndBufSize;
int fRcvBufSize;
int fRateLogging;
private:
FairMQSocket* fSocket;
bool fIsValid;
std::string fChannelName;
};
#endif /* FAIRMQCHANNEL_H_ */

View File

@@ -17,152 +17,168 @@
namespace FairMQParser
{
// TODO : add key-value map<string,string> parameter for replacing/updating values from keys
// function that convert property tree (given the xml or json structure) to FairMQMap
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& device_id, const std::string& root_node, const std::string& format_flag)
// TODO : add key-value map<string,string> parameter for replacing/updating values from keys
// function that convert property tree (given the xml or json structure) to FairMQMap
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& deviceId, const std::string& rootNode, const std::string& formatFlag)
{
// Create fair mq map
FairMQMap MQChannelMap;
// variables to create key for the mq map. Note: maybe device name and id useless here
std::string deviceIdKey;
std::string channelKey;
// do a first loop just to print the device-id in xml/json input
for(const auto& p : pt.get_child(rootNode))
{
// Create fair mq map
FairMQMap MQChannelMap;
// variables to create key for the mq map. Note: maybe device name and id useless here
std::string kdevice_id;
std::string kchannel;
// do a first loop just to print the device-id in xml/json input
for(const auto& p : pt.get_child(root_node))
if (p.first != "device")
{
if (p.first != "device")
continue;
//get id attribute to choose the device
if(format_flag=="xml")
{
kdevice_id=p.second.get<std::string>("<xmlattr>.id");
MQLOG(DEBUG)<<"Found device id '"<< kdevice_id <<"' in XML input";
}
if(format_flag=="json")
{
kdevice_id=p.second.get<std::string>("id");
MQLOG(DEBUG)<<"Found device id '"<< kdevice_id <<"' in JSON input";
}
continue;
}
// Extract value from boost::property_tree
// For each device in fairMQOptions
for(const auto& p : pt.get_child(root_node))
{
if (p.first != "device")
continue;
//get id attribute to choose the device
if(format_flag=="xml")
kdevice_id=p.second.get<std::string>("<xmlattr>.id");
if(format_flag=="json")
kdevice_id=p.second.get<std::string>("id");
// if not correct device id, do not fill MQMap
if(device_id != kdevice_id)
//get id attribute to choose the device
if (formatFlag == "xml")
{
deviceIdKey = p.second.get<std::string>("<xmlattr>.id");
MQLOG(DEBUG) << "Found device id '" << deviceIdKey << "' in XML input";
}
if (formatFlag == "json")
{
deviceIdKey = p.second.get<std::string>("id");
MQLOG(DEBUG) << "Found device id '"<< deviceIdKey << "' in JSON input";
}
}
// Extract value from boost::property_tree
// For each device in fairMQOptions
for(const auto& p : pt.get_child(rootNode))
{
if (p.first != "device")
{
continue;
}
//get id attribute to choose the device
if (formatFlag == "xml")
{
deviceIdKey = p.second.get<std::string>("<xmlattr>.id");
}
if (formatFlag == "json")
{
deviceIdKey = p.second.get<std::string>("id");
}
// if not correct device id, do not fill MQMap
if (deviceId != deviceIdKey)
{
continue;
}
// print if DEBUG log level set
std::stringstream deviceStream;
deviceStream << "[node = " << p.first
<< "] id = " << deviceIdKey;
MQLOG(DEBUG) << deviceStream.str();
// for each channel in device
for(const auto& q : p.second.get_child(""))
{
if (q.first != "channel")
{
continue;
}
//get name attribute to form key
if (formatFlag == "xml")
{
channelKey = q.second.get<std::string>("<xmlattr>.name");
}
if (formatFlag=="json")
{
channelKey = q.second.get<std::string>("name");
}
// print if DEBUG log level set
std::stringstream ss_device;
ss_device << "[node = " << p.first
<< "] id = " << kdevice_id;
MQLOG(DEBUG)<<ss_device.str();
std::stringstream channelStream;
channelStream << "\t [node = " << q.first
<< "] name = " << channelKey;
MQLOG(DEBUG) << channelStream.str();
// for each channel in device
for(const auto& q : p.second.get_child(""))
// temporary FairMQChannel container
std::vector<FairMQChannel> channelList;
int socketCounter = 0;
// for each socket in channel
for (const auto& r : q.second.get_child(""))
{
if (q.first != "channel")
continue;
//get name attribute to form key
if(format_flag=="xml")
kchannel=q.second.get<std::string>("<xmlattr>.name");
if(format_flag=="json")
kchannel=q.second.get<std::string>("name");
// print if DEBUG log level set
std::stringstream ss_chan;
ss_chan << "\t [node = " << q.first
<< "] name = " << kchannel;
MQLOG(DEBUG)<<ss_chan.str();
// temporary FairMQChannel container
std::vector<FairMQChannel> channel_list;
int count_socket=0;
// for each socket in channel
for(const auto& r : q.second.get_child(""))
if (r.first != "socket")
{
if (r.first != "socket")
continue;
count_socket++;
FairMQChannel channel;
// print if DEBUG log level set
std::stringstream ss_sock;
ss_sock << "\t \t [node = " << r.first
<< "] socket index = " << count_socket;
MQLOG(DEBUG)<<ss_sock.str();
MQLOG(DEBUG)<< "\t \t \t type = " << r.second.get<std::string>("type",channel.fType);
MQLOG(DEBUG)<< "\t \t \t method = " << r.second.get<std::string>("method",channel.fMethod);
MQLOG(DEBUG)<< "\t \t \t address = " << r.second.get<std::string>("address",channel.fAddress);
MQLOG(DEBUG)<< "\t \t \t sndBufSize = " << r.second.get<int>("sndBufSize",channel.fSndBufSize);
MQLOG(DEBUG)<< "\t \t \t rcvBufSize = " << r.second.get<int>("rcvBufSize",channel.fRcvBufSize);
MQLOG(DEBUG)<< "\t \t \t rateLogging = " << r.second.get<int>("rateLogging",channel.fRateLogging);
continue;
}
channel.fType = r.second.get<std::string>("type",channel.fType);
channel.fMethod = r.second.get<std::string>("method",channel.fMethod);
channel.fAddress = r.second.get<std::string>("address",channel.fAddress);
channel.fSndBufSize = r.second.get<int>("sndBufSize",channel.fSndBufSize);//int
channel.fRcvBufSize = r.second.get<int>("rcvBufSize",channel.fRcvBufSize);//int
channel.fRateLogging = r.second.get<int>("rateLogging",channel.fRateLogging);//int
++socketCounter;
FairMQChannel channel;
channel_list.push_back(channel);
}// end socket loop
//fill mq map option
MQChannelMap.insert(std::make_pair(kchannel,std::move(channel_list)));
}
// print if DEBUG log level set
std::stringstream socket;
socket << "\t \t [node = " << r.first
<< "] socket index = " << socketCounter;
MQLOG(DEBUG) << socket.str();
MQLOG(DEBUG) << "\t \t \t type = " << r.second.get<std::string>("type", channel.fType);
MQLOG(DEBUG) << "\t \t \t method = " << r.second.get<std::string>("method", channel.fMethod);
MQLOG(DEBUG) << "\t \t \t address = " << r.second.get<std::string>("address", channel.fAddress);
MQLOG(DEBUG) << "\t \t \t sndBufSize = " << r.second.get<int>("sndBufSize", channel.fSndBufSize);
MQLOG(DEBUG) << "\t \t \t rcvBufSize = " << r.second.get<int>("rcvBufSize", channel.fRcvBufSize);
MQLOG(DEBUG) << "\t \t \t rateLogging = " << r.second.get<int>("rateLogging", channel.fRateLogging);
channel.fType = r.second.get<std::string>("type", channel.fType);
channel.fMethod = r.second.get<std::string>("method", channel.fMethod);
channel.fAddress = r.second.get<std::string>("address", channel.fAddress);
channel.fSndBufSize = r.second.get<int>("sndBufSize", channel.fSndBufSize); // int
channel.fRcvBufSize = r.second.get<int>("rcvBufSize", channel.fRcvBufSize); // int
channel.fRateLogging = r.second.get<int>("rateLogging", channel.fRateLogging); // int
channelList.push_back(channel);
}// end socket loop
//fill mq map option
MQChannelMap.insert(std::make_pair(channelKey,std::move(channelList)));
}
if(MQChannelMap.size()>0)
{
MQLOG(DEBUG)<<"---- Channel-keys found are :";
for(const auto& p : MQChannelMap)
MQLOG(DEBUG)<<p.first;
}
else
{
MQLOG(WARN)<<"---- No channel-keys found for device-id "<<device_id;
MQLOG(WARN)<<"---- Check the "<< format_flag <<" inputs and/or command line inputs";
}
return MQChannelMap;
}
////////////////////////////////////////////////////////////////////////////
FairMQMap JSON::UserParser(const std::string& filename, const std::string& device_id, const std::string& root_node)
if (MQChannelMap.size() > 0)
{
boost::property_tree::ptree pt;
boost::property_tree::read_json(filename, pt);
return ptreeToMQMap(pt,device_id,root_node,"json");
MQLOG(DEBUG) << "---- Channel-keys found are :";
for (const auto& p : MQChannelMap)
{
MQLOG(DEBUG) << p.first;
}
}
FairMQMap JSON::UserParser(std::stringstream& input_ss, const std::string& device_id, const std::string& root_node)
else
{
boost::property_tree::ptree pt;
boost::property_tree::read_json(input_ss, pt);
return ptreeToMQMap(pt,device_id,root_node,"json");
MQLOG(WARN) << "---- No channel-keys found for device-id " << deviceId;
MQLOG(WARN) << "---- Check the "<< formatFlag << " inputs and/or command line inputs";
}
return MQChannelMap;
}
////////////////////////////////////////////////////////////////////////////
FairMQMap JSON::UserParser(const std::string& filename, const std::string& deviceId, const std::string& rootNode)
{
boost::property_tree::ptree pt;
boost::property_tree::read_json(filename, pt);
return ptreeToMQMap(pt, deviceId, rootNode,"json");
}
FairMQMap JSON::UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode)
{
boost::property_tree::ptree pt;
boost::property_tree::read_json(input, pt);
return ptreeToMQMap(pt, deviceId, rootNode,"json");
}
} // end FairMQParser namespace

View File

@@ -8,31 +8,30 @@
#ifndef FAIRMQPARSER_H
#define FAIRMQPARSER_H
// FairRoot
#include "FairMQChannel.h"
// Boost
#include <boost/property_tree/ptree.hpp>
// std
#include <string>
#include <vector>
#include <map>
// Boost
#include <boost/property_tree/ptree.hpp>
// FairMQ
#include "FairMQChannel.h"
namespace FairMQParser
{
typedef std::map<std::string, std::vector<FairMQChannel> > FairMQMap;
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& device_id, const std::string& root_node, const std::string& format_flag="json");
struct JSON
{
FairMQMap UserParser(const std::string& filename, const std::string& device_id, const std::string& root_node="fairMQOptions");
FairMQMap UserParser(std::stringstream& input_ss, const std::string& device_id, const std::string& root_node="fairMQOptions");
};
} // end FairMQParser namespace
#endif /* FAIRMQPARSER_H */
typedef std::map< std::string,std::vector<FairMQChannel> > FairMQMap;
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& deviceId, const std::string& rootNode, const std::string& formatFlag = "json");
struct JSON
{
FairMQMap UserParser(const std::string& filename, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
FairMQMap UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
};
} // FairMQParser namespace
#endif /* FAIRMQPARSER_H */

View File

@@ -8,11 +8,11 @@
#include "FairMQProgOptions.h"
#include <algorithm>
FairMQProgOptions::FairMQProgOptions() :
FairProgOptions(),
fMQParserOptions("MQ-Device parser options"),
fMQtree(),
fFairMQmap()
FairMQProgOptions::FairMQProgOptions()
: FairProgOptions()
, fMQParserOptions("MQ-Device parser options")
, fMQtree()
, fFairMQmap()
{
InitOptionDescription();
}
@@ -21,18 +21,16 @@ FairMQProgOptions::~FairMQProgOptions()
{
}
int FairMQProgOptions::ParseAll(const int argc, char** argv, bool AllowUnregistered)
{
// before parsing, define cmdline and optionally cfgfile description,
// and also what is visible for the user
AddToCmdLineOptions(fGenericDesc);
AddToCmdLineOptions(fMQParserOptions);
// if config file option enabled then id non required in cmdline but required in configfile
// else required in cmdline
if(fUseConfigFile)
if (fUseConfigFile)
{
fCmdline_options.add_options()
("device-id", po::value< std::string >(), "Device ID");
@@ -40,39 +38,40 @@ int FairMQProgOptions::ParseAll(const int argc, char** argv, bool AllowUnregiste
("device-id", po::value< std::string >()->required(), "Device ID");
}
else
{
fCmdline_options.add_options()
("device-id", po::value< std::string >()->required(), "Device ID");
}
fVisible_options.add_options()
("device-id", po::value< std::string >()->required(), "Device ID (required value)");
// parse command line
if(ParseCmdLine(argc,argv,fCmdline_options,fvarmap,AllowUnregistered))
if (ParseCmdLine(argc,argv,fCmdline_options,fvarmap,AllowUnregistered))
{
return 1;
}
// if txt/INI configuration file enabled then parse it
if(fUseConfigFile && !fConfigFile.empty())
if (fUseConfigFile && !fConfigFile.empty())
{
AddToCfgFileOptions(fMQParserOptions,false);
if(ParseCfgFile(fConfigFile,fConfig_file_options,fvarmap,AllowUnregistered))
if (ParseCfgFile(fConfigFile, fConfig_file_options, fvarmap, AllowUnregistered))
{
return 1;
}
}
// set log level before printing (default is 0 = DEBUG level)
int verbose=GetValue<int>("verbose");
SET_LOGGER_LEVEL(verbose);
PrintOptions();
return 0;
}
int FairMQProgOptions::NotifySwitchOption()
{
if ( fvarmap.count("help") )
@@ -99,8 +98,7 @@ void FairMQProgOptions::InitOptionDescription()
("config-json-string", po::value< std::vector<std::string> >()->multitoken(), "JSON input as command line string.")
("config-json-filename", po::value< std::string >(), "JSON input as file.")
//("ini.config.string", po::value< std::vector<std::string> >()->multitoken(), "INI input as command line string.")
//("ini.config.filename", po::value< std::string >(), "INI input as file.")
// ("ini.config.string", po::value< std::vector<std::string> >()->multitoken(), "INI input as command line string.")
// ("ini.config.filename", po::value< std::string >(), "INI input as file.")
;
}

View File

@@ -17,21 +17,20 @@ namespace pt = boost::property_tree;
class FairMQProgOptions : public FairProgOptions
{
protected:
typedef std::map<std::string, std::vector<FairMQChannel> > FairMQMap;
typedef std::map< std::string,std::vector<FairMQChannel> > FairMQMap;
public:
FairMQProgOptions();
virtual ~FairMQProgOptions();
virtual int ParseAll(const int argc, char** argv, bool AllowUnregistered=false);
virtual int ParseAll(const int argc, char** argv, bool AllowUnregistered = false);
// external parser, store function
template < typename T, typename ...Args>
template <typename T, typename ...Args>
int UserParser(Args &&... args)
{
try
{
Store( T().UserParser(std::forward<Args>(args)...) );
Store(T().UserParser(std::forward<Args>(args)...));
}
catch (std::exception& e)
{
@@ -40,38 +39,36 @@ public:
}
return 0;
}
int Store(const po::variables_map& vm)
{
fvarmap = vm;
return 0;
}
int Store(const pt::ptree& tree)
{
fMQtree = tree;
return 0;
}
int Store(const FairMQMap& channels)
{
fFairMQmap = channels;
return 0;
}
FairMQMap GetFairMQMap()
{
return fFairMQmap;
}
protected:
po::options_description fMQParserOptions;
pt::ptree fMQtree;
FairMQMap fFairMQmap;
virtual int NotifySwitchOption();// for custom help & version printing
virtual int NotifySwitchOption(); // for custom help & version printing
void InitOptionDescription();
};

View File

@@ -35,7 +35,7 @@
* fVisible_options.add(fCmdline_options);
* }
* virtual ~MyOptions(){}
* virtual int ParseAll(const int argc, char** argv, bool AllowUnregistered=false)
* virtual int ParseAll(const int argc, char** argv, bool AllowUnregistered = false)
* {
* if(ParseCmdLine(argc,argv,fCmdline_options,fvarmap,AllowUnregistered))
* return 1;
@@ -47,50 +47,53 @@
*/
template<class T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
std::copy(v.begin(), v.end(), std::ostream_iterator<T>(os, " "));
return os;
}
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
std::copy(v.begin(), v.end(), std::ostream_iterator<T>(os, " "));
return os;
}
namespace po = boost::program_options;
class FairProgOptions
class FairProgOptions
{
public:
FairProgOptions();
virtual ~FairProgOptions();
// add options_description
int AddToCmdLineOptions(const po::options_description& optdesc, bool visible=true);
int AddToCfgFileOptions(const po::options_description& optdesc, bool visible=true);
int AddToCmdLineOptions(const po::options_description& optdesc, bool visible = true);
int AddToCfgFileOptions(const po::options_description& optdesc, bool visible = true);
int AddToEnvironmentOptions(const po::options_description& optdesc);
void EnableCfgFile(const std::string& filename="")
void EnableCfgFile(const std::string& filename = "")
{
fUseConfigFile=true;
if(filename.empty())
fUseConfigFile = true;
if (filename.empty())
{
fCmdline_options.add_options()
("config,c", po::value<std::string>(&fConfigFile)->required(), "Path to configuration file");
}
else
fConfigFile=filename;
{
fConfigFile = filename;
}
}
void UseConfigFile(const std::string& filename="")
void UseConfigFile(const std::string& filename = "")
{
fUseConfigFile=true;
if(filename.empty())
fUseConfigFile = true;
if (filename.empty())
{
fCmdline_options.add_options()
("config,c", po::value<std::string>(&fConfigFile)->required(), "Path to configuration file");
}
else
fConfigFile=filename;
{
fConfigFile = filename;
}
}
// set value corresponding to the key
template<typename T>
T GetValue(const std::string& key) const
@@ -98,11 +101,13 @@ public:
T val;
try
{
if ( fvarmap.count(key) )
val=fvarmap[key].as<T>();
if (fvarmap.count(key))
{
val = fvarmap[key].as<T>();
}
else
{
LOG(ERROR) <<"Key '"<< key <<"' not found in boost variable map";
LOG(ERROR) << "Key '"<< key <<"' not found in boost variable map";
LOG(INFO) << "Command line / txt config file options are the following : ";
this->PrintHelp();
}
@@ -113,7 +118,7 @@ public:
LOG(ERROR) << e.what();
this->PrintHelp();
}
return val;
}
@@ -122,24 +127,22 @@ public:
const po::variables_map& GetVarMap() const {return fvarmap;}
// boost prog options parsers
int ParseCmdLine(const int argc, char** argv, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered=false);
int ParseCmdLine(const int argc, char** argv, const po::options_description& desc, bool AllowUnregistered=false);
int ParseCfgFile(const std::string& filename, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered=false);
int ParseCfgFile(const std::string& filename, const po::options_description& desc, bool AllowUnregistered=false);
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered=false);
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, bool AllowUnregistered=false);
int ParseCmdLine(const int argc, char** argv, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered = false);
int ParseCmdLine(const int argc, char** argv, const po::options_description& desc, bool AllowUnregistered = false);
int ParseCfgFile(const std::string& filename, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered = false);
int ParseCfgFile(const std::string& filename, const po::options_description& desc, bool AllowUnregistered = false);
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered = false);
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, bool AllowUnregistered = false);
int ParseEnvironment(const std::function<std::string(std::string)>&);
virtual int ParseAll(const int argc, char** argv, bool AllowUnregistered=false)=0;
virtual int ParseAll(const int argc, char** argv, bool AllowUnregistered = false) = 0;
virtual int PrintOptions();
int PrintHelp() const;
protected:
// options container
po::variables_map fvarmap;
@@ -152,7 +155,7 @@ protected:
// Description of cmd line and simple configuration file (configuration file like txt, but not like xml json ini)
po::options_description fCmdline_options;
po::options_description fConfig_file_options;
// Description which is printed in help command line
po::options_description fVisible_options;
@@ -165,17 +168,16 @@ protected:
template<typename T>
void UpadateVarMap(const std::string& key, const T& val)
{
replace(fvarmap,key,val);
replace(fvarmap, key, val);
}
template<typename T>
void replace( std::map<std::string, po::variable_value>& vm, const std::string& opt, const T& val)
void replace(std::map<std::string, po::variable_value>& vm, const std::string& opt, const T& val)
{
vm[opt].value() = boost::any(val);
}
private:
private:
// /////////////////////////////////////////////
// Methods below are helper functions used in the PrintOptions method
typedef std::tuple<std::string, std::string,std::string, std::string> VarValInfo_t;
@@ -184,20 +186,24 @@ private:
VarValInfo_t Get_variable_value_info(const po::variable_value& var_val);
template<typename T>
std::string variable_value_to_string(const po::variable_value& var_val)
std::string variable_value_to_string(const po::variable_value& var_val)
{
auto& value = var_val.value();
std::ostringstream ostr;
if (auto q = boost::any_cast<T>(&value))
{
auto& value = var_val.value();
std::ostringstream ostr;
if(auto q = boost::any_cast< T >(&value))
ostr<<*q;
std::string val_str=ostr.str();
return val_str;
ostr << *q;
}
std::string val_str = ostr.str();
return val_str;
}
static void Max(int &val, const int &comp)
{
if (comp>val)
val=comp;
if (comp > val)
{
val = comp;
}
}
};