diff --git a/include/CLI/App.hpp b/include/CLI/App.hpp index 8516bcdf..39900c6d 100644 --- a/include/CLI/App.hpp +++ b/include/CLI/App.hpp @@ -847,7 +847,7 @@ class App { if(out.tellp() != 0) { out << std::endl; } - out << "; " << opt->get_description() << std::endl; + out << "; " << detail::fix_newlines("; ", opt->get_description()) << std::endl; } out << name << "=" << value << std::endl; } diff --git a/include/CLI/StringTools.hpp b/include/CLI/StringTools.hpp index 64b8603f..ded9eaa6 100644 --- a/include/CLI/StringTools.hpp +++ b/include/CLI/StringTools.hpp @@ -187,5 +187,21 @@ inline std::vector split_up(std::string str) { return output; } +/// Add a leader to the beginning of all new lines (nothing is added +/// at the start of the first line). `"; "` would be for ini files +/// +/// Can't use Regex, or this would be a subs. +inline std::string fix_newlines(std::string leader, std::string input) { + std::string::size_type n = 0; + while(n != std::string::npos && n < input.size()) { + n = input.find('\n', n); + if(n != std::string::npos) { + input = input.substr(0, n + 1) + leader + input.substr(n + 1); + n += leader.size(); + } + } + return input; +} + } // namespace detail } // namespace CLI diff --git a/tests/HelpersTest.cpp b/tests/HelpersTest.cpp index e64a12e0..3f29cc38 100644 --- a/tests/HelpersTest.cpp +++ b/tests/HelpersTest.cpp @@ -359,3 +359,17 @@ TEST(Types, LexicalCastString) { CLI::detail::lexical_cast(input, output); EXPECT_EQ(input, output); } + +TEST(FixNewLines, BasicCheck) { + std::string input = "one\ntwo"; + std::string output = "one\n; two"; + std::string result = CLI::detail::fix_newlines("; ", input); + EXPECT_EQ(result, output); +} + +TEST(FixNewLines, EdgesCheck) { + std::string input = "\none\ntwo\n"; + std::string output = "\n; one\n; two\n; "; + std::string result = CLI::detail::fix_newlines("; ", input); + EXPECT_EQ(result, output); +} diff --git a/tests/IniTest.cpp b/tests/IniTest.cpp index 2021e34a..f3812153 100644 --- a/tests/IniTest.cpp +++ b/tests/IniTest.cpp @@ -600,6 +600,19 @@ TEST_F(TApp, IniOutputShortDoubleDescription) { EXPECT_EQ(str, "; " + description1 + "\n" + flag1 + "=false\n\n; " + description2 + "\n" + flag2 + "=false\n"); } +TEST_F(TApp, IniOutputMultiLineDescription) { + std::string flag = "some_flag"; + std::string description = "Some short description.\nThat has lines."; + app.add_flag("--" + flag, description); + + run(); + + std::string str = app.config_to_str(true, "", true); + EXPECT_THAT(str, HasSubstr("; Some short description.\n")); + EXPECT_THAT(str, HasSubstr("; That has lines.\n")); + EXPECT_THAT(str, HasSubstr(flag + "=false\n")); +} + TEST_F(TApp, IniOutputVector) { std::vector v;