diff options
| author | Taylor C. Richberger <taywee@gmx.com> | 2016-05-06 15:33:23 -0400 | 
|---|---|---|
| committer | Taylor C. Richberger <taywee@gmx.com> | 2016-05-06 15:33:23 -0400 | 
| commit | dabfd73fc1387c434fd5f10cf661a01e64252e04 (patch) | |
| tree | 516f1db8e2891b85b0d40d31d0aba28dc67a0b3d | |
| parent | Merge branch '10-help-generator-parameters-should-be-in-a-structure' into 'ma... (diff) | |
| parent | add overloads and tests, and improve help generation in general (diff) | |
| download | args.hxx-dabfd73fc1387c434fd5f10cf661a01e64252e04.tar.xz | |
Merge branch '8-argumentparser-help-should-be-overloaded-and-should-also-have-an-overloaded-operator-method' into 'master'
add overloads and tests, and improve help generation in general
Closes #8
See merge request !5
| -rw-r--r-- | args.hxx | 62 | ||||
| -rw-r--r-- | test.cxx | 15 | 
2 files changed, 56 insertions, 21 deletions
| @@ -679,14 +679,31 @@ namespace args          public:              struct HelpParams              { +                /** The width of the help menu +                 */                  unsigned int width = 80; +                /** The indent of the program line +                 */                  unsigned int progindent = 2; -                unsigned int progtailindent = 2; +                /** The indent of the program trailing lines for long parameters +                 */ +                unsigned int progtailindent = 4; +                /** The indent of the description and epilogs +                 */                  unsigned int descriptionindent = 4; -                unsigned int flagindent = 4; -                unsigned int eachgroupindent = 2; +                /** The indent of the flags +                 */ +                unsigned int flagindent = 6; +                /** The indent of the flag descriptions +                 */                  unsigned int helpindent = 25; -                unsigned int gutter = 25; +                /** The additional indent each group adds +                 */ +                unsigned int eachgroupindent = 2; + +                /** The minimum gutter between each flag and its help +                 */ +                unsigned int gutter = 1;              } helpParams;              ArgumentParser(const std::string &description, const std::string &epilog = std::string()) :                  Group("arguments", Group::Validators::AllChildGroups), @@ -750,10 +767,6 @@ namespace args               */              void LongSeparator(const std::string &longseparator)              { -                if (longseparator.empty()) -                { -                    throw ParseError("The long separator may not be empty"); -                }                  this->longseparator = longseparator;              } @@ -766,24 +779,15 @@ namespace args              void Terminator(const std::string &terminator)              { this->terminator = terminator; } -            /** Generate a help menu as a string. -             * -             * \param width the width of the terminal -             * \param progindent the indent of the program name line -             * \param descriptionindent the indent of the description and epilog lines -             * \param flagindent the indent of the flags themselves -             * \param helpindent the indent of the flag help texts -             * \param gutter the required minimum spacing between the flag text and the flag help -             * \return the help text as a single string +            /** Pass the help menu into an ostream               */ -            std::string Help() const +            void Help(std::ostream &help) const              {                  bool hasoptions = false;                  bool hasarguments = false;                  const std::vector<std::string> description(Wrap(this->description, helpParams.width - helpParams.descriptionindent));                  const std::vector<std::string> epilog(Wrap(this->epilog, helpParams.width - helpParams.descriptionindent)); -                std::ostringstream help;                  std::ostringstream prognameline;                  prognameline << prog;                  if (HasFlag()) @@ -805,7 +809,7 @@ namespace args                  }                  for (; progit != std::end(proglines); ++progit)                  { -                    help << std::string(helpParams.progindent + 4, ' ') << *progit << '\n'; +                    help << std::string(helpParams.progtailindent, ' ') << *progit << '\n';                  }                  help << '\n'; @@ -849,6 +853,16 @@ namespace args                  {                      help << std::string(helpParams.descriptionindent, ' ') << line << "\n";                  } +            } + +            /** Generate a help menu as a string. +             * +             * \return the help text as a single string +             */ +            std::string Help() const +            { +                std::ostringstream help; +                Help(help);                  return help.str();              } @@ -876,7 +890,7 @@ namespace args                      {                          const std::string argchunk(chunk.substr(longprefix.size()));                          // Try to separate it, in case of a separator: -                        const auto separator = argchunk.find(longseparator); +                        const auto separator = longseparator.empty() ? argchunk.npos : argchunk.find(longseparator);                          const std::string arg = (separator != argchunk.npos ?                              std::string(argchunk, 0, separator)                              : argchunk); @@ -997,6 +1011,12 @@ namespace args              }      }; +    std::ostream &operator<<(std::ostream &os, ArgumentParser &parser) +    { +        parser.Help(os); +        return os; +    } +      /** Boolean argument matcher       */      class Flag : public FlagBase @@ -245,3 +245,18 @@ TEST_CASE("Custom parser prefixes (Some Windows styles)", "[args]")      REQUIRE(input.value == "/dev/null");      REQUIRE_FALSE(output);  } + +TEST_CASE("Help menu can be grabbed as a string, passed into a stream, or by using the overloaded stream operator", "[args]") +{ +    std::ostream null(nullptr); +    args::ArgumentParser parser("This command likes to break your disks"); +    args::HelpFlag help(parser, "HELP", "Show this help menu.", args::Matcher({"help"})); +    args::ArgFlag<long> bs(parser, "BYTES", "Block size", args::Matcher({"bs"}), 512); +    args::ArgFlag<long> skip(parser, "BYTES", "Bytes to skip", args::Matcher({"skip"}), 0); +    args::ArgFlag<std::string> input(parser, "BLOCK SIZE", "Block size", args::Matcher({"if"})); +    args::ArgFlag<std::string> output(parser, "BLOCK SIZE", "Block size", args::Matcher({"of"})); +    parser.ParseArgs(std::vector<std::string>{"--skip=8", "--if=/dev/null"}); +    null << parser.Help(); +    parser.Help(null); +    null << parser; +} | 
