From 9bc4c477e39725d6031a601f5341363bcbf54646 Mon Sep 17 00:00:00 2001 From: "Taylor C. Richberger" Date: Sat, 16 Jul 2016 03:44:22 -0600 Subject: fix many bugs, add tests for terminator --- Doxyfile | 2 +- Makefile | 2 +- args.hxx | 46 +++++++++++++++++++++++++++++++++++++++++++--- test.cxx | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/Doxyfile b/Doxyfile index 8c76055..3a626fa 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "args" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 6.0.0 +PROJECT_NUMBER = 6.0.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/Makefile b/Makefile index 9242807..ae4dbdb 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ FLAGS += -O2 endif LIBS = -CFLAGS += -I. $(FLAGS) -c -MMD +CFLAGS += -I. $(FLAGS) -c -MMD -Wall -Wextra LDFLAGS += $(FLAGS) SOURCES = test.cxx diff --git a/args.hxx b/args.hxx index 8deb71b..7be2305 100644 --- a/args.hxx +++ b/args.hxx @@ -574,6 +574,15 @@ namespace args } virtual void ParseValue(const std::string &value) = 0; + + virtual void Reset() noexcept override + { + matched = false; + ready = true; +#ifdef ARGS_NOEXCEPT + error = Error::None; +#endif + } }; /** Class for all kinds of validating groups, including ArgumentParser @@ -686,7 +695,7 @@ namespace args { next = group->GetNextPositional(); } - if (next and next->Ready()) + if (next && next->Ready()) { return next; } @@ -1162,7 +1171,7 @@ namespace args { const auto &chunk = *it; - if (!terminated and chunk == terminator) + if (!terminated && chunk == terminator) { terminated = true; // If a long arg was found @@ -1475,10 +1484,11 @@ namespace args class CounterFlag : public Flag { private: + const int startcount; int count; public: - CounterFlag(Group &group, const std::string &name, const std::string &help, Matcher &&matcher, const int startcount = 0): Flag(group, name, help, std::move(matcher)), count(startcount) {} + CounterFlag(Group &group, const std::string &name, const std::string &help, Matcher &&matcher, const int startcount = 0): Flag(group, name, help, std::move(matcher)), startcount(startcount), count(startcount) {} virtual ~CounterFlag() {} @@ -1508,6 +1518,12 @@ namespace args { return count; } + + virtual void Reset() noexcept override + { + FlagBase::Reset(); + count = startcount; + } }; /** A default Reader class for argument classes @@ -1645,6 +1661,12 @@ namespace args { return name + std::string("..."); } + + virtual void Reset() noexcept override + { + ValueFlagBase::Reset(); + values.clear(); + } }; /** A mapping value flag class @@ -1778,6 +1800,12 @@ namespace args { return name + std::string("..."); } + + virtual void Reset() noexcept override + { + ValueFlagBase::Reset(); + values.clear(); + } }; /** A positional argument class @@ -1873,6 +1901,12 @@ namespace args { return values; } + + virtual void Reset() noexcept override + { + PositionalBase::Reset(); + values.clear(); + } }; /** A positional argument mapping class @@ -2009,5 +2043,11 @@ namespace args { return name + std::string("..."); } + + virtual void Reset() noexcept override + { + PositionalBase::Reset(); + values.clear(); + } }; } diff --git a/test.cxx b/test.cxx index 8d77bf4..ad3bfd8 100644 --- a/test.cxx +++ b/test.cxx @@ -162,6 +162,47 @@ TEST_CASE("Positional arguments and positional argument lists work as expected", REQUIRE((args::get(baz) == std::vector{'a', 'b', 'c', 'x', 'y', 'z'})); } +TEST_CASE("The option terminator works as expected", "[args]") +{ + args::ArgumentParser parser("This is a test program.", "This goes after the options."); + args::Positional foo(parser, "FOO", "test flag"); + args::Positional bar(parser, "BAR", "test flag"); + args::PositionalList baz(parser, "BAZ", "test flag"); + args::Flag ofoo(parser, "FOO", "test flag", {'f', "foo"}); + args::Flag obar(parser, "BAR", "test flag", {"bar", 'b'}); + args::ValueFlag obaz(parser, "BAZ", "test flag", {'a', "baz"}); + parser.ParseArgs(std::vector{"--foo", "this is a test flag", "0", "a", "b", "--baz", "7.0", "c", "x", "y", "z"}); + REQUIRE(foo); + REQUIRE((args::get(foo) == "this is a test flag")); + REQUIRE(bar); + REQUIRE(!args::get(bar)); + REQUIRE(baz); + REQUIRE((args::get(baz) == std::vector{"a", "b", "c", "x", "y", "z"})); + REQUIRE(ofoo); + REQUIRE(!obar); + REQUIRE(obaz); + parser.ParseArgs(std::vector{"--foo", "this is a test flag", "0", "a", "--", "b", "--baz", "7.0", "c", "x", "y", "z"}); + REQUIRE(foo); + REQUIRE((args::get(foo) == "this is a test flag")); + REQUIRE(bar); + REQUIRE(!args::get(bar)); + REQUIRE(baz); + REQUIRE((args::get(baz) == std::vector{"a", "b", "--baz", "7.0", "c", "x", "y", "z"})); + REQUIRE(ofoo); + REQUIRE(!obar); + REQUIRE(!obaz); + parser.ParseArgs(std::vector{"--foo", "--", "this is a test flag", "0", "a", "b", "--baz", "7.0", "c", "x", "y", "z"}); + REQUIRE(foo); + REQUIRE((args::get(foo) == "this is a test flag")); + REQUIRE(bar); + REQUIRE(!args::get(bar)); + REQUIRE(baz); + REQUIRE((args::get(baz) == std::vector{"a", "b", "--baz", "7.0", "c", "x", "y", "z"})); + REQUIRE(ofoo); + REQUIRE(!obar); + REQUIRE(!obaz); +} + TEST_CASE("Positional lists work with sets", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); -- cgit v1.2.1