mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-03 22:54:39 +00:00
commit
bda0866320
24
README.md
24
README.md
@ -58,7 +58,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ try {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ try {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ try {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@ The square of 4 is 16
|
||||
|
||||
### Printing Help
|
||||
|
||||
```ArgumentParser.print_help()``` print a help message, including the program usage and information about the arguments registered with the ArgumentParser. For the previous example, here's the default help message:
|
||||
`std::cout << program` prints a help message, including the program usage and information about the arguments registered with the `ArgumentParser`. For the previous example, here's the default help message:
|
||||
|
||||
```
|
||||
$ ./main --help
|
||||
@ -235,6 +235,8 @@ Optional arguments:
|
||||
-v, --verbose enable verbose logging
|
||||
```
|
||||
|
||||
You may also get the help message in string via `program.help().str()`.
|
||||
|
||||
### List of Arguments
|
||||
|
||||
ArgumentParser objects usually associate a single command-line argument with a single action to be taken. The ```.nargs``` associates a different number of command-line arguments with a single action. When using ```nargs(N)```, N arguments from the command line will be gathered together into a list.
|
||||
@ -251,7 +253,7 @@ try {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -280,7 +282,7 @@ try {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -312,7 +314,7 @@ try {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -388,7 +390,7 @@ try {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -424,7 +426,7 @@ try {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -466,7 +468,7 @@ try {
|
||||
}
|
||||
catch (const std::runtime_error& err) {
|
||||
std::cout << err.what() << std::endl;
|
||||
program.print_help();
|
||||
std::cout << program;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,6 @@ SOFTWARE.
|
||||
#include <algorithm>
|
||||
#include <any>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
@ -75,8 +74,12 @@ template <typename T>
|
||||
using enable_if_not_container = std::enable_if_t<!is_container_v<T>, T>;
|
||||
} // namespace
|
||||
|
||||
class ArgumentParser;
|
||||
|
||||
class Argument {
|
||||
friend class ArgumentParser;
|
||||
friend auto operator<<(std::ostream &, ArgumentParser const &)
|
||||
-> std::ostream &;
|
||||
|
||||
public:
|
||||
Argument() = default;
|
||||
@ -412,39 +415,54 @@ public:
|
||||
throw std::logic_error("No such argument");
|
||||
}
|
||||
|
||||
// Print help message
|
||||
friend auto operator<<(std::ostream &stream, const ArgumentParser &parser)
|
||||
-> std::ostream & {
|
||||
if (auto sen = std::ostream::sentry(stream)) {
|
||||
stream.setf(std::ios_base::left);
|
||||
stream << "Usage: " << parser.mProgramName << " [options] ";
|
||||
size_t tLongestArgumentLength = parser.get_length_of_longest_argument();
|
||||
|
||||
for (const auto &argument : parser.mPositionalArguments) {
|
||||
stream << argument->mNames.front() << " ";
|
||||
}
|
||||
stream << "\n\n";
|
||||
|
||||
if (!parser.mPositionalArguments.empty())
|
||||
stream << "Positional arguments:\n";
|
||||
|
||||
for (const auto &mPositionalArgument : parser.mPositionalArguments) {
|
||||
stream.width(tLongestArgumentLength);
|
||||
stream << *mPositionalArgument;
|
||||
}
|
||||
|
||||
if (!parser.mOptionalArguments.empty())
|
||||
stream << (parser.mPositionalArguments.empty() ? "" : "\n")
|
||||
<< "Optional arguments:\n";
|
||||
|
||||
for (const auto &mOptionalArgument : parser.mOptionalArguments) {
|
||||
stream.width(tLongestArgumentLength);
|
||||
stream << *mOptionalArgument;
|
||||
}
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
// Format help message
|
||||
auto help() const -> std::ostringstream {
|
||||
std::ostringstream out;
|
||||
out << *this;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Printing the one and only help message
|
||||
// I've stuck with a simple message format, nothing fancy.
|
||||
// TODO: support user-defined help and usage messages for the ArgumentParser
|
||||
std::string print_help() {
|
||||
std::stringstream stream;
|
||||
stream << std::left;
|
||||
stream << "Usage: " << mProgramName << " [options] ";
|
||||
size_t tLongestArgumentLength = get_length_of_longest_argument();
|
||||
|
||||
for (const auto &argument : mPositionalArguments) {
|
||||
stream << argument->mNames.front() << " ";
|
||||
}
|
||||
stream << "\n\n";
|
||||
|
||||
if (!mPositionalArguments.empty())
|
||||
stream << "Positional arguments:\n";
|
||||
|
||||
for (const auto &mPositionalArgument : mPositionalArguments) {
|
||||
stream.width(tLongestArgumentLength);
|
||||
stream << *mPositionalArgument;
|
||||
}
|
||||
|
||||
if (!mOptionalArguments.empty())
|
||||
stream << (mPositionalArguments.empty() ? "" : "\n")
|
||||
<< "Optional arguments:\n";
|
||||
|
||||
for (const auto &mOptionalArgument : mOptionalArguments) {
|
||||
stream.width(tLongestArgumentLength);
|
||||
stream << *mOptionalArgument;
|
||||
}
|
||||
|
||||
std::cout << stream.str();
|
||||
return stream.str();
|
||||
[[deprecated("Use cout << program; instead. See also help().")]] std::string
|
||||
print_help() {
|
||||
auto out = help();
|
||||
std::cout << out.rdbuf();
|
||||
return out.str();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -507,7 +525,7 @@ private:
|
||||
}
|
||||
|
||||
// Used by print_help.
|
||||
size_t get_length_of_longest_argument() {
|
||||
size_t get_length_of_longest_argument() const {
|
||||
if (mArgumentMap.empty())
|
||||
return 0;
|
||||
std::vector<size_t> argumentLengths(mArgumentMap.size());
|
||||
|
@ -1,6 +1,7 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <iostream>
|
||||
#include <argparse.hpp>
|
||||
#include <test_help.hpp>
|
||||
#include <test_parse_args.hpp>
|
||||
#include <test_positional_arguments.hpp>
|
||||
#include <test_optional_arguments.hpp>
|
||||
@ -11,4 +12,4 @@
|
||||
#include <test_invalid_arguments.hpp>
|
||||
#include <test_negative_numbers.hpp>
|
||||
#include <test_required_arguments.hpp>
|
||||
#include <test_issue_37.hpp>
|
||||
#include <test_issue_37.hpp>
|
18
test/test_help.hpp
Normal file
18
test/test_help.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <catch.hpp>
|
||||
#include <argparse.hpp>
|
||||
|
||||
TEST_CASE("Users can format help message", "[help]") {
|
||||
argparse::ArgumentParser program("test");
|
||||
program.add_argument("input")
|
||||
.help("positional input");
|
||||
program.add_argument("-c")
|
||||
.help("optional input");
|
||||
|
||||
std::ostringstream s;
|
||||
s << program;
|
||||
REQUIRE_FALSE(s.str().empty());
|
||||
|
||||
auto msg = program.help().str();
|
||||
REQUIRE(msg == s.str());
|
||||
}
|
Loading…
Reference in New Issue
Block a user