mirror of https://gitee.com/bigwinds/arangodb
217 lines
6.0 KiB
C++
217 lines
6.0 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
///
|
|
/// @author Jan Steemann
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Option.h"
|
|
|
|
#include "ProgramOptions/Parameters.h"
|
|
|
|
#include <velocypack/Builder.h>
|
|
#include <velocypack/velocypack-aliases.h>
|
|
|
|
#include <iostream>
|
|
|
|
using namespace arangodb::options;
|
|
|
|
// create an option, consisting of single string
|
|
Option::Option(std::string const& value, std::string const& description,
|
|
Parameter* parameter, std::underlying_type<Flags>::type flags)
|
|
: section(), name(), description(description), shorthand(), parameter(parameter), flags(flags) {
|
|
auto parts = splitName(value);
|
|
section = parts.first;
|
|
name = parts.second;
|
|
|
|
size_t const pos = name.find(',');
|
|
if (pos != std::string::npos) {
|
|
shorthand = stripShorthand(name.substr(pos + 1));
|
|
name = name.substr(0, pos);
|
|
}
|
|
}
|
|
|
|
void Option::toVPack(VPackBuilder& builder) const {
|
|
parameter->toVPack(builder);
|
|
}
|
|
|
|
// format a version string
|
|
std::string Option::toVersionString(uint32_t version) const {
|
|
if (version == 0) {
|
|
return "-";
|
|
}
|
|
|
|
std::string result("v");
|
|
// intentionally using integer division here...
|
|
result += std::to_string(version / 10000) + ".";
|
|
version -= (version / 10000) * 10000;
|
|
result += std::to_string(version / 100) + ".";
|
|
version -= (version / 100) * 100;
|
|
result += std::to_string(version);
|
|
return result;
|
|
}
|
|
|
|
// format multiple version strings
|
|
std::string Option::toVersionString(std::vector<uint32_t> const& versions) const {
|
|
std::string result;
|
|
for (auto const& it : versions) {
|
|
if (!result.empty()) {
|
|
result += ", ";
|
|
}
|
|
result += toVersionString(it);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// returns the version in which the option was introduced as a proper
|
|
// version string - if the version is unknown this will return "-"
|
|
std::string Option::introducedInString() const {
|
|
return toVersionString(introducedInVersions);
|
|
}
|
|
|
|
// returns the version in which the option was deprecated as a proper
|
|
// version string - if the version is unknown this will return "-"
|
|
std::string Option::deprecatedInString() const {
|
|
return toVersionString(deprecatedInVersions);
|
|
}
|
|
|
|
// print help for an option
|
|
// the special search string "." will show help for all sections, even if hidden
|
|
void Option::printHelp(std::string const& search, size_t tw, size_t ow, bool) const {
|
|
if (search == "." || !hasFlag(arangodb::options::Flags::Hidden)) {
|
|
std::cout << " " << pad(nameWithType(), ow) << " ";
|
|
|
|
std::string value = description;
|
|
if (hasFlag(arangodb::options::Flags::Obsolete)) {
|
|
value += " (obsolete option)";
|
|
} else {
|
|
std::string description = parameter->description();
|
|
if (!description.empty()) {
|
|
value.append(". ");
|
|
value.append(description);
|
|
}
|
|
value += " (default: " + parameter->valueString() + ")";
|
|
if (hasIntroducedIn()) {
|
|
value += " (introduced in " + introducedInString() + ")";
|
|
}
|
|
if (hasDeprecatedIn()) {
|
|
value += " (deprecated in " + deprecatedInString() + ")";
|
|
}
|
|
}
|
|
auto parts = wordwrap(value, tw - ow - 6);
|
|
size_t const n = parts.size();
|
|
for (size_t i = 0; i < n; ++i) {
|
|
std::cout << trim(parts[i]) << std::endl;
|
|
if (i < n - 1) {
|
|
std::cout << " " << pad("", ow) << " ";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// determine the width of an option help string
|
|
size_t Option::optionsWidth() const {
|
|
if (hasFlag(arangodb::options::Flags::Hidden)) {
|
|
return 0;
|
|
}
|
|
|
|
return nameWithType().size();
|
|
}
|
|
|
|
// strip the "--" from a string
|
|
std::string Option::stripPrefix(std::string const& name) {
|
|
size_t pos = name.find("--");
|
|
if (pos == 0) {
|
|
// strip initial "--"
|
|
return name.substr(2);
|
|
}
|
|
return name;
|
|
}
|
|
|
|
// strip the "-" from a string
|
|
std::string Option::stripShorthand(std::string const& name) {
|
|
size_t pos = name.find("-");
|
|
if (pos == 0) {
|
|
// strip initial "-"
|
|
return name.substr(1);
|
|
}
|
|
return name;
|
|
}
|
|
|
|
// split an option name at the ".", if it exists
|
|
std::pair<std::string, std::string> Option::splitName(std::string name) {
|
|
std::string section;
|
|
name = stripPrefix(name);
|
|
// split at "."
|
|
size_t pos = name.find(".");
|
|
if (pos == std::string::npos) {
|
|
// global option
|
|
section = "";
|
|
} else {
|
|
// section-specific option
|
|
section = name.substr(0, pos);
|
|
name = name.substr(pos + 1);
|
|
}
|
|
|
|
return std::make_pair(section, name);
|
|
}
|
|
|
|
std::vector<std::string> Option::wordwrap(std::string const& value, size_t size) {
|
|
std::vector<std::string> result;
|
|
std::string next = value;
|
|
|
|
if (size > 0) {
|
|
while (next.size() > size) {
|
|
size_t m = next.find_last_of("., ", size - 1);
|
|
|
|
if (m == std::string::npos || m < size / 2) {
|
|
m = size;
|
|
} else {
|
|
m += 1;
|
|
}
|
|
|
|
result.emplace_back(next.substr(0, m));
|
|
next = next.substr(m);
|
|
}
|
|
}
|
|
|
|
result.emplace_back(next);
|
|
|
|
return result;
|
|
}
|
|
|
|
// right-pad a string
|
|
std::string Option::pad(std::string const& value, size_t length) {
|
|
size_t const valueLength = value.size();
|
|
if (valueLength > length) {
|
|
return value.substr(0, length);
|
|
}
|
|
if (valueLength == length) {
|
|
return value;
|
|
}
|
|
return value + std::string(length - valueLength, ' ');
|
|
}
|
|
|
|
std::string Option::trim(std::string const& value) {
|
|
size_t const pos = value.find_first_not_of(" \t\n\r");
|
|
if (pos == std::string::npos) {
|
|
return "";
|
|
}
|
|
return value.substr(pos);
|
|
}
|