mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-05-01 05:03:52 +00:00
Added file validator functions, not used yet
This commit is contained in:
parent
b5ea5ce065
commit
fb16cb93fd
@ -14,6 +14,12 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
|
// C standard library
|
||||||
|
// Only needed for existence checking
|
||||||
|
// Could be swapped for filesystem in C++17
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
//#define CLI_LOG 1
|
//#define CLI_LOG 1
|
||||||
|
|
||||||
namespace CLI {
|
namespace CLI {
|
||||||
@ -61,6 +67,7 @@ struct Combiner {
|
|||||||
bool positional;
|
bool positional;
|
||||||
bool required;
|
bool required;
|
||||||
bool defaulted;
|
bool defaulted;
|
||||||
|
std::vector<std::function<bool(std::string)>> validators;
|
||||||
|
|
||||||
/// Can be or-ed together
|
/// Can be or-ed together
|
||||||
Combiner operator | (Combiner b) const {
|
Combiner operator | (Combiner b) const {
|
||||||
@ -69,18 +76,49 @@ struct Combiner {
|
|||||||
self.positional = positional || b.positional;
|
self.positional = positional || b.positional;
|
||||||
self.required = required || b.required;
|
self.required = required || b.required;
|
||||||
self.defaulted = defaulted || b.defaulted;
|
self.defaulted = defaulted || b.defaulted;
|
||||||
|
self.validators.reserve(validators.size() + b.validators.size());
|
||||||
|
self.validators.insert(self.validators.end(), validators.begin(), validators.end());
|
||||||
|
self.validators.insert(self.validators.end(), b.validators.begin(), b.validators.end());
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call to give the number of arguments expected on cli
|
/// Call to give the number of arguments expected on cli
|
||||||
Combiner operator() (int n) const {
|
Combiner operator() (int n) const {
|
||||||
return Combiner{n, positional, required, defaulted};
|
Combiner self = *this;
|
||||||
|
self.num = n;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/// Call to give a validator
|
||||||
|
Combiner operator() (std::function<bool(std::string)> func) const {
|
||||||
|
Combiner self = *this;
|
||||||
|
self.validators.push_back(func);
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
Combiner operator, (Combiner b) const {
|
Combiner operator, (Combiner b) const {
|
||||||
return *this | b;
|
return *this | b;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool _ExistingFile(std::string filename) {
|
||||||
|
// std::fstream f(name.c_str());
|
||||||
|
// return f.good();
|
||||||
|
// Fastest way according to http://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c
|
||||||
|
struct stat buffer;
|
||||||
|
return (stat(filename.c_str(), &buffer) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _ExistingDirectory(std::string filename) {
|
||||||
|
struct stat buffer;
|
||||||
|
if(stat(filename.c_str(), &buffer) == 0 && (buffer.st_mode & S_IFDIR) )
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _NonexistentPath(std::string filename) {
|
||||||
|
struct stat buffer;
|
||||||
|
return stat(filename.c_str(), &buffer) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct Error : public std::runtime_error {
|
struct Error : public std::runtime_error {
|
||||||
Error(std::string parent, std::string name) : runtime_error(parent + ": " + name) {}
|
Error(std::string parent, std::string name) : runtime_error(parent + ": " + name) {}
|
||||||
};
|
};
|
||||||
@ -137,12 +175,20 @@ std::tuple<std::string, std::string> split(std::string fullname) {
|
|||||||
} else throw BadNameString(fullname);
|
} else throw BadNameString(fullname);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Combiner NOTHING {0, false,false,false};
|
const Combiner NOTHING {0, false,false,false, {}};
|
||||||
const Combiner REQUIRED {1, false,true, false};
|
const Combiner REQUIRED {1, false,true, false, {}};
|
||||||
const Combiner DEFAULT {1, false,false,true};
|
const Combiner DEFAULT {1, false,false,true, {}};
|
||||||
const Combiner POSITIONAL{1, true, false,false};
|
const Combiner POSITIONAL {1, true, false,false, {}};
|
||||||
const Combiner ARGS {1, false,false,false};
|
const Combiner ARGS {1, false,false,false, {}};
|
||||||
const Combiner UNLIMITED {-1,false,false,false};
|
const Combiner UNLIMITED {-1,false,false,false, {}};
|
||||||
|
const Combiner VALIDATORS {1, false, false, false, {}};
|
||||||
|
|
||||||
|
// Warning about using these validators:
|
||||||
|
// The files could be added/deleted after the validation. This is not common,
|
||||||
|
// but if this is a possibility, check the file you open afterwards
|
||||||
|
const Combiner ExistingFile {1, false, false, false, {_ExistingFile}};
|
||||||
|
const Combiner ExistingDirectory {1, false, false, false, {_ExistingDirectory}};
|
||||||
|
const Combiner NonexistentPath {1, false, false, false, {_NonexistentPath}};
|
||||||
|
|
||||||
typedef std::vector<std::vector<std::string>> results_t;
|
typedef std::vector<std::vector<std::string>> results_t;
|
||||||
typedef std::function<bool(results_t)> callback_t;
|
typedef std::function<bool(results_t)> callback_t;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "CLI.hpp"
|
#include "CLI.hpp"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
TEST(Split, GoodStrings) {
|
TEST(Split, GoodStrings) {
|
||||||
@ -41,3 +43,25 @@ TEST(Split, BadStrings) {
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Validators, FileExists) {
|
||||||
|
std::string myfile{"TestFileNotUsed.txt"};
|
||||||
|
EXPECT_FALSE(CLI::_ExistingFile(myfile));
|
||||||
|
bool ok = static_cast<bool>(std::ofstream(myfile.c_str()).put('a')); // create file
|
||||||
|
EXPECT_TRUE(ok);
|
||||||
|
EXPECT_TRUE(CLI::_ExistingFile(myfile));
|
||||||
|
|
||||||
|
std::remove(myfile.c_str());
|
||||||
|
EXPECT_FALSE(CLI::_ExistingFile(myfile));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Validators, FileNotExists) {
|
||||||
|
std::string myfile{"TestFileNotUsed.txt"};
|
||||||
|
EXPECT_TRUE(CLI::_NonexistentPath(myfile));
|
||||||
|
bool ok = static_cast<bool>(std::ofstream(myfile.c_str()).put('a')); // create file
|
||||||
|
EXPECT_TRUE(ok);
|
||||||
|
EXPECT_FALSE(CLI::_NonexistentPath(myfile));
|
||||||
|
|
||||||
|
std::remove(myfile.c_str());
|
||||||
|
EXPECT_TRUE(CLI::_NonexistentPath(myfile));
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user