diff --git a/fairmq/FairMQDevice.cxx b/fairmq/FairMQDevice.cxx index 869f0bec..59e17206 100644 --- a/fairmq/FairMQDevice.cxx +++ b/fairmq/FairMQDevice.cxx @@ -993,7 +993,7 @@ void FairMQDevice::LogSocketRates() bytesOut.at(i) = bytesOutNew.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) " << "out: " << msgPerSecOut.at(i) << " (" << mbPerSecOut.at(i) << " MB)"; } diff --git a/fairmq/options/FairMQParser.cxx b/fairmq/options/FairMQParser.cxx index f634510b..48ce217c 100644 --- a/fairmq/options/FairMQParser.cxx +++ b/fairmq/options/FairMQParser.cxx @@ -14,24 +14,27 @@ #include "FairMQParser.h" #include "FairMQLogger.h" -#include #include using namespace std; -namespace FairMQParser +namespace fair +{ +namespace mq +{ +namespace parser { // TODO : add key-value map 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 string& id, const string& rootNode, const string& formatFlag) +// 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) { // Create fair mq map FairMQMap channelMap; //Helper::PrintPropertyTree(pt); - //Helper::PrintDeviceList(pt.get_child(rootNode), formatFlag); + //Helper::PrintDeviceList(pt.get_child(rootNode)); // 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()) { @@ -56,24 +59,10 @@ FairMQMap JSON::UserParser(stringstream& input, const string& deviceId, const st 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 { -void PrintDeviceList(const boost::property_tree::ptree& tree, const string& formatFlag) +void PrintDeviceList(const boost::property_tree::ptree& tree) { 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(".id"); - LOG(debug) << "Found config for '" << deviceIdKey << "' in XML input"; - } - - if (formatFlag == "json") - { - string key = p.second.get("key", ""); - if (key != "") - { - deviceIdKey = key; - LOG(debug) << "Found config for device key '" << deviceIdKey << "' in JSON input"; - } - else - { - deviceIdKey = p.second.get("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; @@ -160,48 +124,13 @@ void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap 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(".id"); - } - - if (formatFlag == "json") - { - // check if key is provided, otherwise use id - string key = p.second.get("key", ""); - - if (key != "") - { - deviceIdKey = key; - // LOG(debug) << "Found config for device key '" << deviceIdKey << "' in JSON input"; - } - else - { - deviceIdKey = p.second.get("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; @@ -260,69 +189,6 @@ void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMa 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(".name"); - } - - if (formatFlag == "json") - { - channelKey = p.second.get("name"); - - numSockets = p.second.get("numSockets", 0); - - // try to get common properties to use for all subChannels - commonChannel.UpdateType(p.second.get("type", commonChannel.GetType())); - commonChannel.UpdateMethod(p.second.get("method", commonChannel.GetMethod())); - commonChannel.UpdateAddress(p.second.get("address", commonChannel.GetAddress())); - commonChannel.UpdateTransport(p.second.get("transport", commonChannel.GetTransport())); - commonChannel.UpdateSndBufSize(p.second.get("sndBufSize", commonChannel.GetSndBufSize())); - commonChannel.UpdateRcvBufSize(p.second.get("rcvBufSize", commonChannel.GetRcvBufSize())); - commonChannel.UpdateSndKernelSize(p.second.get("sndKernelSize", commonChannel.GetSndKernelSize())); - commonChannel.UpdateRcvKernelSize(p.second.get("rcvKernelSize", commonChannel.GetRcvKernelSize())); - commonChannel.UpdateRateLogging(p.second.get("rateLogging", commonChannel.GetRateLogging())); - } - - // temporary FairMQChannel container - vector 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 ++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("type", channel.GetType())); - channel.UpdateMethod(p.second.get("method", channel.GetMethod())); - channel.UpdateAddress(p.second.get("address", channel.GetAddress())); - channel.UpdateTransport(p.second.get("transport", channel.GetTransport())); - channel.UpdateSndBufSize(p.second.get("sndBufSize", channel.GetSndBufSize())); - channel.UpdateRcvBufSize(p.second.get("rcvBufSize", channel.GetRcvBufSize())); - channel.UpdateSndKernelSize(p.second.get("sndKernelSize", channel.GetSndKernelSize())); - channel.UpdateRcvKernelSize(p.second.get("rcvKernelSize", channel.GetRcvKernelSize())); - channel.UpdateRateLogging(p.second.get("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 if (socketCounter) @@ -435,4 +270,6 @@ void PrintPropertyTree(const boost::property_tree::ptree& tree, int level) } // Helper namespace -} // FairMQParser namespace +} // namespace parser +} // namespace mq +} // namespace fair diff --git a/fairmq/options/FairMQParser.h b/fairmq/options/FairMQParser.h index ffe8696b..12f87780 100644 --- a/fairmq/options/FairMQParser.h +++ b/fairmq/options/FairMQParser.h @@ -17,12 +17,16 @@ #include "FairMQChannel.h" -namespace FairMQParser +namespace fair +{ +namespace mq +{ +namespace parser { using FairMQMap = std::unordered_map>; -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 { @@ -30,23 +34,19 @@ struct JSON 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 { -void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string& formatFlag = "json"); -void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& deviceId, const std::string& formatFlag); -void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& formatFlag); +void PrintDeviceList(const boost::property_tree::ptree& tree); +void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& deviceId); +void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap); void SocketParser(const boost::property_tree::ptree& tree, std::vector& channelList, const std::string& channelName, const FairMQChannel& commonChannel); void PrintPropertyTree(const boost::property_tree::ptree& tree, int level = 0); } // Helper namespace -} // FairMQParser namespace +} // namespace parser +} // namespace mq +} // namespace fair #endif /* FAIRMQPARSER_H */ diff --git a/fairmq/options/FairMQProgOptions.cxx b/fairmq/options/FairMQProgOptions.cxx index 29cf5deb..9e12adb7 100644 --- a/fairmq/options/FairMQProgOptions.cxx +++ b/fairmq/options/FairMQProgOptions.cxx @@ -31,7 +31,7 @@ FairMQProgOptions::FairMQProgOptions() , fMQKeyMap() { InitOptionDescription(); - ParseDefaults(fCmdLineOptions); + ParseDefaults(); } FairMQProgOptions::~FairMQProgOptions() @@ -52,7 +52,7 @@ int FairMQProgOptions::ParseAll(const vector& cmdLineArgs, bool allowUnr 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. return 1; @@ -83,93 +83,53 @@ int FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool al fair::Logger::SetConsoleSeverity(severity); } - // check if one of required MQ config option is there - auto parserOptions = fMQParserOptions.options(); - bool optionExists = false; - vector MQParserKeys; - for (const auto& p : parserOptions) - { - MQParserKeys.push_back(p->canonical_display_name()); - if (fVarMap.count(p->canonical_display_name())) - { - optionExists = true; - break; - } - } + string id; - 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:"; - for (const auto& p : MQParserKeys) - { - LOG(warn) << " --" << p; - } - LOG(warn) << "No channels will be created (You can create them manually)."; + id = fVarMap["config-key"].as(); } else { - string id; + id = fVarMap["id"].as(); + } - if (fVarMap.count("config-key")) - { - id = fVarMap["config-key"].as(); - } - else - { - id = fVarMap["id"].as(); - } - - // if cmdline mq-config called then use the default xml/json parser + // check if any config parser is selected + try + { if (fVarMap.count("mq-config")) { - LOG(debug) << "mq-config: Using default XML/JSON parser"; - - string file = fVarMap["mq-config"].as(); - - string ext = boost::filesystem::extension(file); - - transform(ext.begin(), ext.end(), ext.begin(), ::tolower); - - if (ext == ".json") - { - UserParser(file, id); - } - else - { - if (ext == ".xml") - { - UserParser(file, id); - } - else - { - LOG(error) << "mq-config command line called but file extension '" << ext << "' not recognized. Program will now exit"; - return 1; - } - } + LOG(debug) << "mq-config: Using default JSON parser"; + Store(fair::mq::parser::JSON().UserParser(fVarMap["mq-config"].as(), id)); } else if (fVarMap.count("config-json-string")) { LOG(debug) << "config-json-string: Parsing JSON string"; - - string value = FairMQ::ConvertVariableValue().Run(fVarMap.at("config-json-string")); + string value = fair::mq::ConvertVariableValue()(fVarMap.at("config-json-string")); stringstream ss; ss << value; - UserParser(ss, id); + Store(fair::mq::parser::JSON().UserParser(ss, id)); } - else if (fVarMap.count("config-xml-string")) - { - LOG(debug) << "config-json-string: Parsing XML string"; - - string value = FairMQ::ConvertVariableValue().Run(fVarMap.at("config-xml-string")); - stringstream ss; - ss << value; - UserParser(ss, id); - } - else if (fVarMap.count(FairMQParser::SUBOPT::OptionKeyChannelConfig)) + else if (fVarMap.count("channel-config")) { LOG(debug) << "channel-config: Parsing channel configuration"; - UserParser(fVarMap, id); + Store(fair::mq::parser::SUBOPT().UserParser(fVarMap.at("channel-config").as>(), 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(); @@ -223,15 +183,15 @@ void FairMQProgOptions::UpdateMQValues() string rcvKernelSizeKey = "chans." + p.first + "." + to_string(index) + ".rcvKernelSize"; string rateLoggingKey = "chans." + p.first + "." + to_string(index) + ".rateLogging"; - fMQKeyMap[typeKey] = make_tuple(p.first, index, "type"); - fMQKeyMap[methodKey] = make_tuple(p.first, index, "method"); - fMQKeyMap[addressKey] = make_tuple(p.first, index, "address"); - fMQKeyMap[transportKey] = make_tuple(p.first, index, "transport"); - fMQKeyMap[sndBufSizeKey] = make_tuple(p.first, index, "sndBufSize"); - fMQKeyMap[rcvBufSizeKey] = make_tuple(p.first, index, "rcvBufSize"); - fMQKeyMap[sndKernelSizeKey] = make_tuple(p.first, index, "sndKernelSize"); - fMQKeyMap[rcvKernelSizeKey] = make_tuple(p.first, index, "rcvkernelSize"); - fMQKeyMap[rateLoggingKey] = make_tuple(p.first, index, "rateLogging"); + fMQKeyMap[typeKey] = MQKey{p.first, index, "type"}; + fMQKeyMap[methodKey] = MQKey{p.first, index, "method"}; + fMQKeyMap[addressKey] = MQKey{p.first, index, "address"}; + fMQKeyMap[transportKey] = MQKey{p.first, index, "transport"}; + fMQKeyMap[sndBufSizeKey] = MQKey{p.first, index, "sndBufSize"}; + fMQKeyMap[rcvBufSizeKey] = MQKey{p.first, index, "rcvBufSize"}; + fMQKeyMap[sndKernelSizeKey] = MQKey{p.first, index, "sndKernelSize"}; + fMQKeyMap[rcvKernelSizeKey] = MQKey{p.first, index, "rcvkernelSize"}; + fMQKeyMap[rateLoggingKey] = MQKey{p.first, index, "rateLogging"}; UpdateVarMap(typeKey, channel.GetType()); UpdateVarMap(methodKey, channel.GetMethod()); @@ -253,7 +213,7 @@ int FairMQProgOptions::ImmediateOptions() { if (fVarMap.count("help")) { - cout << "===== FairMQ Program Options =====" << endl << fVisibleOptions; + cout << "===== FairMQ Program Options =====" << endl << fAllOptions; return 1; } @@ -285,13 +245,11 @@ void FairMQProgOptions::InitOptionDescription() ; fMQParserOptions.add_options() - ("config-xml-string", po::value>()->multitoken(), "XML input as command line string.") ("config-json-string", po::value>()->multitoken(), "JSON input as command line string.") ("mq-config", po::value(), "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>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list") + ("channel-config", po::value>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list") ; - AddToCmdLineOptions(fGeneralDesc); AddToCmdLineOptions(fMQCmdOptions); AddToCmdLineOptions(fMQParserOptions); } diff --git a/fairmq/options/FairMQProgOptions.h b/fairmq/options/FairMQProgOptions.h index 092dcedd..2d3c6dea 100644 --- a/fairmq/options/FairMQProgOptions.h +++ b/fairmq/options/FairMQProgOptions.h @@ -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 int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) override; - // external parser, store function - template - int UserParser(Args &&... args) - { - try - { - Store(T().UserParser(std::forward(args)...)); - } - catch (std::exception& e) - { - LOG(error) << e.what(); - return 1; - } - return 0; - } - FairMQMap GetFairMQMap() const { return fFairMQMap; @@ -78,12 +62,6 @@ class FairMQProgOptions : public FairProgOptions 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 int UpdateValue(const std::string& key, T val) { @@ -99,11 +77,7 @@ class FairMQProgOptions : public FairProgOptions { if (fMQKeyMap.count(key)) { - std::string channelName; - int index = 0; - std::string member; - std::tie(channelName, index, member) = fMQKeyMap.at(key); - UpdateChannelMap(channelName, index, member, val); + UpdateChannelMap(fMQKeyMap.at(key).channel, fMQKeyMap.at(key).index, fMQKeyMap.at(key).member, val); } } @@ -135,11 +109,7 @@ class FairMQProgOptions : public FairProgOptions { if (fMQKeyMap.count(key)) { - std::string channelName; - int index = 0; - std::string member; - std::tie(channelName, index, member) = fMQKeyMap.at(key); - UpdateChannelMap(channelName, index, member, val); + UpdateChannelMap(fMQKeyMap.at(key).channel, fMQKeyMap.at(key).index, fMQKeyMap.at(key).member, val); } } @@ -189,6 +159,13 @@ class FairMQProgOptions : public FairProgOptions int UpdateChannelMap(const FairMQMap& map); protected: + struct MQKey + { + std::string channel; + int index; + std::string member; + }; + po::options_description fMQCmdOptions; po::options_description fMQParserOptions; FairMQMap fFairMQMap; @@ -196,7 +173,6 @@ class FairMQProgOptions : public FairProgOptions // map of read channel info - channel name - number of subchannels std::unordered_map fChannelInfo; - using MQKey = std::tuple;//store key info std::map fMQKeyMap;// key=full path - val=key info int ImmediateOptions() override; // for custom help & version printing diff --git a/fairmq/options/FairMQSuboptParser.cxx b/fairmq/options/FairMQSuboptParser.cxx index 3859bff2..d4d22a1a 100644 --- a/fairmq/options/FairMQSuboptParser.cxx +++ b/fairmq/options/FairMQSuboptParser.cxx @@ -12,68 +12,81 @@ /// @brief Parser implementation for key-value subopt format #include "FairMQSuboptParser.h" + #include #include +#include // make_pair using boost::property_tree::ptree; +using namespace std; -namespace FairMQParser +namespace fair +{ +namespace mq +{ +namespace parser { 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& channelConfig, const string& deviceId, const string& rootNode) { - std::string nodeKey = rootNode + ".device"; ptree pt; - pt.put(nodeKey + ".id", deviceId.c_str()); - nodeKey += ".channels"; + ptree devicesArray; + ptree deviceProperties; - // parsing of channel properties is the only implemented method right now - if (omap.count(OptionKeyChannelConfig) > 0) + ptree channelsArray; + + for (auto token : channelConfig) { - std::map channelProperties; - auto tokens = omap[OptionKeyChannelConfig].as>(); - for (auto token : tokens) + string channelName; + ptree channelProperties; + + ptree socketsArray; + ptree socketProperties; + + string argString(token); + char* subopts = &argString[0]; + char* value = nullptr; + while (subopts && *subopts != 0 && *subopts != ' ') { - // std::map::iterator channelProperty = channelProperties.end(); - ptree socketProperty; - std::string channelName; - std::string argString(token); - char* subopts = &argString[0]; - char* value = nullptr; - while (subopts && *subopts != 0 && *subopts != ' ') + int subopt = getsubopt(&subopts, (char**)channelOptionKeys, &value); + if (subopt == NAME) { - // char* saved = subopts; - int subopt=getsubopt(&subopts, (char**)channelOptionKeys, &value); - if (subopt == NAME) - { - channelName = value; - channelProperties[channelName].put("name", channelName); - } - else if (subopt>=0 && value != nullptr) - { - socketProperty.put(channelOptionKeys[subopt], value); - } + channelName = value; + channelProperties.put("name", channelName); } - if (channelName != "") + else if (subopt >= 0 && value != nullptr) { - channelProperties[channelName].add_child("sockets.socket", socketProperty); - } - else - { - // TODO: what is the error policy here, should we abort? - LOG(error) << "missing channel name in argument of option --channel-config"; + socketProperties.put(channelOptionKeys[subopt], value); } } - 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); } -} // namespace FairMQParser +} +} +} diff --git a/fairmq/options/FairMQSuboptParser.h b/fairmq/options/FairMQSuboptParser.h index 1e618b33..5bb5ffe5 100644 --- a/fairmq/options/FairMQSuboptParser.h +++ b/fairmq/options/FairMQSuboptParser.h @@ -17,11 +17,18 @@ #include "FairMQParser.h" // for FairMQMap #include #include +#include +#include namespace po = boost::program_options; -namespace FairMQParser +namespace fair { +namespace mq +{ +namespace parser +{ + /** * A parser implementation for FairMQ channel properties. * 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 * and introducing additional parser functions. */ -struct SUBOPT { - enum channelOptionKeyIds { - NAME = 0, // name of the channel - TYPE, // push, pull, publish, subscribe, etc - METHOD, // bind or connect - ADDRESS, // host, protocol and port address - TRANSPORT, // - SNDBUFSIZE, // size of the send queue - RCVBUFSIZE, // size of the receive queue - SNDKERNELSIZE, - RCVKERNELSIZE, - RATELOGGING, // logging rate - lastsocketkey - }; +struct SUBOPT +{ + enum channelOptionKeyIds + { + NAME = 0, // name of the channel + TYPE, // push, pull, publish, subscribe, etc + METHOD, // bind or connect + ADDRESS, // host, protocol and port address + TRANSPORT, // + SNDBUFSIZE, // size of the send queue + RCVBUFSIZE, // size of the receive queue + SNDKERNELSIZE, + RCVKERNELSIZE, + RATELOGGING, // logging rate + lastsocketkey + }; - constexpr static const char *channelOptionKeys[] = { - /*[NAME] = */ "name", - /*[TYPE] = */ "type", - /*[METHOD] = */ "method", - /*[ADDRESS] = */ "address", - /*[TRANSPORT] = */ "transport", - /*[SNDBUFSIZE] = */ "sndBufSize", - /*[RCVBUFSIZE] = */ "rcvBufSize", - /*[SNDKERNELSIZE] = */ "sndKernelSize", - /*[RCVKERNELSIZE] = */ "rcvKernelSize", - /*[RATELOGGING] = */ "rateLogging", - nullptr - }; + constexpr static const char *channelOptionKeys[] = { + /*[NAME] = */ "name", + /*[TYPE] = */ "type", + /*[METHOD] = */ "method", + /*[ADDRESS] = */ "address", + /*[TRANSPORT] = */ "transport", + /*[SNDBUFSIZE] = */ "sndBufSize", + /*[RCVBUFSIZE] = */ "rcvBufSize", + /*[SNDKERNELSIZE] = */ "sndKernelSize", + /*[RCVKERNELSIZE] = */ "rcvKernelSize", + /*[RATELOGGING] = */ "rateLogging", + nullptr + }; - constexpr static const char* OptionKeyChannelConfig = "channel-config"; - - FairMQMap UserParser(const po::variables_map& omap, const std::string& deviceId, const std::string& rootNode = "fairMQOptions"); + FairMQMap UserParser(const std::vector& channelConfig, const std::string& deviceId, const std::string& rootNode = "fairMQOptions"); }; + +} +} } #endif /* FAIRMQPARSER_SUBOPT_H */ diff --git a/fairmq/options/FairProgOptions.cxx b/fairmq/options/FairProgOptions.cxx index 4bb6e8d3..5a26790e 100644 --- a/fairmq/options/FairProgOptions.cxx +++ b/fairmq/options/FairProgOptions.cxx @@ -19,15 +19,15 @@ #include using namespace std; +using namespace fair::mq; FairProgOptions::FairProgOptions() : fVarMap() - , fGeneralDesc("General options") - , fCmdLineOptions("Command line options") - , fVisibleOptions("Visible options") + , fGeneralOptions("General options") + , fAllOptions("Command line options") , fConfigMutex() { - fGeneralDesc.add_options() + fGeneralOptions.add_options() ("help,h", "produce help") ("version,v", "print version") ("severity", po::value()->default_value("debug"), "Log severity level: trace, debug, info, state, warn, error, fatal, nolog") @@ -35,6 +35,8 @@ FairProgOptions::FairProgOptions() ("color", po::value()->default_value(true), "Log color (true/false)") ("log-to-file", po::value()->default_value(""), "Log output to a file.") ("print-options", po::value()->implicit_value(true), "print options in machine-readable format (