put everything in the argparse namespace

This commit is contained in:
Carl Pearson
2020-04-01 13:59:50 -05:00
parent a132c7d925
commit 193219ac50
4 changed files with 46 additions and 57 deletions

View File

@@ -16,7 +16,7 @@ Download the latest [`argparse.hpp`](https://raw.githubusercontent.com/cwpearson
int main(int argc, char **argv) { int main(int argc, char **argv) {
// A parser object // A parser object
Parser p; argparse::Parser p;
// Program data corresponding to flags, options, and positional arguments // Program data corresponding to flags, options, and positional arguments
bool verbose = false; bool verbose = false;
@@ -70,7 +70,7 @@ They are invoked like `--long-opt value` (not `--long-opt=value`).
```c++ ```c++
Parser p; argparse::Parser p;
p.add_option(var1, "--long-opt") p.add_option(var1, "--long-opt")
``` ```
@@ -81,7 +81,7 @@ The boolean variable is ALWAYS set to `true` if the flag is found.
They are invoked like `--long-flag` (not `--long-flag=true` or `--long-flag true`). They are invoked like `--long-flag` (not `--long-flag=true` or `--long-flag true`).
```c++ ```c++
Parser p; argparse::Parser p;
p.add_option(flag1, "--long-flag") p.add_option(flag1, "--long-flag")
p.add_option(flag2, "--antother-flag", "-s"); p.add_option(flag2, "--antother-flag", "-s");
``` ```
@@ -94,7 +94,7 @@ Use `required()` to require them.
`add_positional()` returns a `PosnlBase *` that may be queried with `found()` to see if an optional positional argument was found. `add_positional()` returns a `PosnlBase *` that may be queried with `found()` to see if an optional positional argument was found.
```c++ ```c++
Parser p; argparse::Parser p;
p.add_positional(var1)->required(); p.add_positional(var1)->required();
auto something = p.add_positional(var2); auto something = p.add_positional(var2);
if (something->found()) { if (something->found()) {
@@ -107,7 +107,7 @@ Here, the first `--` is the value for `--option` and will be in `s1`.
The second `--` marks the beginning of positional arguments. and the string `aa` will be in `s2`. The second `--` marks the beginning of positional arguments. and the string `aa` will be in `s2`.
```c++ ```c++
Parser p; argparse::Parser p;
std::string s1, s2; std::string s1, s2;
p.add_option(s1, "--option"); p.add_option(s1, "--option");
p.add_positional(s2); p.add_positional(s2);
@@ -123,7 +123,7 @@ $ ./myexe --option -- -- aa
## Parsing ## Parsing
```c++ ```c++
Parser p; argparse::Parser p;
// set up flags, arguments, and options // set up flags, arguments, and options
p.parse(argc, argv); p.parse(argc, argv);
``` ```

View File

@@ -3,7 +3,7 @@
int main(int argc, char **argv) { int main(int argc, char **argv) {
// A parser object // A parser object
Parser p; argparse::Parser p;
// Program data corresponding to flags, options, and positional arguments // Program data corresponding to flags, options, and positional arguments
bool verbose = false; bool verbose = false;

View File

@@ -1,12 +1,11 @@
#pragma once #pragma once
#include <string>
#include <vector>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string>
#include <vector>
namespace argparse {
class OptionBase { class OptionBase {
public: public:
@@ -21,9 +20,7 @@ template <typename T> class Option : public OptionBase {
public: public:
Option(T &val, const std::string &l) : long_(l), val_(&val) {} Option(T &val, const std::string &l) : long_(l), val_(&val) {}
void set_val(const std::string &val) override { set_val((T *)nullptr, val); } void set_val(const std::string &val) override { set_val((T *)nullptr, val); }
const std::string &long_str() override { const std::string &long_str() override { return long_; }
return long_;
}
private: private:
void set_val(size_t *, const std::string &val) { // convert to size_t void set_val(size_t *, const std::string &val) { // convert to size_t
@@ -50,20 +47,17 @@ class Flag {
bool *val_; bool *val_;
public: public:
Flag(bool &val, const std::string &l, const std::string &s) : long_(l), short_(s), val_(&val) {} Flag(bool &val, const std::string &l, const std::string &s)
: long_(l), short_(s), val_(&val) {}
const std::string &long_str() const noexcept { return long_; } const std::string &long_str() const noexcept { return long_; }
const std::string &short_str() const noexcept { return short_; } const std::string &short_str() const noexcept { return short_; }
void set() const noexcept { *val_ = true; } void set() const noexcept { *val_ = true; }
void help(const std::string &s) { void help(const std::string &s) { help_ = s; }
help_ = s;
}
const std::string &help_str() const noexcept { const std::string &help_str() const noexcept { return help_; }
return help_;
}
}; };
class PosnlBase { class PosnlBase {
@@ -96,7 +90,7 @@ public:
set_val((T *)nullptr, val); set_val((T *)nullptr, val);
} }
bool found() override {return found_; } bool found() override { return found_; }
private: private:
// https://stackoverflow.com/questions/5512910/explicit-specialization-of-template-class-member-function // https://stackoverflow.com/questions/5512910/explicit-specialization-of-template-class-member-function
@@ -159,17 +153,18 @@ class Parser {
} }
public: public:
Parser() : noUnrecognized_(false), help_(false), consume_(true) { Parser() : noUnrecognized_(false), help_(false), consume_(true) {
add_flag(help_, "--help", "-h")->help("Print help message"); add_flag(help_, "--help", "-h")->help("Print help message");
} }
Parser(const std::string &description) : description_(description), noUnrecognized_(false), help_(false), consume_(true) { Parser(const std::string &description)
: description_(description), noUnrecognized_(false), help_(false),
consume_(true) {
add_flag(help_, "--help", "-h")->help("Print help message"); add_flag(help_, "--help", "-h")->help("Print help message");
} }
bool parse(int &argc, char ** argv) { bool parse(int &argc, char **argv) {
std::vector<char*> newArgv; std::vector<char *> newArgv;
if (argc > 0) { if (argc > 0) {
newArgv.push_back(argv[0]); newArgv.push_back(argv[0]);
} }
@@ -178,7 +173,6 @@ public:
bool optsOkay = true; // okay to interpret as opt/flag bool optsOkay = true; // okay to interpret as opt/flag
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
// try interpreting as a flag or option if it looks like one // try interpreting as a flag or option if it looks like one
if (optsOkay && starts_with(argv[i], "-")) { if (optsOkay && starts_with(argv[i], "-")) {
// '--' indicates only positional arguments follow // '--' indicates only positional arguments follow
@@ -208,8 +202,8 @@ public:
++pi; ++pi;
} else { } else {
newArgv.push_back(argv[i]); newArgv.push_back(argv[i]);
std::cerr << "encountered unexpected positional argument " << pi << ": " << argv[i] std::cerr << "encountered unexpected positional argument " << pi
<< "\n"; << ": " << argv[i] << "\n";
} }
} }
} }
@@ -228,7 +222,6 @@ public:
} }
} }
return true; return true;
}; };
@@ -266,17 +259,13 @@ public:
/*! \brief error on unrecognized flags and options /*! \brief error on unrecognized flags and options
*/ */
void no_unrecognized() { void no_unrecognized() { noUnrecognized_ = true; }
noUnrecognized_ = true;
}
/*! \brief don't modify argc/argv /*! \brief don't modify argc/argv
*/ */
void no_consume() { void no_consume() { consume_ = false; }
consume_ = false;
}
bool need_help() const noexcept { bool need_help() const noexcept { return help_; }
return help_;
}
}; };
} // namespace argparse

View File

@@ -15,7 +15,7 @@ TEST_CASE("argparse") {
}; };
int argc = sizeof(argv) / sizeof(argv[0]); int argc = sizeof(argv) / sizeof(argv[0]);
Parser p; argparse::Parser p;
bool campi = false; bool campi = false;
size_t x; size_t x;
@@ -45,7 +45,7 @@ TEST_CASE("argparse") {
SECTION("no args") { SECTION("no args") {
char *argv[] = {nullptr}; char *argv[] = {nullptr};
int argc = sizeof(argv) / sizeof(argv[0]); int argc = sizeof(argv) / sizeof(argv[0]);
Parser p; argparse::Parser p;
REQUIRE(p.parse(argc, argv)); REQUIRE(p.parse(argc, argv));
} }
@@ -56,7 +56,7 @@ TEST_CASE("argparse") {
}; };
int argc = sizeof(argv) / sizeof(argv[0]); int argc = sizeof(argv) / sizeof(argv[0]);
Parser p("a test program"); argparse::Parser p("a test program");
REQUIRE(p.parse(argc, argv)); REQUIRE(p.parse(argc, argv));
} }
@@ -64,7 +64,7 @@ TEST_CASE("argparse") {
char *argv[] = {"some-exe"}; char *argv[] = {"some-exe"};
int argc = sizeof(argv) / sizeof(argv[0]); int argc = sizeof(argv) / sizeof(argv[0]);
Parser p; argparse::Parser p;
p.no_unrecognized(); p.no_unrecognized();
REQUIRE(p.parse(argc, argv)); REQUIRE(p.parse(argc, argv));
} }
@@ -73,7 +73,7 @@ TEST_CASE("argparse") {
char *argv[] = {"some-exe", "-f"}; char *argv[] = {"some-exe", "-f"};
int argc = sizeof(argv) / sizeof(argv[0]); int argc = sizeof(argv) / sizeof(argv[0]);
Parser p; argparse::Parser p;
p.no_unrecognized(); p.no_unrecognized();
REQUIRE(false == p.parse(argc, argv)); REQUIRE(false == p.parse(argc, argv));
} }
@@ -85,7 +85,7 @@ TEST_CASE("argparse") {
std::string a; std::string a;
std::string b; std::string b;
Parser p; argparse::Parser p;
p.add_positional(a)->required(); p.add_positional(a)->required();
p.add_positional(b)->required(); p.add_positional(b)->required();
REQUIRE(false == p.parse(argc, argv)); REQUIRE(false == p.parse(argc, argv));
@@ -98,7 +98,7 @@ TEST_CASE("argparse") {
std::string a; std::string a;
std::string b; std::string b;
Parser p; argparse::Parser p;
REQUIRE(true == p.parse(argc, argv)); REQUIRE(true == p.parse(argc, argv));
REQUIRE(p.need_help()); REQUIRE(p.need_help());
@@ -112,7 +112,7 @@ TEST_CASE("argparse") {
std::string a; std::string a;
std::string b; std::string b;
Parser p; argparse::Parser p;
REQUIRE(true == p.parse(argc, argv)); REQUIRE(true == p.parse(argc, argv));
REQUIRE(p.need_help()); REQUIRE(p.need_help());
} }
@@ -124,7 +124,7 @@ TEST_CASE("argparse") {
std::string a; std::string a;
std::string b; std::string b;
Parser p; argparse::Parser p;
REQUIRE(true == p.parse(argc, argv)); REQUIRE(true == p.parse(argc, argv));
REQUIRE(p.need_help()); REQUIRE(p.need_help());
} }