Commit 1d9ae57a92c367ec6e92c982e42f7edb573084f6
1 parent
239525bc
parse groups
Showing
3 changed files
with
48 additions
and
15 deletions
src/cxxopts.cpp
| @@ -363,7 +363,7 @@ Options::add_option | @@ -363,7 +363,7 @@ Options::add_option | ||
| 363 | 363 | ||
| 364 | //add the help details | 364 | //add the help details |
| 365 | auto& options = m_help[group]; | 365 | auto& options = m_help[group]; |
| 366 | - options.push_back(HelpDetails{s, l, desc, value->has_arg()}); | 366 | + options.options.push_back(HelpOptionDetails{s, l, desc, value->has_arg()}); |
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | void | 369 | void |
| @@ -382,11 +382,11 @@ Options::add_one_option | @@ -382,11 +382,11 @@ Options::add_one_option | ||
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | std::string | 384 | std::string |
| 385 | -Options::help() const | 385 | +Options::help_one_group(const std::string& g) const |
| 386 | { | 386 | { |
| 387 | typedef std::vector<std::pair<std::string, std::string>> OptionHelp; | 387 | typedef std::vector<std::pair<std::string, std::string>> OptionHelp; |
| 388 | 388 | ||
| 389 | - auto group = m_help.find(""); | 389 | + auto group = m_help.find(g); |
| 390 | if (group == m_help.end()) | 390 | if (group == m_help.end()) |
| 391 | { | 391 | { |
| 392 | return ""; | 392 | return ""; |
| @@ -396,10 +396,14 @@ Options::help() const | @@ -396,10 +396,14 @@ Options::help() const | ||
| 396 | 396 | ||
| 397 | size_t longest = 0; | 397 | size_t longest = 0; |
| 398 | 398 | ||
| 399 | - std::string result = "Usage:\n " + m_program + " [OPTION...] " | ||
| 400 | - + m_help_string + "\n\n"; | 399 | + std::string result; |
| 400 | + | ||
| 401 | + if (!g.empty()) | ||
| 402 | + { | ||
| 403 | + result += " " + g + " options:\n\n"; | ||
| 404 | + } | ||
| 401 | 405 | ||
| 402 | - for (const auto& o : group->second) | 406 | + for (const auto& o : group->second.options) |
| 403 | { | 407 | { |
| 404 | auto s = format_option(o.s, o.l, o.has_arg); | 408 | auto s = format_option(o.s, o.l, o.has_arg); |
| 405 | longest = std::max(longest, s.size()); | 409 | longest = std::max(longest, s.size()); |
| @@ -412,7 +416,7 @@ Options::help() const | @@ -412,7 +416,7 @@ Options::help() const | ||
| 412 | int allowed = 76 - longest - OPTION_DESC_GAP; | 416 | int allowed = 76 - longest - OPTION_DESC_GAP; |
| 413 | 417 | ||
| 414 | auto fiter = format.begin(); | 418 | auto fiter = format.begin(); |
| 415 | - for (const auto& o : group->second) | 419 | + for (const auto& o : group->second.options) |
| 416 | { | 420 | { |
| 417 | auto d = format_description(o.desc, longest + OPTION_DESC_GAP, allowed); | 421 | auto d = format_description(o.desc, longest + OPTION_DESC_GAP, allowed); |
| 418 | 422 | ||
| @@ -436,4 +440,18 @@ Options::help() const | @@ -436,4 +440,18 @@ Options::help() const | ||
| 436 | return result; | 440 | return result; |
| 437 | } | 441 | } |
| 438 | 442 | ||
| 443 | +std::string | ||
| 444 | +Options::help(const std::vector<std::string>& groups) const | ||
| 445 | +{ | ||
| 446 | + std::string result = "Usage:\n " + m_program + " [OPTION...] " | ||
| 447 | + + m_help_string + "\n\n"; | ||
| 448 | + | ||
| 449 | + for (const auto& g : groups) | ||
| 450 | + { | ||
| 451 | + result += help_one_group(g); | ||
| 452 | + } | ||
| 453 | + | ||
| 454 | + return result; | ||
| 455 | +} | ||
| 456 | + | ||
| 439 | } | 457 | } |
src/cxxopts.hpp
| @@ -326,7 +326,7 @@ namespace cxxopts | @@ -326,7 +326,7 @@ namespace cxxopts | ||
| 326 | int m_count; | 326 | int m_count; |
| 327 | }; | 327 | }; |
| 328 | 328 | ||
| 329 | - struct HelpDetails | 329 | + struct HelpOptionDetails |
| 330 | { | 330 | { |
| 331 | std::string s; | 331 | std::string s; |
| 332 | std::string l; | 332 | std::string l; |
| @@ -334,6 +334,13 @@ namespace cxxopts | @@ -334,6 +334,13 @@ namespace cxxopts | ||
| 334 | bool has_arg; | 334 | bool has_arg; |
| 335 | }; | 335 | }; |
| 336 | 336 | ||
| 337 | + struct HelpGroupDetails | ||
| 338 | + { | ||
| 339 | + std::string name; | ||
| 340 | + std::string description; | ||
| 341 | + std::vector<HelpOptionDetails> options; | ||
| 342 | + }; | ||
| 343 | + | ||
| 337 | class Options | 344 | class Options |
| 338 | { | 345 | { |
| 339 | public: | 346 | public: |
| @@ -390,7 +397,7 @@ namespace cxxopts | @@ -390,7 +397,7 @@ namespace cxxopts | ||
| 390 | parse_positional(std::string option); | 397 | parse_positional(std::string option); |
| 391 | 398 | ||
| 392 | std::string | 399 | std::string |
| 393 | - help() const; | 400 | + help(const std::vector<std::string>& groups = {""}) const; |
| 394 | 401 | ||
| 395 | private: | 402 | private: |
| 396 | 403 | ||
| @@ -425,6 +432,9 @@ namespace cxxopts | @@ -425,6 +432,9 @@ namespace cxxopts | ||
| 425 | const std::string& name | 432 | const std::string& name |
| 426 | ); | 433 | ); |
| 427 | 434 | ||
| 435 | + std::string | ||
| 436 | + help_one_group(const std::string& group) const; | ||
| 437 | + | ||
| 428 | std::string m_program; | 438 | std::string m_program; |
| 429 | std::string m_help_string; | 439 | std::string m_help_string; |
| 430 | 440 | ||
| @@ -432,7 +442,7 @@ namespace cxxopts | @@ -432,7 +442,7 @@ namespace cxxopts | ||
| 432 | std::string m_positional; | 442 | std::string m_positional; |
| 433 | 443 | ||
| 434 | //mapping from groups to help options | 444 | //mapping from groups to help options |
| 435 | - std::map<std::string, std::vector<HelpDetails>> m_help; | 445 | + std::map<std::string, HelpGroupDetails> m_help; |
| 436 | }; | 446 | }; |
| 437 | 447 | ||
| 438 | class OptionAdder | 448 | class OptionAdder |
src/example.cpp
| @@ -48,10 +48,20 @@ int main(int argc, char* argv[]) | @@ -48,10 +48,20 @@ int main(int argc, char* argv[]) | ||
| 48 | ("option_that_is_too_long_for_the_help", "A very long option") | 48 | ("option_that_is_too_long_for_the_help", "A very long option") |
| 49 | ; | 49 | ; |
| 50 | 50 | ||
| 51 | + options.add_options("Group") | ||
| 52 | + ("c,compile", "compile") | ||
| 53 | + ("d,drop", "drop", cxxopts::value<std::vector<std::string>>()); | ||
| 54 | + | ||
| 51 | options.parse_positional("positional"); | 55 | options.parse_positional("positional"); |
| 52 | 56 | ||
| 53 | options.parse(argc, argv); | 57 | options.parse(argc, argv); |
| 54 | 58 | ||
| 59 | + if (options.count("help")) | ||
| 60 | + { | ||
| 61 | + std::cout << options.help({"", "Group"}) << std::endl; | ||
| 62 | + exit(0); | ||
| 63 | + } | ||
| 64 | + | ||
| 55 | if (apple) | 65 | if (apple) |
| 56 | { | 66 | { |
| 57 | std::cout << "Saw option ‘a’" << std::endl; | 67 | std::cout << "Saw option ‘a’" << std::endl; |
| @@ -72,11 +82,6 @@ int main(int argc, char* argv[]) | @@ -72,11 +82,6 @@ int main(int argc, char* argv[]) | ||
| 72 | } | 82 | } |
| 73 | } | 83 | } |
| 74 | 84 | ||
| 75 | - if (options.count("help")) | ||
| 76 | - { | ||
| 77 | - std::cout << options.help() << std::endl; | ||
| 78 | - } | ||
| 79 | - | ||
| 80 | if (options.count("positional")) | 85 | if (options.count("positional")) |
| 81 | { | 86 | { |
| 82 | std::cout << "Positional = " << options["positional"].as<std::string>() | 87 | std::cout << "Positional = " << options["positional"].as<std::string>() |