mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into spdvpk
This commit is contained in:
commit
67514b60b6
|
@ -24,11 +24,13 @@
|
|||
#define ARANGODB_PROGRAM_OPTIONS_OPTION_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "ProgramOptions2/Parameters.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "ProgramOptions2/Parameters.h"
|
||||
|
||||
namespace arangodb {
|
||||
namespace options {
|
||||
|
||||
|
@ -57,6 +59,10 @@ struct Option {
|
|||
}
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const {
|
||||
parameter->toVPack(builder);
|
||||
}
|
||||
|
||||
// get display name for the option
|
||||
std::string displayName() const { return "--" + fullName(); }
|
||||
|
||||
|
@ -69,8 +75,9 @@ struct Option {
|
|||
}
|
||||
|
||||
// print help for an option
|
||||
void printHelp(size_t tw, size_t ow) const {
|
||||
if (!hidden) {
|
||||
// the special search string "." will show help for all sections, even if hidden
|
||||
void printHelp(std::string const& search, size_t tw, size_t ow) const {
|
||||
if (search == "." || !hidden) {
|
||||
std::cout << " " << pad(nameWithType(), ow) << " ";
|
||||
|
||||
std::string value = description;
|
||||
|
|
|
@ -25,6 +25,12 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include <numeric>
|
||||
#include <type_traits>
|
||||
|
||||
namespace arangodb {
|
||||
namespace options {
|
||||
|
||||
|
@ -33,7 +39,7 @@ template <typename T>
|
|||
typename std::enable_if<std::is_signed<T>::value, T>::type toNumber(
|
||||
std::string const& value) {
|
||||
auto v = static_cast<T>(std::stoll(value));
|
||||
if (v < std::numeric_limits<T>::min() || v > std::numeric_limits<T>::max()) {
|
||||
if (v < (std::numeric_limits<T>::min)() || v > (std::numeric_limits<T>::max)()) {
|
||||
throw std::out_of_range(value);
|
||||
}
|
||||
return static_cast<T>(v);
|
||||
|
@ -44,7 +50,7 @@ template <typename T>
|
|||
typename std::enable_if<std::is_unsigned<T>::value, T>::type toNumber(
|
||||
std::string const& value) {
|
||||
auto v = static_cast<T>(std::stoull(value));
|
||||
if (v < std::numeric_limits<T>::min() || v > std::numeric_limits<T>::max()) {
|
||||
if (v < (std::numeric_limits<T>::min)() || v > (std::numeric_limits<T>::max)()) {
|
||||
throw std::out_of_range(value);
|
||||
}
|
||||
return static_cast<T>(v);
|
||||
|
@ -56,6 +62,20 @@ double toNumber<double>(std::string const& value) {
|
|||
return std::stod(value);
|
||||
}
|
||||
|
||||
// convert a string into another type, specialized version for numbers
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_arithmetic<T>::value, T>::type fromString(
|
||||
std::string const& value) {
|
||||
return toNumber<T>(value);
|
||||
}
|
||||
|
||||
// convert a string into another type, specialized version for string -> string
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_same<T, std::string>::value, T>::type fromString(
|
||||
std::string const& value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// stringify a value, base version for any type
|
||||
template <typename T>
|
||||
inline std::string stringifyValue(T const& value) {
|
||||
|
@ -90,6 +110,8 @@ struct Parameter {
|
|||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
virtual void toVPack(VPackBuilder&) const = 0;
|
||||
};
|
||||
|
||||
// specialized type for boolean values
|
||||
|
@ -119,6 +141,10 @@ struct BooleanParameter : public Parameter {
|
|||
return "";
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.add(VPackValue(*ptr));
|
||||
}
|
||||
|
||||
ValueType* ptr;
|
||||
bool required;
|
||||
};
|
||||
|
@ -136,8 +162,8 @@ struct NumericParameter : public Parameter {
|
|||
std::string set(std::string const& value) override {
|
||||
try {
|
||||
ValueType v = toNumber<ValueType>(value);
|
||||
if (v >= std::numeric_limits<T>::min() &&
|
||||
v <= std::numeric_limits<T>::max()) {
|
||||
if (v >= (std::numeric_limits<T>::min)() &&
|
||||
v <= (std::numeric_limits<T>::max)()) {
|
||||
*ptr = v;
|
||||
return "";
|
||||
}
|
||||
|
@ -147,6 +173,10 @@ struct NumericParameter : public Parameter {
|
|||
return "number out of range";
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.add(VPackValue(*ptr));
|
||||
}
|
||||
|
||||
ValueType* ptr;
|
||||
};
|
||||
|
||||
|
@ -206,28 +236,28 @@ struct UInt64Parameter : public NumericParameter<uint64_t> {
|
|||
|
||||
template <typename T>
|
||||
struct BoundedParameter : public T {
|
||||
BoundedParameter(typename T::ValueType* ptr, typename T::ValueType min,
|
||||
typename T::ValueType max)
|
||||
: T(ptr), min(min), max(max) {}
|
||||
BoundedParameter(typename T::ValueType* ptr, typename T::ValueType minValue,
|
||||
typename T::ValueType maxValue)
|
||||
: T(ptr), minValue(minValue), maxValue(maxValue) {}
|
||||
|
||||
std::string set(std::string const& value) override {
|
||||
try {
|
||||
typename T::ValueType v = toNumber<typename T::ValueType>(value);
|
||||
if (v >= std::numeric_limits<typename T::ValueType>::min() &&
|
||||
v <= std::numeric_limits<typename T::ValueType>::max() && v >= min &&
|
||||
v <= max) {
|
||||
if (v >= (std::numeric_limits<typename T::ValueType>::min)() &&
|
||||
v <= (std::numeric_limits<typename T::ValueType>::max)() && v >= minValue &&
|
||||
v <= maxValue) {
|
||||
*this->ptr = v;
|
||||
return "";
|
||||
}
|
||||
} catch (...) {
|
||||
return "invalid numeric value";
|
||||
}
|
||||
return "number out of allowed range (" + std::to_string(min) + " - " +
|
||||
std::to_string(max) + ")";
|
||||
return "number out of allowed range (" + std::to_string(minValue) + " - " +
|
||||
std::to_string(maxValue) + ")";
|
||||
}
|
||||
|
||||
typename T::ValueType min;
|
||||
typename T::ValueType max;
|
||||
typename T::ValueType minValue;
|
||||
typename T::ValueType maxValue;
|
||||
};
|
||||
|
||||
// concrete double number value type
|
||||
|
@ -253,9 +283,33 @@ struct StringParameter : public Parameter {
|
|||
return "";
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.add(VPackValue(*ptr));
|
||||
}
|
||||
|
||||
ValueType* ptr;
|
||||
};
|
||||
|
||||
// specialized type for discrete values (defined in the unordered_set)
|
||||
// this templated type needs a concrete value type
|
||||
template <typename T>
|
||||
struct DiscreteValuesParameter : public T {
|
||||
DiscreteValuesParameter(typename T::ValueType* ptr,
|
||||
std::unordered_set<typename T::ValueType> const& allowed)
|
||||
: T(ptr), allowed(allowed) {}
|
||||
|
||||
std::string set(std::string const& value) override {
|
||||
auto it = allowed.find(fromString<typename T::ValueType>(value));
|
||||
|
||||
if (it == allowed.end()) {
|
||||
return "invalid value " + value;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::unordered_set<typename T::ValueType> allowed;
|
||||
};
|
||||
|
||||
// specialized type for vectors of values
|
||||
// this templated type needs a concrete value type
|
||||
template <typename T>
|
||||
|
@ -290,6 +344,13 @@ struct VectorParameter : public Parameter {
|
|||
return result;
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.openArray();
|
||||
for (size_t i = 0; i < ptr->size(); ++i) {
|
||||
builder.add(VPackValue(ptr->at(i)));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<typename T::ValueType>* ptr;
|
||||
};
|
||||
|
||||
|
@ -299,6 +360,9 @@ struct ObsoleteParameter : public Parameter {
|
|||
std::string name() const override { return "obsolete"; }
|
||||
std::string valueString() const override { return "-"; }
|
||||
std::string set(std::string const&) override { return ""; }
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.add(VPackValue(VPackValueType::Null));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@
|
|||
#include "ProgramOptions2/Option.h"
|
||||
#include "ProgramOptions2/Section.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#define ARANGODB_PROGRAM_OPTIONS_PROGNAME "#progname#"
|
||||
|
||||
namespace arangodb {
|
||||
|
@ -149,20 +154,24 @@ class ProgramOptions {
|
|||
// prints usage information
|
||||
void printUsage() const { std::cout << _usage << std::endl << std::endl; }
|
||||
|
||||
// prints a help for all options
|
||||
void printHelp(std::string const& section) const {
|
||||
// prints a help for all options, or the options of a section
|
||||
// the special search string "*" will show help for all sections
|
||||
// the special search string "." will show help for all sections, even if hidden
|
||||
void printHelp(std::string const& search) const {
|
||||
printUsage();
|
||||
|
||||
size_t const tw = _terminalWidth();
|
||||
size_t const ow = optionsWidth();
|
||||
|
||||
for (auto const& it : _sections) {
|
||||
if (section == "*" || section == it.second.name) {
|
||||
it.second.printHelp(tw, ow);
|
||||
if (search == "*" || search == "." || search == it.second.name) {
|
||||
it.second.printHelp(search, tw, ow);
|
||||
}
|
||||
}
|
||||
|
||||
printSectionsHelp();
|
||||
if (search == "*") {
|
||||
printSectionsHelp();
|
||||
}
|
||||
}
|
||||
|
||||
// prints the names for all section help options
|
||||
|
@ -177,6 +186,28 @@ class ProgramOptions {
|
|||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
// returns a VPack representation of the option values
|
||||
VPackBuilder toVPack(bool onlyTouched, std::unordered_set<std::string> const& exclude) const {
|
||||
VPackBuilder builder;
|
||||
builder.openObject();
|
||||
|
||||
walk([&builder, &exclude](Section const&, Option const& option) {
|
||||
std::string full(option.fullName());
|
||||
if (exclude.find(full) != exclude.end()) {
|
||||
// excluded option
|
||||
return;
|
||||
}
|
||||
|
||||
// add key
|
||||
builder.add(VPackValue(full));
|
||||
// add value
|
||||
option.toVPack(builder);
|
||||
}, onlyTouched);
|
||||
|
||||
builder.close();
|
||||
return builder;
|
||||
}
|
||||
|
||||
// translate a shorthand option
|
||||
std::string translateShorthand(std::string const& name) const {
|
||||
auto it = _shorthands.find(name);
|
||||
|
@ -188,7 +219,7 @@ class ProgramOptions {
|
|||
}
|
||||
|
||||
void walk(std::function<void(Section const&, Option const&)> const& callback,
|
||||
bool onlyTouched) {
|
||||
bool onlyTouched) const {
|
||||
for (auto const& it : _sections) {
|
||||
if (it.second.obsolete) {
|
||||
// obsolete section. ignore it
|
||||
|
|
|
@ -61,8 +61,9 @@ struct Section {
|
|||
}
|
||||
|
||||
// print help for a section
|
||||
void printHelp(size_t tw, size_t ow) const {
|
||||
if (hidden || !hasOptions()) {
|
||||
// the special search string "." will show help for all sections, even if hidden
|
||||
void printHelp(std::string const& search, size_t tw, size_t ow) const {
|
||||
if (search != "." && (hidden || !hasOptions())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -71,7 +72,7 @@ struct Section {
|
|||
|
||||
// propagate print command to options
|
||||
for (auto const& it : options) {
|
||||
it.second.printHelp(tw, ow);
|
||||
it.second.printHelp(search, tw, ow);
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
|
Loading…
Reference in New Issue