Provide a variant type for command-line-option values.
More...
Namespaces |
namespace | balcl |
Detailed Description
- Outline
-
-
- Purpose:
- Provide a variant type for command-line-option values.
-
- Classes:
-
- See also:
- Component balcl_optiontype, Component balcl_commandline
-
- Description:
- This component provides a value-semantic class,
balcl::OptionValue
, that can have a value of any of the types specified by balcl::OptionType
-- i.e., any of the values that can be associated with a command-line option by balcl::CommandLine
. The balcl::OptionValue
class has two related states:
-
A default-constructed
balcl::OptionValue
object is in the "unset state" -- meaning that no type has been defined for a value (its type is void
). In this state, balcl::OptionType::e_VOID == type()
and false == hasNonVoidType()
. To have a value, a type must be specified for the value by using the setType
method or using one of the constructors that define an initial value. Example 1 shows how this state can be set and reset.
-
If a
balcl::OptionValue
object has a (non-'void') type it can have a value of that type or be in a "null state". Objects in the null state can be used to represent the value of command-line options that were not entered on the command line (assuming no default value was specified for the option). Example 2 shows how this feature can be used.
-
- Usage:
- This section illustrates intended use of this component.
-
- Example 1: Basic Use of balcl::OptionValue:
- The following snippets of code illustrate how to create and use a
balcl::OptionValue
object. Note that balcl::OptionValue
objects are typically used in a description of a sequence of command-line options (see balcl_optiontype
).
- First, we create a default
balcl::OptionValue
, valueA
, and observe that it is in the unset state: Next, we create a second balcl::OptionValue
having the value 5, and then confirm its value and observe that it does not compare equal to the valueA
: Then, we call the reset
method of valueB
resetting it to the unset state, and observe that valueA
now compares equal to valueB
: valueB.reset();
assert(valueA == valueB);
Now, we change the type of valueA
so that it can be hold a double
value: Finally, we set the object to the null state. Notice that the type of that value is not changed:
-
- Example 2: Interpreting Option Parser Results:
- Command-line options have values of many different types (e.g.,
int
, double
, string, date) or their values may not be specified -- after all, some command-line options may be optional. The balcl::OptionValue
class can be used to represent such values.
- First, we define
MyCommandLineParser
, a simple command-line argument parser. This class accepts a description (e.g., option name, value type) of allowable options on construction and provides a parse
method that accepts argc
and argv
, the values made available (by the operating system) to main
:
class MyCommandLineParser {
public:
MyCommandLineParser(const MyOptionDescription *descriptions,
bsl::size_t count);
int parse(int argc, const char **argv);
After a successful call to the parse
method, the results are available by several accessors. Note that the index
of a result corresponds to the index of that option in the description provided on construction:
bool isParsed() const;
const char *name (bsl::size_t index) const;
const balcl::OptionValue& value(bsl::size_t index) const;
bsl::size_t numOptions() const;
};
Note that neither our option description nor our parser support the concept of default values for options that are not entered on the command line.
- Then, we create a description having three allowable options (elided), a parser object, and invoke
parse
on the arguments available from main
: int main(int argc, const char **argv)
{
MyOptionDescription optionDescriptions[NUM_OPTIONS] = {
};
MyCommandLineParser parser(optionDescriptions, NUM_OPTIONS);
int rc = parser.parse(argc, argv);
assert(0 == rc);
assert(true == parser.isParsed());
Now, we examine the value of each defined option: for (bsl::size_t i = 0; i < parser.numOptions(); ++i) {
const char *name = parser.name(i);
const balcl::OptionValue& value = parser.value(i);
Since our (toy) parser has no feature for handling default values for options that are not specified on the command line, we must handle those explicitly.
- If the option named "outputDir" was set, we use that value; otherwise, we set a default value, the current directory:
if (0 == bsl::strcmp("outputDir", name)) {
setOutputDir(value.isNull()
? "."
: value.the<bsl::string>().c_str());
}
If the option named "verbosityLevel" was set we use that value; otherwise, we set a default value, 1
: if (0 == bsl::strcmp("verbosityLevel", name)) {
setVerbosityLevel(value.isNull()
? 1
: value.the<int>());
}
The option named "caseInsensitive" has no associated value. If that option appeared on the command line, the value of the program flag is set to true
, otherwise (false == isNull()
) that flag is set to false
: if (0 == bsl::strcmp("caseInsensitive", name)) {
setCaseInsensitivityFlag(value.isNull()
? false
: true);
}
}
Finally, we continue with the execution of our program using the values obtained from the command-line options: