mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
Merge pull request #4559 from kittywhiskers/auxbps
merge bitcoin#16566...#18004: auxillary backports
This commit is contained in:
commit
c679fd9ab6
@ -13,7 +13,7 @@ define $(package)_preprocess_cmds
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_config_cmds
|
define $(package)_config_cmds
|
||||||
$(host_prefix)/bin/cmake -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix) ..
|
$(host_prefix)/bin/cmake -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix) -DCMAKE_C_FLAGS="-Wl,--build-id=none" ..
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_build_cmds
|
define $(package)_build_cmds
|
||||||
|
@ -100,7 +100,7 @@ bool CProposalValidator::ValidateName()
|
|||||||
|
|
||||||
static constexpr std::string_view strAllowedChars{"-_abcdefghijklmnopqrstuvwxyz0123456789"};
|
static constexpr std::string_view strAllowedChars{"-_abcdefghijklmnopqrstuvwxyz0123456789"};
|
||||||
|
|
||||||
std::transform(strName.begin(), strName.end(), strName.begin(), ToLower);
|
strName = ToLower(strName);
|
||||||
|
|
||||||
if (strName.find_first_not_of(strAllowedChars) != std::string::npos) {
|
if (strName.find_first_not_of(strAllowedChars) != std::string::npos) {
|
||||||
strErrorMessages += "name contains invalid characters;";
|
strErrorMessages += "name contains invalid characters;";
|
||||||
|
@ -261,10 +261,32 @@ std::string BCLog::Logger::LogTimestampStr(const std::string& str)
|
|||||||
return strStamped;
|
return strStamped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace BCLog {
|
||||||
|
/** Belts and suspenders: make sure outgoing log messages don't contain
|
||||||
|
* potentially suspicious characters, such as terminal control codes.
|
||||||
|
*
|
||||||
|
* This escapes control characters except newline ('\n') in C syntax.
|
||||||
|
* It escapes instead of removes them to still allow for troubleshooting
|
||||||
|
* issues where they accidentally end up in strings.
|
||||||
|
*/
|
||||||
|
std::string LogEscapeMessage(const std::string& str) {
|
||||||
|
std::string ret;
|
||||||
|
for (char ch_in : str) {
|
||||||
|
uint8_t ch = (uint8_t)ch_in;
|
||||||
|
if ((ch >= 32 || ch == '\n') && ch != '\x7f') {
|
||||||
|
ret += ch_in;
|
||||||
|
} else {
|
||||||
|
ret += strprintf("\\x%02x", ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BCLog::Logger::LogPrintStr(const std::string& str)
|
void BCLog::Logger::LogPrintStr(const std::string& str)
|
||||||
{
|
{
|
||||||
StdLockGuard scoped_lock(m_cs);
|
StdLockGuard scoped_lock(m_cs);
|
||||||
std::string str_prefixed = str;
|
std::string str_prefixed = LogEscapeMessage(str);
|
||||||
|
|
||||||
if (m_log_threadnames && m_started_new_line) {
|
if (m_log_threadnames && m_started_new_line) {
|
||||||
// 16 chars total, "dash-" is 5 of them and another 1 is a NUL terminator
|
// 16 chars total, "dash-" is 5 of them and another 1 is a NUL terminator
|
||||||
|
@ -42,8 +42,8 @@ bool fNameLookup = DEFAULT_NAME_LOOKUP;
|
|||||||
static const int SOCKS5_RECV_TIMEOUT = 20 * 1000;
|
static const int SOCKS5_RECV_TIMEOUT = 20 * 1000;
|
||||||
static std::atomic<bool> interruptSocks5Recv(false);
|
static std::atomic<bool> interruptSocks5Recv(false);
|
||||||
|
|
||||||
enum Network ParseNetwork(std::string net) {
|
enum Network ParseNetwork(const std::string& net_in) {
|
||||||
Downcase(net);
|
std::string net = ToLower(net_in);
|
||||||
if (net == "ipv4") return NET_IPV4;
|
if (net == "ipv4") return NET_IPV4;
|
||||||
if (net == "ipv6") return NET_IPV6;
|
if (net == "ipv6") return NET_IPV6;
|
||||||
if (net == "onion") return NET_ONION;
|
if (net == "onion") return NET_ONION;
|
||||||
|
@ -38,7 +38,7 @@ public:
|
|||||||
bool randomize_credentials;
|
bool randomize_credentials;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Network ParseNetwork(std::string net);
|
enum Network ParseNetwork(const std::string& net);
|
||||||
std::string GetNetworkName(enum Network net);
|
std::string GetNetworkName(enum Network net);
|
||||||
bool SetProxy(enum Network net, const proxyType &addrProxy);
|
bool SetProxy(enum Network net, const proxyType &addrProxy);
|
||||||
bool GetProxy(enum Network net, proxyType &proxyInfoOut);
|
bool GetProxy(enum Network net, proxyType &proxyInfoOut);
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QThread>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
static int64_t nLastHeaderTipUpdateNotification = 0;
|
static int64_t nLastHeaderTipUpdateNotification = 0;
|
||||||
@ -40,23 +41,37 @@ ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QO
|
|||||||
optionsModel(_optionsModel),
|
optionsModel(_optionsModel),
|
||||||
peerTableModel(nullptr),
|
peerTableModel(nullptr),
|
||||||
banTableModel(nullptr),
|
banTableModel(nullptr),
|
||||||
pollTimer(nullptr)
|
m_thread(new QThread(this))
|
||||||
{
|
{
|
||||||
cachedBestHeaderHeight = -1;
|
cachedBestHeaderHeight = -1;
|
||||||
cachedBestHeaderTime = -1;
|
cachedBestHeaderTime = -1;
|
||||||
peerTableModel = new PeerTableModel(m_node, this);
|
peerTableModel = new PeerTableModel(m_node, this);
|
||||||
banTableModel = new BanTableModel(m_node, this);
|
banTableModel = new BanTableModel(m_node, this);
|
||||||
pollTimer = new QTimer(this);
|
|
||||||
connect(pollTimer, &QTimer::timeout, this, &ClientModel::updateTimer);
|
|
||||||
pollTimer->start(MODEL_UPDATE_DELAY);
|
|
||||||
mnListCached = std::make_shared<CDeterministicMNList>();
|
mnListCached = std::make_shared<CDeterministicMNList>();
|
||||||
|
|
||||||
|
QTimer* timer = new QTimer;
|
||||||
|
timer->setInterval(MODEL_UPDATE_DELAY);
|
||||||
|
connect(timer, &QTimer::timeout, [this] {
|
||||||
|
// no locking required at this point
|
||||||
|
// the following calls will acquire the required lock
|
||||||
|
Q_EMIT mempoolSizeChanged(m_node.getMempoolSize(), m_node.getMempoolDynamicUsage());
|
||||||
|
Q_EMIT islockCountChanged(m_node.llmq().getInstantSentLockCount());
|
||||||
|
});
|
||||||
|
connect(m_thread, &QThread::finished, timer, &QObject::deleteLater);
|
||||||
|
connect(m_thread, &QThread::started, [timer] { timer->start(); });
|
||||||
|
// move timer to thread so that polling doesn't disturb main event loop
|
||||||
|
timer->moveToThread(m_thread);
|
||||||
|
m_thread->start();
|
||||||
|
|
||||||
subscribeToCoreSignals();
|
subscribeToCoreSignals();
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientModel::~ClientModel()
|
ClientModel::~ClientModel()
|
||||||
{
|
{
|
||||||
unsubscribeFromCoreSignals();
|
unsubscribeFromCoreSignals();
|
||||||
|
|
||||||
|
m_thread->quit();
|
||||||
|
m_thread->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ClientModel::getNumConnections(unsigned int flags) const
|
int ClientModel::getNumConnections(unsigned int flags) const
|
||||||
@ -128,14 +143,6 @@ std::vector<const CGovernanceObject*> ClientModel::getAllGovernanceObjects()
|
|||||||
return m_node.gov().getAllNewerThan(0);
|
return m_node.gov().getAllNewerThan(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientModel::updateTimer()
|
|
||||||
{
|
|
||||||
// no locking required at this point
|
|
||||||
// the following calls will acquire the required lock
|
|
||||||
Q_EMIT mempoolSizeChanged(m_node.getMempoolSize(), m_node.getMempoolDynamicUsage());
|
|
||||||
Q_EMIT islockCountChanged(m_node.llmq().getInstantSentLockCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientModel::updateNumConnections(int numConnections)
|
void ClientModel::updateNumConnections(int numConnections)
|
||||||
{
|
{
|
||||||
Q_EMIT numConnectionsChanged(numConnections);
|
Q_EMIT numConnectionsChanged(numConnections);
|
||||||
|
@ -104,7 +104,8 @@ private:
|
|||||||
PeerTableModel *peerTableModel;
|
PeerTableModel *peerTableModel;
|
||||||
BanTableModel *banTableModel;
|
BanTableModel *banTableModel;
|
||||||
|
|
||||||
QTimer *pollTimer;
|
//! A thread to interact with m_node asynchronously
|
||||||
|
QThread* const m_thread;
|
||||||
|
|
||||||
// The cache for mn list is not technically needed because CDeterministicMNManager
|
// The cache for mn list is not technically needed because CDeterministicMNManager
|
||||||
// caches it internally for recent blocks but it's not enough to get consistent
|
// caches it internally for recent blocks but it's not enough to get consistent
|
||||||
@ -133,7 +134,6 @@ Q_SIGNALS:
|
|||||||
void showProgress(const QString &title, int nProgress);
|
void showProgress(const QString &title, int nProgress);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void updateTimer();
|
|
||||||
void updateNumConnections(int numConnections);
|
void updateNumConnections(int numConnections);
|
||||||
void updateNetworkActive(bool networkActive);
|
void updateNetworkActive(bool networkActive);
|
||||||
void updateAlert();
|
void updateAlert();
|
||||||
|
@ -470,16 +470,19 @@ int GuiMain(int argc, char* argv[])
|
|||||||
|
|
||||||
BitcoinApplication app(*node, argc, argv);
|
BitcoinApplication app(*node, argc, argv);
|
||||||
|
|
||||||
// Register meta types used for QMetaObject::invokeMethod
|
// Register meta types used for QMetaObject::invokeMethod and Qt::QueuedConnection
|
||||||
qRegisterMetaType<bool*>();
|
qRegisterMetaType<bool*>();
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
qRegisterMetaType<WalletModel*>();
|
qRegisterMetaType<WalletModel*>();
|
||||||
#endif
|
#endif
|
||||||
// Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
|
// Register typedefs (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
|
||||||
// IMPORTANT if it is no longer a typedef use the normal variant above
|
// IMPORTANT: if CAmount is no longer a typedef use the normal variant above (see https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1)
|
||||||
qRegisterMetaType<CAmount>("CAmount");
|
qRegisterMetaType<CAmount>("CAmount");
|
||||||
|
qRegisterMetaType<size_t>("size_t");
|
||||||
|
|
||||||
qRegisterMetaType<std::function<void()>>("std::function<void()>");
|
qRegisterMetaType<std::function<void()>>("std::function<void()>");
|
||||||
qRegisterMetaType<QMessageBox::Icon>("QMessageBox::Icon");
|
qRegisterMetaType<QMessageBox::Icon>("QMessageBox::Icon");
|
||||||
|
|
||||||
/// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these
|
/// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these
|
||||||
// Command-line options take precedence:
|
// Command-line options take precedence:
|
||||||
node->setupServerArgs();
|
node->setupServerArgs();
|
||||||
|
@ -564,7 +564,7 @@ static UniValue masternodelist(const JSONRPCRequest& request)
|
|||||||
if (!request.params[0].isNull()) strMode = request.params[0].get_str();
|
if (!request.params[0].isNull()) strMode = request.params[0].get_str();
|
||||||
if (!request.params[1].isNull()) strFilter = request.params[1].get_str();
|
if (!request.params[1].isNull()) strFilter = request.params[1].get_str();
|
||||||
|
|
||||||
std::transform(strMode.begin(), strMode.end(), strMode.begin(), ToLower);
|
strMode = ToLower(strMode);
|
||||||
|
|
||||||
if (request.fHelp || (
|
if (request.fHelp || (
|
||||||
strMode != "addr" && strMode != "full" && strMode != "info" && strMode != "json" &&
|
strMode != "addr" && strMode != "full" && strMode != "info" && strMode != "json" &&
|
||||||
|
@ -188,7 +188,7 @@ bool ParseBoolV(const UniValue& v, const std::string &strName)
|
|||||||
else if (v.isStr())
|
else if (v.isStr())
|
||||||
strBool = v.get_str();
|
strBool = v.get_str();
|
||||||
|
|
||||||
std::transform(strBool.begin(), strBool.end(), strBool.begin(), ToLower);
|
strBool = ToLower(strBool);
|
||||||
|
|
||||||
if (strBool == "true" || strBool == "yes" || strBool == "1") {
|
if (strBool == "true" || strBool == "yes" || strBool == "1") {
|
||||||
return true;
|
return true;
|
||||||
|
@ -25,6 +25,11 @@
|
|||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
/* defined in logging.cpp */
|
||||||
|
namespace BCLog {
|
||||||
|
std::string LogEscapeMessage(const std::string& str);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(util_criticalsection)
|
BOOST_AUTO_TEST_CASE(util_criticalsection)
|
||||||
@ -1325,17 +1330,9 @@ BOOST_AUTO_TEST_CASE(test_ToLower)
|
|||||||
BOOST_CHECK_EQUAL(ToLower(0), 0);
|
BOOST_CHECK_EQUAL(ToLower(0), 0);
|
||||||
BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff');
|
BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff');
|
||||||
|
|
||||||
std::string testVector;
|
BOOST_CHECK_EQUAL(ToLower(""), "");
|
||||||
Downcase(testVector);
|
BOOST_CHECK_EQUAL(ToLower("#HODL"), "#hodl");
|
||||||
BOOST_CHECK_EQUAL(testVector, "");
|
BOOST_CHECK_EQUAL(ToLower("\x00\xfe\xff"), "\x00\xfe\xff");
|
||||||
|
|
||||||
testVector = "#HODL";
|
|
||||||
Downcase(testVector);
|
|
||||||
BOOST_CHECK_EQUAL(testVector, "#hodl");
|
|
||||||
|
|
||||||
testVector = "\x00\xfe\xff";
|
|
||||||
Downcase(testVector);
|
|
||||||
BOOST_CHECK_EQUAL(testVector, "\x00\xfe\xff");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_ToUpper)
|
BOOST_AUTO_TEST_CASE(test_ToUpper)
|
||||||
@ -1346,6 +1343,10 @@ BOOST_AUTO_TEST_CASE(test_ToUpper)
|
|||||||
BOOST_CHECK_EQUAL(ToUpper('{'), '{');
|
BOOST_CHECK_EQUAL(ToUpper('{'), '{');
|
||||||
BOOST_CHECK_EQUAL(ToUpper(0), 0);
|
BOOST_CHECK_EQUAL(ToUpper(0), 0);
|
||||||
BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff');
|
BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff');
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(ToUpper(""), "");
|
||||||
|
BOOST_CHECK_EQUAL(ToUpper("#hodl"), "#HODL");
|
||||||
|
BOOST_CHECK_EQUAL(ToUpper("\x00\xfe\xff"), "\x00\xfe\xff");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_Capitalize)
|
BOOST_AUTO_TEST_CASE(test_Capitalize)
|
||||||
@ -1478,4 +1479,17 @@ BOOST_AUTO_TEST_CASE(test_spanparsing)
|
|||||||
BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
|
BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
|
||||||
|
{
|
||||||
|
// ASCII and UTF-8 must pass through unaltered.
|
||||||
|
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Valid log message貓"), "Valid log message貓");
|
||||||
|
// Newlines must pass through unaltered.
|
||||||
|
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Message\n with newlines\n"), "Message\n with newlines\n");
|
||||||
|
// Other control characters are escaped in C syntax.
|
||||||
|
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("\x01\x7f Corrupted log message\x0d"), R"(\x01\x7f Corrupted log message\x0d)");
|
||||||
|
// Embedded NULL characters are escaped too.
|
||||||
|
const std::string NUL("O\x00O", 3);
|
||||||
|
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -630,9 +630,18 @@ std::string HexStr(const Span<const uint8_t> s)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downcase(std::string& str)
|
std::string ToLower(const std::string& str)
|
||||||
{
|
{
|
||||||
std::transform(str.begin(), str.end(), str.begin(), [](char c){return ToLower(c);});
|
std::string r;
|
||||||
|
for (auto ch : str) r += ToLower((unsigned char)ch);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToUpper(const std::string& str)
|
||||||
|
{
|
||||||
|
std::string r;
|
||||||
|
for (auto ch : str) r += ToUpper((unsigned char)ch);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Capitalize(std::string str)
|
std::string Capitalize(std::string str)
|
||||||
|
@ -203,6 +203,8 @@ bool ConvertBits(const O& outfn, I it, I end) {
|
|||||||
* Converts the given character to its lowercase equivalent.
|
* Converts the given character to its lowercase equivalent.
|
||||||
* This function is locale independent. It only converts uppercase
|
* This function is locale independent. It only converts uppercase
|
||||||
* characters in the standard 7-bit ASCII range.
|
* characters in the standard 7-bit ASCII range.
|
||||||
|
* This is a feature, not a limitation.
|
||||||
|
*
|
||||||
* @param[in] c the character to convert to lowercase.
|
* @param[in] c the character to convert to lowercase.
|
||||||
* @return the lowercase equivalent of c; or the argument
|
* @return the lowercase equivalent of c; or the argument
|
||||||
* if no conversion is possible.
|
* if no conversion is possible.
|
||||||
@ -213,17 +215,22 @@ constexpr char ToLower(char c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the given string to its lowercase equivalent.
|
* Returns the lowercase equivalent of the given string.
|
||||||
* This function is locale independent. It only converts uppercase
|
* This function is locale independent. It only converts uppercase
|
||||||
* characters in the standard 7-bit ASCII range.
|
* characters in the standard 7-bit ASCII range.
|
||||||
* @param[in,out] str the string to convert to lowercase.
|
* This is a feature, not a limitation.
|
||||||
|
*
|
||||||
|
* @param[in] str the string to convert to lowercase.
|
||||||
|
* @returns lowercased equivalent of str
|
||||||
*/
|
*/
|
||||||
void Downcase(std::string& str);
|
std::string ToLower(const std::string& str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the given character to its uppercase equivalent.
|
* Converts the given character to its uppercase equivalent.
|
||||||
* This function is locale independent. It only converts lowercase
|
* This function is locale independent. It only converts lowercase
|
||||||
* characters in the standard 7-bit ASCII range.
|
* characters in the standard 7-bit ASCII range.
|
||||||
|
* This is a feature, not a limitation.
|
||||||
|
*
|
||||||
* @param[in] c the character to convert to uppercase.
|
* @param[in] c the character to convert to uppercase.
|
||||||
* @return the uppercase equivalent of c; or the argument
|
* @return the uppercase equivalent of c; or the argument
|
||||||
* if no conversion is possible.
|
* if no conversion is possible.
|
||||||
@ -233,13 +240,25 @@ constexpr char ToUpper(char c)
|
|||||||
return (c >= 'a' && c <= 'z' ? (c - 'a') + 'A' : c);
|
return (c >= 'a' && c <= 'z' ? (c - 'a') + 'A' : c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the uppercase equivalent of the given string.
|
||||||
|
* This function is locale independent. It only converts lowercase
|
||||||
|
* characters in the standard 7-bit ASCII range.
|
||||||
|
* This is a feature, not a limitation.
|
||||||
|
*
|
||||||
|
* @param[in] str the string to convert to uppercase.
|
||||||
|
* @returns UPPERCASED EQUIVALENT OF str
|
||||||
|
*/
|
||||||
|
std::string ToUpper(const std::string& str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capitalizes the first character of the given string.
|
* Capitalizes the first character of the given string.
|
||||||
* This function is locale independent. It only capitalizes the
|
* This function is locale independent. It only converts lowercase
|
||||||
* first character of the argument if it has an uppercase equivalent
|
* characters in the standard 7-bit ASCII range.
|
||||||
* in the standard 7-bit ASCII range.
|
* This is a feature, not a limitation.
|
||||||
|
*
|
||||||
* @param[in] str the string to capitalize.
|
* @param[in] str the string to capitalize.
|
||||||
* @return string with the first letter capitalized.
|
* @returns string with the first letter capitalized.
|
||||||
*/
|
*/
|
||||||
std::string Capitalize(std::string str);
|
std::string Capitalize(std::string str);
|
||||||
|
|
||||||
|
@ -427,7 +427,7 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin
|
|||||||
key.erase(is_index);
|
key.erase(is_index);
|
||||||
}
|
}
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
std::transform(key.begin(), key.end(), key.begin(), ToLower);
|
key = ToLower(key);
|
||||||
if (key[0] == '/')
|
if (key[0] == '/')
|
||||||
key[0] = '-';
|
key[0] = '-';
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user