CommandOption.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
44 #include "CommandOption.hpp"
45 #include "CommandOptionParser.hpp"
46 #include "StringUtils.hpp"
47 
48 #include <sstream>
49 
50 using namespace std;
51 using namespace gnsstk::StringUtils;
52 
53 namespace gnsstk
54 {
56 
57  CommandOption::CommandOption(
60  const char shOpt,
61  const std::string& loOpt,
62  const std::string& desc,
63  const bool req,
64  CommandOptionVec& optVectorList)
65  : optFlag(of), optType(ot),
66  shortOpt(shOpt), longOpt(loOpt), description(desc),
67  required(req), count(0), maxCount(0), order(0), parser(NULL)
68  {
69  if (ot == CommandOption::stdType)
70  {
71  if ( (shOpt == 0) && (loOpt.size() == 0) )
72  {
73  InvalidParameter exc("A short or long command option must be specified");
74  GNSSTK_THROW(exc);
75  }
76  // if short option is specified, allow only printable, non-space characters
77  if ( (shOpt != 0) && !isgraph(shOpt) )
78  {
79  InvalidParameter exc("Invalid short command option character");
80  GNSSTK_THROW(exc);
81  }
82  // if long option is specified, allow only printable, non-space characters
83  for ( size_t i = longOpt.size(); i > 0; --i )
84  {
85  if ( !isgraph(longOpt[i - 1]) )
86  {
87  InvalidParameter exc("Invalid long command option character");
88  GNSSTK_THROW(exc);
89  }
90  }
91  }
92  optVectorList.push_back(this);
93  }
94 
95  // Prints out short options with a leading '-' and long ones with '--'.
96  // Puts a '|' between them if it has both.
98  {
99  string toReturn;
100  if (shortOpt != 0)
101  {
102  toReturn += string("-") + string(1, shortOpt);
103  if (!longOpt.empty())
104  toReturn += string(" | --") + longOpt;
105  }
106  else
107  {
108  toReturn += string("--") + longOpt;
109  }
110  return toReturn;
111  }
112 
113  // Prints out short options with a leading '-' and long ones with '--'.
114  // Puts a ',' between them if it has both.
116  {
117  string toReturn(" ");
118  if (shortOpt != 0)
119  {
120  toReturn += string("-") + string(1, shortOpt);
121  if (!longOpt.empty())
122  {
123  toReturn += string(", --") + longOpt;
124  if (optFlag == hasArgument)
125  toReturn += "=" + getArgString();
126  }
127  else
128  {
129  if (optFlag == hasArgument)
130  toReturn += " " + getArgString();
131  }
132  }
133  else
134  {
135  toReturn += string(" --") + longOpt;
136  if (optFlag == hasArgument)
137  toReturn += "=" + getArgString();
138  }
139  return toReturn;
140  }
141 
142  // creates the struct option for getopt_long
143  struct option CommandOption::toGetoptLongOption() const
144  {
145  struct option o = {longOpt.c_str(), optFlag, NULL, 0};
146  return o;
147  }
148 
149  // makes the string for getopt
151  {
152  std::string opt(1, shortOpt);
153  if (optFlag == hasArgument) opt += ":";
154  return opt;
155  }
156 
157  // get the order of the specified instance of this command option
158  unsigned long CommandOption::getOrder(unsigned long idx) const
159  {
160  if (order.size() == 0)
161  return 0;
162 
163  if (idx == (unsigned long)-1)
164  return order[order.size()-1];
165 
166  if (idx >= order.size())
167  return 0;
168 
169  return order[idx];
170  }
171 
172  // writes out the vector of values for this command option
173  std::ostream& CommandOption::dumpValue(std::ostream& out) const
174  {
175  std::vector<std::string>::const_iterator itr = value.begin();
176  while(itr != value.end())
177  {
178  out << *itr << std::endl;
179  itr++;
180  }
181  return out;
182  }
183 
184  // returns a string like this:
185  //
186  // -f | --foo <arg>
187  // this is the description
188  //
189  std::string CommandOption::getDescription() const
190  {
191  ostringstream out;
192  // do the option itself first
193  out << '\t';
194  if (shortOpt != 0)
195  {
196  out << '-' << shortOpt;
197  if (!longOpt.empty())
198  out << " | ";
199  else
200  out << '\t';
201  }
202  if (! longOpt.empty())
203  {
204  out << "--" << longOpt;
205  }
206  if (optFlag == hasArgument)
207  {
208  out << " " << getArgString();
209  }
210  // and the description goes on a new line
211  out << endl << prettyPrint(description,
212  "\n",
213  " ",
214  " ");
215  if (maxCount != 0)
216  {
217  out << "\t\tUp to " << maxCount << " may be used on the command line."
218  << endl;
219  }
220  return out.str();
221  }
222 
223  // this checks if it expects number or string type arguments.
224  // it returns a string describing the error, if any.
226  {
227  if (required && (count == 0))
228  return "Required option " + getOptionString() + " was not found.";
229 
230  return string();
231  }
232 
234  {
235  if (required && (count == 0))
236  return "Required trailing argument was not found.";
237 
238  return string();
239  }
240 
242  {
243  string errstr = CommandOption::checkArguments();
244 
245  if (!errstr.empty())
246  return errstr;
247 
248  vector<string>::size_type vecindex;
249  for(vecindex = 0; vecindex < value.size(); vecindex++)
250  {
251  if (!isDigitString(value[vecindex]))
252  {
253  string errstr("Argument for ");
254  errstr += getOptionString();
255  errstr += string(" should be a digit string.");
256  return errstr;
257  }
258  }
259 
260  return string();
261  }
262 
264  {
265  string errstr = CommandOption::checkArguments();
266 
267  if (!errstr.empty())
268  return errstr;
269 
270  vector<string>::size_type vecindex;
271  for(vecindex = 0; vecindex < value.size(); vecindex++)
272  {
273  if (!isDecimalString(value[vecindex]))
274  {
275  string errstr("Argument for ");
276  errstr += getOptionString();
277  errstr += string(" should be a decimal string.");
278  return errstr;
279  }
280  }
281 
282  return string();
283  }
284 
286  {
287  string errstr = CommandOption::checkArguments();
288 
289  if (!errstr.empty())
290  return errstr;
291 
292  vector<string>::size_type vecindex;
293  for(vecindex = 0; vecindex < value.size(); vecindex++)
294  {
295  if (!isAlphaString(value[vecindex]))
296  {
297  string errstr("Argument for ");
298  errstr += getOptionString();
299  errstr += string(" should be an alphabetic string.");
300  return errstr;
301  }
302  }
303  return errstr;
304  }
305 
307  {
308  if (doOneOfChecking)
309  {
311  if (oo != string())
312  return oo;
313  }
314 
315  // mutex doesn't call CommandOption::checkArguments because
316  // it uses "required" differently
317  string errstr("Only one of the following options may be specified: ");
318  int firstSpec = -1;
319  bool touched = false;
320 
321  for (size_t i = 0; i < optionVec.size(); i++)
322  {
323  CommandOption *opt = optionVec[i];
324 
325  if (i)
326  errstr += ", ";
327  errstr += opt->getOptionString();
328  if (opt->getCount())
329  {
330  if (firstSpec != -1)
331  touched = true;
332  else
333  firstSpec = i;
334  }
335  }
336 
337  if (touched)
338  return errstr;
339 
340  return string();
341  }
342 
344  {
345  if (NULL == opt)
346  {
347  InvalidParameter exc("Invalid option address");
348  GNSSTK_THROW(exc);
349  }
350  optionVec.push_back(opt);
351  }
352 
354  {
355  // n-of doesn't call CommandOption::checkArguments because
356  // it doesn't use "required"
357  string fewerrstr("At least " + StringUtils::asString(N));
358 
359  string manyerrstr("No more than " + StringUtils::asString(maxCount));
360  string errstr(" of the following options must be specified: ");
361 
362  bool found = false;
363  unsigned long n = 0;
364 
365  for (CommandOptionVec::size_type i = 0; i < optionVec.size(); i++)
366  {
367  n += optionVec[i]->getCount();
368  if (i > 0)
369  errstr += ", ";
370  errstr += optionVec[i]->getOptionString();
371  }
372 
373  if (n < N)
374  return fewerrstr + errstr;
375  if (n > maxCount)
376  return manyerrstr + errstr;
377 
378  return string();
379  }
380 
381  std::vector<CommandOption*> CommandOptionNOf::which() const
382  {
383  std::vector<CommandOption*> rv;
384 
385  for (CommandOptionVec::size_type i = 0; i < optionVec.size(); i++)
386  {
387  if (optionVec[i]->getCount())
388  {
389  rv.push_back(optionVec[i]);
390  }
391  }
392 
393  return rv;
394  }
395 
397  {
398  if (NULL == opt)
399  {
400  InvalidParameter exc("Invalid option address");
401  GNSSTK_THROW(exc);
402  }
403  optionVec.push_back(opt);
404  }
405 
407  {
408  // one-of doesn't call CommandOption::checkArguments because
409  // it doesn't use "required"
410  string errstr("One of the following options must be specified: ");
411  bool found = false;
412 
413  for (size_t i = 0; i < optionVec.size(); i++)
414  {
415  if (optionVec[i]->getCount())
416  found = true;
417  if (i > 0)
418  errstr += ", ";
419  errstr += optionVec[i]->getOptionString();
420  }
421 
422  if (!found)
423  return errstr;
424 
425  return string();
426  }
427 
429  {
430  CommandOption *rv = NULL;
431 
432  for (size_t i = 0; i < optionVec.size(); i++)
433  {
434  if (optionVec[i]->getCount())
435  {
436  rv = optionVec[i];
437  break;
438  }
439  }
440 
441  return rv;
442  }
443 
445  {
446  string errstr("The following options must be used together: ");
447  bool found = false, notFound = false;
448 
449  for (size_t i = 0; i < optionVec.size(); i++)
450  {
451  if (optionVec[i]->getCount())
452  found = true;
453  else
454  notFound = true;
455  if (i > 0)
456  errstr += ", ";
457  errstr += optionVec[i]->getOptionString();
458  }
459 
460  if (found && notFound)
461  return errstr;
462 
463  return string();
464  }
465 
466  unsigned long CommandOptionAllOf::getCount() const
467  {
468  unsigned long rv = 0;
469  for (size_t i = 0; i < optionVec.size(); i++)
470  {
471  if (optionVec[i]->getCount() == 0)
472  return 0;
473  rv += optionVec[i]->getCount();
474  }
475  return rv;
476  }
477 
479  const CommandOption* parent,
480  const CommandOption* child)
481  : CommandOption(noArgument, metaType, 0, "", "")
482  {
483  if (NULL == parent)
484  {
485  InvalidParameter exc("Invalid parent address");
486  GNSSTK_THROW(exc);
487  }
488  if (NULL == child)
489  {
490  InvalidParameter exc("Invalid child address");
491  GNSSTK_THROW(exc);
492  }
493  requiree = parent;
494  requirer = child;
495  }
496 
498  {
499  // dependent doesn't call CommandOption::checkArguments because
500  // it doesn't use "required"
501  string errstr;
502 
503  if (!requiree)
504  errstr = "Null requiree (parent) for CommandOptionDependent";
505  if (!requirer)
506  errstr = "Null requirer (child) for CommandOptionDependent";
507 
508  if (requirer->getCount() && !requiree->getCount())
509  errstr = "Option " + requirer->getOptionString() + " requires " +
511 
512  return errstr;
513  }
514 
516  {
517  string rv;
518  if (optionVec.size() > 1)
519  rv += "(";
520  for (size_t i = 0; i < optionVec.size(); i++)
521  {
522  if (i) rv += ",";
523  rv += optionVec[i]->getOptionString();
524  }
525  if (optionVec.size() > 1)
526  rv += ")";
527 
528  return rv;
529  }
530 
531  unsigned long CommandOptionGroupOr::getCount() const
532  {
533  unsigned long rv = 0;
534  for (size_t i = 0; i < optionVec.size(); i++)
535  rv += optionVec[i]->getCount();
536 
537  return rv;
538  }
539 
540  unsigned long CommandOptionGroupAnd::getCount() const
541  {
542  unsigned long rv = 0;
543  for (size_t i = 0; i < optionVec.size(); i++)
544  {
545  if (optionVec[i]->getCount() == 0)
546  return 0;
547  rv += optionVec[i]->getCount();
548  }
549  return rv;
550  }
551 
552  void CommandOptionHelpUsage::printHelp(std::ostream& out, bool pretty)
553  {
555  // Secret option! Ask for help once, get the normal usage.
556  // Ask for help twice, get doxygen-formatted comments to
557  // insert into your code's documentation.
558  if (getCount() == 1)
559  parser->displayUsage(out, pretty);
560  else if (getCount() > 1)
562  }
563 
564 } // namespace gnsstk
gnsstk::CommandOption::getOptionString
virtual std::string getOptionString() const
Definition: CommandOption.cpp:97
gnsstk::CommandOptionWithStringArg::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:285
gnsstk::CommandOption::stdType
@ stdType
The argument of this option can be any type.
Definition: CommandOption.hpp:135
gnsstk::CommandOption::longOpt
std::string longOpt
The string for the long option (for example, "--foo").
Definition: CommandOption.hpp:246
gnsstk::CommandOption::required
bool required
Whether or not this is a required command line option.
Definition: CommandOption.hpp:252
gnsstk::CommandOption::toGetoptShortOption
std::string toGetoptShortOption() const
Returns a string for use with getopt.
Definition: CommandOption.cpp:150
gnsstk::CommandOption::description
std::string description
The description for the help text.
Definition: CommandOption.hpp:248
gnsstk::CommandOptionParser::displayUsageDoxygen
std::ostream & displayUsageDoxygen(std::ostream &out)
Definition: CommandOptionParser.cpp:440
gnsstk::defaultCommandOptionList
CommandOptionVec defaultCommandOptionList
Definition: CommandOption.cpp:55
gnsstk::CommandOption::getOrder
unsigned long getOrder(unsigned long idx=-1) const
Definition: CommandOption.cpp:158
gnsstk::CommandOptionMutex::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:306
const
#define const
Definition: getopt.c:43
StringUtils.hpp
gnsstk::CommandOptionOneOf::addOption
void addOption(CommandOption *opt)
Add an option to the list of mutually exclusive options.
Definition: CommandOption.cpp:396
gnsstk::CommandOptionDependent::CommandOptionDependent
CommandOptionDependent()
Default Constructor.
Definition: CommandOption.hpp:663
gnsstk::StringUtils::isAlphaString
bool isAlphaString(const std::string &s)
Definition: StringUtils.hpp:1922
gnsstk::CommandOption::CommandOptionType
CommandOptionType
Definition: CommandOption.hpp:132
gnsstk::CommandOption::maxCount
unsigned long maxCount
Definition: CommandOption.hpp:258
gnsstk::CommandOptionHelpUsage::printHelp
virtual void printHelp(std::ostream &out, bool pretty=true)
Definition: CommandOption.cpp:552
gnsstk::CommandOptionDependent::requirer
const CommandOption * requirer
Definition: CommandOption.hpp:665
gnsstk::CommandOptionWithNumberArg::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:241
gnsstk::CommandOptionAllOf::getCount
virtual unsigned long getCount() const
returns the sum of all encapsulated option counts if all are in use, zero otherwise.
Definition: CommandOption.cpp:466
gnsstk::CommandOptionDependent::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:497
gnsstk::CommandOptionNOf::N
unsigned long N
Definition: CommandOption.hpp:528
gnsstk::CommandOption::getArgString
virtual std::string getArgString() const
Returns a string with the argument format.
Definition: CommandOption.hpp:176
gnsstk::CommandOption::getCount
virtual unsigned long getCount() const
Definition: CommandOption.hpp:188
gnsstk::CommandOptionOneOf::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:406
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::CommandOption::dumpValue
std::ostream & dumpValue(std::ostream &out) const
Displays this->value to the stream out.
Definition: CommandOption.cpp:173
gnsstk::CommandOption::getDescription
std::string getDescription() const
Returns a formatted string with the description of this option.
Definition: CommandOption.cpp:189
CommandOptionParser.hpp
gnsstk::CommandOptionOneOf::optionVec
CommandOptionVec optionVec
Definition: CommandOption.hpp:563
NULL
#define NULL
Definition: getopt1.c:64
gnsstk::CommandOptionOneOf::whichOne
CommandOption * whichOne() const
Definition: CommandOption.cpp:428
gnsstk::CommandOption::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:225
gnsstk::CommandOptionGroupOr::getCount
virtual unsigned long getCount() const
returns the sum of all encapsulated option counts.
Definition: CommandOption.cpp:531
gnsstk::CommandOptionNOf::which
std::vector< CommandOption * > which() const
Definition: CommandOption.cpp:381
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::CommandOptionRest::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:233
gnsstk::CommandOption::shortOpt
char shortOpt
The character for the short option (for example, '-f').
Definition: CommandOption.hpp:244
gnsstk::CommandOptionAllOf::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:444
gnsstk::CommandOptionGroupOr::getOptionString
virtual std::string getOptionString() const
return a string containing the aggregated option strings
Definition: CommandOption.cpp:515
CommandOption.hpp
gnsstk::CommandOptionVec
std::vector< CommandOption * > CommandOptionVec
Definition: CommandOption.hpp:66
gnsstk::CommandOption::count
unsigned long count
Definition: CommandOption.hpp:255
gnsstk::CommandOption::optFlag
CommandOptionFlag optFlag
Flag for determining whether this option has an argument or not.
Definition: CommandOption.hpp:239
gnsstk::CommandOption::value
std::vector< std::string > value
Any arguments passed with this option get put in here.
Definition: CommandOption.hpp:250
gnsstk::CommandOptionNOf::addOption
void addOption(CommandOption *opt)
Add an option to the list of mutually exclusive options.
Definition: CommandOption.cpp:343
gnsstk::CommandOption
Definition: CommandOption.hpp:115
gnsstk::CommandOptionWithDecimalArg::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:263
gnsstk::CommandOption::order
std::vector< unsigned long > order
The order in which this option was encountered on the command line.
Definition: CommandOption.hpp:260
gnsstk::CommandOption::hasArgument
@ hasArgument
option requires an argument
Definition: CommandOption.hpp:126
gnsstk::StringUtils
Definition: IonexStoreStrategy.cpp:44
option
Definition: getopt.h:94
GNSSTK_ASSERT
#define GNSSTK_ASSERT(CONDITION)
Provide an "ASSERT" type macro.
Definition: Exception.hpp:373
gnsstk::CommandOptionGroupAnd::getCount
virtual unsigned long getCount() const
returns the sum of all encapsulated option counts if all are in use, zero otherwise.
Definition: CommandOption.cpp:540
gnsstk::CommandOption::getFullOptionString
std::string getFullOptionString() const
Definition: CommandOption.cpp:115
std
Definition: Angle.hpp:142
gnsstk::CommandOptionNOf::optionVec
CommandOptionVec optionVec
Definition: CommandOption.hpp:527
gnsstk::StringUtils::isDecimalString
bool isDecimalString(const std::string &s)
Definition: StringUtils.hpp:1885
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::CommandOptionParser::displayUsage
std::ostream & displayUsage(std::ostream &out, bool doPretty=true)
Definition: CommandOptionParser.cpp:375
gnsstk::CommandOptionMutex::doOneOfChecking
bool doOneOfChecking
Definition: CommandOption.hpp:629
gnsstk::CommandOption::parser
CommandOptionParser * parser
Definition: CommandOption.hpp:263
gnsstk::CommandOptionNOf::checkArguments
virtual std::string checkArguments()
Definition: CommandOption.cpp:353
gnsstk::CommandOptionDependent::requiree
const CommandOption * requiree
Definition: CommandOption.hpp:665
gnsstk::StringUtils::isDigitString
bool isDigitString(const std::string &s)
Definition: StringUtils.hpp:1871
gnsstk::CommandOption::CommandOptionFlag
CommandOptionFlag
Definition: CommandOption.hpp:123
docstring_generator.parser
parser
Definition: docstring_generator.py:89
gnsstk::StringUtils::prettyPrint
std::string & prettyPrint(std::string &aStr, const std::string &lineDelim="\n", const std::string &indent="", const std::string &firstIndent=" ", const std::string::size_type len=80, const char wordDelim=' ')
Definition: StringUtils.hpp:2774


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:38