Nymph  v1.5.2
Flow-Based Data Processing Framework
KTCommandLineHandler.hh
Go to the documentation of this file.
1 
9 #ifndef KTCOMMANDLINEHANDLER_H_
10 #define KTCOMMANDLINEHANDLER_H_
11 
12 #include "KTLogger.hh"
13 
14 #include "param.hh"
15 #include "singleton.hh"
16 
17 #include <boost/program_options.hpp>
18 namespace po = boost::program_options;
19 
20 #include <map>
21 #include <set>
22 #include <stdexcept>
23 #include <string>
24 #include <vector>
25 
26 namespace Nymph
27 {
28  KTLOGGER(utillog_clh, "KTCommandLineHandler.hh");
29 
30  class CommandLineHandlerException : public std::logic_error
31  {
32  public:
33  CommandLineHandlerException(std::string const& why);
34  };
35 
36 
57  class KTCommandLineHandler : public scarab::singleton< KTCommandLineHandler >
58  {
59  protected:
60  typedef std::map< std::string, po::options_description* > OptDescMap;
61  typedef OptDescMap::iterator OptDescMapIt;
62  typedef OptDescMap::const_iterator OptDescMapCIt;
63 
64  //**************
65  // Singleton
66  //**************
67 
68  protected:
69  friend class scarab::singleton< KTCommandLineHandler >;
70  friend class scarab::destroyer< KTCommandLineHandler >;
72  virtual ~KTCommandLineHandler();
73 
74  //**************
75  // Identification
76  //**************
77 
78  public:
79  const std::string& GetExecutableName() const;
80  const std::string& GetPackageString() const;
81 
82  private:
83  std::string fExecutableName; // from argv[0], if provided
84  std::string fPackageString; // Package name and version
85 
86  //**************
87  // Command line arguments
88  //**************
89 
90  public:
91  bool ProcessCommandLine(int argC, char** argV);
92 
93  bool TakeArguments(int argC, char** argV);
94  bool GetArgumentsTaken();
95  int GetNArgs();
96  char** GetArgV();
97 
98  private:
99  int fNArgs;
100  char** fArgV;
102 
103  //**************
104  // Option-adding interface
105  //**************
106 
107  public:
109  OptDescMapIt CreateNewOptionGroup(const std::string& aTitle);
110 
112  bool AddOption(const std::string& aTitle, const std::string& aHelpMsg, const std::string& aLongOpt, char aShortOpt, bool aWarnOnDuplicate=true);
114  bool AddOption(const std::string& aTitle, const std::string& aHelpMsg, const std::string& aLongOpt, bool aWarnOnDuplicate=true);
115 
117  template< class XValueType >
118  bool AddOption(const std::string& aTitle, const std::string& aHelpMsg, const std::string& aLongOpt, char aShortOpt, bool aWarnOnDuplicate=true);
120  template< class XValueType >
121  bool AddOption(const std::string& aTitle, const std::string& aHelpMsg, const std::string& aLongOpt, bool aWarnOnDuplicate=true);
122 
124  po::options_description* GetOptionsDescription(const std::string& aKey);
125 
127  bool FinalizeNewOptionGroups();
128 
129  protected:
130  OptDescMap fProposedGroups;
131  std::set< std::string > fAllGroupKeys;
132  std::set< std::string > fAllOptionsLong;
133  std::set< char > fAllOptionsShort;
134 
135  po::options_description fCommandLineOptions;
136  po::options_description fPrintHelpOptions;
137 
138  protected:
140  bool AddCommandLineOptions(const po::options_description& aSetOfOpts);
141 
142  //**************
143  // Parsing
144  //**************
145 
146  public:
148  void InitialCommandLineProcessing();
149 
151  bool DelayedCommandLineProcessing();
152 
153  private:
154  std::vector< std::string > fCommandLineParseLater;
155 
156  //**************
157  // Access to values
158  //**************
159 
160  public:
162  bool IsCommandLineOptSet(const std::string& aCLOption);
163 
165  template< class XReturnType >
166  XReturnType GetCommandLineValue(const std::string& aCLOption);
167 
169  template< class XReturnType >
170  XReturnType GetCommandLineValue(const std::string& aCLOption, XReturnType defaultValue);
171 
172  bool GetPrintHelpMessageFlag() const;
173  bool GetPrintHelpMessageAfterConfigFlag() const;
174  bool GetPrintVersionMessage() const;
175 
177  const std::string& GetConfigFilename() const;
178 
180  const std::string& GetCommandLineJSON() const;
181 
182  const po::parsed_options* GetParsedOptions() const;
183  const po::variables_map* GetVariablesMap() const;
184 
185  const scarab::param_node* GetConfigOverride() const;
186 
187  private:
188  po::parsed_options fParsedOptions;
189  po::variables_map fCommandLineVarMap;
190 
191  scarab::param_node fConfigOverrideValues;
192  static const char fDash = '-';
193  static const char fSeparator = '=';
194  static const char fNodeSeparator = '.';
195 
199 
200  std::string fConfigFilename;
201  std::string fCommandLineJSON;
202 
203  //**************
204  // Print useful information
205  //**************
206 
207  public:
208  virtual void PrintHelpMessage();
209  virtual void PrintVersionMessage();
210  };
211 
212  inline const std::string& KTCommandLineHandler::GetExecutableName() const
213  {
214  return fExecutableName;
215  }
216  inline const std::string& KTCommandLineHandler::GetPackageString() const
217  {
218  return fPackageString;
219  }
220 
221  template< class XValueType >
222  bool KTCommandLineHandler::AddOption(const std::string& aTitle, const std::string& aHelpMsg, const std::string& aLongOpt, char aShortOpt, bool aWarnOnDuplicate)
223  {
224  if (fAllOptionsLong.find(aLongOpt) != fAllOptionsLong.end())
225  {
226  if (aWarnOnDuplicate)
227  KTWARN(utillog_clh, "There is already an option called <" << aLongOpt << ">");
228  return false;
229  }
230  if (fAllOptionsShort.find(aShortOpt) != fAllOptionsShort.end())
231  {
232  if (aWarnOnDuplicate)
233  KTWARN(utillog_clh, "There is already a short option called <" << aShortOpt << ">");
234  return false;
235  }
236 
237  // option is okay at this point
238 
239  OptDescMapIt tIter = fProposedGroups.find(aTitle);
240  if (tIter == fProposedGroups.end())
241  {
242  tIter = CreateNewOptionGroup(aTitle);
243  }
244 
245  std::string tOptionName = aLongOpt;
246  fAllOptionsLong.insert(aLongOpt);
247  tOptionName += "," + std::string(&aShortOpt);
248  fAllOptionsShort.insert(aShortOpt);
249 
250  tIter->second->add_options()(tOptionName.c_str(), po::value< XValueType >(), aHelpMsg.c_str());
251 
252  return true;
253 
254  }
255 
256  template< class XValueType >
257  bool KTCommandLineHandler::AddOption(const std::string& aTitle, const std::string& aHelpMsg, const std::string& aLongOpt, bool aWarnOnDuplicate)
258  {
259  if (fAllOptionsLong.find(aLongOpt) != fAllOptionsLong.end())
260  {
261  if (aWarnOnDuplicate)
262  KTWARN(utillog_clh, "There is already an option called <" << aLongOpt << ">");
263  return false;
264  }
265 
266  // option is okay at this point
267 
268  OptDescMapIt tIter = fProposedGroups.find(aTitle);
269  if (tIter == fProposedGroups.end())
270  {
271  tIter = CreateNewOptionGroup(aTitle);
272  }
273 
274  fAllOptionsLong.insert(aLongOpt);
275 
276  tIter->second->add_options()(aLongOpt.c_str(), po::value< XValueType >(), aHelpMsg.c_str());
277 
278  return true;
279 
280  }
281 
282 
283  template< class XReturnType >
284  XReturnType KTCommandLineHandler::GetCommandLineValue(const std::string& aCLOption)
285  {
286  if (! IsCommandLineOptSet(aCLOption))
287  {
288  KTWARN(utillog_clh, "Command line option <" << aCLOption << "> was not set!\n"
289  "Next time check whether it's set before calling this function.");
290  throw CommandLineHandlerException("Command line option " + aCLOption + " was not set!");
291  }
292  return fCommandLineVarMap[aCLOption].as< XReturnType >();
293  }
294 
295  template< class XReturnType >
296  XReturnType KTCommandLineHandler::GetCommandLineValue(const std::string& aCLOption, XReturnType defaultValue)
297  {
298  if (! IsCommandLineOptSet(aCLOption))
299  {
300  return defaultValue;
301  }
302  return fCommandLineVarMap[aCLOption].as< XReturnType >();
303  }
304 
305  inline const std::string& KTCommandLineHandler::GetConfigFilename() const
306  {
307  return fConfigFilename;
308  }
309 
310  inline const std::string& KTCommandLineHandler::GetCommandLineJSON() const
311  {
312  return fCommandLineJSON;
313  }
314 
316  {
317  return fPrintVersionMessage;
318  }
319 
321  {
322  return fPrintHelpMessage;
323  }
324 
326  {
327  return fPrintHelpMessageAfterConfig;
328  }
329 
330  inline const po::parsed_options* KTCommandLineHandler::GetParsedOptions() const
331  {
332  return &fParsedOptions;
333  }
334 
335  inline const po::variables_map* KTCommandLineHandler::GetVariablesMap() const
336  {
337  return &fCommandLineVarMap;
338  }
339 
340  inline const scarab::param_node* KTCommandLineHandler::GetConfigOverride() const
341  {
342  return &fConfigOverrideValues;
343  }
344 
345 } /* namespace Nymph */
346 #endif /* KTCOMMANDLINEHANDLER_H_ */
CommandLineHandlerException(std::string const &why)
const scarab::param_node * GetConfigOverride() const
const std::string & GetPackageString() const
std::vector< std::string > fCommandLineParseLater
OptDescMap::iterator OptDescMapIt
po::options_description fPrintHelpOptions
bool AddOption(const std::string &aTitle, const std::string &aHelpMsg, const std::string &aLongOpt, char aShortOpt, bool aWarnOnDuplicate=true)
Simple option adding function, with short option (flag only; no values allowed)
const std::string & GetConfigFilename() const
Return the file name provided by the user on the command line for the config file.
scarab::param_node fConfigOverrideValues
const po::variables_map * GetVariablesMap() const
po::options_description fCommandLineOptions
std::set< std::string > fAllOptionsLong
const std::string & GetCommandLineJSON() const
Return the string of json provided by the user on the command line.
XReturnType GetCommandLineValue(const std::string &aCLOption)
Return the value of a command line option; throws an exception if the value was not set...
Parses and stores command-line options.
KTLOGGER(applog, "KTApplication")
std::map< std::string, po::options_description *> OptDescMap
const std::string & GetExecutableName() const
const po::parsed_options * GetParsedOptions() const
OptDescMap::const_iterator OptDescMapCIt
#define KTWARN(...)
Definition: KTLogger.hh:346
Contains the logger class and macros, based on Kasper&#39;s KLogger class.
std::set< std::string > fAllGroupKeys