11// ****************************************************************************
22// * This file is free software: you can redistribute it and/or modify *
33// * it under the terms of the GNU General Public License as published by *
4- // * the Free Software Foundation, either version 3 of the License, or *
5- // * (at your option) any later version. *
4+ // * the Free Software Foundation, either version 3 of the License, or *
5+ // * (at your option) any later version. *
66// * *
77// * Primary Authors: Matthias Richter <richterm@scieq.net> *
88// * *
2222#include < cstdlib>
2323#include < cerrno>
2424#include < cstring>
25+ #include < sstream>
2526#include < iostream>
2627#include < sstream>
2728#include < getopt.h>
@@ -34,6 +35,7 @@ using std::endl;
3435using std::string;
3536using std::unique_ptr;
3637using std::vector;
38+ using std::stringstream;
3739
3840Component::Component ()
3941 : mOutputBuffer()
@@ -47,78 +49,95 @@ Component::Component()
4749Component::~Component ()
4850= default ;
4951
52+ constexpr const char * Component::OptionKeys[];
53+
54+ bpo::options_description Component::GetOptionsDescription ()
55+ {
56+ bpo::options_description od (" HLT Component options" );
57+ od.add_options ()
58+ ((std::string (OptionKeys[OptionKeyLibrary]) + " ,l" ).c_str (),
59+ bpo::value<string>()->required (),
60+ " component library" )
61+ ((std::string (OptionKeys[OptionKeyComponent]) + " ,c" ).c_str (),
62+ bpo::value<string>()->required (),
63+ " component id" )
64+ ((std::string (OptionKeys[OptionKeyParameter]) + " ,p" ).c_str (),
65+ bpo::value<string>()->default_value (" " ),
66+ " component command line parameter" )
67+ ((std::string (OptionKeys[OptionKeyRun]) + " ,r" ).c_str (),
68+ bpo::value<string>()->default_value (" -1" ),
69+ " run number" )
70+ ((std::string (OptionKeys[OptionKeyMsgsize]) + " ,s" ).c_str (),
71+ bpo::value<string>()->default_value (" 0" ),
72+ " maximum size of output buffer/msg" )
73+ ((std::string (OptionKeys[OptionKeyOutputMode]) + " ,m" ).c_str (),
74+ bpo::value<string>()->default_value (" 2" ),
75+ " output mode" );
76+
77+ return od;
78+ }
79+
5080int Component::init (int argc, char ** argv)
5181{
5282 // / initialize: scan arguments, setup system interface and create component
5383
54- // parse options
55- static struct option programOptions[] = {
56- {" library" , required_argument, nullptr , ' l' },
57- {" component" , required_argument, nullptr , ' c' },
58- {" parameter" , required_argument, nullptr , ' p' },
59- {" run" , required_argument, nullptr , ' r' },
60- {" msgsize" , required_argument, nullptr , ' s' },
61- {" output-mode" , required_argument, nullptr , ' m' },
62- {" instance-id" , required_argument, nullptr , ' i' },
63- {nullptr , 0 , nullptr , 0 }
64- };
65-
66- /* getopt_long stores the option index here. */
67- char c = 0 ;
68- int iOption = 0 ;
84+ // the hidden options are not exposed to the outside
85+ bpo::options_description od (" component options" );
86+ od.add_options ()
87+ (OptionKeys[OptionKeyInstanceId],
88+ bpo::value<string>()->required (),
89+ " internal instance id" );
90+ // now add all the visible options
91+ od.add (GetOptionsDescription ());
6992
7093 // HLT components are implemented in shared libraries, the library name
7194 // and component id are used to factorize a component
7295 // optionally, a list of configuration parameters can be specified as
7396 // one single string which is translated in an array of string in the
7497 // argc/argv format
75- const char * componentLibrary = " " ;
76- const char * componentId = " " ;
77- const char * componentParameter = " " ;
78- const char * instanceId=" " ;
98+ string componentParameter;
99+ string instanceId;
79100
80101 // the configuration and calibration is fixed for every run and identified
81102 // by the run no
82103 int runNumber = 0 ;
83104
84- optind = 1 ; // indicate new start of scanning, especially when getop has been used in a higher layer already
85- while ((c = getopt_long (argc, argv, " l:c:p:r:s:m:i:" , programOptions, &iOption)) != -1 ) {
86- switch (c) {
87- case ' l' :
88- componentLibrary = optarg;
89- break ;
90- case ' c' :
91- componentId = optarg;
92- break ;
93- case ' p' :
94- componentParameter = optarg;
95- break ;
96- case ' r' :
97- std::stringstream (optarg) >> runNumber;
98- break ;
99- case ' s' : {
100- unsigned size = 0 ;
101- std::stringstream (optarg) >> size;
102- mOutputBuffer .resize (size);
103- } break ;
104- case ' m' : {
105- unsigned outputMode;
106- std::stringstream (optarg) >> outputMode;
107- mFormatHandler .setOutputMode (outputMode);
108- } break ;
109- case ' i' : {
110- instanceId=optarg;
111- break ;
112- }
113- case ' ?' :
114- // TODO: more error handling
115- break ;
116- default :
117- cerr << " unknown option: '" << c << " '" << endl;
105+ bpo::variables_map varmap;
106+ bpo::store (bpo::parse_command_line (argc, argv, od), varmap);
107+
108+ for (int option = 0 ; option < OptionKeyLast; ++option) {
109+ if (varmap.count (OptionKeys[option]) == 0 ) continue ;
110+ switch (option) {
111+ case OptionKeyLibrary: break ;
112+ case OptionKeyComponent: break ;
113+ case OptionKeyParameter:
114+ componentParameter = varmap[OptionKeys[option]].as <string>();
115+ break ;
116+ case OptionKeyRun:
117+ stringstream (varmap[OptionKeys[option]].as <string>()) >> runNumber;
118+ break ;
119+ case OptionKeyMsgsize: {
120+ unsigned size = 0 ;
121+ stringstream (varmap[OptionKeys[option]].as <string>()) >> size;
122+ mOutputBuffer .resize (size);
123+ } break ;
124+ case OptionKeyOutputMode: {
125+ unsigned mode;
126+ stringstream (varmap[OptionKeys[option]].as <string>()) >> mode;
127+ mFormatHandler .setOutputMode (mode);
128+ } break ;
129+ case OptionKeyInstanceId: break ;
130+ instanceId = varmap[OptionKeys[option]].as <string>();
131+ break ;
118132 }
119133 }
120134
121- if (componentLibrary == nullptr || componentLibrary[0 ] == 0 || componentId == nullptr || componentId[0 ] == 0 ||
135+ // TODO: this can be a loop over all required options
136+ // probably we won't come here anyhow as the parser will detect
137+ // the absence of a required parameter, check and handle the parser
138+ // exception
139+ if (varmap.count (OptionKeys[OptionKeyLibrary]) == 0 ||
140+ varmap.count (OptionKeys[OptionKeyComponent]) == 0 ||
122141 runNumber < 0 ) {
123142 cerr << " missing argument" << endl;
124143 return -EINVAL;
@@ -136,14 +155,15 @@ int Component::init(int argc, char** argv)
136155 mpSystem = iface.release ();
137156
138157 // load the component library
139- if ((iResult = mpSystem->loadLibrary (componentLibrary)) != 0 ) return iResult > 0 ? -iResult : iResult;
158+ if ((iResult = mpSystem->loadLibrary (varmap[OptionKeys[OptionKeyLibrary]].as <string>().c_str ())) != 0 )
159+ return iResult > 0 ? -iResult : iResult;
140160
141161 // chop the parameter string in order to provide parameters in the argc/argv format
142162 vector<const char *> parameters;
143- unsigned parameterLength = strlen ( componentParameter);
163+ unsigned parameterLength = componentParameter. length ( );
144164 unique_ptr<char > parameterBuffer (new char [parameterLength + 1 ]);
145165 if (parameterLength > 0 && parameterBuffer.get () != nullptr ) {
146- strcpy (parameterBuffer.get (), componentParameter);
166+ strcpy (parameterBuffer.get (), componentParameter. c_str () );
147167 char * iterator = parameterBuffer.get ();
148168 parameters.push_back (iterator);
149169 for (; *iterator != 0 ; iterator++) {
@@ -155,8 +175,8 @@ int Component::init(int argc, char** argv)
155175
156176 // create component
157177 string description;
158- description+=" chainid=" ; description+= instanceId;
159- if ((iResult=mpSystem->createComponent (componentId , nullptr , parameters.size (), ¶meters[0 ], &mProcessor , description.c_str ()))<0 ) {
178+ description+=" chainid=" + instanceId;
179+ if ((iResult=mpSystem->createComponent (varmap[OptionKeys[OptionKeyComponent]]. as <string>(). c_str () , nullptr , parameters.size (), ¶meters[0 ], &mProcessor , description.c_str ()))<0 ) {
160180 // the ALICE HLT external interface uses the following error definition
161181 // 0 success
162182 // >0 error number
0 commit comments