1
0
Fork 0
This commit is contained in:
Jan 2019-01-22 14:06:17 +01:00 committed by GitHub
parent 36cfec1cce
commit 5502ed2a3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 102 deletions

View File

@ -1219,10 +1219,10 @@ void RestoreFeature::validateOptions(std::shared_ptr<options::ProgramOptions> op
for (auto& it : _options.numberOfShards) {
auto parts = basics::StringUtils::split(it, '=');
if (parts.size() == 1 && basics::StringUtils::uint64(parts[0]) > 0) {
if (parts.size() == 1 && basics::StringUtils::int64(parts[0]) > 0) {
// valid
continue;
} else if (parts.size() == 2 && basics::StringUtils::uint64(parts[1]) > 0) {
} else if (parts.size() == 2 && basics::StringUtils::int64(parts[1]) > 0) {
// valid
continue;
}
@ -1235,12 +1235,12 @@ void RestoreFeature::validateOptions(std::shared_ptr<options::ProgramOptions> op
for (auto& it : _options.replicationFactor) {
auto parts = basics::StringUtils::split(it, '=');
if (parts.size() == 1) {
if (parts[0] == "satellite" || basics::StringUtils::uint64(parts[0]) > 0) {
if (parts[0] == "satellite" || basics::StringUtils::int64(parts[0]) > 0) {
// valid
continue;
}
} else if (parts.size() == 2) {
if (parts[1] == "satellite" || basics::StringUtils::uint64(parts[1]) > 0) {
if (parts[1] == "satellite" || basics::StringUtils::int64(parts[1]) > 0) {
// valid
continue;
}

View File

@ -25,6 +25,7 @@
#include "Basics/Common.h"
#include "Basics/Exceptions.h"
#include "Basics/NumberUtils.h"
#include "Basics/fpconv.h"
#include <velocypack/Builder.h>
@ -38,10 +39,9 @@
namespace arangodb {
namespace options {
// convert a string into a number, base version for signed integer types
// convert a string into a number, base version for signed or unsigned integer types
template <typename T>
inline typename std::enable_if<std::is_signed<T>::value, T>::type toNumber(std::string value,
T base) {
inline T toNumber(std::string value, T base) {
auto n = value.size();
int64_t m = 1;
int64_t d = 1;
@ -93,82 +93,22 @@ inline typename std::enable_if<std::is_signed<T>::value, T>::type toNumber(std::
m = 1000 * 1000 * 1000;
value = value.substr(0, n - 1);
} else if (suffix == "%") {
m = static_cast<int64_t>(base);
m = static_cast<T>(base);
d = 100;
value = value.substr(0, n - 1);
}
}
auto v = static_cast<int64_t>(std::stoll(value));
if (v < static_cast<int64_t>((std::numeric_limits<T>::min)()) ||
v > static_cast<int64_t>((std::numeric_limits<T>::max)())) {
throw std::out_of_range(value);
char const* p = value.data();
char const* e = p + value.size();
// skip leading whitespace
while (p < e && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) {
++p;
}
return static_cast<T>(v * m / d);
}
// convert a string into a number, base version for unsigned integer types
template <typename T>
inline typename std::enable_if<std::is_unsigned<T>::value, T>::type toNumber(std::string value,
T base) {
auto n = value.size();
uint64_t m = 1;
uint64_t d = 1;
bool seen = false;
if (n > 3) {
std::string suffix = value.substr(n - 3);
if (suffix == "kib" || suffix == "KiB") {
m = 1024;
value = value.substr(0, n - 2);
seen = true;
} else if (suffix == "mib" || suffix == "MiB") {
m = 1024 * 1024;
value = value.substr(0, n - 2);
seen = true;
} else if (suffix == "gib" || suffix == "GiB") {
m = 1024 * 1024 * 1024;
value = value.substr(0, n - 2);
seen = true;
}
}
if (!seen && n > 2) {
std::string suffix = value.substr(n - 2);
if (suffix == "kb" || suffix == "KB") {
m = 1000;
value = value.substr(0, n - 2);
seen = true;
} else if (suffix == "mb" || suffix == "MB") {
m = 1000 * 1000;
value = value.substr(0, n - 2);
seen = true;
} else if (suffix == "gb" || suffix == "GB") {
m = 1000 * 1000 * 1000;
value = value.substr(0, n - 2);
seen = true;
}
}
if (!seen && n > 1) {
std::string suffix = value.substr(n - 1);
if (suffix == "k" || suffix == "K") {
m = 1000;
value = value.substr(0, n - 1);
} else if (suffix == "m" || suffix == "M") {
m = 1000 * 1000;
value = value.substr(0, n - 1);
} else if (suffix == "g" || suffix == "G") {
m = 1000 * 1000 * 1000;
value = value.substr(0, n - 1);
} else if (suffix == "%") {
m = static_cast<uint64_t>(base);
d = 100;
value = value.substr(0, n - 1);
}
}
auto v = static_cast<uint64_t>(std::stoull(value));
if (v < static_cast<uint64_t>((std::numeric_limits<T>::min)()) ||
v > static_cast<uint64_t>((std::numeric_limits<T>::max)())) {
bool valid = true;
auto v = arangodb::NumberUtils::atoi<T>(p, e, valid);
if (!valid) {
throw std::out_of_range(value);
}
return static_cast<T>(v * m / d);
@ -260,7 +200,7 @@ struct BooleanParameter : public Parameter {
(value == "true" || value == "on" || value == "1" || value == "yes");
return "";
}
return "invalid value. expecting 'true' or 'false'";
return "invalid value for type " + this->name() + ". expecting 'true' or 'false'";
}
std::string typeDescription() const override {
@ -300,7 +240,7 @@ struct AtomicBooleanParameter : public Parameter {
ptr->store(value == "true" || value == "on" || value == "1");
return "";
}
return "invalid value. expecting 'true' or 'false'";
return "invalid value for type " + this->name() + ". expecting 'true' or 'false'";
}
std::string typeDescription() const override {
@ -332,7 +272,7 @@ struct NumericParameter : public Parameter {
*ptr = v;
return "";
} catch (...) {
return "invalid numeric value '" + value + "'";
return "invalid numeric value '" + value + "' for type " + this->name();
}
}
@ -425,7 +365,7 @@ struct BoundedParameter : public T {
return "";
}
} catch (...) {
return "invalid numeric value '" + value + "'";
return "invalid numeric value '" + value + "' for type " + this->name();
}
return "number '" + value + "' out of allowed range (" +
std::to_string(minValue) + " - " + std::to_string(maxValue) + ")";

View File

@ -97,14 +97,12 @@ void ProgramOptions::printHelp(std::string const& search) const {
// prints the names for all section help options
void ProgramOptions::printSectionsHelp() const {
char const* colorStart;
char const* colorEnd;
char const* colorStart = "";
char const* colorEnd = "";
if (isatty(STDOUT_FILENO)) {
colorStart = ShellColorsFeature::SHELL_COLOR_BRIGHT;
colorEnd = ShellColorsFeature::SHELL_COLOR_RESET;
} else {
colorStart = colorEnd = "";
}
// print names of sections
@ -275,7 +273,16 @@ bool ProgramOptions::setValue(std::string const& name, std::string const& value)
if (!result.empty()) {
// parameter validation failed
return fail("error setting value for option '--" + name + "': " + result);
char const* colorStart1 = "";
char const* colorStart2 = "";
char const* colorEnd = "";
if (isatty(STDERR_FILENO)) {
colorStart1 = ShellColorsFeature::SHELL_COLOR_RED;
colorStart2 = ShellColorsFeature::SHELL_COLOR_BOLD_RED;
colorEnd = ShellColorsFeature::SHELL_COLOR_RESET;
}
return fail(std::string("error setting value for option '") + colorStart2 + "--" + name + colorEnd + "': " + colorStart1 + result + colorEnd);
}
_processingResult.touch(name);
@ -355,18 +362,19 @@ std::string ProgramOptions::getDescription(std::string const& name) {
// handle an unknown option
bool ProgramOptions::unknownOption(std::string const& name) {
char const* colorStart;
char const* colorEnd;
char const* colorStart1 = "";
char const* colorStart2 = "";
char const* colorStart3 = "";
char const* colorEnd = "";
if (isatty(STDERR_FILENO)) {
colorStart = ShellColorsFeature::SHELL_COLOR_BRIGHT;
colorStart1 = ShellColorsFeature::SHELL_COLOR_RED;
colorStart2 = ShellColorsFeature::SHELL_COLOR_BOLD_RED;
colorStart3 = ShellColorsFeature::SHELL_COLOR_BRIGHT;
colorEnd = ShellColorsFeature::SHELL_COLOR_RESET;
} else {
colorStart = colorEnd = "";
}
fail(std::string("unknown option '") + colorStart + "--" + name + colorEnd +
"'");
fail(std::string(colorStart1) + "unknown option '" + colorStart2 + "--" + name + colorStart1 + "'" + colorEnd);
auto similarOptions = similar(name, 8, 4);
if (!similarOptions.empty()) {
@ -382,7 +390,7 @@ bool ProgramOptions::unknownOption(std::string const& name) {
}
for (auto const& it : similarOptions) {
std::cerr << " " << colorStart << Option::pad(it, maxWidth) << colorEnd
std::cerr << " " << colorStart3 << Option::pad(it, maxWidth) << colorEnd
<< " " << getDescription(it) << std::endl;
}
std::cerr << std::endl;
@ -393,12 +401,12 @@ bool ProgramOptions::unknownOption(std::string const& name) {
// a now removed or renamed option was specified...
auto& now = (*it).second;
if (now.empty()) {
std::cerr << "Please note that the specified option '" << colorStart << "--"
std::cerr << "Please note that the specified option '" << colorStart3 << "--"
<< name << colorEnd << "' has been removed in this ArangoDB version";
} else {
std::cerr << "Please note that the specified option '" << colorStart
<< "--" << name << colorEnd << "' has been renamed to '--"
<< colorStart << now << colorEnd << "' in this ArangoDB version";
std::cerr << "Please note that the specified option '" << colorStart3
<< "--" << name << colorEnd << "' has been renamed to '" << colorStart3
<< "--" << now << colorEnd << "' in this ArangoDB version";
}
std::cerr
@ -407,8 +415,8 @@ bool ProgramOptions::unknownOption(std::string const& name) {
<< std::endl;
}
std::cerr << "Use " << colorStart << "--help" << colorEnd << " or "
<< colorStart << "--help-all" << colorEnd
std::cerr << "Use " << colorStart3 << "--help" << colorEnd << " or "
<< colorStart3 << "--help-all" << colorEnd
<< " to get an overview of available options" << std::endl
<< std::endl;
@ -418,8 +426,16 @@ bool ProgramOptions::unknownOption(std::string const& name) {
// report an error (callback from parser)
bool ProgramOptions::fail(std::string const& message) {
_processingResult.failed(true);
std::cerr << "Error while processing " << _context << " for "
<< TRI_Basename(_progname.c_str()) << ":" << std::endl;
char const* colorStart = "";
char const* colorEnd = "";
if (isatty(STDERR_FILENO)) {
colorStart = ShellColorsFeature::SHELL_COLOR_RED;
colorEnd = ShellColorsFeature::SHELL_COLOR_RESET;
}
std::cerr << colorStart << "Error while processing " << _context << " for "
<< TRI_Basename(_progname.c_str()) << ":" << colorEnd << std::endl;
failNotice(message);
std::cerr << std::endl;
#ifdef _WIN32