From 895969a4f6ed6fd7290146c3d078773f6d136944 Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Sun, 16 Jun 2019 16:24:53 -0400 Subject: [PATCH 01/11] Create .travis.yml --- .travis.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..a5110b9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,22 @@ +sudo: false +language: cpp +compiler: + - gcc + - clang +addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-5.0 + packages: + - g++-7 + - clang-5.0 +env: +- CXXFLAGS="-std=c++17" +install: +- "[ $CXX = g++ ] && export CXX=g++-7 || true" +- "[ $CXX = clang++ ] && export CXX=clang++-5.0 || true" +script: + - mkdir build && cd build + - cmake ../. + - make && make check From 811d1edc8b223784c748bd20556f06da49781746 Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Sun, 16 Jun 2019 16:28:53 -0400 Subject: [PATCH 02/11] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a5110b9..7ddb21d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ install: - "[ $CXX = g++ ] && export CXX=g++-7 || true" - "[ $CXX = clang++ ] && export CXX=clang++-5.0 || true" script: + - cd test - mkdir build && cd build - cmake ../. - make && make check From f9eb9779d697ad185cae27e2e4d0f505834b682f Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Sun, 16 Jun 2019 16:31:02 -0400 Subject: [PATCH 03/11] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7ddb21d..3090a07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,4 +20,4 @@ script: - cd test - mkdir build && cd build - cmake ../. - - make && make check + - make && ./tests From a2bd79892070bc8a5f04cee4a68a0e918e241d84 Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Sun, 16 Jun 2019 16:36:05 -0400 Subject: [PATCH 04/11] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index af3ebba..f6958ba 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,14 @@ pprint

+

+ travis + + license + + version +

+ ## Highlights * Single header file From a91b11d2031445cb997a920204e054b66fcd2bf2 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Sun, 4 Aug 2019 23:25:19 -0500 Subject: [PATCH 05/11] Use OSX CI and Windows to test other toolchains --- .travis.yml | 50 +++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3090a07..4f98d23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,23 +1,31 @@ -sudo: false -language: cpp -compiler: - - gcc - - clang -addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-5.0 - packages: - - g++-7 - - clang-5.0 -env: -- CXXFLAGS="-std=c++17" +matrix: + include: + - os: linux + dist: bionic + language: cpp + compiler: gcc + - os: osx + osx_image: xcode10.2 + language: cpp + compiler: clang + - os: windows + language: bash + env: CXX=cl.exe install: -- "[ $CXX = g++ ] && export CXX=g++-7 || true" -- "[ $CXX = clang++ ] && export CXX=clang++-5.0 || true" + - | + if [[ $TRAVIS_OS_NAME == 'windows' ]]; then + choco install ninja cmake + elif [[ $TRAVIS_OS_NAME == 'osx' ]]; then + export PATH=~/Library/Python/3.7/bin:$PATH + pip3 install --user ninja cmake + else + pip install --user ninja cmake + fi script: - - cd test - - mkdir build && cd build - - cmake ../. - - make && ./tests + - | + if [[ $TRAVIS_OS_NAME == 'windows' ]]; then + cmd.exe /C '"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64 && cmake -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DARGPARSE_BUILD_TESTS=ON && ninja -C build' + else + cmake -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DARGPARSE_BUILD_TESTS=ON && ninja -C build + fi + - ./build/test/tests From 7cb710f404af94b268d03342c543ce6397edbfb5 Mon Sep 17 00:00:00 2001 From: Mio Date: Tue, 6 Aug 2019 20:41:24 +0800 Subject: [PATCH 06/11] Remove extra new lines --- include/argparse.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index 7411918..476286d 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -152,8 +152,8 @@ public: if (mIsOptional) { if (mIsUsed && mValues.size() != mNumArgs && !mDefaultValue.has_value()) { std::stringstream stream; - stream << "error: " << mUsedName << ": expected " << mNumArgs << " argument(s). " - << mValues.size() << " provided.\n" << std::endl; + stream << "error: " << mUsedName << ": expected " << mNumArgs << " argument(s). " + << mValues.size() << " provided."; throw std::runtime_error(stream.str()); } else { @@ -163,8 +163,8 @@ public: else { if (mValues.size() != mNumArgs && !mDefaultValue.has_value()) { std::stringstream stream; - stream << "error: " << mUsedName << ": expected " << mNumArgs << " argument(s). " - << mValues.size() << " provided.\n" << std::endl; + stream << "error: " << mUsedName << ": expected " << mNumArgs << " argument(s). " + << mValues.size() << " provided."; throw std::runtime_error(stream.str()); } } From 39c720e6c094b959f6916ed5ea2b465a041f12c0 Mon Sep 17 00:00:00 2001 From: Mio Date: Tue, 6 Aug 2019 20:48:51 +0800 Subject: [PATCH 07/11] Add a mIsRquired field --- include/argparse.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/argparse.hpp b/include/argparse.hpp index 7411918..96e453d 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -102,6 +102,11 @@ public: return *this; } + Argument& required() { + mIsRequired = true; + return *this; + } + Argument& implicit_value(std::any aImplicitValue) { mImplicitValue = std::move(aImplicitValue); mNumArgs = 0; @@ -158,6 +163,16 @@ public: } else { // TODO: check if an implicit value was programmed for this argument + if (!mIsUsed && !mDefaultValue.has_value() && mIsRequired) { + std::stringstream stream; + stream << "error: " << mNames[0] << ": required."; + throw std::runtime_error(stream.str()); + } + if (mIsUsed && mIsRequired && mValues.size() == 0) { + std::stringstream stream; + stream << "error: " << mUsedName << ": no value provided."; + throw std::runtime_error(stream.str()); + } } } else { @@ -298,6 +313,7 @@ public: std::vector mRawValues; size_t mNumArgs = 1; bool mIsOptional = false; + bool mIsRequired = false; bool mIsUsed = false; // relevant for optional arguments. True if used by user public: From 47122880860507d0433482e2d3ae34d1a3d243db Mon Sep 17 00:00:00 2001 From: Mio Date: Tue, 6 Aug 2019 20:52:31 +0800 Subject: [PATCH 08/11] Change the format of required arguments --- include/argparse.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index 96e453d..bece74c 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -194,7 +194,11 @@ public: friend std::ostream& operator<<(std::ostream& stream, const Argument& argument) { std::stringstream nameStream; std::copy(std::begin(argument.mNames), std::end(argument.mNames), std::ostream_iterator(nameStream, " ")); - return stream << nameStream.str() << "\t" << argument.mHelp << "\n"; + stream << nameStream.str() << "\t" << argument.mHelp; + if (argument.mIsRequired) + stream << "[Required]"; + stream << "\n"; + return stream; } From 34165a8ed78e752eeb0798ec89c136cf0451ce40 Mon Sep 17 00:00:00 2001 From: Mio Date: Wed, 7 Aug 2019 19:53:35 +0800 Subject: [PATCH 09/11] Add corresponding tests for required arguments --- test/test_required_arguments.hpp | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 test/test_required_arguments.hpp diff --git a/test/test_required_arguments.hpp b/test/test_required_arguments.hpp new file mode 100644 index 0000000..ffb45a9 --- /dev/null +++ b/test/test_required_arguments.hpp @@ -0,0 +1,45 @@ +#pragma once +#include +#include + +TEST_CASE("Parse required arguments which is not set and doesn't have default value.", "[required_arguments]") { + argparse::ArgumentParser program("test"); + program.add_argument("--output", "-o").required(); + REQUIRE_THROWS(program.parse_args({ "./main" })); +} + +TEST_CASE("Parse required arguments without default value which is set as empty value and doesn't have default value.", "[required_arguments]") { + argparse::ArgumentParser program("test"); + program.add_argument("--output", "-o").required(); + REQUIRE_THROWS(program.parse_args({ "./main", "-o" })); +} + +TEST_CASE("Parse required arguments without default value which is set as some value and doesn't have default value.", "[required_arguments]") { + argparse::ArgumentParser program("test"); + program.add_argument("--output", "-o").required(); + program.parse_args({ "./main", "-o", "filename" }); + REQUIRE(program.get("--output") == "filename"); + REQUIRE(program.get("-o") == "filename"); +} + +TEST_CASE("Parse required arguments which is not set and has default value.", "[required_arguments]") { + argparse::ArgumentParser program("test"); + program.add_argument("--output", "-o").required().default_value(std::string("filename")); + program.parse_args({ "./main" }); + REQUIRE(program.get("--output") == "filename"); + REQUIRE(program.get("-o") == "filename"); +} + +TEST_CASE("Parse required arguments without default value which is set as empty and has default value.", "[required_arguments]") { + argparse::ArgumentParser program("test"); + program.add_argument("--output", "-o").required().default_value(std::string("filename")); + REQUIRE_THROWS(program.parse_args({ "./main", "-o" })); +} + +TEST_CASE("Parse required arguments without default value which is set as some value and has default value.", "[required_arguments]") { + argparse::ArgumentParser program("test"); + program.add_argument("--output", "-o").required().default_value(std::string("filename")); + program.parse_args({ "./main", "-o", "anotherfile" }); + REQUIRE(program.get("--output") == "anotherfile"); + REQUIRE(program.get("-o") == "anotherfile"); +} \ No newline at end of file From 466e3aa37c08bc2416440d464e93d78a5fd7d45a Mon Sep 17 00:00:00 2001 From: Mio Date: Wed, 7 Aug 2019 19:58:25 +0800 Subject: [PATCH 10/11] Include new tests --- test/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/main.cpp b/test/main.cpp index 2885d40..8d9aa37 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -10,3 +10,4 @@ #include #include #include +#include \ No newline at end of file From 3c7fcad1465e5c250631488c5071e448632349ab Mon Sep 17 00:00:00 2001 From: Mio Date: Wed, 7 Aug 2019 19:58:32 +0800 Subject: [PATCH 11/11] Fix typo --- test/test_required_arguments.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test_required_arguments.hpp b/test/test_required_arguments.hpp index ffb45a9..f9ac26e 100644 --- a/test/test_required_arguments.hpp +++ b/test/test_required_arguments.hpp @@ -2,19 +2,19 @@ #include #include -TEST_CASE("Parse required arguments which is not set and doesn't have default value.", "[required_arguments]") { +TEST_CASE("Parse required arguments which are not set and don't have default value.", "[required_arguments]") { argparse::ArgumentParser program("test"); program.add_argument("--output", "-o").required(); REQUIRE_THROWS(program.parse_args({ "./main" })); } -TEST_CASE("Parse required arguments without default value which is set as empty value and doesn't have default value.", "[required_arguments]") { +TEST_CASE("Parse required arguments which are set as empty value and don't have default value.", "[required_arguments]") { argparse::ArgumentParser program("test"); program.add_argument("--output", "-o").required(); REQUIRE_THROWS(program.parse_args({ "./main", "-o" })); } -TEST_CASE("Parse required arguments without default value which is set as some value and doesn't have default value.", "[required_arguments]") { +TEST_CASE("Parse required arguments which are set as some value and don't have default value.", "[required_arguments]") { argparse::ArgumentParser program("test"); program.add_argument("--output", "-o").required(); program.parse_args({ "./main", "-o", "filename" }); @@ -22,7 +22,7 @@ TEST_CASE("Parse required arguments without default value which is set as some v REQUIRE(program.get("-o") == "filename"); } -TEST_CASE("Parse required arguments which is not set and has default value.", "[required_arguments]") { +TEST_CASE("Parse required arguments which are not set and have default value.", "[required_arguments]") { argparse::ArgumentParser program("test"); program.add_argument("--output", "-o").required().default_value(std::string("filename")); program.parse_args({ "./main" }); @@ -30,13 +30,13 @@ TEST_CASE("Parse required arguments which is not set and has default value.", "[ REQUIRE(program.get("-o") == "filename"); } -TEST_CASE("Parse required arguments without default value which is set as empty and has default value.", "[required_arguments]") { +TEST_CASE("Parse required arguments which are set as empty and have default value.", "[required_arguments]") { argparse::ArgumentParser program("test"); program.add_argument("--output", "-o").required().default_value(std::string("filename")); REQUIRE_THROWS(program.parse_args({ "./main", "-o" })); } -TEST_CASE("Parse required arguments without default value which is set as some value and has default value.", "[required_arguments]") { +TEST_CASE("Parse required arguments which are set as some value and have default value.", "[required_arguments]") { argparse::ArgumentParser program("test"); program.add_argument("--output", "-o").required().default_value(std::string("filename")); program.parse_args({ "./main", "-o", "anotherfile" });