Use boost::program_options for managing command line options of the executables.

Existing scripts in example/Tutorial3/macro have been updated to use the new format.
Your own executables are not affected, but your scripts which use FairMQ executables have to be updated to the new format.
Use the `--help` option with any FairMQ executable to find out the available options.
This commit is contained in:
Alexey Rybalchenko
2014-09-30 11:37:18 +02:00
parent 101bc4c9e7
commit 0cef5692b1
13 changed files with 923 additions and 372 deletions

View File

@@ -15,6 +15,8 @@
#include <iostream>
#include <csignal>
#include "boost/program_options.hpp"
#include "FairMQLogger.h"
#include "FairMQMerger.h"
@@ -24,10 +26,7 @@
#include "FairMQTransportFactoryZMQ.h"
#endif
using std::cout;
using std::cin;
using std::endl;
using std::stringstream;
using namespace std;
FairMQMerger merger;
@@ -52,20 +51,105 @@ static void s_catch_signals(void)
sigaction(SIGTERM, &action, NULL);
}
int main(int argc, char** argv)
typedef struct DeviceOptions
{
if (argc < 16 || (argc - 8) % 4 != 0)
string id;
int ioThreads;
int numInputs;
vector<string> inputSocketType;
vector<int> inputBufSize;
vector<string> inputMethod;
vector<string> inputAddress;
string outputSocketType;
int outputBufSize;
string outputMethod;
string outputAddress;
} DeviceOptions_t;
inline bool parse_cmd_line(int _argc, char* _argv[], DeviceOptions* _options)
{
if (_options == NULL)
throw std::runtime_error("Internal error: options' container is empty.");
namespace bpo = boost::program_options;
bpo::options_description desc("Options");
desc.add_options()
("id", bpo::value<string>()->required(), "Device ID")
("io-threads", bpo::value<int>()->default_value(1), "Number of I/O threads")
("num-inputs", bpo::value<int>()->required(), "Number of Merger input sockets")
("input-socket-type", bpo::value< vector<string> >()->required(), "Input socket type: sub/pull")
("input-buff-size", bpo::value< vector<int> >()->required(), "Input buffer size in number of messages (ZeroMQ)/bytes(nanomsg)")
("input-method", bpo::value< vector<string> >()->required(), "Input method: bind/connect")
("input-address", bpo::value< vector<string> >()->required(), "Input address, e.g.: \"tcp://localhost:5555\"")
("output-socket-type", bpo::value<string>()->required(), "Output socket type: pub/push")
("output-buff-size", bpo::value<int>()->required(), "Output buffer size in number of messages (ZeroMQ)/bytes(nanomsg)")
("output-method", bpo::value<string>()->required(), "Output method: bind/connect")
("output-address", bpo::value<string>()->required(), "Output address, e.g.: \"tcp://localhost:5555\"")
("help", "Print help messages");
bpo::variables_map vm;
bpo::store(bpo::parse_command_line(_argc, _argv, desc), vm);
if ( vm.count("help") )
{
cout << "Usage: merger \tID numIoTreads numInputs\n"
<< "\t\tinputSocketType inputRcvBufSize inputMethod inputAddress\n"
<< "\t\tinputSocketType inputRcvBufSize inputMethod inputAddress\n"
<< "\t\t...\n"
<< "\t\toutputSocketType outputSndBufSize outputMethod outputAddress\n" << argc << " arguments provided" << endl;
return 1;
LOG(INFO) << "FairMQ Merger" << endl << desc;
return false;
}
bpo::notify(vm);
if ( vm.count("id") )
_options->id = vm["id"].as<string>();
if ( vm.count("io-threads") )
_options->ioThreads = vm["io-threads"].as<int>();
if ( vm.count("num-inputs") )
_options->numInputs = vm["num-inputs"].as<int>();
if ( vm.count("input-socket-type") )
_options->inputSocketType = vm["input-socket-type"].as< vector<string> >();
if ( vm.count("input-buff-size") )
_options->inputBufSize = vm["input-buff-size"].as< vector<int> >();
if ( vm.count("input-method") )
_options->inputMethod = vm["input-method"].as< vector<string> >();
if ( vm.count("input-address") )
_options->inputAddress = vm["input-address"].as< vector<string> >();
if ( vm.count("output-socket-type") )
_options->outputSocketType = vm["output-socket-type"].as<string>();
if ( vm.count("output-buff-size") )
_options->outputBufSize = vm["output-buff-size"].as<int>();
if ( vm.count("output-method") )
_options->outputMethod = vm["output-method"].as<string>();
if ( vm.count("output-address") )
_options->outputAddress = vm["output-address"].as<string>();
return true;
}
int main(int argc, char** argv)
{
s_catch_signals();
DeviceOptions_t options;
try
{
if (!parse_cmd_line(argc, argv, &options))
return 0;
}
catch (exception& e)
{
LOG(ERROR) << e.what();
return 1;
}
LOG(INFO) << "PID: " << getpid();
#ifdef NANOMSG
@@ -76,49 +160,26 @@ int main(int argc, char** argv)
merger.SetTransport(transportFactory);
int i = 1;
merger.SetProperty(FairMQMerger::Id, argv[i]);
++i;
int numIoThreads;
stringstream(argv[i]) >> numIoThreads;
merger.SetProperty(FairMQMerger::NumIoThreads, numIoThreads);
++i;
int numInputs;
stringstream(argv[i]) >> numInputs;
merger.SetProperty(FairMQMerger::NumInputs, numInputs);
++i;
merger.SetProperty(FairMQMerger::Id, options.id);
merger.SetProperty(FairMQMerger::NumIoThreads, options.ioThreads);
merger.SetProperty(FairMQMerger::NumInputs, options.numInputs);
merger.SetProperty(FairMQMerger::NumOutputs, 1);
merger.ChangeState(FairMQMerger::INIT);
for (int iInput = 0; iInput < numInputs; iInput++)
for (int i = 0; i < options.numInputs; ++i)
{
merger.SetProperty(FairMQMerger::InputSocketType, argv[i], iInput);
++i;
int inputRcvBufSize;
stringstream(argv[i]) >> inputRcvBufSize;
merger.SetProperty(FairMQMerger::InputRcvBufSize, inputRcvBufSize, iInput);
++i;
merger.SetProperty(FairMQMerger::InputMethod, argv[i], iInput);
++i;
merger.SetProperty(FairMQMerger::InputAddress, argv[i], iInput);
++i;
merger.SetProperty(FairMQMerger::InputSocketType, options.inputSocketType.at(i), i);
merger.SetProperty(FairMQMerger::InputRcvBufSize, options.inputBufSize.at(i), i);
merger.SetProperty(FairMQMerger::InputMethod, options.inputMethod.at(i), i);
merger.SetProperty(FairMQMerger::InputAddress, options.inputAddress.at(i), i);
}
merger.SetProperty(FairMQMerger::OutputSocketType, argv[i], 0);
++i;
int outputSndBufSize;
stringstream(argv[i]) >> outputSndBufSize;
merger.SetProperty(FairMQMerger::OutputSndBufSize, outputSndBufSize, 0);
++i;
merger.SetProperty(FairMQMerger::OutputMethod, argv[i], 0);
++i;
merger.SetProperty(FairMQMerger::OutputAddress, argv[i], 0);
++i;
merger.SetProperty(FairMQMerger::OutputSocketType, options.outputSocketType);
merger.SetProperty(FairMQMerger::OutputSndBufSize, options.outputBufSize);
merger.SetProperty(FairMQMerger::OutputMethod, options.outputMethod);
merger.SetProperty(FairMQMerger::OutputAddress, options.outputAddress);
merger.ChangeState(FairMQMerger::SETOUTPUT);
merger.ChangeState(FairMQMerger::SETINPUT);