libcyberradio  22.01.24
App.cpp
1 /***************************************************************************
2  * \file App.h
3  *
4  * \brief Defines basic application-level constructs.
5  *
6  * \author DA
7  * \copyright Copyright (c) 2015-2021 CyberRadio Solutions, Inc.
8  *
9  */
10 
11 #include "LibCyberRadio/Common/App.h"
12 #include "LibCyberRadio/Common/Pythonesque.h"
13 #include <iostream>
14 #include <sstream>
15 #include <iomanip>
16 #include <algorithm>
17 #include <stdlib.h>
18 #include <getopt.h>
19 
20 
21 namespace LibCyberRadio
22 {
23 
25  // AppOption
27 
28  int AppOption::TYPE_NONE = 0;
30  int AppOption::TYPE_FLOAT = 2;
31  int AppOption::TYPE_DOUBLE = 3;
32  int AppOption::TYPE_STRING = 4;
36 
38  {
40  valuePtr = (void*)0;
41  showDefault = false;
42  }
43 
44  AppOption::AppOption(const std::string& shortName, const std::string& longName,
45  int valueType, void *valuePtr,
46  const std::string& helpArgName, const std::string& helpText,
47  bool showDefault)
48  {
49  this->shortName = shortName;
50  this->longName = longName;
51  this->valueType = valueType;
52  this->valuePtr = valuePtr;
53  this->helpArgName = helpArgName;
54  this->helpText = helpText;
55  this->showDefault = showDefault;
56  }
57 
59  {
60  this->shortName = opt.shortName;
61  this->longName = opt.longName;
62  this->valueType = opt.valueType;
63  this->valuePtr = opt.valuePtr;
64  this->helpArgName = opt.helpArgName;
65  this->helpText = opt.helpText;
66  this->showDefault = opt.showDefault;
67  }
68 
70  {
71  if ( this != &opt )
72  {
73  this->shortName = opt.shortName;
74  this->longName = opt.longName;
75  this->valueType = opt.valueType;
76  this->valuePtr = opt.valuePtr;
77  this->helpArgName = opt.helpArgName;
78  this->helpText = opt.helpText;
79  this->showDefault = opt.showDefault;
80  }
81  return *this;
82  }
83 
85  {
86  }
87 
88 
89 
91  // AppHelpTextFormatter
93 
95  {
96  _maxOptionWidth = 5;
97  _displayWidth = displayWidth;
98  }
99 
101  {
102  }
103 
104  void AppHelpTextFormatter::addPreOptionText(const std::string& text)
105  {
106  if ( text != "" )
107  _preOptionText.push_back(text);
108  }
109 
110  void AppHelpTextFormatter::addOptionText(const std::string& option,
111  const std::string& text)
112  {
113  if ( option != "" )
114  {
115  _options.push_back(option);
116  _optionText.push_back(text);
117  if ( (int)option.length() > _maxOptionWidth )
118  _maxOptionWidth = option.length();
119  }
120  }
121 
122  void AppHelpTextFormatter::addPostOptionText(const std::string& text)
123  {
124  if ( text != "" )
125  _postOptionText.push_back(text);
126  }
127 
129  {
130  std::ostringstream oss, ossTmp;
131  // Format pre-option text
132  for (BasicStringListIterator it = _preOptionText.begin(); it != _preOptionText.end();
133  it++)
134  {
135  oss << wordWrappedText(*it, _displayWidth, 0);
136  }
137  // Format option text
138  for (BasicStringListIterator ito = _options.begin(), itt = _optionText.begin();
139  ito != _options.end();
140  ito++, itt++)
141  {
142  ossTmp.str("");
143  ossTmp.clear();
144  ossTmp << std::left << std::setw(_maxOptionWidth) << *ito
145  << std::setw(0) << " "
146  << std::setw(0) << *itt;
147  oss << wordWrappedText(ossTmp.str(), _displayWidth, _maxOptionWidth + 2);
148  }
149  // Format post-option text
150  for (BasicStringListIterator it = _postOptionText.begin(); it != _postOptionText.end();
151  it++)
152  {
153  oss << wordWrappedText(*it, _displayWidth, 0);
154  }
155  return oss.str();
156  }
157 
158  std::string AppHelpTextFormatter::wordWrappedText(const std::string& text, int width,
159  int hangingIndent)
160  {
161  std::string ret;
162  std::string hangingIndentText(hangingIndent, ' ');
163  BasicStringList textLines = Pythonesque::Split(text, "\n");
164  for (BasicStringListIterator itl = textLines.begin(); itl != textLines.end(); itl++)
165  {
166  if ( itl == textLines.begin() )
167  {
168  std::string::size_type curPos = 0;
169  int curLine = 0;
170  BasicStringList words = Pythonesque::Split(*itl, " ");
171  for (BasicStringListIterator itw = words.begin(); itw != words.end(); itw++)
172  {
173  // See if printing the next word will go beyond the allowed width
174  if ( curPos + 1 + itw->length() > (std::string::size_type)width )
175  {
176  ret.append("\n");
177  curLine++;
178  // apply hanging indent if needed
179  if ( curLine != 0 )
180  {
181  ret.append(hangingIndentText);
182  curPos = hangingIndentText.length();
183  }
184  // then print the word
185  ret.append(*itw);
186  curPos += itw->length();
187  }
188  else
189  {
190  // Print a space then print the word
191  if (curPos != 0)
192  ret.append(" ");
193  ret.append(*itw);
194  curPos += itw->length() + 1;
195  }
196  }
197  ret.append("\n");
198  }
199  else
200  {
201  ret.append( wordWrappedText(*itl, width, hangingIndent) );
202  }
203  }
204  if ( textLines.size() == 0 )
205  ret.append("\n");
206  return ret;
207  }
208 
209 
211  // AppOptionParser
213 
215  {
216  _allowUnknownOption = false;
217  _displayWidth = 75;
218  // Configure options that we support automatically:
219  // --help
220  addOption("", "help", AppOption::TYPE_NONE, (void*)0, "",
221  "Print this help text", false);
222  // --version
223  addOption("", "version", AppOption::TYPE_NONE, (void*)0, "",
224  "Print version information and exit", false);
225  // Dispatch map for option handler functions. Each option type
226  // (AppOption::TYPE_* constant) should have a corresponding handler
227  // function.
228  // To add a new option type:
229  // (1) Define a member function with this signature to handle that
230  // option type:
231  // int handler(int optindex, const std::string& optarg);
232  // (2) Add the new handler the dispatch map below.
233  _optionHelpers[AppOption::TYPE_NONE] = &AppOptionParser::handleOptionNone;
234  _optionHelpers[AppOption::TYPE_INTEGER] = &AppOptionParser::handleOptionInt;
235  _optionHelpers[AppOption::TYPE_FLOAT] = &AppOptionParser::handleOptionFloat;
236  _optionHelpers[AppOption::TYPE_DOUBLE] = &AppOptionParser::handleOptionDouble;
237  _optionHelpers[AppOption::TYPE_STRING] = &AppOptionParser::handleOptionString;
238  _optionHelpers[AppOption::TYPE_BOOLEAN] = &AppOptionParser::handleOptionBool;
239  _optionHelpers[AppOption::TYPE_BOOLEAN_SET_TRUE] = &AppOptionParser::handleOptionBooleanSetTrue;
240  _optionHelpers[AppOption::TYPE_BOOLEAN_SET_FALSE] = &AppOptionParser::handleOptionBooleanSetFalse;
241  }
242 
244  {
245  }
246 
248  {
249  _optionList.push_back( opt );
250  }
251 
252  void AppOptionParser::addOption(const std::string& shortName,
253  const std::string& longName,
254  int valueType, void *valuePtr,
255  const std::string& helpArgName, const std::string& helpText,
256  bool showDefault)
257  {
258  addOption( AppOption(shortName, longName, valueType, valuePtr,
259  helpArgName, helpText, showDefault) );
260  }
261 
263  {
264  _allowUnknownOption = allow;
265  }
266 
267  void AppOptionParser::setDescription(const std::string& description)
268  {
269  _description = description;
270  }
271 
272  void AppOptionParser::setDisplayWidth(int displayWidth)
273  {
274  _displayWidth = displayWidth;
275  }
276 
277  void AppOptionParser::setEpilogText(const std::string& epilogText)
278  {
279  _epilogText = epilogText;
280  }
281 
282  void AppOptionParser::setExecutable(const std::string& executable)
283  {
284  _executable = executable;
285  }
286 
287  void AppOptionParser::setUnparsedArgText(const std::string& unparsedArgText)
288  {
289  _unparsedArgText = unparsedArgText;
290  }
291 
292  void AppOptionParser::setVersion(const std::string& version)
293  {
294  _version = version;
295  }
296 
297  int AppOptionParser::parse(int argc, char** argv)
298  {
299  int ret = 0;
300  // Form short argument list and long option structure list
301  std::string shargs;
302  struct option longOptions[_optionList.size() + 1];
303  for (int i = 0; i < (int)_optionList.size(); i++)
304  {
305  // If a long option has a corresponding short option,
306  // set the return value to the short option character.
307  if ( _optionList[i].shortName.length() == 1 )
308  {
309  shargs.append(_optionList[i].shortName);
310  if ( optionValueArg(_optionList[i].valueType) )
311  shargs.append(":");
312  longOptions[i].val = (int)_optionList[i].shortName[0];
313  }
314  // Otherwise, encode the index in the return value.
315  else
316  {
317  longOptions[i].val = 32768+i;
318  }
319  longOptions[i].name = _optionList[i].longName.c_str();
320  longOptions[i].has_arg = optionValueArg(_optionList[i].valueType);
321  longOptions[i].flag = (int*)0;
322  }
323  // Terminate long option structure list with an empty element
324  longOptions[_optionList.size()].name = (char*)0;
325  longOptions[_optionList.size()].has_arg = 0;
326  longOptions[_optionList.size()].flag = (int*)0;
327  longOptions[_optionList.size()].val = 0;
328 #ifdef DEBUG
329  std::cerr << "[DBG] Short option list: " << shargs << std::endl;
330 #endif
331 
332  // Parse options
333  int opt = 0;
334  int optindex = 0;
335  while (1)
336  {
337  opt = getopt_long(/* int */ argc, /* char * const argv[] */ argv,
338  /* const char *optstring */ shargs.c_str(),
339  /* const struct option *longopts */ (const struct option *)longOptions,
340  /* int *longindex */ &optindex);
341  if (opt == -1)
342  break;
343 #ifdef DEBUG
344  std::cerr << "Option parsed: " << opt << " (" << (char)opt << ")" << std::endl;
345 #endif
346 
347  switch(opt)
348  {
349  case '?':
350  // Option is unknown.
351  if ( !_allowUnknownOption )
352  ret = 2;
353  break;
354  default:
355  // Option is known but we haven't handled it yet.
356  ret = handleOptionReturn(opt, optarg ? optarg : "");
357  if ( ret == 1 )
358  std::cerr << "ERROR: Improperly formatted argument!" << std::endl;
359  break;
360  }
361  if ( ret != 0 )
362  break;
363  }
364  // Collect unparsed arguments. Use of unparsed arguments is application-specific.
365  if ( (ret == 0) && (optind < argc) )
366  {
367  while (optind < argc)
368  unparsedArgs.push_back( argv[optind++] );
369  }
370 
371  return ret;
372  }
373 
374  int AppOptionParser::handleOptionReturn(int opt, const std::string& optarg)
375  {
376  int ret = 0;
377  // We need to find the option index that corresponds to our option
378  // return value.
379  int our_optindex = -1;
380  // -- Short options, and long options w/ short options, have return
381  // values < 32768; return value = short option value
382  if ( opt < 32768 )
383  {
384  // Find the option where return value = short option value
385  for (int i = 0; i < (int)_optionList.size(); i++)
386  {
387  if ( (_optionList[i].shortName.length() == 1) &&
388  (_optionList[i].shortName[0] == (char)opt) )
389  {
390  our_optindex = i;
391  break;
392  }
393  }
394  }
395  // -- Long options w/o short options have return values >= 32768; option
396  // index = return value - 32768
397  else
398  {
399  our_optindex = opt - 32768;
400  }
401  // Dispatch option handler if we can
402  if ( our_optindex != -1 )
403  {
404  if ( _optionList[our_optindex].longName == "version" ) // Version information request
405  {
406  std::cerr << _description << ", Version " << _version << std::endl;
407  ret = 3;
408  }
409  else if ( _optionList[our_optindex].longName == "help" ) // Help requested
410  {
411  printUsage();
412  ret = 2;
413  }
414  else if ( _optionHelpers.count(_optionList[our_optindex].valueType) > 0 )
415  {
416  ret = (this->*_optionHelpers[_optionList[our_optindex].valueType])(our_optindex, optarg);
417  }
418  else
419  ret = 1;
420  }
421  else
422  ret = 1;
423  return ret;
424  }
425 
426  void AppOptionParser::printUsage()
427  {
428  std::ostringstream ossPre, ossPost;
429  AppHelpTextFormatter fmtr(_displayWidth);
430  ossPre << _description << ", Version " << _version << "\n\n" << "Usage:\n" << _executable;
431  if ( _optionList.size() > 0 )
432  ossPre << " [options]";
433  if ( _unparsedArgText.length() > 0 )
434  ossPre << " " << _unparsedArgText;
435  ossPre << "\n\n";
436  if ( _optionList.size() > 0 )
437  {
438  ossPre << "Options:\n\n";
439  std::string opt, optText;
440  for (int i = 0; i < (int)_optionList.size(); i++)
441  {
442  opt = "";
443  if ( _optionList[i].shortName.length() == 1 )
444  {
445  opt.append("-");
446  opt.append(_optionList[i].shortName);
447  if ( optionValueArg(_optionList[i].valueType) > no_argument )
448  {
449  opt.append(" ");
450  opt.append(_optionList[i].helpArgName);
451  }
452  }
453  if ( _optionList[i].longName.length() > 0 )
454  {
455  if ( opt != "" )
456  opt.append(", ");
457  opt.append("--");
458  opt.append(_optionList[i].longName);
459  if ( optionValueArg(_optionList[i].valueType) > no_argument )
460  {
461  opt.append("=");
462  opt.append(_optionList[i].helpArgName);
463  }
464  }
465  // std::cerr << std::left << std::setw(25) << opt
466  // << std::setw(0) << " "
467  // << std::setw(0) << _optionList[i].help_text
468  // << "\n";
469  optText = _optionList[i].helpText;
470  optText.append( getDefault(_optionList[i]) );
471  fmtr.addOptionText(opt, optText);
472  }
473  }
474  if ( _epilogText.length() > 0 )
475  ossPost << "\n" << _epilogText << "\n";
476  fmtr.addPreOptionText(ossPre.str());
477  fmtr.addPostOptionText(ossPost.str());
478  //std::cerr << "[DBG] Formatter loaded" << std::endl;
479  std::cerr << fmtr.getFormattedText() << std::endl;
480  }
481 
482  int AppOptionParser::optionValueArg(int valueType)
483  {
484  int ret = no_argument;
485  if ( (valueType >= AppOption::TYPE_INTEGER) &&
486  (valueType <= AppOption::TYPE_BOOLEAN) )
487  ret = required_argument;
488  return ret;
489  }
490 
491  std::string AppOptionParser::getDefault(const AppOption& opt)
492  {
493  std::ostringstream oss;
494  int *iptr;
495  float *fptr;
496  double *dptr;
497  bool *bptr;
498  std::string *sptr;
499  if ( opt.showDefault && (opt.valuePtr != (void*)0) )
500  {
501  oss << " Default: ";
502  if ( opt.valueType == AppOption::TYPE_INTEGER )
503  {
504  iptr = (int *)opt.valuePtr;
505  oss << *iptr << ".";
506  }
507  else if ( opt.valueType == AppOption::TYPE_FLOAT )
508  {
509  fptr = (float *)opt.valuePtr;
510  oss << *fptr << ".";
511  }
512  else if ( opt.valueType == AppOption::TYPE_DOUBLE )
513  {
514  dptr = (double *)opt.valuePtr;
515  oss << *dptr << ".";
516  }
517  else if ( opt.valueType == AppOption::TYPE_STRING )
518  {
519  sptr = (std::string *)opt.valuePtr;
520  oss << *sptr << ".";
521  }
522  else if ( (opt.valueType >= AppOption::TYPE_BOOLEAN) &&
523  (opt.valueType <= AppOption::TYPE_BOOLEAN_SET_FALSE) )
524  {
525  bptr = (bool *)opt.valuePtr;
526  oss << (*bptr ? "True" : "False") << ".";
527  }
528  else
529  {
530  oss << "None.";
531  }
532  }
533  return oss.str();
534  }
535 
536  int AppOptionParser::handleOptionNone(int optindex, const std::string& optarg)
537  {
538  return 0;
539  }
540 
541  int AppOptionParser::handleOptionInt(int optindex, const std::string& optarg)
542  {
543  int ret = 0;
544  if ( _optionList[optindex].valuePtr != (void*)0 )
545  {
546  char *endptr;
547  int *vptr = (int *)_optionList[optindex].valuePtr;
548  int tmp = (int)strtol(optarg.c_str(), &endptr, 10);
549  if ( *endptr == '\0' )
550  *vptr = tmp;
551  else
552  ret = 1;
553  }
554  return ret;
555  }
556 
557  int AppOptionParser::handleOptionFloat(int optindex, const std::string& optarg)
558  {
559  int ret = 0;
560  if ( _optionList[optindex].valuePtr != (void*)0 )
561  {
562  char *endptr;
563  float *vptr = (float *)_optionList[optindex].valuePtr;
564  float tmp = (float)strtod(optarg.c_str(), &endptr);
565  if ( *endptr == '\0' )
566  *vptr = tmp;
567  else
568  ret = 1;
569  }
570  return ret;
571  }
572 
573  int AppOptionParser::handleOptionDouble(int optindex, const std::string& optarg)
574  {
575  int ret = 0;
576  if ( _optionList[optindex].valuePtr != (void*)0 )
577  {
578  char *endptr;
579  double *vptr = (double *)_optionList[optindex].valuePtr;
580  double tmp = strtod(optarg.c_str(), &endptr);
581  if ( *endptr == '\0' )
582  *vptr = tmp;
583  else
584  ret = 1;
585  }
586  return ret;
587  }
588 
589  int AppOptionParser::handleOptionString(int optindex, const std::string& optarg)
590  {
591  int ret = 0;
592  if ( _optionList[optindex].valuePtr != (void*)0 )
593  {
594  std::string *vptr = (std::string *)_optionList[optindex].valuePtr;
595  *vptr = optarg;
596  }
597  return ret;
598  }
599 
600  int AppOptionParser::handleOptionBool(int optindex, const std::string& optarg)
601  {
602  int ret = 0;
603  if ( _optionList[optindex].valuePtr != (void*)0 )
604  {
605  std::string val = optarg;
606  bool *vptr = (bool *)_optionList[optindex].valuePtr;
607  std::transform(val.begin(), val.end(), val.begin(), ::tolower);
608  if ( (val == "true") || (val == "yes") || (val == "on") || (val == "1") )
609  *vptr = true;
610  else if ( (val == "false") || (val == "no") || (val == "off") || (val == "0") )
611  *vptr = false;
612  else
613  ret = 1;
614  }
615  return ret;
616  }
617 
618  int AppOptionParser::handleOptionBooleanSetTrue(int optindex, const std::string& optarg)
619  {
620  int ret = 0;
621  if ( _optionList[optindex].valuePtr != (void*)0 )
622  {
623  bool *vptr = (bool *)_optionList[optindex].valuePtr;
624  *vptr = true;
625  }
626  return ret;
627  }
628 
629  int AppOptionParser::handleOptionBooleanSetFalse(int optindex, const std::string& optarg)
630  {
631  int ret = 0;
632  if ( _optionList[optindex].valuePtr != (void*)0 )
633  {
634  bool *vptr = (bool *)_optionList[optindex].valuePtr;
635  *vptr = false;
636  }
637  return ret;
638  }
639 
640 
641 
643  // App
645 
647  {
648  description = "Generic Application";
649  version = "0.0.1";
650  }
651 
652  int App::run(int argc, char *argv[])
653  {
654  defineOptions(argv[0]);
655  int ret = parseCommandLine(argc, argv);
656  if ( ret == 0 )
657  ret = mainLoop();
658  return ret;
659  }
660 
661  void App::defineOptions(const char *argv0)
662  {
663  // Base-class implementation configures basic app info and usage info
664  _optParser.setDescription(description);
665  _optParser.setVersion(version);
666  _optParser.setExecutable(argv0);
667  _optParser.setUnparsedArgText("");
668  _optParser.setEpilogText("");
669  // Derived classes should call base-class version, then extend/override with their
670  // own supported options.
671  }
672 
674  {
675  // Base-class implementation does nothing; derived classes should override
676  // with their own implementations.
677  int ret = 0;
678  return ret;
679  }
680 
681  int App::parseCommandLine(int argc, char* argv[])
682  {
683  return _optParser.parse(argc, argv);
684  }
685 
686 }
void allowUnknownOption(bool allow=true)
Determines whether or not the parser will allow unknown options to pass through the parser without ge...
Definition: App.cpp:262
static int TYPE_NONE
Option does not set a value.
Definition: App.h:119
virtual AppOption & operator=(const AppOption &opt)
Makes one AppOption object equivalent to another.
Definition: App.cpp:69
std::string shortName
Short option name, without leading hyphen.
Definition: App.h:86
virtual void addPreOptionText(const std::string &text)
Adds text that gets displayed before the list of options.
Definition: App.cpp:104
virtual void defineOptions(const char *argv0)
Defines which command-line options are supported by the application, as well as any help text that is...
Definition: App.cpp:661
static int TYPE_BOOLEAN
Option explicitly sets a boolean value.
Definition: App.h:139
virtual ~AppHelpTextFormatter()
Destroys an AppHelpTextFormatter object.
Definition: App.cpp:100
void setExecutable(const std::string &executable)
Sets the portion of the usage information where the executable name is displayed. ...
Definition: App.cpp:282
void setVersion(const std::string &version)
Sets the portion of the usage information that represents the application version.
Definition: App.cpp:292
virtual int mainLoop()
Defines the application&#39;s main processing loop.
Definition: App.cpp:673
static int TYPE_BOOLEAN_SET_TRUE
Option sets a boolean value that is False by default but becomes True if this option is specified...
Definition: App.h:144
void setDescription(const std::string &description)
Sets the portion of the usage information where the application description is displayed.
Definition: App.cpp:267
virtual ~AppOptionParser()
Destroys an AppOptionParser object.
Definition: App.cpp:243
void setDisplayWidth(int displayWidth=75)
Sets the display width of the usage information.
Definition: App.cpp:272
AppOptionParser()
Constructs an AppOptionParser object.
Definition: App.cpp:214
static BasicStringList Split(const std::string &str, const std::string &sep, int maxsplit=INT_MAX)
Splits the given string into a list of string tokens.
Definition: Pythonesque.cpp:77
std::string version
The application version.
Definition: App.h:496
BASIC_LIST_CONTAINER< std::string > BasicStringList
Type representing a list of strings.
Definition: BasicList.h:25
static int TYPE_INTEGER
Option sets an integer value.
Definition: App.h:123
App()
Constructs an App object.
Definition: App.cpp:646
Defines functionality for LibCyberRadio applications.
Definition: App.h:23
BasicStringList unparsedArgs
The collection of arguments that were not dealt with by the parser during option parsing.
Definition: App.h:407
void * valuePtr
Pointer to a variable that holds the option value.
Definition: App.h:100
void setEpilogText(const std::string &epilogText)
Sets the epilog portion of the usage information; that is, the part that comes after the list of supp...
Definition: App.cpp:277
void setUnparsedArgText(const std::string &unparsedArgText)
Sets the portion of the usage information that represents the collection of unparsed arguments...
Definition: App.cpp:287
virtual std::string getFormattedText()
Gets the formatted help text.
Definition: App.cpp:128
virtual int run(int argc, char *argv[])
Runs the application.
Definition: App.cpp:652
virtual void addPostOptionText(const std::string &text)
Adds text that gets displayed after the list of options.
Definition: App.cpp:122
virtual void addOption(const AppOption &opt)
Adds an allowed option to the parser.
Definition: App.cpp:247
static int TYPE_DOUBLE
Option sets a double-precision floating-point value.
Definition: App.h:131
static int TYPE_FLOAT
Option sets a floating-point value.
Definition: App.h:127
AppOption()
Constructs an empty AppOption object.
Definition: App.cpp:37
bool showDefault
Show the default value in the option help text.
Definition: App.h:113
std::string description
The application description.
Definition: App.h:492
std::string helpText
Option help text.
Definition: App.h:108
AppHelpTextFormatter(int displayWidth=75)
Constructs an AppHelpTextFormatter object.
Definition: App.cpp:94
std::string longName
Long option name, without leading hyphens.
Definition: App.h:91
static int TYPE_STRING
Option sets a string value.
Definition: App.h:135
virtual int parse(int argc, char **argv)
Parses the command-line options.
Definition: App.cpp:297
virtual void addOptionText(const std::string &option, const std::string &text)
Adds an option and its help text to the list of options.
Definition: App.cpp:110
virtual ~AppOption()
Destroys an AppOption object.
Definition: App.cpp:84
static int TYPE_BOOLEAN_SET_FALSE
Option sets a boolean value that is True by default but becomes False if this option is specified...
Definition: App.h:149
Defines a command-line option that is supported by an application.
Definition: App.h:28
int valueType
Type of value that this option sets.
Definition: App.h:96
std::string helpArgName
Option argument name to display in the help text.
Definition: App.h:104