2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-08 12:24:56 +00:00

Use UTF-8 exclusively internally

This removes SystemString, SystemChar, etc.
All filepaths and log strings are assumed to be UTF-8,
with conversions to UTF-16 for Windows APIs as appropriate.

Updates amuse, athena, boo, kabufua and nod
This commit is contained in:
2021-06-30 14:20:45 -04:00
parent 6e12554026
commit 9ca1a38171
160 changed files with 2029 additions and 2753 deletions

View File

@@ -19,11 +19,11 @@
extern logvisor::Module LogModule;
struct ToolPassInfo {
hecl::SystemString pname;
hecl::SystemString cwd;
std::vector<hecl::SystemString> args;
std::vector<hecl::SystemChar> flags;
hecl::SystemString output;
std::string pname;
std::string cwd;
std::vector<std::string> args;
std::vector<char> flags;
std::string output;
hecl::Database::Project* project = nullptr;
unsigned verbosityLevel = 0;
bool force = false;
@@ -55,9 +55,9 @@ protected:
bool continuePrompt() {
if (!m_info.yes) {
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("\n" BLUE BOLD "Continue?" NORMAL " (Y/n) ")));
fmt::print(FMT_STRING("\n" BLUE BOLD "Continue?" NORMAL " (Y/n) "));
else
fmt::print(FMT_STRING(_SYS_STR("\nContinue? (Y/n) ")));
fmt::print(FMT_STRING("\nContinue? (Y/n) "));
fflush(stdout);
int ch;
@@ -73,7 +73,7 @@ protected:
#endif
{
if (ch == 'n' || ch == 'N') {
fmt::print(FMT_STRING(_SYS_STR("\n")));
fmt::print(FMT_STRING("\n"));
return false;
}
if (ch == 'y' || ch == 'Y' || ch == '\r' || ch == '\n')
@@ -83,7 +83,7 @@ protected:
tcsetattr(0, TCSANOW, &tioOld);
#endif
}
fmt::print(FMT_STRING(_SYS_STR("\n")));
fmt::print(FMT_STRING("\n"));
return true;
}
@@ -93,7 +93,7 @@ public:
hecl::GuiMode = info.gui;
}
virtual ~ToolBase() = default;
virtual hecl::SystemStringView toolName() const = 0;
virtual std::string_view toolName() const = 0;
virtual int run() = 0;
virtual void cancel() {}
explicit operator bool() const { return m_good; }
@@ -107,11 +107,11 @@ private:
FILE* m_sout = nullptr;
HelpFunc m_helpFunc;
int m_lineWidth;
hecl::SystemString m_wrapBuffer;
std::string m_wrapBuffer;
void _wrapBuf(hecl::SystemString& string) {
void _wrapBuf(std::string& string) {
int counter;
hecl::SystemString::iterator it = string.begin();
std::string::iterator it = string.begin();
while (it != string.end()) {
std::ptrdiff_t v = it - string.begin();
@@ -120,33 +120,33 @@ private:
for (counter = WRAP_INDENT; counter < m_lineWidth; ++counter) {
if (it >= string.end())
return;
if (*it == _SYS_STR('\n')) {
if (*it == '\n') {
counter = WRAP_INDENT;
++it;
}
if (counter == WRAP_INDENT) {
for (int i = 0; i < WRAP_INDENT; ++i)
it = string.insert(it, _SYS_STR(' ')) + 1;
it = string.insert(it, ' ') + 1;
}
if (it >= string.end())
return;
if (*it != _SYS_STR('\n'))
if (*it != '\n')
++it;
}
/* check for whitespace */
if (isspace(*it)) {
*it = _SYS_STR('\n');
*it = '\n';
counter = WRAP_INDENT;
++it;
} else {
/* check for nearest whitespace back in string */
for (hecl::SystemString::iterator k = it; k != string.begin(); --k) {
for (std::string::iterator k = it; k != string.begin(); --k) {
if (isspace(*k)) {
counter = WRAP_INDENT;
if (k - string.begin() < v)
k = string.insert(it, _SYS_STR('\n'));
k = string.insert(it, '\n');
else
*k = _SYS_STR('\n');
*k = '\n';
it = k + 1;
break;
}
@@ -175,61 +175,61 @@ public:
#endif
}
void print(const hecl::SystemChar* str) { fmt::print(m_sout, FMT_STRING(_SYS_STR("{}")), str); }
void print(const char* str) { fmt::print(m_sout, FMT_STRING("{}"), str); }
void printBold(const hecl::SystemChar* str) {
void printBold(const char* str) {
if (XTERM_COLOR)
fmt::print(m_sout, FMT_STRING(_SYS_STR("" BOLD "{}" NORMAL "")), str);
fmt::print(m_sout, FMT_STRING("" BOLD "{}" NORMAL ""), str);
else
fmt::print(m_sout, FMT_STRING(_SYS_STR("{}")), str);
fmt::print(m_sout, FMT_STRING("{}"), str);
}
void secHead(const hecl::SystemChar* headName) {
void secHead(const char* headName) {
if (XTERM_COLOR)
fmt::print(m_sout, FMT_STRING(_SYS_STR("" BOLD "{}" NORMAL "\n")), headName);
fmt::print(m_sout, FMT_STRING("" BOLD "{}" NORMAL "\n"), headName);
else
fmt::print(m_sout, FMT_STRING(_SYS_STR("{}\n")), headName);
fmt::print(m_sout, FMT_STRING("{}\n"), headName);
}
void optionHead(const hecl::SystemChar* flag, const hecl::SystemChar* synopsis) {
void optionHead(const char* flag, const char* synopsis) {
if (XTERM_COLOR)
fmt::print(m_sout, FMT_STRING(_SYS_STR("" BOLD "{}" NORMAL " ({})\n")), flag, synopsis);
fmt::print(m_sout, FMT_STRING("" BOLD "{}" NORMAL " ({})\n"), flag, synopsis);
else
fmt::print(m_sout, FMT_STRING(_SYS_STR("{} ({})\n")), flag, synopsis);
fmt::print(m_sout, FMT_STRING("{} ({})\n"), flag, synopsis);
}
void beginWrap() { m_wrapBuffer.clear(); }
void wrap(const hecl::SystemChar* str) { m_wrapBuffer += str; }
void wrap(const char* str) { m_wrapBuffer += str; }
void wrapBold(const hecl::SystemChar* str) {
void wrapBold(const char* str) {
if (XTERM_COLOR)
m_wrapBuffer += _SYS_STR("" BOLD "");
m_wrapBuffer += "" BOLD "";
m_wrapBuffer += str;
if (XTERM_COLOR)
m_wrapBuffer += _SYS_STR("" NORMAL "");
m_wrapBuffer += "" NORMAL "";
}
void endWrap() {
_wrapBuf(m_wrapBuffer);
m_wrapBuffer += _SYS_STR('\n');
fmt::print(m_sout, FMT_STRING(_SYS_STR("{}")), m_wrapBuffer);
m_wrapBuffer += '\n';
fmt::print(m_sout, FMT_STRING("{}"), m_wrapBuffer);
m_wrapBuffer.clear();
}
};
static hecl::SystemString MakePathArgAbsolute(const hecl::SystemString& arg, const hecl::SystemString& cwd) {
static std::string MakePathArgAbsolute(const std::string& arg, const std::string& cwd) {
#if _WIN32
if (arg.size() >= 2 && iswalpha(arg[0]) && arg[1] == _SYS_STR(':'))
if (arg.size() >= 2 && iswalpha(arg[0]) && arg[1] == ':')
return arg;
if (arg[0] == _SYS_STR('\\') || arg[0] == _SYS_STR('/'))
if (arg[0] == '\\' || arg[0] == '/')
return arg;
return cwd + _SYS_STR('\\') + arg;
return cwd + '\\' + arg;
#else
if (arg[0] == _SYS_STR('/') || arg[0] == _SYS_STR('\\'))
if (arg[0] == '/' || arg[0] == '\\')
return arg;
if (cwd.back() == _SYS_STR('/') || cwd.back() == _SYS_STR('\\'))
if (cwd.back() == '/' || cwd.back() == '\\')
return cwd + arg;
return cwd + _SYS_STR('/') + arg;
return cwd + '/' + arg;
#endif
}

View File

@@ -15,22 +15,22 @@ class ToolCook final : public ToolBase {
public:
explicit ToolCook(const ToolPassInfo& info) : ToolBase(info), m_useProj(info.project) {
/* Check for recursive flag */
for (hecl::SystemChar arg : info.flags)
if (arg == _SYS_STR('r'))
for (char arg : info.flags)
if (arg == 'r')
m_recursive = true;
/* Scan args */
if (info.args.size()) {
/* See if project path is supplied via args and use that over the getcwd one */
m_selectedItems.reserve(info.args.size());
for (const hecl::SystemString& arg : info.args) {
for (const std::string& arg : info.args) {
if (arg.empty())
continue;
else if (arg == _SYS_STR("--fast")) {
else if (arg == "--fast") {
m_fast = true;
continue;
} else if (arg.size() >= 8 && !arg.compare(0, 7, _SYS_STR("--spec="))) {
hecl::SystemString specName(arg.begin() + 7, arg.end());
} else if (arg.size() >= 8 && !arg.compare(0, 7, "--spec=")) {
std::string specName(arg.begin() + 7, arg.end());
for (const hecl::Database::DataSpecEntry* spec : hecl::Database::DATA_SPEC_REGISTRY) {
if (!hecl::StrCaseCmp(spec->m_name.data(), specName.c_str())) {
m_spec = spec;
@@ -38,12 +38,12 @@ public:
}
}
if (!m_spec)
LogModule.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to find data spec '{}'")), specName);
LogModule.report(logvisor::Fatal, FMT_STRING("unable to find data spec '{}'"), specName);
continue;
} else if (arg.size() >= 2 && arg[0] == _SYS_STR('-') && arg[1] == _SYS_STR('-'))
} else if (arg.size() >= 2 && arg[0] == '-' && arg[1] == '-')
continue;
hecl::SystemString subPath;
std::string subPath;
hecl::ProjectRootPath root = hecl::SearchForProject(MakePathArgAbsolute(arg, info.cwd), subPath);
if (root) {
if (!m_fallbackProj) {
@@ -51,8 +51,8 @@ public:
m_useProj = m_fallbackProj.get();
} else if (m_fallbackProj->getProjectRootPath() != root)
LogModule.report(logvisor::Fatal,
FMT_STRING(_SYS_STR("hecl cook can only process multiple items in the same project; ")
_SYS_STR("'{}' and '{}' are different projects")),
FMT_STRING("hecl cook can only process multiple items in the same project; "
"'{}' and '{}' are different projects"),
m_fallbackProj->getProjectRootPath().getAbsolutePath(),
root.getAbsolutePath());
m_selectedItems.emplace_back(*m_useProj, subPath);
@@ -67,85 +67,91 @@ public:
/* Default case: recursive at root */
if (m_selectedItems.empty()) {
m_selectedItems.reserve(1);
m_selectedItems.push_back({hecl::ProjectPath(*m_useProj, _SYS_STR(""))});
m_selectedItems.push_back({hecl::ProjectPath(*m_useProj, "")});
m_recursive = true;
}
}
static void Help(HelpOutput& help) {
help.secHead(_SYS_STR("NAME"));
help.secHead("NAME");
help.beginWrap();
help.wrap(_SYS_STR("hecl-cook - Cook objects within the project database\n"));
help.wrap("hecl-cook - Cook objects within the project database\n");
help.endWrap();
help.secHead(_SYS_STR("SYNOPSIS"));
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap(_SYS_STR("hecl cook [-rf] [--fast] [--spec=<spec>] [<pathspec>...]\n"));
help.wrap("hecl cook [-rf] [--fast] [--spec=<spec>] [<pathspec>...]\n");
help.endWrap();
help.secHead(_SYS_STR("DESCRIPTION"));
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap(_SYS_STR("This command initiates a cooking pass on the project database. Cooking ")
_SYS_STR("is analogous to compiling in software development. The resulting object buffers ")
_SYS_STR("are cached within the project database. HECL performs the following ")
_SYS_STR("tasks for each object during the cook process:\n\n"));
help.wrapBold(_SYS_STR("- Object Gather: "));
help.wrap(_SYS_STR("Files added with "));
help.wrapBold(_SYS_STR("hecl add"));
help.wrap(_SYS_STR(" are queried for their dependent files (e.g. "));
help.wrapBold(_SYS_STR(".blend"));
help.wrap(_SYS_STR(" files return any linked "));
help.wrapBold(_SYS_STR(".png"));
help.wrap(_SYS_STR(" images). If the dependent files are unable to be found, the cook process aborts.\n\n"));
help.wrapBold(_SYS_STR("- Modtime Comparison: "));
help.wrap(_SYS_STR("Files that have previously finished a cook pass are inspected for their time of ")
_SYS_STR("last modification. If the file hasn't changed since its previous cook-pass, the ") _SYS_STR(
"process is skipped. If the file has been moved or deleted, the object is automatically ")
_SYS_STR("removed from the project database.\n\n"));
help.wrapBold(_SYS_STR("- Cook: "));
help.wrap(_SYS_STR("A type-specific procedure compiles the file's contents into an efficient format ")
_SYS_STR("for use by the runtime. A data-buffer is provided to HECL.\n\n"));
help.wrapBold(_SYS_STR("- Hash and Compress: "));
help.wrap(_SYS_STR("The data-buffer is hashed and compressed before being cached in the object database.\n\n"));
help.wrap(
"This command initiates a cooking pass on the project database. Cooking "
"is analogous to compiling in software development. The resulting object buffers "
"are cached within the project database. HECL performs the following "
"tasks for each object during the cook process:\n\n");
help.wrapBold("- Object Gather: ");
help.wrap("Files added with ");
help.wrapBold("hecl add");
help.wrap(" are queried for their dependent files (e.g. ");
help.wrapBold(".blend");
help.wrap(" files return any linked ");
help.wrapBold(".png");
help.wrap(" images). If the dependent files are unable to be found, the cook process aborts.\n\n");
help.wrapBold("- Modtime Comparison: ");
help.wrap(
"Files that have previously finished a cook pass are inspected for their time of "
"last modification. If the file hasn't changed since its previous cook-pass, the "
"process is skipped. If the file has been moved or deleted, the object is automatically "
"removed from the project database.\n\n");
help.wrapBold("- Cook: ");
help.wrap(
"A type-specific procedure compiles the file's contents into an efficient format "
"for use by the runtime. A data-buffer is provided to HECL.\n\n");
help.wrapBold("- Hash and Compress: ");
help.wrap("The data-buffer is hashed and compressed before being cached in the object database.\n\n");
help.endWrap();
help.secHead(_SYS_STR("OPTIONS"));
help.optionHead(_SYS_STR("<pathspec>..."), _SYS_STR("input file(s)"));
help.secHead("OPTIONS");
help.optionHead("<pathspec>...", "input file(s)");
help.beginWrap();
help.wrap(_SYS_STR("Specifies working file(s) containing production data to be cooked by HECL. ")
_SYS_STR("Glob-strings may be specified (e.g. "));
help.wrapBold(_SYS_STR("*.blend"));
help.wrap(_SYS_STR(") to automatically cook all matching current-directory files in the project database. ")
_SYS_STR("If no path specified, all files in the project database are cooked.\n"));
help.wrap(
"Specifies working file(s) containing production data to be cooked by HECL. "
"Glob-strings may be specified (e.g. ");
help.wrapBold("*.blend");
help.wrap(
") to automatically cook all matching current-directory files in the project database. "
"If no path specified, all files in the project database are cooked.\n");
help.endWrap();
help.optionHead(_SYS_STR("-r"), _SYS_STR("recursion"));
help.optionHead("-r", "recursion");
help.beginWrap();
help.wrap(_SYS_STR("Enables recursive file-matching for cooking entire directories of working files.\n"));
help.wrap("Enables recursive file-matching for cooking entire directories of working files.\n");
help.endWrap();
help.optionHead(_SYS_STR("-f"), _SYS_STR("force"));
help.optionHead("-f", "force");
help.beginWrap();
help.wrap(_SYS_STR("Forces cooking of all matched files, ignoring timestamp differences.\n"));
help.wrap("Forces cooking of all matched files, ignoring timestamp differences.\n");
help.endWrap();
help.optionHead(_SYS_STR("--fast"), _SYS_STR("fast cook"));
help.optionHead("--fast", "fast cook");
help.beginWrap();
help.wrap(_SYS_STR("Performs draft-optimization cooking for supported data types.\n"));
help.wrap("Performs draft-optimization cooking for supported data types.\n");
help.endWrap();
help.optionHead(_SYS_STR("--spec=<spec>"), _SYS_STR("data specification"));
help.optionHead("--spec=<spec>", "data specification");
help.beginWrap();
help.wrap(_SYS_STR("Specifies a DataSpec to use when cooking. ")
_SYS_STR("This build of hecl supports the following values of <spec>:\n"));
help.wrap(
"Specifies a DataSpec to use when cooking. "
"This build of hecl supports the following values of <spec>:\n");
for (const hecl::Database::DataSpecEntry* spec : hecl::Database::DATA_SPEC_REGISTRY) {
if (!spec->m_factory)
continue;
help.wrap(_SYS_STR(" "));
help.wrap(" ");
help.wrapBold(spec->m_name.data());
help.wrap(_SYS_STR("\n"));
help.wrap("\n");
}
}
hecl::SystemStringView toolName() const override { return _SYS_STR("cook"sv); }
std::string_view toolName() const override { return "cook"sv; }
int run() override {
hecl::MultiProgressPrinter printer(true);

View File

@@ -32,18 +32,18 @@ public:
LogModule.report(logvisor::Fatal, FMT_STRING("hecl extract needs a source path as its first argument"));
if (!info.project) {
hecl::SystemString rootDir;
std::string rootDir;
if (info.output.empty()) {
/* Get name from input file and init project there */
hecl::SystemString baseFile = info.args.front();
size_t slashPos = baseFile.rfind(_SYS_STR('/'));
if (slashPos == hecl::SystemString::npos)
slashPos = baseFile.rfind(_SYS_STR('\\'));
if (slashPos != hecl::SystemString::npos)
std::string baseFile = info.args.front();
size_t slashPos = baseFile.rfind('/');
if (slashPos == std::string::npos)
slashPos = baseFile.rfind('\\');
if (slashPos != std::string::npos)
baseFile.assign(baseFile.begin() + slashPos + 1, baseFile.end());
size_t dotPos = baseFile.rfind(_SYS_STR('.'));
if (dotPos != hecl::SystemString::npos)
size_t dotPos = baseFile.rfind('.');
if (dotPos != std::string::npos)
baseFile.assign(baseFile.begin(), baseFile.begin() + dotPos);
if (baseFile.empty())
@@ -62,8 +62,8 @@ public:
newProjRoot.makeDir();
m_fallbackProj.reset(new hecl::Database::Project(newProjRoot));
if (logvisor::ErrorCount > ErrorRef)
LogModule.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to init project at '{}'")), rootDir);
LogModule.report(logvisor::Info, FMT_STRING(_SYS_STR("initialized project at '{}/.hecl'")), rootDir);
LogModule.report(logvisor::Fatal, FMT_STRING("unable to init project at '{}'"), rootDir);
LogModule.report(logvisor::Info, FMT_STRING("initialized project at '{}/.hecl'"), rootDir);
m_useProj = m_fallbackProj.get();
} else
m_useProj = info.project;
@@ -87,44 +87,44 @@ public:
}
static void Help(HelpOutput& help) {
help.secHead(_SYS_STR("NAME"));
help.secHead("NAME");
help.beginWrap();
help.wrap(_SYS_STR("hecl-extract - Extract objects from supported package/image formats\n"));
help.wrap("hecl-extract - Extract objects from supported package/image formats\n");
help.endWrap();
help.secHead(_SYS_STR("SYNOPSIS"));
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap(_SYS_STR("hecl extract <packagefile> [<subnode>...]\n"));
help.wrap("hecl extract <packagefile> [<subnode>...]\n");
help.endWrap();
help.secHead(_SYS_STR("DESCRIPTION"));
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap(_SYS_STR("This command recursively extracts all or part of a dataspec-supported ")
_SYS_STR("package format. Each object is decoded to a working format and added to the project.\n\n"));
help.wrap("This command recursively extracts all or part of a dataspec-supported "
"package format. Each object is decoded to a working format and added to the project.\n\n");
help.endWrap();
help.secHead(_SYS_STR("OPTIONS"));
help.optionHead(_SYS_STR("<packagefile>[/<subnode>...]"), _SYS_STR("input file"));
help.secHead("OPTIONS");
help.optionHead("<packagefile>[/<subnode>...]", "input file");
help.beginWrap();
help.wrap(_SYS_STR("Specifies the package file or disc image to source data from. ")
_SYS_STR("An optional subnode specifies a named hierarchical-node specific ")
_SYS_STR("to the game architecture (levels/areas)."));
help.wrap("Specifies the package file or disc image to source data from. "
"An optional subnode specifies a named hierarchical-node specific "
"to the game architecture (levels/areas).");
help.endWrap();
}
hecl::SystemStringView toolName() const override { return _SYS_STR("extract"sv); }
std::string_view toolName() const override { return "extract"sv; }
static void _recursivePrint(int level, hecl::Database::IDataSpec::ExtractReport& rep) {
for (int l = 0; l < level; ++l)
fmt::print(FMT_STRING(_SYS_STR(" ")));
fmt::print(FMT_STRING(" "));
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("" BOLD "{}" NORMAL "")), rep.name);
fmt::print(FMT_STRING("" BOLD "{}" NORMAL ""), rep.name);
else
fmt::print(FMT_STRING(_SYS_STR("{}")), rep.name);
fmt::print(FMT_STRING("{}"), rep.name);
if (rep.desc.size())
fmt::print(FMT_STRING(_SYS_STR(" [{}]")), rep.desc);
fmt::print(FMT_STRING(_SYS_STR("\n")));
fmt::print(FMT_STRING(" [{}]"), rep.desc);
fmt::print(FMT_STRING("\n"));
for (hecl::Database::IDataSpec::ExtractReport& child : rep.childOpts)
_recursivePrint(level + 1, child);
}
@@ -132,32 +132,32 @@ public:
int run() override {
if (m_specPasses.empty()) {
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("" RED BOLD "NOTHING TO EXTRACT" NORMAL "\n")));
fmt::print(FMT_STRING("" RED BOLD "NOTHING TO EXTRACT" NORMAL "\n"));
else
fmt::print(FMT_STRING(_SYS_STR("NOTHING TO EXTRACT\n")));
fmt::print(FMT_STRING("NOTHING TO EXTRACT\n"));
return 1;
}
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("" GREEN BOLD "ABOUT TO EXTRACT:" NORMAL "\n")));
fmt::print(FMT_STRING("" GREEN BOLD "ABOUT TO EXTRACT:" NORMAL "\n"));
else
fmt::print(FMT_STRING(_SYS_STR("ABOUT TO EXTRACT:\n")));
fmt::print(FMT_STRING("ABOUT TO EXTRACT:\n"));
for (hecl::Database::IDataSpec::ExtractReport& rep : m_reps) {
_recursivePrint(0, rep);
fmt::print(FMT_STRING(_SYS_STR("\n")));
fmt::print(FMT_STRING("\n"));
}
fflush(stdout);
if (continuePrompt()) {
for (SpecExtractPass& ds : m_specPasses) {
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("" MAGENTA BOLD "Using DataSpec {}:" NORMAL "\n")), ds.m_entry->m_name);
fmt::print(FMT_STRING("" MAGENTA BOLD "Using DataSpec {}:" NORMAL "\n"), ds.m_entry->m_name);
else
fmt::print(FMT_STRING(_SYS_STR("Using DataSpec {}:\n")), ds.m_entry->m_name);
fmt::print(FMT_STRING("Using DataSpec {}:\n"), ds.m_entry->m_name);
ds.m_instance->doExtract(m_einfo, {true});
fmt::print(FMT_STRING(_SYS_STR("\n\n")));
fmt::print(FMT_STRING("\n\n"));
}
}

View File

@@ -20,50 +20,50 @@ public:
static void Help(HelpOutput& help) {
/* clang-format off */
help.printBold(
_SYS_STR(" ___________ \n")
_SYS_STR(" ,.-'\"...........``~., \n")
_SYS_STR(" ,.-\".......................\"-., \n")
_SYS_STR(" ,/..................................\":, \n")
_SYS_STR(" .,?........................................, \n")
_SYS_STR(" /...........................................,}\n")
_SYS_STR(" ./........................................,:`^`..}\n")
_SYS_STR(" ./.......................................,:\"...../\n")
_SYS_STR(" ?.....__..................................:`...../\n")
_SYS_STR(" /__.(...\"~-,_...........................,:`....../\n")
_SYS_STR(" /(_....\"~,_....\"~,_.....................,:`...._/ \n")
_SYS_STR(" {.._$;_....\"=,_.....\"-,_......,.-~-,},.~\";/....} \n")
_SYS_STR(" ((...*~_......\"=-._...\";,,./`........../\"..../ \n")
_SYS_STR(" ,,,___.`~,......\"~.,....................`......}....../ \n")
_SYS_STR("............(....`=-,,...`.........................(...;_,,-\" \n")
_SYS_STR("............/.`~,......`-.................................../ \n")
_SYS_STR(".............`~.*-,.....................................|,./...,__ \n")
_SYS_STR(",,_..........}.>-._...................................|.......`=~-, \n")
_SYS_STR(".....`=~-,__......`,................................. \n")
_SYS_STR("...................`=~-,,.,........................... \n")
_SYS_STR(".........................`:,,..........................`\n")
_SYS_STR("...........................`=-,...............,%%`>--==`` \n")
_SYS_STR(".................................._.........._,-%%...` \n")
_SYS_STR("...................................,\n"));
" ___________ \n"
" ,.-'\"...........``~., \n"
" ,.-\".......................\"-., \n"
" ,/..................................\":, \n"
" .,?........................................, \n"
" /...........................................,}\n"
" ./........................................,:`^`..}\n"
" ./.......................................,:\"...../\n"
" ?.....__..................................:`...../\n"
" /__.(...\"~-,_...........................,:`....../\n"
" /(_....\"~,_....\"~,_.....................,:`...._/ \n"
" {.._$;_....\"=,_.....\"-,_......,.-~-,},.~\";/....} \n"
" ((...*~_......\"=-._...\";,,./`........../\"..../ \n"
" ,,,___.`~,......\"~.,....................`......}....../ \n"
"............(....`=-,,...`.........................(...;_,,-\" \n"
"............/.`~,......`-.................................../ \n"
".............`~.*-,.....................................|,./...,__ \n"
",,_..........}.>-._...................................|.......`=~-, \n"
".....`=~-,__......`,................................. \n"
"...................`=~-,,.,........................... \n"
".........................`:,,..........................`\n"
"...........................`=-,...............,%%`>--==`` \n"
".................................._.........._,-%%...` \n"
"...................................,\n");
/* clang-format on */
}
static void ShowHelp(const hecl::SystemString& toolName) {
static void ShowHelp(const std::string& toolName) {
/* Select tool's help-text streamer */
HelpOutput::HelpFunc helpFunc = nullptr;
if (toolName == _SYS_STR("init"))
if (toolName == "init")
helpFunc = ToolInit::Help;
else if (toolName == _SYS_STR("spec"))
else if (toolName == "spec")
helpFunc = ToolSpec::Help;
else if (toolName == _SYS_STR("extract"))
else if (toolName == "extract")
helpFunc = ToolExtract::Help;
else if (toolName == _SYS_STR("cook"))
else if (toolName == "cook")
helpFunc = ToolCook::Help;
else if (toolName == _SYS_STR("package") || toolName == _SYS_STR("pack"))
else if (toolName == "package" || toolName == "pack")
helpFunc = ToolPackage::Help;
else if (toolName == _SYS_STR("help"))
else if (toolName == "help")
helpFunc = ToolHelp::Help;
else {
LogModule.report(logvisor::Error, FMT_STRING(_SYS_STR("unrecognized tool '{}' - can't help")), toolName);
LogModule.report(logvisor::Error, FMT_STRING("unrecognized tool '{}' - can't help"), toolName);
return;
}
@@ -71,7 +71,7 @@ public:
ho.go();
}
hecl::SystemStringView toolName() const override { return _SYS_STR("help"sv); }
std::string_view toolName() const override { return "help"sv; }
int run() override {
ShowHelp(m_info.args.front());

View File

@@ -22,11 +22,11 @@ public:
/* Scan args */
if (info.args.size()) {
/* See if project path is supplied via args and use that over the getcwd one */
for (const hecl::SystemString& arg : info.args) {
for (const std::string& arg : info.args) {
if (arg.empty())
continue;
hecl::SystemString subPath;
std::string subPath;
hecl::ProjectRootPath root = hecl::SearchForProject(MakePathArgAbsolute(arg, info.cwd), subPath);
if (root) {
@@ -47,83 +47,82 @@ public:
~ToolImage() override = default;
static void Help(HelpOutput& help) {
help.secHead(_SYS_STR("NAME"));
help.secHead("NAME");
help.beginWrap();
help.wrap(_SYS_STR("hecl-image - Generate GameCube/Wii disc image from packaged files\n"));
help.wrap("hecl-image - Generate GameCube/Wii disc image from packaged files\n");
help.endWrap();
help.secHead(_SYS_STR("SYNOPSIS"));
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap(_SYS_STR("hecl image [<input-dir>]\n"));
help.wrap("hecl image [<input-dir>]\n");
help.endWrap();
help.secHead(_SYS_STR("DESCRIPTION"));
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap(_SYS_STR("This command uses the current contents of `out` to generate a GameCube or ")
_SYS_STR("Wii disc image. `hecl package` must have been run previously to be effective.\n"));
help.wrap("This command uses the current contents of `out` to generate a GameCube or "
"Wii disc image. `hecl package` must have been run previously to be effective.\n");
help.endWrap();
help.secHead(_SYS_STR("OPTIONS"));
help.optionHead(_SYS_STR("<input-dir>"), _SYS_STR("input directory"));
help.secHead("OPTIONS");
help.optionHead("<input-dir>", "input directory");
help.beginWrap();
help.wrap(_SYS_STR("Specifies a project subdirectory to root the resulting image from. ")
_SYS_STR("Project must contain an out/sys and out/files directory to succeed.\n"));
help.wrap("Specifies a project subdirectory to root the resulting image from. "
"Project must contain an out/sys and out/files directory to succeed.\n");
help.endWrap();
}
hecl::SystemStringView toolName() const override { return _SYS_STR("image"sv); }
std::string_view toolName() const override { return "image"sv; }
int run() override {
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("" GREEN BOLD "ABOUT TO IMAGE:" NORMAL "\n")));
fmt::print(FMT_STRING("" GREEN BOLD "ABOUT TO IMAGE:" NORMAL "\n"));
else
fmt::print(FMT_STRING(_SYS_STR("ABOUT TO IMAGE:\n")));
fmt::print(FMT_STRING("ABOUT TO IMAGE:\n"));
fmt::print(FMT_STRING(_SYS_STR(" {}\n")), m_useProj->getProjectRootPath().getAbsolutePath());
fmt::print(FMT_STRING(" {}\n"), m_useProj->getProjectRootPath().getAbsolutePath());
fflush(stdout);
if (continuePrompt()) {
hecl::ProjectPath outPath(m_useProj->getProjectWorkingPath(), _SYS_STR("out"));
hecl::ProjectPath outPath(m_useProj->getProjectWorkingPath(), "out");
if (!outPath.isDirectory()) {
LogModule.report(logvisor::Error, FMT_STRING(_SYS_STR("{} is not a directory")), outPath.getAbsolutePath());
LogModule.report(logvisor::Error, FMT_STRING("{} is not a directory"), outPath.getAbsolutePath());
return 1;
}
hecl::ProjectPath bootBinPath(outPath, _SYS_STR("sys/boot.bin"));
hecl::ProjectPath bootBinPath(outPath, "sys/boot.bin");
if (!bootBinPath.isFile()) {
LogModule.report(logvisor::Error, FMT_STRING(_SYS_STR("{} is not a file")), bootBinPath.getAbsolutePath());
LogModule.report(logvisor::Error, FMT_STRING("{} is not a file"), bootBinPath.getAbsolutePath());
return 1;
}
athena::io::FileReader r(bootBinPath.getAbsolutePath());
if (r.hasError()) {
LogModule.report(logvisor::Error, FMT_STRING(_SYS_STR("unable to open {}")), bootBinPath.getAbsolutePath());
LogModule.report(logvisor::Error, FMT_STRING("unable to open {}"), bootBinPath.getAbsolutePath());
return 1;
}
std::string id = r.readString(6);
r.close();
hecl::SystemStringConv idView(id);
hecl::SystemString fileOut = hecl::SystemString(outPath.getAbsolutePath()) + _SYS_STR('/') + idView.c_str();
std::string fileOut = std::string(outPath.getAbsolutePath()) + '/' + id;
hecl::MultiProgressPrinter printer(true);
auto progFunc = [&printer](float totalProg, nod::SystemStringView fileName, size_t fileBytesXfered) {
auto progFunc = [&printer](float totalProg, std::string_view fileName, size_t fileBytesXfered) {
printer.print(fileName, std::nullopt, totalProg);
};
if (id[0] == 'G') {
fileOut += _SYS_STR(".gcm");
fileOut += ".gcm";
if (nod::DiscBuilderGCN::CalculateTotalSizeRequired(outPath.getAbsolutePath()) == UINT64_MAX)
return 1;
LogModule.report(logvisor::Info, FMT_STRING(_SYS_STR("Generating {} as GameCube image")), fileOut);
LogModule.report(logvisor::Info, FMT_STRING("Generating {} as GameCube image"), fileOut);
nod::DiscBuilderGCN db(fileOut, progFunc);
if (db.buildFromDirectory(outPath.getAbsolutePath()) != nod::EBuildResult::Success)
return 1;
} else {
fileOut += _SYS_STR(".iso");
fileOut += ".iso";
bool dualLayer;
if (nod::DiscBuilderWii::CalculateTotalSizeRequired(outPath.getAbsolutePath(), dualLayer) == UINT64_MAX)
return 1;
LogModule.report(logvisor::Info, FMT_STRING(_SYS_STR("Generating {} as {}-layer Wii image")), fileOut,
dualLayer ? _SYS_STR("dual") : _SYS_STR("single"));
LogModule.report(logvisor::Info, FMT_STRING("Generating {} as {}-layer Wii image"), fileOut,
dualLayer ? "dual" : "single");
nod::DiscBuilderWii db(fileOut, dualLayer, progFunc);
if (db.buildFromDirectory(outPath.getAbsolutePath()) != nod::EBuildResult::Success)
return 1;

View File

@@ -4,12 +4,12 @@
#include <cstdio>
class ToolInit final : public ToolBase {
const hecl::SystemString* m_dir = nullptr;
const std::string* m_dir = nullptr;
public:
explicit ToolInit(const ToolPassInfo& info) : ToolBase(info) {
hecl::Sstat theStat;
const hecl::SystemString* dir;
const std::string* dir;
if (info.args.size())
dir = &info.args.front();
else
@@ -18,18 +18,18 @@ public:
if (hecl::Stat(dir->c_str(), &theStat)) {
hecl::MakeDir(dir->c_str());
if (hecl::Stat(dir->c_str(), &theStat)) {
LogModule.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to stat '{}'")), *dir);
LogModule.report(logvisor::Fatal, FMT_STRING("unable to stat '{}'"), *dir);
return;
}
}
if (!S_ISDIR(theStat.st_mode)) {
LogModule.report(logvisor::Fatal, FMT_STRING(_SYS_STR("'{}' is not a directory")), *dir);
LogModule.report(logvisor::Fatal, FMT_STRING("'{}' is not a directory"), *dir);
return;
}
hecl::SystemString testPath = *dir + _SYS_STR("/.hecl/beacon");
std::string testPath = *dir + "/.hecl/beacon";
if (!hecl::Stat(testPath.c_str(), &theStat)) {
LogModule.report(logvisor::Fatal, FMT_STRING(_SYS_STR("project already exists at '{}'")), *dir);
LogModule.report(logvisor::Fatal, FMT_STRING("project already exists at '{}'"), *dir);
return;
}
@@ -43,35 +43,35 @@ public:
hecl::Database::Project proj((hecl::ProjectRootPath(*m_dir)));
if (logvisor::ErrorCount > ErrorRef)
return 1;
LogModule.report(logvisor::Info, FMT_STRING(_SYS_STR("initialized project at '{}/.hecl'")), *m_dir);
LogModule.report(logvisor::Info, FMT_STRING("initialized project at '{}/.hecl'"), *m_dir);
return 0;
}
static void Help(HelpOutput& help) {
help.secHead(_SYS_STR("NAME"));
help.secHead("NAME");
help.beginWrap();
help.wrap(_SYS_STR("hecl-init - Initialize a brand-new project database\n"));
help.wrap("hecl-init - Initialize a brand-new project database\n");
help.endWrap();
help.secHead(_SYS_STR("SYNOPSIS"));
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap(_SYS_STR("hecl init [<dir>]\n"));
help.wrap("hecl init [<dir>]\n");
help.endWrap();
help.secHead(_SYS_STR("DESCRIPTION"));
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap(_SYS_STR("Creates a "));
help.wrapBold(_SYS_STR(".hecl"));
help.wrap(_SYS_STR(" directory within the selected directory with an initialized database index. ")
_SYS_STR("This constitutes an empty HECL project, ready for making stuff!!\n"));
help.wrap("Creates a ");
help.wrapBold(".hecl");
help.wrap(" directory within the selected directory with an initialized database index. "
"This constitutes an empty HECL project, ready for making stuff!!\n");
help.endWrap();
help.secHead(_SYS_STR("OPTIONS"));
help.optionHead(_SYS_STR("<dir>"), _SYS_STR("group directory path"));
help.secHead("OPTIONS");
help.optionHead("<dir>", "group directory path");
help.beginWrap();
help.wrap(_SYS_STR("Directory to create new project database in. If not specified, current directory is used.\n"));
help.wrap("Directory to create new project database in. If not specified, current directory is used.\n");
help.endWrap();
}
hecl::SystemStringView toolName() const override { return _SYS_STR("init"sv); }
std::string_view toolName() const override { return "init"sv; }
};

View File

@@ -13,22 +13,22 @@ public:
}
static void Help(HelpOutput& help) {
help.secHead(_SYS_STR("NAME"));
help.secHead("NAME");
help.beginWrap();
help.wrap(_SYS_STR("hecl-installaddon - Installs embedded Blender addon into local Blender\n"));
help.wrap("hecl-installaddon - Installs embedded Blender addon into local Blender\n");
help.endWrap();
help.secHead(_SYS_STR("SYNOPSIS"));
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap(_SYS_STR("hecl installaddon\n"));
help.wrap("hecl installaddon\n");
help.endWrap();
help.secHead(_SYS_STR("DESCRIPTION"));
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap(_SYS_STR("Installs the hecl Blender addon into Blender. The path to the blender executable ")
_SYS_STR("can be overridden by setting the BLENDER_BIN environment variable."));
help.wrap("Installs the hecl Blender addon into Blender. The path to the blender executable "
"can be overridden by setting the BLENDER_BIN environment variable.");
help.endWrap();
}
hecl::SystemStringView toolName() const override { return _SYS_STR("installaddon"sv); }
std::string_view toolName() const override { return "installaddon"sv; }
};

View File

@@ -21,8 +21,8 @@ class ToolPackage final : public ToolBase {
void CheckFile(const hecl::ProjectPath& path) {
auto lastComp = path.getLastComponent();
if (hecl::StringUtils::BeginsWith(lastComp, _SYS_STR("!world")) &&
hecl::StringUtils::EndsWith(lastComp, _SYS_STR(".blend")))
if (hecl::StringUtils::BeginsWith(lastComp, "!world") &&
hecl::StringUtils::EndsWith(lastComp, ".blend"))
AddSelectedItem(path);
}
@@ -47,8 +47,8 @@ class ToolPackage final : public ToolBase {
* and no nested !world.blend files == General PAK */
if (checkGeneral && origSize == m_selectedItems.size()) {
auto pathComps = path.getPathComponents();
if (pathComps.size() == 2 && pathComps[0] != _SYS_STR("out") && pathComps[1] != _SYS_STR("Shared") &&
pathComps[0].find(_SYS_STR(".app")) == hecl::SystemString::npos)
if (pathComps.size() == 2 && pathComps[0] != "out" && pathComps[1] != "Shared" &&
pathComps[0].find(".app") == std::string::npos)
AddSelectedItem(path);
}
}
@@ -62,14 +62,14 @@ public:
if (info.args.size()) {
/* See if project path is supplied via args and use that over the getcwd one */
m_selectedItems.reserve(info.args.size());
for (const hecl::SystemString& arg : info.args) {
for (const std::string& arg : info.args) {
if (arg.empty())
continue;
else if (arg == _SYS_STR("--fast")) {
else if (arg == "--fast") {
m_fast = true;
continue;
} else if (arg.size() >= 8 && !arg.compare(0, 7, _SYS_STR("--spec="))) {
hecl::SystemString specName(arg.begin() + 7, arg.end());
} else if (arg.size() >= 8 && !arg.compare(0, 7, "--spec=")) {
std::string specName(arg.begin() + 7, arg.end());
for (const hecl::Database::DataSpecEntry* spec : hecl::Database::DATA_SPEC_REGISTRY) {
if (!hecl::StrCaseCmp(spec->m_name.data(), specName.c_str())) {
m_spec = spec;
@@ -77,12 +77,12 @@ public:
}
}
if (!m_spec)
LogModule.report(logvisor::Fatal, FMT_STRING(_SYS_STR("unable to find data spec '{}'")), specName);
LogModule.report(logvisor::Fatal, FMT_STRING("unable to find data spec '{}'"), specName);
continue;
} else if (arg.size() >= 2 && arg[0] == _SYS_STR('-') && arg[1] == _SYS_STR('-'))
} else if (arg.size() >= 2 && arg[0] == '-' && arg[1] == '-')
continue;
hecl::SystemString subPath;
std::string subPath;
hecl::ProjectRootPath root = hecl::SearchForProject(MakePathArgAbsolute(arg, info.cwd), subPath);
if (root) {
@@ -91,8 +91,8 @@ public:
m_useProj = m_fallbackProj.get();
} else if (m_fallbackProj->getProjectRootPath() != root)
LogModule.report(logvisor::Fatal,
FMT_STRING(_SYS_STR("hecl package can only process multiple items in the same project; ")
_SYS_STR("'{}' and '{}' are different projects")),
FMT_STRING("hecl package can only process multiple items in the same project; "
"'{}' and '{}' are different projects"),
m_fallbackProj->getProjectRootPath().getAbsolutePath(),
root.getAbsolutePath());
@@ -107,60 +107,65 @@ public:
/* Default case: recursive at root */
if (m_selectedItems.empty())
FindSelectedItems({*m_useProj, _SYS_STR("")}, true);
FindSelectedItems({*m_useProj, ""}, true);
}
static void Help(HelpOutput& help) {
help.secHead(_SYS_STR("NAME"));
help.secHead("NAME");
help.beginWrap();
help.wrap(_SYS_STR("hecl-pack\n") _SYS_STR("hecl-package - Package objects within the project database\n"));
help.wrap(
"hecl-pack\n"
"hecl-package - Package objects within the project database\n");
help.endWrap();
help.secHead(_SYS_STR("SYNOPSIS"));
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap(_SYS_STR("hecl package [--spec=<spec>] [<input-dir>]\n"));
help.wrap("hecl package [--spec=<spec>] [<input-dir>]\n");
help.endWrap();
help.secHead(_SYS_STR("DESCRIPTION"));
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap(_SYS_STR("This command initiates a packaging pass on the project database. Packaging ")
_SYS_STR("is analogous to linking in software development. All objects necessary to ") _SYS_STR(
"generate a complete package are gathered, grouped, and indexed within a .upak file.\n"));
help.wrap(
"This command initiates a packaging pass on the project database. Packaging "
"is analogous to linking in software development. All objects necessary to "
"generate a complete package are gathered, grouped, and indexed within a .upak file.\n");
help.endWrap();
help.secHead(_SYS_STR("OPTIONS"));
help.optionHead(_SYS_STR("--spec=<spec>"), _SYS_STR("data specification"));
help.secHead("OPTIONS");
help.optionHead("--spec=<spec>", "data specification");
help.beginWrap();
help.wrap(_SYS_STR("Specifies a DataSpec to use when cooking and generating the package. ")
_SYS_STR("This build of hecl supports the following values of <spec>:\n"));
help.wrap(
"Specifies a DataSpec to use when cooking and generating the package. "
"This build of hecl supports the following values of <spec>:\n");
for (const hecl::Database::DataSpecEntry* spec : hecl::Database::DATA_SPEC_REGISTRY) {
if (!spec->m_factory)
continue;
help.wrap(_SYS_STR(" "));
help.wrap(" ");
help.wrapBold(spec->m_name.data());
help.wrap(_SYS_STR("\n"));
help.wrap("\n");
}
help.endWrap();
help.secHead(_SYS_STR("OPTIONS"));
help.optionHead(_SYS_STR("<input-dir>"), _SYS_STR("input directory"));
help.secHead("OPTIONS");
help.optionHead("<input-dir>", "input directory");
help.beginWrap();
help.wrap(_SYS_STR("Specifies a project subdirectory to root the resulting package from. ")
_SYS_STR("If any dependent files fall outside this subdirectory, they will be implicitly ")
_SYS_STR("gathered and packaged.\n"));
help.wrap(
"Specifies a project subdirectory to root the resulting package from. "
"If any dependent files fall outside this subdirectory, they will be implicitly "
"gathered and packaged.\n");
help.endWrap();
}
hecl::SystemStringView toolName() const override { return _SYS_STR("package"sv); }
std::string_view toolName() const override { return "package"sv; }
int run() override {
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("" GREEN BOLD "ABOUT TO PACKAGE:" NORMAL "\n")));
fmt::print(FMT_STRING("" GREEN BOLD "ABOUT TO PACKAGE:" NORMAL "\n"));
else
fmt::print(FMT_STRING(_SYS_STR("ABOUT TO PACKAGE:\n")));
fmt::print(FMT_STRING("ABOUT TO PACKAGE:\n"));
for (auto& item : m_selectedItems)
fmt::print(FMT_STRING(_SYS_STR(" {}\n")), item.getRelativePath());
fmt::print(FMT_STRING(" {}\n"), item.getRelativePath());
fflush(stdout);
if (continuePrompt()) {
@@ -168,7 +173,7 @@ public:
hecl::ClientProcess cp(&printer);
for (const hecl::ProjectPath& path : m_selectedItems) {
if (!m_useProj->packagePath(path, printer, m_fast, m_spec, &cp))
LogModule.report(logvisor::Error, FMT_STRING(_SYS_STR("Unable to package {}")), path.getAbsolutePath());
LogModule.report(logvisor::Error, FMT_STRING("Unable to package {}"), path.getAbsolutePath());
}
cp.waitUntilComplete();
}

View File

@@ -16,12 +16,12 @@ public:
LogModule.report(logvisor::Fatal, FMT_STRING("hecl spec must be ran within a project directory"));
const auto& specs = info.project->getDataSpecs();
hecl::SystemString firstArg = info.args.front();
std::string firstArg = info.args.front();
hecl::ToLower(firstArg);
if (firstArg == _SYS_STR("enable"))
if (firstArg == "enable")
mode = MENABLE;
else if (firstArg == _SYS_STR("disable"))
else if (firstArg == "disable")
mode = MDISABLE;
else
return;
@@ -41,46 +41,46 @@ public:
}
}
if (!found)
LogModule.report(logvisor::Fatal, FMT_STRING(_SYS_STR("'{}' is not found in the dataspec registry")), *it);
LogModule.report(logvisor::Fatal, FMT_STRING("'{}' is not found in the dataspec registry"), *it);
}
}
static void Help(HelpOutput& help) {
help.secHead(_SYS_STR("NAME"));
help.secHead("NAME");
help.beginWrap();
help.wrap(_SYS_STR("hecl-spec - Configure target data options\n"));
help.wrap("hecl-spec - Configure target data options\n");
help.endWrap();
help.secHead(_SYS_STR("SYNOPSIS"));
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap(_SYS_STR("hecl spec [enable|disable] [<specname>...]\n"));
help.wrap("hecl spec [enable|disable] [<specname>...]\n");
help.endWrap();
help.secHead(_SYS_STR("DESCRIPTION"));
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap(
_SYS_STR("This command configures the HECL project with the user's preferred target DataSpecs.\n\n")
_SYS_STR("Providing enable/disable argument will bulk-set the enable status of the provided spec(s)")
_SYS_STR("list. If enable/disable is not provided, a list of supported DataSpecs is printed.\n\n"));
"This command configures the HECL project with the user's preferred target DataSpecs.\n\n"
"Providing enable/disable argument will bulk-set the enable status of the provided spec(s)"
"list. If enable/disable is not provided, a list of supported DataSpecs is printed.\n\n");
help.endWrap();
help.secHead(_SYS_STR("OPTIONS"));
help.optionHead(_SYS_STR("<specname>..."), _SYS_STR("DataSpec name(s)"));
help.secHead("OPTIONS");
help.optionHead("<specname>...", "DataSpec name(s)");
help.beginWrap();
help.wrap(_SYS_STR("Specifies platform-names to enable/disable"));
help.wrap("Specifies platform-names to enable/disable");
help.endWrap();
}
hecl::SystemStringView toolName() const override { return _SYS_STR("spec"sv); }
std::string_view toolName() const override { return "spec"sv; }
int run() override {
if (!m_info.project) {
for (const hecl::Database::DataSpecEntry* spec : hecl::Database::DATA_SPEC_REGISTRY) {
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("" BOLD CYAN "{}" NORMAL "\n")), spec->m_name);
fmt::print(FMT_STRING("" BOLD CYAN "{}" NORMAL "\n"), spec->m_name);
else
fmt::print(FMT_STRING(_SYS_STR("{}\n")), spec->m_name);
fmt::print(FMT_STRING(_SYS_STR(" {}\n")), spec->m_desc);
fmt::print(FMT_STRING("{}\n"), spec->m_name);
fmt::print(FMT_STRING(" {}\n"), spec->m_desc);
}
return 0;
}
@@ -89,28 +89,28 @@ public:
if (mode == MLIST) {
for (auto& spec : specs) {
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("" BOLD CYAN "{}" NORMAL "")), spec.spec.m_name);
fmt::print(FMT_STRING("" BOLD CYAN "{}" NORMAL ""), spec.spec.m_name);
else
fmt::print(FMT_STRING(_SYS_STR("{}")), spec.spec.m_name);
fmt::print(FMT_STRING("{}"), spec.spec.m_name);
if (spec.active) {
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR(" " BOLD GREEN "[ENABLED]" NORMAL "")));
fmt::print(FMT_STRING(" " BOLD GREEN "[ENABLED]" NORMAL ""));
else
fmt::print(FMT_STRING(_SYS_STR(" [ENABLED]")));
fmt::print(FMT_STRING(" [ENABLED]"));
}
fmt::print(FMT_STRING(_SYS_STR("\n {}\n")), spec.spec.m_desc);
fmt::print(FMT_STRING("\n {}\n"), spec.spec.m_desc);
}
return 0;
}
std::vector<hecl::SystemString> opSpecs;
std::vector<std::string> opSpecs;
auto it = m_info.args.begin();
++it;
for (; it != m_info.args.end(); ++it) {
hecl::SystemString itName = *it;
std::string itName = *it;
hecl::ToLower(itName);
for (auto& spec : specs) {
hecl::SystemString compName(spec.spec.m_name);
std::string compName(spec.spec.m_name);
hecl::ToLower(compName);
if (itName == compName) {
opSpecs.emplace_back(spec.spec.m_name);

View File

@@ -46,27 +46,27 @@ bool XTERM_COLOR = false;
*/
/* Main usage message */
static void printHelp(const hecl::SystemChar* pname) {
static void printHelp(const char* pname) {
if (XTERM_COLOR)
fmt::print(FMT_STRING(_SYS_STR("" BOLD "HECL" NORMAL "")));
fmt::print(FMT_STRING("" BOLD "HECL" NORMAL ""));
else
fmt::print(FMT_STRING(_SYS_STR("HECL")));
fmt::print(FMT_STRING("HECL"));
#if HECL_HAS_NOD
#define TOOL_LIST "extract|init|cook|package|image|installaddon|help"
#else
#define TOOL_LIST "extract|init|cook|package|installaddon|help"
#endif
#if HECL_GIT
fmt::print(FMT_STRING(_SYS_STR(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: {} " TOOL_LIST "\n")), pname);
fmt::print(FMT_STRING(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: {} " TOOL_LIST "\n"), pname);
#elif HECL_VER
fmt::print(FMT_STRING(_SYS_STR(" Version " HECL_VER_S "\nUsage: {} " TOOL_LIST "\n")), pname);
fmt::print(FMT_STRING(" Version " HECL_VER_S "\nUsage: {} " TOOL_LIST "\n"), pname);
#else
fmt::print(FMT_STRING(_SYS_STR("\nUsage: {} " TOOL_LIST "\n")), pname);
fmt::print(FMT_STRING("\nUsage: {} " TOOL_LIST "\n"), pname);
#endif
}
/* Regex patterns */
static const hecl::SystemRegex regOPEN(_SYS_STR("-o([^\"]*|\\S*)"), std::regex::ECMAScript | std::regex::optimize);
static const std::regex regOPEN("-o([^\"]*|\\S*)", std::regex::ECMAScript | std::regex::optimize);
static ToolBase* ToolPtr = nullptr;
@@ -85,40 +85,36 @@ static void AthenaExc(athena::error::Level level, const char* file, const char*,
AthenaLog.vreport(logvisor::Level(level), fmt, args);
}
hecl::SystemString ExeDir;
std::string ExeDir;
#if _WIN32
static ToolPassInfo CreateInfo(int argc, const wchar_t** argv) {
#else
static ToolPassInfo CreateInfo(int argc, const char** argv) {
#endif
hecl::SystemChar cwdbuf[1024];
static ToolPassInfo CreateInfo(int argc, char** argv) {
char cwdbuf[1024];
ToolPassInfo info;
info.pname = argv[0];
if (hecl::Getcwd(cwdbuf, static_cast<int>(std::size(cwdbuf)))) {
info.cwd = cwdbuf;
if (info.cwd.size() && info.cwd.back() != _SYS_STR('/') && info.cwd.back() != _SYS_STR('\\')) {
if (info.cwd.size() && info.cwd.back() != '/' && info.cwd.back() != '\\') {
#if _WIN32
info.cwd += _SYS_STR('\\');
info.cwd += '\\';
#else
info.cwd += _SYS_STR('/');
info.cwd += '/';
#endif
}
if (hecl::PathRelative(argv[0])) {
ExeDir = hecl::SystemString(cwdbuf) + _SYS_STR('/');
ExeDir = std::string(cwdbuf) + '/';
}
hecl::SystemString Argv0(argv[0]);
hecl::SystemString::size_type lastIdx = Argv0.find_last_of(_SYS_STR("/\\"));
if (lastIdx != hecl::SystemString::npos) {
std::string Argv0(argv[0]);
std::string::size_type lastIdx = Argv0.find_last_of("/\\");
if (lastIdx != std::string::npos) {
ExeDir.insert(ExeDir.end(), Argv0.begin(), Argv0.begin() + lastIdx);
}
}
/* Concatenate args */
std::vector<hecl::SystemString> args;
std::vector<std::string> args;
args.reserve(argc - 2);
for (int i = 2; i < argc; ++i) {
args.emplace_back(argv[i]);
@@ -127,11 +123,11 @@ static ToolPassInfo CreateInfo(int argc, const char** argv) {
if (!args.empty()) {
/* Extract output argument */
for (auto it = args.cbegin(); it != args.cend();) {
const hecl::SystemString& arg = *it;
hecl::SystemRegexMatch oMatch;
const std::string& arg = *it;
std::smatch oMatch;
if (std::regex_search(arg, oMatch, regOPEN)) {
const hecl::SystemString& token = oMatch[1].str();
const std::string& token = oMatch[1].str();
if (token.size()) {
if (info.output.empty()) {
@@ -162,28 +158,28 @@ static ToolPassInfo CreateInfo(int argc, const char** argv) {
/* Iterate flags */
bool threadArg = false;
for (auto it = args.cbegin(); it != args.cend();) {
const hecl::SystemString& arg = *it;
const std::string& arg = *it;
if (threadArg) {
threadArg = false;
hecl::CpuCountOverride = int(hecl::StrToUl(arg.c_str(), nullptr, 0));
it = args.erase(it);
continue;
}
if (arg.size() < 2 || arg[0] != _SYS_STR('-') || arg[1] == _SYS_STR('-')) {
if (arg.size() < 2 || arg[0] != '-' || arg[1] == '-') {
++it;
continue;
}
for (auto chit = arg.cbegin() + 1; chit != arg.cend(); ++chit) {
if (*chit == _SYS_STR('v'))
if (*chit == 'v')
++info.verbosityLevel;
else if (*chit == _SYS_STR('f'))
else if (*chit == 'f')
info.force = true;
else if (*chit == _SYS_STR('y'))
else if (*chit == 'y')
info.yes = true;
else if (*chit == _SYS_STR('g'))
else if (*chit == 'g')
info.gui = true;
else if (*chit == _SYS_STR('j')) {
else if (*chit == 'j') {
++chit;
if (*chit)
hecl::CpuCountOverride = int(hecl::StrToUl(&*chit, nullptr, 0));
@@ -199,14 +195,14 @@ static ToolPassInfo CreateInfo(int argc, const char** argv) {
/* Gather remaining args */
info.args.reserve(args.size());
for (const hecl::SystemString& arg : args)
for (const std::string& arg : args)
info.args.push_back(arg);
}
return info;
}
static std::unique_ptr<hecl::Database::Project> FindProject(hecl::SystemStringView cwd) {
static std::unique_ptr<hecl::Database::Project> FindProject(std::string_view cwd) {
const hecl::ProjectRootPath rootPath = hecl::SearchForProject(cwd);
if (!rootPath) {
return nullptr;
@@ -224,47 +220,47 @@ static std::unique_ptr<hecl::Database::Project> FindProject(hecl::SystemStringVi
return newProj;
}
static std::unique_ptr<ToolBase> MakeSelectedTool(hecl::SystemString toolName, ToolPassInfo& info) {
hecl::SystemString toolNameLower = toolName;
static std::unique_ptr<ToolBase> MakeSelectedTool(std::string toolName, ToolPassInfo& info) {
std::string toolNameLower = toolName;
hecl::ToLower(toolNameLower);
if (toolNameLower == _SYS_STR("init")) {
if (toolNameLower == "init") {
return std::make_unique<ToolInit>(info);
}
if (toolNameLower == _SYS_STR("spec")) {
if (toolNameLower == "spec") {
return std::make_unique<ToolSpec>(info);
}
if (toolNameLower == _SYS_STR("extract")) {
if (toolNameLower == "extract") {
return std::make_unique<ToolExtract>(info);
}
if (toolNameLower == _SYS_STR("cook")) {
if (toolNameLower == "cook") {
return std::make_unique<ToolCook>(info);
}
if (toolNameLower == _SYS_STR("package") || toolNameLower == _SYS_STR("pack")) {
if (toolNameLower == "package" || toolNameLower == "pack") {
return std::make_unique<ToolPackage>(info);
}
#if HECL_HAS_NOD
if (toolNameLower == _SYS_STR("image")) {
if (toolNameLower == "image") {
return std::make_unique<ToolImage>(info);
}
#endif
if (toolNameLower == _SYS_STR("installaddon")) {
if (toolNameLower == "installaddon") {
return std::make_unique<ToolInstallAddon>(info);
}
if (toolNameLower == _SYS_STR("help")) {
if (toolNameLower == "help") {
return std::make_unique<ToolHelp>(info);
}
auto fp = hecl::FopenUnique(toolName.c_str(), _SYS_STR("rb"));
auto fp = hecl::FopenUnique(toolName.c_str(), "rb");
if (fp == nullptr) {
LogModule.report(logvisor::Error, FMT_STRING(_SYS_STR("unrecognized tool '{}'")), toolNameLower);
LogModule.report(logvisor::Error, FMT_STRING("unrecognized tool '{}'"), toolNameLower);
return nullptr;
}
fp.reset();
@@ -275,14 +271,16 @@ static std::unique_ptr<ToolBase> MakeSelectedTool(hecl::SystemString toolName, T
}
#if _WIN32
int wmain(int argc, const wchar_t** argv)
#include <nowide/args.hpp>
#else
/* SIGWINCH should do nothing */
static void SIGWINCHHandler(int sig) {}
int main(int argc, const char** argv)
#endif
{
if (argc > 1 && !hecl::StrCmp(argv[1], _SYS_STR("--dlpackage"))) {
int main(int argc, char** argv) {
#if _WIN32
nowide::args _(argc, argv);
#endif
if (argc > 1 && !hecl::StrCmp(argv[1], "--dlpackage")) {
fmt::print(FMT_STRING("{}\n"), METAFORCE_DLPACKAGE);
return 100;
}
@@ -295,9 +293,10 @@ int main(int argc, const char** argv)
/* Xterm check */
#if _WIN32
const char* conemuANSI = getenv("ConEmuANSI");
if (conemuANSI && !strcmp(conemuANSI, "ON"))
const auto conemuANSI = hecl::GetEnv("ConEmuANSI");
if (conemuANSI && conemuANSI == "ON") {
XTERM_COLOR = true;
}
#else
const char* term = getenv("TERM");
if (term && !strncmp(term, "xterm", 5))
@@ -311,8 +310,8 @@ int main(int argc, const char** argv)
atSetExceptionHandler(AthenaExc);
#if SENTRY_ENABLED
hecl::Runtime::FileStoreManager fileMgr{_SYS_STR("sentry-native-hecl")};
hecl::SystemUTF8Conv cacheDir{fileMgr.getStoreRoot()};
hecl::Runtime::FileStoreManager fileMgr{"sentry-native-hecl"};
std::string cacheDir{fileMgr.getStoreRoot()};
logvisor::RegisterSentry("hecl", METAFORCE_WC_DESCRIBE, cacheDir.c_str());
#endif
@@ -323,8 +322,9 @@ int main(int argc, const char** argv)
system("PAUSE");
#endif
return 0;
} else if (argc == 0) {
printHelp(_SYS_STR("hecl"));
}
if (argc == 0) {
printHelp("hecl");
#if WIN_PAUSE
system("PAUSE");
#endif
@@ -353,7 +353,7 @@ int main(int argc, const char** argv)
return 1;
}
if (info.verbosityLevel) {
LogModule.report(logvisor::Info, FMT_STRING(_SYS_STR("Constructed tool '{}' {}\n")), tool->toolName(),
LogModule.report(logvisor::Info, FMT_STRING("Constructed tool '{}' {}\n"), tool->toolName(),
info.verbosityLevel);
}