diff --git a/CHANGELOG.md b/CHANGELOG.md index 9017a4fc..945af2b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,6 @@ ## Version 0.7 (in progress) * Allow comments in ini files (lines starting with `;`) -* Ini files support flags -* Ini files support vectors -* Ini files support subcommands (only read) +* Ini files support flags, vectors, subcommands * Added CodeCov code coverage reports * Lots of small bugfixes related to adding tests to increase coverage * Error handling now uses scoped enum in errors diff --git a/README.md b/README.md index 924e10f6..ce6c7746 100644 --- a/README.md +++ b/README.md @@ -206,7 +206,8 @@ in_subcommand = Wow sub.subcommand = true ``` -Spaces before and after the name and argument are ignored. Multiple arguments are separated by spaces. One set of quotes will be removed, preserving spaces (the same way the command line works). Boolean options can be `true`, `on`, `1`, `yes`; or `false`, `off`, `0`, `no` (case insensitive). Sections (and `.` separated names) are treated as subcommands (note: this does not mean that subcommand was passed, it just sets the "defaults". +Spaces before and after the name and argument are ignored. Multiple arguments are separated by spaces. One set of quotes will be removed, preserving spaces (the same way the command line works). Boolean options can be `true`, `on`, `1`, `yes`; or `false`, `off`, `0`, `no` (case insensitive). Sections (and `.` separated names) are treated as subcommands (note: this does not mean that subcommand was passed, it just sets the "defaults". To print a configuration file from the passed +arguments, use `.config_to_str(default_also=false)`, where `default_also` will also show any defaulted arguments. ## Subclassing diff --git a/include/CLI/App.hpp b/include/CLI/App.hpp index 36948bdf..b0028d1d 100644 --- a/include/CLI/App.hpp +++ b/include/CLI/App.hpp @@ -547,34 +547,37 @@ public: /// @name Help ///@{ - /// Produce a string that could be read in as a config of the current values of the App. Set default_also to include default arguments. - std::string config_to_str(bool default_also=false) const { + /// Produce a string that could be read in as a config of the current values of the App. Set default_also to include default arguments. Prefix will add a string to the beginning of each option. + std::string config_to_str(bool default_also=false, std::string prefix="") const { std::stringstream out; for(const Option_p &opt : options_) { // Only process option with a long-name if(opt->lnames_.size() > 0) { + std::string name = prefix + opt->lnames_[0]; // Non-flags if(opt->get_expected() != 0) { // If the option was found on command line if(opt->count() > 0) - out << opt->lnames_[0] << "=" << detail::join(opt->results()) << std::endl; + out << name << "=" << detail::join(opt->results()) << std::endl; // If the option has a default and is requested by optional argument else if(default_also && opt->defaultval_ != "") - out << opt->lnames_[0] << "=" << opt->defaultval_ << std::endl; + out << name << "=" << opt->defaultval_ << std::endl; // Flag, one passed } else if(opt->count() == 1) { - out << opt->lnames_[0] << "=true" << std::endl; + out << name << "=true" << std::endl; // Flag, multiple passed } else if(opt->count() > 1) { - out << opt->lnames_[0] << "=" << opt->count() << std::endl; + out << name << "=" << opt->count() << std::endl; } } } + for(const App_p &subcom : subcommands_) + out << subcom->config_to_str(default_also, prefix + subcom->name_ + "."); return out.str(); } diff --git a/tests/IniTest.cpp b/tests/IniTest.cpp index 3ed735fe..b1bc12f7 100644 --- a/tests/IniTest.cpp +++ b/tests/IniTest.cpp @@ -549,3 +549,17 @@ TEST_F(TApp, IniOutputDefault) { str = app.config_to_str(true); EXPECT_THAT(str, HasSubstr("simple=7")); } + +TEST_F(TApp, IniOutputSubcom) { + + app.add_flag("--simple"); + auto subcom = app.add_subcommand("other"); + subcom->add_flag("--newer"); + + args = {"--simple", "other", "--newer"}; + run(); + + std::string str = app.config_to_str(); + EXPECT_THAT(str, HasSubstr("simple=true")); + EXPECT_THAT(str, HasSubstr("other.newer=true")); +}