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 1 ## Version 1.7.0: Parse breakup (in progress)
2 2  
3 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 7 * Added `parse(string)` to split up and parse a command-line style string directly. [#186]
7 8 * Added `ignore_underscore` and related functions, to ignore underscores when matching names. [#185]
8 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 16 [#183]: https://github.com/CLIUtils/CLI11/pull/183
16 17 [#185]: https://github.com/CLIUtils/CLI11/pull/185
17 18 [#186]: https://github.com/CLIUtils/CLI11/pull/186
  19 +[#187]: https://github.com/CLIUtils/CLI11/pull/187
18 20  
19 21 ## Version 1.6.2: Help-all
20 22  
... ...
include/CLI/App.hpp
... ... @@ -1193,21 +1193,9 @@ class App {
1193 1193 detail::trim(commandline);
1194 1194 // the next section of code is to deal with quoted arguments after an '=' or ':' for windows like operations
1195 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 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 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 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 249 } // namespace detail
238 250 } // namespace CLI
... ...
tests/HelpersTest.cpp
... ... @@ -47,9 +47,8 @@ TEST(StringTools, Modify) {
47 47 }
48 48  
49 49 TEST(StringTools, Modify2) {
50   - int cnt = 0;
51 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 52 if((index > 1) && (str[index - 1] != ' ')) {
54 53 str[index] = 'a';
55 54 str[index + 1] = 't';
... ... @@ -60,9 +59,8 @@ TEST(StringTools, Modify2) {
60 59 }
61 60  
62 61 TEST(StringTools, Modify3) {
63   - int cnt = 0;
64 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 64 str.erase(index, 3);
67 65 str.insert(str.begin(), 'a');
68 66 return 0;
... ...
tests/StringParseTest.cpp
... ... @@ -26,6 +26,30 @@ TEST_F(TApp, ExistingExeCheck) {
26 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 53 TEST_F(TApp, ExistingExeCheckWithLotsOfSpace) {
30 54  
31 55 TempFile tmpexe{"this is a weird file.exe"};
... ...
tests/SubcommandTest.cpp
... ... @@ -798,7 +798,7 @@ TEST_F(ManySubcommands, MaxCommands) {
798 798 // The extra subcommand counts as an extra
799 799 args = {"sub1", "sub2", "sub3"};
800 800 EXPECT_NO_THROW(run());
801   - EXPECT_EQ(sub2->remaining().size(), 1);
  801 + EXPECT_EQ(sub2->remaining().size(), (size_t)1);
802 802  
803 803 // Currently, setting sub2 to throw causes an extras error
804 804 // In the future, would passing on up to app's extras be better?
... ...