Skip to content

Commit

Permalink
Use filter fn to simplify, sort includes
Browse files Browse the repository at this point in the history
  • Loading branch information
henryiii committed May 6, 2018
1 parent 3ff6fca commit 101d847
Show file tree
Hide file tree
Showing 18 changed files with 105 additions and 67 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Other changes:
* Testing (only) now uses submodules. [#111]
* Removed `requires` in favor of `needs` (deprecated in last version) [#112]
* Better CMake policy handling [#110]
* Includes are properly sorted [#120]
* `lname` and `sname` have getters, added `const get_parent` [#120]

[#109]: https://github.com/CLIUtils/CLI11/pull/109
[#110]: https://github.com/CLIUtils/CLI11/pull/110
Expand All @@ -42,6 +44,7 @@ Other changes:
[#116]: https://github.com/CLIUtils/CLI11/pull/116
[#118]: https://github.com/CLIUtils/CLI11/pull/118
[#118]: https://github.com/CLIUtils/CLI11/pull/119
[#120]: https://github.com/CLIUtils/CLI11/pull/120

### Version 1.5.3: Compiler compatibility
This version fixes older AppleClang compilers by removing the optimization for casting. The minimum version of Boost Optional supported has been clarified to be 1.58. CUDA 7.0 NVCC is now supported.
Expand Down
2 changes: 1 addition & 1 deletion examples/enum.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <sstream>
#include <CLI/CLI.hpp>
#include <sstream>

enum class Level : int { High, Medium, Low };

Expand Down
4 changes: 2 additions & 2 deletions examples/inter_argument_order.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include <CLI/CLI.hpp>
#include <algorithm>
#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
#include <vector>

int main(int argc, char **argv) {
CLI::App app{"An app to practice mixing unlimited arguments, but still recover the original order."};
Expand Down
11 changes: 7 additions & 4 deletions include/CLI/App.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,8 +1013,8 @@ class App {
for(const Option_p &opt : options_) {

// Only process option with a long-name and configurable
if(!opt->lnames_.empty() && opt->get_configurable()) {
std::string name = prefix + opt->lnames_[0];
if(!opt->get_lnames().empty() && opt->get_configurable()) {
std::string name = prefix + opt->get_lnames()[0];
std::string value;

// Non-flags
Expand All @@ -1025,8 +1025,8 @@ class App {
value = detail::inijoin(opt->results());

// If the option has a default and is requested by optional argument
else if(default_also && !opt->defaultval_.empty())
value = opt->defaultval_;
else if(default_also && !opt->get_defaultval().empty())
value = opt->get_defaultval();
// Flag, one passed
} else if(opt->count() == 1) {
value = "true";
Expand Down Expand Up @@ -1148,6 +1148,9 @@ class App {
/// Get the parent of this subcommand (or nullptr if master app)
App *get_parent() { return parent_; }

/// Get the parent of this subcommand (or nullptr if master app) (const version)
const App *get_parent() const { return parent_; }

/// Get a pointer to the config option. (const)
const Option *get_config_ptr() const { return config_ptr_; }

Expand Down
81 changes: 41 additions & 40 deletions include/CLI/Formatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,44 @@

namespace CLI {

inline std::string
Formatter::make_group(std::string group, std::vector<const Option *> opts, bool is_positional) const {
inline std::string Formatter::make_group(const App *app,
std::string group,
bool is_positional,
std::function<bool(const Option *)> filter) const {
std::stringstream out;
out << "\n" << group << ":\n";
for(const Option *opt : opts) {
out << make_option(opt, is_positional);
std::vector<const Option *> opts = app->get_options(filter);

if(!opts.empty()) {
out << "\n" << group << ":\n";
for(const Option *opt : opts) {
out << make_option(opt, is_positional);
}
}

return out.str();
}

inline std::string Formatter::make_positionals(const App *app) const {
return make_group(app, get_label("Positionals"), true, [](const Option *opt) {
return !opt->get_group().empty() && opt->get_positional();
});
}

inline std::string Formatter::make_groups(const App *app, AppFormatMode mode) const {
std::stringstream out;
std::vector<std::string> groups = app->get_groups();
std::vector<const Option *> positionals =
app->get_options([](const Option *opt) { return !opt->get_group().empty() && opt->get_positional(); });

if(!positionals.empty())
out << make_group(get_label("Positionals"), positionals, true);

// Options
for(const std::string &group : groups) {
std::vector<const Option *> grouped_items =
app->get_options([&group](const Option *opt) { return opt->nonpositional() && opt->get_group() == group; });

if(mode == AppFormatMode::Sub) {
grouped_items.erase(std::remove_if(grouped_items.begin(),
grouped_items.end(),
[app](const Option *opt) {
return app->get_help_ptr() == opt || app->get_help_all_ptr() == opt;
}),
grouped_items.end());
}
if(!group.empty()) {
out << make_group(app, group, false, [app, mode, &group](const Option *opt) {
return opt->get_group() == group // Must be in the right group
&& opt->nonpositional() // Must not be a positional
&& (mode != AppFormatMode::Sub // If mode is Sub, then
|| (app->get_help_ptr() != opt // Ignore help pointer
&& app->get_help_all_ptr() != opt)); // Ignore help all pointer
});

if(!group.empty() && !grouped_items.empty()) {
out << make_group(group, grouped_items, false);
if(group != groups.back())
out << "\n";
}
Expand Down Expand Up @@ -113,21 +115,19 @@ inline std::string Formatter::make_footer(const App *app) const {

inline std::string Formatter::operator()(const App *app, std::string name, AppFormatMode mode) const {

// This immediatly forwards to the make_expanded method. This is done this way so that subcommands can
// have overridden formatters
if(mode == AppFormatMode::Sub)
return make_expanded(app);

std::stringstream out;
if(mode == AppFormatMode::Normal) {
out << make_description(app);
out << make_usage(app, name);
out << make_groups(app, mode);
out << make_subcommands(app, mode);
out << make_footer(app);
} else if(mode == AppFormatMode::Sub) {
out << make_expanded(app);
} else if(mode == AppFormatMode::All) {
out << make_description(app);
out << make_usage(app, name);
out << make_groups(app, mode);
out << make_subcommands(app, mode);
}

out << make_description(app);
out << make_usage(app, name);
out << make_positionals(app);
out << make_groups(app, mode);
out << make_subcommands(app, mode);
out << make_footer(app);

return out.str();
}
Expand All @@ -151,8 +151,6 @@ inline std::string Formatter::make_subcommands(const App *app, AppFormatMode mod
// For each group, filter out and print subcommands
for(const std::string &group : subcmd_groups_seen) {
out << "\n" << group << ":\n";
if(mode == AppFormatMode::All)
out << "\n";
std::vector<const App *> subcommands_group = app->get_subcommands(
[&group](const App *app) { return detail::to_lower(app->get_group()) == detail::to_lower(group); });
for(const App *new_com : subcommands_group) {
Expand All @@ -177,7 +175,10 @@ inline std::string Formatter::make_subcommand(const App *sub) const {

inline std::string Formatter::make_expanded(const App *sub) const {
std::stringstream out;
out << sub->get_name() << "\n " << sub->get_description();
if(sub->get_description().empty())
out << sub->get_name();
else
out << sub->get_name() << " -> " << sub->get_description();
out << make_groups(sub, AppFormatMode::Sub);
return out.str();
}
Expand Down
13 changes: 10 additions & 3 deletions include/CLI/FormatterFwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// Distributed under the 3-Clause BSD License. See accompanying
// file LICENSE or https://github.com/CLIUtils/CLI11 for details.

#include <string>
#include <map>
#include <string>

#include "CLI/StringTools.hpp"

Expand Down Expand Up @@ -72,10 +72,16 @@ class Formatter {
///@{

/// This prints out a group of options
virtual std::string make_group(std::string group, std::vector<const Option *> opts, bool is_positional) const;
///
/// Use the filter to pick out the items you want in your group
virtual std::string
make_group(const App *app, std::string group, bool is_positional, std::function<bool(const Option *)> filter) const;

/// This prints out just the positionals "group"
virtual std::string make_positionals(const App *app) const;

/// This prints out all the groups of options
virtual std::string make_groups(const App *app, AppFormatMode mode) const;
std::string make_groups(const App *app, AppFormatMode mode) const;

/// This prints out all the subcommands
virtual std::string make_subcommands(const App *app, AppFormatMode mode) const;
Expand All @@ -102,6 +108,7 @@ class Formatter {
/// @name Options
///@{

/// This prints out an option help line, either positional or optional form
virtual std::string make_option(const Option *opt, bool is_positional) const {
std::stringstream out;
detail::format_help(
Expand Down
6 changes: 6 additions & 0 deletions include/CLI/Option.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,12 @@ class Option : public OptionBase<Option> {
/// The default value (for help printing)
std::string get_defaultval() const { return defaultval_; }

/// Get the long names
const std::vector<std::string> get_lnames() const { return lnames_; }

/// Get the short names
const std::vector<std::string> get_snames() const { return snames_; }

/// The number of times the option expects to be included
int get_expected() const { return expected_; }

Expand Down
2 changes: 1 addition & 1 deletion include/CLI/StringTools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#include <locale>
#include <sstream>
#include <string>
#include <vector>
#include <type_traits>
#include <vector>

namespace CLI {
namespace detail {
Expand Down
4 changes: 2 additions & 2 deletions include/CLI/Validators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace CLI {

///
struct Validator {
/// This is the type name, if emtpy the type name will not be changed
/// This is the type name, if empty the type name will not be changed
std::string tname;
std::function<std::string(const std::string &filename)> func;

Expand Down Expand Up @@ -77,7 +77,7 @@ struct Validator {
}
};

// The implemntation of the built in validators is using the Validator class;
// The implementation of the built in validators is using the Validator class;
// the user is only expected to use the const (static) versions (since there's no setup).
// Therefore, this is in detail.
namespace detail {
Expand Down
2 changes: 1 addition & 1 deletion scripts/check_style.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -evx

clang-format --version

git ls-files -- '*.cpp' '*.hpp' | xargs clang-format -i -style=file
git ls-files -- '*.cpp' '*.hpp' | xargs clang-format -sort-includes -i -style=file

git diff --exit-code --color

Expand Down
2 changes: 1 addition & 1 deletion tests/AppTest.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "app_helper.hpp"
#include <cstdlib>
#include <complex>
#include <cstdlib>

TEST_F(TApp, OneFlagShort) {
app.add_flag("-c,--count");
Expand Down
5 changes: 4 additions & 1 deletion tests/CreationTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#include <cstdlib>

TEST_F(TApp, AddingExistingShort) {
app.add_flag("-c,--count");
CLI::Option *opt = app.add_flag("-c,--count");
EXPECT_EQ(opt->get_lnames(), std::vector<std::string>({"count"}));
EXPECT_EQ(opt->get_snames(), std::vector<std::string>({"c"}));

EXPECT_THROW(app.add_flag("--cat,-c"), CLI::OptionAlreadyAdded);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/FormatterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include "CLI/CLI.hpp"
#endif

#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <fstream>

using ::testing::HasSubstr;
Expand Down
19 changes: 17 additions & 2 deletions tests/HelpTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include "CLI/CLI.hpp"
#endif

#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <fstream>

using ::testing::HasSubstr;
Expand Down Expand Up @@ -492,7 +492,8 @@ TEST_F(CapturedHelp, CallForAllHelp) {
EXPECT_EQ(err.str(), "");
}
TEST_F(CapturedHelp, CallForAllHelpOutput) {
app.add_subcommand("one");
app.set_help_all_flag("--help-all", "Help all");
app.add_subcommand("one", "One description");
CLI::App *sub = app.add_subcommand("two");
sub->add_flag("--three");

Expand All @@ -502,6 +503,20 @@ TEST_F(CapturedHelp, CallForAllHelpOutput) {
EXPECT_THAT(out.str(), HasSubstr("one"));
EXPECT_THAT(out.str(), HasSubstr("two"));
EXPECT_THAT(out.str(), HasSubstr("--three"));

EXPECT_EQ(out.str(),
"My Test Program\n"
"Usage: [OPTIONS] [SUBCOMMAND]\n"
"\n"
"Options:\n"
" -h,--help Print this help message and exit\n"
" --help-all Help all\n"
"\n"
"Subcommands:\n"
"one -> One description\n"
"two\n"
"Options:\n"
" --three \n");
}
TEST_F(CapturedHelp, NewFormattedHelp) {
app.formatter([](const CLI::App *, std::string, CLI::AppFormatMode) { return "New Help"; });
Expand Down
4 changes: 2 additions & 2 deletions tests/HelpersTest.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "app_helper.hpp"

#include <complex>
#include <cstdint>
#include <cstdio>
#include <fstream>
#include <cstdint>
#include <string>
#include <complex>

TEST(Split, SimpleByToken) {
auto out = CLI::detail::split("one.two.three", '.');
Expand Down
2 changes: 1 addition & 1 deletion tests/IniTest.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "app_helper.hpp"

#include "gmock/gmock.h"
#include <cstdio>
#include <sstream>
#include "gmock/gmock.h"

using ::testing::HasSubstr;
using ::testing::Not;
Expand Down
2 changes: 1 addition & 1 deletion tests/SubcommandTest.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "app_helper.hpp"

#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

using ::testing::HasSubstr;
using ::testing::Not;
Expand Down
8 changes: 4 additions & 4 deletions tests/TimerTest.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "CLI/Timer.hpp"
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <chrono>
#include <thread>
#include <sstream>
#include <string>
#include <thread>

using ::testing::HasSubstr;

Expand Down

0 comments on commit 101d847

Please sign in to comment.