finish cmd

This commit is contained in:
yyc12345 2023-03-04 00:13:03 +08:00
parent 2bdeee9007
commit e166b8ec5b
5 changed files with 186 additions and 61 deletions

View File

@ -13,6 +13,9 @@
/* TODO: /* TODO:
do not re-allocated ctx and file for each loading in future. do not re-allocated ctx and file for each loading in future.
this will be implemented by free all objects within doc. this will be implemented by free all objects within doc.
split encoding and temp folder setting
and load command only have file name arg.
*/ */
namespace Unvirt::CmdHelper { namespace Unvirt::CmdHelper {
@ -39,6 +42,7 @@ namespace Unvirt::CmdHelper {
// split // split
for (auto it = u8cmd.begin(); it != u8cmd.end(); ++it) { for (auto it = u8cmd.begin(); it != u8cmd.end(); ++it) {
mCmdChar = (*it); mCmdChar = (*it);
if (!std::isprint(mCmdChar)) continue; // skip all invalid characters
switch (mState) { switch (mState) {
case StateType::SPACE: case StateType::SPACE:
@ -169,11 +173,11 @@ namespace Unvirt::CmdHelper {
else if (subcmd == "unload") this->ProcUnLoad(cmds); else if (subcmd == "unload") this->ProcUnLoad(cmds);
else if (subcmd == "info") this->ProcInfo(cmds); else if (subcmd == "info") this->ProcInfo(cmds);
else if (subcmd == "ls") this->ProcLs(cmds); else if (subcmd == "ls") this->ProcLs(cmds);
else if (subcmd == "page") this->ProcPage(cmds); else if (subcmd == "items") this->ProcItems(cmds);
else if (subcmd == "help") this->PrintHelp(); else if (subcmd == "help") this->PrintHelp();
else if (subcmd == "exit") break; else if (subcmd == "exit") break;
else { else {
this->PrintCommonError("No such command \"\".", subcmd.c_str()); this->PrintCommonError("No such command \"%s\".", subcmd.c_str());
this->PrintHelp(); this->PrintHelp();
} }
@ -192,7 +196,7 @@ namespace Unvirt::CmdHelper {
} }
bool InteractiveCmd::HasOpenedFile(void) { bool InteractiveCmd::HasOpenedFile(void) {
return (m_Ctx != nullptr || m_File == nullptr || m_Doc != nullptr); return (m_Ctx != nullptr || m_File != nullptr || m_Doc != nullptr);
} }
void InteractiveCmd::PrintHelp(void) { void InteractiveCmd::PrintHelp(void) {
@ -215,9 +219,9 @@ namespace Unvirt::CmdHelper {
fputs("\tDescription: List something about loaded Virtools composition.\n", f); fputs("\tDescription: List something about loaded Virtools composition.\n", f);
fputs("\tSyntax: ls <obj | mgr> [page]\n", f); fputs("\tSyntax: ls <obj | mgr> [page]\n", f);
fputs("page\n", f); fputs("items\n", f);
fputs("\tDescription: Set up how many items should be listed in one page when using \"ls\" command.\n", f); fputs("\tDescription: Set up how many items should be listed in one page when using \"ls\" command.\n", f);
fputs("\tSyntax: page <num>\n", f); fputs("\tSyntax: items <num>\n", f);
fputs("exit\n", f); fputs("exit\n", f);
fputs("\tDescription: Exit program\n", f); fputs("\tDescription: Exit program\n", f);
@ -243,6 +247,7 @@ namespace Unvirt::CmdHelper {
std::vfprintf(stdout, u8_fmt, argptr); std::vfprintf(stdout, u8_fmt, argptr);
std::fputs(UNVIRT_TERMCOLTAIL, stdout); std::fputs(UNVIRT_TERMCOLTAIL, stdout);
va_end(argptr); va_end(argptr);
std::fputc('\n', stdout);
} }
@ -288,13 +293,17 @@ namespace Unvirt::CmdHelper {
if (err != LibCmo::CK2::CKERROR::CKERR_OK) { if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
// fail to load. release all. // fail to load. release all.
this->PrintCommonError("Fail to open file. Function return: %s\n%s", this->PrintCommonError("Fail to open file. Function return: %s\n%s",
Unvirt::AccessibleValue::GetCkErrorName(err), Unvirt::AccessibleValue::GetCkErrorName(err).c_str(),
Unvirt::AccessibleValue::GetCkErrorDescription(err) Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str()
); );
if (m_Doc != nullptr) delete m_Doc; if (m_Doc != nullptr) delete m_Doc;
if (m_File != nullptr) delete m_File; if (m_File != nullptr) delete m_File;
if (m_Ctx != nullptr) delete m_Ctx; if (m_Ctx != nullptr) delete m_Ctx;
m_Doc = nullptr;
m_File = nullptr;
m_Ctx = nullptr;
} }
} }
@ -309,6 +318,10 @@ namespace Unvirt::CmdHelper {
if (m_Doc != nullptr) delete m_Doc; if (m_Doc != nullptr) delete m_Doc;
if (m_File != nullptr) delete m_File; if (m_File != nullptr) delete m_File;
if (m_Ctx != nullptr) delete m_Ctx; if (m_Ctx != nullptr) delete m_Ctx;
m_Doc = nullptr;
m_File = nullptr;
m_Ctx = nullptr;
} }
void InteractiveCmd::ProcInfo(const std::deque<std::string>& cmd) { void InteractiveCmd::ProcInfo(const std::deque<std::string>& cmd) {
@ -323,14 +336,54 @@ namespace Unvirt::CmdHelper {
} }
void InteractiveCmd::ProcLs(const std::deque<std::string>& cmd) { void InteractiveCmd::ProcLs(const std::deque<std::string>& cmd) {
// static values of switches
static const std::vector<std::string> c_AllowedSwitches{ static const std::vector<std::string> c_AllowedSwitches{
"obj", "mgr" "obj", "mgr"
}; };
// check pre-requirement
if (!HasOpenedFile()) {
this->PrintCommonError("No loaded file.");
return;
}
// check requirement
size_t pos = 0u;
std::string sw;
if (!ArgParser::ParseSwitch(cmd, pos, c_AllowedSwitches, sw)) {
this->PrintArgParseError(cmd, pos);
return;
}
++pos;
int32_t gotten_page;
if (!ArgParser::ParseInt(cmd, pos, gotten_page) || gotten_page <= 0) {
gotten_page = 0; // asssume as zero
}
size_t page = static_cast<size_t>(gotten_page);
// show list
if (sw == c_AllowedSwitches[0]) {
// obj list
if (page * this->m_PageLen >= m_Doc->m_FileObjects.size()) {
this->PrintCommonError("Page out of range.");
return;
}
Unvirt::StructFormatter::PrintObjectList(this->m_Doc->m_FileObjects, page, this->m_PageLen);
} else {
// mgr list
if (page * this->m_PageLen >= m_Doc->m_FileManagersData.size()) {
this->PrintCommonError("Page out of range.");
return;
}
Unvirt::StructFormatter::PrintManagerList(this->m_Doc->m_FileManagersData, page, this->m_PageLen);
}
} }
void InteractiveCmd::ProcPage(const std::deque<std::string>& cmd) { void InteractiveCmd::ProcItems(const std::deque<std::string>& cmd) {
// check requirement // check requirement
size_t pos = 0u; size_t pos = 0u;
int32_t count; int32_t count;

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <VTUtils.h> #include <VTUtils.hpp>
#include <CKDefines.hpp> #include <CKDefines.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
@ -152,7 +152,7 @@ namespace Unvirt::CmdHelper {
void ProcUnLoad(const std::deque<std::string>& cmd); void ProcUnLoad(const std::deque<std::string>& cmd);
void ProcInfo(const std::deque<std::string>& cmd); void ProcInfo(const std::deque<std::string>& cmd);
void ProcLs(const std::deque<std::string>& cmd); void ProcLs(const std::deque<std::string>& cmd);
void ProcPage(const std::deque<std::string>& cmd); void ProcItems(const std::deque<std::string>& cmd);
CmdSplitter m_CmdSplitter; CmdSplitter m_CmdSplitter;
size_t m_PageLen; size_t m_PageLen;

View File

@ -2,8 +2,7 @@
#include "AccessibleValue.hpp" #include "AccessibleValue.hpp"
#include "TerminalHelper.hpp" #include "TerminalHelper.hpp"
namespace Unvirt { namespace Unvirt::StructFormatter {
namespace StructFormatter {
static FILE* fout = stdout; static FILE* fout = stdout;
@ -53,5 +52,74 @@ namespace Unvirt {
} }
static void PrintCKSTRING(const std::string& name) {
if (name.empty()) {
fputs(UNVIRT_TERMCOL_LIGHT_MAGENTA(("<anonymous>")), fout);
} else {
fputs(name.c_str(), fout);
} }
} }
static void PrintPointer(const void* ptr) {
if (ptr == nullptr) {
fputs(UNVIRT_TERMCOL_LIGHT_CYAN(("<null>")), fout);
} else {
fprintf(fout, "<0x%08zX>", reinterpret_cast<size_t>(ptr));
}
}
static void PrintCKGUID(const LibCmo::CK2::CKGUID& guid) {
fprintf(stdout, "<0x%08" PRIx32 ", 0x%08" PRIx32 ">", guid.d1, guid.d2);
}
void PrintObjectList(const LibCmo::CK2::XArray<LibCmo::CK2::CKFileObject>& ls, size_t page, size_t pageitems) {
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKFileObject\n")), fout);
size_t fulllen = ls.size(),
startpos = page * pageitems,
fullpage = fulllen / pageitems;
// print header
fputs("Index\tCK ID\tCKObject\tCKStateChunk\tName\n", fout);
// print body
for (size_t counter = startpos; counter < fulllen && (counter - startpos) < pageitems; ++counter) {
const auto& obj = ls[counter];
fprintf(stdout, "%zu\t%" PRIu32 "\t", counter, obj.ObjectId);
PrintPointer(obj.ObjPtr);
fputc('\t', fout);
PrintPointer(obj.Data);
fputc('\t', fout);
PrintCKSTRING(obj.Name);
fputc('\n', fout);
}
fprintf(fout, "Page %zu of %zu\n", page, fullpage);
}
void PrintManagerList(const LibCmo::CK2::XArray<LibCmo::CK2::CKFileManagerData>& ls, size_t page, size_t pageitems) {
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKFileManager\n")), fout);
size_t fulllen = ls.size(),
startpos = page * pageitems,
fullpage = fulllen / pageitems;
// print header
fputs("Index\tCKGUID\tCKBaseManager\tCKStateChunk\n", fout);
// print body
for (size_t counter = startpos; counter < fulllen && (counter - startpos) < pageitems; ++counter) {
const auto& mgr = ls[counter];
fprintf(stdout, "%zu\t", counter);
PrintCKGUID(mgr.Manager);
fputc('\t', fout);
PrintPointer(mgr.MgrPtr);
fputc('\t', fout);
PrintPointer(mgr.Data);
fputc('\n', fout);
}
fprintf(fout, "Page %zu of %zu\n", page, fullpage);
}
}

View File

@ -2,10 +2,10 @@
#include <CKFile.hpp> #include <CKFile.hpp>
namespace Unvirt { namespace Unvirt::StructFormatter {
namespace StructFormatter {
void PrintCKFileInfo(const LibCmo::CK2::CKFileInfo& fileinfo); void PrintCKFileInfo(const LibCmo::CK2::CKFileInfo& fileinfo);
void PrintObjectList(const LibCmo::CK2::XArray<LibCmo::CK2::CKFileObject>& ls, size_t page, size_t pageitems);
void PrintManagerList(const LibCmo::CK2::XArray<LibCmo::CK2::CKFileManagerData>& ls, size_t page, size_t pageitems);
} }
}

View File

@ -1,6 +1,7 @@
#include "AccessibleValue.hpp" #include "AccessibleValue.hpp"
#include "TerminalHelper.hpp" #include "TerminalHelper.hpp"
#include "StructFormatter.hpp" #include "StructFormatter.hpp"
#include "CmdHelper.hpp"
#include "CKMinContext.hpp" #include "CKMinContext.hpp"
#include "CKFile.hpp" #include "CKFile.hpp"
@ -12,16 +13,19 @@ int main(int argc, char* argv[]) {
Unvirt::TerminalHelper::EnsureTerminalColor(); Unvirt::TerminalHelper::EnsureTerminalColor();
Unvirt::TerminalHelper::EnsureTerminalEncoding(); Unvirt::TerminalHelper::EnsureTerminalEncoding();
LibCmo::CK2::CKMinContext vtctx; //LibCmo::CK2::CKMinContext vtctx;
vtctx.SetTempPath("Temp"); //vtctx.SetTempPath("Temp");
vtctx.SetEncoding("850"); //vtctx.SetEncoding("850");
LibCmo::CK2::CKFile vtfile(&vtctx); //LibCmo::CK2::CKFile vtfile(&vtctx);
LibCmo::CK2::CKFileDocument* doc; //LibCmo::CK2::CKFileDocument* doc;
LibCmo::CK2::CKERROR err = vtfile.DeepLoad("Level_02.NMO", &doc); //LibCmo::CK2::CKERROR err = vtfile.DeepLoad("Level_02.NMO", &doc);
if (doc) //if (doc)
Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo); // Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo);
auto cmd = new Unvirt::CmdHelper::InteractiveCmd();
cmd->Run();
delete cmd;
return 0; return 0;
} }