Add value name to ProgramOptions::Option::requiresValue() member function

This value name is displayed in operator<<(ostream, ProgramOptions&)
when a option requires a value.
This commit is contained in:
David Capello 2012-09-05 21:12:04 -03:00
parent 8962c6dbe7
commit 6051387211
3 changed files with 23 additions and 14 deletions

View File

@ -134,7 +134,7 @@ void ProgramOptions::parse(int argc, const char* argv[])
if (i+1 >= argc) { if (i+1 >= argc) {
stringstream msg; stringstream msg;
msg << "Missing value in '--" << optionName msg << "Missing value in '--" << optionName
<< "'=VALUE option specification"; << "=" << option->getValueName() << "' option specification";
throw ProgramOptionNeedsValue(msg.str()); throw ProgramOptionNeedsValue(msg.str());
} }
optionValue = argv[++i]; optionValue = argv[++i];
@ -173,7 +173,10 @@ std::ostream& operator<<(std::ostream& os, const base::ProgramOptions& po)
for (base::ProgramOptions::OptionList::const_iterator for (base::ProgramOptions::OptionList::const_iterator
it=po.options().begin(), end=po.options().end(); it != end; ++it) { it=po.options().begin(), end=po.options().end(); it != end; ++it) {
const base::ProgramOptions::Option* option = *it; const base::ProgramOptions::Option* option = *it;
size_t optionWidth = std::min<int>(26, 6+option->name().size()+1); size_t optionWidth =
std::min<int>(26, 6+option->name().size()+1+
(option->doesRequireValue() ? option->getValueName().size()+1: 0));
if (maxOptionWidth < optionWidth) if (maxOptionWidth < optionWidth)
maxOptionWidth = optionWidth; maxOptionWidth = optionWidth;
} }
@ -181,13 +184,16 @@ std::ostream& operator<<(std::ostream& os, const base::ProgramOptions& po)
for (base::ProgramOptions::OptionList::const_iterator for (base::ProgramOptions::OptionList::const_iterator
it=po.options().begin(), end=po.options().end(); it != end; ++it) { it=po.options().begin(), end=po.options().end(); it != end; ++it) {
const base::ProgramOptions::Option* option = *it; const base::ProgramOptions::Option* option = *it;
size_t optionWidth = 6+option->name().size()+1; size_t optionWidth = 6+option->name().size()+1+
(option->doesRequireValue() ? option->getValueName().size()+1: 0);
if (option->mnemonic() != 0) if (option->mnemonic() != 0)
os << setw(3) << '-' << option->mnemonic() << ", "; os << setw(3) << '-' << option->mnemonic() << ", ";
else else
os << setw(6) << ' '; os << setw(6) << ' ';
os << "--" << option->name(); os << "--" << option->name();
if (option->doesRequireValue())
os << " " << option->getValueName();
if (!option->description().empty()) { if (!option->description().empty()) {
bool multilines = (option->description().find('\n') != string::npos); bool multilines = (option->description().find('\n') != string::npos);

View File

@ -39,20 +39,23 @@ namespace base {
Option(const std::string& name) Option(const std::string& name)
: m_name(name) : m_name(name)
, m_mnemonic(0) , m_mnemonic(0)
, m_enabled(false) , m_enabled(false) {
, m_requiresValue(false) {
} }
// Getters // Getters
const std::string& name() const { return m_name; } const std::string& name() const { return m_name; }
const std::string& description() const { return m_description; } const std::string& description() const { return m_description; }
const std::string& value() const { return m_value; } const std::string& value() const { return m_value; }
const std::string& getValueName() const { return m_valueName; }
char mnemonic() const { return m_mnemonic; } char mnemonic() const { return m_mnemonic; }
bool enabled() const { return m_enabled; } bool enabled() const { return m_enabled; }
bool doesRequireValue() const { return m_requiresValue; } bool doesRequireValue() const { return !m_valueName.empty(); }
// Setters // Setters
Option& description(const std::string& desc) { m_description = desc; return *this; } Option& description(const std::string& desc) { m_description = desc; return *this; }
Option& mnemonic(char mnemonic) { m_mnemonic = mnemonic; return *this; } Option& mnemonic(char mnemonic) { m_mnemonic = mnemonic; return *this; }
Option& requiresValue() { m_requiresValue = true; return *this; } Option& requiresValue(const std::string& valueName) {
m_valueName = valueName;
return *this;
}
private: private:
void setValue(const std::string& value) { m_value = value; } void setValue(const std::string& value) { m_value = value; }
void setEnabled(bool enabled) { m_enabled = enabled; } void setEnabled(bool enabled) { m_enabled = enabled; }
@ -60,9 +63,9 @@ namespace base {
std::string m_name; // Name of the option (e.g. "help" for "--help") std::string m_name; // Name of the option (e.g. "help" for "--help")
std::string m_description; // Description of the option (this can be used when the help is printed). std::string m_description; // Description of the option (this can be used when the help is printed).
std::string m_value; // The value specified by the user in the command line. std::string m_value; // The value specified by the user in the command line.
std::string m_valueName; // Empty if this option doesn't require a value, or the name of the expected value.
char m_mnemonic; // One character that can be used in the command line to use this option. char m_mnemonic; // One character that can be used in the command line to use this option.
bool m_enabled; // True if the user specified this argument. bool m_enabled; // True if the user specified this argument.
bool m_requiresValue; // True if this option needs another argument.
friend class ProgramOptions; friend class ProgramOptions;
}; };

View File

@ -16,7 +16,7 @@ TEST(ProgramOptions, OptionMembers)
ProgramOptions::Option& help = ProgramOptions::Option& help =
po.add("help").mnemonic('h').description("Show the help"); po.add("help").mnemonic('h').description("Show the help");
ProgramOptions::Option& output = ProgramOptions::Option& output =
po.add("output").mnemonic('O').requiresValue(); po.add("output").mnemonic('O').requiresValue("OUTPUT");
EXPECT_EQ("help", help.name()); EXPECT_EQ("help", help.name());
EXPECT_EQ("Show the help", help.description()); EXPECT_EQ("Show the help", help.description());
@ -35,7 +35,7 @@ TEST(ProgramOptions, Reset)
{ {
ProgramOptions po; ProgramOptions po;
ProgramOptions::Option& help = po.add("help"); ProgramOptions::Option& help = po.add("help");
ProgramOptions::Option& file = po.add("file").requiresValue(); ProgramOptions::Option& file = po.add("file").requiresValue("FILE");
EXPECT_FALSE(help.enabled()); EXPECT_FALSE(help.enabled());
EXPECT_FALSE(file.enabled()); EXPECT_FALSE(file.enabled());
EXPECT_EQ("", file.value()); EXPECT_EQ("", file.value());
@ -56,8 +56,8 @@ TEST(ProgramOptions, Parse)
{ {
ProgramOptions po; ProgramOptions po;
ProgramOptions::Option& help = po.add("help").mnemonic('?'); ProgramOptions::Option& help = po.add("help").mnemonic('?');
ProgramOptions::Option& input = po.add("input").mnemonic('i').requiresValue(); ProgramOptions::Option& input = po.add("input").mnemonic('i').requiresValue("INPUT");
ProgramOptions::Option& output = po.add("output").mnemonic('o').requiresValue(); ProgramOptions::Option& output = po.add("output").mnemonic('o').requiresValue("OUTPUT");
const char* argv1[] = { "program.exe", "-?" }; const char* argv1[] = { "program.exe", "-?" };
po.parse(2, argv1); po.parse(2, argv1);
@ -111,8 +111,8 @@ TEST(ProgramOptions, ParseErrors)
{ {
ProgramOptions po; ProgramOptions po;
ProgramOptions::Option& help = po.add("help").mnemonic('?'); ProgramOptions::Option& help = po.add("help").mnemonic('?');
ProgramOptions::Option& input = po.add("input").mnemonic('i').requiresValue(); ProgramOptions::Option& input = po.add("input").mnemonic('i').requiresValue("INPUT");
ProgramOptions::Option& output = po.add("output").mnemonic('o').requiresValue(); ProgramOptions::Option& output = po.add("output").mnemonic('o').requiresValue("OUTPUT");
const char* argv1[] = { "program.exe", "--input" }; const char* argv1[] = { "program.exe", "--input" };
EXPECT_THROW(po.parse(2, argv1), ProgramOptionNeedsValue); EXPECT_THROW(po.parse(2, argv1), ProgramOptionNeedsValue);