refactor: finish unvirt context refactor
This commit is contained in:
@@ -36,7 +36,7 @@ namespace Unvirt::CmdHelper {
|
|||||||
|
|
||||||
struct LsParam {
|
struct LsParam {
|
||||||
LsPart part;
|
LsPart part;
|
||||||
size_t page;
|
size_t page; ///< One-based page.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class DataPart {
|
enum class DataPart {
|
||||||
@@ -46,7 +46,7 @@ namespace Unvirt::CmdHelper {
|
|||||||
|
|
||||||
struct DataParam {
|
struct DataParam {
|
||||||
DataPart part;
|
DataPart part;
|
||||||
size_t index;
|
size_t index; ///< Zero-based index
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ChunkPart {
|
enum class ChunkPart {
|
||||||
@@ -56,7 +56,7 @@ namespace Unvirt::CmdHelper {
|
|||||||
|
|
||||||
struct ChunkParam {
|
struct ChunkParam {
|
||||||
ChunkPart part;
|
ChunkPart part;
|
||||||
size_t index;
|
size_t index; ///< Zero-based index
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SearchPart {
|
enum class SearchPart {
|
||||||
@@ -76,7 +76,7 @@ namespace Unvirt::CmdHelper {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ItemsParam {
|
struct ItemsParam {
|
||||||
size_t count;
|
size_t count; ///< The lowest value is one.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class StyleLevel {
|
enum class StyleLevel {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <yycc.hpp>
|
||||||
#include <yycc/string/op.hpp>
|
#include <yycc/string/op.hpp>
|
||||||
#include <yycc/cenum.hpp>
|
#include <yycc/cenum.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "StructFmt.hpp"
|
#include "StructFmt.hpp"
|
||||||
#include "Docstring.hpp"
|
#include "Docstring.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
#include <yycc.hpp>
|
||||||
#include <yycc/string/op.hpp>
|
#include <yycc/string/op.hpp>
|
||||||
#include <yycc/carton/termcolor.hpp>
|
#include <yycc/carton/termcolor.hpp>
|
||||||
#include <yycc/carton/tabulate.hpp>
|
#include <yycc/carton/tabulate.hpp>
|
||||||
@@ -104,7 +105,7 @@ namespace Unvirt::StructFmt {
|
|||||||
static bool CheckPageHeader(const PageBreaker& pager, size_t page) {
|
static bool CheckPageHeader(const PageBreaker& pager, size_t page) {
|
||||||
bool good_page = pager.IsValidPage(page);
|
bool good_page = pager.IsValidPage(page);
|
||||||
if (!good_page) {
|
if (!good_page) {
|
||||||
termcolor::cprint(u8"Page out of range.", Color::LightRed);
|
termcolor::cprintln(u8"Page out of range.", Color::LightRed);
|
||||||
}
|
}
|
||||||
return good_page;
|
return good_page;
|
||||||
}
|
}
|
||||||
@@ -514,7 +515,7 @@ namespace Unvirt::StructFmt {
|
|||||||
|
|
||||||
|
|
||||||
void PrintCKFileInfo(const LibCmo::CK2::CKFileInfo& fileinfo) {
|
void PrintCKFileInfo(const LibCmo::CK2::CKFileInfo& fileinfo) {
|
||||||
termcolor::cprint(u8"CKFileInfo", Color::LightYellow);
|
termcolor::cprintln(u8"CKFileInfo", Color::LightYellow);
|
||||||
std::cout << strop::printf(u8"FileVersion: %" PRIuCKDWORD, fileinfo.FileVersion) << std::endl;
|
std::cout << strop::printf(u8"FileVersion: %" PRIuCKDWORD, fileinfo.FileVersion) << std::endl;
|
||||||
LibCmo::CKDWORD ck_series[3] {
|
LibCmo::CKDWORD ck_series[3] {
|
||||||
(fileinfo.CKVersion >> 24) & 0xFF,
|
(fileinfo.CKVersion >> 24) & 0xFF,
|
||||||
@@ -645,7 +646,7 @@ namespace Unvirt::StructFmt {
|
|||||||
size_t page,
|
size_t page,
|
||||||
size_t pageitems,
|
size_t pageitems,
|
||||||
bool full_detail) {
|
bool full_detail) {
|
||||||
termcolor::cprint(u8"CKFileObject", Color::LightYellow);
|
termcolor::cprintln(u8"CKFileObject", Color::LightYellow);
|
||||||
|
|
||||||
PageBreaker pager(ls.size(), pageitems);
|
PageBreaker pager(ls.size(), pageitems);
|
||||||
if (!CheckPageHeader(pager, page)) return;
|
if (!CheckPageHeader(pager, page)) return;
|
||||||
@@ -664,7 +665,7 @@ namespace Unvirt::StructFmt {
|
|||||||
size_t page,
|
size_t page,
|
||||||
size_t pageitems,
|
size_t pageitems,
|
||||||
bool full_detail) {
|
bool full_detail) {
|
||||||
termcolor::cprint(u8"CKFileObject Searching Result", Color::LightYellow);
|
termcolor::cprintln(u8"CKFileObject Searching Result", Color::LightYellow);
|
||||||
|
|
||||||
PageBreaker pager(idxls.size(), pageitems);
|
PageBreaker pager(idxls.size(), pageitems);
|
||||||
if (!pager.IsValidPage(page)) return;
|
if (!pager.IsValidPage(page)) return;
|
||||||
@@ -700,7 +701,7 @@ namespace Unvirt::StructFmt {
|
|||||||
size_t page,
|
size_t page,
|
||||||
size_t pageitems,
|
size_t pageitems,
|
||||||
bool full_detail) {
|
bool full_detail) {
|
||||||
termcolor::cprint(u8"CKFileManager", Color::LightYellow);
|
termcolor::cprintln(u8"CKFileManager", Color::LightYellow);
|
||||||
|
|
||||||
PageBreaker pager(ls.size(), pageitems);
|
PageBreaker pager(ls.size(), pageitems);
|
||||||
if (!pager.IsValidPage(page)) return;
|
if (!pager.IsValidPage(page)) return;
|
||||||
@@ -718,7 +719,7 @@ namespace Unvirt::StructFmt {
|
|||||||
size_t page,
|
size_t page,
|
||||||
size_t pageitems,
|
size_t pageitems,
|
||||||
bool full_detail) {
|
bool full_detail) {
|
||||||
termcolor::cprint(u8"CKFileManager Searching Result", Color::LightYellow);
|
termcolor::cprintln(u8"CKFileManager Searching Result", Color::LightYellow);
|
||||||
|
|
||||||
PageBreaker pager(ls.size(), pageitems);
|
PageBreaker pager(ls.size(), pageitems);
|
||||||
if (!pager.IsValidPage(page)) return;
|
if (!pager.IsValidPage(page)) return;
|
||||||
@@ -736,7 +737,7 @@ namespace Unvirt::StructFmt {
|
|||||||
|
|
||||||
void PrintCKObject(const LibCmo::CK2::ObjImpls::CKObject* obj) {
|
void PrintCKObject(const LibCmo::CK2::ObjImpls::CKObject* obj) {
|
||||||
if (obj == nullptr) {
|
if (obj == nullptr) {
|
||||||
termcolor::cprint(u8"Null Object", Color::LightRed);
|
termcolor::cprintln(u8"Null Object", Color::LightRed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,26 +786,26 @@ namespace Unvirt::StructFmt {
|
|||||||
PrintCKMeshDetail(static_cast<LibCmo::CK2::ObjImpls::CKMesh*>(mobj));
|
PrintCKMeshDetail(static_cast<LibCmo::CK2::ObjImpls::CKMesh*>(mobj));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
termcolor::cprint(u8"Not Implemented.", Color::LightRed);
|
termcolor::cprintln(u8"Not Implemented.", Color::LightRed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintCKBaseManager(const LibCmo::CK2::MgrImpls::CKBaseManager* mgr) {
|
void PrintCKBaseManager(const LibCmo::CK2::MgrImpls::CKBaseManager* mgr) {
|
||||||
termcolor::cprint(u8"CKBaseManager", Color::LightYellow);
|
termcolor::cprintln(u8"CKBaseManager", Color::LightYellow);
|
||||||
if (mgr == nullptr) {
|
if (mgr == nullptr) {
|
||||||
termcolor::cprint(u8"Null Manager", Color::LightRed);
|
termcolor::cprintln(u8"Null Manager", Color::LightRed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
termcolor::cprint(u8"Not Implemented.", Color::LightRed);
|
termcolor::cprintln(u8"Not Implemented.", Color::LightRed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintCKStateChunk(const LibCmo::CK2::CKStateChunk* chunk) {
|
void PrintCKStateChunk(const LibCmo::CK2::CKStateChunk* chunk) {
|
||||||
termcolor::cprint(u8"CKStateChunk", Color::LightYellow);
|
termcolor::cprintln(u8"CKStateChunk", Color::LightYellow);
|
||||||
if (chunk == nullptr) {
|
if (chunk == nullptr) {
|
||||||
termcolor::cprint(u8"Null Chunk", Color::LightRed);
|
termcolor::cprintln(u8"Null Chunk", Color::LightRed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,7 +839,7 @@ namespace Unvirt::StructFmt {
|
|||||||
operchunk->StartRead();
|
operchunk->StartRead();
|
||||||
const auto collection = operchunk->GetIdentifiersProfile();
|
const auto collection = operchunk->GetIdentifiersProfile();
|
||||||
operchunk->StopRead();
|
operchunk->StopRead();
|
||||||
termcolor::cprint(u8"Identifiers", Color::LightYellow);
|
termcolor::cprintln(u8"Identifiers", Color::LightYellow);
|
||||||
auto ident_table = CreateStandardTable({
|
auto ident_table = CreateStandardTable({
|
||||||
u8"Identifier",
|
u8"Identifier",
|
||||||
u8"Data Address",
|
u8"Data Address",
|
||||||
|
|||||||
@@ -1,226 +1,58 @@
|
|||||||
#include "UnvirtContext.hpp"
|
#include "UnvirtContext.hpp"
|
||||||
|
#include "Docstring.hpp"
|
||||||
#include <YYCCommonplace.hpp>
|
#include "StructFmt.hpp"
|
||||||
#include <CK2/MgrImpls/CKPathManager.hpp>
|
#include <LibCmo/CK2/MgrImpls/CKPathManager.hpp>
|
||||||
|
#include <yycc/string/op.hpp>
|
||||||
|
#include <yycc/string/reinterpret.hpp>
|
||||||
|
#include <yycc/carton/termcolor.hpp>
|
||||||
|
#include <yycc/patch/stream.hpp>
|
||||||
|
#include <yycc/windows/console.hpp>
|
||||||
|
#include <iostream>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
using namespace yycc::patch::stream;
|
||||||
|
namespace strop = yycc::string::op;
|
||||||
|
namespace termcolor = yycc::carton::termcolor;
|
||||||
|
namespace ph = std::placeholders;
|
||||||
|
|
||||||
namespace Unvirt::Context {
|
namespace Unvirt::Context {
|
||||||
|
|
||||||
#pragma region Specialized for CmdHelper
|
|
||||||
|
|
||||||
class EncodingListArgument : public CmdHelper::Nodes::AbstractArgument {
|
|
||||||
public:
|
|
||||||
using ArgValue_t = CmdHelper::AMItems::StringArrayItem;
|
|
||||||
public:
|
|
||||||
EncodingListArgument(const std::u8string_view& argname) :
|
|
||||||
AbstractArgument(argname) {}
|
|
||||||
virtual ~EncodingListArgument() {}
|
|
||||||
YYCC_DEF_CLS_COPY_MOVE(EncodingListArgument);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool BeginConsume(const std::u8string& cur_cmd, CmdHelper::ArgumentsMap& am) override {
|
|
||||||
// split given argument
|
|
||||||
std::vector<std::u8string> encs = YYCC::StringHelper::Split(cur_cmd, u8",");
|
|
||||||
// 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);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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_Splitter(), m_Parser(), m_Help(),
|
// Initialize command processor
|
||||||
m_PageLen(10u), m_ListStyleIsFull(true), m_OrderExit(false),
|
m_Commander(), m_OrderExit(false), m_ItemPerPage(10u), m_ListStyle(CmdHelper::StyleLevel::Full), m_IsSearching(false),
|
||||||
m_SearchPart(SearchPart::None), m_SearchIdxResult(),
|
m_SearchPart(CmdHelper::SearchPart::Object), m_SearchIdxResult(),
|
||||||
m_Ctx(nullptr), m_FileReader(nullptr), m_IsShallowRead(true) {
|
// Initialize Virtools
|
||||||
|
m_Ctx(nullptr), m_FileReader(nullptr), m_IsShallowRead(true) {
|
||||||
|
|
||||||
// Setup command parser
|
// Set up commander with our callback.
|
||||||
// get root node first
|
m_Commander.SetLoadDelegate(std::bind(UnvirtContext::HandleLoad, this, ph::_1));
|
||||||
CmdHelper::Nodes::RootNode& root = m_Parser.GetRoot();
|
m_Commander.SetUnloadDelegate(std::bind(UnvirtContext::HandleUnLoad, this, ph::_1));
|
||||||
// setup tree
|
m_Commander.SetSaveDelegate(std::bind(UnvirtContext::HandleSave, this, ph::_1));
|
||||||
root
|
m_Commander.SetInfoDelegate(std::bind(UnvirtContext::HandleInfo, this, ph::_1));
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"load")
|
m_Commander.SetLsDelegate(std::bind(UnvirtContext::HandleLs, this, ph::_1));
|
||||||
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"stage", { u8"deep", u8"shallow"})
|
m_Commander.SetDataDelegate(std::bind(UnvirtContext::HandleData, this, ph::_1));
|
||||||
.Comment(u8"The stage of loading. 'deep' will load to CKObject stage. 'shallow' will load to CKStateChunk stage.")
|
m_Commander.SetChunkDelegate(std::bind(UnvirtContext::HandleChunk, this, ph::_1));
|
||||||
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"filepath")
|
m_Commander.SetSearchDelegate(std::bind(UnvirtContext::HandleSearch, this, ph::_1));
|
||||||
.Comment(u8"The path to loading file.")
|
m_Commander.SetItemsDelegate(std::bind(UnvirtContext::HandleItems, this, ph::_1));
|
||||||
.Executes(
|
m_Commander.SetStyleDelegate(std::bind(UnvirtContext::HandleStyle, this, ph::_1));
|
||||||
std::bind(&UnvirtContext::ProcLoad, this, std::placeholders::_1),
|
m_Commander.SetEncodingDelegate(std::bind(UnvirtContext::HandleEncoding, this, ph::_1));
|
||||||
u8"Load a Virtools composition."
|
m_Commander.SetTempDelegate(std::bind(UnvirtContext::HandleTemp, this, ph::_1));
|
||||||
)
|
m_Commander.SetRscClearDelegate(std::bind(UnvirtContext::HandleRscClear, this, ph::_1));
|
||||||
)
|
m_Commander.SetRscAddDelegate(std::bind(UnvirtContext::HandleRscAdd, this, ph::_1));
|
||||||
)
|
m_Commander.SetTestDelegate(std::bind(UnvirtContext::HandleTest, this, ph::_1));
|
||||||
)
|
m_Commander.SetVersionDelegate(std::bind(UnvirtContext::HandleVersion, this, ph::_1));
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"unload")
|
m_Commander.SetHelpDelegate(std::bind(UnvirtContext::HandleHelp, this, ph::_1));
|
||||||
.Executes(
|
m_Commander.SetExitDelegate(std::bind(UnvirtContext::HandleExit, this, ph::_1));
|
||||||
std::bind(&UnvirtContext::ProcUnLoad, this, std::placeholders::_1),
|
|
||||||
u8"Release loaded Virtools composition."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"save")
|
|
||||||
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"filepath")
|
|
||||||
.Comment(u8"The path to save file.")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcSave, this, std::placeholders::_1),
|
|
||||||
u8"Save the loaded file into a new file."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"info")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcInfo, this, std::placeholders::_1),
|
|
||||||
u8"Show the header info of loaded Virtools composition."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"ls")
|
|
||||||
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"part", { u8"obj", u8"mgr", u8"search"})
|
|
||||||
.Comment(u8"Which list you want to list.")
|
|
||||||
.Then<CmdHelper::Nodes::ArithmeticArgument<size_t>>(CmdHelper::Nodes::ArithmeticArgument<size_t>(u8"page", GetOneBasedIndexConstraint())
|
|
||||||
.Comment(u8"The page index. Start with 1.")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcLs, this, std::placeholders::_1),
|
|
||||||
u8"List something about loaded Virtools composition."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"data")
|
|
||||||
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"part", { u8"obj", u8"mgr"})
|
|
||||||
.Comment(u8"Which list you want to show data.")
|
|
||||||
.Then<CmdHelper::Nodes::ArithmeticArgument<size_t>>(CmdHelper::Nodes::ArithmeticArgument<size_t>(u8"index")
|
|
||||||
.Comment(u8"The index. Start with 0.")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcData, this, std::placeholders::_1),
|
|
||||||
u8"Show the specific CKObject / CKBaseManager data."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"chunk")
|
|
||||||
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"part", { u8"obj", u8"mgr"})
|
|
||||||
.Comment(u8"Which list you want to show chunk.")
|
|
||||||
.Then<CmdHelper::Nodes::ArithmeticArgument<size_t>>(CmdHelper::Nodes::ArithmeticArgument<size_t>(u8"index")
|
|
||||||
.Comment(u8"The index. Start with 0.")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcChunk, this, std::placeholders::_1),
|
|
||||||
u8"Show the specific CKStateChunk data."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"search")
|
|
||||||
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"part", { u8"obj", u8"mgr"})
|
|
||||||
.Comment(u8"Which list you want to search.")
|
|
||||||
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"mode", { u8"plain", u8"re"})
|
|
||||||
.Comment(u8"The search mode. `plain` will search by substring and `re` will do regex search.")
|
|
||||||
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"text")
|
|
||||||
.Comment(u8"The text or regex to search.")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcSearch, this, std::placeholders::_1),
|
|
||||||
u8"Search object or manager by text or regex. Please note that the regex have limited UTF8 support and may cause undefined behavior."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"items")
|
|
||||||
.Then<CmdHelper::Nodes::ArithmeticArgument<size_t>>(CmdHelper::Nodes::ArithmeticArgument<size_t>(u8"count", GetOneBasedIndexConstraint())
|
|
||||||
.Comment(u8"The count of items you want to show in one page.")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcItems, this, std::placeholders::_1),
|
|
||||||
u8"Set up how many items should be listed in one page when using 'ls' command."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"style")
|
|
||||||
.Then<CmdHelper::Nodes::Choice>(CmdHelper::Nodes::Choice(u8"level", { u8"full", u8"simple"})
|
|
||||||
.Comment(u8"The amount of showen content.")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcStyle, this, std::placeholders::_1),
|
|
||||||
u8"Change the detail level of showen data in `ls` command."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"encoding")
|
|
||||||
.Then<EncodingListArgument>(EncodingListArgument(u8"enc")
|
|
||||||
.Comment(u8"CKContext used encoding splitted by ','. Support mutiple encoding.")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcEncoding, this, std::placeholders::_1),
|
|
||||||
u8"Set the encoding series for CKContext."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"temp")
|
|
||||||
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"temppath")
|
|
||||||
.Comment(u8"The path to Temp folder.")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcTemp, this, std::placeholders::_1),
|
|
||||||
u8"Set the Temp path for CKContext."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"rsc")
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"clear")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcRsc, this, std::placeholders::_1, true),
|
|
||||||
u8"Clear all data resources paths."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"add")
|
|
||||||
.Then<CmdHelper::Nodes::StringArgument>(CmdHelper::Nodes::StringArgument(u8"datares")
|
|
||||||
.Comment(u8"The data resources path .")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcRsc, this, std::placeholders::_1, false),
|
|
||||||
u8"Add a path to let Virtools find resources."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"test")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcTest, this, std::placeholders::_1),
|
|
||||||
u8"Call custom debugging function (only available in Debug mode)."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"help")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcHelp, this, std::placeholders::_1),
|
|
||||||
u8"Output this help page."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.Then<CmdHelper::Nodes::Literal>(CmdHelper::Nodes::Literal(u8"exit")
|
|
||||||
.Executes(
|
|
||||||
std::bind(&UnvirtContext::ProcExit, this, std::placeholders::_1),
|
|
||||||
u8"Exit program."
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// create help document
|
|
||||||
m_Help = m_Parser.Help();
|
|
||||||
|
|
||||||
// initialize CK engine and create context
|
// initialize CK engine and create context
|
||||||
LibCmo::CK2::CKERROR err = LibCmo::CK2::CKStartUp();
|
LibCmo::CK2::CKERROR err = LibCmo::CK2::CKStartUp();
|
||||||
if (err != LibCmo::CK2::CKERROR::CKERR_OK)
|
if (err != LibCmo::CK2::CKERROR::CKERR_OK)
|
||||||
throw std::runtime_error("fail to initialize CK2 engine.");
|
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, ph::_1));
|
||||||
m_Ctx->SetGlobalImagesSaveOptions(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL);
|
m_Ctx->SetGlobalImagesSaveOptions(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +63,10 @@ namespace Unvirt::Context {
|
|||||||
LibCmo::CK2::CKShutdown();
|
LibCmo::CK2::CKShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Virtools Controller
|
||||||
|
|
||||||
bool UnvirtContext::HasOpenedFile() {
|
bool UnvirtContext::HasOpenedFile() {
|
||||||
return m_FileReader != nullptr;
|
return m_FileReader != nullptr;
|
||||||
}
|
}
|
||||||
@@ -238,7 +74,8 @@ namespace Unvirt::Context {
|
|||||||
void UnvirtContext::ClearDocument() {
|
void UnvirtContext::ClearDocument() {
|
||||||
if (m_FileReader == nullptr) return;
|
if (m_FileReader == nullptr) return;
|
||||||
// clear search result
|
// clear search result
|
||||||
m_SearchPart = SearchPart::None;
|
m_IsSearching = false;
|
||||||
|
m_SearchPart = CmdHelper::SearchPart::Object;
|
||||||
m_SearchIdxResult.clear();
|
m_SearchIdxResult.clear();
|
||||||
// delete reader
|
// delete reader
|
||||||
delete m_FileReader;
|
delete m_FileReader;
|
||||||
@@ -250,58 +87,72 @@ namespace Unvirt::Context {
|
|||||||
|
|
||||||
void UnvirtContext::PrintContextMsg(LibCmo::CKSTRING msg) {
|
void UnvirtContext::PrintContextMsg(LibCmo::CKSTRING msg) {
|
||||||
if (msg != nullptr) {
|
if (msg != nullptr) {
|
||||||
YYCC::ConsoleHelper::FormatLine(YYCC_COLOR_LIGHT_YELLOW(u8"[CKContext] ") "%s", msg);
|
termcolor::cprintln(msg, termcolor::Color::LightYellow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::PrintCommonInfo(const char8_t* u8_fmt, ...) {
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Message Printer
|
||||||
|
|
||||||
|
void UnvirtContext::PrintInfo(const char8_t* u8_fmt, ...) {
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, u8_fmt);
|
va_start(argptr, u8_fmt);
|
||||||
YYCC::ConsoleHelper::WriteLine(
|
std::cout << strop::vprintf(u8_fmt, argptr) << std::endl;
|
||||||
YYCC::StringHelper::VPrintf(u8_fmt, argptr).c_str()
|
|
||||||
);
|
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::PrintCommonError(const char8_t* u8_fmt, ...) {
|
void UnvirtContext::PrintError(const char8_t* u8_fmt, ...) {
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, u8_fmt);
|
va_start(argptr, u8_fmt);
|
||||||
YYCC::ConsoleHelper::FormatLine(YYCC_COLOR_LIGHT_RED(u8"%s"),
|
termcolor::cprintln(strop::vprintf(u8_fmt, argptr), termcolor::Color::LightRed);
|
||||||
YYCC::StringHelper::VPrintf(u8_fmt, argptr).c_str()
|
|
||||||
);
|
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region Main Run
|
#pragma region Main Runner
|
||||||
|
|
||||||
void UnvirtContext::Run() {
|
void UnvirtContext::Run() {
|
||||||
// Enable terminal color feature
|
// Enable terminal color feature
|
||||||
YYCC::ConsoleHelper::EnableColorfulConsole();
|
#if defined(YYCC_OS_WINDOWS)
|
||||||
|
yycc::windows::console::colorful_console();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Show banner
|
// Show banner
|
||||||
YYCC::ConsoleHelper::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"Unvirt") " (based on LibCmo " LIBCMO_VER_STR ") built at " __DATE__ " " __TIME__);
|
std::cout << termcolor::colored(u8"Unvirt", termcolor::Color::LightYellow)
|
||||||
YYCC::ConsoleHelper::WriteLine(u8"Type 'help' for more infomation. Type 'exit' to quit.");
|
<< " (based on LibCmo " LIBCMO_VER_STR ") built at " __DATE__ " " __TIME__ << std::endl
|
||||||
|
<< u8"Type 'help' for more infomation. Type 'exit' to quit." << std::endl;
|
||||||
|
|
||||||
// start process loop
|
// start process loop
|
||||||
while (true) {
|
while (true) {
|
||||||
// get command
|
// get command
|
||||||
YYCC::ConsoleHelper::Write(YYCC_COLOR_GREEN(u8"> "));
|
termcolor::cprint(u8"> ", termcolor::Color::Green);
|
||||||
std::u8string u8cmd = YYCC::ConsoleHelper::ReadLine();
|
std::string cmd;
|
||||||
|
if (std::getline(std::cin, cmd).fail()) continue;
|
||||||
|
auto u8cmd = yycc::string::reinterpret::as_utf8_view(cmd);
|
||||||
|
|
||||||
// lex command line first
|
// pass to commander
|
||||||
if (!m_Splitter.Lex(u8cmd)) {
|
auto rv = this->m_Commander.Dispatch(u8cmd);
|
||||||
this->PrintCommonError(u8"Lexer error \"%s\".\nType 'help' for usage.", u8cmd.c_str());
|
if (!rv.has_value()) {
|
||||||
continue;
|
switch (rv.error()) {
|
||||||
}
|
case CmdHelper::Error::Lexer:
|
||||||
// if result is empty, skip to next one
|
this->PrintError(u8"Lexer error.");
|
||||||
auto cmds = m_Splitter.GetResult();
|
break;
|
||||||
if (cmds.empty()) continue;
|
case CmdHelper::Error::BadVerb:
|
||||||
|
this->PrintError(u8"Unknown verb.");
|
||||||
// run command parser
|
break;
|
||||||
if (!m_Parser.Parse(cmds)) {
|
case CmdHelper::Error::BadArg:
|
||||||
this->PrintCommonError(u8"Parser error \"%s\".\nType 'help' for usage.", u8cmd.c_str());
|
this->PrintError(u8"Bad argument.");
|
||||||
|
break;
|
||||||
|
case CmdHelper::Error::TooLessParam:
|
||||||
|
this->PrintError(u8"Given arguments are too less.");
|
||||||
|
break;
|
||||||
|
case CmdHelper::Error::TooMuchParam:
|
||||||
|
this->PrintError(u8"Given arguments are too much.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->PrintError(u8"Please type 'help' for usage.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether sub processor need exit.
|
// check whether sub processor need exit.
|
||||||
@@ -313,48 +164,48 @@ namespace Unvirt::Context {
|
|||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region Proc Detail
|
#pragma region Handler
|
||||||
|
|
||||||
void UnvirtContext::ProcLoad(const CmdHelper::ArgumentsMap& amap) {
|
void UnvirtContext::HandleLoad(const CmdHelper::LoadParam& param) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (HasOpenedFile()) {
|
if (HasOpenedFile()) {
|
||||||
PrintCommonError(u8"Already have a opened file. Close it before calling 'load'.");
|
PrintError(u8"Already have a opened file. Close it before calling 'load'.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!m_Ctx->IsValidEncoding()) {
|
if (!m_Ctx->IsValidEncoding()) {
|
||||||
PrintCommonError(u8"You have not set encoding properly. Set it before loading by calling 'encoding'.");
|
PrintError(u8"You have not set encoding properly. Set it before loading by calling 'encoding'.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get argument
|
// load file
|
||||||
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
|
|
||||||
m_FileReader = new LibCmo::CK2::CKFileReader(m_Ctx);
|
m_FileReader = new LibCmo::CK2::CKFileReader(m_Ctx);
|
||||||
LibCmo::CK2::CKERROR err;
|
LibCmo::CK2::CKERROR err;
|
||||||
if (is_deep) {
|
switch (param.stage) {
|
||||||
err = m_FileReader->DeepLoad(filepath.c_str());
|
case CmdHelper::LoadStage::Shallow:
|
||||||
m_IsShallowRead = false;
|
err = m_FileReader->ShallowLoad(param.filepath.c_str());
|
||||||
} else {
|
m_IsShallowRead = true;
|
||||||
err = m_FileReader->ShallowLoad(filepath.c_str());
|
break;
|
||||||
m_IsShallowRead = true;
|
case CmdHelper::LoadStage::Deep:
|
||||||
|
err = m_FileReader->DeepLoad(param.filepath.c_str());
|
||||||
|
m_IsShallowRead = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unreachable code");
|
||||||
}
|
}
|
||||||
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(u8"Fail to load file. Function return: %s\n\t%s",
|
PrintError(u8"Fail to load file. Function return: %s (%s)",
|
||||||
Unvirt::AccessibleValue::GetCkErrorName(err).c_str(),
|
Docstring::GetCkErrorName(err).c_str(),
|
||||||
Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str()
|
Docstring::GetCkErrorDescription(err).c_str());
|
||||||
);
|
|
||||||
|
|
||||||
ClearDocument();
|
ClearDocument();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcUnLoad(const CmdHelper::ArgumentsMap&) {
|
void UnvirtContext::HandleUnLoad(const CmdHelper::UnloadParam& param) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
this->PrintCommonError(u8"No loaded file.");
|
this->PrintError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,19 +213,17 @@ namespace Unvirt::Context {
|
|||||||
ClearDocument();
|
ClearDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unvirt::Context::UnvirtContext::ProcSave(const CmdHelper::ArgumentsMap& amap) {
|
void UnvirtContext::HandleSave(const CmdHelper::SaveParam& param) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError(u8"No loaded file.");
|
PrintError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!m_Ctx->IsValidEncoding()) {
|
if (!m_Ctx->IsValidEncoding()) {
|
||||||
PrintCommonError(u8"You have not set encoding properly. Set it before saving by calling 'encoding'.");
|
PrintError(u8"You have not set encoding properly. Set it before saving by calling 'encoding'.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@@ -384,12 +233,12 @@ namespace Unvirt::Context {
|
|||||||
m_Ctx->SetFileWriteMode(m_FileReader->GetFileInfo().FileWriteMode);
|
m_Ctx->SetFileWriteMode(m_FileReader->GetFileInfo().FileWriteMode);
|
||||||
|
|
||||||
// run writer
|
// run writer
|
||||||
LibCmo::CK2::CKERROR err = writer.Save(filepath.c_str());
|
LibCmo::CK2::CKERROR err = writer.Save(param.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(u8"Fail to save file. Function return: %s\n\t%s",
|
PrintError(u8"Fail to save file. Function return: %s\n\t%s",
|
||||||
Unvirt::AccessibleValue::GetCkErrorName(err).c_str(),
|
Docstring::GetCkErrorName(err).c_str(),
|
||||||
Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str()
|
Docstring::GetCkErrorDescription(err).c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,80 +247,70 @@ namespace Unvirt::Context {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcInfo(const CmdHelper::ArgumentsMap&) {
|
void UnvirtContext::HandleInfo(const CmdHelper::InfoParam& param) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError(u8"No loaded file.");
|
PrintError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print
|
// print
|
||||||
Unvirt::StructFormatter::PrintCKFileInfo(m_FileReader->GetFileInfo());
|
StructFmt::PrintCKFileInfo(m_FileReader->GetFileInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcLs(const CmdHelper::ArgumentsMap& amap) {
|
void UnvirtContext::HandleLs(const CmdHelper::LsParam& param) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError(u8"No loaded file.");
|
PrintError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get 0 based page (-1)
|
// get 0 based page (-1)
|
||||||
size_t page = amap.Get<CmdHelper::Nodes::ArithmeticArgument<size_t>::ArgValue_t>(u8"page").Get() - 1u;
|
size_t page = param.page - 1;
|
||||||
|
bool full_detail = m_ListStyle == CmdHelper::StyleLevel::Full;
|
||||||
|
|
||||||
// show list
|
// show list
|
||||||
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"part").Get()) {
|
switch (param.part) {
|
||||||
case 0u:
|
case CmdHelper::LsPart::Object: {
|
||||||
{
|
|
||||||
// obj list
|
// obj list
|
||||||
Unvirt::StructFormatter::PrintObjectList(
|
StructFmt::PrintObjectList(m_FileReader->GetFileObjects(),
|
||||||
m_FileReader->GetFileObjects(),
|
m_FileReader->GetFileInfo(),
|
||||||
m_FileReader->GetFileInfo(),
|
page,
|
||||||
page, this->m_PageLen,
|
this->m_ItemPerPage,
|
||||||
m_ListStyleIsFull
|
full_detail);
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1u:
|
case CmdHelper::LsPart::Manager: {
|
||||||
{
|
|
||||||
// mgr list
|
// mgr list
|
||||||
Unvirt::StructFormatter::PrintManagerList(
|
StructFmt::PrintManagerList(m_FileReader->GetManagersData(), page, this->m_ItemPerPage, full_detail);
|
||||||
m_FileReader->GetManagersData(),
|
|
||||||
page, this->m_PageLen,
|
|
||||||
m_ListStyleIsFull
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2u:
|
case CmdHelper::LsPart::Search: {
|
||||||
{
|
|
||||||
// search list
|
// search list
|
||||||
switch (m_SearchPart) {
|
if (m_IsSearching) {
|
||||||
case SearchPart::None:
|
switch (m_SearchPart) {
|
||||||
{
|
case CmdHelper::SearchPart::Object: {
|
||||||
PrintCommonError(u8"No search result to list.");
|
StructFmt::PrintSearchedObjectList(m_SearchIdxResult,
|
||||||
break;
|
m_FileReader->GetFileObjects(),
|
||||||
}
|
m_FileReader->GetFileInfo(),
|
||||||
case SearchPart::Object:
|
page,
|
||||||
{
|
this->m_ItemPerPage,
|
||||||
Unvirt::StructFormatter::PrintSearchedObjectList(
|
full_detail);
|
||||||
m_SearchIdxResult,
|
break;
|
||||||
m_FileReader->GetFileObjects(),
|
}
|
||||||
m_FileReader->GetFileInfo(),
|
case CmdHelper::SearchPart::Manager: {
|
||||||
page, this->m_PageLen,
|
StructFmt::PrintSearchedManagerList(m_SearchIdxResult,
|
||||||
m_ListStyleIsFull
|
m_FileReader->GetManagersData(),
|
||||||
);
|
page,
|
||||||
break;
|
this->m_ItemPerPage,
|
||||||
}
|
full_detail);
|
||||||
case SearchPart::Manager:
|
break;
|
||||||
{
|
}
|
||||||
Unvirt::StructFormatter::PrintSearchedManagerList(
|
default:
|
||||||
m_SearchIdxResult,
|
throw std::runtime_error("unreachable code");
|
||||||
m_FileReader->GetManagersData(),
|
|
||||||
page, this->m_PageLen,
|
|
||||||
m_ListStyleIsFull
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
PrintError(u8"No search result to list.");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -480,36 +319,36 @@ namespace Unvirt::Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcData(const CmdHelper::ArgumentsMap& amap) {
|
void UnvirtContext::HandleData(const CmdHelper::DataParam& param) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError(u8"No loaded file.");
|
PrintError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get index
|
// get index
|
||||||
size_t index = amap.Get<CmdHelper::Nodes::ArithmeticArgument<size_t>::ArgValue_t>(u8"index").Get();
|
size_t index = param.index;
|
||||||
|
|
||||||
// show data
|
// show data
|
||||||
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"part").Get()) {
|
switch (param.part) {
|
||||||
case 0u:
|
case CmdHelper::DataPart::Object:
|
||||||
{
|
{
|
||||||
if (index >= m_FileReader->GetFileObjects().size()) {
|
if (index >= m_FileReader->GetFileObjects().size()) {
|
||||||
PrintCommonError(u8"Index out of range.");
|
PrintError(u8"Index out of range.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Unvirt::StructFormatter::PrintCKObject(m_FileReader->GetFileObjects()[index].ObjPtr);
|
StructFmt::PrintCKObject(m_FileReader->GetFileObjects()[index].ObjPtr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1u:
|
case CmdHelper::DataPart::Manager:
|
||||||
{
|
{
|
||||||
if (index >= m_FileReader->GetManagersData().size()) {
|
if (index >= m_FileReader->GetManagersData().size()) {
|
||||||
PrintCommonError(u8"Index out of range.");
|
PrintError(u8"Index out of range.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// todo: finish manager display
|
// todo: finish manager display
|
||||||
PrintCommonError(u8"Not supported now.");
|
PrintError(u8"Not supported now.");
|
||||||
//Unvirt::StructFormatter::PrintCKBaseManager(m_FileReader->GetManagersData()[index].Data);
|
//StructFmt::PrintCKBaseManager(m_FileReader->GetManagersData()[index].Data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -517,34 +356,34 @@ namespace Unvirt::Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcChunk(const CmdHelper::ArgumentsMap& amap) {
|
void UnvirtContext::HandleChunk(const CmdHelper::ChunkParam& param) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError(u8"No loaded file.");
|
PrintError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get index
|
// get index
|
||||||
size_t index = amap.Get<CmdHelper::Nodes::ArithmeticArgument<size_t>::ArgValue_t>(u8"index").Get();
|
size_t index = param.index;
|
||||||
|
|
||||||
// show data
|
// show data
|
||||||
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"part").Get()) {
|
switch (param.part) {
|
||||||
case 0:
|
case CmdHelper::ChunkPart::Object:
|
||||||
{
|
{
|
||||||
if (index >= m_FileReader->GetFileObjects().size()) {
|
if (index >= m_FileReader->GetFileObjects().size()) {
|
||||||
PrintCommonError(u8"Index out of range.");
|
PrintError(u8"Index out of range.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Unvirt::StructFormatter::PrintCKStateChunk(m_FileReader->GetFileObjects()[index].Data);
|
StructFmt::PrintCKStateChunk(m_FileReader->GetFileObjects()[index].Data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case CmdHelper::ChunkPart::Manager:
|
||||||
{
|
{
|
||||||
if (index >= m_FileReader->GetManagersData().size()) {
|
if (index >= m_FileReader->GetManagersData().size()) {
|
||||||
PrintCommonError(u8"Index out of range.");
|
PrintError(u8"Index out of range.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Unvirt::StructFormatter::PrintCKStateChunk(m_FileReader->GetManagersData()[index].Data);
|
StructFmt::PrintCKStateChunk(m_FileReader->GetManagersData()[index].Data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -552,20 +391,20 @@ namespace Unvirt::Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcSearch(const CmdHelper::ArgumentsMap& amap) {
|
void UnvirtContext::HandleSearch(const CmdHelper::SearchParam& param) {
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError(u8"No loaded file.");
|
PrintError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get search text *amap->Get<CmdHelper::StringArgument::vType>("text")
|
// get search text
|
||||||
std::u8string search_text = amap.Get<CmdHelper::Nodes::StringArgument::ArgValue_t>(u8"text").Get();
|
std::u8string search_text = param.text;
|
||||||
|
|
||||||
// analyse search mode
|
// analyse search mode
|
||||||
std::function<bool(const LibCmo::XContainer::XString&)> search_fct = nullptr;
|
std::function<bool(const LibCmo::XContainer::XString&)> search_fct = nullptr;
|
||||||
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"mode").Get()) {
|
switch (param.mode) {
|
||||||
case 0u:
|
case CmdHelper::SearchMode::PlainText:
|
||||||
{
|
{
|
||||||
// plain mode
|
// plain mode
|
||||||
search_fct = [&search_text](const LibCmo::XContainer::XString& cmp) -> bool {
|
search_fct = [&search_text](const LibCmo::XContainer::XString& cmp) -> bool {
|
||||||
@@ -573,18 +412,18 @@ namespace Unvirt::Context {
|
|||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1u:
|
case CmdHelper::SearchMode::Regex:
|
||||||
{
|
{
|
||||||
// regex mode
|
// regex mode
|
||||||
|
|
||||||
// get ordinary search text
|
// get ordinary search text
|
||||||
std::string ordinary_search_text = YYCC::EncodingHelper::ToOrdinary(search_text);
|
std::string ordinary_search_text = yycc::string::reinterpret::as_ordinary(search_text);
|
||||||
// try construct regex
|
// try construct regex
|
||||||
std::regex re;
|
std::regex re;
|
||||||
try {
|
try {
|
||||||
re = std::regex(ordinary_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(u8"Invalid regular expressions: %s", e.what());
|
PrintError(u8"Invalid regular expressions: %s", e.what());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +431,7 @@ namespace Unvirt::Context {
|
|||||||
// 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 {
|
||||||
// get ordinary name and comapre
|
// get ordinary name and comapre
|
||||||
std::string ordinary_cmp = YYCC::EncodingHelper::ToOrdinary(cmp);
|
std::string ordinary_cmp = yycc::string::reinterpret::as_ordinary(cmp);
|
||||||
return std::regex_search(ordinary_cmp, re);
|
return std::regex_search(ordinary_cmp, re);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
@@ -602,11 +441,12 @@ namespace Unvirt::Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// start search
|
// start search
|
||||||
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"part").Get()) {
|
m_IsSearching = true;
|
||||||
case 0u:
|
m_SearchPart = param.part;
|
||||||
|
switch (param.part) {
|
||||||
|
case CmdHelper::SearchPart::Object:
|
||||||
{
|
{
|
||||||
// object
|
// object
|
||||||
m_SearchPart = SearchPart::Object;
|
|
||||||
m_SearchIdxResult.clear();
|
m_SearchIdxResult.clear();
|
||||||
|
|
||||||
size_t counter = 0;
|
size_t counter = 0;
|
||||||
@@ -619,12 +459,11 @@ namespace Unvirt::Context {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1u:
|
case CmdHelper::SearchPart::Manager:
|
||||||
{
|
{
|
||||||
// manager
|
// manager
|
||||||
m_SearchPart = SearchPart::Manager;
|
|
||||||
m_SearchIdxResult.clear();
|
m_SearchIdxResult.clear();
|
||||||
PrintCommonError(u8"Not supported now.");
|
PrintError(u8"Not supported now.");
|
||||||
// todo: remove this return when fixing manager searching.
|
// todo: remove this return when fixing manager searching.
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
@@ -635,62 +474,44 @@ namespace Unvirt::Context {
|
|||||||
|
|
||||||
// report search result
|
// report search result
|
||||||
if (m_SearchIdxResult.empty()) {
|
if (m_SearchIdxResult.empty()) {
|
||||||
PrintCommonInfo(u8"Search done, but no result.");
|
PrintInfo(u8"Search done, but no result.");
|
||||||
} else {
|
} else {
|
||||||
PrintCommonInfo(u8"Search done with %" PRIuSIZET " results. Use `ls search` to check them.", m_SearchIdxResult.size());
|
PrintInfo(u8"Search done with %" PRIuSIZET " results. Use `ls search` to check them.", m_SearchIdxResult.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcItems(const CmdHelper::ArgumentsMap& amap) {
|
void UnvirtContext::HandleItems(const CmdHelper::ItemsParam& param) {
|
||||||
// assign
|
// assign
|
||||||
m_PageLen = amap.Get<CmdHelper::Nodes::ArithmeticArgument<size_t>::ArgValue_t>(u8"count").Get();
|
m_ItemPerPage = param.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcStyle(const CmdHelper::ArgumentsMap& amap) {
|
void UnvirtContext::HandleStyle(const CmdHelper::StyleParam& param) {
|
||||||
// set list style level
|
|
||||||
switch (amap.Get<CmdHelper::Nodes::Choice::ArgValue_t>(u8"level").Get()) {
|
|
||||||
case 0u:
|
|
||||||
{
|
|
||||||
// full level
|
|
||||||
m_ListStyleIsFull = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1u:
|
|
||||||
{
|
|
||||||
// simple level
|
|
||||||
m_ListStyleIsFull = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("unreachable code");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnvirtContext::ProcEncoding(const CmdHelper::ArgumentsMap& amap) {
|
|
||||||
const auto& encodings = amap.Get<EncodingListArgument::ArgValue_t>(u8"enc").Get();
|
|
||||||
m_Ctx->SetEncoding(encodings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnvirtContext::ProcTemp(const CmdHelper::ArgumentsMap& amap) {
|
|
||||||
// assign
|
// assign
|
||||||
std::u8string temp_path = amap.Get<CmdHelper::Nodes::StringArgument::ArgValue_t>(u8"temppath").Get();
|
m_ListStyle = param.level;
|
||||||
if (!m_Ctx->GetPathManager()->SetTempFolder(temp_path.c_str())) {
|
}
|
||||||
PrintCommonError(u8"Set temp folder failed. Check your path first.");
|
|
||||||
|
void UnvirtContext::HandleEncoding(const CmdHelper::EncodingParam& param) {
|
||||||
|
m_Ctx->SetEncoding(param.enc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnvirtContext::HandleTemp(const CmdHelper::TempParam& param) {
|
||||||
|
// assign
|
||||||
|
if (!m_Ctx->GetPathManager()->SetTempFolder(param.dirpath.c_str())) {
|
||||||
|
PrintError(u8"Set temp folder failed. Check your path first.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unvirt::Context::UnvirtContext::ProcRsc(const CmdHelper::ArgumentsMap& amap, bool is_clear) {
|
void UnvirtContext::HandleRscClear(const CmdHelper::RscClearParam& param) {
|
||||||
if (is_clear) {
|
m_Ctx->GetPathManager()->ClearPath();
|
||||||
m_Ctx->GetPathManager()->ClearPath();
|
}
|
||||||
} else {
|
|
||||||
std::u8string data_res = amap.Get<CmdHelper::Nodes::StringArgument::ArgValue_t>(u8"datares").Get();
|
void UnvirtContext::HandleRscAdd(const CmdHelper::RscAddParam& param) {
|
||||||
if (!m_Ctx->GetPathManager()->AddPath(data_res.c_str())) {
|
if (!m_Ctx->GetPathManager()->AddPath(param.dirpath.c_str())) {
|
||||||
PrintCommonError(u8"Set data resource folder failed. Check your path first.");
|
PrintError(u8"Set data resource folder failed. Check your path first.");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unvirt::Context::UnvirtContext::ProcTest(const CmdHelper::ArgumentsMap& amap) {
|
void UnvirtContext::HandleTest(const CmdHelper::TestParam& param) {
|
||||||
#if defined(LIBCMO_BUILD_DEBUG)
|
#if defined(LIBCMO_BUILD_DEBUG)
|
||||||
// MARK: Add the debug code here.
|
// MARK: Add the debug code here.
|
||||||
|
|
||||||
@@ -699,11 +520,11 @@ namespace Unvirt::Context {
|
|||||||
|
|
||||||
// check pre-requirement
|
// check pre-requirement
|
||||||
if (!HasOpenedFile()) {
|
if (!HasOpenedFile()) {
|
||||||
PrintCommonError(u8"No loaded file.");
|
PrintError(u8"No loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!m_IsShallowRead) {
|
if (!m_IsShallowRead) {
|
||||||
PrintCommonError(u8"Transparent Column Fixer only accept shallow loaded file.");
|
PrintError(u8"Transparent Column Fixer only accept shallow loaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -732,15 +553,25 @@ namespace Unvirt::Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
PrintCommonError(u8"Test command only available in Debug mode.");
|
PrintError(u8"Test command only available in Debug mode.");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unvirt::Context::UnvirtContext::ProcHelp(const CmdHelper::ArgumentsMap&) {
|
void UnvirtContext::HandleVersion(const CmdHelper::VersionParam& param) {
|
||||||
m_Help.Print();
|
// MARK: Copied from splash at Main Runner.
|
||||||
|
std::cout << termcolor::colored(u8"Unvirt", termcolor::Color::LightYellow)
|
||||||
|
<< " (based on LibCmo " LIBCMO_VER_STR ") built at " __DATE__ " " __TIME__ << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnvirtContext::ProcExit(const CmdHelper::ArgumentsMap&) {
|
void UnvirtContext::HandleHelp(const CmdHelper::HelpParam& param) {
|
||||||
|
std::cout << u8"version: Show version info about this program." << std::endl
|
||||||
|
<< u8"help: Print this page." << std::endl
|
||||||
|
<< u8"exit: Quit this program." << std::endl
|
||||||
|
<< std::endl
|
||||||
|
<< u8"See manual provided with this program for more commands because it is so long." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnvirtContext::HandleExit(const CmdHelper::ExitParam& param) {
|
||||||
m_OrderExit = true;
|
m_OrderExit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <VTAll.hpp>
|
#include <VTAll.hpp>
|
||||||
|
#include <yycc.hpp>
|
||||||
#include "AccessibleValue.hpp"
|
#include <yycc/macro/class_copy_move.hpp>
|
||||||
#include "StructFormatter.hpp"
|
|
||||||
#include "CmdHelper.hpp"
|
#include "CmdHelper.hpp"
|
||||||
|
|
||||||
namespace Unvirt::Context {
|
namespace Unvirt::Context {
|
||||||
@@ -11,52 +10,54 @@ namespace Unvirt::Context {
|
|||||||
public:
|
public:
|
||||||
UnvirtContext();
|
UnvirtContext();
|
||||||
~UnvirtContext();
|
~UnvirtContext();
|
||||||
YYCC_DEL_CLS_COPY_MOVE(UnvirtContext);
|
YYCC_DELETE_COPY_MOVE(UnvirtContext)
|
||||||
|
|
||||||
|
public:
|
||||||
void Run();
|
void Run();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
enum class SearchPart {
|
void PrintInfo(const char8_t* u8_fmt, ...);
|
||||||
None, Object, Manager
|
void PrintError(const char8_t* u8_fmt, ...);
|
||||||
};
|
|
||||||
void PrintCommonInfo(const char8_t* u8_fmt, ...);
|
|
||||||
void PrintCommonError(const char8_t* u8_fmt, ...);
|
|
||||||
|
|
||||||
void ProcLoad(const CmdHelper::ArgumentsMap& amap);
|
private:
|
||||||
void ProcUnLoad(const CmdHelper::ArgumentsMap& amap);
|
void HandleLoad(const CmdHelper::LoadParam& param);
|
||||||
void ProcSave(const CmdHelper::ArgumentsMap& amap);
|
void HandleUnLoad(const CmdHelper::UnloadParam& param);
|
||||||
void ProcInfo(const CmdHelper::ArgumentsMap& amap);
|
void HandleSave(const CmdHelper::SaveParam& param);
|
||||||
void ProcLs(const CmdHelper::ArgumentsMap& amap);
|
void HandleInfo(const CmdHelper::InfoParam& param);
|
||||||
void ProcData(const CmdHelper::ArgumentsMap& amap);
|
void HandleLs(const CmdHelper::LsParam& param);
|
||||||
void ProcChunk(const CmdHelper::ArgumentsMap& amap);
|
void HandleData(const CmdHelper::DataParam& param);
|
||||||
void ProcSearch(const CmdHelper::ArgumentsMap& amap);
|
void HandleChunk(const CmdHelper::ChunkParam& param);
|
||||||
void ProcItems(const CmdHelper::ArgumentsMap& amap);
|
void HandleSearch(const CmdHelper::SearchParam& param);
|
||||||
void ProcStyle(const CmdHelper::ArgumentsMap& amap);
|
void HandleItems(const CmdHelper::ItemsParam& param);
|
||||||
void ProcEncoding(const CmdHelper::ArgumentsMap& amap);
|
void HandleStyle(const CmdHelper::StyleParam& param);
|
||||||
void ProcTemp(const CmdHelper::ArgumentsMap& amap);
|
void HandleEncoding(const CmdHelper::EncodingParam& param);
|
||||||
void ProcRsc(const CmdHelper::ArgumentsMap& amap, bool is_clear);
|
void HandleTemp(const CmdHelper::TempParam& param);
|
||||||
void ProcTest(const CmdHelper::ArgumentsMap& amap);
|
void HandleRscClear(const CmdHelper::RscClearParam& param);
|
||||||
void ProcHelp(const CmdHelper::ArgumentsMap& amap);
|
void HandleRscAdd(const CmdHelper::RscAddParam& param);
|
||||||
void ProcExit(const CmdHelper::ArgumentsMap& amap);
|
void HandleTest(const CmdHelper::TestParam& param);
|
||||||
|
void HandleVersion(const CmdHelper::VersionParam& param);
|
||||||
|
void HandleHelp(const CmdHelper::HelpParam& param);
|
||||||
|
void HandleExit(const CmdHelper::ExitParam& param);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
CmdHelper::Commander m_Commander;
|
||||||
|
bool m_OrderExit;
|
||||||
|
size_t m_ItemPerPage;
|
||||||
|
CmdHelper::StyleLevel m_ListStyle;
|
||||||
|
bool m_IsSearching;
|
||||||
|
CmdHelper::SearchPart m_SearchPart;
|
||||||
|
std::vector<size_t> m_SearchIdxResult;
|
||||||
|
|
||||||
|
private:
|
||||||
bool HasOpenedFile();
|
bool HasOpenedFile();
|
||||||
void ClearDocument();
|
void ClearDocument();
|
||||||
void PrintContextMsg(LibCmo::CKSTRING msg);
|
void PrintContextMsg(LibCmo::CKSTRING msg);
|
||||||
|
|
||||||
CmdHelper::CmdSplitter m_Splitter;
|
private:
|
||||||
CmdHelper::CommandParser m_Parser;
|
|
||||||
CmdHelper::HelpDocument m_Help;
|
|
||||||
|
|
||||||
size_t m_PageLen;
|
|
||||||
bool m_ListStyleIsFull;
|
|
||||||
SearchPart m_SearchPart;
|
|
||||||
std::vector<size_t> m_SearchIdxResult;
|
|
||||||
|
|
||||||
bool m_OrderExit;
|
|
||||||
LibCmo::CK2::CKContext* m_Ctx;
|
LibCmo::CK2::CKContext* m_Ctx;
|
||||||
LibCmo::CK2::CKFileReader* m_FileReader;
|
LibCmo::CK2::CKFileReader* m_FileReader;
|
||||||
bool m_IsShallowRead;
|
bool m_IsShallowRead;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user