mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 15:14: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) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ try {
|
|||||||
}
|
}
|
||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ try {
|
|||||||
}
|
}
|
||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +194,7 @@ try {
|
|||||||
}
|
}
|
||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ The square of 4 is 16
|
|||||||
|
|
||||||
### Printing Help
|
### 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
|
$ ./main --help
|
||||||
@ -235,6 +235,8 @@ Optional arguments:
|
|||||||
-v, --verbose enable verbose logging
|
-v, --verbose enable verbose logging
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You may also get the help message in string via `program.help().str()`.
|
||||||
|
|
||||||
### List of Arguments
|
### 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.
|
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) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +282,7 @@ try {
|
|||||||
}
|
}
|
||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +314,7 @@ try {
|
|||||||
}
|
}
|
||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +390,7 @@ try {
|
|||||||
}
|
}
|
||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,7 +426,7 @@ try {
|
|||||||
}
|
}
|
||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,7 +468,7 @@ try {
|
|||||||
}
|
}
|
||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
program.print_help();
|
std::cout << program;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ SOFTWARE.
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <any>
|
#include <any>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -75,8 +74,12 @@ template <typename T>
|
|||||||
using enable_if_not_container = std::enable_if_t<!is_container_v<T>, T>;
|
using enable_if_not_container = std::enable_if_t<!is_container_v<T>, T>;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
class ArgumentParser;
|
||||||
|
|
||||||
class Argument {
|
class Argument {
|
||||||
friend class ArgumentParser;
|
friend class ArgumentParser;
|
||||||
|
friend auto operator<<(std::ostream &, ArgumentParser const &)
|
||||||
|
-> std::ostream &;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Argument() = default;
|
Argument() = default;
|
||||||
@ -412,39 +415,54 @@ public:
|
|||||||
throw std::logic_error("No such argument");
|
throw std::logic_error("No such argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Printing the one and only help message
|
// Print help message
|
||||||
// I've stuck with a simple message format, nothing fancy.
|
friend auto operator<<(std::ostream &stream, const ArgumentParser &parser)
|
||||||
// TODO: support user-defined help and usage messages for the ArgumentParser
|
-> std::ostream & {
|
||||||
std::string print_help() {
|
if (auto sen = std::ostream::sentry(stream)) {
|
||||||
std::stringstream stream;
|
stream.setf(std::ios_base::left);
|
||||||
stream << std::left;
|
stream << "Usage: " << parser.mProgramName << " [options] ";
|
||||||
stream << "Usage: " << mProgramName << " [options] ";
|
size_t tLongestArgumentLength = parser.get_length_of_longest_argument();
|
||||||
size_t tLongestArgumentLength = get_length_of_longest_argument();
|
|
||||||
|
|
||||||
for (const auto &argument : mPositionalArguments) {
|
for (const auto &argument : parser.mPositionalArguments) {
|
||||||
stream << argument->mNames.front() << " ";
|
stream << argument->mNames.front() << " ";
|
||||||
}
|
}
|
||||||
stream << "\n\n";
|
stream << "\n\n";
|
||||||
|
|
||||||
if (!mPositionalArguments.empty())
|
if (!parser.mPositionalArguments.empty())
|
||||||
stream << "Positional arguments:\n";
|
stream << "Positional arguments:\n";
|
||||||
|
|
||||||
for (const auto &mPositionalArgument : mPositionalArguments) {
|
for (const auto &mPositionalArgument : parser.mPositionalArguments) {
|
||||||
stream.width(tLongestArgumentLength);
|
stream.width(tLongestArgumentLength);
|
||||||
stream << *mPositionalArgument;
|
stream << *mPositionalArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mOptionalArguments.empty())
|
if (!parser.mOptionalArguments.empty())
|
||||||
stream << (mPositionalArguments.empty() ? "" : "\n")
|
stream << (parser.mPositionalArguments.empty() ? "" : "\n")
|
||||||
<< "Optional arguments:\n";
|
<< "Optional arguments:\n";
|
||||||
|
|
||||||
for (const auto &mOptionalArgument : mOptionalArguments) {
|
for (const auto &mOptionalArgument : parser.mOptionalArguments) {
|
||||||
stream.width(tLongestArgumentLength);
|
stream.width(tLongestArgumentLength);
|
||||||
stream << *mOptionalArgument;
|
stream << *mOptionalArgument;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << stream.str();
|
return stream;
|
||||||
return stream.str();
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
[[deprecated("Use cout << program; instead. See also help().")]] std::string
|
||||||
|
print_help() {
|
||||||
|
auto out = help();
|
||||||
|
std::cout << out.rdbuf();
|
||||||
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -507,7 +525,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Used by print_help.
|
// Used by print_help.
|
||||||
size_t get_length_of_longest_argument() {
|
size_t get_length_of_longest_argument() const {
|
||||||
if (mArgumentMap.empty())
|
if (mArgumentMap.empty())
|
||||||
return 0;
|
return 0;
|
||||||
std::vector<size_t> argumentLengths(mArgumentMap.size());
|
std::vector<size_t> argumentLengths(mArgumentMap.size());
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <argparse.hpp>
|
#include <argparse.hpp>
|
||||||
|
#include <test_help.hpp>
|
||||||
#include <test_parse_args.hpp>
|
#include <test_parse_args.hpp>
|
||||||
#include <test_positional_arguments.hpp>
|
#include <test_positional_arguments.hpp>
|
||||||
#include <test_optional_arguments.hpp>
|
#include <test_optional_arguments.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