Skip to content

Commit

Permalink
Merge branch 'master' of github.com:p-ranav/argparse
Browse files Browse the repository at this point in the history
  • Loading branch information
p-ranav committed Aug 17, 2019
2 parents e40d9d5 + 272b19b commit 8df0a87
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 5 deletions.
31 changes: 31 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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:
- |
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:
- |
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
<img height="100" src="https://i.imgur.com/oDXeMUQ.png" alt="pprint"/>
</p>

<p align="center">
<img src="https://travis-ci.org/p-ranav/argparse.svg?branch=master" alt="travis"/>
<a href="https://github.com/p-ranav/argparse/blob/master/LICENSE">
<img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="license"/>
</a>
<img src="https://img.shields.io/badge/version-1.8-blue.svg?cacheSeconds=2592000" alt="version"/>
</p>

## Highlights

* Single header file
Expand Down
30 changes: 25 additions & 5 deletions include/argparse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ class Argument {
return *this;
}

Argument& required() {
mIsRequired = true;
return *this;
}

Argument& implicit_value(std::any aImplicitValue) {
mImplicitValue = std::move(aImplicitValue);
mNumArgs = 0;
Expand Down Expand Up @@ -152,19 +157,29 @@ class Argument {
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 {
// 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 {
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());
}
}
Expand All @@ -179,7 +194,11 @@ class Argument {
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<std::string>(nameStream, " "));
return stream << nameStream.str() << "\t" << argument.mHelp << "\n";
stream << nameStream.str() << "\t" << argument.mHelp;
if (argument.mIsRequired)
stream << "[Required]";
stream << "\n";
return stream;
}


Expand Down Expand Up @@ -298,6 +317,7 @@ class Argument {
std::vector<std::string> mRawValues;
size_t mNumArgs = 1;
bool mIsOptional = false;
bool mIsRequired = false;
bool mIsUsed = false; // relevant for optional arguments. True if used by user

public:
Expand Down
1 change: 1 addition & 0 deletions test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
#include <test_parent_parsers.hpp>
#include <test_invalid_arguments.hpp>
#include <test_negative_numbers.hpp>
#include <test_required_arguments.hpp>
45 changes: 45 additions & 0 deletions test/test_required_arguments.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once
#include <catch.hpp>
#include <argparse.hpp>

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 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 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" });
REQUIRE(program.get("--output") == "filename");
REQUIRE(program.get("-o") == "filename");
}

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" });
REQUIRE(program.get("--output") == "filename");
REQUIRE(program.get("-o") == "filename");
}

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 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" });
REQUIRE(program.get("--output") == "anotherfile");
REQUIRE(program.get("-o") == "anotherfile");
}

0 comments on commit 8df0a87

Please sign in to comment.