mirror of https://gitee.com/bigwinds/arangodb
vadim (#7983)
This commit is contained in:
parent
36cfec1cce
commit
5502ed2a3a
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) + ")";
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue