fix: fix Unvirt build issue, but it doesn't work
This commit is contained in:
parent
34015d2d1c
commit
3735a202f3
|
@ -153,7 +153,7 @@ namespace LibCmo::CK2 {
|
||||||
* @details It accept a CKSTRING representing the string need to be printed.
|
* @details It accept a CKSTRING representing the string need to be printed.
|
||||||
* The passed CKSTRING is guaranteen that it can not be nullptr.
|
* The passed CKSTRING is guaranteen that it can not be nullptr.
|
||||||
*/
|
*/
|
||||||
using OutputCallback = void(*)(CKSTRING);
|
using OutputCallback = std::function<void(CKSTRING)>;
|
||||||
/**
|
/**
|
||||||
* @brief Output plain message.
|
* @brief Output plain message.
|
||||||
* @param[in] str Plain message. nullptr is allowed but not suggested.
|
* @param[in] str Plain message. nullptr is allowed but not suggested.
|
||||||
|
|
|
@ -403,6 +403,9 @@ namespace LibCmo::EncodingHelper {
|
||||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
|
|
||||||
struct WindowsEncodingToken {
|
struct WindowsEncodingToken {
|
||||||
|
WindowsEncodingToken(const std::u8string_view& universal_code, UINT cp) :
|
||||||
|
m_Name(universal_code), m_CodePage(cp) {}
|
||||||
|
std::u8string m_Name;
|
||||||
UINT m_CodePage;
|
UINT m_CodePage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -412,7 +415,8 @@ namespace LibCmo::EncodingHelper {
|
||||||
static const iconv_t c_InvalidIconvType = reinterpret_cast<iconv_t>(-1);
|
static const iconv_t c_InvalidIconvType = reinterpret_cast<iconv_t>(-1);
|
||||||
|
|
||||||
struct IconvEncodingToken {
|
struct IconvEncodingToken {
|
||||||
IconvEncodingToken(const std::string_view& iconv_code) :
|
IconvEncodingToken(const std::u8string_view& universal_code, const std::string_view& iconv_code) :
|
||||||
|
m_Name(universal_code),
|
||||||
m_FromUTF8(c_InvalidIconvType), m_ToUTF8(c_InvalidIconvType) {
|
m_FromUTF8(c_InvalidIconvType), m_ToUTF8(c_InvalidIconvType) {
|
||||||
// if iconv code is empty, do nothing
|
// if iconv code is empty, do nothing
|
||||||
if (iconv_code.empty()) return;
|
if (iconv_code.empty()) return;
|
||||||
|
@ -426,6 +430,8 @@ namespace LibCmo::EncodingHelper {
|
||||||
if (this->m_ToUTF8 != c_InvalidIconvType)
|
if (this->m_ToUTF8 != c_InvalidIconvType)
|
||||||
iconv_close(token_cast->m_ToUTF8);
|
iconv_close(token_cast->m_ToUTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::u8string m_Name;
|
||||||
iconv_t m_FromUTF8;
|
iconv_t m_FromUTF8;
|
||||||
iconv_t m_ToUTF8;
|
iconv_t m_ToUTF8;
|
||||||
};
|
};
|
||||||
|
@ -508,7 +514,7 @@ namespace LibCmo::EncodingHelper {
|
||||||
if (!YYCC::WinFctHelper::IsValidCodePage(cp))
|
if (!YYCC::WinFctHelper::IsValidCodePage(cp))
|
||||||
return INVALID_ENCODING_TOKEN;
|
return INVALID_ENCODING_TOKEN;
|
||||||
// create token and return
|
// create token and return
|
||||||
WindowsEncodingToken* token = new WindowsEncodingToken { cp };
|
WindowsEncodingToken* token = new WindowsEncodingToken(enc_name, cp);
|
||||||
return token;
|
return token;
|
||||||
#else
|
#else
|
||||||
// get iconv code first
|
// get iconv code first
|
||||||
|
@ -516,7 +522,7 @@ namespace LibCmo::EncodingHelper {
|
||||||
if (!GetIconvCode(enc_name, code))
|
if (!GetIconvCode(enc_name, code))
|
||||||
return INVALID_ENCODING_TOKEN;
|
return INVALID_ENCODING_TOKEN;
|
||||||
// create token and set default value
|
// create token and set default value
|
||||||
IconvEncodingToken* token = new IconvEncodingToken(code);
|
IconvEncodingToken* token = new IconvEncodingToken(enc_name, code);
|
||||||
// check whether token has been initialized correctly
|
// check whether token has been initialized correctly
|
||||||
if (token->m_FromUTF8 == c_InvalidIconvType || token->m_ToUTF8 == c_InvalidIconvType) {
|
if (token->m_FromUTF8 == c_InvalidIconvType || token->m_ToUTF8 == c_InvalidIconvType) {
|
||||||
// failed. free resource and return
|
// failed. free resource and return
|
||||||
|
@ -541,6 +547,34 @@ namespace LibCmo::EncodingHelper {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::u8string GetEncodingTokenAssociatedName(EncodingToken token) {
|
||||||
|
// prepare return value
|
||||||
|
std::u8string ret;
|
||||||
|
// if token is invalid, return directly
|
||||||
|
if (token == INVALID_ENCODING_TOKEN) return ret;
|
||||||
|
|
||||||
|
// get associated name
|
||||||
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
|
WindowsEncodingToken* token_cast = static_cast<WindowsEncodingToken*>(token);
|
||||||
|
ret = token_cast->m_Name;
|
||||||
|
#else
|
||||||
|
IconvEncodingToken* token_cast = static_cast<IconvEncodingToken*>(token);
|
||||||
|
ret = token_cast->m_Name;
|
||||||
|
#endif
|
||||||
|
// return value
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValidEncodingName(const std::u8string_view& enc_name) {
|
||||||
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
|
UINT cp = CP_ACP;
|
||||||
|
return GetWindowsCodePage(enc_name, cp);
|
||||||
|
#else
|
||||||
|
std::string code;
|
||||||
|
return GetIconvCode(enc_name, code);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region Exposed Convertion Functions
|
#pragma region Exposed Convertion Functions
|
||||||
|
|
|
@ -55,6 +55,23 @@ namespace LibCmo::EncodingHelper {
|
||||||
* If token is #INVALID_ENCODING_TOKEN, this function does nothing.
|
* If token is #INVALID_ENCODING_TOKEN, this function does nothing.
|
||||||
*/
|
*/
|
||||||
void DestroyEncodingToken(EncodingToken token);
|
void DestroyEncodingToken(EncodingToken token);
|
||||||
|
/**
|
||||||
|
* @brief Get associated universal encoding name of given encoding token.
|
||||||
|
* @param[in] token The encoding token for getting name.
|
||||||
|
* @return Encoding token associated name (the universal encoding name used to create this token).
|
||||||
|
* Blank if given token is invalid or fail to get.
|
||||||
|
*/
|
||||||
|
std::u8string GetEncodingTokenAssociatedName(EncodingToken token);
|
||||||
|
/**
|
||||||
|
* @brief Check whether given universal encoding name can be used to produce token.
|
||||||
|
* @param[in] enc_name Universal encoding name.
|
||||||
|
* @return True if it is, otherwise false.
|
||||||
|
* @remarks
|
||||||
|
* Please note this function only check whether given encoding name is acceptable by token creator.
|
||||||
|
* Hoewver it doesn't mean that the token must be created if this function return true.
|
||||||
|
* Because there are some runtime issues which can cause that fail to create encoding token.
|
||||||
|
*/
|
||||||
|
bool IsValidEncodingName(const std::u8string_view& enc_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert native string to UTF8 string by given encoding.
|
* @brief Convert native string to UTF8 string by given encoding.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "CmdHelper.hpp"
|
#include "CmdHelper.hpp"
|
||||||
|
#include <VTAll.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace Unvirt::CmdHelper {
|
namespace Unvirt::CmdHelper {
|
||||||
|
@ -11,7 +12,7 @@ namespace Unvirt::CmdHelper {
|
||||||
return m_Result;
|
return m_Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CmdSplitter::Convert(const std::u8string& u8cmd) {
|
bool CmdSplitter::Lex(const std::u8string& u8cmd) {
|
||||||
// Clear variables
|
// Clear variables
|
||||||
m_ValidResult = false;
|
m_ValidResult = false;
|
||||||
m_Result.clear();
|
m_Result.clear();
|
||||||
|
@ -537,7 +538,12 @@ if (!this->IsRootNode()) { \
|
||||||
bool EncodingListArgument::BeginConsume(const std::u8string& cur_cmd, ArgumentsMap& am) {
|
bool EncodingListArgument::BeginConsume(const std::u8string& cur_cmd, ArgumentsMap& am) {
|
||||||
// split given argument
|
// split given argument
|
||||||
std::vector<std::u8string> encs = YYCC::StringHelper::Split(cur_cmd, u8",");
|
std::vector<std::u8string> encs = YYCC::StringHelper::Split(cur_cmd, u8",");
|
||||||
// add into map
|
// check each parts is a valid encoding name
|
||||||
|
for (const auto& item : encs) {
|
||||||
|
if (!LibCmo::EncodingHelper::IsValidEncodingName(item))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// okey, add into map
|
||||||
am.Add<ArgValue_t>(m_ArgumentName, encs);
|
am.Add<ArgValue_t>(m_ArgumentName, encs);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,9 @@ namespace Unvirt::CmdHelper {
|
||||||
m_CurrentChar(u8'\0'), m_Buffer(), m_Result(), m_ValidResult(false),
|
m_CurrentChar(u8'\0'), m_Buffer(), m_Result(), m_ValidResult(false),
|
||||||
m_State(StateType::NORMAL), m_PrevState(StateType::NORMAL) {}
|
m_State(StateType::NORMAL), m_PrevState(StateType::NORMAL) {}
|
||||||
~CmdSplitter() {}
|
~CmdSplitter() {}
|
||||||
YYCC_DEL_CLS_COPY_MOVE(CmdSplitter);
|
YYCC_DEF_CLS_COPY_MOVE(CmdSplitter);
|
||||||
|
|
||||||
bool Convert(const std::u8string& u8cmd);
|
bool Lex(const std::u8string& u8cmd);
|
||||||
const Result_t& GetResult() const;
|
const Result_t& GetResult() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -241,7 +241,7 @@ namespace Unvirt::CmdHelper {
|
||||||
|
|
||||||
class AbstractNode {
|
class AbstractNode {
|
||||||
public:
|
public:
|
||||||
using FctExecution_t = void(*)(const ArgumentsMap&);
|
using FctExecution_t = std::function<void(const ArgumentsMap&)>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AbstractNode();
|
AbstractNode();
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <YYCCommonplace.hpp>
|
#include <YYCCommonplace.hpp>
|
||||||
#include "AccessibleValue.hpp"
|
#include "AccessibleValue.hpp"
|
||||||
#include "TerminalHelper.hpp"
|
|
||||||
|
|
||||||
namespace Console = YYCC::ConsoleHelper;
|
namespace Console = YYCC::ConsoleHelper;
|
||||||
|
|
||||||
|
|
|
@ -1,193 +1,208 @@
|
||||||
#include "UnvirtContext.hpp"
|
#include "UnvirtContext.hpp"
|
||||||
|
|
||||||
|
#include <YYCCommonplace.hpp>
|
||||||
#include <CK2/MgrImpls/CKPathManager.hpp>
|
#include <CK2/MgrImpls/CKPathManager.hpp>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
namespace Unvirt::Context {
|
namespace Unvirt::Context {
|
||||||
|
|
||||||
|
#pragma region Constraint Help Function
|
||||||
|
|
||||||
|
static YYCC::Constraints::Constraint<size_t> GetOneBasedIndexConstraint() {
|
||||||
|
return YYCC::Constraints::Constraint<size_t> {
|
||||||
|
[](const size_t& val) -> bool {
|
||||||
|
return val > 0u;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
#pragma region UnvirtContext Misc
|
#pragma region UnvirtContext Misc
|
||||||
|
|
||||||
UnvirtContext::UnvirtContext() :
|
UnvirtContext::UnvirtContext() :
|
||||||
m_Root(), m_Splitter(), m_Help(nullptr),
|
m_Splitter(), m_Parser(), m_Help(),
|
||||||
m_PageLen(10u), m_ListStyleIsFull(true), m_OrderExit(false),
|
m_PageLen(10u), m_ListStyleIsFull(true), m_OrderExit(false),
|
||||||
m_SearchPart(SearchPart::None), m_SearchIdxResult(),
|
m_SearchPart(SearchPart::None), m_SearchIdxResult(),
|
||||||
m_Ctx(nullptr), m_FileReader(nullptr), m_IsShallowRead(true) {
|
m_Ctx(nullptr), m_FileReader(nullptr), m_IsShallowRead(true) {
|
||||||
|
|
||||||
// create command root
|
// Setup command parser
|
||||||
CmdHelper::CommandRoot* root = &m_Root;
|
// get root node first
|
||||||
|
CmdHelper::Nodes::RootNode& root = m_Parser.GetRoot();
|
||||||
|
// setup tree
|
||||||
root
|
root
|
||||||
->Then((new CmdHelper::Literal("load"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"load")
|
||||||
->Then((new CmdHelper::Choice("stage", { "deep", "shallow"}))
|
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"stage", { u8"deep", u8"shallow"})
|
||||||
->Comment("The stage of loading. 'deep' will load to CKObject stage. 'shallow' will load to CKStateChunk stage.")
|
.Comment(u8"The stage of loading. 'deep' will load to CKObject stage. 'shallow' will load to CKStateChunk stage.")
|
||||||
->Then((new CmdHelper::StringArgument("filepath"))
|
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"filepath")
|
||||||
->Comment("The path to loading file.")
|
.Comment(u8"The path to loading file.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcLoad, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcLoad, this, std::placeholders::_1),
|
||||||
"Load a Virtools composition."
|
u8"Load a Virtools composition."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("unload"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"unload")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcUnLoad, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcUnLoad, this, std::placeholders::_1),
|
||||||
"Release loaded Virtools composition."
|
u8"Release loaded Virtools composition."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("save"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"save")
|
||||||
->Then((new CmdHelper::StringArgument("filepath"))
|
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"filepath")
|
||||||
->Comment("The path to save file.")
|
.Comment(u8"The path to save file.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcSave, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcSave, this, std::placeholders::_1),
|
||||||
"Save the loaded file into a new file."
|
u8"Save the loaded file into a new file."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("info"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"info")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcInfo, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcInfo, this, std::placeholders::_1),
|
||||||
"Show the header info of loaded Virtools composition."
|
u8"Show the header info of loaded Virtools composition."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("ls"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"ls")
|
||||||
->Then((new CmdHelper::Choice("part", { "obj", "mgr", "search"}))
|
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"part", { u8"obj", u8"mgr", u8"search"})
|
||||||
->Comment("Which list you want to list.")
|
.Comment(u8"Which list you want to list.")
|
||||||
->Then((new CmdHelper::IntArgument("page", [](int32_t v) -> bool { return v > 0; }))
|
.Then<CmdHelper::Nodes::ArithmeticArgument<size_t>>(CmdHelper::Nodes::ArithmeticArgument<size_t>(u8"page", GetOneBasedIndexConstraint())
|
||||||
->Comment("The page index. Start with 1.")
|
.Comment(u8"The page index. Start with 1.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcLs, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcLs, this, std::placeholders::_1),
|
||||||
"List something about loaded Virtools composition."
|
u8"List something about loaded Virtools composition."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("data"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"data")
|
||||||
->Then((new CmdHelper::Choice("part", { "obj", "mgr"}))
|
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"part", { u8"obj", u8"mgr"})
|
||||||
->Comment("Which list you want to show data.")
|
.Comment(u8"Which list you want to show data.")
|
||||||
->Then((new CmdHelper::IntArgument("index", [](int32_t v) -> bool { return v >= 0; }))
|
.Then<CmdHelper::Nodes::ArithmeticArgument<size_t>>(CmdHelper::Nodes::ArithmeticArgument<size_t>(u8"index")
|
||||||
->Comment("The index. Start with 0.")
|
.Comment(u8"The index. Start with 0.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcData, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcData, this, std::placeholders::_1),
|
||||||
"Show the specific CKObject / CKBaseManager data."
|
u8"Show the specific CKObject / CKBaseManager data."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("chunk"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"chunk")
|
||||||
->Then((new CmdHelper::Choice("part", { "obj", "mgr"}))
|
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"part", { u8"obj", u8"mgr"})
|
||||||
->Comment("Which list you want to show chunk.")
|
.Comment(u8"Which list you want to show chunk.")
|
||||||
->Then((new CmdHelper::IntArgument("index", [](int32_t v) -> bool { return v >= 0; }))
|
.Then<CmdHelper::Nodes::ArithmeticArgument<size_t>>(CmdHelper::Nodes::ArithmeticArgument<size_t>(u8"index")
|
||||||
->Comment("The index. Start with 0.")
|
.Comment(u8"The index. Start with 0.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcChunk, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcChunk, this, std::placeholders::_1),
|
||||||
"Show the specific CKStateChunk data."
|
u8"Show the specific CKStateChunk data."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("search"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"search")
|
||||||
->Then((new CmdHelper::Choice("part", { "obj", "mgr"}))
|
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"part", { u8"obj", u8"mgr"})
|
||||||
->Comment("Which list you want to search.")
|
.Comment(u8"Which list you want to search.")
|
||||||
->Then((new CmdHelper::Choice("mode", { "plain", "re"}))
|
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"mode", { u8"plain", u8"re"})
|
||||||
->Comment("The search mode. `plain` will search by substring and `re` will do regex search.")
|
.Comment(u8"The search mode. `plain` will search by substring and `re` will do regex search.")
|
||||||
->Then((new CmdHelper::StringArgument("text"))
|
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"text")
|
||||||
->Comment("The text or regex to search.")
|
.Comment(u8"The text or regex to search.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcSearch, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcSearch, this, std::placeholders::_1),
|
||||||
"Search object or manager by text or regex. Please note that the regex have limited UTF8 support and may cause undefined behavior."
|
u8"Search object or manager by text or regex. Please note that the regex have limited UTF8 support and may cause undefined behavior."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("items"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"items")
|
||||||
->Then((new CmdHelper::IntArgument("count", [](int32_t v) -> bool { return v > 0; }))
|
.Then<CmdHelper::Nodes::ArithmeticArgument<size_t>>(CmdHelper::Nodes::ArithmeticArgument<size_t>(u8"count", GetOneBasedIndexConstraint())
|
||||||
->Comment("The count of items you want to show in one page.")
|
.Comment(u8"The count of items you want to show in one page.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcItems, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcItems, this, std::placeholders::_1),
|
||||||
"Set up how many items should be listed in one page when using 'ls' command."
|
u8"Set up how many items should be listed in one page when using 'ls' command."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("style"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"style")
|
||||||
->Then((new CmdHelper::Choice("level", { "full", "simple"}))
|
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"level", { u8"full", u8"simple"})
|
||||||
->Comment("The amount of showen content.")
|
.Comment(u8"The amount of showen content.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcStyle, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcStyle, this, std::placeholders::_1),
|
||||||
"Change the detail level of showen data in `ls` command."
|
u8"Change the detail level of showen data in `ls` command."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("encoding"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"encoding")
|
||||||
->Then((new CmdHelper::EncodingArgument("enc"))
|
.Then<CmdHelper::Nodes::EncodingListArgument>(CmdHelper::Nodes::EncodingListArgument(u8"enc")
|
||||||
->Comment("CKContext used encoding splitted by ','. Support mutiple encoding.")
|
.Comment(u8"CKContext used encoding splitted by ','. Support mutiple encoding.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcEncoding, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcEncoding, this, std::placeholders::_1),
|
||||||
"Set the encoding series for CKContext."
|
u8"Set the encoding series for CKContext."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("temp"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"temp")
|
||||||
->Then((new CmdHelper::StringArgument("temppath"))
|
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"temppath")
|
||||||
->Comment("The path to Temp folder.")
|
.Comment(u8"The path to Temp folder.")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcTemp, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcTemp, this, std::placeholders::_1),
|
||||||
"Set the Temp path for CKContext."
|
u8"Set the Temp path for CKContext."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("rsc"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"rsc")
|
||||||
->Then((new CmdHelper::Literal("clear"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"clear")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcRsc, this, std::placeholders::_1, true),
|
std::bind(&UnvirtContext::ProcRsc, this, std::placeholders::_1, true),
|
||||||
"Clear all data resources paths."
|
u8"Clear all data resources paths."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("add"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"add")
|
||||||
->Then((new CmdHelper::StringArgument("datares"))
|
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"datares")
|
||||||
->Comment("The data resources path .")
|
.Comment(u8"The data resources path .")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcRsc, this, std::placeholders::_1, false),
|
std::bind(&UnvirtContext::ProcRsc, this, std::placeholders::_1, false),
|
||||||
"Add a path to let Virtools find resources."
|
u8"Add a path to let Virtools find resources."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("test"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"test")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcTest, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcTest, this, std::placeholders::_1),
|
||||||
"Call custom debugging function (only available in Debug mode)."
|
u8"Call custom debugging function (only available in Debug mode)."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("help"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"help")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcHelp, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcHelp, this, std::placeholders::_1),
|
||||||
"Output this help page."
|
u8"Output this help page."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->Then((new CmdHelper::Literal("exit"))
|
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"exit")
|
||||||
->Executes(
|
.Executes(
|
||||||
std::bind(&UnvirtContext::ProcExit, this, std::placeholders::_1),
|
std::bind(&UnvirtContext::ProcExit, this, std::placeholders::_1),
|
||||||
"Exit program."
|
u8"Exit program."
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// create help
|
// create help document
|
||||||
m_Help = root->RootHelp();
|
m_Help = m_Parser.Help();
|
||||||
|
|
||||||
// create context
|
// initialize CK engine and create context
|
||||||
LibCmo::CK2::CKStartUp();
|
LibCmo::CK2::CKERROR err = LibCmo::CK2::CKStartUp();
|
||||||
|
if (err != LibCmo::CK2::CKERROR::CKERR_OK)
|
||||||
|
throw std::runtime_error("fail to initialize CK2 engine.");
|
||||||
m_Ctx = new LibCmo::CK2::CKContext();
|
m_Ctx = new LibCmo::CK2::CKContext();
|
||||||
m_Ctx->SetOutputCallback(std::bind(&UnvirtContext::PrintContextMsg, this, std::placeholders::_1));
|
m_Ctx->SetOutputCallback(std::bind(&UnvirtContext::PrintContextMsg, this, std::placeholders::_1));
|
||||||
m_Ctx->SetGlobalImagesSaveOptions(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL);
|
m_Ctx->SetGlobalImagesSaveOptions(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnvirtContext::~UnvirtContext() {
|
UnvirtContext::~UnvirtContext() {
|
||||||
if (m_Help != nullptr)
|
// free context and shutdown CK engine.
|
||||||
delete m_Help;
|
|
||||||
|
|
||||||
// free context
|
|
||||||
ClearDocument();
|
ClearDocument();
|
||||||
delete m_Ctx;
|
delete m_Ctx;
|
||||||
LibCmo::CK2::CKShutdown();
|
LibCmo::CK2::CKShutdown();
|
||||||
|
@ -212,26 +227,26 @@ namespace Unvirt::Context {
|
||||||
|
|
||||||
void UnvirtContext::PrintContextMsg(LibCmo::CKSTRING msg) {
|
void UnvirtContext::PrintContextMsg(LibCmo::CKSTRING msg) {
|
||||||
if (msg != nullptr) {
|
if (msg != nullptr) {
|
||||||
fprintf(stdout, UNVIRT_TERMCOL_LIGHT_YELLOW(("[CKContext] ")) "%s\n", msg);
|
YYCC::ConsoleHelper::FormatLine(YYCC_COLOR_LIGHT_YELLOW(u8"[CKContext] ") "%s", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::PrintCommonInfo(const char* u8_fmt, ...) {
|
void UnvirtContext::PrintCommonInfo(const char8_t* u8_fmt, ...) {
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, u8_fmt);
|
va_start(argptr, u8_fmt);
|
||||||
std::vfprintf(stdout, u8_fmt, argptr);
|
YYCC::ConsoleHelper::WriteLine(
|
||||||
|
YYCC::StringHelper::VPrintf(u8_fmt, argptr).c_str()
|
||||||
|
);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
std::fputc('\n', stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::PrintCommonError(const char* u8_fmt, ...) {
|
void UnvirtContext::PrintCommonError(const char8_t* u8_fmt, ...) {
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, u8_fmt);
|
va_start(argptr, u8_fmt);
|
||||||
std::fputs(UNVIRT_TERMCOLHDR_LIGHT_RED, stdout);
|
YYCC::ConsoleHelper::FormatLine(YYCC_COLOR_LIGHT_RED(u8"%s"),
|
||||||
std::vfprintf(stdout, u8_fmt, argptr);
|
YYCC::StringHelper::VPrintf(u8_fmt, argptr).c_str()
|
||||||
std::fputs(UNVIRT_TERMCOLTAIL, stdout);
|
);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
std::fputc('\n', stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
@ -239,23 +254,34 @@ namespace Unvirt::Context {
|
||||||
#pragma region Main Run
|
#pragma region Main Run
|
||||||
|
|
||||||
void UnvirtContext::Run() {
|
void UnvirtContext::Run() {
|
||||||
Unvirt::TerminalHelper::EnsureTerminalColor();
|
// Enable terminal color feature
|
||||||
Unvirt::TerminalHelper::EnsureTerminalEncoding();
|
YYCC::ConsoleHelper::EnableColorfulConsole();
|
||||||
std::string u8cmd;
|
|
||||||
|
|
||||||
|
// Show banner
|
||||||
|
YYCC::ConsoleHelper::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"Unvirt"));
|
||||||
|
YYCC::ConsoleHelper::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"Type 'help' for more infomation. Type 'exit' to quit."));
|
||||||
|
|
||||||
|
// start process loop
|
||||||
while (true) {
|
while (true) {
|
||||||
// get command
|
// get command
|
||||||
TerminalHelper::GetCmdLine(u8cmd);
|
YYCC::ConsoleHelper::Write(YYCC_COLOR_GREEN(u8"> "));
|
||||||
|
std::u8string u8cmd = YYCC::ConsoleHelper::ReadLine();
|
||||||
|
|
||||||
// split cmd and parse it
|
// lex command line first
|
||||||
auto cmds = m_Splitter.Convert(u8cmd);
|
if (!m_Splitter.Lex(u8cmd)) {
|
||||||
|
this->PrintCommonError(u8"Lexer error \"%s\".\nType 'help' for usage.", u8cmd.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// if result is empty, skip to next one
|
||||||
|
auto cmds = m_Splitter.GetResult();
|
||||||
if (cmds.empty()) continue;
|
if (cmds.empty()) continue;
|
||||||
|
|
||||||
// get sub command
|
// run command parser
|
||||||
if (!m_Root.RootConsume(cmds)) {
|
if (!m_Parser.Parse(cmds)) {
|
||||||
this->PrintCommonError("Syntax error \"%s\".\nType 'help' for usage.", u8cmd.c_str());
|
this->PrintCommonError(u8"Parser error \"%s\".\nType 'help' for usage.", u8cmd.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check whether sub processor need exit.
|
||||||
if (m_OrderExit) {
|
if (m_OrderExit) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -266,15 +292,20 @@ namespace Unvirt::Context {
|
||||||
|
|
||||||
#pragma region Proc Detail
|
#pragma region Proc Detail
|
||||||
|
|
||||||
void UnvirtContext::ProcLoad(const CmdHelper::ArgumentsMap* amap) {
|
void UnvirtContext::ProcLoad(const CmdHelper::ArgumentsMap& amap) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (HasOpenedFile()) {
|
if (HasOpenedFile()) {
|
||||||
PrintCommonError("Already have a opened file. Close it before calling 'load'.");
|
PrintCommonError(u8"Already have a opened file. Close it before calling 'load'.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!m_Ctx->IsValidEncoding()) {
|
||||||
|
PrintCommonError(u8"You have not set encoding properly. Set it before loading by calling 'encoding'.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string filepath = *amap->Get<CmdHelper::StringArgument::vType>("filepath");
|
// get argument
|
||||||
bool is_deep = *amap->Get<CmdHelper::Choice::vType>("stage") == 0;
|
std::u8string filepath = amap.Get<CmdHelper::Nodes::StringArgument::ArgValue_t>(u8"filepath").Get();
|
||||||
|
bool is_deep = amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"stage").Get() == 0u;
|
||||||
|
|
||||||
// proc
|
// proc
|
||||||
m_FileReader = new LibCmo::CK2::CKFileReader(m_Ctx);
|
m_FileReader = new LibCmo::CK2::CKFileReader(m_Ctx);
|
||||||
|
@ -288,7 +319,7 @@ namespace Unvirt::Context {
|
||||||
}
|
}
|
||||||
if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
|
if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
|
||||||
// fail to load. release all.
|
// fail to load. release all.
|
||||||
PrintCommonError("Fail to load file. Function return: %s\n\t%s",
|
PrintCommonError(u8"Fail to load file. Function return: %s\n\t%s",
|
||||||
Unvirt::AccessibleValue::GetCkErrorName(err).c_str(),
|
Unvirt::AccessibleValue::GetCkErrorName(err).c_str(),
|
||||||
Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str()
|
Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str()
|
||||||
);
|
);
|
||||||
|
@ -297,10 +328,10 @@ namespace Unvirt::Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcUnLoad(const CmdHelper::ArgumentsMap*) {
|
void UnvirtContext::ProcUnLoad(const CmdHelper::ArgumentsMap&) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
this->PrintCommonError("No loaded file.");
|
this->PrintCommonError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,14 +339,18 @@ namespace Unvirt::Context {
|
||||||
ClearDocument();
|
ClearDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unvirt::Context::UnvirtContext::ProcSave(const CmdHelper::ArgumentsMap* amap) {
|
void Unvirt::Context::UnvirtContext::ProcSave(const CmdHelper::ArgumentsMap& amap) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError("No loaded file.");
|
PrintCommonError(u8"No loaded file.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!m_Ctx->IsValidEncoding()) {
|
||||||
|
PrintCommonError(u8"You have not set encoding properly. Set it before saving by calling 'encoding'.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string filepath = *amap->Get<CmdHelper::StringArgument::vType>("filepath");
|
std::u8string filepath = amap.Get<CmdHelper::Nodes::StringArgument::ArgValue_t>(u8"filepath").Get();
|
||||||
|
|
||||||
// construct writer from reader
|
// construct writer from reader
|
||||||
LibCmo::CK2::CKFileWriter writer(m_Ctx, m_FileReader, m_IsShallowRead);
|
LibCmo::CK2::CKFileWriter writer(m_Ctx, m_FileReader, m_IsShallowRead);
|
||||||
|
@ -329,7 +364,7 @@ namespace Unvirt::Context {
|
||||||
LibCmo::CK2::CKERROR err = writer.Save(filepath.c_str());
|
LibCmo::CK2::CKERROR err = writer.Save(filepath.c_str());
|
||||||
if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
|
if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
|
||||||
// fail to load. release all.
|
// fail to load. release all.
|
||||||
PrintCommonError("Fail to save file. Function return: %s\n\t%s",
|
PrintCommonError(u8"Fail to save file. Function return: %s\n\t%s",
|
||||||
Unvirt::AccessibleValue::GetCkErrorName(err).c_str(),
|
Unvirt::AccessibleValue::GetCkErrorName(err).c_str(),
|
||||||
Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str()
|
Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str()
|
||||||
);
|
);
|
||||||
|
@ -340,10 +375,10 @@ namespace Unvirt::Context {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcInfo(const CmdHelper::ArgumentsMap*) {
|
void UnvirtContext::ProcInfo(const CmdHelper::ArgumentsMap&) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError("No loaded file.");
|
PrintCommonError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,46 +386,46 @@ namespace Unvirt::Context {
|
||||||
Unvirt::StructFormatter::PrintCKFileInfo(m_FileReader->GetFileInfo());
|
Unvirt::StructFormatter::PrintCKFileInfo(m_FileReader->GetFileInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcLs(const CmdHelper::ArgumentsMap* amap) {
|
void UnvirtContext::ProcLs(const CmdHelper::ArgumentsMap& amap) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError("No loaded file.");
|
PrintCommonError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get 0 based page (-1)
|
// get 0 based page (-1)
|
||||||
size_t page = *amap->Get<CmdHelper::IntArgument::vType>("page") - 1;
|
size_t page = amap.Get<CmdHelper::Nodes::ArithmeticArgument<size_t>::ArgValue_t>(u8"page").Get() - 1u;
|
||||||
|
|
||||||
// show list
|
// show list
|
||||||
switch (*amap->Get<CmdHelper::Choice::vType>("part")) {
|
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"part").Get()) {
|
||||||
case 0:
|
case 0u:
|
||||||
{
|
{
|
||||||
// obj list
|
// obj list
|
||||||
Unvirt::StructFormatter::PrintObjectList(
|
Unvirt::StructFormatter::PrintObjectList(
|
||||||
m_FileReader->GetFileObjects(),
|
m_FileReader->GetFileObjects(),
|
||||||
m_FileReader->GetFileInfo(),
|
m_FileReader->GetFileInfo(),
|
||||||
page, this->m_PageLen,
|
page, this->m_PageLen,
|
||||||
m_ListStyleIsFull
|
m_ListStyleIsFull
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1u:
|
||||||
{
|
{
|
||||||
// mgr list
|
// mgr list
|
||||||
Unvirt::StructFormatter::PrintManagerList(
|
Unvirt::StructFormatter::PrintManagerList(
|
||||||
m_FileReader->GetManagersData(),
|
m_FileReader->GetManagersData(),
|
||||||
page, this->m_PageLen,
|
page, this->m_PageLen,
|
||||||
m_ListStyleIsFull
|
m_ListStyleIsFull
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2u:
|
||||||
{
|
{
|
||||||
// search list
|
// search list
|
||||||
switch (m_SearchPart) {
|
switch (m_SearchPart) {
|
||||||
case SearchPart::None:
|
case SearchPart::None:
|
||||||
{
|
{
|
||||||
PrintCommonError("No search result to list.");
|
PrintCommonError(u8"No search result to list.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SearchPart::Object:
|
case SearchPart::Object:
|
||||||
|
@ -417,60 +452,64 @@ namespace Unvirt::Context {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unreachable code");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcData( const CmdHelper::ArgumentsMap* amap) {
|
void UnvirtContext::ProcData(const CmdHelper::ArgumentsMap& amap) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError("No loaded file.");
|
PrintCommonError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get index
|
// get index
|
||||||
size_t index = *amap->Get<CmdHelper::IntArgument::vType>("index");
|
size_t index = amap.Get<CmdHelper::Nodes::ArithmeticArgument<size_t>::ArgValue_t>(u8"index").Get();
|
||||||
|
|
||||||
// show data
|
// show data
|
||||||
switch (*amap->Get<CmdHelper::Choice::vType>("part")) {
|
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"part").Get()) {
|
||||||
case 0:
|
case 0u:
|
||||||
{
|
{
|
||||||
if (index >= m_FileReader->GetFileObjects().size()) {
|
if (index >= m_FileReader->GetFileObjects().size()) {
|
||||||
PrintCommonError("Index out of range.");
|
PrintCommonError(u8"Index out of range.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Unvirt::StructFormatter::PrintCKObject(m_FileReader->GetFileObjects()[index].ObjPtr);
|
Unvirt::StructFormatter::PrintCKObject(m_FileReader->GetFileObjects()[index].ObjPtr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1u:
|
||||||
{
|
{
|
||||||
if (index >= m_FileReader->GetManagersData().size()) {
|
if (index >= m_FileReader->GetManagersData().size()) {
|
||||||
PrintCommonError("Index out of range.");
|
PrintCommonError(u8"Index out of range.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// todo: finish manager display
|
// todo: finish manager display
|
||||||
PrintCommonError("Not supported now.");
|
PrintCommonError(u8"Not supported now.");
|
||||||
//Unvirt::StructFormatter::PrintCKBaseManager(m_FileReader->GetManagersData()[index].Data);
|
//Unvirt::StructFormatter::PrintCKBaseManager(m_FileReader->GetManagersData()[index].Data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unreachable code");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcChunk(const CmdHelper::ArgumentsMap* amap) {
|
void UnvirtContext::ProcChunk(const CmdHelper::ArgumentsMap& amap) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError("No loaded file.");
|
PrintCommonError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get index
|
// get index
|
||||||
size_t index = *amap->Get<CmdHelper::IntArgument::vType>("index");
|
size_t index = amap.Get<CmdHelper::Nodes::ArithmeticArgument<size_t>::ArgValue_t>(u8"index").Get();
|
||||||
|
|
||||||
// show data
|
// show data
|
||||||
switch (*amap->Get<CmdHelper::Choice::vType>("part")) {
|
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"part").Get()) {
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
if (index >= m_FileReader->GetFileObjects().size()) {
|
if (index >= m_FileReader->GetFileObjects().size()) {
|
||||||
PrintCommonError("Index out of range.");
|
PrintCommonError(u8"Index out of range.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Unvirt::StructFormatter::PrintCKStateChunk(m_FileReader->GetFileObjects()[index].Data);
|
Unvirt::StructFormatter::PrintCKStateChunk(m_FileReader->GetFileObjects()[index].Data);
|
||||||
|
@ -479,29 +518,31 @@ namespace Unvirt::Context {
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if (index >= m_FileReader->GetManagersData().size()) {
|
if (index >= m_FileReader->GetManagersData().size()) {
|
||||||
PrintCommonError("Index out of range.");
|
PrintCommonError(u8"Index out of range.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Unvirt::StructFormatter::PrintCKStateChunk(m_FileReader->GetManagersData()[index].Data);
|
Unvirt::StructFormatter::PrintCKStateChunk(m_FileReader->GetManagersData()[index].Data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unreachable code");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcSearch(const CmdHelper::ArgumentsMap* amap) {
|
void UnvirtContext::ProcSearch(const CmdHelper::ArgumentsMap& amap) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError("No loaded file.");
|
PrintCommonError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get search text
|
// get search text *amap->Get<CmdHelper::StringArgument::vType>("text")
|
||||||
std::string search_text(*amap->Get<CmdHelper::StringArgument::vType>("text"));
|
std::u8string search_text = amap.Get<CmdHelper::Nodes::StringArgument::ArgValue_t>(u8"text").Get();
|
||||||
|
|
||||||
// analyse search mode
|
// analyse search mode
|
||||||
std::function<bool(const LibCmo::XContainer::XString&)> search_fct = [](const LibCmo::XContainer::XString&) -> bool { return false; };
|
std::function<bool(const LibCmo::XContainer::XString&)> search_fct = nullptr;
|
||||||
switch (*amap->Get<CmdHelper::Choice::vType>("mode")) {
|
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"mode").Get()) {
|
||||||
case 0:
|
case 0u:
|
||||||
{
|
{
|
||||||
// plain mode
|
// plain mode
|
||||||
search_fct = [&search_text](const LibCmo::XContainer::XString& cmp) -> bool {
|
search_fct = [&search_text](const LibCmo::XContainer::XString& cmp) -> bool {
|
||||||
|
@ -509,31 +550,37 @@ namespace Unvirt::Context {
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1u:
|
||||||
{
|
{
|
||||||
// regex mode
|
// regex mode
|
||||||
|
|
||||||
|
// get ordinary search text
|
||||||
|
std::string ordinary_search_text = YYCC::EncodingHelper::ToOrdinary(search_text);
|
||||||
// try construct regex
|
// try construct regex
|
||||||
std::regex re;
|
std::regex re;
|
||||||
try {
|
try {
|
||||||
re = std::regex(search_text, std::regex_constants::ECMAScript);
|
re = std::regex(ordinary_search_text, std::regex_constants::ECMAScript);
|
||||||
} catch (const std::regex_error& e) {
|
} catch (const std::regex_error& e) {
|
||||||
PrintCommonError("Invalid regular expressions: %s", e.what());
|
PrintCommonError(u8"Invalid regular expressions: %s", e.what());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// use copy ctor capture to input regex
|
// use copy ctor capture to input regex
|
||||||
// because re will be freed when exiting this switch.
|
// because re will be freed when exiting this switch.
|
||||||
search_fct = [re](const LibCmo::XContainer::XString& cmp) -> bool {
|
search_fct = [re](const LibCmo::XContainer::XString& cmp) -> bool {
|
||||||
return std::regex_search(cmp, re);
|
// get ordinary name and comapre
|
||||||
|
std::string ordinary_cmp = YYCC::EncodingHelper::ToOrdinary(cmp);
|
||||||
|
return std::regex_search(ordinary_cmp, re);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unreachable code");
|
||||||
}
|
}
|
||||||
|
|
||||||
// start search
|
// start search
|
||||||
switch (*amap->Get<CmdHelper::Choice::vType>("part")) {
|
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"part").Get()) {
|
||||||
case 0:
|
case 0u:
|
||||||
{
|
{
|
||||||
// object
|
// object
|
||||||
m_SearchPart = SearchPart::Object;
|
m_SearchPart = SearchPart::Object;
|
||||||
|
@ -549,85 +596,91 @@ namespace Unvirt::Context {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1u:
|
||||||
{
|
{
|
||||||
// manager
|
// manager
|
||||||
m_SearchPart = SearchPart::Manager;
|
m_SearchPart = SearchPart::Manager;
|
||||||
m_SearchIdxResult.clear();
|
m_SearchIdxResult.clear();
|
||||||
PrintCommonError("Not supported now.");
|
PrintCommonError(u8"Not supported now.");
|
||||||
// todo: remove this return when fixing manager searching.
|
// todo: remove this return when fixing manager searching.
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unreachable code");
|
||||||
}
|
}
|
||||||
|
|
||||||
// report search result
|
// report search result
|
||||||
if (m_SearchIdxResult.empty()) {
|
if (m_SearchIdxResult.empty()) {
|
||||||
PrintCommonInfo("Search done, but no result.");
|
PrintCommonInfo(u8"Search done, but no result.");
|
||||||
} else {
|
} else {
|
||||||
PrintCommonInfo("Search done with %" PRIuSIZET " results. Use `ls search` to check them.", m_SearchIdxResult.size());
|
PrintCommonInfo(u8"Search done with %" PRIuSIZET " results. Use `ls search` to check them.", m_SearchIdxResult.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcItems(const CmdHelper::ArgumentsMap* amap) {
|
void UnvirtContext::ProcItems(const CmdHelper::ArgumentsMap& amap) {
|
||||||
// assign
|
// assign
|
||||||
m_PageLen = *amap->Get<CmdHelper::IntArgument::vType>("count");
|
m_PageLen = amap.Get<CmdHelper::Nodes::ArithmeticArgument<size_t>::ArgValue_t>(u8"count").Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcStyle(const CmdHelper::ArgumentsMap* amap) {
|
void UnvirtContext::ProcStyle(const CmdHelper::ArgumentsMap& amap) {
|
||||||
// set list style level
|
// set list style level
|
||||||
switch (*amap->Get<CmdHelper::Choice::vType>("level")) {
|
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"level").Get()) {
|
||||||
case 0:
|
case 0u:
|
||||||
{
|
{
|
||||||
// full level
|
// full level
|
||||||
m_ListStyleIsFull = true;
|
m_ListStyleIsFull = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1u:
|
||||||
{
|
{
|
||||||
// simple level
|
// simple level
|
||||||
m_ListStyleIsFull = false;
|
m_ListStyleIsFull = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unreachable code");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcEncoding(const CmdHelper::ArgumentsMap* amap) {
|
void UnvirtContext::ProcEncoding(const CmdHelper::ArgumentsMap& amap) {
|
||||||
const auto& encodings = *amap->Get<CmdHelper::EncodingArgument::vType>("enc");
|
const auto& encodings = amap.Get<CmdHelper::Nodes::EncodingListArgument::ArgValue_t>(u8"enc").Get();
|
||||||
m_Ctx->SetEncoding(encodings);
|
m_Ctx->SetEncoding(encodings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcTemp(const CmdHelper::ArgumentsMap* amap) {
|
void UnvirtContext::ProcTemp(const CmdHelper::ArgumentsMap& amap) {
|
||||||
// assign
|
// assign
|
||||||
if (!m_Ctx->GetPathManager()->SetTempFolder(amap->Get<CmdHelper::StringArgument::vType>("temppath")->c_str())) {
|
std::u8string temp_path = amap.Get<CmdHelper::Nodes::StringArgument::ArgValue_t>(u8"temppath").Get();
|
||||||
PrintCommonError("Set temp folder failed. Check your path first.");
|
if (!m_Ctx->GetPathManager()->SetTempFolder(temp_path.c_str())) {
|
||||||
|
PrintCommonError(u8"Set temp folder failed. Check your path first.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unvirt::Context::UnvirtContext::ProcRsc(const CmdHelper::ArgumentsMap* amap, bool isClear) {
|
void Unvirt::Context::UnvirtContext::ProcRsc(const CmdHelper::ArgumentsMap& amap, bool is_clear) {
|
||||||
if (isClear) {
|
if (is_clear) {
|
||||||
m_Ctx->GetPathManager()->ClearPath();
|
m_Ctx->GetPathManager()->ClearPath();
|
||||||
} else {
|
} else {
|
||||||
if (!m_Ctx->GetPathManager()->AddPath(amap->Get<CmdHelper::StringArgument::vType>("datares")->c_str())) {
|
std::u8string data_res = amap.Get<CmdHelper::Nodes::StringArgument::ArgValue_t>(u8"datares").Get();
|
||||||
PrintCommonError("Set data resource folder failed. Check your path first.");
|
if (!m_Ctx->GetPathManager()->AddPath(data_res.c_str())) {
|
||||||
|
PrintCommonError(u8"Set data resource folder failed. Check your path first.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unvirt::Context::UnvirtContext::ProcTest(const CmdHelper::ArgumentsMap* amap) {
|
void Unvirt::Context::UnvirtContext::ProcTest(const CmdHelper::ArgumentsMap& amap) {
|
||||||
#if defined(LIBCMO_BUILD_DEBUG)
|
#if defined(LIBCMO_BUILD_DEBUG)
|
||||||
// MARK: Add the debug code here.
|
// MARK: Add the debug code here.
|
||||||
|
|
||||||
// todo: temporaryly write Transparent Column Fixer code.
|
// todo: temporaryly write Transparent Column Fixer code.
|
||||||
// move to independent app in future.
|
// move to independent app in future.
|
||||||
|
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError("No loaded file.");
|
PrintCommonError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!m_IsShallowRead) {
|
if (!m_IsShallowRead) {
|
||||||
PrintCommonError("Transparent Column Fixer only accept shallow loaded file.");
|
PrintCommonError(u8"Transparent Column Fixer only accept shallow loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,21 +706,21 @@ namespace Unvirt::Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
PrintCommonError("Test command only available in Debug mode.");
|
PrintCommonError(u8"Test command only available in Debug mode.");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unvirt::Context::UnvirtContext::ProcHelp(const CmdHelper::ArgumentsMap&) {
|
||||||
|
m_Help.Print();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unvirt::Context::UnvirtContext::ProcHelp(const CmdHelper::ArgumentsMap*) {
|
void UnvirtContext::ProcExit(const CmdHelper::ArgumentsMap&) {
|
||||||
m_Help->Print();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnvirtContext::ProcExit(const CmdHelper::ArgumentsMap*) {
|
|
||||||
m_OrderExit = true;
|
m_OrderExit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,9 @@
|
||||||
#include <VTAll.hpp>
|
#include <VTAll.hpp>
|
||||||
|
|
||||||
#include "AccessibleValue.hpp"
|
#include "AccessibleValue.hpp"
|
||||||
#include "TerminalHelper.hpp"
|
|
||||||
#include "StructFormatter.hpp"
|
#include "StructFormatter.hpp"
|
||||||
#include "CmdHelper.hpp"
|
#include "CmdHelper.hpp"
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace Unvirt::Context {
|
namespace Unvirt::Context {
|
||||||
|
|
||||||
class UnvirtContext {
|
class UnvirtContext {
|
||||||
|
@ -23,39 +19,39 @@ namespace Unvirt::Context {
|
||||||
enum class SearchPart {
|
enum class SearchPart {
|
||||||
None, Object, Manager
|
None, Object, Manager
|
||||||
};
|
};
|
||||||
void PrintCommonInfo(const char* u8_fmt, ...);
|
void PrintCommonInfo(const char8_t* u8_fmt, ...);
|
||||||
void PrintCommonError(const char* u8_fmt, ...);
|
void PrintCommonError(const char8_t* u8_fmt, ...);
|
||||||
|
|
||||||
void ProcLoad(const CmdHelper::ArgumentsMap* amap);
|
void ProcLoad(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcUnLoad(const CmdHelper::ArgumentsMap* amap);
|
void ProcUnLoad(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcSave(const CmdHelper::ArgumentsMap* amap);
|
void ProcSave(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcInfo(const CmdHelper::ArgumentsMap* amap);
|
void ProcInfo(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcLs(const CmdHelper::ArgumentsMap* amap);
|
void ProcLs(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcData(const CmdHelper::ArgumentsMap* amap);
|
void ProcData(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcChunk(const CmdHelper::ArgumentsMap* amap);
|
void ProcChunk(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcSearch(const CmdHelper::ArgumentsMap* amap);
|
void ProcSearch(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcItems(const CmdHelper::ArgumentsMap* amap);
|
void ProcItems(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcStyle(const CmdHelper::ArgumentsMap* amap);
|
void ProcStyle(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcEncoding(const CmdHelper::ArgumentsMap* amap);
|
void ProcEncoding(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcTemp(const CmdHelper::ArgumentsMap* amap);
|
void ProcTemp(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcRsc(const CmdHelper::ArgumentsMap* amap, bool isClear);
|
void ProcRsc(const CmdHelper::ArgumentsMap& amap, bool is_clear);
|
||||||
void ProcTest(const CmdHelper::ArgumentsMap* amap);
|
void ProcTest(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcHelp(const CmdHelper::ArgumentsMap* amap);
|
void ProcHelp(const CmdHelper::ArgumentsMap& amap);
|
||||||
void ProcExit(const CmdHelper::ArgumentsMap* amap);
|
void ProcExit(const CmdHelper::ArgumentsMap& amap);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool HasOpenedFile();
|
bool HasOpenedFile();
|
||||||
void ClearDocument();
|
void ClearDocument();
|
||||||
void PrintContextMsg(LibCmo::CKSTRING msg);
|
void PrintContextMsg(LibCmo::CKSTRING msg);
|
||||||
|
|
||||||
CmdHelper::CommandRoot m_Root;
|
|
||||||
CmdHelper::HelpDocument* m_Help;
|
|
||||||
CmdHelper::CmdSplitter m_Splitter;
|
CmdHelper::CmdSplitter m_Splitter;
|
||||||
|
CmdHelper::CommandParser m_Parser;
|
||||||
|
CmdHelper::HelpDocument m_Help;
|
||||||
|
|
||||||
size_t m_PageLen;
|
size_t m_PageLen;
|
||||||
bool m_ListStyleIsFull;
|
bool m_ListStyleIsFull;
|
||||||
SearchPart m_SearchPart;
|
SearchPart m_SearchPart;
|
||||||
LibCmo::XContainer::XArray<size_t> m_SearchIdxResult;
|
std::vector<size_t> m_SearchIdxResult;
|
||||||
|
|
||||||
bool m_OrderExit;
|
bool m_OrderExit;
|
||||||
LibCmo::CK2::CKContext* m_Ctx;
|
LibCmo::CK2::CKContext* m_Ctx;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user