mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 16:46:47 +00:00
FairMQProgOptions fixes and cleanup
- Remove singular key names from JSON schema. - Align the property tree created by `FairMQSuboptParser` with the format required by the main parser (plural names). - Fix `--print-options` to print all options (not only those that have their value set). - remove XML parser (outdated and unused). - various code cleanup.
This commit is contained in:
parent
4e2a195289
commit
f8d4fe01d0
|
@ -993,7 +993,7 @@ void FairMQDevice::LogSocketRates()
|
||||||
bytesOut.at(i) = bytesOutNew.at(i);
|
bytesOut.at(i) = bytesOutNew.at(i);
|
||||||
msgOut.at(i) = msgOutNew.at(i);
|
msgOut.at(i) = msgOutNew.at(i);
|
||||||
|
|
||||||
LOG(debug) << filteredChannelNames.at(i) << ": "
|
LOG(info) << filteredChannelNames.at(i) << ": "
|
||||||
<< "in: " << msgPerSecIn.at(i) << " (" << mbPerSecIn.at(i) << " MB) "
|
<< "in: " << msgPerSecIn.at(i) << " (" << mbPerSecIn.at(i) << " MB) "
|
||||||
<< "out: " << msgPerSecOut.at(i) << " (" << mbPerSecOut.at(i) << " MB)";
|
<< "out: " << msgPerSecOut.at(i) << " (" << mbPerSecOut.at(i) << " MB)";
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,24 +14,27 @@
|
||||||
|
|
||||||
#include "FairMQParser.h"
|
#include "FairMQParser.h"
|
||||||
#include "FairMQLogger.h"
|
#include "FairMQLogger.h"
|
||||||
#include <boost/property_tree/xml_parser.hpp>
|
|
||||||
#include <boost/property_tree/json_parser.hpp>
|
#include <boost/property_tree/json_parser.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace FairMQParser
|
namespace fair
|
||||||
|
{
|
||||||
|
namespace mq
|
||||||
|
{
|
||||||
|
namespace parser
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO : add key-value map<string,string> parameter for replacing/updating values from keys
|
// 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
|
// function that convert property tree (given the json structure) to FairMQMap
|
||||||
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const string& id, const string& rootNode, const string& formatFlag)
|
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const string& id, const string& rootNode)
|
||||||
{
|
{
|
||||||
// Create fair mq map
|
// Create fair mq map
|
||||||
FairMQMap channelMap;
|
FairMQMap channelMap;
|
||||||
//Helper::PrintPropertyTree(pt);
|
//Helper::PrintPropertyTree(pt);
|
||||||
//Helper::PrintDeviceList(pt.get_child(rootNode), formatFlag);
|
//Helper::PrintDeviceList(pt.get_child(rootNode));
|
||||||
// Extract value from boost::property_tree
|
// Extract value from boost::property_tree
|
||||||
Helper::DeviceParser(pt.get_child(rootNode), channelMap, id, formatFlag);
|
Helper::DeviceParser(pt.get_child(rootNode), channelMap, id);
|
||||||
|
|
||||||
if (channelMap.empty())
|
if (channelMap.empty())
|
||||||
{
|
{
|
||||||
|
@ -56,24 +59,10 @@ FairMQMap JSON::UserParser(stringstream& input, const string& deviceId, const st
|
||||||
return ptreeToMQMap(pt, deviceId, rootNode);
|
return ptreeToMQMap(pt, deviceId, rootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
FairMQMap XML::UserParser(const string& filename, const string& deviceId, const string& rootNode)
|
|
||||||
{
|
|
||||||
boost::property_tree::ptree pt;
|
|
||||||
boost::property_tree::read_xml(filename, pt);
|
|
||||||
return ptreeToMQMap(pt, deviceId, rootNode, "xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
FairMQMap XML::UserParser(stringstream& input, const string& deviceId, const string& rootNode)
|
|
||||||
{
|
|
||||||
boost::property_tree::ptree pt;
|
|
||||||
boost::property_tree::read_xml(input, pt);
|
|
||||||
return ptreeToMQMap(pt, deviceId, rootNode, "xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Helper
|
namespace Helper
|
||||||
{
|
{
|
||||||
|
|
||||||
void PrintDeviceList(const boost::property_tree::ptree& tree, const string& formatFlag)
|
void PrintDeviceList(const boost::property_tree::ptree& tree)
|
||||||
{
|
{
|
||||||
string deviceIdKey;
|
string deviceIdKey;
|
||||||
|
|
||||||
|
@ -97,35 +86,10 @@ void PrintDeviceList(const boost::property_tree::ptree& tree, const string& form
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.first == "device")
|
|
||||||
{
|
|
||||||
// get id attribute to choose the device
|
|
||||||
if (formatFlag == "xml")
|
|
||||||
{
|
|
||||||
deviceIdKey = p.second.get<string>("<xmlattr>.id");
|
|
||||||
LOG(debug) << "Found config for '" << deviceIdKey << "' in XML input";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formatFlag == "json")
|
|
||||||
{
|
|
||||||
string key = p.second.get<string>("key", "");
|
|
||||||
if (key != "")
|
|
||||||
{
|
|
||||||
deviceIdKey = key;
|
|
||||||
LOG(debug) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deviceIdKey = p.second.get<string>("id");
|
|
||||||
LOG(debug) << "Found config for device id '" << deviceIdKey << "' in JSON input";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const string& deviceId, const string& formatFlag)
|
void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const string& deviceId)
|
||||||
{
|
{
|
||||||
string deviceIdKey;
|
string deviceIdKey;
|
||||||
|
|
||||||
|
@ -160,48 +124,13 @@ void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap
|
||||||
|
|
||||||
LOG(debug) << "Found with following channels:";
|
LOG(debug) << "Found with following channels:";
|
||||||
|
|
||||||
ChannelParser(q.second, channelMap, formatFlag);
|
ChannelParser(q.second, channelMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.first == "device")
|
|
||||||
{
|
|
||||||
if (formatFlag == "xml")
|
|
||||||
{
|
|
||||||
deviceIdKey = p.second.get<string>("<xmlattr>.id");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formatFlag == "json")
|
|
||||||
{
|
|
||||||
// check if key is provided, otherwise use id
|
|
||||||
string key = p.second.get<string>("key", "");
|
|
||||||
|
|
||||||
if (key != "")
|
|
||||||
{
|
|
||||||
deviceIdKey = key;
|
|
||||||
// LOG(debug) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deviceIdKey = p.second.get<string>("id");
|
|
||||||
// LOG(debug) << "Found config for device id '" << deviceIdKey << "' in JSON input";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if not correct device id, do not fill MQMap
|
|
||||||
if (deviceId != deviceIdKey)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(debug) << "Found with following channels:";
|
|
||||||
|
|
||||||
ChannelParser(p.second, channelMap, formatFlag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const string& formatFlag)
|
void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap)
|
||||||
{
|
{
|
||||||
string channelKey;
|
string channelKey;
|
||||||
|
|
||||||
|
@ -260,69 +189,6 @@ void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMa
|
||||||
channelMap.insert(make_pair(channelKey, move(channelList)));
|
channelMap.insert(make_pair(channelKey, move(channelList)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.first == "channel")
|
|
||||||
{
|
|
||||||
// try to get common properties to use for all subChannels
|
|
||||||
FairMQChannel commonChannel;
|
|
||||||
int numSockets = 0;
|
|
||||||
|
|
||||||
// get name attribute to form key
|
|
||||||
if (formatFlag == "xml")
|
|
||||||
{
|
|
||||||
channelKey = p.second.get<string>("<xmlattr>.name");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formatFlag == "json")
|
|
||||||
{
|
|
||||||
channelKey = p.second.get<string>("name");
|
|
||||||
|
|
||||||
numSockets = p.second.get<int>("numSockets", 0);
|
|
||||||
|
|
||||||
// try to get common properties to use for all subChannels
|
|
||||||
commonChannel.UpdateType(p.second.get<string>("type", commonChannel.GetType()));
|
|
||||||
commonChannel.UpdateMethod(p.second.get<string>("method", commonChannel.GetMethod()));
|
|
||||||
commonChannel.UpdateAddress(p.second.get<string>("address", commonChannel.GetAddress()));
|
|
||||||
commonChannel.UpdateTransport(p.second.get<string>("transport", commonChannel.GetTransport()));
|
|
||||||
commonChannel.UpdateSndBufSize(p.second.get<int>("sndBufSize", commonChannel.GetSndBufSize()));
|
|
||||||
commonChannel.UpdateRcvBufSize(p.second.get<int>("rcvBufSize", commonChannel.GetRcvBufSize()));
|
|
||||||
commonChannel.UpdateSndKernelSize(p.second.get<int>("sndKernelSize", commonChannel.GetSndKernelSize()));
|
|
||||||
commonChannel.UpdateRcvKernelSize(p.second.get<int>("rcvKernelSize", commonChannel.GetRcvKernelSize()));
|
|
||||||
commonChannel.UpdateRateLogging(p.second.get<int>("rateLogging", commonChannel.GetRateLogging()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// temporary FairMQChannel container
|
|
||||||
vector<FairMQChannel> channelList;
|
|
||||||
|
|
||||||
if (numSockets > 0)
|
|
||||||
{
|
|
||||||
LOG(debug) << "" << channelKey << ":";
|
|
||||||
LOG(debug) << "\tnumSockets of " << numSockets << " specified,";
|
|
||||||
LOG(debug) << "\tapplying common settings to each:";
|
|
||||||
|
|
||||||
LOG(debug) << "\ttype = " << commonChannel.GetType();
|
|
||||||
LOG(debug) << "\tmethod = " << commonChannel.GetMethod();
|
|
||||||
LOG(debug) << "\taddress = " << commonChannel.GetAddress();
|
|
||||||
LOG(debug) << "\ttransport = " << commonChannel.GetTransport();
|
|
||||||
LOG(debug) << "\tsndBufSize = " << commonChannel.GetSndBufSize();
|
|
||||||
LOG(debug) << "\trcvBufSize = " << commonChannel.GetRcvBufSize();
|
|
||||||
LOG(debug) << "\tsndKernelSize = " << commonChannel.GetSndKernelSize();
|
|
||||||
LOG(debug) << "\trcvKernelSize = " << commonChannel.GetRcvKernelSize();
|
|
||||||
LOG(debug) << "\trateLogging = " << commonChannel.GetRateLogging();
|
|
||||||
|
|
||||||
for (int i = 0; i < numSockets; ++i)
|
|
||||||
{
|
|
||||||
FairMQChannel channel(commonChannel);
|
|
||||||
channelList.push_back(channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SocketParser(p.second.get_child(""), channelList, channelKey, commonChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
channelMap.insert(make_pair(channelKey, move(channelList)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,37 +232,6 @@ void SocketParser(const boost::property_tree::ptree& tree, vector<FairMQChannel>
|
||||||
++socketCounter;
|
++socketCounter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.first == "socket")
|
|
||||||
{
|
|
||||||
// create new channel and apply setting from the common channel
|
|
||||||
FairMQChannel channel(commonChannel);
|
|
||||||
|
|
||||||
// if the socket field specifies or overrides something from the common channel, apply those settings
|
|
||||||
channel.UpdateType(p.second.get<string>("type", channel.GetType()));
|
|
||||||
channel.UpdateMethod(p.second.get<string>("method", channel.GetMethod()));
|
|
||||||
channel.UpdateAddress(p.second.get<string>("address", channel.GetAddress()));
|
|
||||||
channel.UpdateTransport(p.second.get<string>("transport", channel.GetTransport()));
|
|
||||||
channel.UpdateSndBufSize(p.second.get<int>("sndBufSize", channel.GetSndBufSize()));
|
|
||||||
channel.UpdateRcvBufSize(p.second.get<int>("rcvBufSize", channel.GetRcvBufSize()));
|
|
||||||
channel.UpdateSndKernelSize(p.second.get<int>("sndKernelSize", channel.GetSndKernelSize()));
|
|
||||||
channel.UpdateRcvKernelSize(p.second.get<int>("rcvKernelSize", channel.GetRcvKernelSize()));
|
|
||||||
channel.UpdateRateLogging(p.second.get<int>("rateLogging", channel.GetRateLogging()));
|
|
||||||
|
|
||||||
LOG(debug) << "" << channelName << "[" << socketCounter << "]:";
|
|
||||||
LOG(debug) << "\ttype = " << channel.GetType();
|
|
||||||
LOG(debug) << "\tmethod = " << channel.GetMethod();
|
|
||||||
LOG(debug) << "\taddress = " << channel.GetAddress();
|
|
||||||
LOG(debug) << "\ttransport = " << channel.GetTransport();
|
|
||||||
LOG(debug) << "\tsndBufSize = " << channel.GetSndBufSize();
|
|
||||||
LOG(debug) << "\trcvBufSize = " << channel.GetRcvBufSize();
|
|
||||||
LOG(debug) << "\tsndKernelSize = " << channel.GetSndKernelSize();
|
|
||||||
LOG(debug) << "\trcvKernelSize = " << channel.GetRcvKernelSize();
|
|
||||||
LOG(debug) << "\trateLogging = " << channel.GetRateLogging();
|
|
||||||
|
|
||||||
channelList.push_back(channel);
|
|
||||||
++socketCounter;
|
|
||||||
}
|
|
||||||
} // end socket loop
|
} // end socket loop
|
||||||
|
|
||||||
if (socketCounter)
|
if (socketCounter)
|
||||||
|
@ -435,4 +270,6 @@ void PrintPropertyTree(const boost::property_tree::ptree& tree, int level)
|
||||||
|
|
||||||
} // Helper namespace
|
} // Helper namespace
|
||||||
|
|
||||||
} // FairMQParser namespace
|
} // namespace parser
|
||||||
|
} // namespace mq
|
||||||
|
} // namespace fair
|
||||||
|
|
|
@ -17,12 +17,16 @@
|
||||||
|
|
||||||
#include "FairMQChannel.h"
|
#include "FairMQChannel.h"
|
||||||
|
|
||||||
namespace FairMQParser
|
namespace fair
|
||||||
|
{
|
||||||
|
namespace mq
|
||||||
|
{
|
||||||
|
namespace parser
|
||||||
{
|
{
|
||||||
|
|
||||||
using FairMQMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
using FairMQMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
||||||
|
|
||||||
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& deviceId, const std::string& rootNode, const std::string& formatFlag = "json");
|
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& deviceId, const std::string& rootNode);
|
||||||
|
|
||||||
struct JSON
|
struct JSON
|
||||||
{
|
{
|
||||||
|
@ -30,23 +34,19 @@ struct JSON
|
||||||
FairMQMap UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
|
FairMQMap UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XML
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Helper
|
namespace Helper
|
||||||
{
|
{
|
||||||
|
|
||||||
void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string& formatFlag = "json");
|
void PrintDeviceList(const boost::property_tree::ptree& tree);
|
||||||
void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& deviceId, const std::string& formatFlag);
|
void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& deviceId);
|
||||||
void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& formatFlag);
|
void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap);
|
||||||
void SocketParser(const boost::property_tree::ptree& tree, std::vector<FairMQChannel>& channelList, const std::string& channelName, const FairMQChannel& commonChannel);
|
void SocketParser(const boost::property_tree::ptree& tree, std::vector<FairMQChannel>& channelList, const std::string& channelName, const FairMQChannel& commonChannel);
|
||||||
void PrintPropertyTree(const boost::property_tree::ptree& tree, int level = 0);
|
void PrintPropertyTree(const boost::property_tree::ptree& tree, int level = 0);
|
||||||
|
|
||||||
} // Helper namespace
|
} // Helper namespace
|
||||||
|
|
||||||
} // FairMQParser namespace
|
} // namespace parser
|
||||||
|
} // namespace mq
|
||||||
|
} // namespace fair
|
||||||
|
|
||||||
#endif /* FAIRMQPARSER_H */
|
#endif /* FAIRMQPARSER_H */
|
||||||
|
|
|
@ -31,7 +31,7 @@ FairMQProgOptions::FairMQProgOptions()
|
||||||
, fMQKeyMap()
|
, fMQKeyMap()
|
||||||
{
|
{
|
||||||
InitOptionDescription();
|
InitOptionDescription();
|
||||||
ParseDefaults(fCmdLineOptions);
|
ParseDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
FairMQProgOptions::~FairMQProgOptions()
|
FairMQProgOptions::~FairMQProgOptions()
|
||||||
|
@ -52,7 +52,7 @@ int FairMQProgOptions::ParseAll(const vector<string>& cmdLineArgs, bool allowUnr
|
||||||
|
|
||||||
int FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool allowUnregistered)
|
int FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool allowUnregistered)
|
||||||
{
|
{
|
||||||
if (FairProgOptions::ParseCmdLine(argc, argv, fCmdLineOptions, fVarMap, allowUnregistered))
|
if (FairProgOptions::ParseCmdLine(argc, argv, allowUnregistered))
|
||||||
{
|
{
|
||||||
// ParseCmdLine returns 0 if no immediate switches found.
|
// ParseCmdLine returns 0 if no immediate switches found.
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -83,93 +83,53 @@ int FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool al
|
||||||
fair::Logger::SetConsoleSeverity(severity);
|
fair::Logger::SetConsoleSeverity(severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if one of required MQ config option is there
|
string id;
|
||||||
auto parserOptions = fMQParserOptions.options();
|
|
||||||
bool optionExists = false;
|
|
||||||
vector<string> MQParserKeys;
|
|
||||||
for (const auto& p : parserOptions)
|
|
||||||
{
|
|
||||||
MQParserKeys.push_back(p->canonical_display_name());
|
|
||||||
if (fVarMap.count(p->canonical_display_name()))
|
|
||||||
{
|
|
||||||
optionExists = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!optionExists)
|
// check if config-key for config parser is provided
|
||||||
|
if (fVarMap.count("config-key"))
|
||||||
{
|
{
|
||||||
LOG(warn) << "FairMQProgOptions: no channels configuration provided via neither of:";
|
id = fVarMap["config-key"].as<string>();
|
||||||
for (const auto& p : MQParserKeys)
|
|
||||||
{
|
|
||||||
LOG(warn) << " --" << p;
|
|
||||||
}
|
|
||||||
LOG(warn) << "No channels will be created (You can create them manually).";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string id;
|
id = fVarMap["id"].as<string>();
|
||||||
|
}
|
||||||
|
|
||||||
if (fVarMap.count("config-key"))
|
// check if any config parser is selected
|
||||||
{
|
try
|
||||||
id = fVarMap["config-key"].as<string>();
|
{
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id = fVarMap["id"].as<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// if cmdline mq-config called then use the default xml/json parser
|
|
||||||
if (fVarMap.count("mq-config"))
|
if (fVarMap.count("mq-config"))
|
||||||
{
|
{
|
||||||
LOG(debug) << "mq-config: Using default XML/JSON parser";
|
LOG(debug) << "mq-config: Using default JSON parser";
|
||||||
|
Store(fair::mq::parser::JSON().UserParser(fVarMap["mq-config"].as<string>(), id));
|
||||||
string file = fVarMap["mq-config"].as<string>();
|
|
||||||
|
|
||||||
string ext = boost::filesystem::extension(file);
|
|
||||||
|
|
||||||
transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
|
|
||||||
|
|
||||||
if (ext == ".json")
|
|
||||||
{
|
|
||||||
UserParser<FairMQParser::JSON>(file, id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ext == ".xml")
|
|
||||||
{
|
|
||||||
UserParser<FairMQParser::XML>(file, id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(error) << "mq-config command line called but file extension '" << ext << "' not recognized. Program will now exit";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (fVarMap.count("config-json-string"))
|
else if (fVarMap.count("config-json-string"))
|
||||||
{
|
{
|
||||||
LOG(debug) << "config-json-string: Parsing JSON string";
|
LOG(debug) << "config-json-string: Parsing JSON string";
|
||||||
|
string value = fair::mq::ConvertVariableValue<fair::mq::VarInfoToString>()(fVarMap.at("config-json-string"));
|
||||||
string value = FairMQ::ConvertVariableValue<FairMQ::ToString>().Run(fVarMap.at("config-json-string"));
|
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << value;
|
ss << value;
|
||||||
UserParser<FairMQParser::JSON>(ss, id);
|
Store(fair::mq::parser::JSON().UserParser(ss, id));
|
||||||
}
|
}
|
||||||
else if (fVarMap.count("config-xml-string"))
|
else if (fVarMap.count("channel-config"))
|
||||||
{
|
|
||||||
LOG(debug) << "config-json-string: Parsing XML string";
|
|
||||||
|
|
||||||
string value = FairMQ::ConvertVariableValue<FairMQ::ToString>().Run(fVarMap.at("config-xml-string"));
|
|
||||||
stringstream ss;
|
|
||||||
ss << value;
|
|
||||||
UserParser<FairMQParser::XML>(ss, id);
|
|
||||||
}
|
|
||||||
else if (fVarMap.count(FairMQParser::SUBOPT::OptionKeyChannelConfig))
|
|
||||||
{
|
{
|
||||||
LOG(debug) << "channel-config: Parsing channel configuration";
|
LOG(debug) << "channel-config: Parsing channel configuration";
|
||||||
UserParser<FairMQParser::SUBOPT>(fVarMap, id);
|
Store(fair::mq::parser::SUBOPT().UserParser(fVarMap.at("channel-config").as<vector<string>>(), id));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(warn) << "FairMQProgOptions: no channels configuration provided via neither of:";
|
||||||
|
for (const auto& p : fMQParserOptions.options())
|
||||||
|
{
|
||||||
|
LOG(warn) << "--" << p->canonical_display_name();
|
||||||
|
}
|
||||||
|
LOG(warn) << "No channels will be created (You can create them manually).";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
LOG(error) << e.what();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FairProgOptions::PrintOptions();
|
FairProgOptions::PrintOptions();
|
||||||
|
@ -223,15 +183,15 @@ void FairMQProgOptions::UpdateMQValues()
|
||||||
string rcvKernelSizeKey = "chans." + p.first + "." + to_string(index) + ".rcvKernelSize";
|
string rcvKernelSizeKey = "chans." + p.first + "." + to_string(index) + ".rcvKernelSize";
|
||||||
string rateLoggingKey = "chans." + p.first + "." + to_string(index) + ".rateLogging";
|
string rateLoggingKey = "chans." + p.first + "." + to_string(index) + ".rateLogging";
|
||||||
|
|
||||||
fMQKeyMap[typeKey] = make_tuple(p.first, index, "type");
|
fMQKeyMap[typeKey] = MQKey{p.first, index, "type"};
|
||||||
fMQKeyMap[methodKey] = make_tuple(p.first, index, "method");
|
fMQKeyMap[methodKey] = MQKey{p.first, index, "method"};
|
||||||
fMQKeyMap[addressKey] = make_tuple(p.first, index, "address");
|
fMQKeyMap[addressKey] = MQKey{p.first, index, "address"};
|
||||||
fMQKeyMap[transportKey] = make_tuple(p.first, index, "transport");
|
fMQKeyMap[transportKey] = MQKey{p.first, index, "transport"};
|
||||||
fMQKeyMap[sndBufSizeKey] = make_tuple(p.first, index, "sndBufSize");
|
fMQKeyMap[sndBufSizeKey] = MQKey{p.first, index, "sndBufSize"};
|
||||||
fMQKeyMap[rcvBufSizeKey] = make_tuple(p.first, index, "rcvBufSize");
|
fMQKeyMap[rcvBufSizeKey] = MQKey{p.first, index, "rcvBufSize"};
|
||||||
fMQKeyMap[sndKernelSizeKey] = make_tuple(p.first, index, "sndKernelSize");
|
fMQKeyMap[sndKernelSizeKey] = MQKey{p.first, index, "sndKernelSize"};
|
||||||
fMQKeyMap[rcvKernelSizeKey] = make_tuple(p.first, index, "rcvkernelSize");
|
fMQKeyMap[rcvKernelSizeKey] = MQKey{p.first, index, "rcvkernelSize"};
|
||||||
fMQKeyMap[rateLoggingKey] = make_tuple(p.first, index, "rateLogging");
|
fMQKeyMap[rateLoggingKey] = MQKey{p.first, index, "rateLogging"};
|
||||||
|
|
||||||
UpdateVarMap<string>(typeKey, channel.GetType());
|
UpdateVarMap<string>(typeKey, channel.GetType());
|
||||||
UpdateVarMap<string>(methodKey, channel.GetMethod());
|
UpdateVarMap<string>(methodKey, channel.GetMethod());
|
||||||
|
@ -253,7 +213,7 @@ int FairMQProgOptions::ImmediateOptions()
|
||||||
{
|
{
|
||||||
if (fVarMap.count("help"))
|
if (fVarMap.count("help"))
|
||||||
{
|
{
|
||||||
cout << "===== FairMQ Program Options =====" << endl << fVisibleOptions;
|
cout << "===== FairMQ Program Options =====" << endl << fAllOptions;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,13 +245,11 @@ void FairMQProgOptions::InitOptionDescription()
|
||||||
;
|
;
|
||||||
|
|
||||||
fMQParserOptions.add_options()
|
fMQParserOptions.add_options()
|
||||||
("config-xml-string", po::value<vector<string>>()->multitoken(), "XML input as command line string.")
|
|
||||||
("config-json-string", po::value<vector<string>>()->multitoken(), "JSON input as command line string.")
|
("config-json-string", po::value<vector<string>>()->multitoken(), "JSON input as command line string.")
|
||||||
("mq-config", po::value<string>(), "JSON/XML input as file. The configuration object will check xml or json file extention and will call the json or xml parser accordingly")
|
("mq-config", po::value<string>(), "JSON/XML input as file. The configuration object will check xml or json file extention and will call the json or xml parser accordingly")
|
||||||
(FairMQParser::SUBOPT::OptionKeyChannelConfig, po::value<vector<string>>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list")
|
("channel-config", po::value<vector<string>>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list")
|
||||||
;
|
;
|
||||||
|
|
||||||
AddToCmdLineOptions(fGeneralDesc);
|
|
||||||
AddToCmdLineOptions(fMQCmdOptions);
|
AddToCmdLineOptions(fMQCmdOptions);
|
||||||
AddToCmdLineOptions(fMQParserOptions);
|
AddToCmdLineOptions(fMQParserOptions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,22 +52,6 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
// default parser for the mq-configuration file (JSON/XML) is called if command line key mq-config is called
|
// default parser for the mq-configuration file (JSON/XML) is called if command line key mq-config is called
|
||||||
int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) override;
|
int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) override;
|
||||||
|
|
||||||
// external parser, store function
|
|
||||||
template <typename T, typename ...Args>
|
|
||||||
int UserParser(Args &&... args)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Store(T().UserParser(std::forward<Args>(args)...));
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
LOG(error) << e.what();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FairMQMap GetFairMQMap() const
|
FairMQMap GetFairMQMap() const
|
||||||
{
|
{
|
||||||
return fFairMQMap;
|
return fFairMQMap;
|
||||||
|
@ -78,12 +62,6 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
return fChannelInfo;
|
return fChannelInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store key-value of type T into variable_map.
|
|
||||||
// If key is found in fMQKeyMap, update the FairMQChannelMap accordingly
|
|
||||||
// Note that the fMQKeyMap is filled:
|
|
||||||
// - if UpdateChannelMap(const FairMQMap& map) method is called
|
|
||||||
// - if UserParser template method is called (it is called in the ParseAll method if json or xml MQ-config files is provided)
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int UpdateValue(const std::string& key, T val)
|
int UpdateValue(const std::string& key, T val)
|
||||||
{
|
{
|
||||||
|
@ -99,11 +77,7 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
{
|
{
|
||||||
if (fMQKeyMap.count(key))
|
if (fMQKeyMap.count(key))
|
||||||
{
|
{
|
||||||
std::string channelName;
|
UpdateChannelMap(fMQKeyMap.at(key).channel, fMQKeyMap.at(key).index, fMQKeyMap.at(key).member, val);
|
||||||
int index = 0;
|
|
||||||
std::string member;
|
|
||||||
std::tie(channelName, index, member) = fMQKeyMap.at(key);
|
|
||||||
UpdateChannelMap(channelName, index, member, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,11 +109,7 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
{
|
{
|
||||||
if (fMQKeyMap.count(key))
|
if (fMQKeyMap.count(key))
|
||||||
{
|
{
|
||||||
std::string channelName;
|
UpdateChannelMap(fMQKeyMap.at(key).channel, fMQKeyMap.at(key).index, fMQKeyMap.at(key).member, val);
|
||||||
int index = 0;
|
|
||||||
std::string member;
|
|
||||||
std::tie(channelName, index, member) = fMQKeyMap.at(key);
|
|
||||||
UpdateChannelMap(channelName, index, member, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,6 +159,13 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
int UpdateChannelMap(const FairMQMap& map);
|
int UpdateChannelMap(const FairMQMap& map);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
struct MQKey
|
||||||
|
{
|
||||||
|
std::string channel;
|
||||||
|
int index;
|
||||||
|
std::string member;
|
||||||
|
};
|
||||||
|
|
||||||
po::options_description fMQCmdOptions;
|
po::options_description fMQCmdOptions;
|
||||||
po::options_description fMQParserOptions;
|
po::options_description fMQParserOptions;
|
||||||
FairMQMap fFairMQMap;
|
FairMQMap fFairMQMap;
|
||||||
|
@ -196,7 +173,6 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
// map of read channel info - channel name - number of subchannels
|
// map of read channel info - channel name - number of subchannels
|
||||||
std::unordered_map<std::string, int> fChannelInfo;
|
std::unordered_map<std::string, int> fChannelInfo;
|
||||||
|
|
||||||
using MQKey = std::tuple<std::string, int, std::string>;//store key info
|
|
||||||
std::map<std::string, MQKey> fMQKeyMap;// key=full path - val=key info
|
std::map<std::string, MQKey> fMQKeyMap;// key=full path - val=key info
|
||||||
|
|
||||||
int ImmediateOptions() override; // for custom help & version printing
|
int ImmediateOptions() override; // for custom help & version printing
|
||||||
|
|
|
@ -12,68 +12,81 @@
|
||||||
/// @brief Parser implementation for key-value subopt format
|
/// @brief Parser implementation for key-value subopt format
|
||||||
|
|
||||||
#include "FairMQSuboptParser.h"
|
#include "FairMQSuboptParser.h"
|
||||||
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <utility> // make_pair
|
||||||
|
|
||||||
using boost::property_tree::ptree;
|
using boost::property_tree::ptree;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
namespace FairMQParser
|
namespace fair
|
||||||
|
{
|
||||||
|
namespace mq
|
||||||
|
{
|
||||||
|
namespace parser
|
||||||
{
|
{
|
||||||
|
|
||||||
constexpr const char* SUBOPT::channelOptionKeys[];
|
constexpr const char* SUBOPT::channelOptionKeys[];
|
||||||
|
|
||||||
FairMQMap SUBOPT::UserParser(const po::variables_map& omap, const std::string& deviceId, const std::string& rootNode)
|
FairMQMap SUBOPT::UserParser(const vector<string>& channelConfig, const string& deviceId, const string& rootNode)
|
||||||
{
|
{
|
||||||
std::string nodeKey = rootNode + ".device";
|
|
||||||
ptree pt;
|
ptree pt;
|
||||||
|
|
||||||
pt.put(nodeKey + ".id", deviceId.c_str());
|
ptree devicesArray;
|
||||||
nodeKey += ".channels";
|
ptree deviceProperties;
|
||||||
|
|
||||||
// parsing of channel properties is the only implemented method right now
|
ptree channelsArray;
|
||||||
if (omap.count(OptionKeyChannelConfig) > 0)
|
|
||||||
|
for (auto token : channelConfig)
|
||||||
{
|
{
|
||||||
std::map<std::string, ptree> channelProperties;
|
string channelName;
|
||||||
auto tokens = omap[OptionKeyChannelConfig].as<std::vector<std::string>>();
|
ptree channelProperties;
|
||||||
for (auto token : tokens)
|
|
||||||
|
ptree socketsArray;
|
||||||
|
ptree socketProperties;
|
||||||
|
|
||||||
|
string argString(token);
|
||||||
|
char* subopts = &argString[0];
|
||||||
|
char* value = nullptr;
|
||||||
|
while (subopts && *subopts != 0 && *subopts != ' ')
|
||||||
{
|
{
|
||||||
// std::map<std::string, ptree>::iterator channelProperty = channelProperties.end();
|
int subopt = getsubopt(&subopts, (char**)channelOptionKeys, &value);
|
||||||
ptree socketProperty;
|
if (subopt == NAME)
|
||||||
std::string channelName;
|
|
||||||
std::string argString(token);
|
|
||||||
char* subopts = &argString[0];
|
|
||||||
char* value = nullptr;
|
|
||||||
while (subopts && *subopts != 0 && *subopts != ' ')
|
|
||||||
{
|
{
|
||||||
// char* saved = subopts;
|
channelName = value;
|
||||||
int subopt=getsubopt(&subopts, (char**)channelOptionKeys, &value);
|
channelProperties.put("name", channelName);
|
||||||
if (subopt == NAME)
|
|
||||||
{
|
|
||||||
channelName = value;
|
|
||||||
channelProperties[channelName].put("name", channelName);
|
|
||||||
}
|
|
||||||
else if (subopt>=0 && value != nullptr)
|
|
||||||
{
|
|
||||||
socketProperty.put(channelOptionKeys[subopt], value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (channelName != "")
|
else if (subopt >= 0 && value != nullptr)
|
||||||
{
|
{
|
||||||
channelProperties[channelName].add_child("sockets.socket", socketProperty);
|
socketProperties.put(channelOptionKeys[subopt], value);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: what is the error policy here, should we abort?
|
|
||||||
LOG(error) << "missing channel name in argument of option --channel-config";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto channelProperty : channelProperties)
|
|
||||||
|
if (channelName != "")
|
||||||
{
|
{
|
||||||
pt.add_child(nodeKey + ".channel", channelProperty.second);
|
socketsArray.push_back(make_pair("", socketProperties));
|
||||||
|
channelProperties.add_child("sockets", socketsArray);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: what is the error policy here, should we abort?
|
||||||
|
LOG(error) << "missing channel name in argument of option --channel-config";
|
||||||
|
}
|
||||||
|
|
||||||
|
channelsArray.push_back(make_pair("", channelProperties));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deviceProperties.put("id", deviceId);
|
||||||
|
deviceProperties.add_child("channels", channelsArray);
|
||||||
|
|
||||||
|
devicesArray.push_back(make_pair("", deviceProperties));
|
||||||
|
|
||||||
|
pt.add_child("fairMQOptions.devices", devicesArray);
|
||||||
|
|
||||||
return ptreeToMQMap(pt, deviceId, rootNode);
|
return ptreeToMQMap(pt, deviceId, rootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace FairMQParser
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -17,11 +17,18 @@
|
||||||
#include "FairMQParser.h" // for FairMQMap
|
#include "FairMQParser.h" // for FairMQMap
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
namespace FairMQParser
|
namespace fair
|
||||||
{
|
{
|
||||||
|
namespace mq
|
||||||
|
{
|
||||||
|
namespace parser
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A parser implementation for FairMQ channel properties.
|
* A parser implementation for FairMQ channel properties.
|
||||||
* The parser handles a comma separated key=value list format by using the
|
* The parser handles a comma separated key=value list format by using the
|
||||||
|
@ -38,39 +45,42 @@ namespace FairMQParser
|
||||||
* the concept is extensible by renaming UserParser to ChannelPropertyParser
|
* the concept is extensible by renaming UserParser to ChannelPropertyParser
|
||||||
* and introducing additional parser functions.
|
* and introducing additional parser functions.
|
||||||
*/
|
*/
|
||||||
struct SUBOPT {
|
struct SUBOPT
|
||||||
enum channelOptionKeyIds {
|
{
|
||||||
NAME = 0, // name of the channel
|
enum channelOptionKeyIds
|
||||||
TYPE, // push, pull, publish, subscribe, etc
|
{
|
||||||
METHOD, // bind or connect
|
NAME = 0, // name of the channel
|
||||||
ADDRESS, // host, protocol and port address
|
TYPE, // push, pull, publish, subscribe, etc
|
||||||
TRANSPORT, //
|
METHOD, // bind or connect
|
||||||
SNDBUFSIZE, // size of the send queue
|
ADDRESS, // host, protocol and port address
|
||||||
RCVBUFSIZE, // size of the receive queue
|
TRANSPORT, //
|
||||||
SNDKERNELSIZE,
|
SNDBUFSIZE, // size of the send queue
|
||||||
RCVKERNELSIZE,
|
RCVBUFSIZE, // size of the receive queue
|
||||||
RATELOGGING, // logging rate
|
SNDKERNELSIZE,
|
||||||
lastsocketkey
|
RCVKERNELSIZE,
|
||||||
};
|
RATELOGGING, // logging rate
|
||||||
|
lastsocketkey
|
||||||
|
};
|
||||||
|
|
||||||
constexpr static const char *channelOptionKeys[] = {
|
constexpr static const char *channelOptionKeys[] = {
|
||||||
/*[NAME] = */ "name",
|
/*[NAME] = */ "name",
|
||||||
/*[TYPE] = */ "type",
|
/*[TYPE] = */ "type",
|
||||||
/*[METHOD] = */ "method",
|
/*[METHOD] = */ "method",
|
||||||
/*[ADDRESS] = */ "address",
|
/*[ADDRESS] = */ "address",
|
||||||
/*[TRANSPORT] = */ "transport",
|
/*[TRANSPORT] = */ "transport",
|
||||||
/*[SNDBUFSIZE] = */ "sndBufSize",
|
/*[SNDBUFSIZE] = */ "sndBufSize",
|
||||||
/*[RCVBUFSIZE] = */ "rcvBufSize",
|
/*[RCVBUFSIZE] = */ "rcvBufSize",
|
||||||
/*[SNDKERNELSIZE] = */ "sndKernelSize",
|
/*[SNDKERNELSIZE] = */ "sndKernelSize",
|
||||||
/*[RCVKERNELSIZE] = */ "rcvKernelSize",
|
/*[RCVKERNELSIZE] = */ "rcvKernelSize",
|
||||||
/*[RATELOGGING] = */ "rateLogging",
|
/*[RATELOGGING] = */ "rateLogging",
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static const char* OptionKeyChannelConfig = "channel-config";
|
FairMQMap UserParser(const std::vector<std::string>& channelConfig, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
|
||||||
|
|
||||||
FairMQMap UserParser(const po::variables_map& omap, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* FAIRMQPARSER_SUBOPT_H */
|
#endif /* FAIRMQPARSER_SUBOPT_H */
|
||||||
|
|
|
@ -19,15 +19,15 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace fair::mq;
|
||||||
|
|
||||||
FairProgOptions::FairProgOptions()
|
FairProgOptions::FairProgOptions()
|
||||||
: fVarMap()
|
: fVarMap()
|
||||||
, fGeneralDesc("General options")
|
, fGeneralOptions("General options")
|
||||||
, fCmdLineOptions("Command line options")
|
, fAllOptions("Command line options")
|
||||||
, fVisibleOptions("Visible options")
|
|
||||||
, fConfigMutex()
|
, fConfigMutex()
|
||||||
{
|
{
|
||||||
fGeneralDesc.add_options()
|
fGeneralOptions.add_options()
|
||||||
("help,h", "produce help")
|
("help,h", "produce help")
|
||||||
("version,v", "print version")
|
("version,v", "print version")
|
||||||
("severity", po::value<string>()->default_value("debug"), "Log severity level: trace, debug, info, state, warn, error, fatal, nolog")
|
("severity", po::value<string>()->default_value("debug"), "Log severity level: trace, debug, info, state, warn, error, fatal, nolog")
|
||||||
|
@ -35,6 +35,8 @@ FairProgOptions::FairProgOptions()
|
||||||
("color", po::value<bool>()->default_value(true), "Log color (true/false)")
|
("color", po::value<bool>()->default_value(true), "Log color (true/false)")
|
||||||
("log-to-file", po::value<string>()->default_value(""), "Log output to a file.")
|
("log-to-file", po::value<string>()->default_value(""), "Log output to a file.")
|
||||||
("print-options", po::value<bool>()->implicit_value(true), "print options in machine-readable format (<option>:<computed-value>:<type>:<description>)");
|
("print-options", po::value<bool>()->implicit_value(true), "print options in machine-readable format (<option>:<computed-value>:<type>:<description>)");
|
||||||
|
|
||||||
|
fAllOptions.add(fGeneralOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
FairProgOptions::~FairProgOptions()
|
FairProgOptions::~FairProgOptions()
|
||||||
|
@ -42,54 +44,45 @@ FairProgOptions::~FairProgOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add option descriptions
|
/// Add option descriptions
|
||||||
int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc, bool visible)
|
int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc, bool /* visible */)
|
||||||
{
|
{
|
||||||
fCmdLineOptions.add(optDesc);
|
fAllOptions.add(optDesc);
|
||||||
if (visible)
|
|
||||||
{
|
|
||||||
fVisibleOptions.add(optDesc);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
po::options_description& FairProgOptions::GetCmdLineOptions()
|
po::options_description& FairProgOptions::GetCmdLineOptions()
|
||||||
{
|
{
|
||||||
return fCmdLineOptions;
|
return fAllOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
|
int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, bool allowUnregistered)
|
||||||
{
|
{
|
||||||
// get options from cmd line and store in variable map
|
// get options from cmd line and store in variable map
|
||||||
// here we use command_line_parser instead of parse_command_line, to allow unregistered and positional options
|
// here we use command_line_parser instead of parse_command_line, to allow unregistered and positional options
|
||||||
if (allowUnregistered)
|
if (allowUnregistered)
|
||||||
{
|
{
|
||||||
po::command_line_parser parser{argc, argv};
|
po::command_line_parser parser{argc, argv};
|
||||||
parser.options(desc).allow_unregistered();
|
parser.options(fAllOptions).allow_unregistered();
|
||||||
po::parsed_options parsedOptions = parser.run();
|
po::parsed_options parsedOptions = parser.run();
|
||||||
po::store(parsedOptions, varmap);
|
po::store(parsedOptions, fVarMap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
po::store(po::parse_command_line(argc, argv, desc), varmap);
|
po::store(po::parse_command_line(argc, argv, fAllOptions), fVarMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles options like "--help" or "--version"
|
// Handles options like "--help" or "--version"
|
||||||
// return 1 if switch options found in varmap
|
// return 1 if switch options found in fVarMap
|
||||||
if (ImmediateOptions())
|
if (ImmediateOptions())
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
po::notify(varmap);
|
po::notify(fVarMap);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, bool allowUnregistered)
|
void FairProgOptions::ParseDefaults()
|
||||||
{
|
|
||||||
return ParseCmdLine(argc, argv, desc, fVarMap, allowUnregistered);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FairProgOptions::ParseDefaults(const po::options_description& desc)
|
|
||||||
{
|
{
|
||||||
vector<string> emptyArgs;
|
vector<string> emptyArgs;
|
||||||
emptyArgs.push_back("dummy");
|
emptyArgs.push_back("dummy");
|
||||||
|
@ -101,148 +94,85 @@ void FairProgOptions::ParseDefaults(const po::options_description& desc)
|
||||||
return str.c_str();
|
return str.c_str();
|
||||||
});
|
});
|
||||||
|
|
||||||
po::store(po::parse_command_line(argv.size(), const_cast<char**>(argv.data()), desc), fVarMap);
|
po::store(po::parse_command_line(argv.size(), const_cast<char**>(argv.data()), fAllOptions), fVarMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FairProgOptions::PrintOptions()
|
int FairProgOptions::PrintOptions()
|
||||||
{
|
{
|
||||||
// Method to overload.
|
|
||||||
// -> loop over variable map and print its content
|
// -> loop over variable map and print its content
|
||||||
// -> In this example the following types are supported:
|
// -> In this example the following types are supported:
|
||||||
// string, int, float, double, short, boost::filesystem::path
|
// string, int, float, double, short, boost::filesystem::path
|
||||||
// vector<string>, vector<int>, vector<float>, vector<double>, vector<short>
|
// vector<string>, vector<int>, vector<float>, vector<double>, vector<short>
|
||||||
|
|
||||||
MapVarValInfo_t mapinfo;
|
map<string, VarValInfo> mapinfo;
|
||||||
|
|
||||||
// get string length for formatting and convert varmap values into string
|
// get string length for formatting and convert varmap values into string
|
||||||
int maxLength1st = 0;
|
int maxLen1st = 0;
|
||||||
int maxLength2nd = 0;
|
int maxLen2nd = 0;
|
||||||
int maxLengthTypeInfo = 0;
|
int maxLenTypeInfo = 0;
|
||||||
int maxLengthDefault = 0;
|
int maxLenDefault = 0;
|
||||||
int maxLengthEmpty = 0;
|
int maxLenEmpty = 0;
|
||||||
int totalLength = 0;
|
|
||||||
for (const auto& m : fVarMap)
|
for (const auto& m : fVarMap)
|
||||||
{
|
{
|
||||||
Max(maxLength1st, m.first.length());
|
Max(maxLen1st, m.first.length());
|
||||||
|
|
||||||
VarValInfo_t valinfo = GetVariableValueInfo(m.second);
|
VarValInfo valinfo = GetVariableValueInfo(m.second);
|
||||||
mapinfo[m.first] = valinfo;
|
mapinfo[m.first] = valinfo;
|
||||||
string valueStr;
|
|
||||||
string typeInfoStr;
|
|
||||||
string defaultStr;
|
|
||||||
string emptyStr;
|
|
||||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = valinfo;
|
|
||||||
|
|
||||||
Max(maxLength2nd, valueStr.length());
|
Max(maxLen2nd, valinfo.value.length());
|
||||||
Max(maxLengthTypeInfo, typeInfoStr.length());
|
Max(maxLenTypeInfo, valinfo.type.length());
|
||||||
Max(maxLengthDefault, defaultStr.length());
|
Max(maxLenDefault, valinfo.defaulted.length());
|
||||||
Max(maxLengthEmpty, emptyStr.length());
|
Max(maxLenEmpty, valinfo.empty.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : limit the value length field in a better way
|
// TODO : limit the value len field in a better way
|
||||||
if (maxLength2nd > 100)
|
if (maxLen2nd > 100)
|
||||||
{
|
{
|
||||||
maxLength2nd = 100;
|
maxLen2nd = 100;
|
||||||
}
|
}
|
||||||
totalLength = maxLength1st + maxLength2nd + maxLengthTypeInfo + maxLengthDefault + maxLengthEmpty;
|
|
||||||
|
|
||||||
// maxLength2nd = 200;
|
|
||||||
|
|
||||||
// formatting and printing
|
|
||||||
|
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << "\n";
|
ss << "Configuration: \n";
|
||||||
|
|
||||||
ss << setfill('*') << setw(totalLength + 3) << "*" << "\n"; // +3 because of string " = "
|
|
||||||
string title = " Configuration ";
|
|
||||||
|
|
||||||
int leftSpaceLength = 0;
|
|
||||||
int rightSpaceLength = 0;
|
|
||||||
int leftTitleShiftLength = 0;
|
|
||||||
int rightTitleShiftLength = 0;
|
|
||||||
|
|
||||||
leftTitleShiftLength = title.length() / 2;
|
|
||||||
|
|
||||||
if ((title.length()) % 2)
|
|
||||||
{
|
|
||||||
rightTitleShiftLength = leftTitleShiftLength + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rightTitleShiftLength = leftTitleShiftLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
leftSpaceLength = (totalLength + 3) / 2 - leftTitleShiftLength;
|
|
||||||
if ((totalLength + 3) % 2)
|
|
||||||
{
|
|
||||||
rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
ss << setfill ('*') << setw(leftSpaceLength) << "*"
|
|
||||||
<< setw(title.length()) << title
|
|
||||||
<< setfill ('*') << setw(rightSpaceLength) << "*" << "\n";
|
|
||||||
|
|
||||||
ss << setfill ('*') << setw (totalLength+3) << "*" << "\n";
|
|
||||||
|
|
||||||
for (const auto& p : mapinfo)
|
for (const auto& p : mapinfo)
|
||||||
{
|
{
|
||||||
string keyStr;
|
|
||||||
string valueStr;
|
|
||||||
string typeInfoStr;
|
|
||||||
string defaultStr;
|
|
||||||
string emptyStr;
|
|
||||||
keyStr = p.first;
|
|
||||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
|
||||||
ss << setfill(' ')
|
ss << setfill(' ')
|
||||||
<< setw(maxLength1st) << left
|
<< setw(maxLen1st) << left << p.first << " = "
|
||||||
<< p.first << " = "
|
<< setw(maxLen2nd) << p.second.value
|
||||||
<< setw(maxLength2nd)
|
<< setw(maxLenTypeInfo) << p.second.type
|
||||||
<< valueStr
|
<< setw(maxLenDefault) << p.second.defaulted
|
||||||
<< setw(maxLengthTypeInfo)
|
<< setw(maxLenEmpty) << p.second.empty
|
||||||
<< typeInfoStr
|
|
||||||
<< setw(maxLengthDefault)
|
|
||||||
<< defaultStr
|
|
||||||
<< setw(maxLengthEmpty)
|
|
||||||
<< emptyStr
|
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
ss << setfill ('*') << setw(totalLength + 3) << "*";// +3 for " = "
|
|
||||||
|
|
||||||
LOG(debug) << ss.str();
|
LOG(info) << ss.str();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FairProgOptions::PrintOptionsRaw()
|
int FairProgOptions::PrintOptionsRaw()
|
||||||
{
|
{
|
||||||
MapVarValInfo_t mapInfo;
|
const std::vector<boost::shared_ptr<po::option_description>>& options = fAllOptions.options();
|
||||||
|
|
||||||
for (const auto& m : fVarMap)
|
for (const auto& o : options)
|
||||||
{
|
{
|
||||||
mapInfo[m.first] = GetVariableValueInfo(m.second);
|
VarValInfo value;
|
||||||
}
|
if (fVarMap.count(o->canonical_display_name()))
|
||||||
|
{
|
||||||
|
value = GetVariableValueInfo(fVarMap[o->canonical_display_name()]);
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& p : mapInfo)
|
string description = o->description();
|
||||||
{
|
|
||||||
string keyStr;
|
replace(description.begin(), description.end(), '\n', ' ');
|
||||||
string valueStr;
|
|
||||||
string typeInfoStr;
|
cout << o->long_name() << ":" << value.value << ":" << (value.type == "" ? "<unknown>" : value.type) << ":" << description << endl;
|
||||||
string defaultStr;
|
|
||||||
string emptyStr;
|
|
||||||
keyStr = p.first;
|
|
||||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
|
||||||
auto option = fCmdLineOptions.find_nothrow(keyStr, false);
|
|
||||||
cout << keyStr << ":" << valueStr << ":" << typeInfoStr << ":" << (option ? option->description() : "<not found>") << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FairProgOptions::VarValInfo_t FairProgOptions::GetVariableValueInfo(const po::variable_value& varValue)
|
VarValInfo FairProgOptions::GetVariableValueInfo(const po::variable_value& varValue)
|
||||||
{
|
{
|
||||||
return FairMQ::ConvertVariableValue<FairMQ::ToVarInfo>().Run(varValue);
|
return ConvertVariableValue<ToVarValInfo>()(varValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,35 +26,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FairProgOptions abstract base class
|
|
||||||
* parse command line, configuration file options.
|
|
||||||
*
|
|
||||||
* The user defines in the derived class the option descriptions and
|
|
||||||
* the pure virtual ParseAll() method
|
|
||||||
*
|
|
||||||
* class MyOptions : public FairProgOptions
|
|
||||||
* {
|
|
||||||
* public :
|
|
||||||
* MyOptions() : FairProgOptions()
|
|
||||||
* {
|
|
||||||
* fCmdlineOptions.add(fGenericDesc);
|
|
||||||
* fVisibleOptions.add(fCmdlineOptions);
|
|
||||||
* }
|
|
||||||
* virtual ~MyOptions() {}
|
|
||||||
* virtual void ParseAll(const int argc, char** argv, bool allowUnregistered = false)
|
|
||||||
* {
|
|
||||||
* if (ParseCmdLine(argc, argv, fCmdlineOptions, fVarMap, allowUnregistered))
|
|
||||||
* {
|
|
||||||
* exit(EXIT_FAILURE);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* PrintOptions();
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
@ -120,7 +91,7 @@ class FairProgOptions
|
||||||
{
|
{
|
||||||
if (fVarMap.count(key))
|
if (fVarMap.count(key))
|
||||||
{
|
{
|
||||||
valueStr = FairMQ::ConvertVariableValue<FairMQ::ToString>().Run(fVarMap.at(key));
|
valueStr = fair::mq::ConvertVariableValue<fair::mq::VarInfoToString>()(fVarMap.at(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
|
@ -158,12 +129,10 @@ class FairProgOptions
|
||||||
|
|
||||||
const po::variables_map& GetVarMap() const { return fVarMap; }
|
const po::variables_map& GetVarMap() const { return fVarMap; }
|
||||||
|
|
||||||
// boost prog options parsers
|
int ParseCmdLine(const int argc, char const* const* argv, bool allowUnregistered = false);
|
||||||
int ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
|
void ParseDefaults();
|
||||||
int ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, bool allowUnregistered = false);
|
|
||||||
void ParseDefaults(const po::options_description& desc);
|
|
||||||
|
|
||||||
virtual int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) = 0;// TODO change return type to bool and propagate to executable
|
virtual int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) = 0;
|
||||||
|
|
||||||
virtual int PrintOptions();
|
virtual int PrintOptions();
|
||||||
virtual int PrintOptionsRaw();
|
virtual int PrintOptionsRaw();
|
||||||
|
@ -172,37 +141,29 @@ class FairProgOptions
|
||||||
// options container
|
// options container
|
||||||
po::variables_map fVarMap;
|
po::variables_map fVarMap;
|
||||||
|
|
||||||
// basic description categories
|
// options descriptions
|
||||||
po::options_description fGeneralDesc;
|
po::options_description fGeneralOptions;
|
||||||
|
po::options_description fAllOptions;
|
||||||
po::options_description fCmdLineOptions;
|
|
||||||
|
|
||||||
// Description which is printed in help command line
|
|
||||||
po::options_description fVisibleOptions;
|
|
||||||
|
|
||||||
mutable std::mutex fConfigMutex;
|
mutable std::mutex fConfigMutex;
|
||||||
|
|
||||||
virtual int ImmediateOptions() = 0;
|
virtual int ImmediateOptions() = 0;
|
||||||
|
|
||||||
// UpdateVarMap() and replace() --> helper functions to modify the value of variable map after calling po::store
|
// UpdateVarMap() and Replace() --> helper functions to modify the value of variable map after calling po::store
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void UpdateVarMap(const std::string& key, const T& val)
|
void UpdateVarMap(const std::string& key, const T& val)
|
||||||
{
|
{
|
||||||
replace(fVarMap, key, val);
|
Replace(fVarMap, key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void replace(std::map<std::string, po::variable_value>& vm, const std::string& key, const T& val)
|
void Replace(std::map<std::string, po::variable_value>& vm, const std::string& key, const T& val)
|
||||||
{
|
{
|
||||||
vm[key].value() = boost::any(val);
|
vm[key].value() = boost::any(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Methods below are helper functions used in the PrintOptions method
|
fair::mq::VarValInfo GetVariableValueInfo(const po::variable_value& varValue);
|
||||||
using VarValInfo_t = std::tuple<std::string, std::string, std::string, std::string>;
|
|
||||||
using MapVarValInfo_t = std::map<std::string, VarValInfo_t>;
|
|
||||||
|
|
||||||
VarValInfo_t GetVariableValueInfo(const po::variable_value& varValue);
|
|
||||||
|
|
||||||
static void Max(int& val, const int& comp)
|
static void Max(int& val, const int& comp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,9 +21,21 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <ostream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <tuple>
|
|
||||||
|
namespace fair
|
||||||
|
{
|
||||||
|
namespace mq
|
||||||
|
{
|
||||||
|
|
||||||
|
struct VarValInfo
|
||||||
|
{
|
||||||
|
std::string value;
|
||||||
|
std::string type;
|
||||||
|
std::string defaulted;
|
||||||
|
std::string empty;
|
||||||
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
|
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
|
||||||
|
@ -32,23 +44,22 @@ std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace FairMQ
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool is_this_type(const po::variable_value& varValue)
|
bool typeIs(const boost::program_options::variable_value& varValue)
|
||||||
{
|
{
|
||||||
auto& value = varValue.value();
|
auto& value = varValue.value();
|
||||||
if (auto q = boost::any_cast<T>(&value))
|
if (auto q = boost::any_cast<T>(&value))
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::string ConvertVariableValueToString(const po::variable_value& varValue)
|
std::string ConvertVariableValueToString(const boost::program_options::variable_value& varValue)
|
||||||
{
|
{
|
||||||
auto& value = varValue.value();
|
auto& value = varValue.value();
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
|
@ -62,7 +73,7 @@ std::string ConvertVariableValueToString(const po::variable_value& varValue)
|
||||||
|
|
||||||
// string specialization
|
// string specialization
|
||||||
template<>
|
template<>
|
||||||
inline std::string ConvertVariableValueToString<std::string>(const po::variable_value& varValue)
|
inline std::string ConvertVariableValueToString<std::string>(const boost::program_options::variable_value& varValue)
|
||||||
{
|
{
|
||||||
auto& value = varValue.value();
|
auto& value = varValue.value();
|
||||||
std::string valueStr;
|
std::string valueStr;
|
||||||
|
@ -75,7 +86,7 @@ inline std::string ConvertVariableValueToString<std::string>(const po::variable_
|
||||||
|
|
||||||
// boost::filesystem::path specialization
|
// boost::filesystem::path specialization
|
||||||
template<>
|
template<>
|
||||||
inline std::string ConvertVariableValueToString<boost::filesystem::path>(const po::variable_value& varValue)
|
inline std::string ConvertVariableValueToString<boost::filesystem::path>(const boost::program_options::variable_value& varValue)
|
||||||
{
|
{
|
||||||
auto& value = varValue.value();
|
auto& value = varValue.value();
|
||||||
std::string valueStr;
|
std::string valueStr;
|
||||||
|
@ -87,11 +98,12 @@ inline std::string ConvertVariableValueToString<boost::filesystem::path>(const p
|
||||||
}
|
}
|
||||||
|
|
||||||
// policy to convert boost variable value into string
|
// policy to convert boost variable value into string
|
||||||
struct ToString
|
struct VarInfoToString
|
||||||
{
|
{
|
||||||
using returned_type = std::string;
|
using returned_type = std::string;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::string Value(const po::variable_value& varValue, const std::string&, const std::string&, const std::string&)
|
std::string Value(const boost::program_options::variable_value& varValue, const std::string&, const std::string&, const std::string&)
|
||||||
{
|
{
|
||||||
return ConvertVariableValueToString<T>(varValue);
|
return ConvertVariableValueToString<T>(varValue);
|
||||||
}
|
}
|
||||||
|
@ -102,20 +114,21 @@ struct ToString
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// policy to convert variable value content into a tuple with value, type, defaulted, empty information
|
// policy to convert variable value content into VarValInfo
|
||||||
struct ToVarInfo
|
struct ToVarValInfo
|
||||||
{
|
{
|
||||||
using returned_type = std::tuple<std::string, std::string,std::string, std::string>;
|
using returned_type = fair::mq::VarValInfo;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
returned_type Value(const po::variable_value& varValue, const std::string& type, const std::string& defaulted, const std::string& empty)
|
returned_type Value(const boost::program_options::variable_value& varValue, const std::string& type, const std::string& defaulted, const std::string& empty)
|
||||||
{
|
{
|
||||||
std::string valueStr = ConvertVariableValueToString<T>(varValue);
|
std::string valueStr = ConvertVariableValueToString<T>(varValue);
|
||||||
return make_tuple(valueStr, type, defaulted, empty);
|
return fair::mq::VarValInfo{valueStr, type, defaulted, empty};
|
||||||
}
|
}
|
||||||
|
|
||||||
returned_type DefaultValue(const std::string& defaulted, const std::string& empty)
|
returned_type DefaultValue(const std::string& defaulted, const std::string& empty)
|
||||||
{
|
{
|
||||||
return make_tuple(std::string("Unknown value"), std::string(" [Unknown]"), defaulted, empty);
|
return fair::mq::VarValInfo{std::string("Unknown value"), std::string(" [Unknown]"), defaulted, empty};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,113 +136,90 @@ struct ToVarInfo
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct ConvertVariableValue : T
|
struct ConvertVariableValue : T
|
||||||
{
|
{
|
||||||
//typename T::returned_type Run(const po::variable_value& varValue) //-> decltype(T::returned_type)
|
auto operator()(const boost::program_options::variable_value& varValue) -> typename T::returned_type
|
||||||
auto Run(const po::variable_value& varValue) -> typename T::returned_type
|
|
||||||
{
|
{
|
||||||
std::string defaultedValue;
|
std::string defaulted;
|
||||||
std::string emptyValue;
|
std::string empty;
|
||||||
|
|
||||||
if (varValue.empty())
|
if (varValue.empty())
|
||||||
{
|
{
|
||||||
emptyValue = " [empty]";
|
empty = " [empty]";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (varValue.defaulted())
|
if (varValue.defaulted())
|
||||||
{
|
{
|
||||||
defaultedValue = " [default]";
|
defaulted = " [default]";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
defaultedValue = " [provided]";
|
defaulted = " [provided]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// emptyValue += " *";
|
if (typeIs<std::string>(varValue))
|
||||||
|
return T::template Value<std::string>(varValue, std::string("<string>"), defaulted, empty);
|
||||||
|
|
||||||
//////////////////////////////// std types
|
if (typeIs<std::vector<std::string>>(varValue))
|
||||||
// std::string albeit useless here
|
return T::template Value<std::vector<std::string>>(varValue, std::string("<vector<string>>"), defaulted, empty);
|
||||||
if (is_this_type<std::string>(varValue))
|
|
||||||
return T::template Value<std::string>(varValue, std::string("<string>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// std::vector<std::string>
|
if (typeIs<int>(varValue))
|
||||||
if (is_this_type<std::vector<std::string>>(varValue))
|
return T::template Value<int>(varValue, std::string("<int>"), defaulted, empty);
|
||||||
return T::template Value<std::vector<std::string>>(varValue, std::string("<vector<string>>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// int
|
if (typeIs<std::vector<int>>(varValue))
|
||||||
if (is_this_type<int>(varValue))
|
return T::template Value<std::vector<int>>(varValue, std::string("<vector<int>>"), defaulted, empty);
|
||||||
return T::template Value<int>(varValue, std::string("<int>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// std::vector<int>
|
if (typeIs<float>(varValue))
|
||||||
if (is_this_type<std::vector<int>>(varValue))
|
return T::template Value<float>(varValue, std::string("<float>"), defaulted, empty);
|
||||||
return T::template Value<std::vector<int>>(varValue, std::string("<vector<int>>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// float
|
if (typeIs<std::vector<float>>(varValue))
|
||||||
if (is_this_type<float>(varValue))
|
return T::template Value<std::vector<float>>(varValue, std::string("<vector<float>>"), defaulted, empty);
|
||||||
return T::template Value<float>(varValue, std::string("<float>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// std::vector float
|
if (typeIs<double>(varValue))
|
||||||
if (is_this_type<std::vector<float>>(varValue))
|
return T::template Value<double>(varValue, std::string("<double>"), defaulted, empty);
|
||||||
return T::template Value<std::vector<float>>(varValue, std::string("<vector<float>>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// double
|
if (typeIs<std::vector<double>>(varValue))
|
||||||
if (is_this_type<double>(varValue))
|
return T::template Value<std::vector<double>>(varValue, std::string("<vector<double>>"), defaulted, empty);
|
||||||
return T::template Value<double>(varValue, std::string("<double>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// std::vector double
|
if (typeIs<short>(varValue))
|
||||||
if (is_this_type<std::vector<double>>(varValue))
|
return T::template Value<short>(varValue, std::string("<short>"), defaulted, empty);
|
||||||
return T::template Value<std::vector<double>>(varValue, std::string("<vector<double>>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// short
|
if (typeIs<std::vector<short>>(varValue))
|
||||||
if (is_this_type<short>(varValue))
|
return T::template Value<std::vector<short>>(varValue, std::string("<vector<short>>"), defaulted, empty);
|
||||||
return T::template Value<short>(varValue, std::string("<short>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// std::vector short
|
if (typeIs<long>(varValue))
|
||||||
if (is_this_type<std::vector<short>>(varValue))
|
return T::template Value<long>(varValue, std::string("<long>"), defaulted, empty);
|
||||||
return T::template Value<std::vector<short>>(varValue, std::string("<vector<short>>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// long
|
if (typeIs<std::vector<long>>(varValue))
|
||||||
if (is_this_type<long>(varValue))
|
return T::template Value<std::vector<long>>(varValue, std::string("<vector<long>>"), defaulted, empty);
|
||||||
return T::template Value<long>(varValue, std::string("<long>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// std::vector short
|
if (typeIs<std::size_t>(varValue))
|
||||||
if (is_this_type<std::vector<long>>(varValue))
|
return T::template Value<std::size_t>(varValue, std::string("<std::size_t>"), defaulted, empty);
|
||||||
return T::template Value<std::vector<long>>(varValue, std::string("<vector<long>>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// size_t
|
if (typeIs<std::vector<std::size_t>>(varValue))
|
||||||
if (is_this_type<std::size_t>(varValue))
|
return T::template Value<std::vector<std::size_t>>(varValue, std::string("<vector<std::size_t>>"), defaulted, empty);
|
||||||
return T::template Value<std::size_t>(varValue, std::string("<std::size_t>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// std::vector size_t
|
if (typeIs<std::uint64_t>(varValue))
|
||||||
if (is_this_type<std::vector<std::size_t>>(varValue))
|
return T::template Value<std::uint64_t>(varValue, std::string("<std::uint64_t>"), defaulted, empty);
|
||||||
return T::template Value<std::vector<std::size_t>>(varValue, std::string("<vector<std::size_t>>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// uint64_t
|
if (typeIs<std::vector<std::uint64_t>>(varValue))
|
||||||
if (is_this_type<std::uint64_t>(varValue))
|
return T::template Value<std::vector<std::uint64_t>>(varValue, std::string("<vector<std::uint64_t>>"), defaulted, empty);
|
||||||
return T::template Value<std::uint64_t>(varValue, std::string("<std::uint64_t>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// std::vector uint64_t
|
if (typeIs<bool>(varValue))
|
||||||
if (is_this_type<std::vector<std::uint64_t>>(varValue))
|
return T::template Value<bool>(varValue, std::string("<bool>"), defaulted, empty);
|
||||||
return T::template Value<std::vector<std::uint64_t>>(varValue, std::string("<vector<std::uint64_t>>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// bool
|
if (typeIs<std::vector<bool>>(varValue))
|
||||||
if (is_this_type<bool>(varValue))
|
return T::template Value<std::vector<bool>>(varValue, std::string("<vector<bool>>"), defaulted, empty);
|
||||||
return T::template Value<bool>(varValue, std::string("<bool>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// std::vector bool
|
if (typeIs<boost::filesystem::path>(varValue))
|
||||||
if (is_this_type<std::vector<bool>>(varValue))
|
return T::template Value<boost::filesystem::path>(varValue, std::string("<boost::filesystem::path>"), defaulted, empty);
|
||||||
return T::template Value<std::vector<bool>>(varValue, std::string("<vector<bool>>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
//////////////////////////////// boost types
|
|
||||||
// boost::filesystem::path
|
|
||||||
if (is_this_type<boost::filesystem::path>(varValue))
|
|
||||||
return T::template Value<boost::filesystem::path>(varValue, std::string("<boost::filesystem::path>"), defaultedValue, emptyValue);
|
|
||||||
|
|
||||||
// if we get here, the type is not supported return unknown info
|
// if we get here, the type is not supported return unknown info
|
||||||
return T::DefaultValue(defaultedValue, emptyValue);
|
return T::DefaultValue(defaulted, empty);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // FairMQ namespace
|
} // namespace mq
|
||||||
|
} // namespace fair
|
||||||
|
|
||||||
#endif /* FAIRPROGOPTIONSHELPER_H */
|
#endif /* FAIRPROGOPTIONSHELPER_H */
|
||||||
|
|
|
@ -35,8 +35,8 @@ int main(int argc, char** argv)
|
||||||
("output.file.branch", po::value<std::string>(), "output branch name")
|
("output.file.branch", po::value<std::string>(), "output branch name")
|
||||||
;
|
;
|
||||||
|
|
||||||
config.AddToCmdLineOptions(format_desc,true);
|
config.AddToCmdLineOptions(format_desc);
|
||||||
config.AddToCmdLineOptions(io_file_opt_desc,true);
|
config.AddToCmdLineOptions(io_file_opt_desc);
|
||||||
|
|
||||||
config.EnableCfgFile();// UseConfigFile (by default config file is not defined)
|
config.EnableCfgFile();// UseConfigFile (by default config file is not defined)
|
||||||
config.AddToCfgFileOptions(format_desc,false);//false because already added to visible
|
config.AddToCfgFileOptions(format_desc,false);//false because already added to visible
|
||||||
|
|
|
@ -71,9 +71,9 @@ SAMPLER+=" --same-msg $sameMsg"
|
||||||
# SAMPLER+=" --msg-rate 1000"
|
# SAMPLER+=" --msg-rate 1000"
|
||||||
SAMPLER+=" --max-iterations $maxIterations"
|
SAMPLER+=" --max-iterations $maxIterations"
|
||||||
SAMPLER+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/benchmark.json"
|
SAMPLER+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/benchmark.json"
|
||||||
xterm -geometry 90x23+0+0 -hold -e $affinitySamp @CMAKE_BINARY_DIR@/bin/$SAMPLER &
|
xterm -geometry 90x50+0+0 -hold -e $affinitySamp @CMAKE_BINARY_DIR@/bin/$SAMPLER &
|
||||||
echo ""
|
echo ""
|
||||||
echo "started: xterm -geometry 90x23+0+0 -hold -e $affinitySamp @CMAKE_BINARY_DIR@/bin/$SAMPLER"
|
echo "started: xterm -geometry 90x50+0+0 -hold -e $affinitySamp @CMAKE_BINARY_DIR@/bin/$SAMPLER"
|
||||||
echo "pid: $!"
|
echo "pid: $!"
|
||||||
|
|
||||||
SINK="sink"
|
SINK="sink"
|
||||||
|
@ -84,8 +84,8 @@ SINK+=" --transport $transport"
|
||||||
SINK+=" --severity debug"
|
SINK+=" --severity debug"
|
||||||
SINK+=" --max-iterations $maxIterations"
|
SINK+=" --max-iterations $maxIterations"
|
||||||
SINK+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/benchmark.json"
|
SINK+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/benchmark.json"
|
||||||
xterm -geometry 90x23+550+0 -hold -e $affinitySink @CMAKE_BINARY_DIR@/bin/$SINK &
|
xterm -geometry 90x50+550+0 -hold -e $affinitySink @CMAKE_BINARY_DIR@/bin/$SINK &
|
||||||
echo ""
|
echo ""
|
||||||
echo "started: xterm -geometry 90x23+550+0 -hold -e $affinitySink @CMAKE_BINARY_DIR@/bin/$SINK"
|
echo "started: xterm -geometry 90x50+550+0 -hold -e $affinitySink @CMAKE_BINARY_DIR@/bin/$SINK"
|
||||||
echo "pid: $!"
|
echo "pid: $!"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user