diff --git a/cmdopt.cpp b/cmdopt.cpp index ec876652..a7f6a845 100644 --- a/cmdopt.cpp +++ b/cmdopt.cpp @@ -24,13 +24,17 @@ using util::cmdopt::option::base; using util::cmdopt::option::bytes; using util::cmdopt::option::count; +using util::cmdopt::option::null; +using util::cmdopt::option::present; using util::cmdopt::option::value; using util::cmdopt::parser; /////////////////////////////////////////////////////////////////////////////// base::base (std::string _name): - m_name (_name) + m_name (_name), + m_required (false), + m_seen (false) { ; } @@ -58,13 +62,18 @@ base::execute (const char *restrict) //----------------------------------------------------------------------------- void base::start (void) -{ ; } +{ + m_seen = false; +} //----------------------------------------------------------------------------- void base::finish (void) -{ ; } +{ + if (m_required && !m_seen) + throw invalid_required (m_name); +} //----------------------------------------------------------------------------- @@ -75,6 +84,38 @@ base::name (void) const } +//----------------------------------------------------------------------------- +bool +base::required (void) const +{ + return m_required; +} + + +//----------------------------------------------------------------------------- +bool +base::required (bool _required) +{ + return m_required = _required; +} + + +//----------------------------------------------------------------------------- +bool +base::seen (void) const +{ + return m_seen; +} + + +//----------------------------------------------------------------------------- +bool +base::seen (bool _seen) +{ + return m_seen = _seen; +} + + /////////////////////////////////////////////////////////////////////////////// namespace util { namespace cmdopt { namespace option { template class value; @@ -96,6 +137,7 @@ void count::execute (void) { ++this->data (); + this->seen (true); } @@ -112,6 +154,9 @@ parser::scan (int argc, char *const *argv) CHECK_GE (argc, 0); CHECK (argv); + for (auto &j: m_options) + j->start (); + // start iterating after our program's name int i = 1; while (i < argc) { @@ -130,6 +175,9 @@ parser::scan (int argc, char *const *argv) i += inc; } + for (auto &j: m_options) + j->finish (); + return i; } diff --git a/cmdopt.hpp b/cmdopt.hpp index 56e642ce..92818027 100644 --- a/cmdopt.hpp +++ b/cmdopt.hpp @@ -38,8 +38,16 @@ namespace util { namespace cmdopt { std::string name (void) const; + bool required (void) const; + bool required (bool); + + bool seen (void) const; + bool seen (bool); + private: std::string m_name; + bool m_required; + bool m_seen; }; @@ -71,7 +79,7 @@ namespace util { namespace cmdopt { class bytes : public value { public: - bytes (std::string name); + using value::value; using value::execute; void execute (const char *restrict) override; @@ -91,6 +99,9 @@ namespace util { namespace cmdopt { class invalid_null : public error { using error::error; }; + class invalid_required : public error + { using error::error; }; + class parser { public: diff --git a/cmdopt.ipp b/cmdopt.ipp index d0489a2d..4ee5d2dd 100644 --- a/cmdopt.ipp +++ b/cmdopt.ipp @@ -48,6 +48,8 @@ namespace util { namespace cmdopt { } catch (...) { throw invalid_value (__func__); } + + seen (true); }