Skip to content

Commit

Permalink
fix case with short options only
Browse files Browse the repository at this point in the history
  • Loading branch information
artpaul committed Apr 19, 2021
1 parent d08aba7 commit 0dcaa38
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 60 deletions.
84 changes: 47 additions & 37 deletions include/cxxopts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,13 +337,21 @@ class value_base : public std::enable_shared_from_this<value_base> {
}

private:
/// A default value for the option.
std::string default_value_{};
/// A name of an environment variable from which a default
/// value will be read.
std::string env_var_{};
/// An implicit value for the option.
std::string implicit_value_{};
/// Configuration of the value parser.
parse_context parse_ctx_{};

/// The default value has been set.
bool default_{false};
/// The environment variable has been set.
bool env_{false};
/// The implicit value has been set.
bool implicit_{false};
};
#if defined(__GNUC__)
Expand Down Expand Up @@ -768,7 +776,6 @@ class options {

struct help_group_details {
std::string name{};
std::string description{};
std::vector<help_option_details> options{};
};

Expand All @@ -792,33 +799,6 @@ class options {
public:
explicit options(std::string program, std::string help_string = {});

options&
positional_help(std::string help_text);

options&
custom_help(std::string help_text);

options&
show_positional_help();

options&
allow_unrecognised_options();

options&
set_tab_expansion(bool expansion = true);

options&
set_width(size_t width);

/**
* Stop parsing at first positional argument.
*/
options&
stop_on_positional();

option_adder
add_options(std::string group = {});

/**
* Adds list of options to the specific group.
*/
Expand All @@ -835,6 +815,15 @@ class options {
const std::string& group,
const option& option);

option_adder
add_options(std::string group = {});

options&
allow_unrecognised_options(const bool value = true);

options&
custom_help(std::string help_text);

template <typename ... Args>
void
parse_positional(Args&& ... args) {
Expand All @@ -853,6 +842,34 @@ class options {
void
parse_positional(std::vector<std::string> options);

options&
positional_help(std::string help_text);

options&
set_tab_expansion(bool expansion = true);

options&
set_width(size_t width);

options&
show_positional_help(const bool value = true);

/**
* Stop parsing at first positional argument.
*/
options&
stop_on_positional(const bool value = true);

public:
/**
* Parses the command line arguments according to the current specification.
*/
parse_result
parse(int argc, const char* const* argv) const;

/**
* Generates help for the options.
*/
std::string
help(const std::vector<std::string>& groups = {}) const;

Expand All @@ -865,19 +882,12 @@ class options {
const help_group_details&
group_help(const std::string& group) const;

public:
/**
* Parses the command line arguments according to the current specification.
*/
parse_result
parse(int argc, const char* const* argv) const;

private:
void
add_option(
const std::string& group,
const std::string& s,
const std::string& l,
std::string s,
std::string l,
std::string desc,
const std::shared_ptr<detail::value_base>& value,
std::string arg_help);
Expand Down
48 changes: 25 additions & 23 deletions src/cxxopts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ static const std::basic_regex<char> option_matcher
("--([[:alnum:]][-_[:alnum:]]+)(=(.*))?|-(\\?|[[:alnum:]]+)");

static const std::basic_regex<char> option_specifier
("((\\?|[[:alnum:]]),)?[ ]*([[:alnum:]][-_[:alnum:]]*)?");
("((\\?|[[:alnum:]]),)?[ ]*(\\?|([[:alnum:]][-_[:alnum:]]*))?");

static const std::basic_regex<char> integer_pattern
("(-)?(0x)?([0-9a-zA-Z]+)|((0x)?0)");
Expand Down Expand Up @@ -797,6 +797,7 @@ class options::option_parser {

if (oi == options_.end()) {
if (allow_unrecognised_) {
// TODO: keep unrecognized.
continue;
}
// Error.
Expand Down Expand Up @@ -1015,8 +1016,8 @@ options::options(std::string program, std::string help_string)
}

options&
options::positional_help(std::string help_text) {
positional_help_ = std::move(help_text);
options::allow_unrecognised_options(const bool value) {
allow_unrecognised_ = value;
return *this;
}

Expand All @@ -1027,32 +1028,32 @@ options::custom_help(std::string help_text) {
}

options&
options::show_positional_help() {
show_positional_ = true;
options::positional_help(std::string help_text) {
positional_help_ = std::move(help_text);
return *this;
}

options&
options::allow_unrecognised_options() {
allow_unrecognised_ = true;
options::show_positional_help(const bool value) {
show_positional_ = value;
return *this;
}

options&
options::set_width(size_t width) {
width_ = width;
options::set_tab_expansion(bool expansion) {
tab_expansion_ = expansion;
return *this;
}

options&
options::set_tab_expansion(bool expansion) {
tab_expansion_ = expansion;
options::set_width(size_t width) {
width_ = width;
return *this;
}

options&
options::stop_on_positional() {
stop_on_positional_ = true;
options::stop_on_positional(const bool value) {
stop_on_positional_ = value;
return *this;
}

Expand Down Expand Up @@ -1090,8 +1091,8 @@ options::add_option(const std::string& group, const option& opt) {
void
options::add_option(
const std::string& group,
const std::string& s,
const std::string& l,
std::string s,
std::string l,
std::string desc,
const std::shared_ptr<detail::value_base>& value,
std::string arg_help)
Expand Down Expand Up @@ -1292,8 +1293,7 @@ options::help_one_group(const std::string& g) const {
}

for (const auto& o : group->second.options) {
if (positional_set_.find(o.l) != positional_set_.end() &&
!show_positional_)
if (!show_positional_ && positional_set_.find(o.l) != positional_set_.end())
{
continue;
}
Expand All @@ -1312,8 +1312,7 @@ options::help_one_group(const std::string& g) const {

auto fiter = format.begin();
for (const auto& o : group->second.options) {
if (positional_set_.find(o.l) != positional_set_.end() &&
!show_positional_)
if (!show_positional_ && positional_set_.find(o.l) != positional_set_.end())
{
continue;
}
Expand Down Expand Up @@ -1439,9 +1438,12 @@ options::option_adder::operator()(
throw_or_mimic<invalid_option_format_error>(opts);
}

const auto& short_match = result[2];
const auto& long_match = result[3];
std::string short_match = result[2].str();
std::string long_match = result[3].str();

if (short_match.empty() && long_match.length() == 1) {
std::swap(short_match, long_match);
}
if ((!short_match.length() && !long_match.length()) ||
( short_match.length() && long_match.length() == 1))
{
Expand All @@ -1450,8 +1452,8 @@ options::option_adder::operator()(

options_.add_option(
group_,
short_match.str(),
long_match.str(),
std::move(short_match),
std::move(long_match),
desc,
value,
std::move(arg_help));
Expand Down
8 changes: 8 additions & 0 deletions test/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ TEST_CASE("Value", "traits") {
CHECK(cxxopts::value<std::vector<std::string>>()->is_container());
}

TEST_CASE("Question mark only", "[options]") {
cxxopts::options options("test_short", " - test question mark");
options.add_options()("?", "show help");

const Argv argv({"test_short", "-?"});
CHECK(options.parse(argv.argc(), argv.argv()).count("?") == 1);
}

TEST_CASE("Question mark help", "[options]") {
cxxopts::options options("test_short", " - test question mark");

Expand Down

0 comments on commit 0dcaa38

Please sign in to comment.