Commit f932b51374a070056fa8c5aa2ead278f7153ded0

Authored by Henry Schreiner
Committed by GitHub
1 parent ce6dc072

Touchupwin (#189)

* Move lambda funtion to real function

* Fix some warnings when compiling in LLVM

* Adding one test back in

* Adding details to changelog
CHANGELOG.md
1 ## Version 1.7.0: Parse breakup (in progress) 1 ## Version 1.7.0: Parse breakup (in progress)
2 2
3 The parsing procedure now maps much more sensibly to complex, nested subcommand structures. Each phase of the parsing happens on all subcommands before moving on with the next phase of the parse. This allows several features, like required environment variables, to work properly even through subcommand boundaries. 3 The parsing procedure now maps much more sensibly to complex, nested subcommand structures. Each phase of the parsing happens on all subcommands before moving on with the next phase of the parse. This allows several features, like required environment variables, to work properly even through subcommand boundaries.
4 -Passing the same subcommand multiple times is better supported. A few new features were added as well. 4 +Passing the same subcommand multiple times is better supported. A few new features were added as well, including Windows style option support, parsing strings directly, and ignoring underscores in names.
5 5
  6 +* Support Windows style options with `->allow_windows_style_options`. [#187]
6 * Added `parse(string)` to split up and parse a command-line style string directly. [#186] 7 * Added `parse(string)` to split up and parse a command-line style string directly. [#186]
7 * Added `ignore_underscore` and related functions, to ignore underscores when matching names. [#185] 8 * Added `ignore_underscore` and related functions, to ignore underscores when matching names. [#185]
8 * Subcommands now track how many times they were parsed in a parsing process. `count()` with no arguments will return the number of times a subcommand was encountered. [#179] 9 * Subcommands now track how many times they were parsed in a parsing process. `count()` with no arguments will return the number of times a subcommand was encountered. [#179]
@@ -15,6 +16,7 @@ Passing the same subcommand multiple times is better supported. A few new featur @@ -15,6 +16,7 @@ Passing the same subcommand multiple times is better supported. A few new featur
15 [#183]: https://github.com/CLIUtils/CLI11/pull/183 16 [#183]: https://github.com/CLIUtils/CLI11/pull/183
16 [#185]: https://github.com/CLIUtils/CLI11/pull/185 17 [#185]: https://github.com/CLIUtils/CLI11/pull/185
17 [#186]: https://github.com/CLIUtils/CLI11/pull/186 18 [#186]: https://github.com/CLIUtils/CLI11/pull/186
  19 +[#187]: https://github.com/CLIUtils/CLI11/pull/187
18 20
19 ## Version 1.6.2: Help-all 21 ## Version 1.6.2: Help-all
20 22
include/CLI/App.hpp
@@ -1193,21 +1193,9 @@ class App { @@ -1193,21 +1193,9 @@ class App {
1193 detail::trim(commandline); 1193 detail::trim(commandline);
1194 // the next section of code is to deal with quoted arguments after an '=' or ':' for windows like operations 1194 // the next section of code is to deal with quoted arguments after an '=' or ':' for windows like operations
1195 if(!commandline.empty()) { 1195 if(!commandline.empty()) {
1196 - auto escape_detect = [](std::string &str, size_t offset) {  
1197 - auto next = str[offset + 1];  
1198 - if((next == '\"') || (next == '\'') || (next == '`')) {  
1199 - auto astart = str.find_last_of("-/ \"\'`", offset - 1);  
1200 - if(astart != std::string::npos) {  
1201 - if(str[astart] == (str[offset] == '=') ? '-' : '/')  
1202 - str[offset] = ' '; // interpret this as a space so the split_up works properly  
1203 - }  
1204 - }  
1205 - return (offset + 1);  
1206 - };  
1207 -  
1208 - commandline = detail::find_and_modify(commandline, "=", escape_detect); 1196 + commandline = detail::find_and_modify(commandline, "=", detail::escape_detect);
1209 if(allow_windows_style_options_) 1197 if(allow_windows_style_options_)
1210 - commandline = detail::find_and_modify(commandline, ":", escape_detect); 1198 + commandline = detail::find_and_modify(commandline, ":", detail::escape_detect);
1211 } 1199 }
1212 1200
1213 auto args = detail::split_up(std::move(commandline)); 1201 auto args = detail::split_up(std::move(commandline));
include/CLI/StringTools.hpp
@@ -234,5 +234,17 @@ inline std::string fix_newlines(std::string leader, std::string input) { @@ -234,5 +234,17 @@ inline std::string fix_newlines(std::string leader, std::string input) {
234 return input; 234 return input;
235 } 235 }
236 236
  237 +inline size_t escape_detect(std::string &str, size_t offset) {
  238 + auto next = str[offset + 1];
  239 + if((next == '\"') || (next == '\'') || (next == '`')) {
  240 + auto astart = str.find_last_of("-/ \"\'`", offset - 1);
  241 + if(astart != std::string::npos) {
  242 + if(str[astart] == (str[offset] == '=') ? '-' : '/')
  243 + str[offset] = ' '; // interpret this as a space so the split_up works properly
  244 + }
  245 + }
  246 + return offset + 1;
  247 +};
  248 +
237 } // namespace detail 249 } // namespace detail
238 } // namespace CLI 250 } // namespace CLI
tests/HelpersTest.cpp
@@ -47,9 +47,8 @@ TEST(StringTools, Modify) { @@ -47,9 +47,8 @@ TEST(StringTools, Modify) {
47 } 47 }
48 48
49 TEST(StringTools, Modify2) { 49 TEST(StringTools, Modify2) {
50 - int cnt = 0;  
51 std::string newString = 50 std::string newString =
52 - CLI::detail::find_and_modify("this is a string test", "is", [&cnt](std::string &str, size_t index) { 51 + CLI::detail::find_and_modify("this is a string test", "is", [](std::string &str, size_t index) {
53 if((index > 1) && (str[index - 1] != ' ')) { 52 if((index > 1) && (str[index - 1] != ' ')) {
54 str[index] = 'a'; 53 str[index] = 'a';
55 str[index + 1] = 't'; 54 str[index + 1] = 't';
@@ -60,9 +59,8 @@ TEST(StringTools, Modify2) { @@ -60,9 +59,8 @@ TEST(StringTools, Modify2) {
60 } 59 }
61 60
62 TEST(StringTools, Modify3) { 61 TEST(StringTools, Modify3) {
63 - int cnt = 0;  
64 // this picks up 3 sets of 3 after the 'b' then collapses the new first set 62 // this picks up 3 sets of 3 after the 'b' then collapses the new first set
65 - std::string newString = CLI::detail::find_and_modify("baaaaaaaaaa", "aaa", [&cnt](std::string &str, size_t index) { 63 + std::string newString = CLI::detail::find_and_modify("baaaaaaaaaa", "aaa", [](std::string &str, size_t index) {
66 str.erase(index, 3); 64 str.erase(index, 3);
67 str.insert(str.begin(), 'a'); 65 str.insert(str.begin(), 'a');
68 return 0; 66 return 0;
tests/StringParseTest.cpp
@@ -26,6 +26,30 @@ TEST_F(TApp, ExistingExeCheck) { @@ -26,6 +26,30 @@ TEST_F(TApp, ExistingExeCheck) {
26 EXPECT_EQ(str3, "\"quoted string\""); 26 EXPECT_EQ(str3, "\"quoted string\"");
27 } 27 }
28 28
  29 +TEST_F(TApp, ExistingExeCheckWithSpace) {
  30 +
  31 + TempFile tmpexe{"Space File.out"};
  32 +
  33 + std::string str, str2, str3;
  34 + app.add_option("-s,--string", str);
  35 + app.add_option("-t,--tstr", str2);
  36 + app.add_option("-m,--mstr", str3);
  37 +
  38 + {
  39 + std::ofstream out{tmpexe};
  40 + out << "useless string doesn't matter" << std::endl;
  41 + }
  42 +
  43 + app.parse(std::string("./") + std::string(tmpexe) +
  44 + " --string=\"this is my quoted string\" -t 'qstring 2' -m=`\"quoted string\"`",
  45 + true);
  46 + EXPECT_EQ(str, "this is my quoted string");
  47 + EXPECT_EQ(str2, "qstring 2");
  48 + EXPECT_EQ(str3, "\"quoted string\"");
  49 +
  50 + EXPECT_EQ(app.get_name(), std::string("./") + std::string(tmpexe));
  51 +}
  52 +
29 TEST_F(TApp, ExistingExeCheckWithLotsOfSpace) { 53 TEST_F(TApp, ExistingExeCheckWithLotsOfSpace) {
30 54
31 TempFile tmpexe{"this is a weird file.exe"}; 55 TempFile tmpexe{"this is a weird file.exe"};
tests/SubcommandTest.cpp
@@ -798,7 +798,7 @@ TEST_F(ManySubcommands, MaxCommands) { @@ -798,7 +798,7 @@ TEST_F(ManySubcommands, MaxCommands) {
798 // The extra subcommand counts as an extra 798 // The extra subcommand counts as an extra
799 args = {"sub1", "sub2", "sub3"}; 799 args = {"sub1", "sub2", "sub3"};
800 EXPECT_NO_THROW(run()); 800 EXPECT_NO_THROW(run());
801 - EXPECT_EQ(sub2->remaining().size(), 1); 801 + EXPECT_EQ(sub2->remaining().size(), (size_t)1);
802 802
803 // Currently, setting sub2 to throw causes an extras error 803 // Currently, setting sub2 to throw causes an extras error
804 // In the future, would passing on up to app's extras be better? 804 // In the future, would passing on up to app's extras be better?