@@ -40,6 +40,7 @@ namespace pmon::util::cli
4040 std::vector<std::pair<std::string, std::string>> GetForwardedOptions () const ;
4141 private:
4242 void AddGroup_ (std::string name, std::string desc);
43+ CLI::App* AddSubcommand_ (std::string name, std::string desc);
4344 void RegisterElement_ (OptionsElement_* pElement);
4445 protected:
4546 // types
@@ -61,12 +62,14 @@ namespace pmon::util::cli
6162 // functions
6263 void Finalize_ (int argc, const char * const * argv);
6364 int Exit_ (const CLI::ParseError& e, bool captureDiagnostics);
65+ std::string GetDiagnostics_ () const ;
6466 // data
6567 std::ostringstream diagnostics_;
6668 std::vector<OptionsElement_*> elementPtrs_;
6769 bool finalized_ = false ;
6870 std::string activeGroup_;
6971 CLI::App app_;
72+ CLI::App* pCurrentSubcommand_ = &app_;
7073 };
7174
7275 template <class T >
@@ -105,7 +108,7 @@ namespace pmon::util::cli
105108 }
106109 static std::string GetDiagnostics ()
107110 {
108- return Get_ ().diagnostics_ . str ();
111+ return Get_ ().GetDiagnostics_ ();
109112 }
110113 private:
111114 static T& Get_ ()
@@ -126,7 +129,7 @@ namespace pmon::util::cli
126129 data_{ defaultValue }
127130 {
128131 // create the option
129- pOption_ = pParent->app_ . add_option (std::move (names), data_, std::move (description));
132+ pOption_ = pParent->pCurrentSubcommand_ -> add_option (std::move (names), data_, std::move (description));
130133 // if customizer is a Validator object, add it to the option
131134 if constexpr (std::is_base_of_v<CLI::Validator, std::decay_t <U>> ) {
132135 if (customizer.get_modifying ()) {
@@ -146,7 +149,7 @@ namespace pmon::util::cli
146149 data_{ defaultValue }
147150 {
148151 // create the option
149- pOption_ = pParent->app_ . add_option (std::move (names), data_, std::move (description));
152+ pOption_ = pParent->pCurrentSubcommand_ -> add_option (std::move (names), data_, std::move (description));
150153 OptionCommonPostCreate_ (pParent);
151154 }
152155 Option (const Option&) = delete ;
@@ -227,7 +230,10 @@ namespace pmon::util::cli
227230 CLI::Option* GetOption_ (T& el) const { return el.pOption_ ; }
228231 CLI::App& GetApp_ (OptionsContainer& con) const { return con.app_ ; }
229232 void SetForwarding_ (OptionsElement_& el, bool forwarding = false ) { el.forwarding_ = forwarding; }
230- void AddGroup_ (OptionsContainer& con, std::string name, std::string desc = {}) { con.AddGroup_ (std::move (name), std::move (desc)); }
233+ void AddGroup_ (OptionsContainer& con, std::string name, std::string desc = {}) {
234+ con.AddGroup_ (std::move (name), std::move (desc)); }
235+ const CLI::App* AddSubcommand_ (OptionsContainer& con, std::string name, std::string desc = {}) {
236+ return con.AddSubcommand_ (std::move (name), std::move (desc)); }
231237 };
232238
233239 class MutualExclusion : RuleBase_
@@ -303,6 +309,24 @@ namespace pmon::util::cli
303309 }
304310 };
305311
312+ class Subcommand : RuleBase_
313+ {
314+ public:
315+ Subcommand (OptionsContainer* pCon, std::string name, std::string desc = {})
316+ {
317+ pSubcommand_ = AddSubcommand_ (*pCon, std::move (name), std::move (desc));
318+ }
319+ bool Active () const
320+ {
321+ if (pSubcommand_) {
322+ return pSubcommand_->parsed ();
323+ }
324+ return false ;
325+ }
326+ private:
327+ const CLI::App* pSubcommand_ = nullptr ;
328+ };
329+
306330 class SilentGroup : RuleBase_
307331 {
308332 public:
0 commit comments