Static Value-Flow Analysis
Static Public Member Functions | Protected Types | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Private Member Functions | List of all members
OptionBase Class Referenceabstract

#include <CommandLine.h>

Inheritance diagram for OptionBase:
Option< std::string > Option< u32_t > Option< bool > OptionMap< PointsTo::Type > OptionMap< SVF::NodeIDAllocator::Strategy > OptionMap< BVDataPTAImpl::PTBackingType > OptionMap< enum hclust_fast_methods > OptionMap< enum PTAStat::ClockType > OptionMap< MemSSA::MemPartition > OptionMultiple< PointerAnalysis::PTATY > OptionMultiple< WPAPass::AliasCheckRule > Option< T > OptionMap< T > OptionMultiple< T >

Static Public Member Functions

static std::vector< std::stringparseOptions (int argc, char *argv[], std::string description, std::string callFormat)
 

Protected Types

typedef std::pair< std::string, std::stringPossibilityDescription
 Name/description pairs. More...
 
typedef std::vector< std::pair< std::string, std::string > > PossibilityDescriptions
 
template<typename T >
using OptionPossibility = std::tuple< T, std::string, std::string >
 

Protected Member Functions

 OptionBase (std::string name, std::string description)
 
 OptionBase (std::string name, std::string description, PossibilityDescriptions possibilityDescriptions)
 
virtual bool parseAndSetValue (const std::string value)=0
 From a given string, set the value of this option. More...
 
virtual bool isBool (void) const
 
virtual bool isMultiple (void) const
 Whether this option is an OptionMultiple. More...
 
virtual bool canSet (void) const =0
 Can this option be set? More...
 

Static Protected Member Functions

template<typename T >
static PossibilityDescriptions extractPossibilityDescriptions (const std::vector< OptionPossibility< T >> possibilities)
 
static std::map< std::string, OptionBase * > & getOptionsMap (void)
 

Protected Attributes

std::string name
 
std::string description
 
PossibilityDescriptions possibilityDescriptions
 For when we have possibilities like in an OptionMap. More...
 

Static Private Member Functions

static std::string buildUsage (const std::string description, const std::string argv0, const std::string callFormat)
 
static OptionBasegetOption (const std::string optName)
 Find option based on name in options map. Returns nullptr if not found. More...
 
static void usageAndExit (const std::string usage, bool error)
 Print usage and exit. If error is set, print to stderr and exits with code 1. More...
 
static bool isHelpName (const std::string name)
 Returns whether name is one of the reserved help options. More...
 

Detailed Description

Definition at line 20 of file CommandLine.h.

Member Typedef Documentation

◆ OptionPossibility

template<typename T >
using OptionBase::OptionPossibility = std::tuple<T, std::string, std::string>
protected

Value/name/description tuples. If [1] is the value on the commandline for an option, we'd set the value for the associated Option to [0].

Definition at line 30 of file CommandLine.h.

◆ PossibilityDescription

Name/description pairs.

Definition at line 24 of file CommandLine.h.

◆ PossibilityDescriptions

typedef std::vector<std::pair<std::string, std::string> > OptionBase::PossibilityDescriptions
protected

Definition at line 25 of file CommandLine.h.

Constructor & Destructor Documentation

◆ OptionBase() [1/2]

OptionBase::OptionBase ( std::string  name,
std::string  description 
)
inlineprotected

Definition at line 33 of file CommandLine.h.

35  {
36  }
std::string name
Definition: CommandLine.h:316
std::string description
Definition: CommandLine.h:317
OptionBase(std::string name, std::string description)
Definition: CommandLine.h:33

◆ OptionBase() [2/2]

OptionBase::OptionBase ( std::string  name,
std::string  description,
PossibilityDescriptions  possibilityDescriptions 
)
inlineprotected

Definition at line 38 of file CommandLine.h.

40  {
41  assert(name[0] != '-' && "OptionBase: name starts with '-'");
42  assert(!isHelpName(name) && "OptionBase: reserved help name");
43  assert(getOptionsMap().find(name) == getOptionsMap().end() && "OptionBase: duplicate option");
44 
45  // Types with empty names (i.e., OptionMultiple) can handle things themselves.
46  if (!name.empty())
47  {
48  // Standard name=value option.
49  getOptionsMap()[name] = this;
50  }
51  }
PossibilityDescriptions possibilityDescriptions
For when we have possibilities like in an OptionMap.
Definition: CommandLine.h:319
static std::map< std::string, OptionBase * > & getOptionsMap(void)
Definition: CommandLine.h:307
static bool isHelpName(const std::string name)
Returns whether name is one of the reserved help options.
Definition: CommandLine.h:285

Member Function Documentation

◆ buildUsage()

static std::string OptionBase::buildUsage ( const std::string  description,
const std::string  argv0,
const std::string  callFormat 
)
inlinestaticprivate

Sets the usage member to a usage string, built from the static list of options. argv0 is argv[0] and callFormat is how the command should be used, minus the command name (e.g. "[options] <input-bitcode...>".

Definition at line 174 of file CommandLine.h.

177  {
178  // Determine longest option to split into two columns: options and descriptions.
179  unsigned longest = 0;
180  for (const std::pair<std::string, OptionBase *> nopt : getOptionsMap())
181  {
182  const std::string name = std::get<0>(nopt);
183  const OptionBase *option = std::get<1>(nopt);
184  if (option->isMultiple())
185  {
186  // For Multiple, description goes in left column.
187  if (option->description.length() > longest) longest = option->description.length();
188  }
189  else
190  {
191  if (name.length() > longest) longest = name.length();
192  }
193 
194  for (const PossibilityDescription &pd : option->possibilityDescriptions)
195  {
196  const std::string possibility = std::get<0>(pd);
197  if (possibility.length() + 3 > longest) longest = possibility.length() + 3;
198  }
199  }
200 
201  std::stringstream ss;
202 
203  ss << description << std::endl << std::endl;
204 
205  ss << "USAGE:" << std::endl;
206  ss << " " << argv0 << " " << callFormat << std::endl;
207  ss << std::endl;
208 
209  ss << "OPTIONS:" << std::endl;
210 
211  // Required as we have OptionMultiples doing a many-to-one in options.
212  std::unordered_set<const OptionBase *> handled;
213  for (const std::pair<std::string, OptionBase *> nopt : getOptionsMap())
214  {
215  const std::string name = std::get<0>(nopt);
216  const OptionBase *option = std::get<1>(nopt);
217  if (handled.find(option) != handled.end()) continue;
218  handled.insert(option);
219 
220  if (option->isMultiple())
221  {
222  // description
223  // -name1 - description
224  // -name2 - description
225  // ...
226  ss << " " << option->description << std::endl;
227  for (const PossibilityDescription &pd : option->possibilityDescriptions)
228  {
229  const std::string possibility = std::get<0>(pd);
230  const std::string description = std::get<1>(pd);
231  ss << " -" << possibility << std::string(longest - possibility.length() + 2, ' ');
232  ss << "- " << description << std::endl;
233  }
234  }
235  else
236  {
237  // name - description
238  // or
239  // name - description
240  // =opt1 - description
241  // =opt2 - description
242  // ...
243  ss << " -" << name << std::string(longest - name.length() + 2, ' ');
244  ss << "- " << option->description << std::endl;
245  for (const PossibilityDescription &pd : option->possibilityDescriptions)
246  {
247  const std::string possibility = std::get<0>(pd);
248  const std::string description = std::get<1>(pd);
249  ss << " =" << possibility << std::string(longest - possibility.length() + 2, ' ');
250  ss << "- " << description << std::endl;
251  }
252  }
253  }
254 
255  // Help message.
256  ss << std::endl;
257  ss << " -help" << std::string(longest - 4 + 2, ' ') << "- show usage and exit" << std::endl;
258  ss << " -h" << std::string(longest - 1 + 2, ' ') << "- show usage and exit" << std::endl;
259 
260  // How to set boolean options.
261  ss << std::endl;
262  ss << "Note: for boolean options, -name true and -name false are invalid." << std::endl;
263  ss << " Use -name, -name=true, or -name=false." << std::endl;
264 
265  return ss.str();
266  }
const char *const string
Definition: cJSON.h:172
std::pair< std::string, std::string > PossibilityDescription
Name/description pairs.
Definition: CommandLine.h:24
virtual bool isMultiple(void) const
Whether this option is an OptionMultiple.
Definition: CommandLine.h:64

◆ canSet()

virtual bool OptionBase::canSet ( void  ) const
protectedpure virtual

◆ extractPossibilityDescriptions()

template<typename T >
static PossibilityDescriptions OptionBase::extractPossibilityDescriptions ( const std::vector< OptionPossibility< T >>  possibilities)
inlinestaticprotected

Definition at line 294 of file CommandLine.h.

295  {
297  for (const OptionPossibility<T> &op : possibilities)
298  {
299  possibilityDescriptions.push_back(std::make_pair(std::get<1>(op), std::get<2>(op)));
300  }
301 
303  }
std::vector< std::pair< std::string, std::string > > PossibilityDescriptions
Definition: CommandLine.h:25

◆ getOption()

static OptionBase* OptionBase::getOption ( const std::string  optName)
inlinestaticprivate

Find option based on name in options map. Returns nullptr if not found.

Definition at line 269 of file CommandLine.h.

270  {
271  auto optIt = getOptionsMap().find(optName);
272  if (optIt == getOptionsMap().end()) return nullptr;
273  else return optIt->second;
274  }

◆ getOptionsMap()

static std::map<std::string, OptionBase *>& OptionBase::getOptionsMap ( void  )
inlinestaticprotected

Not unordered map so we can have sorted names when building the usage string. Map of option names to their object.

Definition at line 307 of file CommandLine.h.

308  {
309  // Not static member to avoid initialisation order problems.
310  static std::map<std::string, OptionBase *> options;
311  return options;
312  }

◆ isBool()

virtual bool OptionBase::isBool ( void  ) const
inlineprotectedvirtual

Whether this option represents a boolean. Important as such arguments don't require a value.

Reimplemented in Option< T >, Option< std::string >, Option< u32_t >, and Option< bool >.

Definition at line 58 of file CommandLine.h.

59  {
60  return false;
61  }

◆ isHelpName()

static bool OptionBase::isHelpName ( const std::string  name)
inlinestaticprivate

Returns whether name is one of the reserved help options.

Definition at line 285 of file CommandLine.h.

286  {
287  static std::vector<std::string> helpNames = {"help", "h", "-help"};
288  return std::find(helpNames.begin(), helpNames.end(), name) != helpNames.end();
289  }

◆ isMultiple()

virtual bool OptionBase::isMultiple ( void  ) const
inlineprotectedvirtual

Whether this option is an OptionMultiple.

Reimplemented in OptionMultiple< T >, OptionMultiple< PointerAnalysis::PTATY >, and OptionMultiple< WPAPass::AliasCheckRule >.

Definition at line 64 of file CommandLine.h.

65  {
66  return false;
67  }

◆ parseAndSetValue()

virtual bool OptionBase::parseAndSetValue ( const std::string  value)
protectedpure virtual

◆ parseOptions()

static std::vector<std::string> OptionBase::parseOptions ( int  argc,
char *  argv[],
std::string  description,
std::string  callFormat 
)
inlinestatic

Parse all constructed OptionBase children, returning positional arguments in the order they appeared.

Definition at line 75 of file CommandLine.h.

76  {
77  const std::string usage = buildUsage(description, std::string(argv[0]), callFormat);
78 
79  std::vector<std::string> positionalArguments;
80 
81  for (int i = 1; i < argc; ++i)
82  {
83  std::string arg(argv[i]);
84  if (arg.empty()) continue;
85  if (arg[0] != '-')
86  {
87  // Positional argument. NOT a value to another argument because we
88  // "skip" over evaluating those without the corresponding argument.
89  positionalArguments.push_back(arg);
90  continue;
91  }
92 
93  // Chop off '-'.
94  arg = arg.substr(1);
95 
96  std::string argName;
97  std::string argValue;
98  OptionBase *opt = nullptr;
99 
100  size_t equalsSign = arg.find('=');
101  if (equalsSign != std::string::npos)
102  {
103  // Argument has an equal sign, i.e. argName=argValue
104  argName = arg.substr(0, equalsSign);
105  if (isHelpName(argName)) usageAndExit(usage, false);
106 
107  opt = getOption(argName);
108  if (opt == nullptr)
109  {
110  std::cerr << "Unknown option: " << argName << std::endl;
111  usageAndExit(usage, true);
112  }
113 
114  argValue = arg.substr(equalsSign + 1);
115  }
116  else
117  {
118  argName = arg;
119  if (isHelpName(argName)) usageAndExit(usage, false);
120 
121  opt = getOption(argName);
122  if (opt == nullptr)
123  {
124  std::cerr << "Unknown option: " << argName << std::endl;
125  usageAndExit(usage, true);
126  }
127 
128  // No equals sign means we may need next argument.
129  if (opt->isBool())
130  {
131  // Booleans do not accept -arg true/-arg false.
132  // They must be -arg=true/-arg=false.
133  argValue = "true";
134  }
135  else if (opt->isMultiple())
136  {
137  // Name is the value and will be converted to an enum.
138  argValue = argName;
139  }
140  else if (i + 1 < argc)
141  {
142  // On iteration, we'll skip the value.
143  ++i;
144  argValue = std::string(argv[i]);
145  }
146  else
147  {
148  std::cerr << "Expected value for: " << argName << std::endl;
149  usageAndExit(usage, true);
150  }
151  }
152 
153  if (!opt->canSet())
154  {
155  std::cerr << "Unable to set: " << argName << "; check for duplicates" << std::endl;
156  usageAndExit(usage, true);
157  }
158 
159  bool valueSet = opt->parseAndSetValue(argValue);
160  if (!valueSet)
161  {
162  std::cerr << "Bad value for: " << argName << std::endl;
163  usageAndExit(usage, true);
164  }
165  }
166 
167  return positionalArguments;
168  }
virtual bool canSet(void) const =0
Can this option be set?
static std::string buildUsage(const std::string description, const std::string argv0, const std::string callFormat)
Definition: CommandLine.h:174
static OptionBase * getOption(const std::string optName)
Find option based on name in options map. Returns nullptr if not found.
Definition: CommandLine.h:269
static void usageAndExit(const std::string usage, bool error)
Print usage and exit. If error is set, print to stderr and exits with code 1.
Definition: CommandLine.h:277
virtual bool isBool(void) const
Definition: CommandLine.h:58
virtual bool parseAndSetValue(const std::string value)=0
From a given string, set the value of this option.

◆ usageAndExit()

static void OptionBase::usageAndExit ( const std::string  usage,
bool  error 
)
inlinestaticprivate

Print usage and exit. If error is set, print to stderr and exits with code 1.

Definition at line 277 of file CommandLine.h.

278  {
279  if (error) std::cerr << usage;
280  else std::cout << usage;
281  std::exit(error ? 1 : 0);
282  }
Definition: cJSON.cpp:89

Member Data Documentation

◆ description

std::string OptionBase::description
protected

Definition at line 317 of file CommandLine.h.

◆ name

std::string OptionBase::name
protected

Definition at line 316 of file CommandLine.h.

◆ possibilityDescriptions

PossibilityDescriptions OptionBase::possibilityDescriptions
protected

For when we have possibilities like in an OptionMap.

Definition at line 319 of file CommandLine.h.


The documentation for this class was generated from the following file: