Merge branch 'master' of github.com:p-ranav/argparse

This commit is contained in:
Pranav Srinivas Kumar 2019-08-17 16:57:15 -05:00
commit 8df0a878ac
5 changed files with 110 additions and 5 deletions

31
.travis.yml Normal file
View File

@ -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

View File

@ -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

View File

@ -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;
@ -152,19 +157,29 @@ 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 {
// 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());
}
}
@ -179,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<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;
}
@ -298,6 +317,7 @@ public:
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:

View File

@ -10,3 +10,4 @@
#include <test_parent_parsers.hpp>
#include <test_invalid_arguments.hpp>
#include <test_negative_numbers.hpp>
#include <test_required_arguments.hpp>

View File

@ -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");
}