update shit
This commit is contained in:
parent
21948246d0
commit
a519b2d8d5
|
@ -1,4 +1,6 @@
|
||||||
#include "CmdHelper.hpp"
|
#include "CmdHelper.hpp"
|
||||||
|
#include "TerminalHelper.hpp"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace Unvirt {
|
namespace Unvirt {
|
||||||
namespace CmdHelper {
|
namespace CmdHelper {
|
||||||
|
@ -14,7 +16,7 @@ namespace Unvirt {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CmdSplitter::Convert(std::string& u8cmd) {
|
std::vector<std::string> CmdSplitter::Convert(const std::string& u8cmd) {
|
||||||
// set up variables
|
// set up variables
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
@ -69,11 +71,77 @@ namespace Unvirt {
|
||||||
|
|
||||||
#pragma region interactive cmd helper classes
|
#pragma region interactive cmd helper classes
|
||||||
|
|
||||||
SubCmd::SubCmd() {
|
|
||||||
|
OptionsDescription::OptionsDescription() :
|
||||||
|
mLongNameDict(), mShortNameMapping(), mPositionalArgMapping() {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
OptionsDescription::~OptionsDescription() { ; }
|
||||||
|
|
||||||
|
void OptionsDescription::AddOption(
|
||||||
|
const char* fullname, char shortname, CmdArgType type, const char* description) {
|
||||||
|
// pre-check
|
||||||
|
if (fullname == nullptr ||
|
||||||
|
fullname[0] == '\0' ||
|
||||||
|
fullname[0] == '-')
|
||||||
|
throw std::invalid_argument("Invalid Option Long Name.");
|
||||||
|
|
||||||
|
// construct data
|
||||||
|
std::string sfullname(fullname);
|
||||||
|
OptionDescription data{
|
||||||
|
fullname, shortname, type, (description != nullptr ? description : "")
|
||||||
|
};
|
||||||
|
|
||||||
|
// check requirement
|
||||||
|
if (mLongNameDict.contains(sfullname)) throw std::invalid_argument("Duplicated Option Long Name.");
|
||||||
|
if (shortname != '\0')
|
||||||
|
if (mShortNameMapping.contains(shortname)) throw std::invalid_argument("Duplicated Option Short Name.");
|
||||||
|
|
||||||
|
// add them
|
||||||
|
mShortNameMapping.emplace(shortname, sfullname);
|
||||||
|
mLongNameDict.emplace(sfullname, std::move(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
SubCmd::~SubCmd() {
|
void OptionsDescription::AddPositionalOption(const char* corresponding_longname) {
|
||||||
|
// pre-check
|
||||||
|
if (corresponding_longname == nullptr) throw std::invalid_argument("Invalid Option Long Name.");
|
||||||
|
|
||||||
|
// construct data
|
||||||
|
std::string fullname(corresponding_longname);
|
||||||
|
|
||||||
|
// check requirement
|
||||||
|
if (!mLongNameDict.contains(fullname)) throw std::invalid_argument("No Matched Option.");
|
||||||
|
if (!mPositionalArgMapping.empty()) {
|
||||||
|
for (const auto& i : mPositionalArgMapping) {
|
||||||
|
if (i == fullname)throw std::invalid_argument("Duplicated Option.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set value
|
||||||
|
mPositionalArgMapping.push_back(std::move(fullname));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsDescription::PrintHelp(FILE* f) {
|
||||||
|
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("Allowed Options: \n")), f);
|
||||||
|
for (const auto& [key, value] : mLongNameDict) {
|
||||||
|
fprintf(f, "--%s\t%s\n", value.mLongName.c_str(), value.mDescription.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mPositionalArgMapping.empty()) {
|
||||||
|
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("\nPositional Options: \n")), f);
|
||||||
|
for (const auto& i : mPositionalArgMapping) {
|
||||||
|
fprintf(f, "[%s] ", i.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VariablesMap::VariablesMap() {
|
||||||
|
}
|
||||||
|
|
||||||
|
VariablesMap::~VariablesMap() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace Unvirt {
|
namespace Unvirt {
|
||||||
namespace CmdHelper {
|
namespace CmdHelper {
|
||||||
|
@ -15,7 +16,7 @@ namespace Unvirt {
|
||||||
CmdSplitter& operator=(const CmdSplitter&) = delete;
|
CmdSplitter& operator=(const CmdSplitter&) = delete;
|
||||||
~CmdSplitter();
|
~CmdSplitter();
|
||||||
|
|
||||||
std::vector<std::string> Convert(std::string& u8cmd);
|
std::vector<std::string> Convert(const std::string& u8cmd);
|
||||||
private:
|
private:
|
||||||
char mCmdChar;
|
char mCmdChar;
|
||||||
std::string* mBuffer;
|
std::string* mBuffer;
|
||||||
|
@ -120,13 +121,68 @@ namespace Unvirt {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SubCmd {
|
enum class CmdArgType {
|
||||||
|
NONE,
|
||||||
|
STRING,
|
||||||
|
INT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OptionDescription {
|
||||||
|
std::string mLongName;
|
||||||
|
char mShortName;
|
||||||
|
CmdArgType mType;
|
||||||
|
std::string mDescription;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OptionsDescription {
|
||||||
public:
|
public:
|
||||||
SubCmd();
|
OptionsDescription();
|
||||||
~SubCmd();
|
OptionsDescription(const OptionsDescription&) = delete;
|
||||||
|
OptionsDescription& operator=(const OptionsDescription&) = delete;
|
||||||
|
~OptionsDescription();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add an option
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fullname">The long name of this option. Should NOT be blank or NULL.</param>
|
||||||
|
/// <param name="shortname">A single char for the short name of this option. Leave ZERO to omit this.</param>
|
||||||
|
/// <param name="type">The value type of this option. Set to CmdArgType::NONE to indicate this is a switch (no value).</param>
|
||||||
|
/// <param name="sescription">The description of this option. This can be NULL.</param>
|
||||||
|
void AddOption(const char* fullname, char shortname, CmdArgType type, const char* sescription);
|
||||||
|
void AddPositionalOption(const char* corresponding_longname);
|
||||||
|
|
||||||
|
void PrintHelp(FILE* f);
|
||||||
private:
|
private:
|
||||||
|
std::unordered_map<std::string, OptionDescription> mLongNameDict;
|
||||||
|
std::unordered_map<char, std::string> mShortNameMapping;
|
||||||
|
std::vector<std::string> mPositionalArgMapping;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnyVariable {
|
||||||
|
CmdArgType mType;
|
||||||
|
void* mData;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VariablesMap {
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, AnyVariable> mDataPair;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VariablesMap();
|
||||||
|
~VariablesMap();
|
||||||
|
|
||||||
|
void Clear(void);
|
||||||
|
bool AddPair(std::string& name, CmdArgType t, std::string& val);
|
||||||
|
bool Contain(const char* probe);
|
||||||
|
template<typename T>
|
||||||
|
T* GetData(const char* opt) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmdRegisteryEntry {
|
||||||
|
OptionsDescription mOptDesc;
|
||||||
|
std::function<void(OptionsDescription&, VariablesMap&)> mBindProc;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InteractiveCmd {
|
class InteractiveCmd {
|
||||||
|
@ -137,7 +193,9 @@ namespace Unvirt {
|
||||||
void Run(void);
|
void Run(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//std::unordered_map<std::string, CmdRegisteryEntry> mCmdDispatcher;
|
bool AnalyzeCmd(std::vector<std::string>& args);
|
||||||
|
void PrintHelp(FILE* f);
|
||||||
|
std::unordered_map<std::string, CmdRegisteryEntry> mCmdDispatcher;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user