Update Arguments class.

This commit is contained in:
XMRig
2022-04-16 02:52:46 +07:00
parent dfc3b4632a
commit fe8e198106
4 changed files with 171 additions and 45 deletions

View File

@ -137,22 +137,22 @@ static int exportTopology(const Process &)
xmrig::Entry::Id xmrig::Entry::get(const Process &process)
{
const Arguments &args = process.arguments();
if (args.hasArg("-h") || args.hasArg("--help")) {
if (args.contains("-h", "--help")) {
return Usage;
}
if (args.hasArg("-V") || args.hasArg("--version") || args.hasArg("--versions")) {
if (args.contains("-V", "--version", "--versions")) {
return Version;
}
# ifdef XMRIG_FEATURE_HWLOC
if (args.hasArg("--export-topology")) {
if (args.contains("--export-topology")) {
return Topo;
}
# endif
# ifdef XMRIG_FEATURE_OPENCL
if (args.hasArg("--print-platforms")) {
if (args.contains("--print-platforms")) {
return Platforms;
}
# endif

View File

@ -18,7 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/net/stratum/SelfSelectClient.h"
#include "3rdparty/rapidjson/document.h"
#include "3rdparty/rapidjson/error/en.h"

View File

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,19 +16,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <uv.h>
#include "base/tools/Arguments.h"
namespace xmrig {
const String Arguments::m_empty;
} // namespace xmrig
xmrig::Arguments::Arguments(int argc, char **argv) :
m_argv(argv),
m_argc(argc)
{
uv_setup_args(argc, argv);
m_data.reserve(argc);
for (size_t i = 0; i < static_cast<size_t>(argc); ++i) {
add(argv[i]);
@ -36,52 +44,127 @@ xmrig::Arguments::Arguments(int argc, char **argv) :
}
bool xmrig::Arguments::hasArg(const char *name) const
const xmrig::String &xmrig::Arguments::value(const char *key) const
{
if (m_argc == 1) {
return false;
if (size() < 3) {
return m_empty;
}
return std::find(m_data.begin() + 1, m_data.end(), name) != m_data.end();
for (size_t i = size() - 2; i > 0; i--) {
if (at(i) == key) {
const auto &v = value(i + 1);
if (!v.isNull()) {
return v;
}
}
}
return m_empty;
}
const char *xmrig::Arguments::value(const char *key1, const char *key2) const
const xmrig::String &xmrig::Arguments::value(size_t i) const
{
const size_t size = m_data.size();
if (size < 3) {
return nullptr;
const auto &v = at(i);
return v.size() < 1 || *v.data() == '-' ? m_empty : v;
}
size_t xmrig::Arguments::pos(const char *key) const
{
if (size() < 2) {
return 0;
}
for (size_t i = 1; i < size - 1; ++i) {
if (m_data[i] == key1 || (key2 && m_data[i] == key2)) {
return m_data[i + 1];
for (size_t i = size() - 1; i > 0; i--) {
if (at(i) == key) {
return i;
}
}
return nullptr;
return 0;
}
std::vector<xmrig::String> xmrig::Arguments::values(const char *key) const
{
const size_t n = count(key);
if (!n) {
return {};
}
std::vector<String> out;
out.reserve(n);
for (size_t i = 1; i < size(); ++i) {
if (at(i) == key) {
const auto &v = value(i + 1);
if (!v.isNull()) {
++i;
out.emplace_back(v);
}
}
}
return out;
}
void xmrig::Arguments::forEach(const Callback &callback) const
{
for (size_t i = 1; i < size(); ++i) {
const auto &v = value(i + 1);
callback(at(i), v, i);
if (!v.isNull()) {
++i;
}
}
}
void xmrig::Arguments::add(const char *arg)
{
if (arg == nullptr) {
const size_t size = arg == nullptr ? 0U : strlen(arg);
if (size < 1) {
return;
}
const size_t size = strlen(arg);
if (size > 4 && arg[0] == '-' && arg[1] == '-') {
const char *p = strchr(arg, '=');
if (*arg != '-') {
return add(arg, size);
}
if (p) {
const auto keySize = static_cast<size_t>(p - arg);
if (size > 1 && arg[1] != '-') {
static char tmp[3] = { 0x2d, 0x00, 0x00 };
m_data.emplace_back(arg, keySize);
m_data.emplace_back(arg + keySize + 1);
for (size_t i = 1; i < size; i++) {
tmp[1] = arg[i];
add(tmp, 2);
}
return;
}
if (size > 3) {
const char *p = nullptr;
if (size > 5 && (p = strchr(arg, '='))) {
const auto ks = static_cast<size_t>(p - arg);
add(arg, ks);
if (size - ks > 1) {
add(arg + ks + 1, size - ks - 1);
}
m_data.emplace_back(arg);
return;
}
add(arg, size);
}
}

View File

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,7 +20,8 @@
#define XMRIG_ARGUMENTS_H
#include <vector>
#include <algorithm>
#include <functional>
#include "base/tools/String.h"
@ -32,20 +33,63 @@ namespace xmrig {
class Arguments
{
public:
using Callback = std::function<void(const String &key, const String &value, size_t index)>;
Arguments(int argc, char **argv);
bool hasArg(const char *name) const;
const char *value(const char *key1, const char *key2 = nullptr) const;
template<typename... Args>
bool contains(Args... args) const {
static_assert(sizeof...(args) >= 2, "Expected at least 2 arguments");
for (const char *key : { args... }) {
if (contains(key)) {
return true;
}
}
return false;
}
template<typename... Args>
const String &value(Args... args) const {
static_assert(sizeof...(args) >= 2, "Expected at least 2 arguments");
for (const char *key : { args... }) {
const auto &v = value(key);
if (v) {
return v;
}
}
return m_empty;
}
const String &value(const char *key) const;
const String &value(size_t i) const;
size_t pos(const char *key) const;
std::vector<String> values(const char *key) const;
void forEach(const Callback &callback) const;
inline bool contains(const char *key) const { return size() > 1 && std::find(m_data.begin() + 1, m_data.end(), key) != m_data.end(); }
inline char **argv() const { return m_argv; }
inline const std::vector<String> &data() const { return m_data; }
inline const String &at(size_t i) const { return i < size() ? m_data[i] : m_empty; }
inline int argc() const { return m_argc; }
inline size_t count(const char *key) const { return size() > 1 ? std::count(m_data.begin() + 1, m_data.end(), key) : 0U; }
inline size_t size() const { return m_data.size(); }
inline const String &operator[](size_t i) const { return at(i); }
private:
static const String m_empty;
inline void add(const char *arg, size_t size) { m_data.emplace_back(arg, size); }
void add(const char *arg);
char **m_argv;
int m_argc;
const int m_argc;
std::vector<String> m_data;
};