diff --git a/hecl/driver/ToolBase.hpp b/hecl/driver/ToolBase.hpp index 48f233703..6a28a7251 100644 --- a/hecl/driver/ToolBase.hpp +++ b/hecl/driver/ToolBase.hpp @@ -55,9 +55,9 @@ protected: bool continuePrompt() { if (!m_info.yes) { if (XTERM_COLOR) - hecl::Printf(_SYS_STR("\n" BLUE BOLD "Continue?" NORMAL " (Y/n) ")); + fmt::print(fmt(_SYS_STR("\n" BLUE BOLD "Continue?" NORMAL " (Y/n) "))); else - hecl::Printf(_SYS_STR("\nContinue? (Y/n) ")); + fmt::print(fmt(_SYS_STR("\nContinue? (Y/n) "))); fflush(stdout); int ch; @@ -73,7 +73,7 @@ protected: #endif { if (ch == 'n' || ch == 'N') { - hecl::Printf(_SYS_STR("\n")); + fmt::print(fmt(_SYS_STR("\n"))); return false; } if (ch == 'y' || ch == 'Y' || ch == '\r' || ch == '\n') @@ -83,7 +83,7 @@ protected: tcsetattr(0, TCSANOW, &tioOld); #endif } - hecl::Printf(_SYS_STR("\n")); + fmt::print(fmt(_SYS_STR("\n"))); return true; } @@ -175,27 +175,27 @@ public: #endif } - void print(const hecl::SystemChar* str) { hecl::FPrintf(m_sout, _SYS_STR("%s"), str); } + void print(const hecl::SystemChar* str) { fmt::print(m_sout, fmt(_SYS_STR("{}")), str); } void printBold(const hecl::SystemChar* str) { if (XTERM_COLOR) - hecl::FPrintf(m_sout, _SYS_STR("" BOLD "%s" NORMAL ""), str); + fmt::print(m_sout, fmt(_SYS_STR("" BOLD "{}" NORMAL "")), str); else - hecl::FPrintf(m_sout, _SYS_STR("%s"), str); + fmt::print(m_sout, fmt(_SYS_STR("{}")), str); } void secHead(const hecl::SystemChar* headName) { if (XTERM_COLOR) - hecl::FPrintf(m_sout, _SYS_STR("" BOLD "%s" NORMAL "\n"), headName); + fmt::print(m_sout, fmt(_SYS_STR("" BOLD "{}" NORMAL "\n")), headName); else - hecl::FPrintf(m_sout, _SYS_STR("%s\n"), headName); + fmt::print(m_sout, fmt(_SYS_STR("{}\n")), headName); } void optionHead(const hecl::SystemChar* flag, const hecl::SystemChar* synopsis) { if (XTERM_COLOR) - hecl::FPrintf(m_sout, _SYS_STR("" BOLD "%s" NORMAL " (%s)\n"), flag, synopsis); + fmt::print(m_sout, fmt(_SYS_STR("" BOLD "{}" NORMAL " ({})\n")), flag, synopsis); else - hecl::FPrintf(m_sout, _SYS_STR("%s (%s)\n"), flag, synopsis); + fmt::print(m_sout, fmt(_SYS_STR("{} ({})\n")), flag, synopsis); } void beginWrap() { m_wrapBuffer.clear(); } @@ -213,7 +213,7 @@ public: void endWrap() { _wrapBuf(m_wrapBuffer); m_wrapBuffer += _SYS_STR('\n'); - hecl::FPrintf(m_sout, _SYS_STR("%s"), m_wrapBuffer.c_str()); + fmt::print(m_sout, fmt(_SYS_STR("{}")), m_wrapBuffer); m_wrapBuffer.clear(); } }; diff --git a/hecl/driver/ToolCook.hpp b/hecl/driver/ToolCook.hpp index d9b2fd7b9..0d17d9b8c 100644 --- a/hecl/driver/ToolCook.hpp +++ b/hecl/driver/ToolCook.hpp @@ -38,7 +38,7 @@ public: } } if (!m_spec) - LogModule.report(logvisor::Fatal, "unable to find data spec '%s'", specName.c_str()); + LogModule.report(logvisor::Fatal, fmt("unable to find data spec '{}'"), specName); continue; } else if (arg.size() >= 2 && arg[0] == _SYS_STR('-') && arg[1] == _SYS_STR('-')) continue; @@ -51,18 +51,18 @@ public: m_useProj = m_fallbackProj.get(); } else if (m_fallbackProj->getProjectRootPath() != root) LogModule.report(logvisor::Fatal, - _SYS_STR("hecl cook can only process multiple items in the same project; ") - _SYS_STR("'%s' and '%s' are different projects"), - m_fallbackProj->getProjectRootPath().getAbsolutePath().data(), - root.getAbsolutePath().data()); + fmt(_SYS_STR("hecl cook can only process multiple items in the same project; ") + _SYS_STR("'{}' and '{}' are different projects")), + m_fallbackProj->getProjectRootPath().getAbsolutePath(), + root.getAbsolutePath()); m_selectedItems.emplace_back(*m_useProj, subPath); } } } if (!m_useProj) LogModule.report(logvisor::Fatal, - "hecl cook must be ran within a project directory or " - "provided a path within a project"); + fmt("hecl cook must be ran within a project directory or " + "provided a path within a project")); /* Default case: recursive at root */ if (m_selectedItems.empty()) { diff --git a/hecl/driver/ToolExtract.hpp b/hecl/driver/ToolExtract.hpp index fdac6d278..1f16e93b3 100644 --- a/hecl/driver/ToolExtract.hpp +++ b/hecl/driver/ToolExtract.hpp @@ -29,7 +29,7 @@ class ToolExtract final : public ToolBase { public: ToolExtract(const ToolPassInfo& info) : ToolBase(info) { if (!m_info.args.size()) - LogModule.report(logvisor::Fatal, "hecl extract needs a source path as its first argument"); + LogModule.report(logvisor::Fatal, fmt("hecl extract needs a source path as its first argument")); if (!info.project) { hecl::SystemString rootDir; @@ -47,7 +47,7 @@ public: baseFile.assign(baseFile.begin(), baseFile.begin() + dotPos); if (baseFile.empty()) - LogModule.report(logvisor::Fatal, "hecl extract must be ran within a project directory"); + LogModule.report(logvisor::Fatal, fmt("hecl extract must be ran within a project directory")); rootDir = info.cwd + baseFile; } else { @@ -62,8 +62,8 @@ public: newProjRoot.makeDir(); m_fallbackProj.reset(new hecl::Database::Project(newProjRoot)); if (logvisor::ErrorCount > ErrorRef) - LogModule.report(logvisor::Fatal, "unable to init project at '%s'", rootDir.c_str()); - LogModule.report(logvisor::Info, _SYS_STR("initialized project at '%s/.hecl'"), rootDir.c_str()); + LogModule.report(logvisor::Fatal, fmt("unable to init project at '{}'"), rootDir); + LogModule.report(logvisor::Info, fmt(_SYS_STR("initialized project at '{}/.hecl'")), rootDir); m_useProj = m_fallbackProj.get(); } else m_useProj = info.project; @@ -116,15 +116,15 @@ public: static void _recursivePrint(int level, hecl::Database::IDataSpec::ExtractReport& rep) { for (int l = 0; l < level; ++l) - hecl::Printf(_SYS_STR(" ")); + fmt::print(fmt(_SYS_STR(" "))); if (XTERM_COLOR) - hecl::Printf(_SYS_STR("" BOLD "%s" NORMAL ""), rep.name.c_str()); + fmt::print(fmt(_SYS_STR("" BOLD "{}" NORMAL "")), rep.name); else - hecl::Printf(_SYS_STR("%s"), rep.name.c_str()); + fmt::print(fmt(_SYS_STR("{}")), rep.name); if (rep.desc.size()) - hecl::Printf(_SYS_STR(" [%s]"), rep.desc.c_str()); - hecl::Printf(_SYS_STR("\n")); + fmt::print(fmt(_SYS_STR(" [{}]")), rep.desc); + fmt::print(fmt(_SYS_STR("\n"))); for (hecl::Database::IDataSpec::ExtractReport& child : rep.childOpts) _recursivePrint(level + 1, child); } @@ -132,32 +132,32 @@ public: int run() { if (m_specPasses.empty()) { if (XTERM_COLOR) - hecl::Printf(_SYS_STR("" RED BOLD "NOTHING TO EXTRACT" NORMAL "\n")); + fmt::print(fmt(_SYS_STR("" RED BOLD "NOTHING TO EXTRACT" NORMAL "\n"))); else - hecl::Printf(_SYS_STR("NOTHING TO EXTRACT\n")); + fmt::print(fmt(_SYS_STR("NOTHING TO EXTRACT\n"))); return 1; } if (XTERM_COLOR) - hecl::Printf(_SYS_STR("" GREEN BOLD "ABOUT TO EXTRACT:" NORMAL "\n")); + fmt::print(fmt(_SYS_STR("" GREEN BOLD "ABOUT TO EXTRACT:" NORMAL "\n"))); else - hecl::Printf(_SYS_STR("ABOUT TO EXTRACT:\n")); + fmt::print(fmt(_SYS_STR("ABOUT TO EXTRACT:\n"))); for (hecl::Database::IDataSpec::ExtractReport& rep : m_reps) { _recursivePrint(0, rep); - hecl::Printf(_SYS_STR("\n")); + fmt::print(fmt(_SYS_STR("\n"))); } fflush(stdout); if (continuePrompt()) { for (SpecExtractPass& ds : m_specPasses) { if (XTERM_COLOR) - hecl::Printf(_SYS_STR("" MAGENTA BOLD "Using DataSpec %s:" NORMAL "\n"), ds.m_entry->m_name.data()); + fmt::print(fmt(_SYS_STR("" MAGENTA BOLD "Using DataSpec {}:" NORMAL "\n")), ds.m_entry->m_name); else - hecl::Printf(_SYS_STR("Using DataSpec %s:\n"), ds.m_entry->m_name.data()); + fmt::print(fmt(_SYS_STR("Using DataSpec {}:\n")), ds.m_entry->m_name); ds.m_instance->doExtract(m_einfo, {true}); - hecl::Printf(_SYS_STR("\n\n")); + fmt::print(fmt(_SYS_STR("\n\n"))); } } diff --git a/hecl/driver/ToolHelp.hpp b/hecl/driver/ToolHelp.hpp index 2abeb904e..590cbf1ef 100644 --- a/hecl/driver/ToolHelp.hpp +++ b/hecl/driver/ToolHelp.hpp @@ -9,7 +9,7 @@ class ToolHelp final : public ToolBase { public: ToolHelp(const ToolPassInfo& info) : ToolBase(info) { if (m_info.args.empty()) { - LogModule.report(logvisor::Error, "help requires a tool name argument"); + LogModule.report(logvisor::Error, fmt("help requires a tool name argument")); return; } m_good = true; @@ -64,7 +64,7 @@ public: else if (toolName == _SYS_STR("help")) helpFunc = ToolHelp::Help; else { - LogModule.report(logvisor::Error, _SYS_STR("unrecognized tool '%s' - can't help"), toolName.c_str()); + LogModule.report(logvisor::Error, fmt(_SYS_STR("unrecognized tool '{}' - can't help")), toolName); return; } diff --git a/hecl/driver/ToolImage.hpp b/hecl/driver/ToolImage.hpp index ea071aa88..6644313b3 100644 --- a/hecl/driver/ToolImage.hpp +++ b/hecl/driver/ToolImage.hpp @@ -17,7 +17,7 @@ class ToolImage final : public ToolBase { public: ToolImage(const ToolPassInfo& info) : ToolBase(info), m_useProj(info.project) { if (!info.project) - LogModule.report(logvisor::Fatal, "hecl image must be ran within a project directory"); + LogModule.report(logvisor::Fatal, fmt("hecl image must be ran within a project directory")); /* Scan args */ if (info.args.size()) { @@ -40,8 +40,8 @@ public: } if (!m_useProj) LogModule.report(logvisor::Fatal, - "hecl image must be ran within a project directory or " - "provided a path within a project"); + fmt("hecl image must be ran within a project directory or " + "provided a path within a project")); } ~ToolImage() {} @@ -75,29 +75,29 @@ public: int run() { if (XTERM_COLOR) - hecl::Printf(_SYS_STR("" GREEN BOLD "ABOUT TO IMAGE:" NORMAL "\n")); + fmt::print(fmt(_SYS_STR("" GREEN BOLD "ABOUT TO IMAGE:" NORMAL "\n"))); else - hecl::Printf(_SYS_STR("ABOUT TO IMAGE:\n")); + fmt::print(fmt(_SYS_STR("ABOUT TO IMAGE:\n"))); - hecl::Printf(_SYS_STR(" %s\n"), m_useProj->getProjectRootPath().getAbsolutePath().data()); + fmt::print(fmt(_SYS_STR(" {}\n")), m_useProj->getProjectRootPath().getAbsolutePath()); fflush(stdout); if (continuePrompt()) { hecl::ProjectPath outPath(m_useProj->getProjectWorkingPath(), _SYS_STR("out")); if (!outPath.isDirectory()) { - LogModule.report(logvisor::Error, _SYS_STR("%s is not a directory"), outPath.getAbsolutePath().data()); + LogModule.report(logvisor::Error, fmt(_SYS_STR("{} is not a directory")), outPath.getAbsolutePath()); return 1; } hecl::ProjectPath bootBinPath(outPath, _SYS_STR("sys/boot.bin")); if (!bootBinPath.isFile()) { - LogModule.report(logvisor::Error, _SYS_STR("%s is not a file"), bootBinPath.getAbsolutePath().data()); + LogModule.report(logvisor::Error, fmt(_SYS_STR("{} is not a file")), bootBinPath.getAbsolutePath()); return 1; } athena::io::FileReader r(bootBinPath.getAbsolutePath()); if (r.hasError()) { - LogModule.report(logvisor::Error, _SYS_STR("unable to open %s"), bootBinPath.getAbsolutePath().data()); + LogModule.report(logvisor::Error, fmt(_SYS_STR("unable to open {}")), bootBinPath.getAbsolutePath()); return 1; } std::string id = r.readString(6); @@ -113,7 +113,7 @@ public: fileOut += _SYS_STR(".gcm"); if (nod::DiscBuilderGCN::CalculateTotalSizeRequired(outPath.getAbsolutePath()) == UINT64_MAX) return 1; - LogModule.report(logvisor::Info, _SYS_STR("Generating %s as GameCube image"), fileOut.c_str()); + LogModule.report(logvisor::Info, fmt(_SYS_STR("Generating {} as GameCube image")), fileOut); nod::DiscBuilderGCN db(fileOut, progFunc); if (db.buildFromDirectory(outPath.getAbsolutePath()) != nod::EBuildResult::Success) return 1; @@ -122,7 +122,7 @@ public: bool dualLayer; if (nod::DiscBuilderWii::CalculateTotalSizeRequired(outPath.getAbsolutePath(), dualLayer) == UINT64_MAX) return 1; - LogModule.report(logvisor::Info, _SYS_STR("Generating %s as %s-layer Wii image"), fileOut.c_str(), + LogModule.report(logvisor::Info, fmt(_SYS_STR("Generating {} as {}-layer Wii image")), fileOut, dualLayer ? _SYS_STR("dual") : _SYS_STR("single")); nod::DiscBuilderWii db(fileOut, dualLayer, progFunc); if (db.buildFromDirectory(outPath.getAbsolutePath()) != nod::EBuildResult::Success) diff --git a/hecl/driver/ToolInit.hpp b/hecl/driver/ToolInit.hpp index da6e1334e..27adc5ad8 100644 --- a/hecl/driver/ToolInit.hpp +++ b/hecl/driver/ToolInit.hpp @@ -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, _SYS_STR("unable to stat '%s'"), dir->c_str()); + LogModule.report(logvisor::Fatal, fmt(_SYS_STR("unable to stat '{}'")), *dir); return; } } if (!S_ISDIR(theStat.st_mode)) { - LogModule.report(logvisor::Fatal, _SYS_STR("'%s' is not a directory"), dir->c_str()); + LogModule.report(logvisor::Fatal, fmt(_SYS_STR("'{}' is not a directory")), *dir); return; } hecl::SystemString testPath = *dir + _SYS_STR("/.hecl/beacon"); if (!hecl::Stat(testPath.c_str(), &theStat)) { - LogModule.report(logvisor::Fatal, _SYS_STR("project already exists at '%s'"), dir->c_str()); + LogModule.report(logvisor::Fatal, fmt(_SYS_STR("project already exists at '{}'")), *dir); return; } @@ -43,7 +43,7 @@ public: hecl::Database::Project proj((hecl::ProjectRootPath(*m_dir))); if (logvisor::ErrorCount > ErrorRef) return 1; - LogModule.report(logvisor::Info, _SYS_STR("initialized project at '%s/.hecl'"), m_dir->c_str()); + LogModule.report(logvisor::Info, fmt(_SYS_STR("initialized project at '{}/.hecl'")), *m_dir); return 0; } diff --git a/hecl/driver/ToolPackage.hpp b/hecl/driver/ToolPackage.hpp index fb03595f6..495b75896 100644 --- a/hecl/driver/ToolPackage.hpp +++ b/hecl/driver/ToolPackage.hpp @@ -61,7 +61,7 @@ class ToolPackage final : public ToolBase { public: ToolPackage(const ToolPassInfo& info) : ToolBase(info), m_useProj(info.project) { if (!info.project) - LogModule.report(logvisor::Fatal, "hecl package must be ran within a project directory"); + LogModule.report(logvisor::Fatal, fmt("hecl package must be ran within a project directory")); /* Scan args */ if (info.args.size()) { @@ -82,7 +82,7 @@ public: } } if (!m_spec) - LogModule.report(logvisor::Fatal, "unable to find data spec '%s'", specName.c_str()); + LogModule.report(logvisor::Fatal, fmt("unable to find data spec '{}'"), specName); continue; } else if (arg.size() >= 2 && arg[0] == _SYS_STR('-') && arg[1] == _SYS_STR('-')) continue; @@ -96,10 +96,10 @@ public: m_useProj = m_fallbackProj.get(); } else if (m_fallbackProj->getProjectRootPath() != root) LogModule.report(logvisor::Fatal, - _SYS_STR("hecl package can only process multiple items in the same project; ") - _SYS_STR("'%s' and '%s' are different projects"), - m_fallbackProj->getProjectRootPath().getAbsolutePath().data(), - root.getAbsolutePath().data()); + fmt(_SYS_STR("hecl package can only process multiple items in the same project; ") + _SYS_STR("'{}' and '{}' are different projects")), + m_fallbackProj->getProjectRootPath().getAbsolutePath(), + root.getAbsolutePath()); FindSelectedItems({*m_useProj, subPath}, true); } @@ -107,8 +107,8 @@ public: } if (!m_useProj) LogModule.report(logvisor::Fatal, - "hecl package must be ran within a project directory or " - "provided a path within a project"); + fmt("hecl package must be ran within a project directory or " + "provided a path within a project")); /* Default case: recursive at root */ if (m_selectedItems.empty()) @@ -160,12 +160,12 @@ public: int run() { if (XTERM_COLOR) - hecl::Printf(_SYS_STR("" GREEN BOLD "ABOUT TO PACKAGE:" NORMAL "\n")); + fmt::print(fmt(_SYS_STR("" GREEN BOLD "ABOUT TO PACKAGE:" NORMAL "\n"))); else - hecl::Printf(_SYS_STR("ABOUT TO PACKAGE:\n")); + fmt::print(fmt(_SYS_STR("ABOUT TO PACKAGE:\n"))); for (auto& item : m_selectedItems) - hecl::Printf(_SYS_STR(" %s\n"), item.getRelativePath().data()); + fmt::print(fmt(_SYS_STR(" {}\n")), item.getRelativePath()); fflush(stdout); if (continuePrompt()) { @@ -173,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, _SYS_STR("Unable to package %s"), path.getAbsolutePath().data()); + LogModule.report(logvisor::Error, fmt(_SYS_STR("Unable to package {}")), path.getAbsolutePath()); } cp.waitUntilComplete(); } diff --git a/hecl/driver/ToolSpec.hpp b/hecl/driver/ToolSpec.hpp index a7f9bc4ad..09515bfde 100644 --- a/hecl/driver/ToolSpec.hpp +++ b/hecl/driver/ToolSpec.hpp @@ -13,7 +13,7 @@ public: return; if (!info.project) - LogModule.report(logvisor::Fatal, "hecl spec must be ran within a project directory"); + LogModule.report(logvisor::Fatal, fmt("hecl spec must be ran within a project directory")); const auto& specs = info.project->getDataSpecs(); hecl::SystemString firstArg = info.args.front(); @@ -27,7 +27,7 @@ public: return; if (info.args.size() < 2) - LogModule.report(logvisor::Fatal, "Speclist argument required"); + LogModule.report(logvisor::Fatal, fmt("Speclist argument required")); auto it = info.args.begin(); ++it; @@ -41,7 +41,7 @@ public: } } if (!found) - LogModule.report(logvisor::Fatal, _SYS_STR("'%s' is not found in the dataspec registry"), it->c_str()); + LogModule.report(logvisor::Fatal, fmt(_SYS_STR("'{}' is not found in the dataspec registry")), *it); } } @@ -77,10 +77,10 @@ public: if (!m_info.project) { for (const hecl::Database::DataSpecEntry* spec : hecl::Database::DATA_SPEC_REGISTRY) { if (XTERM_COLOR) - hecl::Printf(_SYS_STR("" BOLD CYAN "%s" NORMAL "\n"), spec->m_name.data()); + fmt::print(fmt(_SYS_STR("" BOLD CYAN "{}" NORMAL "\n")), spec->m_name); else - hecl::Printf(_SYS_STR("%s\n"), spec->m_name.data()); - hecl::Printf(_SYS_STR(" %s\n"), spec->m_desc.data()); + fmt::print(fmt(_SYS_STR("{}\n")), spec->m_name); + fmt::print(fmt(_SYS_STR(" {}\n")), spec->m_desc); } return 0; } @@ -89,16 +89,16 @@ public: if (mode == MLIST) { for (auto& spec : specs) { if (XTERM_COLOR) - hecl::Printf(_SYS_STR("" BOLD CYAN "%s" NORMAL ""), spec.spec.m_name.data()); + fmt::print(fmt(_SYS_STR("" BOLD CYAN "{}" NORMAL "")), spec.spec.m_name); else - hecl::Printf(_SYS_STR("%s"), spec.spec.m_name.data()); + fmt::print(fmt(_SYS_STR("{}")), spec.spec.m_name); if (spec.active) { if (XTERM_COLOR) - hecl::Printf(_SYS_STR(" " BOLD GREEN "[ENABLED]" NORMAL "")); + fmt::print(fmt(_SYS_STR(" " BOLD GREEN "[ENABLED]" NORMAL ""))); else - hecl::Printf(_SYS_STR(" [ENABLED]")); + fmt::print(fmt(_SYS_STR(" [ENABLED]"))); } - hecl::Printf(_SYS_STR("\n %s\n"), spec.spec.m_desc.data()); + fmt::print(fmt(_SYS_STR("\n {}\n")), spec.spec.m_desc); } return 0; } diff --git a/hecl/driver/main.cpp b/hecl/driver/main.cpp index 430394aeb..b53509e55 100644 --- a/hecl/driver/main.cpp +++ b/hecl/driver/main.cpp @@ -45,20 +45,20 @@ bool XTERM_COLOR = false; /* Main usage message */ static void printHelp(const hecl::SystemChar* pname) { if (XTERM_COLOR) - hecl::Printf(_SYS_STR("" BOLD "HECL" NORMAL "")); + fmt::print(fmt(_SYS_STR("" BOLD "HECL" NORMAL ""))); else - hecl::Printf(_SYS_STR("HECL")); + fmt::print(fmt(_SYS_STR("HECL"))); #if HECL_HAS_NOD #define TOOL_LIST "extract|init|cook|package|image|help" #else #define TOOL_LIST "extract|init|cook|package|help" #endif #if HECL_GIT - hecl::Printf(_SYS_STR(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: %s " TOOL_LIST "\n"), pname); + fmt::print(fmt(_SYS_STR(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: {} " TOOL_LIST "\n")), pname); #elif HECL_VER - hecl::Printf(_SYS_STR(" Version " HECL_VER_S "\nUsage: %s " TOOL_LIST "\n"), pname); + fmt::print(fmt(_SYS_STR(" Version " HECL_VER_S "\nUsage: {} " TOOL_LIST "\n")), pname); #else - hecl::Printf(_SYS_STR("\nUsage: %s " TOOL_LIST "\n"), pname); + fmt::print(fmt(_SYS_STR("\nUsage: {} " TOOL_LIST "\n")), pname); #endif } @@ -77,11 +77,9 @@ static void SIGINTHandler(int sig) { } static logvisor::Module AthenaLog("Athena"); -static void AthenaExc(athena::error::Level level, const char* file, const char*, int line, const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - AthenaLog.report(logvisor::Level(level), fmt, ap); - va_end(ap); +static void AthenaExc(athena::error::Level level, const char* file, const char*, int line, + fmt::string_view fmt, fmt::format_args args) { + AthenaLog.vreport(logvisor::Level(level), fmt, args); } static hecl::SystemChar cwdbuf[1024]; @@ -96,7 +94,7 @@ int main(int argc, const char** argv) #endif { if (argc > 1 && !hecl::StrCmp(argv[1], _SYS_STR("--dlpackage"))) { - printf("%s\n", HECL_DLPACKAGE); + fmt::print(fmt("{}\n"), HECL_DLPACKAGE); return 100; } @@ -278,7 +276,7 @@ int main(int argc, const char** argv) else { FILE* fp = hecl::Fopen(argv[1], _SYS_STR("rb")); if (!fp) - LogModule.report(logvisor::Error, _SYS_STR("unrecognized tool '%s'"), toolName.c_str()); + LogModule.report(logvisor::Error, fmt(_SYS_STR("unrecognized tool '{}'")), toolName); else { /* Shortcut-case: implicit extract */ fclose(fp); @@ -295,8 +293,7 @@ int main(int argc, const char** argv) } if (info.verbosityLevel) - LogModule.report(logvisor::Info, _SYS_STR("Constructed tool '%s' %d\n"), tool->toolName().c_str(), - info.verbosityLevel); + LogModule.report(logvisor::Info, fmt(_SYS_STR("Constructed tool '{}' {}\n")), tool->toolName(), info.verbosityLevel); /* Run tool */ ErrorRef = logvisor::ErrorCount; diff --git a/hecl/extern/athena b/hecl/extern/athena index f3852eb0d..478d75f1c 160000 --- a/hecl/extern/athena +++ b/hecl/extern/athena @@ -1 +1 @@ -Subproject commit f3852eb0d2643a9b1d1358c3a89c0002b2cadb90 +Subproject commit 478d75f1cb6ff25fbbd0d22357b6de395c3ab662 diff --git a/hecl/extern/boo b/hecl/extern/boo index b2bf7549f..deefc8e99 160000 --- a/hecl/extern/boo +++ b/hecl/extern/boo @@ -1 +1 @@ -Subproject commit b2bf7549f510ce12ee7b834e0a5c3562846d6303 +Subproject commit deefc8e99520ffacd0d70c27a6beeb1047a0c131 diff --git a/hecl/include/hecl/Blender/Connection.hpp b/hecl/include/hecl/Blender/Connection.hpp index 40e5a736b..147508177 100644 --- a/hecl/include/hecl/Blender/Connection.hpp +++ b/hecl/include/hecl/Blender/Connection.hpp @@ -30,6 +30,7 @@ #include "athena/MemoryWriter.hpp" #include #include "Token.hpp" +#include namespace hecl::blender { using namespace std::literals; @@ -86,11 +87,8 @@ public: } ~PyOutStream() { close(); } void close(); -#if __GNUC__ - __attribute__((__format__(__printf__, 2, 3))) -#endif - void - format(const char* fmt, ...); + template > + void format(const S& format, Args&&... args); void linkBlend(const char* target, const char* objName, bool link = true); void linkBackground(const char* target, const char* sceneName = nullptr); void AABBToBMesh(const atVec3f& min, const atVec3f& max); @@ -713,6 +711,7 @@ class Connection { uint32_t _writeStr(const char* str, uint32_t len, int wpipe); uint32_t _writeStr(const char* str, uint32_t len) { return _writeStr(str, len, m_writepipe[1]); } uint32_t _writeStr(const char* str) { return _writeStr(str, strlen(str)); } + uint32_t _writeStr(const std::string& str) { return _writeStr(str.c_str(), str.size()); } size_t _readBuf(void* buf, size_t len); size_t _writeBuf(const void* buf, size_t len); void _closePipe(); @@ -738,14 +737,14 @@ public: PyOutStream beginPythonOut(bool deleteOnError = false) { bool expect = false; if (!m_lock.compare_exchange_strong(expect, true)) - BlenderLog.report(logvisor::Fatal, "lock already held for blender::Connection::beginPythonOut()"); + BlenderLog.report(logvisor::Fatal, fmt("lock already held for blender::Connection::beginPythonOut()")); return PyOutStream(this, deleteOnError); } DataStream beginData() { bool expect = false; if (!m_lock.compare_exchange_strong(expect, true)) - BlenderLog.report(logvisor::Fatal, "lock already held for blender::Connection::beginDataIn()"); + BlenderLog.report(logvisor::Fatal, fmt("lock already held for blender::Connection::beginDataIn()")); return DataStream(this); } @@ -760,6 +759,14 @@ public: static void Shutdown(); }; +template +void PyOutStream::format(const S& format, Args&&... args) +{ + if (!m_parent || !m_parent->m_lock) + BlenderLog.report(logvisor::Fatal, fmt("lock not held for PyOutStream::format()")); + fmt::print(*this, format, std::forward(args)...); +} + class HMDLBuffers { public: struct Surface; diff --git a/hecl/include/hecl/Compilers.hpp b/hecl/include/hecl/Compilers.hpp index 8e29592d3..6c214559e 100644 --- a/hecl/include/hecl/Compilers.hpp +++ b/hecl/include/hecl/Compilers.hpp @@ -77,12 +77,12 @@ struct Evaluation { #ifdef _LIBCPP_VERSION using StageBinaryData = std::shared_ptr; -static inline StageBinaryData MakeStageBinaryData(size_t sz) { +inline StageBinaryData MakeStageBinaryData(size_t sz) { return StageBinaryData(new uint8_t[sz], std::default_delete{}); } #else using StageBinaryData = std::shared_ptr; -static inline StageBinaryData MakeStageBinaryData(size_t sz) { return StageBinaryData(new uint8_t[sz]); } +inline StageBinaryData MakeStageBinaryData(size_t sz) { return StageBinaryData(new uint8_t[sz]); } #endif template diff --git a/hecl/include/hecl/Console.hpp b/hecl/include/hecl/Console.hpp index c914ffde0..bc54547f3 100644 --- a/hecl/include/hecl/Console.hpp +++ b/hecl/include/hecl/Console.hpp @@ -26,13 +26,13 @@ class Console { Console* m_con; LogVisorAdapter(Console* con) : m_con(con) {} - ~LogVisorAdapter() {} - void report(const char* modName, logvisor::Level severity, const char* format, va_list ap); - void report(const char* modName, logvisor::Level severity, const wchar_t* format, va_list ap); + ~LogVisorAdapter() = default; + void report(const char* modName, logvisor::Level severity, fmt::string_view format, fmt::format_args args); + void report(const char* modName, logvisor::Level severity, fmt::wstring_view format, fmt::wformat_args args); void reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, - const char* format, va_list ap); + fmt::string_view format, fmt::format_args args); void reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, - const wchar_t* format, va_list ap); + fmt::wstring_view format, fmt::wformat_args args); }; public: @@ -80,8 +80,13 @@ public: void listCommands(Console* con, const std::vector& args); bool commandExists(std::string_view cmd); - void report(Level level, const char* fmt, va_list list); - void report(Level level, const char* fmt, ...); + void vreport(Level level, fmt::string_view format, fmt::format_args args); + template > + void report(Level level, const S& format, Args&&... args) { + vreport(level, fmt::to_string_view(format), + fmt::basic_format_args>( + fmt::internal::make_args_checked(format, args...))); + } void init(boo::IWindow* ctx); void proc(); diff --git a/hecl/include/hecl/Database.hpp b/hecl/include/hecl/Database.hpp index a4a3793ce..f4de2c5e1 100644 --- a/hecl/include/hecl/Database.hpp +++ b/hecl/include/hecl/Database.hpp @@ -94,7 +94,7 @@ public: virtual bool canExtract(const ExtractPassInfo& info, std::vector& reps) { (void)info; (void)reps; - LogModule.report(logvisor::Error, "not implemented"); + LogModule.report(logvisor::Error, fmt("not implemented")); return false; } virtual void doExtract(const ExtractPassInfo& info, const MultiProgressPrinter& progress) { @@ -104,7 +104,7 @@ public: virtual bool canCook(const ProjectPath& path, blender::Token& btok) { (void)path; - LogModule.report(logvisor::Error, "not implemented"); + LogModule.report(logvisor::Error, fmt("not implemented")); return false; } virtual const DataSpecEntry* overrideDataSpec(const ProjectPath& path, diff --git a/hecl/include/hecl/FourCC.hpp b/hecl/include/hecl/FourCC.hpp index 06781540b..a407425f5 100644 --- a/hecl/include/hecl/FourCC.hpp +++ b/hecl/include/hecl/FourCC.hpp @@ -37,9 +37,9 @@ public: bool operator!=(uint32_t other) const { return num != other; } std::string toString() const { return std::string(fcc, 4); } uint32_t toUint32() const { return num; } - operator uint32_t() const { return num; } const char* getChars() const { return fcc; } char* getChars() { return fcc; } + bool IsValid() const { return num != 0; } }; #define FOURCC(chars) FourCC(SBIG(chars)) @@ -84,3 +84,6 @@ struct hash { size_t operator()(const hecl::FourCC& val) const noexcept { return val.toUint32(); } }; } // namespace std + +FMT_CUSTOM_FORMATTER(hecl::FourCC, fmt("{:.4s}"), obj.getChars()) +FMT_CUSTOM_FORMATTER(hecl::DNAFourCC, fmt("{:.4s}"), obj.getChars()) diff --git a/hecl/include/hecl/SystemChar.hpp b/hecl/include/hecl/SystemChar.hpp index 8fe2a7ebf..373ae0c76 100644 --- a/hecl/include/hecl/SystemChar.hpp +++ b/hecl/include/hecl/SystemChar.hpp @@ -34,9 +34,6 @@ static inline void ToUpper(SystemString& str) { std::transform(str.begin(), str. #ifndef _SYS_STR #define _SYS_STR(val) L##val #endif -#ifndef FMT_CSTR_SYS -#define FMT_CSTR_SYS "S" -#endif typedef struct _stat Sstat; #else typedef char SystemChar; @@ -48,9 +45,6 @@ static inline void ToUpper(SystemString& str) { std::transform(str.begin(), str. #ifndef _SYS_STR #define _SYS_STR(val) val #endif -#ifndef FMT_CSTR_SYS -#define FMT_CSTR_SYS "s" -#endif typedef struct stat Sstat; #endif diff --git a/hecl/include/hecl/hecl.hpp b/hecl/include/hecl/hecl.hpp index 7ee2ff32d..6d41c84fb 100644 --- a/hecl/include/hecl/hecl.hpp +++ b/hecl/include/hecl/hecl.hpp @@ -154,7 +154,7 @@ inline std::string operator+(std::string_view lhs, const SystemStringConv& rhs) void SanitizePath(std::string& path); void SanitizePath(std::wstring& path); -static inline void Unlink(const SystemChar* file) { +inline void Unlink(const SystemChar* file) { #if _WIN32 _wunlink(file); #else @@ -162,31 +162,31 @@ static inline void Unlink(const SystemChar* file) { #endif } -static inline void MakeDir(const char* dir) { +inline void MakeDir(const char* dir) { #if _WIN32 HRESULT err; if (!CreateDirectoryA(dir, NULL)) if ((err = GetLastError()) != ERROR_ALREADY_EXISTS) - LogModule.report(logvisor::Fatal, "MakeDir(%s)", dir); + LogModule.report(logvisor::Fatal, fmt("MakeDir(%s)"), dir); #else if (mkdir(dir, 0755)) if (errno != EEXIST) - LogModule.report(logvisor::Fatal, "MakeDir(%s): %s", dir, strerror(errno)); + LogModule.report(logvisor::Fatal, fmt("MakeDir({}): {}"), dir, strerror(errno)); #endif } #if _WIN32 -static inline void MakeDir(const wchar_t* dir) { +inline void MakeDir(const wchar_t* dir) { HRESULT err; if (!CreateDirectoryW(dir, NULL)) if ((err = GetLastError()) != ERROR_ALREADY_EXISTS) - LogModule.report(logvisor::Fatal, _SYS_STR("MakeDir(%s)"), dir); + LogModule.report(logvisor::Fatal, fmt(_SYS_STR("MakeDir(%s)")), dir); } #endif int RecursiveMakeDir(const SystemChar* dir); -static inline const SystemChar* GetEnv(const SystemChar* name) { +inline const SystemChar* GetEnv(const SystemChar* name) { #if WINDOWS_STORE return nullptr; #else @@ -198,7 +198,7 @@ static inline const SystemChar* GetEnv(const SystemChar* name) { #endif } -static inline SystemChar* Getcwd(SystemChar* buf, int maxlen) { +inline SystemChar* Getcwd(SystemChar* buf, int maxlen) { #if HECL_UCS2 return _wgetcwd(buf, maxlen); #else @@ -208,7 +208,7 @@ static inline SystemChar* Getcwd(SystemChar* buf, int maxlen) { SystemString GetcwdStr(); -static inline bool IsAbsolute(SystemStringView path) { +inline bool IsAbsolute(SystemStringView path) { #if _WIN32 if (path.size() && (path[0] == _SYS_STR('\\') || path[0] == _SYS_STR('/'))) return true; @@ -228,7 +228,7 @@ int RunProcess(const SystemChar* path, const SystemChar* const args[]); #endif enum class FileLockType { None = 0, Read, Write }; -static inline FILE* Fopen(const SystemChar* path, const SystemChar* mode, FileLockType lock = FileLockType::None) { +inline FILE* Fopen(const SystemChar* path, const SystemChar* mode, FileLockType lock = FileLockType::None) { #if HECL_UCS2 FILE* fp = _wfopen(path, mode); if (!fp) @@ -246,14 +246,14 @@ static inline FILE* Fopen(const SystemChar* path, const SystemChar* mode, FileLo &ov); #else if (flock(fileno(fp), ((lock == FileLockType::Write) ? LOCK_EX : LOCK_SH) | LOCK_NB)) - LogModule.report(logvisor::Error, "flock %s: %s", path, strerror(errno)); + LogModule.report(logvisor::Error, fmt("flock {}: {}"), path, strerror(errno)); #endif } return fp; } -static inline int FSeek(FILE* fp, int64_t offset, int whence) { +inline int FSeek(FILE* fp, int64_t offset, int whence) { #if _WIN32 return _fseeki64(fp, offset, whence); #elif __APPLE__ || __FreeBSD__ @@ -263,7 +263,7 @@ static inline int FSeek(FILE* fp, int64_t offset, int whence) { #endif } -static inline int64_t FTell(FILE* fp) { +inline int64_t FTell(FILE* fp) { #if _WIN32 return _ftelli64(fp); #elif __APPLE__ || __FreeBSD__ @@ -273,7 +273,7 @@ static inline int64_t FTell(FILE* fp) { #endif } -static inline int Rename(const SystemChar* oldpath, const SystemChar* newpath) { +inline int Rename(const SystemChar* oldpath, const SystemChar* newpath) { #if HECL_UCS2 // return _wrename(oldpath, newpath); return MoveFileExW(oldpath, newpath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == 0; @@ -282,7 +282,7 @@ static inline int Rename(const SystemChar* oldpath, const SystemChar* newpath) { #endif } -static inline int Stat(const SystemChar* path, Sstat* statOut) { +inline int Stat(const SystemChar* path, Sstat* statOut) { #if HECL_UCS2 size_t pos; for (pos = 0; pos < 3 && path[pos] != L'\0'; ++pos) {} @@ -296,52 +296,7 @@ static inline int Stat(const SystemChar* path, Sstat* statOut) { #endif } -#if __GNUC__ -__attribute__((__format__(__printf__, 1, 2))) -#endif -static inline void -Printf(const SystemChar* format, ...) { - va_list va; - va_start(va, format); -#if HECL_UCS2 - vwprintf(format, va); -#else - vprintf(format, va); -#endif - va_end(va); -} - -#if __GNUC__ -__attribute__((__format__(__printf__, 2, 3))) -#endif -static inline void -FPrintf(FILE* fp, const SystemChar* format, ...) { - va_list va; - va_start(va, format); -#if HECL_UCS2 - vfwprintf(fp, format, va); -#else - vfprintf(fp, format, va); -#endif - va_end(va); -} - -#if __GNUC__ -__attribute__((__format__(__printf__, 3, 4))) -#endif -static inline void -SNPrintf(SystemChar* str, size_t maxlen, const SystemChar* format, ...) { - va_list va; - va_start(va, format); -#if HECL_UCS2 - _vsnwprintf(str, maxlen, format, va); -#else - vsnprintf(str, maxlen, format, va); -#endif - va_end(va); -} - -static inline int StrCmp(const SystemChar* str1, const SystemChar* str2) { +inline int StrCmp(const SystemChar* str1, const SystemChar* str2) { if (!str1 || !str2) return str1 != str2; #if HECL_UCS2 @@ -351,7 +306,7 @@ static inline int StrCmp(const SystemChar* str1, const SystemChar* str2) { #endif } -static inline int StrNCmp(const SystemChar* str1, const SystemChar* str2, size_t count) { +inline int StrNCmp(const SystemChar* str1, const SystemChar* str2, size_t count) { if (!str1 || !str2) return str1 != str2; #if HECL_UCS2 @@ -361,7 +316,7 @@ static inline int StrNCmp(const SystemChar* str1, const SystemChar* str2, size_t #endif } -static inline int StrCaseCmp(const SystemChar* str1, const SystemChar* str2) { +inline int StrCaseCmp(const SystemChar* str1, const SystemChar* str2) { if (!str1 || !str2) return str1 != str2; #if HECL_UCS2 @@ -371,7 +326,7 @@ static inline int StrCaseCmp(const SystemChar* str1, const SystemChar* str2) { #endif } -static inline unsigned long StrToUl(const SystemChar* str, SystemChar** endPtr, int base) { +inline unsigned long StrToUl(const SystemChar* str, SystemChar** endPtr, int base) { #if HECL_UCS2 return wcstoul(str, endPtr, base); #else @@ -379,46 +334,28 @@ static inline unsigned long StrToUl(const SystemChar* str, SystemChar** endPtr, #endif } -#define FORMAT_BUF_SZ 1024 - -#if __GNUC__ -__attribute__((__format__(__printf__, 1, 2))) -#endif -SystemString -SysFormat(const SystemChar* format, ...); - -#if __GNUC__ -__attribute__((__format__(__printf__, 1, 2))) -#endif -std::string -Format(const char* format, ...); - -std::wstring WideFormat(const wchar_t* format, ...); - -std::u16string Char16Format(const wchar_t* format, ...); - -static inline bool CheckFreeSpace(const SystemChar* path, size_t reqSz) { +inline bool CheckFreeSpace(const SystemChar* path, size_t reqSz) { #if _WIN32 ULARGE_INTEGER freeBytes; wchar_t buf[1024]; wchar_t* end; DWORD ret = GetFullPathNameW(path, 1024, buf, &end); if (!ret || ret > 1024) - LogModule.report(logvisor::Fatal, _SYS_STR("GetFullPathNameW %s"), path); + LogModule.report(logvisor::Fatal, fmt(_SYS_STR("GetFullPathNameW %s")), path); if (end) end[0] = L'\0'; if (!GetDiskFreeSpaceExW(buf, &freeBytes, nullptr, nullptr)) - LogModule.report(logvisor::Fatal, _SYS_STR("GetDiskFreeSpaceExW %s: %d"), path, GetLastError()); + LogModule.report(logvisor::Fatal, fmt(_SYS_STR("GetDiskFreeSpaceExW %s: %d")), path, GetLastError()); return reqSz < freeBytes.QuadPart; #else struct statvfs svfs; if (statvfs(path, &svfs)) - LogModule.report(logvisor::Fatal, "statvfs %s: %s", path, strerror(errno)); + LogModule.report(logvisor::Fatal, fmt("statvfs {}: {}"), path, strerror(errno)); return reqSz < svfs.f_frsize * svfs.f_bavail; #endif } -static inline bool PathRelative(const SystemChar* path) { +inline bool PathRelative(const SystemChar* path) { if (!path || !path[0]) return false; #if _WIN32 && !WINDOWS_STORE @@ -428,7 +365,7 @@ static inline bool PathRelative(const SystemChar* path) { #endif } -static inline int ConsoleWidth(bool* ok = nullptr) { +inline int ConsoleWidth(bool* ok = nullptr) { int retval = 80; #if _WIN32 #if !WINDOWS_STORE @@ -640,8 +577,7 @@ public: return SystemString(beginIt, absPathForward.cend()); } } - LogModule.report(logvisor::Fatal, "unable to resolve '%s' as project relative '%s'", absPath.data(), - m_projRoot.c_str()); + LogModule.report(logvisor::Fatal, fmt("unable to resolve '{}' as project relative '{}'"), absPath, m_projRoot); return SystemString(); } @@ -813,7 +749,7 @@ public: */ ProjectPath getParentPath() const { if (m_relPath == _SYS_STR(".")) - LogModule.report(logvisor::Fatal, "attempted to resolve parent of root project path"); + LogModule.report(logvisor::Fatal, fmt("attempted to resolve parent of root project path")); size_t pos = m_relPath.rfind(_SYS_STR('/')); if (pos == SystemString::npos) return ProjectPath(*m_proj, _SYS_STR("")); @@ -1082,7 +1018,7 @@ public: */ Database::Project& getProject() const { if (!m_proj) - LogModule.report(logvisor::Fatal, "ProjectPath::getProject() called on unqualified path"); + LogModule.report(logvisor::Fatal, fmt("ProjectPath::getProject() called on unqualified path")); return *m_proj; } @@ -1214,7 +1150,7 @@ bool IsPathYAML(const hecl::ProjectPath& path); /* Type-sensitive byte swappers */ template -static inline T bswap16(T val) { +constexpr T bswap16(T val) { #if __GNUC__ return __builtin_bswap16(val); #elif _WIN32 @@ -1225,7 +1161,7 @@ static inline T bswap16(T val) { } template -static inline T bswap32(T val) { +constexpr T bswap32(T val) { #if __GNUC__ return __builtin_bswap32(val); #elif _WIN32 @@ -1238,7 +1174,7 @@ static inline T bswap32(T val) { } template -static inline T bswap64(T val) { +constexpr T bswap64(T val) { #if __GNUC__ return __builtin_bswap64(val); #elif _WIN32 @@ -1252,18 +1188,18 @@ static inline T bswap64(T val) { } #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -static inline int16_t SBig(int16_t val) { return bswap16(val); } -static inline uint16_t SBig(uint16_t val) { return bswap16(val); } -static inline int32_t SBig(int32_t val) { return bswap32(val); } -static inline uint32_t SBig(uint32_t val) { return bswap32(val); } -static inline int64_t SBig(int64_t val) { return bswap64(val); } -static inline uint64_t SBig(uint64_t val) { return bswap64(val); } -inline float SBig(float val) { +constexpr int16_t SBig(int16_t val) { return bswap16(val); } +constexpr uint16_t SBig(uint16_t val) { return bswap16(val); } +constexpr int32_t SBig(int32_t val) { return bswap32(val); } +constexpr uint32_t SBig(uint32_t val) { return bswap32(val); } +constexpr int64_t SBig(int64_t val) { return bswap64(val); } +constexpr uint64_t SBig(uint64_t val) { return bswap64(val); } +constexpr float SBig(float val) { union { float f; atInt32 i; } uval1 = {val}; union { atInt32 i; float f; } uval2 = {bswap32(uval1.i)}; return uval2.f; } -inline double SBig(double val) { +constexpr double SBig(double val) { union { double f; atInt64 i; } uval1 = {val}; union { atInt64 i; double f; } uval2 = {bswap64(uval1.i)}; return uval2.f; @@ -1272,29 +1208,29 @@ inline double SBig(double val) { #define SBIG(q) (((q)&0x000000FF) << 24 | ((q)&0x0000FF00) << 8 | ((q)&0x00FF0000) >> 8 | ((q)&0xFF000000) >> 24) #endif -static inline int16_t SLittle(int16_t val) { return val; } -static inline uint16_t SLittle(uint16_t val) { return val; } -static inline int32_t SLittle(int32_t val) { return val; } -static inline uint32_t SLittle(uint32_t val) { return val; } -static inline int64_t SLittle(int64_t val) { return val; } -static inline uint64_t SLittle(uint64_t val) { return val; } -static inline float SLittle(float val) { return val; } -static inline double SLittle(double val) { return val; } +constexpr int16_t SLittle(int16_t val) { return val; } +constexpr uint16_t SLittle(uint16_t val) { return val; } +constexpr int32_t SLittle(int32_t val) { return val; } +constexpr uint32_t SLittle(uint32_t val) { return val; } +constexpr int64_t SLittle(int64_t val) { return val; } +constexpr uint64_t SLittle(uint64_t val) { return val; } +constexpr float SLittle(float val) { return val; } +constexpr double SLittle(double val) { return val; } #ifndef SLITTLE #define SLITTLE(q) (q) #endif #else -static inline int16_t SLittle(int16_t val) { return bswap16(val); } -static inline uint16_t SLittle(uint16_t val) { return bswap16(val); } -static inline int32_t SLittle(int32_t val) { return bswap32(val); } -static inline uint32_t SLittle(uint32_t val) { return bswap32(val); } -static inline int64_t SLittle(int64_t val) { return bswap64(val); } -static inline uint64_t SLittle(uint64_t val) { return bswap64(val); } -static inline float SLittle(float val) { +constexpr int16_t SLittle(int16_t val) { return bswap16(val); } +constexpr uint16_t SLittle(uint16_t val) { return bswap16(val); } +constexpr int32_t SLittle(int32_t val) { return bswap32(val); } +constexpr uint32_t SLittle(uint32_t val) { return bswap32(val); } +constexpr int64_t SLittle(int64_t val) { return bswap64(val); } +constexpr uint64_t SLittle(uint64_t val) { return bswap64(val); } +constexpr float SLittle(float val) { int32_t ival = bswap32(*((int32_t*)(&val))); return *((float*)(&ival)); } -static inline double SLittle(double val) { +constexpr double SLittle(double val) { int64_t ival = bswap64(*((int64_t*)(&val))); return *((double*)(&ival)); } @@ -1302,14 +1238,14 @@ static inline double SLittle(double val) { #define SLITTLE(q) (((q)&0x000000FF) << 24 | ((q)&0x0000FF00) << 8 | ((q)&0x00FF0000) >> 8 | ((q)&0xFF000000) >> 24) #endif -static inline int16_t SBig(int16_t val) { return val; } -static inline uint16_t SBig(uint16_t val) { return val; } -static inline int32_t SBig(int32_t val) { return val; } -static inline uint32_t SBig(uint32_t val) { return val; } -static inline int64_t SBig(int64_t val) { return val; } -static inline uint64_t SBig(uint64_t val) { return val; } -static inline float SBig(float val) { return val; } -static inline double SBig(double val) { return val; } +constexpr int16_t SBig(int16_t val) { return val; } +constexpr uint16_t SBig(uint16_t val) { return val; } +constexpr int32_t SBig(int32_t val) { return val; } +constexpr uint32_t SBig(uint32_t val) { return val; } +constexpr int64_t SBig(int64_t val) { return val; } +constexpr uint64_t SBig(uint64_t val) { return val; } +constexpr float SBig(float val) { return val; } +constexpr double SBig(double val) { return val; } #ifndef SBIG #define SBIG(q) (q) #endif @@ -1332,3 +1268,6 @@ struct hash { size_t operator()(const hecl::Hash& val) const noexcept { return val.valSizeT(); } }; } // namespace std + +FMT_CUSTOM_FORMATTER(hecl::SystemUTF8Conv, fmt("{}"), obj.str()) +FMT_CUSTOM_FORMATTER(hecl::SystemStringConv, fmt("{}"), obj.sys_str()) \ No newline at end of file diff --git a/hecl/include/hecl/winsupport.hpp b/hecl/include/hecl/winsupport.hpp index 8feecc78b..851d727ed 100644 --- a/hecl/include/hecl/winsupport.hpp +++ b/hecl/include/hecl/winsupport.hpp @@ -34,15 +34,3 @@ inline void* memmem(const void* haystack, size_t hlen, const void* needle, size_ return NULL; } #endif - -inline int asprintf(char** buf, const char* format, ...) { - va_list ap; - va_start(ap, format); - int len = vsnprintf(nullptr, 0, format, ap); - va_end(ap); - *buf = (char*)malloc(len + 1); - va_start(ap, format); - vsnprintf(*buf, len + 1, format, ap); - va_end(ap); - return len; -} diff --git a/hecl/lib/Blender/Connection.cpp b/hecl/lib/Blender/Connection.cpp index d1532ac69..897e85c1e 100644 --- a/hecl/lib/Blender/Connection.cpp +++ b/hecl/lib/Blender/Connection.cpp @@ -62,7 +62,7 @@ extern "C" size_t HECL_STARTUP_SZ; static void InstallBlendershell(const SystemChar* path) { FILE* fp = hecl::Fopen(path, _SYS_STR("w")); if (!fp) - BlenderLog.report(logvisor::Fatal, _SYS_STR("unable to open %s for writing"), path); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("unable to open {} for writing")), path); fwrite(HECL_BLENDERSHELL, 1, HECL_BLENDERSHELL_SZ, fp); fclose(fp); } @@ -70,7 +70,7 @@ static void InstallBlendershell(const SystemChar* path) { static void InstallAddon(const SystemChar* path) { FILE* fp = hecl::Fopen(path, _SYS_STR("wb")); if (!fp) - BlenderLog.report(logvisor::Fatal, _SYS_STR("Unable to install blender addon at '%s'"), path); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("Unable to install blender addon at '{}'")), path); fwrite(HECL_ADDON, 1, HECL_ADDON_SZ, fp); fclose(fp); } @@ -109,20 +109,20 @@ uint32_t Connection::_readStr(char* buf, uint32_t bufSz) { uint32_t readLen; int ret = Read(m_readpipe[0], &readLen, 4); if (ret < 4) { - BlenderLog.report(logvisor::Error, "Pipe error %d %s", ret, strerror(errno)); + BlenderLog.report(logvisor::Error, fmt("Pipe error {} {}"), ret, strerror(errno)); _blenderDied(); return 0; } if (readLen >= bufSz) { - BlenderLog.report(logvisor::Fatal, "Pipe buffer overrun [%d/%d]", readLen, bufSz); + BlenderLog.report(logvisor::Fatal, fmt("Pipe buffer overrun [{}/{}]"), readLen, bufSz); *buf = '\0'; return 0; } ret = Read(m_readpipe[0], buf, readLen); if (ret < 0) { - BlenderLog.report(logvisor::Fatal, strerror(errno)); + BlenderLog.report(logvisor::Fatal, fmt("{}"), strerror(errno)); return 0; } else if (readLen >= 9) { if (!memcmp(buf, "EXCEPTION", std::min(readLen, uint32_t(9)))) { @@ -209,10 +209,10 @@ void Connection::_blenderDied() { std::unique_ptr buf(new char[len + 1]); memset(buf.get(), 0, len + 1); fread(buf.get(), 1, len, errFp); - BlenderLog.report(logvisor::Fatal, "\n%.*s", int(len), buf.get()); + BlenderLog.report(logvisor::Fatal, fmt("\n{:.{}s}"), buf.get(), len); } } - BlenderLog.report(logvisor::Fatal, "Blender Exception"); + BlenderLog.report(logvisor::Fatal, fmt("Blender Exception")); } static std::atomic_bool BlenderFirstInit(false); @@ -229,7 +229,7 @@ static bool RegFileExists(const hecl::SystemChar* path) { Connection::Connection(int verbosityLevel) { #if !WINDOWS_STORE if (hecl::VerbosityLevel >= 1) - BlenderLog.report(logvisor::Info, "Establishing BlenderConnection..."); + BlenderLog.report(logvisor::Info, fmt("Establishing BlenderConnection...")); /* Put hecl_blendershell.py in temp dir */ const SystemChar* TMPDIR = GetTmpDir(); @@ -263,20 +263,20 @@ Connection::Connection(int verbosityLevel) { SECURITY_ATTRIBUTES sattrs = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; HANDLE consoleOutReadTmp, consoleOutWrite, consoleErrWrite, consoleOutRead; if (!CreatePipe(&consoleOutReadTmp, &consoleOutWrite, &sattrs, 1024)) - BlenderLog.report(logvisor::Fatal, "Error with CreatePipe"); + BlenderLog.report(logvisor::Fatal, fmt("Error with CreatePipe")); if (!DuplicateHandle(GetCurrentProcess(), consoleOutWrite, GetCurrentProcess(), &consoleErrWrite, 0, TRUE, DUPLICATE_SAME_ACCESS)) - BlenderLog.report(logvisor::Fatal, "Error with DuplicateHandle"); + BlenderLog.report(logvisor::Fatal, fmt("Error with DuplicateHandle")); if (!DuplicateHandle(GetCurrentProcess(), consoleOutReadTmp, GetCurrentProcess(), &consoleOutRead, // Address of new handle. 0, FALSE, // Make it uninheritable. DUPLICATE_SAME_ACCESS)) - BlenderLog.report(logvisor::Fatal, "Error with DupliateHandle"); + BlenderLog.report(logvisor::Fatal, fmt("Error with DupliateHandle")); if (!CloseHandle(consoleOutReadTmp)) - BlenderLog.report(logvisor::Fatal, "Error with CloseHandle"); + BlenderLog.report(logvisor::Fatal, fmt("Error with CloseHandle")); #else pipe(m_readpipe); pipe(m_writepipe); @@ -359,13 +359,13 @@ Connection::Connection(int verbosityLevel) { if (err == ERROR_BROKEN_PIPE) break; // pipe done - normal exit path. else - BlenderLog.report(logvisor::Error, "Error with ReadFile: %08X", err); // Something bad happened. + BlenderLog.report(logvisor::Error, fmt("Error with ReadFile: %08X"), err); // Something bad happened. } // Display the character read on the screen. auto lk = logvisor::LockLog(); if (!WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), lpBuffer, nBytesRead, &nCharsWritten, NULL)) { - // BlenderLog.report(logvisor::Error, "Error with WriteConsole: %08X", GetLastError()); + // BlenderLog.report(logvisor::Error, fmt("Error with WriteConsole: %08X"), GetLastError()); } } @@ -390,21 +390,18 @@ Connection::Connection(int verbosityLevel) { close(devNull); } - char errbuf[256]; - char readfds[32]; - snprintf(readfds, 32, "%d", m_writepipe[0]); - char writefds[32]; - snprintf(writefds, 32, "%d", m_readpipe[1]); - char vLevel[32]; - snprintf(vLevel, 32, "%d", verbosityLevel); + std::string errbuf; + std::string readfds = fmt::format(fmt("{}"), m_writepipe[0]); + std::string writefds = fmt::format(fmt("{}"), m_readpipe[1]); + std::string vLevel = fmt::format(fmt("{}"), verbosityLevel); /* Try user-specified blender first */ if (blenderBin) { - execlp(blenderBin, blenderBin, "--background", "-P", blenderShellPath.c_str(), "--", readfds, writefds, vLevel, - blenderAddonPath.c_str(), NULL); + execlp(blenderBin, blenderBin, "--background", "-P", blenderShellPath.c_str(), "--", + readfds.c_str(), writefds.c_str(), vLevel.c_str(), blenderAddonPath.c_str(), NULL); if (errno != ENOENT) { - snprintf(errbuf, 256, "NOLAUNCH %s", strerror(errno)); - _writeStr(errbuf, strlen(errbuf), m_readpipe[1]); + errbuf = fmt::format(fmt("NOLAUNCH {}"), strerror(errno)); + _writeStr(errbuf.c_str(), errbuf.size(), m_readpipe[1]); exit(1); } } @@ -418,21 +415,21 @@ Connection::Connection(int verbosityLevel) { steamBlender += "/blender"; #endif blenderBin = steamBlender.c_str(); - execlp(blenderBin, blenderBin, "--background", "-P", blenderShellPath.c_str(), "--", readfds, writefds, vLevel, - blenderAddonPath.c_str(), NULL); + execlp(blenderBin, blenderBin, "--background", "-P", blenderShellPath.c_str(), "--", + readfds.c_str(), writefds.c_str(), vLevel.c_str(), blenderAddonPath.c_str(), NULL); if (errno != ENOENT) { - snprintf(errbuf, 256, "NOLAUNCH %s", strerror(errno)); - _writeStr(errbuf, strlen(errbuf), m_readpipe[1]); + errbuf = fmt::format(fmt("NOLAUNCH {}"), strerror(errno)); + _writeStr(errbuf.c_str(), errbuf.size(), m_readpipe[1]); exit(1); } } /* Otherwise default blender */ - execlp(DEFAULT_BLENDER_BIN, DEFAULT_BLENDER_BIN, "--background", "-P", blenderShellPath.c_str(), "--", readfds, - writefds, vLevel, blenderAddonPath.c_str(), NULL); + execlp(DEFAULT_BLENDER_BIN, DEFAULT_BLENDER_BIN, "--background", "-P", blenderShellPath.c_str(), "--", + readfds.c_str(), writefds.c_str(), vLevel.c_str(), blenderAddonPath.c_str(), NULL); if (errno != ENOENT) { - snprintf(errbuf, 256, "NOLAUNCH %s", strerror(errno)); - _writeStr(errbuf, strlen(errbuf), m_readpipe[1]); + errbuf = fmt::format(fmt("NOLAUNCH {}"), strerror(errno)); + _writeStr(errbuf.c_str(), errbuf.size(), m_readpipe[1]); exit(1); } @@ -448,10 +445,10 @@ Connection::Connection(int verbosityLevel) { /* Stash error path and unlink existing file */ #if _WIN32 m_errPath = hecl::SystemString(TMPDIR) + - hecl::SysFormat(_SYS_STR("/hecl_%016llX.derp"), (unsigned long long)m_pinfo.dwProcessId); + fmt::format(fmt(_SYS_STR("/hecl_{:016X}.derp")), (unsigned long long)m_pinfo.dwProcessId); #else m_errPath = - hecl::SystemString(TMPDIR) + hecl::SysFormat(_SYS_STR("/hecl_%016llX.derp"), (unsigned long long)m_blenderProc); + hecl::SystemString(TMPDIR) + fmt::format(fmt(_SYS_STR("/hecl_{:016X}.derp")), (unsigned long long)m_blenderProc); #endif hecl::Unlink(m_errPath.c_str()); @@ -461,24 +458,24 @@ Connection::Connection(int verbosityLevel) { if (!strncmp(lineBuf, "NOLAUNCH", 8)) { _closePipe(); - BlenderLog.report(logvisor::Fatal, "Unable to launch blender: %s", lineBuf + 9); + BlenderLog.report(logvisor::Fatal, fmt("Unable to launch blender: {}"), lineBuf + 9); } else if (!strncmp(lineBuf, "NOBLENDER", 9)) { _closePipe(); if (blenderBin) - BlenderLog.report(logvisor::Fatal, _SYS_STR("Unable to find blender at '%s' or '%s'"), blenderBin, + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("Unable to find blender at '{}' or '{}'")), blenderBin, DEFAULT_BLENDER_BIN); else - BlenderLog.report(logvisor::Fatal, _SYS_STR("Unable to find blender at '%s'"), DEFAULT_BLENDER_BIN); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("Unable to find blender at '{}'")), DEFAULT_BLENDER_BIN); } else if (!strcmp(lineBuf, "NOT280")) { _closePipe(); - BlenderLog.report(logvisor::Fatal, _SYS_STR("Installed blender version must be >= 2.80")); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("Installed blender version must be >= 2.80"))); } else if (!strcmp(lineBuf, "NOADDON")) { _closePipe(); if (blenderAddonPath != _SYS_STR("SKIPINSTALL")) InstallAddon(blenderAddonPath.c_str()); ++installAttempt; if (installAttempt >= 2) - BlenderLog.report(logvisor::Fatal, _SYS_STR("unable to install blender addon using '%s'"), + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("unable to install blender addon using '{}'")), blenderAddonPath.c_str()); continue; } else if (!strcmp(lineBuf, "ADDONINSTALLED")) { @@ -487,14 +484,14 @@ Connection::Connection(int verbosityLevel) { continue; } else if (strcmp(lineBuf, "READY")) { _closePipe(); - BlenderLog.report(logvisor::Fatal, "read '%s' from blender; expected 'READY'", lineBuf); + BlenderLog.report(logvisor::Fatal, fmt("read '{}' from blender; expected 'READY'"), lineBuf); } _writeStr("ACK"); break; } #else - BlenderLog.report(logvisor::Fatal, "BlenderConnection not available on UWP"); + BlenderLog.report(logvisor::Fatal, fmt("BlenderConnection not available on UWP")); #endif } @@ -510,13 +507,13 @@ void Boolean::read(Connection& conn) { conn._readBuf(&val, 1); } std::streambuf::int_type PyOutStream::StreamBuf::overflow(int_type ch) { if (!m_parent.m_parent || !m_parent.m_parent->m_lock) - BlenderLog.report(logvisor::Fatal, "lock not held for PyOutStream writing"); + BlenderLog.report(logvisor::Fatal, fmt("lock not held for PyOutStream writing")); if (ch != traits_type::eof() && ch != '\n' && ch != '\0') { m_lineBuf += char_type(ch); return ch; } // printf("FLUSHING %s\n", m_lineBuf.c_str()); - m_parent.m_parent->_writeStr(m_lineBuf.c_str()); + m_parent.m_parent->_writeStr(m_lineBuf); char readBuf[16]; m_parent.m_parent->_readStr(readBuf, 16); if (strcmp(readBuf, "OK")) { @@ -533,10 +530,10 @@ static const char* BlendTypeStrs[] = {"NONE", "MESH", "CMESH", "ACTOR" bool Connection::createBlend(const ProjectPath& path, BlendType type) { if (m_lock) { - BlenderLog.report(logvisor::Fatal, "BlenderConnection::createBlend() musn't be called with stream active"); + BlenderLog.report(logvisor::Fatal, fmt("BlenderConnection::createBlend() musn't be called with stream active")); return false; } - _writeStr(("CREATE \""s + path.getAbsolutePathUTF8().data() + "\" " + BlendTypeStrs[int(type)]).c_str()); + _writeStr(fmt::format(fmt("CREATE \"{}\" {}"), path.getAbsolutePathUTF8(), BlendTypeStrs[int(type)])); char lineBuf[256]; _readStr(lineBuf, sizeof(lineBuf)); if (!strcmp(lineBuf, "FINISHED")) { @@ -551,12 +548,12 @@ bool Connection::createBlend(const ProjectPath& path, BlendType type) { bool Connection::openBlend(const ProjectPath& path, bool force) { if (m_lock) { - BlenderLog.report(logvisor::Fatal, "BlenderConnection::openBlend() musn't be called with stream active"); + BlenderLog.report(logvisor::Fatal, fmt("BlenderConnection::openBlend() musn't be called with stream active")); return false; } if (!force && path == m_loadedBlend) return true; - _writeStr(("OPEN \""s + path.getAbsolutePathUTF8().data() + "\"").c_str()); + _writeStr(fmt::format(fmt("OPEN \"{}\""), path.getAbsolutePathUTF8())); char lineBuf[256]; _readStr(lineBuf, sizeof(lineBuf)); if (!strcmp(lineBuf, "FINISHED")) { @@ -586,7 +583,7 @@ bool Connection::openBlend(const ProjectPath& path, bool force) { bool Connection::saveBlend() { if (m_lock) { - BlenderLog.report(logvisor::Fatal, "BlenderConnection::saveBlend() musn't be called with stream active"); + BlenderLog.report(logvisor::Fatal, fmt("BlenderConnection::saveBlend() musn't be called with stream active")); return false; } _writeStr("SAVE"); @@ -600,7 +597,7 @@ bool Connection::saveBlend() { void Connection::deleteBlend() { if (m_loadedBlend) { hecl::Unlink(m_loadedBlend.getAbsolutePath().data()); - BlenderLog.report(logvisor::Info, _SYS_STR("Deleted '%s'"), m_loadedBlend.getAbsolutePath().data()); + BlenderLog.report(logvisor::Info, fmt(_SYS_STR("Deleted '{}'")), m_loadedBlend.getAbsolutePath()); m_loadedBlend = ProjectPath(); } } @@ -612,7 +609,7 @@ PyOutStream::PyOutStream(Connection* parent, bool deleteOnError) char readBuf[16]; m_parent->_readStr(readBuf, 16); if (strcmp(readBuf, "READY")) - BlenderLog.report(logvisor::Fatal, "unable to open PyOutStream with blender"); + BlenderLog.report(logvisor::Fatal, fmt("unable to open PyOutStream with blender")); } void PyOutStream::close() { @@ -621,85 +618,62 @@ void PyOutStream::close() { char readBuf[16]; m_parent->_readStr(readBuf, 16); if (strcmp(readBuf, "DONE")) - BlenderLog.report(logvisor::Fatal, "unable to close PyOutStream with blender"); + BlenderLog.report(logvisor::Fatal, fmt("unable to close PyOutStream with blender")); m_parent->m_pyStreamActive = false; m_parent->m_lock = false; } } -#if __GNUC__ -__attribute__((__format__ (__printf__, 2, 3))) -#endif -void PyOutStream::format(const char* fmt, ...) -{ - if (!m_parent || !m_parent->m_lock) - BlenderLog.report(logvisor::Fatal, "lock not held for PyOutStream::format()"); - va_list ap; - va_start(ap, fmt); - char* result = nullptr; -#ifdef _WIN32 - int length = _vscprintf(fmt, ap); - result = (char*)malloc(length); - vsnprintf(result, length, fmt, ap); -#else - int length = vasprintf(&result, fmt, ap); -#endif - va_end(ap); - if (length > 0) - this->write(result, length); - free(result); -} - void PyOutStream::linkBlend(const char* target, const char* objName, bool link) { - format( - "if '%s' not in bpy.data.scenes:\n" - " with bpy.data.libraries.load('''%s''', link=%s, relative=True) as (data_from, data_to):\n" + format(fmt( + "if '{}' not in bpy.data.scenes:\n" + " with bpy.data.libraries.load('''{}''', link={}, relative=True) as (data_from, data_to):\n" " data_to.scenes = data_from.scenes\n" " obj_scene = None\n" " for scene in data_to.scenes:\n" - " if scene.name == '%s':\n" + " if scene.name == '{}':\n" " obj_scene = scene\n" " break\n" " if not obj_scene:\n" - " raise RuntimeError('''unable to find %s in %s. try deleting it and restart the extract.''')\n" + " raise RuntimeError('''unable to find {} in {}. try deleting it and restart the extract.''')\n" " obj = None\n" " for object in obj_scene.objects:\n" " if object.name == obj_scene.name:\n" " obj = object\n" "else:\n" - " obj = bpy.data.objects['%s']\n" - "\n", + " obj = bpy.data.objects['{}']\n" + "\n"), objName, target, link ? "True" : "False", objName, objName, target, objName); } void PyOutStream::linkBackground(const char* target, const char* sceneName) { if (!sceneName) { - format( - "with bpy.data.libraries.load('''%s''', link=True, relative=True) as (data_from, data_to):\n" + format(fmt( + "with bpy.data.libraries.load('''{}''', link=True, relative=True) as (data_from, data_to):\n" " data_to.scenes = data_from.scenes\n" "obj_scene = None\n" "for scene in data_to.scenes:\n" " obj_scene = scene\n" " break\n" "if not obj_scene:\n" - " raise RuntimeError('''unable to find %s. try deleting it and restart the extract.''')\n" + " raise RuntimeError('''unable to find {}. try deleting it and restart the extract.''')\n" "\n" - "bpy.context.scene.background_set = obj_scene\n", + "bpy.context.scene.background_set = obj_scene\n"), target, target); } else { - format( - "if '%s' not in bpy.data.scenes:\n" - " with bpy.data.libraries.load('''%s''', link=True, relative=True) as (data_from, data_to):\n" + format(fmt( + "if '{}' not in bpy.data.scenes:\n" + " with bpy.data.libraries.load('''{}''', link=True, relative=True) as (data_from, data_to):\n" " data_to.scenes = data_from.scenes\n" " obj_scene = None\n" " for scene in data_to.scenes:\n" - " if scene.name == '%s':\n" + " if scene.name == '{}':\n" " obj_scene = scene\n" " break\n" " if not obj_scene:\n" - " raise RuntimeError('''unable to find %s in %s. try deleting it and restart the extract.''')\n" + " raise RuntimeError('''unable to find {} in {}. try deleting it and restart the extract.''')\n" "\n" - "bpy.context.scene.background_set = bpy.data.scenes['%s']\n", + "bpy.context.scene.background_set = bpy.data.scenes['{}']\n"), sceneName, target, sceneName, sceneName, target, sceneName); } } @@ -707,16 +681,16 @@ void PyOutStream::linkBackground(const char* target, const char* sceneName) { void PyOutStream::AABBToBMesh(const atVec3f& min, const atVec3f& max) { athena::simd_floats minf(min.simd); athena::simd_floats maxf(max.simd); - format( + format(fmt( "bm = bmesh.new()\n" - "bm.verts.new((%f,%f,%f))\n" - "bm.verts.new((%f,%f,%f))\n" - "bm.verts.new((%f,%f,%f))\n" - "bm.verts.new((%f,%f,%f))\n" - "bm.verts.new((%f,%f,%f))\n" - "bm.verts.new((%f,%f,%f))\n" - "bm.verts.new((%f,%f,%f))\n" - "bm.verts.new((%f,%f,%f))\n" + "bm.verts.new(({},{},{}))\n" + "bm.verts.new(({},{},{}))\n" + "bm.verts.new(({},{},{}))\n" + "bm.verts.new(({},{},{}))\n" + "bm.verts.new(({},{},{}))\n" + "bm.verts.new(({},{},{}))\n" + "bm.verts.new(({},{},{}))\n" + "bm.verts.new(({},{},{}))\n" "bm.verts.ensure_lookup_table()\n" "bm.edges.new((bm.verts[0], bm.verts[1]))\n" "bm.edges.new((bm.verts[0], bm.verts[2]))\n" @@ -729,7 +703,7 @@ void PyOutStream::AABBToBMesh(const atVec3f& min, const atVec3f& max) { "bm.edges.new((bm.verts[5], bm.verts[7]))\n" "bm.edges.new((bm.verts[6], bm.verts[2]))\n" "bm.edges.new((bm.verts[6], bm.verts[4]))\n" - "bm.edges.new((bm.verts[6], bm.verts[7]))\n", + "bm.edges.new((bm.verts[6], bm.verts[7]))\n"), minf[0], minf[1], minf[2], maxf[0], minf[1], minf[2], minf[0], maxf[1], minf[2], maxf[0], maxf[1], minf[2], minf[0], minf[1], maxf[2], maxf[0], minf[1], maxf[2], minf[0], maxf[1], maxf[2], maxf[0], maxf[1], maxf[2]); } @@ -763,7 +737,7 @@ ANIMOutStream::ANIMOutStream(Connection* parent) : m_parent(parent) { char readBuf[16]; m_parent->_readStr(readBuf, 16); if (strcmp(readBuf, "ANIMREADY")) - BlenderLog.report(logvisor::Fatal, "unable to open ANIMOutStream"); + BlenderLog.report(logvisor::Fatal, fmt("unable to open ANIMOutStream")); } ANIMOutStream::~ANIMOutStream() { @@ -772,12 +746,12 @@ ANIMOutStream::~ANIMOutStream() { char readBuf[16]; m_parent->_readStr(readBuf, 16); if (strcmp(readBuf, "ANIMDONE")) - BlenderLog.report(logvisor::Fatal, "unable to close ANIMOutStream"); + BlenderLog.report(logvisor::Fatal, fmt("unable to close ANIMOutStream")); } void ANIMOutStream::changeCurve(CurveType type, unsigned crvIdx, unsigned keyCount) { if (m_curCount != m_totalCount) - BlenderLog.report(logvisor::Fatal, "incomplete ANIMOutStream for change"); + BlenderLog.report(logvisor::Fatal, fmt("incomplete ANIMOutStream for change")); m_curCount = 0; m_totalCount = keyCount; char tp = char(type); @@ -792,7 +766,7 @@ void ANIMOutStream::changeCurve(CurveType type, unsigned crvIdx, unsigned keyCou void ANIMOutStream::write(unsigned frame, float val) { if (!m_inCurve) - BlenderLog.report(logvisor::Fatal, "changeCurve not called before write"); + BlenderLog.report(logvisor::Fatal, fmt("changeCurve not called before write")); if (m_curCount < m_totalCount) { struct { uint32_t frm; @@ -801,7 +775,7 @@ void ANIMOutStream::write(unsigned frame, float val) { m_parent->_writeBuf(reinterpret_cast(&key), 8); ++m_curCount; } else - BlenderLog.report(logvisor::Fatal, "ANIMOutStream keyCount overflow"); + BlenderLog.report(logvisor::Fatal, fmt("ANIMOutStream keyCount overflow")); } Mesh::SkinBind::SkinBind(Connection& conn) { @@ -1495,7 +1469,7 @@ DataStream::DataStream(Connection* parent) : m_parent(parent) { char readBuf[16]; m_parent->_readStr(readBuf, 16); if (strcmp(readBuf, "READY")) - BlenderLog.report(logvisor::Fatal, "unable to open DataStream with blender"); + BlenderLog.report(logvisor::Fatal, fmt("unable to open DataStream with blender")); } void DataStream::close() { @@ -1504,7 +1478,7 @@ void DataStream::close() { char readBuf[16]; m_parent->_readStr(readBuf, 16); if (strcmp(readBuf, "DONE")) - BlenderLog.report(logvisor::Fatal, "unable to close DataStream with blender"); + BlenderLog.report(logvisor::Fatal, fmt("unable to close DataStream with blender")); m_parent->m_dataStreamActive = false; m_parent->m_lock = false; } @@ -1540,14 +1514,14 @@ std::vector DataStream::getLightList() { std::pair DataStream::getMeshAABB() { if (m_parent->m_loadedType != BlendType::Mesh && m_parent->m_loadedType != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not a MESH or ACTOR blend"), - m_parent->m_loadedBlend.getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not a MESH or ACTOR blend")), + m_parent->m_loadedBlend.getAbsolutePath()); m_parent->_writeStr("MESHAABB"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable get AABB: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable get AABB: {}"), readBuf); Vector3f minPt(*m_parent); Vector3f maxPt(*m_parent); @@ -1561,66 +1535,60 @@ const char* DataStream::MeshOutputModeString(HMDLTopology topology) { Mesh DataStream::compileMesh(HMDLTopology topology, int skinSlotCount) { if (m_parent->getBlendType() != BlendType::Mesh) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not a MESH blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not a MESH blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("MESHCOMPILE"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to cook mesh: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to cook mesh: {}"), readBuf); return Mesh(*m_parent, topology, skinSlotCount); } Mesh DataStream::compileMesh(std::string_view name, HMDLTopology topology, int skinSlotCount, bool useLuv) { if (m_parent->getBlendType() != BlendType::Area) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an AREA blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an AREA blend")), + m_parent->getBlendPath().getAbsolutePath()); - char req[128]; - snprintf(req, 128, "MESHCOMPILENAME %s %d", name.data(), int(useLuv)); - m_parent->_writeStr(req); + m_parent->_writeStr(fmt::format(fmt("MESHCOMPILENAME {} {}"), name, int(useLuv))); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to cook mesh '%s': %s", name.data(), readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to cook mesh '{}': {}"), name, readBuf); return Mesh(*m_parent, topology, skinSlotCount, useLuv); } ColMesh DataStream::compileColMesh(std::string_view name) { if (m_parent->getBlendType() != BlendType::Area) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an AREA blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an AREA blend")), + m_parent->getBlendPath().getAbsolutePath()); - char req[128]; - snprintf(req, 128, "MESHCOMPILENAMECOLLISION %s", name.data()); - m_parent->_writeStr(req); + m_parent->_writeStr(fmt::format(fmt("MESHCOMPILENAMECOLLISION {}"), name)); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to cook collision mesh '%s': %s", name.data(), readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to cook collision mesh '{}': {}"), name, readBuf); return ColMesh(*m_parent); } std::vector DataStream::compileColMeshes() { if (m_parent->getBlendType() != BlendType::ColMesh) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not a CMESH blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not a CMESH blend")), + m_parent->getBlendPath().getAbsolutePath()); - char req[128]; - snprintf(req, 128, "MESHCOMPILECOLLISIONALL"); - m_parent->_writeStr(req); + m_parent->_writeStr("MESHCOMPILECOLLISIONALL"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to cook collision meshes: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to cook collision meshes: {}"), readBuf); uint32_t meshCount; m_parent->_readBuf(&meshCount, 4); @@ -1636,15 +1604,15 @@ std::vector DataStream::compileColMeshes() { std::vector DataStream::compileLights() { if (m_parent->getBlendType() != BlendType::Area) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an AREA blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an AREA blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("LIGHTCOMPILEALL"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to gather all lights: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to gather all lights: {}"), readBuf); uint32_t lightCount; m_parent->_readBuf(&lightCount, 4); @@ -1660,15 +1628,15 @@ std::vector DataStream::compileLights() { PathMesh DataStream::compilePathMesh() { if (m_parent->getBlendType() != BlendType::PathMesh) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not a PATH blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not a PATH blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("MESHCOMPILEPATH"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to path collision mesh: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to path collision mesh: {}"), readBuf); return PathMesh(*m_parent); } @@ -1676,17 +1644,15 @@ PathMesh DataStream::compilePathMesh() { std::vector DataStream::compileGuiFrame(int version) { std::vector ret; if (m_parent->getBlendType() != BlendType::Frame) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not a FRAME blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not a FRAME blend")), + m_parent->getBlendPath().getAbsolutePath()); - char req[512]; - snprintf(req, 512, "FRAMECOMPILE %d", version); - m_parent->_writeStr(req); + m_parent->_writeStr(fmt::format(fmt("FRAMECOMPILE {}"), version)); char readBuf[1024]; m_parent->_readStr(readBuf, 1024); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to compile frame: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to compile frame: {}"), readBuf); while (true) { m_parent->_readStr(readBuf, 1024); @@ -1703,8 +1669,7 @@ std::vector DataStream::compileGuiFrame(int version) { relative = proj.getProjectRootPath().getProjectRelativeFromAbsolute(absolute.sys_str()); hecl::ProjectPath path(proj.getProjectWorkingPath(), relative); - snprintf(req, 512, "%016" PRIX64, path.hash().val64()); - m_parent->_writeStr(req); + m_parent->_writeStr(fmt::format(fmt("{:016X}"), path.hash().val64())); } uint32_t len; @@ -1720,7 +1685,7 @@ std::vector DataStream::getTextures() { char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to get textures: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to get textures: {}"), readBuf); uint32_t texCount; m_parent->_readBuf(&texCount, 4); @@ -1743,77 +1708,75 @@ std::vector DataStream::getTextures() { Actor DataStream::compileActor() { if (m_parent->getBlendType() != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an ACTOR blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an ACTOR blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("ACTORCOMPILE"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to compile actor: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to compile actor: {}"), readBuf); return Actor(*m_parent); } Actor DataStream::compileActorCharacterOnly() { if (m_parent->getBlendType() != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an ACTOR blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an ACTOR blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("ACTORCOMPILECHARACTERONLY"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to compile actor: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to compile actor: {}"), readBuf); return Actor(*m_parent); } Action DataStream::compileActionChannelsOnly(std::string_view name) { if (m_parent->getBlendType() != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an ACTOR blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an ACTOR blend")), + m_parent->getBlendPath().getAbsolutePath()); - char req[128]; - snprintf(req, 128, "ACTIONCOMPILECHANNELSONLY %s", name.data()); - m_parent->_writeStr(req); + m_parent->_writeStr(fmt::format(fmt("ACTIONCOMPILECHANNELSONLY {}"), name)); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to compile action: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to compile action: {}"), readBuf); return Action(*m_parent); } World DataStream::compileWorld() { if (m_parent->getBlendType() != BlendType::World) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an WORLD blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an WORLD blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("WORLDCOMPILE"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to compile world: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to compile world: {}"), readBuf); return World(*m_parent); } std::vector DataStream::getArmatureNames() { if (m_parent->getBlendType() != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an ACTOR blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an ACTOR blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("GETARMATURENAMES"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to get armatures of actor: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to get armatures of actor: {}"), readBuf); std::vector ret; @@ -1834,15 +1797,15 @@ std::vector DataStream::getArmatureNames() { std::vector DataStream::getSubtypeNames() { if (m_parent->getBlendType() != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an ACTOR blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an ACTOR blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("GETSUBTYPENAMES"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to get subtypes of actor: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to get subtypes of actor: {}"), readBuf); std::vector ret; @@ -1863,15 +1826,15 @@ std::vector DataStream::getSubtypeNames() { std::vector DataStream::getActionNames() { if (m_parent->getBlendType() != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an ACTOR blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an ACTOR blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("GETACTIONNAMES"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to get actions of actor: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to get actions of actor: {}"), readBuf); std::vector ret; @@ -1892,17 +1855,15 @@ std::vector DataStream::getActionNames() { std::vector DataStream::getSubtypeOverlayNames(std::string_view name) { if (m_parent->getBlendType() != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an ACTOR blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an ACTOR blend")), + m_parent->getBlendPath().getAbsolutePath()); - char req[128]; - snprintf(req, 128, "GETSUBTYPEOVERLAYNAMES %s", name.data()); - m_parent->_writeStr(req); + m_parent->_writeStr(fmt::format(fmt("GETSUBTYPEOVERLAYNAMES {}"), name)); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to get subtype overlays of actor: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to get subtype overlays of actor: {}"), readBuf); std::vector ret; @@ -1923,15 +1884,15 @@ std::vector DataStream::getSubtypeOverlayNames(std::string_view nam std::vector DataStream::getAttachmentNames() { if (m_parent->getBlendType() != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an ACTOR blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an ACTOR blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("GETATTACHMENTNAMES"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to get attachments of actor: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to get attachments of actor: {}"), readBuf); std::vector ret; @@ -1955,17 +1916,15 @@ std::unordered_map DataStream::getBoneMatrices(std::strin return {}; if (m_parent->getBlendType() != BlendType::Actor) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an ACTOR blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an ACTOR blend")), + m_parent->getBlendPath().getAbsolutePath()); - char req[128]; - snprintf(req, 128, "GETBONEMATRICES %s", name.data()); - m_parent->_writeStr(req); + m_parent->_writeStr(fmt::format(fmt("GETBONEMATRICES {}"), name)); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to get matrices of armature: %s", readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to get matrices of armature: {}"), readBuf); std::unordered_map ret; @@ -2000,19 +1959,17 @@ bool DataStream::renderPvs(std::string_view path, const atVec3f& location) { return false; if (m_parent->getBlendType() != BlendType::Area) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an AREA blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an AREA blend")), + m_parent->getBlendPath().getAbsolutePath()); - char req[256]; athena::simd_floats f(location.simd); - snprintf(req, 256, "RENDERPVS %s %f %f %f", path.data(), f[0], f[1], f[2]); - m_parent->_writeStr(req); + m_parent->_writeStr(fmt::format(fmt("RENDERPVS {} {} {} {}"), path, f[0], f[1], f[2])); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to render PVS for: %s; %s", - m_parent->getBlendPath().getAbsolutePathUTF8().data(), readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to render PVS for: {}; {}"), + m_parent->getBlendPath().getAbsolutePathUTF8(), readBuf); return true; } @@ -2022,50 +1979,48 @@ bool DataStream::renderPvsLight(std::string_view path, std::string_view lightNam return false; if (m_parent->getBlendType() != BlendType::Area) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not an AREA blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not an AREA blend")), + m_parent->getBlendPath().getAbsolutePath()); - char req[256]; - snprintf(req, 256, "RENDERPVSLIGHT %s %s", path.data(), lightName.data()); - m_parent->_writeStr(req); + m_parent->_writeStr(fmt::format(fmt("RENDERPVSLIGHT {} {}"), path, lightName)); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to render PVS light %s for: %s; %s", lightName.data(), - m_parent->getBlendPath().getAbsolutePathUTF8().data(), readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to render PVS light {} for: {}; {}"), lightName, + m_parent->getBlendPath().getAbsolutePathUTF8(), readBuf); return true; } MapArea DataStream::compileMapArea() { if (m_parent->getBlendType() != BlendType::MapArea) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not a MAPAREA blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not a MAPAREA blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("MAPAREACOMPILE"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to compile map area: %s; %s", - m_parent->getBlendPath().getAbsolutePathUTF8().data(), readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to compile map area: {}; {}"), + m_parent->getBlendPath().getAbsolutePathUTF8(), readBuf); return {*m_parent}; } MapUniverse DataStream::compileMapUniverse() { if (m_parent->getBlendType() != BlendType::MapUniverse) - BlenderLog.report(logvisor::Fatal, _SYS_STR("%s is not a MAPUNIVERSE blend"), - m_parent->getBlendPath().getAbsolutePath().data()); + BlenderLog.report(logvisor::Fatal, fmt(_SYS_STR("{} is not a MAPUNIVERSE blend")), + m_parent->getBlendPath().getAbsolutePath()); m_parent->_writeStr("MAPUNIVERSECOMPILE"); char readBuf[256]; m_parent->_readStr(readBuf, 256); if (strcmp(readBuf, "OK")) - BlenderLog.report(logvisor::Fatal, "unable to compile map universe: %s; %s", - m_parent->getBlendPath().getAbsolutePathUTF8().data(), readBuf); + BlenderLog.report(logvisor::Fatal, fmt("unable to compile map universe: {}; {}"), + m_parent->getBlendPath().getAbsolutePathUTF8(), readBuf); return {*m_parent}; } @@ -2103,7 +2058,7 @@ void Token::shutdown() { m_conn->quitBlender(); m_conn.reset(); if (hecl::VerbosityLevel >= 1) - BlenderLog.report(logvisor::Info, "Blender Shutdown Successful"); + BlenderLog.report(logvisor::Info, fmt("Blender Shutdown Successful")); } } diff --git a/hecl/lib/Blender/MeshOptimizer.cpp b/hecl/lib/Blender/MeshOptimizer.cpp index 19d3c80d8..2ddca9ad8 100644 --- a/hecl/lib/Blender/MeshOptimizer.cpp +++ b/hecl/lib/Blender/MeshOptimizer.cpp @@ -44,7 +44,7 @@ MeshOptimizer::Vertex::Vertex(Connection& conn) { co.read(conn); Index skin_count(conn); if (skin_count.val > MaxSkinEntries) - Log.report(logvisor::Fatal, "Skin entry overflow %u/%u", skin_count.val, MaxSkinEntries); + Log.report(logvisor::Fatal, fmt("Skin entry overflow {}/{}"), skin_count.val, MaxSkinEntries); for (uint32_t i = 0; i < skin_count.val; ++i) skin_ents[i] = Mesh::SkinBind(conn); } @@ -69,7 +69,7 @@ MeshOptimizer::Edge::Edge(Connection& conn) { verts[i] = Index(conn).val; Index face_count(conn); if (face_count > MaxLinkFaces) - Log.report(logvisor::Fatal, "Face overflow %u/%u", face_count.val, MaxLinkFaces); + Log.report(logvisor::Fatal, fmt("Face overflow {}/{}"), face_count.val, MaxLinkFaces); for (uint32_t i = 0; i < face_count.val; ++i) link_faces[i] = Index(conn).val; is_contiguous = Boolean(conn).val; @@ -377,10 +377,10 @@ MeshOptimizer::MeshOptimizer(Connection& conn, const std::vector& mate : materials(materials), use_luvs(use_luvs) { color_count = Index(conn).val; if (color_count > MaxColorLayers) - Log.report(logvisor::Fatal, "Color layer overflow %u/%u", color_count, MaxColorLayers); + Log.report(logvisor::Fatal, fmt("Color layer overflow {}/{}"), color_count, MaxColorLayers); uv_count = Index(conn).val; if (uv_count > MaxUVLayers) - Log.report(logvisor::Fatal, "UV layer overflow %u/%u", uv_count, MaxUVLayers); + Log.report(logvisor::Fatal, fmt("UV layer overflow {}/{}"), uv_count, MaxUVLayers); /* Simultaneously load topology objects and build unique mapping indices */ diff --git a/hecl/lib/CVar.cpp b/hecl/lib/CVar.cpp index 98601b64b..ae1d25d6e 100644 --- a/hecl/lib/CVar.cpp +++ b/hecl/lib/CVar.cpp @@ -226,7 +226,7 @@ bool CVar::fromVec4f(const atVec4f& val) { return false; athena::simd_floats f(val.simd); - m_value.assign(hecl::Format("%f %f %f %f", f[0], f[1], f[2], f[3])); + m_value.assign(fmt::format(fmt("{} {} {} {}"), f[0], f[1], f[2], f[3])); m_flags |= EFlags::Modified; return true; } @@ -243,7 +243,7 @@ bool CVar::fromFloat(float val) { if (isReadOnly() && (com_developer && !com_developer->toBoolean())) return false; - m_value.assign(hecl::Format("%f", val)); + m_value.assign(fmt::format(fmt("{}"), val)); setModified(); return true; } @@ -281,7 +281,7 @@ bool CVar::fromInteger(int val) { if (isReadOnly() && (com_developer && !com_developer->toBoolean())) return false; - m_value = hecl::Format("%i", val); + m_value = fmt::format(fmt("{}"), val); setModified(); return true; } diff --git a/hecl/lib/CVarManager.cpp b/hecl/lib/CVarManager.cpp index 37241bfab..11e89dc73 100644 --- a/hecl/lib/CVarManager.cpp +++ b/hecl/lib/CVarManager.cpp @@ -196,20 +196,20 @@ CVarManager* CVarManager::instance() { return m_instance; } void CVarManager::list(Console* con, const std::vector& /*args*/) { for (const auto& cvar : m_cvars) { if (!cvar.second->isHidden()) - con->report(Console::Level::Info, "%s: %s", cvar.second->name().data(), cvar.second->help().c_str()); + con->report(Console::Level::Info, fmt("{}: {}"), cvar.second->name(), cvar.second->help()); } } void CVarManager::setCVar(Console* con, const std::vector& args) { if (args.size() < 2) { - con->report(Console::Level::Info, "Usage setCvar "); + con->report(Console::Level::Info, fmt("Usage setCvar ")); return; } std::string cvName = args[0]; athena::utility::tolower(cvName); if (m_cvars.find(cvName) == m_cvars.end()) { - con->report(Console::Level::Error, "CVar '%s' does not exist", args[0].c_str()); + con->report(Console::Level::Error, fmt("CVar '%s' does not exist"), args[0].c_str()); return; } @@ -225,26 +225,26 @@ void CVarManager::setCVar(Console* con, const std::vector& args) { return; if (!cv->fromLiteralToType(value)) - con->report(Console::Level::Warning, "Unable to set cvar '%s' to value '%s'", cv->name().data(), value.c_str()); + con->report(Console::Level::Warning, fmt("Unable to set cvar '%s' to value '%s'"), cv->name().data(), value.c_str()); else - con->report(Console::Level::Info, "Set '%s' from '%s' to '%s'", cv->name().data(), oldVal.c_str(), value.c_str()); + con->report(Console::Level::Info, fmt("Set '%s' from '%s' to '%s'"), cv->name().data(), oldVal.c_str(), value.c_str()); } void CVarManager::getCVar(Console* con, const std::vector& args) { if (args.empty()) { - con->report(Console::Level::Info, "Usage getCVar "); + con->report(Console::Level::Info, fmt("Usage getCVar ")); return; } std::string cvName = args[0]; athena::utility::tolower(cvName); if (m_cvars.find(cvName) == m_cvars.end()) { - con->report(Console::Level::Error, "CVar '%s' does not exist", args[0].c_str()); + con->report(Console::Level::Error, fmt("CVar '%s' does not exist"), args[0].c_str()); return; } const auto& cv = m_cvars[cvName]; - con->report(Console::Level::Info, "'%s' = '%s'", cv->name().data(), cv->value().c_str()); + con->report(Console::Level::Info, fmt("'%s' = '%s'"), cv->name().data(), cv->value().c_str()); } void CVarManager::setDeveloperMode(bool v, bool setDeserialized) { diff --git a/hecl/lib/ClientProcess.cpp b/hecl/lib/ClientProcess.cpp index 8b881988d..051c7b207 100644 --- a/hecl/lib/ClientProcess.cpp +++ b/hecl/lib/ClientProcess.cpp @@ -59,7 +59,7 @@ static int GetCPUCount() { void ClientProcess::BufferTransaction::run(blender::Token& btok) { athena::io::FileReader r(m_path.getAbsolutePath(), 32 * 1024, false); if (r.hasError()) { - CP_Log.report(logvisor::Fatal, _SYS_STR("unable to background-buffer '%s'"), m_path.getAbsolutePath().data()); + CP_Log.report(logvisor::Fatal, fmt(_SYS_STR("unable to background-buffer '{}'")), m_path.getAbsolutePath()); return; } if (m_offset) @@ -89,9 +89,7 @@ ClientProcess::Worker::Worker(ClientProcess& proc, int idx) : m_proc(proc), m_id void ClientProcess::Worker::proc() { ClientProcess::ThreadWorker.reset(this); - char thrName[64]; - snprintf(thrName, 64, "HECL Worker %d", m_idx); - logvisor::RegisterThreadName(thrName); + logvisor::RegisterThreadName(fmt::format(fmt("HECL Worker {}"), m_idx).c_str()); std::unique_lock lk(m_proc.m_mutex); while (m_proc.m_running) { @@ -176,25 +174,24 @@ bool ClientProcess::syncCook(const hecl::ProjectPath& path, Database::IDataSpec* if (m_progPrinter) { hecl::SystemString str; if (path.getAuxInfo().empty()) - str = hecl::SysFormat(_SYS_STR("Cooking %s"), path.getRelativePath().data()); + str = fmt::format(fmt(_SYS_STR("Cooking {}")), path.getRelativePath()); else - str = hecl::SysFormat(_SYS_STR("Cooking %s|%s"), path.getRelativePath().data(), path.getAuxInfo().data()); + str = fmt::format(fmt(_SYS_STR("Cooking {}|{}")), path.getRelativePath(), path.getAuxInfo()); m_progPrinter->print(str.c_str(), nullptr, -1.f, hecl::ClientProcess::GetThreadWorkerIdx()); m_progPrinter->flush(); } else { if (path.getAuxInfo().empty()) - LogModule.report(logvisor::Info, _SYS_STR("Cooking %s"), path.getRelativePath().data()); + LogModule.report(logvisor::Info, fmt(_SYS_STR("Cooking {}")), path.getRelativePath()); else - LogModule.report(logvisor::Info, _SYS_STR("Cooking %s|%s"), path.getRelativePath().data(), - path.getAuxInfo().data()); + LogModule.report(logvisor::Info, fmt(_SYS_STR("Cooking {}|{}")), path.getRelativePath(), path.getAuxInfo()); } spec->doCook(path, cooked, false, btok, [](const SystemChar*) {}); if (m_progPrinter) { hecl::SystemString str; if (path.getAuxInfo().empty()) - str = hecl::SysFormat(_SYS_STR("Cooked %s"), path.getRelativePath().data()); + str = fmt::format(fmt(_SYS_STR("Cooked {}")), path.getRelativePath()); else - str = hecl::SysFormat(_SYS_STR("Cooked %s|%s"), path.getRelativePath().data(), path.getAuxInfo().data()); + str = fmt::format(fmt(_SYS_STR("Cooked {}|{}")), path.getRelativePath(), path.getAuxInfo()); m_progPrinter->print(str.c_str(), nullptr, -1.f, hecl::ClientProcess::GetThreadWorkerIdx()); m_progPrinter->flush(); } diff --git a/hecl/lib/Compilers.cpp b/hecl/lib/Compilers.cpp index 6fb0398bd..eb47087e4 100644 --- a/hecl/lib/Compilers.cpp +++ b/hecl/lib/Compilers.cpp @@ -64,15 +64,15 @@ struct ShaderCompiler { const char* strings[] = {"#version 330\n", BOO_GLSL_BINDING_HEAD, text.data()}; shader.setStrings(strings, 3); if (!shader.parse(&glslang::DefaultTBuiltInResource, 110, false, messages)) { - printf("%s\n", text.data()); - Log.report(logvisor::Fatal, "unable to compile shader\n%s", shader.getInfoLog()); + fmt::print(fmt("{}\n"), text); + Log.report(logvisor::Fatal, fmt("unable to compile shader\n{}"), shader.getInfoLog()); return {}; } glslang::TProgram prog; prog.addShader(&shader); if (!prog.link(messages)) { - Log.report(logvisor::Fatal, "unable to link shader program\n%s", prog.getInfoLog()); + Log.report(logvisor::Fatal, fmt("unable to link shader program\n{}"), prog.getInfoLog()); return {}; } @@ -100,7 +100,7 @@ struct ShaderCompiler { if (FAILED(D3DCompilePROC(text.data(), text.size(), "Boo HLSL Source", nullptr, nullptr, "main", D3DShaderTypes[int(S::Enum)], BOO_D3DCOMPILE_FLAG, 0, &blobOut, &errBlob))) { printf("%s\n", text.data()); - Log.report(logvisor::Fatal, "error compiling shader: %s", errBlob->GetBufferPointer()); + Log.report(logvisor::Fatal, fmt("error compiling shader: %s"), errBlob->GetBufferPointer()); return {}; } std::pair ret(MakeStageBinaryData(blobOut->GetBufferSize()), blobOut->GetBufferSize()); @@ -162,8 +162,7 @@ struct ShaderCompiler { pid_t pid = getpid(); const char* tmpdir = getenv("TMPDIR"); - char libFile[1024]; - snprintf(libFile, 1024, "%sboo_metal_shader%d.metallib", tmpdir, pid); + std::string libFile = fmt::format(fmt("{}boo_metal_shader{}.metallib"), tmpdir, pid); /* Pipe source write to compiler */ pid_t compilerPid = fork(); @@ -197,7 +196,7 @@ struct ShaderCompiler { close(compilerIn[1]); /* metallib doesn't like outputting to a pipe, so temp file will have to do */ - execlp("xcrun", "xcrun", "-sdk", "macosx", "metallib", "-", "-o", libFile, NULL); + execlp("xcrun", "xcrun", "-sdk", "macosx", "metallib", "-", "-o", libFile.c_str(), NULL); fprintf(stderr, "execlp fail %s\n", strerror(errno)); exit(1); } @@ -222,29 +221,29 @@ struct ShaderCompiler { while (waitpid(compilerPid, &compilerStat, 0) < 0) { if (errno == EINTR) continue; - Log.report(logvisor::Fatal, "waitpid fail %s", strerror(errno)); + Log.report(logvisor::Fatal, fmt("waitpid fail %s"), strerror(errno)); return {}; } if (WEXITSTATUS(compilerStat)) { - Log.report(logvisor::Fatal, "compile fail"); + Log.report(logvisor::Fatal, fmt("compile fail")); return {}; } while (waitpid(linkerPid, &linkerStat, 0) < 0) { if (errno == EINTR) continue; - Log.report(logvisor::Fatal, "waitpid fail %s", strerror(errno)); + Log.report(logvisor::Fatal, fmt("waitpid fail %s"), strerror(errno)); return {}; } if (WEXITSTATUS(linkerStat)) { - Log.report(logvisor::Fatal, "link fail"); + Log.report(logvisor::Fatal, fmt("link fail")); return {}; } /* Copy temp file into buffer with first byte set to indicate binary data */ - FILE* fin = fopen(libFile, "rb"); + FILE* fin = fopen(libFile.c_str(), "rb"); fseek(fin, 0, SEEK_END); long libLen = ftell(fin); fseek(fin, 0, SEEK_SET); diff --git a/hecl/lib/Console.cpp b/hecl/lib/Console.cpp index 14e58c620..82d704cfa 100644 --- a/hecl/lib/Console.cpp +++ b/hecl/lib/Console.cpp @@ -90,7 +90,7 @@ void Console::executeString(const std::string& str) { if (isInLiteral) { if ((curLiteral.back() != '\'' && curLiteral.back() != '"') || depth > 1) { - report(Level::Warning, "Unterminated string literal"); + report(Level::Warning, fmt("Unterminated string literal")); return; } args.push_back(curLiteral); @@ -104,12 +104,12 @@ void Console::executeString(const std::string& str) { if (m_commands.find(lowComName) != m_commands.end()) { const SConsoleCommand& cmd = m_commands[lowComName]; if (bool(cmd.m_flags & SConsoleCommand::ECommandFlags::Developer) && !com_developer->toBoolean()) { - report(Level::Error, "This command can only be executed in developer mode", commandName.c_str()); + report(Level::Error, fmt("This command can only be executed in developer mode"), commandName); return; } if (bool(cmd.m_flags & SConsoleCommand::ECommandFlags::Cheat) && !com_enableCheats->toBoolean()) { - report(Level::Error, "This command can only be executed with cheats enabled", commandName.c_str()); + report(Level::Error, fmt("This command can only be executed with cheats enabled"), commandName); return; } m_commands[lowComName].m_func(this, args); @@ -120,31 +120,31 @@ void Console::executeString(const std::string& str) { else m_cvarMgr->getCVar(this, args); } else - report(Level::Error, "Command '%s' is not valid!", commandName.c_str()); + report(Level::Error, fmt("Command '{}' is not valid!"), commandName); } } void Console::help(Console* /*con*/, const std::vector& args) { if (args.empty()) { - report(Level::Info, "Expected usage: help "); + report(Level::Info, fmt("Expected usage: help ")); return; } std::string cmd = args.front(); athena::utility::tolower(cmd); auto it = m_commands.find(cmd); if (it == m_commands.end()) { - report(Level::Error, "No such command '%s'", args.front().c_str()); + report(Level::Error, fmt("No such command '{}'"), args.front()); return; } - report(Level::Info, "%s: %s", it->second.m_displayName.c_str(), it->second.m_helpString.c_str()); + report(Level::Info, fmt("{}: {}"), it->second.m_displayName, it->second.m_helpString); if (!it->second.m_usage.empty()) - report(Level::Info, "Usage: %s %s", it->second.m_displayName.c_str(), it->second.m_usage.c_str()); + report(Level::Info, fmt("Usage: {} {}"), it->second.m_displayName, it->second.m_usage); } void Console::listCommands(Console* /*con*/, const std::vector& /*args*/) { for (const auto& comPair : m_commands) - report(Level::Info, "'%s': %s", comPair.second.m_displayName.c_str(), comPair.second.m_helpString.c_str()); + report(Level::Info, fmt("'{}': {}"), comPair.second.m_displayName, comPair.second.m_helpString); } bool Console::commandExists(std::string_view cmd) { @@ -154,23 +154,14 @@ bool Console::commandExists(std::string_view cmd) { return m_commands.find(cmdName) != m_commands.end(); } -void Console::report(Level level, const char* fmt, va_list list) { - char tmp[2048]; - vsnprintf(tmp, 2048, fmt, list); +void Console::vreport(Level level, fmt::string_view fmt, fmt::format_args args) { + std::string tmp = fmt::vformat(fmt, args); std::vector lines = athena::utility::split(tmp, '\n'); - for (const std::string& line : lines) { - std::string v = athena::utility::sprintf("%s", line.c_str()); - m_log.emplace_back(v, level); - } - printf("%s\n", tmp); + for (const std::string& line : lines) + m_log.emplace_back(line, level); + fmt::print(fmt("{}\n"), tmp); } -void Console::report(Level level, const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - report(level, fmt, ap); - va_end(ap); -} void Console::init(boo::IWindow* window) { m_window = window; } @@ -187,7 +178,7 @@ void Console::proc() { } if (m_state == State::Opened) { - printf("\r%s ", m_commandString.c_str()); + fmt::print(fmt("\r{} "), m_commandString); fflush(stdout); } else if (m_state == State::Opening) m_state = State::Opened; @@ -290,7 +281,7 @@ void Console::handleSpecialKeyDown(boo::ESpecialKey sp, boo::EModifierKey mod, b break; } case boo::ESpecialKey::Enter: { - printf("\n"); + fmt::print(fmt("\n")); executeString(m_commandString); m_cursorPosition = -1; m_commandHistory.insert(m_commandHistory.begin(), m_commandString); @@ -372,42 +363,39 @@ void Console::handleSpecialKeyDown(boo::ESpecialKey sp, boo::EModifierKey mod, b void Console::handleSpecialKeyUp(boo::ESpecialKey /*sp*/, boo::EModifierKey /*mod*/) {} -void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, const char* format, va_list ap) { - char tmp[2048]; - vsnprintf(tmp, 2048, format, ap); +void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, + fmt::string_view format, fmt::format_args args) { + auto tmp = fmt::internal::vformat(format, args); std::vector lines = athena::utility::split(tmp, '\n'); for (const std::string& line : lines) { - std::string v = athena::utility::sprintf("[%s] %s", modName, line.c_str()); + auto v = fmt::format(fmt("[%s] %s"), modName, line.c_str()); m_con->m_log.emplace_back(v, Console::Level(severity)); } } -void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, const wchar_t* format, - va_list ap) { - wchar_t tmp[2048]; - vswprintf(tmp, 2048, format, ap); +void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, + fmt::wstring_view format, fmt::wformat_args args) { + auto tmp = fmt::internal::vformat(format, args); std::vector lines = athena::utility::split(athena::utility::wideToUtf8(tmp), '\n'); for (const std::string& line : lines) { - std::string v = athena::utility::sprintf("[%s] %s", modName, line.c_str()); + auto v = fmt::format(fmt("[%s] %s"), modName, line.c_str()); m_con->m_log.emplace_back(v, Console::Level(severity)); } } void Console::LogVisorAdapter::reportSource(const char* modName, logvisor::Level severity, const char* file, - unsigned linenum, const char* format, va_list ap) { - char tmp[2048]; - vsnprintf(tmp, 2048, format, ap); - std::string v = athena::utility::sprintf("[%s] %s %s:%i", modName, tmp, file, linenum); + unsigned linenum, fmt::string_view format, fmt::format_args args) { + auto tmp = fmt::internal::vformat(format, args); + auto v = fmt::format(fmt("[%s] %s %s:%i"), modName, tmp, file, linenum); m_con->m_log.emplace_back(v, Console::Level(severity)); } void Console::LogVisorAdapter::reportSource(const char* modName, logvisor::Level severity, const char* file, - unsigned linenum, const wchar_t* format, va_list ap) { - wchar_t tmp[2048]; - vswprintf(tmp, 2048, format, ap); + unsigned linenum, fmt::wstring_view format, fmt::wformat_args args) { + auto tmp = fmt::internal::vformat(format, args); std::vector lines = athena::utility::split(athena::utility::wideToUtf8(tmp), '\n'); for (const std::string& line : lines) { - std::string v = athena::utility::sprintf("[%s] %s %s:%i", modName, line.c_str(), file, linenum); + auto v = fmt::format(fmt("[%s] %s %s:%i"), modName, line.c_str(), file, linenum); m_con->m_log.emplace_back(v, Console::Level(severity)); } } @@ -416,16 +404,16 @@ void Console::dumpLog() { for (const auto& l : m_log) { switch (l.second) { case Level::Info: - printf("%s\n", l.first.c_str()); + fmt::print(fmt("{}\n"), l.first); break; case Level::Warning: - printf("[Warning] %s\n", l.first.c_str()); + fmt::print(fmt("[Warning] {}\n"), l.first); break; case Level::Error: - printf("[ Error ] %s\n", l.first.c_str()); + fmt::print(fmt("[ Error ] {}\n"), l.first); break; case Level::Fatal: - printf("[ Fatal ] %s\n", l.first.c_str()); + fmt::print(fmt("[ Fatal ] {}\n"), l.first); break; } } diff --git a/hecl/lib/HumanizeNumber.cpp b/hecl/lib/HumanizeNumber.cpp index 33f7e502d..7a3b75905 100644 --- a/hecl/lib/HumanizeNumber.cpp +++ b/hecl/lib/HumanizeNumber.cpp @@ -48,7 +48,7 @@ std::string HumanizeNumber(int64_t quotient, size_t len, const char* suffix, int if (suffix == nullptr) suffix = ""; if ((flags & HNFlags::Divisor1000) != HNFlags::None && (flags & HNFlags::IECPrefixes) != HNFlags::None) - Log.report(logvisor::Fatal, "invalid flags combo"); + Log.report(logvisor::Fatal, fmt("invalid flags combo")); /* setup parameters */ remainder = 0; @@ -109,8 +109,7 @@ std::string HumanizeNumber(int64_t quotient, size_t len, const char* suffix, int /* Check if enough room for `x y' + suffix */ if (len < baselen) - Log.report(logvisor::Fatal, "buffer size %" PRISize "insufficient for minimum size %" PRISize, len, baselen); - std::string ret(len, '\0'); + Log.report(logvisor::Fatal, fmt("buffer size {} insufficient for minimum size {}"), len, baselen); len += 1; if ((scale & int(HNScale::AutoScale)) != 0) { @@ -143,12 +142,10 @@ std::string HumanizeNumber(int64_t quotient, size_t len, const char* suffix, int (flags & HNFlags::Decimal) != HNFlags::None) { s1 = (int)quotient + ((remainder * 10 + divisor / 2) / divisor / 10); s2 = ((remainder * 10 + divisor / 2) / divisor) % 10; - snprintf(&ret[0], len, "%d%s%d%s%s%s", sign * s1, localeconv()->decimal_point, s2, sep, SCALE2PREFIX(i), suffix); + return fmt::format(fmt("{}{}{}{}{}{}"), sign * s1, localeconv()->decimal_point, s2, sep, SCALE2PREFIX(i), suffix); } else - snprintf(&ret[0], len, "%" PRId64 "%s%s%s", sign * (quotient + (remainder + divisor / 2) / divisor), sep, - SCALE2PREFIX(i), suffix); - - return ret; + return fmt::format(fmt("{}{}{}{}"), sign * (quotient + (remainder + divisor / 2) / divisor), sep, + SCALE2PREFIX(i), suffix); } } // namespace hecl diff --git a/hecl/lib/MultiProgressPrinter.cpp b/hecl/lib/MultiProgressPrinter.cpp index 1308d1139..94208dd1e 100644 --- a/hecl/lib/MultiProgressPrinter.cpp +++ b/hecl/lib/MultiProgressPrinter.cpp @@ -2,7 +2,7 @@ #define BOLD "\033[1m" #define NORMAL "\033[0m" -#define PREV_LINE "\r\033[%dA" +#define PREV_LINE "\r\033[{:d}A" #define HIDE_CURSOR "\033[?25l" #define SHOW_CURSOR "\033[?25h" @@ -33,46 +33,46 @@ void MultiProgressPrinter::ThreadStat::print(const TermInfo& tinfo) const { if (submessageLen) { if (messageLen > half - submessageLen - 1) - hecl::Printf(_SYS_STR(" %.*s... %s "), half - submessageLen - 4, m_message.c_str(), m_submessage.c_str()); + fmt::print(fmt(_SYS_STR(" {:.{}}... {} ")), m_message, half - submessageLen - 4, m_submessage); else { - hecl::Printf(_SYS_STR(" %s"), m_message.c_str()); + fmt::print(fmt(_SYS_STR(" {}")), m_message); for (int i = half - messageLen - submessageLen - 1; i >= 0; --i) - hecl::Printf(_SYS_STR(" ")); - hecl::Printf(_SYS_STR("%s "), m_submessage.c_str()); + fmt::print(fmt(_SYS_STR(" "))); + fmt::print(fmt(_SYS_STR("{} ")), m_submessage); } } else { if (messageLen > half) - hecl::Printf(_SYS_STR(" %.*s... "), half - 3, m_message.c_str()); + fmt::print(fmt(_SYS_STR(" {:.{}}... ")), m_message, half - 3); else { - hecl::Printf(_SYS_STR(" %s"), m_message.c_str()); + fmt::print(fmt(_SYS_STR(" {}")), m_message); for (int i = half - messageLen; i >= 0; --i) - hecl::Printf(_SYS_STR(" ")); + fmt::print(fmt(_SYS_STR(" "))); } } if (blocks) { int rightHalf = tinfo.width - half - 4; - int blocks = rightHalf - 7; - int filled = blocks * factor; - int rem = blocks - filled; + int nblocks = rightHalf - 7; + int filled = nblocks * factor; + int rem = nblocks - filled; if (tinfo.xtermColor) { - hecl::Printf(_SYS_STR("" BOLD "%3d%% ["), iFactor); + fmt::print(fmt(_SYS_STR("" BOLD "{:3d}% [")), iFactor); for (int b = 0; b < filled; ++b) - hecl::Printf(_SYS_STR("#")); + fmt::print(fmt(_SYS_STR("#"))); for (int b = 0; b < rem; ++b) - hecl::Printf(_SYS_STR("-")); - hecl::Printf(_SYS_STR("]" NORMAL "")); + fmt::print(fmt(_SYS_STR("-"))); + fmt::print(fmt(_SYS_STR("]" NORMAL ""))); } else { #if _WIN32 SetConsoleTextAttribute(tinfo.console, FOREGROUND_INTENSITY | FOREGROUND_WHITE); #endif - hecl::Printf(_SYS_STR("%3d%% ["), iFactor); + fmt::print(fmt(_SYS_STR("{:3d}% [")), iFactor); for (int b = 0; b < filled; ++b) - hecl::Printf(_SYS_STR("#")); + fmt::print(fmt(_SYS_STR("#"))); for (int b = 0; b < rem; ++b) - hecl::Printf(_SYS_STR("-")); - hecl::Printf(_SYS_STR("]")); + fmt::print(fmt(_SYS_STR("-"))); + fmt::print(fmt(_SYS_STR("]"))); #if _WIN32 SetConsoleTextAttribute(tinfo.console, FOREGROUND_WHITE); #endif @@ -95,24 +95,24 @@ void MultiProgressPrinter::DrawIndeterminateBar() { int rem = blocks - pre - 1; if (m_termInfo.xtermColor) { - hecl::Printf(_SYS_STR("" BOLD " [")); + fmt::print(fmt(_SYS_STR("" BOLD " ["))); for (int b = 0; b < pre; ++b) - hecl::Printf(_SYS_STR("-")); - hecl::Printf(_SYS_STR("#")); + fmt::print(fmt(_SYS_STR("-"))); + fmt::print(fmt(_SYS_STR("#"))); for (int b = 0; b < rem; ++b) - hecl::Printf(_SYS_STR("-")); - hecl::Printf(_SYS_STR("]" NORMAL "")); + fmt::print(fmt(_SYS_STR("-"))); + fmt::print(fmt(_SYS_STR("]" NORMAL ""))); } else { #if _WIN32 SetConsoleTextAttribute(m_termInfo.console, FOREGROUND_INTENSITY | FOREGROUND_WHITE); #endif - hecl::Printf(_SYS_STR(" [")); + fmt::print(fmt(_SYS_STR(" ["))); for (int b = 0; b < pre; ++b) - hecl::Printf(_SYS_STR("-")); - hecl::Printf(_SYS_STR("#")); + fmt::print(fmt(_SYS_STR("-"))); + fmt::print(fmt(_SYS_STR("#"))); for (int b = 0; b < rem; ++b) - hecl::Printf(_SYS_STR("-")); - hecl::Printf(_SYS_STR("]")); + fmt::print(fmt(_SYS_STR("-"))); + fmt::print(fmt(_SYS_STR("]"))); #if _WIN32 SetConsoleTextAttribute(m_termInfo.console, FOREGROUND_WHITE); #endif @@ -122,7 +122,7 @@ void MultiProgressPrinter::DrawIndeterminateBar() { void MultiProgressPrinter::MoveCursorUp(int n) { if (n) { if (m_termInfo.xtermColor) { - hecl::Printf(_SYS_STR("" PREV_LINE ""), n); + fmt::print(fmt(_SYS_STR("" PREV_LINE "")), n); } #if _WIN32 else { @@ -134,7 +134,7 @@ void MultiProgressPrinter::MoveCursorUp(int n) { } #endif } else { - hecl::Printf(_SYS_STR("\r")); + fmt::print(fmt(_SYS_STR("\r"))); } } @@ -152,7 +152,7 @@ void MultiProgressPrinter::DoPrint() { SetConsoleCursorInfo(m_termInfo.console, &cursorInfo); #endif if (m_termInfo.xtermColor) - hecl::Printf(_SYS_STR("" HIDE_CURSOR "")); + fmt::print(fmt(_SYS_STR("" HIDE_CURSOR ""))); if (m_dirty) { m_termInfo.width = (hecl::GuiMode ? 120 : std::max(80, hecl::ConsoleWidth(&m_termInfo.truncate))); @@ -163,7 +163,7 @@ void MultiProgressPrinter::DoPrint() { for (const ThreadStat& stat : m_threadStats) { if (stat.m_active) { stat.print(m_termInfo); - hecl::Printf(_SYS_STR("\n")); + fmt::print(fmt(_SYS_STR("\n"))); ++m_curThreadLines; } } @@ -174,7 +174,7 @@ void MultiProgressPrinter::DoPrint() { #endif ) { DrawIndeterminateBar(); - hecl::Printf(_SYS_STR("\n")); + fmt::print(fmt(_SYS_STR("\n"))); ++m_curProgLines; } else if (m_mainFactor >= 0.f) { float factor = std::max(0.0f, std::min(1.0f, m_mainFactor)); @@ -186,34 +186,34 @@ void MultiProgressPrinter::DoPrint() { int rem = blocks - filled; if (m_termInfo.xtermColor) { - hecl::Printf(_SYS_STR("" BOLD " %3d%% ["), iFactor); + fmt::print(fmt(_SYS_STR("" BOLD " {:3d}% [")), iFactor); for (int b = 0; b < filled; ++b) - hecl::Printf(_SYS_STR("#")); + fmt::print(fmt(_SYS_STR("#"))); for (int b = 0; b < rem; ++b) - hecl::Printf(_SYS_STR("-")); - hecl::Printf(_SYS_STR("]" NORMAL "")); + fmt::print(fmt(_SYS_STR("-"))); + fmt::print(fmt(_SYS_STR("]" NORMAL ""))); } else { #if _WIN32 SetConsoleTextAttribute(m_termInfo.console, FOREGROUND_INTENSITY | FOREGROUND_WHITE); #endif - hecl::Printf(_SYS_STR(" %3d%% ["), iFactor); + fmt::print(fmt(_SYS_STR(" {:3d}% [")), iFactor); for (int b = 0; b < filled; ++b) - hecl::Printf(_SYS_STR("#")); + fmt::print(fmt(_SYS_STR("#"))); for (int b = 0; b < rem; ++b) - hecl::Printf(_SYS_STR("-")); - hecl::Printf(_SYS_STR("]")); + fmt::print(fmt(_SYS_STR("-"))); + fmt::print(fmt(_SYS_STR("]"))); #if _WIN32 SetConsoleTextAttribute(m_termInfo.console, FOREGROUND_WHITE); #endif } - hecl::Printf(_SYS_STR("\n")); + fmt::print(fmt(_SYS_STR("\n"))); ++m_curProgLines; } } else if (m_latestThread != -1) { const ThreadStat& stat = m_threadStats[m_latestThread]; stat.print(m_termInfo); - hecl::Printf(_SYS_STR("\r")); + fmt::print(fmt(_SYS_STR("\r"))); } m_dirty = false; } else if (m_mainIndeterminate @@ -225,12 +225,12 @@ void MultiProgressPrinter::DoPrint() { MoveCursorUp(m_curProgLines); m_curProgLines = 0; DrawIndeterminateBar(); - hecl::Printf(_SYS_STR("\n")); + fmt::print(fmt(_SYS_STR("\n"))); ++m_curProgLines; } if (m_termInfo.xtermColor) - hecl::Printf(_SYS_STR("" SHOW_CURSOR "")); + fmt::print(fmt(_SYS_STR("" SHOW_CURSOR ""))); fflush(stdout); #if _WIN32 @@ -331,7 +331,7 @@ void MultiProgressPrinter::startNewLine() const { m_curThreadLines = 0; m_mainFactor = -1.f; auto logLk = logvisor::LockLog(); - hecl::Printf(_SYS_STR("\n")); + fmt::print(fmt(_SYS_STR("\n"))); } void MultiProgressPrinter::flush() const { diff --git a/hecl/lib/Project.cpp b/hecl/lib/Project.cpp index 622515839..0eb788f67 100644 --- a/hecl/lib/Project.cpp +++ b/hecl/lib/Project.cpp @@ -23,7 +23,7 @@ static const hecl::FourCC HECLfcc("HECL"); * Project::ConfigFile **********************************************/ -static inline bool CheckNewLineAdvance(std::string::const_iterator& it) { +static bool CheckNewLineAdvance(std::string::const_iterator& it) { if (*it == '\n') { it += 1; return true; @@ -84,7 +84,7 @@ void Project::ConfigFile::addLine(std::string_view line) { void Project::ConfigFile::removeLine(std::string_view refLine) { if (!m_lockedFile) { - LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__, "Project::ConfigFile::lockAndRead not yet called"); + LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__, fmt("Project::ConfigFile::lockAndRead not yet called")); return; } @@ -99,7 +99,7 @@ void Project::ConfigFile::removeLine(std::string_view refLine) { bool Project::ConfigFile::checkForLine(std::string_view refLine) { if (!m_lockedFile) { - LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__, "Project::ConfigFile::lockAndRead not yet called"); + LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__, fmt("Project::ConfigFile::lockAndRead not yet called")); return false; } @@ -111,7 +111,7 @@ bool Project::ConfigFile::checkForLine(std::string_view refLine) { void Project::ConfigFile::unlockAndDiscard() { if (!m_lockedFile) { - LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__, "Project::ConfigFile::lockAndRead not yet called"); + LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__, fmt("Project::ConfigFile::lockAndRead not yet called")); return; } @@ -122,7 +122,7 @@ void Project::ConfigFile::unlockAndDiscard() { bool Project::ConfigFile::unlockAndCommit() { if (!m_lockedFile) { - LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__, "Project::ConfigFile::lockAndRead not yet called"); + LogModule.reportSource(logvisor::Fatal, __FILE__, __LINE__, fmt("Project::ConfigFile::lockAndRead not yet called")); return false; } @@ -176,13 +176,13 @@ Project::Project(const ProjectRootPath& rootPath) /* Stat for existing project directory (must already exist) */ Sstat myStat; if (hecl::Stat(m_rootPath.getAbsolutePath().data(), &myStat)) { - LogModule.report(logvisor::Error, _SYS_STR("unable to stat %s"), m_rootPath.getAbsolutePath().data()); + LogModule.report(logvisor::Error, fmt(_SYS_STR("unable to stat {}")), m_rootPath.getAbsolutePath()); return; } if (!S_ISDIR(myStat.st_mode)) { - LogModule.report(logvisor::Error, _SYS_STR("provided path must be a directory; '%s' isn't"), - m_rootPath.getAbsolutePath().data()); + LogModule.report(logvisor::Error, fmt(_SYS_STR("provided path must be a directory; '{}' isn't")), + m_rootPath.getAbsolutePath()); return; } @@ -206,7 +206,7 @@ Project::Project(const ProjectRootPath& rootPath) } fclose(bf); if (beacon.magic != HECLfcc || SBig(beacon.version) != DATA_VERSION) { - LogModule.report(logvisor::Fatal, "incompatible project version"); + LogModule.report(logvisor::Fatal, fmt("incompatible project version")); return; } @@ -219,7 +219,7 @@ const ProjectPath& Project::getProjectCookedPath(const DataSpecEntry& spec) cons for (const ProjectDataSpec& sp : m_compiledSpecs) if (&sp.spec == &spec) return sp.cookedPath; - LogModule.report(logvisor::Fatal, "Unable to find spec '%s'", spec.m_name.data()); + LogModule.report(logvisor::Fatal, fmt("Unable to find spec '{}'"), spec.m_name); return m_cookedRoot; } @@ -460,7 +460,7 @@ bool Project::packagePath(const ProjectPath& path, const hecl::MultiProgressPrin } if (!specEntry) - LogModule.report(logvisor::Fatal, "No matching DataSpec"); + LogModule.report(logvisor::Fatal, fmt("No matching DataSpec")); if (!m_lastPackageSpec || m_lastPackageSpec->getDataSpecEntry() != specEntry) m_lastPackageSpec = specEntry->m_factory(*this, DataSpecTool::Package); diff --git a/hecl/lib/ProjectPath.cpp b/hecl/lib/ProjectPath.cpp index 8dd024823..802946ed6 100644 --- a/hecl/lib/ProjectPath.cpp +++ b/hecl/lib/ProjectPath.cpp @@ -19,7 +19,7 @@ static SystemString CanonRelPath(SystemStringView path) { else if (!match.compare(_SYS_STR(".."))) { if (comps.empty()) { /* Unable to resolve outside project */ - LogModule.report(logvisor::Fatal, _SYS_STR("Unable to resolve outside project root in %s"), path.data()); + LogModule.report(logvisor::Fatal, fmt(_SYS_STR("Unable to resolve outside project root in {}")), path); return _SYS_STR("."); } comps.pop_back(); @@ -180,7 +180,7 @@ Time ProjectPath::getModtime() const { return Time(latestTime); } } - LogModule.report(logvisor::Fatal, _SYS_STR("invalid path type for computing modtime in '%s'"), m_absPath.c_str()); + LogModule.report(logvisor::Fatal, fmt(_SYS_STR("invalid path type for computing modtime in '{}'")), m_absPath); return Time(); } diff --git a/hecl/lib/Runtime/FileStoreManager.cpp b/hecl/lib/Runtime/FileStoreManager.cpp index 6889cb10c..2cb2a9760 100644 --- a/hecl/lib/Runtime/FileStoreManager.cpp +++ b/hecl/lib/Runtime/FileStoreManager.cpp @@ -16,7 +16,7 @@ FileStoreManager::FileStoreManager(SystemStringView domain) : m_domain(domain) { #if !WINDOWS_STORE WCHAR home[MAX_PATH]; if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, home))) - Log.report(logvisor::Fatal, _SYS_STR("unable to locate profile for file store")); + Log.report(logvisor::Fatal, fmt(_SYS_STR("unable to locate profile for file store"))); SystemString path(home); #else @@ -34,15 +34,15 @@ FileStoreManager::FileStoreManager(SystemStringView domain) : m_domain(domain) { #else const char* home = getenv("HOME"); if (!home) - Log.report(logvisor::Fatal, "unable to locate $HOME for file store"); + Log.report(logvisor::Fatal, fmt("unable to locate $HOME for file store")); std::string path(home); path += "/.heclrun"; if (mkdir(path.c_str(), 0755) && errno != EEXIST) - Log.report(logvisor::Fatal, "unable to mkdir at %s", path.c_str()); + Log.report(logvisor::Fatal, fmt("unable to mkdir at {}"), path); path += '/'; path += domain.data(); if (mkdir(path.c_str(), 0755) && errno != EEXIST) - Log.report(logvisor::Fatal, "unable to mkdir at %s", path.c_str()); + Log.report(logvisor::Fatal, fmt("unable to mkdir at {}"), path); m_storeRoot = path; #endif } diff --git a/hecl/lib/Runtime/HMDL_RT.cpp b/hecl/lib/Runtime/HMDL_RT.cpp index f69388324..05295c3e0 100644 --- a/hecl/lib/Runtime/HMDL_RT.cpp +++ b/hecl/lib/Runtime/HMDL_RT.cpp @@ -12,7 +12,7 @@ HMDLData::HMDLData(boo::IGraphicsDataFactory::Context& ctx, const void* metaData meta.read(r); } if (meta.magic != 'TACO') - HMDL_Log.report(logvisor::Fatal, "invalid HMDL magic"); + HMDL_Log.report(logvisor::Fatal, fmt("invalid HMDL magic")); m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, vbo, meta.vertStride, meta.vertCount); m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, ibo, 4, meta.indexCount); diff --git a/hecl/lib/WideStringConvert.cpp b/hecl/lib/WideStringConvert.cpp index e9e46d336..8572b2dde 100644 --- a/hecl/lib/WideStringConvert.cpp +++ b/hecl/lib/WideStringConvert.cpp @@ -11,7 +11,7 @@ std::string WideToUTF8(std::wstring_view src) { utf8proc_uint8_t mb[4]; utf8proc_ssize_t c = utf8proc_encode_char(utf8proc_int32_t(ch), mb); if (c < 0) { - Log.report(logvisor::Warning, "invalid UTF-8 character while encoding"); + Log.report(logvisor::Warning, fmt("invalid UTF-8 character while encoding")); return retval; } retval.append(reinterpret_cast(mb), c); @@ -26,7 +26,7 @@ std::string Char16ToUTF8(std::u16string_view src) { utf8proc_uint8_t mb[4]; utf8proc_ssize_t c = utf8proc_encode_char(utf8proc_int32_t(ch), mb); if (c < 0) { - Log.report(logvisor::Warning, "invalid UTF-8 character while encoding"); + Log.report(logvisor::Warning, fmt("invalid UTF-8 character while encoding")); return retval; } retval.append(reinterpret_cast(mb), c); @@ -42,7 +42,7 @@ std::wstring UTF8ToWide(std::string_view src) { utf8proc_int32_t wc; utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc); if (len < 0) { - Log.report(logvisor::Warning, "invalid UTF-8 character while decoding"); + Log.report(logvisor::Warning, fmt("invalid UTF-8 character while decoding")); return retval; } buf += len; @@ -59,7 +59,7 @@ std::u16string UTF8ToChar16(std::string_view src) { utf8proc_int32_t wc; utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc); if (len < 0) { - Log.report(logvisor::Warning, "invalid UTF-8 character while decoding"); + Log.report(logvisor::Warning, fmt("invalid UTF-8 character while decoding")); return retval; } buf += len; diff --git a/hecl/lib/hecl.cpp b/hecl/lib/hecl.cpp index d4cc0eb25..39625ca1b 100644 --- a/hecl/lib/hecl.cpp +++ b/hecl/lib/hecl.cpp @@ -26,58 +26,6 @@ bool GuiMode = false; logvisor::Module LogModule("hecl"); static const std::string Illegals{"<>?\""}; -#if __GNUC__ -__attribute__((__format__(__printf__, 1, 2))) -#endif -SystemString -SysFormat(const SystemChar* format, ...) { - SystemChar resultBuf[FORMAT_BUF_SZ]; - va_list va; - va_start(va, format); -#if HECL_UCS2 - int printSz = vswprintf(resultBuf, FORMAT_BUF_SZ, format, va); -#else - int printSz = vsnprintf(resultBuf, FORMAT_BUF_SZ, format, va); -#endif - va_end(va); - return SystemString(resultBuf, printSz); -} - -#if __GNUC__ -__attribute__((__format__(__printf__, 1, 2))) -#endif -std::string -Format(const char* format, ...) { - char resultBuf[FORMAT_BUF_SZ]; - va_list va; - va_start(va, format); - int printSz = vsnprintf(resultBuf, FORMAT_BUF_SZ, format, va); - va_end(va); - return std::string(resultBuf, printSz); -} - -std::wstring WideFormat(const wchar_t* format, ...) { - wchar_t resultBuf[FORMAT_BUF_SZ]; - va_list va; - va_start(va, format); - int printSz = vswprintf(resultBuf, FORMAT_BUF_SZ, format, va); - va_end(va); - return std::wstring(resultBuf, printSz); -} - -std::u16string Char16Format(const wchar_t* format, ...) { - wchar_t resultBuf[FORMAT_BUF_SZ]; - va_list va; - va_start(va, format); - size_t printSz = vswprintf(resultBuf, FORMAT_BUF_SZ, format, va); - va_end(va); - std::u16string res; - res.reserve(printSz); - for (size_t i = 0; i < printSz; ++i) - res.push_back(resultBuf[i]); - return res; -} - void SanitizePath(std::string& path) { if (path.empty()) return; @@ -146,7 +94,7 @@ SystemString GetcwdStr() { return SystemString(stackBuffer); if (errno != ERANGE) { // It's not ERANGE, so we don't know how to handle it - LogModule.report(logvisor::Fatal, "Cannot determine the current path."); + LogModule.report(logvisor::Fatal, fmt("Cannot determine the current path.")); // Of course you may choose a different error reporting method } // Ok, the stack buffer isn't long enough; fallback to heap allocation @@ -158,11 +106,11 @@ SystemString GetcwdStr() { return SystemString(cwd.get()); if (errno != ERANGE) { // It's not ERANGE, so we don't know how to handle it - LogModule.report(logvisor::Fatal, "Cannot determine the current path."); + LogModule.report(logvisor::Fatal, fmt("Cannot determine the current path.")); // Of course you may choose a different error reporting method } } - LogModule.report(logvisor::Fatal, "Cannot determine the current path; the path is apparently unreasonably long"); + LogModule.report(logvisor::Fatal, fmt("Cannot determine the current path; the path is apparently unreasonably long")); return SystemString(); } @@ -180,7 +128,7 @@ bool ResourceLock::InProgress(const ProjectPath& path) { bool ResourceLock::SetThreadRes(const ProjectPath& path) { std::unique_lock lk(PathsMutex); if (PathsInProgress.find(std::this_thread::get_id()) != PathsInProgress.cend()) - LogModule.report(logvisor::Fatal, "multiple resource locks on thread"); + LogModule.report(logvisor::Fatal, fmt("multiple resource locks on thread")); for (const auto& p : PathsInProgress) if (p.second == path) @@ -752,13 +700,13 @@ int RunProcess(const SystemChar* path, const SystemChar* const args[]) { SECURITY_ATTRIBUTES sattrs = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; HANDLE consoleOutReadTmp, consoleOutWrite, consoleErrWrite, consoleOutRead; if (!CreatePipe(&consoleOutReadTmp, &consoleOutWrite, &sattrs, 0)) { - LogModule.report(logvisor::Fatal, "Error with CreatePipe"); + LogModule.report(logvisor::Fatal, fmt("Error with CreatePipe")); return -1; } if (!DuplicateHandle(GetCurrentProcess(), consoleOutWrite, GetCurrentProcess(), &consoleErrWrite, 0, TRUE, DUPLICATE_SAME_ACCESS)) { - LogModule.report(logvisor::Fatal, "Error with DuplicateHandle"); + LogModule.report(logvisor::Fatal, fmt("Error with DuplicateHandle")); CloseHandle(consoleOutReadTmp); CloseHandle(consoleOutWrite); return -1; @@ -768,7 +716,7 @@ int RunProcess(const SystemChar* path, const SystemChar* const args[]) { &consoleOutRead, // Address of new handle. 0, FALSE, // Make it uninheritable. DUPLICATE_SAME_ACCESS)) { - LogModule.report(logvisor::Fatal, "Error with DupliateHandle"); + LogModule.report(logvisor::Fatal, fmt("Error with DupliateHandle")); CloseHandle(consoleOutReadTmp); CloseHandle(consoleOutWrite); CloseHandle(consoleErrWrite); @@ -825,13 +773,13 @@ int RunProcess(const SystemChar* path, const SystemChar* const args[]) { if (err == ERROR_BROKEN_PIPE) break; // pipe done - normal exit path. else - LogModule.report(logvisor::Error, "Error with ReadFile: %08X", err); // Something bad happened. + LogModule.report(logvisor::Error, fmt("Error with ReadFile: %08X"), err); // Something bad happened. } // Display the character read on the screen. auto lk = logvisor::LockLog(); if (!WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), lpBuffer, nBytesRead, &nCharsWritten, NULL)) { - // LogModule.report(logvisor::Error, "Error with WriteConsole: %08X", GetLastError()); + // LogModule.report(logvisor::Error, fmt("Error with WriteConsole: %08X"), GetLastError()); } } diff --git a/hecl/shaderc/main.cpp b/hecl/shaderc/main.cpp index f05ab372a..a31cd9aaa 100644 --- a/hecl/shaderc/main.cpp +++ b/hecl/shaderc/main.cpp @@ -3,6 +3,7 @@ #include "athena/FileWriter.hpp" #include "glslang/Public/ShaderLang.h" #include "hecl/hecl.hpp" +#include static logvisor::Module Log("shaderc"); @@ -42,13 +43,13 @@ int main(int argc, const hecl::SystemChar** argv) #if _WIN32 if (!FindBestD3DCompile()) { - Log.report(logvisor::Info, "Unable to find D3DCompiler dll"); + Log.report(logvisor::Info, fmt("Unable to find D3DCompiler dll")); return 1; } #endif if (argc == 1) { - Log.report(logvisor::Info, "Usage: shaderc -o [-D definevar=defineval]... ..."); + Log.report(logvisor::Info, fmt("Usage: shaderc -o [-D definevar=defineval]... ...")); return 0; } @@ -63,7 +64,7 @@ int main(int argc, const hecl::SystemChar** argv) ++i; outPath = argv[i]; } else { - Log.report(logvisor::Error, "Invalid -o argument"); + Log.report(logvisor::Error, fmt("Invalid -o argument")); return 1; } } else if (argv[i][1] == 'D') { @@ -74,7 +75,7 @@ int main(int argc, const hecl::SystemChar** argv) ++i; define = argv[i]; } else { - Log.report(logvisor::Error, "Invalid -D argument"); + Log.report(logvisor::Error, fmt("Invalid -D argument")); return 1; } hecl::SystemUTF8Conv conv(define); @@ -84,7 +85,7 @@ int main(int argc, const hecl::SystemChar** argv) else c.addDefine(defineU8, ""); } else { - Log.report(logvisor::Error, "Unrecognized flag option '%c'", argv[i][1]); + Log.report(logvisor::Error, fmt("Unrecognized flag option '{:c}'"), argv[i][1]); return 1; } } else { @@ -93,7 +94,7 @@ int main(int argc, const hecl::SystemChar** argv) } if (outPath.empty()) { - Log.report(logvisor::Error, "-o option is required"); + Log.report(logvisor::Error, fmt("-o option is required")); return 1; } @@ -105,12 +106,12 @@ int main(int argc, const hecl::SystemChar** argv) baseName = outPath; if (!glslang::InitializeProcess()) { - Log.report(logvisor::Error, "Unable to initialize glslang"); + Log.report(logvisor::Error, fmt("Unable to initialize glslang")); return 1; } hecl::SystemUTF8Conv conv(baseName); - std::pair ret; + std::pair ret; if (!c.compile(conv.str(), ret)) return 1; @@ -118,20 +119,22 @@ int main(int argc, const hecl::SystemChar** argv) hecl::SystemString headerPath = outPath + _SYS_STR(".hpp"); athena::io::FileWriter w(headerPath); if (w.hasError()) { - Log.report(logvisor::Error, _SYS_STR("Error opening '%s' for writing"), headerPath.c_str()); + Log.report(logvisor::Error, fmt(_SYS_STR("Error opening '{}' for writing")), headerPath); return 1; } - w.writeBytes(ret.first.data(), ret.first.size()); + std::string header = ret.first.str(); + w.writeBytes(header.data(), header.size()); } { hecl::SystemString impPath = outPath + _SYS_STR(".cpp"); athena::io::FileWriter w(impPath); if (w.hasError()) { - Log.report(logvisor::Error, _SYS_STR("Error opening '%s' for writing"), impPath.c_str()); + Log.report(logvisor::Error, fmt(_SYS_STR("Error opening '{}' for writing")), impPath); return 1; } - w.writeBytes(ret.second.data(), ret.second.size()); + std::string source = ret.second.str(); + w.writeBytes(source.data(), source.size()); } return 0; diff --git a/hecl/shaderc/shaderc.cpp b/hecl/shaderc/shaderc.cpp index a2f149974..bddec62d1 100644 --- a/hecl/shaderc/shaderc.cpp +++ b/hecl/shaderc/shaderc.cpp @@ -10,26 +10,15 @@ #include #include #include +#include +#include using namespace std::literals; namespace hecl::shaderc { static logvisor::Module Log("shaderc"); -static constexpr std::regex::flag_type RegexFlags = std::regex::ECMAScript | std::regex::optimize; - -#if __GNUC__ -__attribute__((__format__(__printf__, 1, 2))) -#endif -static std::string -Format(const char* format, ...) { - char resultBuf[FORMAT_BUF_SZ]; - va_list va; - va_start(va, format); - int printSz = vsnprintf(resultBuf, FORMAT_BUF_SZ, format, va); - va_end(va); - return std::string(resultBuf, printSz); -} +constexpr std::regex::flag_type RegexFlags = std::regex::ECMAScript | std::regex::optimize; static const char* StageNames[] = { "hecl::PipelineStage::Vertex", @@ -59,41 +48,41 @@ void Compiler::addInputFile(SystemStringView file) { void Compiler::addDefine(std::string_view var, std::string_view val) { m_defines[var.data()] = val; } -static const char* ShaderHeaderTemplate = - "class Shader_%s : public hecl::GeneralShader\n" - "{\n" +constexpr auto ShaderHeaderTemplate = fmt( + "class Shader_{} : public hecl::GeneralShader\n" + "{{\n" "public:\n" " static const boo::VertexFormatInfo VtxFmt;\n" " static const boo::AdditionalPipelineInfo PipelineInfo;\n" " static constexpr bool HasHash = true;\n" - " static constexpr uint64_t Hash() { return 0x%016llX; }\n" + " static constexpr uint64_t Hash() {{ return 0x{:016X}; }}\n" " static constexpr bool HasStageHash = true;\n" " template \n" " static constexpr uint64_t StageHash();\n" - "};\n\n"; + "}};\n\n"); -static const char* StageObjectHeaderTemplate = +constexpr auto StageObjectHeaderTemplate = fmt( "template\n" - "class StageObject_%s : public hecl::StageBinary\n" - "{\n" + "class StageObject_{} : public hecl::StageBinary\n" + "{{\n" " static const hecl::StageBinary Prototype;\n" "public:\n" - " StageObject_%s(hecl::StageConverter& conv, hecl::FactoryCtx& ctx, const Shader_%s& in)\n" - " : hecl::StageBinary(Prototype) {}\n" - "};\n" - "STAGEOBJECT_PROTOTYPE_DECLARATIONS(StageObject_%s)\n\n"; + " StageObject_{}(hecl::StageConverter& conv, hecl::FactoryCtx& ctx, const Shader_{}& in)\n" + " : hecl::StageBinary(Prototype) {{}}\n" + "}};\n" + "STAGEOBJECT_PROTOTYPE_DECLARATIONS(StageObject_{})\n\n"); -static const char* StageObjectImplTemplate = +constexpr auto StageObjectImplTemplate = fmt( "template<>\n" - "const hecl::StageBinary\n" - "StageObject_%s::Prototype = \n" - "{%s_%s_%s_data, sizeof(%s_%s_%s_data)};\n\n"; + "const hecl::StageBinary\n" + "StageObject_{}::Prototype = \n" + "{{{}_{}_{}_data, sizeof({}_{}_{}_data)}};\n\n"); struct CompileSubStageAction { template - static bool Do(const std::string& name, const std::string& basename, const std::string& stage, std::string& implOut) { - implOut += Format(StageObjectImplTemplate, P::Name, S::Name, name.c_str(), P::Name, S::Name, basename.c_str(), - P::Name, S::Name, basename.c_str(), P::Name, S::Name); + static bool Do(const std::string& name, const std::string& basename, const std::string& stage, std::stringstream& out) { + fmt::print(out, StageObjectImplTemplate, P::Name, S::Name, name, P::Name, S::Name, basename, + P::Name, S::Name, basename, P::Name, S::Name); return true; } @@ -101,21 +90,21 @@ struct CompileSubStageAction { struct CompileStageAction { template - static bool Do(const std::string& name, const std::string& basename, const std::string& stage, std::string& implOut) { + static bool Do(const std::string& name, const std::string& basename, const std::string& stage, std::stringstream& out) { std::pair data = CompileShader(stage); if (data.second == 0) return false; - implOut += Format("static const uint8_t %s_%s_%s_data[] = {\n", name.c_str(), P::Name, S::Name); + fmt::print(out, fmt("static const uint8_t {}_{}_{}_data[] = {{\n"), name, P::Name, S::Name); for (size_t i = 0; i < data.second;) { - implOut += " "; + out << " "; for (int j = 0; j < 10 && i < data.second; ++i, ++j) - implOut += Format("0x%02X, ", data.first.get()[i]); - implOut += "\n"; + fmt::print(out, fmt("0x{:02X}, "), data.first.get()[i]); + out << "\n"; } - implOut += "};\n\n"; - implOut += Format(StageObjectImplTemplate, P::Name, S::Name, name.c_str(), P::Name, S::Name, name.c_str(), P::Name, - S::Name, name.c_str(), P::Name, S::Name); + out << "};\n\n"; + fmt::print(out, StageObjectImplTemplate, P::Name, S::Name, name, P::Name, S::Name, name, + P::Name, S::Name, name, P::Name, S::Name); return true; } @@ -123,7 +112,7 @@ struct CompileStageAction { template bool Compiler::StageAction(StageType type, const std::string& name, const std::string& basename, - const std::string& stage, std::string& implOut) { + const std::string& stage, std::stringstream& implOut) { switch (type) { case StageType::Vertex: return Action::template Do(name, basename, stage, implOut); @@ -138,7 +127,7 @@ bool Compiler::StageAction(StageType type, const std::string& name, const std::s default: break; } - Log.report(logvisor::Error, "Unknown stage type"); + Log.report(logvisor::Error, fmt("Unknown stage type")); return false; } @@ -146,7 +135,7 @@ static const std::regex regWord(R"((\w+))", RegexFlags); template bool Compiler::StageAction(const std::string& platforms, StageType type, const std::string& name, - const std::string& basename, const std::string& stage, std::string& implOut) { + const std::string& basename, const std::string& stage, std::stringstream& implOut) { std::smatch match; auto begin = platforms.cbegin(); auto end = platforms.cend(); @@ -183,7 +172,7 @@ bool Compiler::StageAction(const std::string& platforms, StageType type, const s return false; #endif } else { - Log.report(logvisor::Error, "Unknown platform '%s'", plat.c_str()); + Log.report(logvisor::Error, fmt("Unknown platform '{}'"), plat); return false; } begin = match.suffix().first; @@ -219,13 +208,13 @@ static const std::regex regEvaluation(R"(#\s*evaluation\s+(.*))", RegexFlags); bool Compiler::includeFile(SystemStringView file, std::string& out, int depth) { if (depth > 32) { - Log.report(logvisor::Error, _SYS_STR("Too many levels of includes (>32) at '%s'"), file.data()); + Log.report(logvisor::Error, fmt(_SYS_STR("Too many levels of includes (>32) at '{}'")), file); return false; } const std::string* data = getFileContents(file); if (!data) { - Log.report(logvisor::Error, _SYS_STR("Unable to access '%s'"), file.data()); + Log.report(logvisor::Error, fmt(_SYS_STR("Unable to access '{}'")), file); return false; } const std::string& sdata = *data; @@ -251,7 +240,7 @@ bool Compiler::includeFile(SystemStringView file, std::string& out, int depth) { if (std::regex_search(begin, nextBegin, subMatch, regInclude)) { std::string path = subMatch[1].str(); if (path.empty()) { - Log.report(logvisor::Error, _SYS_STR("Empty path provided to include in '%s'"), file.data()); + Log.report(logvisor::Error, fmt(_SYS_STR("Empty path provided to include in '{}'")), file); return false; } @@ -269,7 +258,7 @@ bool Compiler::includeFile(SystemStringView file, std::string& out, int depth) { return true; } -static std::string_view BlendFactorToStr(boo::BlendFactor fac) { +constexpr std::string_view BlendFactorToStr(boo::BlendFactor fac) { switch (fac) { case boo::BlendFactor::Zero: default: @@ -301,7 +290,7 @@ static std::string_view BlendFactorToStr(boo::BlendFactor fac) { } } -static bool StrToBlendFactor(std::string str, boo::BlendFactor& fac) { +inline bool StrToBlendFactor(std::string str, boo::BlendFactor& fac) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); if (str == "zero") fac = boo::BlendFactor::Zero; @@ -330,13 +319,13 @@ static bool StrToBlendFactor(std::string str, boo::BlendFactor& fac) { else if (str == "subtract") fac = boo::BlendFactor::Subtract; else { - Log.report(logvisor::Error, "Unrecognized blend mode '%s'", str.c_str()); + Log.report(logvisor::Error, fmt("Unrecognized blend mode '{}'"), str); return false; } return true; } -static std::string_view PrimitiveToStr(boo::Primitive prim) { +constexpr std::string_view PrimitiveToStr(boo::Primitive prim) { switch (prim) { case boo::Primitive::Triangles: default: @@ -348,7 +337,7 @@ static std::string_view PrimitiveToStr(boo::Primitive prim) { } } -static bool StrToPrimitive(std::string str, boo::Primitive& prim) { +inline bool StrToPrimitive(std::string str, boo::Primitive& prim) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); if (str == "triangles") prim = boo::Primitive::Triangles; @@ -357,13 +346,13 @@ static bool StrToPrimitive(std::string str, boo::Primitive& prim) { else if (str == "patches") prim = boo::Primitive::Patches; else { - Log.report(logvisor::Error, "Unrecognized primitive '%s'", str.c_str()); + Log.report(logvisor::Error, fmt("Unrecognized primitive '{}'"), str); return false; } return true; } -static std::string_view ZTestToStr(boo::ZTest ztest) { +constexpr std::string_view ZTestToStr(boo::ZTest ztest) { switch (ztest) { case boo::ZTest::None: default: @@ -379,7 +368,7 @@ static std::string_view ZTestToStr(boo::ZTest ztest) { } } -static bool StrToZTest(std::string str, boo::ZTest& ztest) { +inline bool StrToZTest(std::string str, boo::ZTest& ztest) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); if (str == "none") ztest = boo::ZTest::None; @@ -392,13 +381,13 @@ static bool StrToZTest(std::string str, boo::ZTest& ztest) { else if (str == "equal") ztest = boo::ZTest::Equal; else { - Log.report(logvisor::Error, "Unrecognized ztest '%s'", str.c_str()); + Log.report(logvisor::Error, fmt("Unrecognized ztest '{}'"), str); return false; } return true; } -static std::string_view CullModeToStr(boo::CullMode cull) { +constexpr std::string_view CullModeToStr(boo::CullMode cull) { switch (cull) { case boo::CullMode::None: default: @@ -410,7 +399,7 @@ static std::string_view CullModeToStr(boo::CullMode cull) { } } -static bool StrToCullMode(std::string str, boo::CullMode& cull) { +inline bool StrToCullMode(std::string str, boo::CullMode& cull) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); if (str == "none") cull = boo::CullMode::None; @@ -419,15 +408,15 @@ static bool StrToCullMode(std::string str, boo::CullMode& cull) { else if (str == "frontface") cull = boo::CullMode::Frontface; else { - Log.report(logvisor::Error, "Unrecognized cull mode '%s'", str.c_str()); + Log.report(logvisor::Error, fmt("Unrecognized cull mode '{}'"), str); return false; } return true; } -static std::string_view BoolToStr(bool b) { return b ? "true"sv : "false"sv; } +constexpr std::string_view BoolToStr(bool b) { return b ? "true"sv : "false"sv; } -static bool StrToBool(std::string str, bool& b) { +inline bool StrToBool(std::string str, bool& b) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); if (strtol(str.c_str(), nullptr, 0)) b = true; @@ -436,13 +425,24 @@ static bool StrToBool(std::string str, bool& b) { else if (str == "false") b = false; else { - Log.report(logvisor::Error, "Unrecognized bool '%s'", str.c_str()); + Log.report(logvisor::Error, fmt("Unrecognized bool '{}'"), str); return false; } return true; } -bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std::pair& out) { +template +constexpr void SemanticOut(std::stringstream& out, + const std::pair& attr, const Format& fmtstr) { + fmt::print(out, fmtstr, + True(attr.first & boo::VertexSemantic::Instanced) + ? " | boo::VertexSemantic::Instanced" + : "", + attr.second); +} + +bool Compiler::compileFile(SystemStringView file, std::string_view baseName, + std::pair& out) { std::string includesPass; if (!includeFile(file, includesPass)) return false; @@ -469,7 +469,7 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std return true; if (shaderName.empty()) { - Log.report(logvisor::Error, "`#shader ` must be issued before stages"); + Log.report(logvisor::Error, fmt("`#shader ` must be issued before stages")); return false; } std::string stage(stageBegin, stageEnd); @@ -503,9 +503,8 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std if (uses.stages.test(5)) return true; - out.first += Format(ShaderHeaderTemplate, shaderName.c_str(), XXH64(shaderName.c_str(), shaderName.size(), 0)); - out.first += Format(StageObjectHeaderTemplate, shaderName.c_str(), shaderName.c_str(), shaderName.c_str(), - shaderName.c_str()); + fmt::print(out.first, ShaderHeaderTemplate, shaderName, XXH64(shaderName.c_str(), shaderName.size(), 0)); + fmt::print(out.first, StageObjectHeaderTemplate, shaderName, shaderName, shaderName, shaderName); if (!shaderBase.empty()) { shaderBases[shaderName] = shaderBase; @@ -534,76 +533,70 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std shaderBase.clear(); } - out.second += Format("static const boo::VertexElementDescriptor %s_vtxfmtelems[] = {\n", shaderName.c_str()); + fmt::print(out.second, fmt("static const boo::VertexElementDescriptor {}_vtxfmtelems[] = {{\n"), shaderName); for (const auto& attr : shaderAttributes) { - const char* fmt; switch (attr.first & boo::VertexSemantic::SemanticMask) { case boo::VertexSemantic::Position3: - fmt = "{boo::VertexSemantic::Position3%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::Position3{}, {}}},\n")); break; case boo::VertexSemantic::Position4: - fmt = "{boo::VertexSemantic::Position4%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::Position4{}, {}}},\n")); break; case boo::VertexSemantic::Normal3: - fmt = "{boo::VertexSemantic::Normal3%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::Normal3{}, {}}},\n")); break; case boo::VertexSemantic::Normal4: - fmt = "{boo::VertexSemantic::Normal4%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::Normal4{}, {}}},\n")); break; case boo::VertexSemantic::Color: - fmt = "{boo::VertexSemantic::Color%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::Color{}, {}}},\n")); break; case boo::VertexSemantic::ColorUNorm: - fmt = "{boo::VertexSemantic::ColorUNorm%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::ColorUNorm{}, {}}},\n")); break; case boo::VertexSemantic::UV2: - fmt = "{boo::VertexSemantic::UV2%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::UV2{}, {}}},\n")); break; case boo::VertexSemantic::UV4: - fmt = "{boo::VertexSemantic::UV4%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::UV4{}, {}}},\n")); break; case boo::VertexSemantic::Weight: - fmt = "{boo::VertexSemantic::Weight%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::Weight{}, {}}},\n")); break; case boo::VertexSemantic::ModelView: - fmt = "{boo::VertexSemantic::ModelView%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::ModelView{}, {}}},\n")); break; default: - fmt = "{boo::VertexSemantic::None%s, %d},\n"; + SemanticOut(out.second, attr, fmt("{{boo::VertexSemantic::None{}, {}}},\n")); break; } - out.second += Format(fmt, - True(attr.first & boo::VertexSemantic::Instanced) - ? " | boo::VertexSemantic::Instanced" - : "", - attr.second); } - out.second += "};\n"; - out.second += Format("const boo::VertexFormatInfo Shader_%s::VtxFmt = { %s_vtxfmtelems };\n\n", shaderName.c_str(), - shaderName.c_str()); - out.second += Format("const boo::AdditionalPipelineInfo Shader_%s::PipelineInfo = {\n", shaderName.c_str()); - out.second += BlendFactorToStr(shaderInfo.srcFac); - out.second += ", "; - out.second += BlendFactorToStr(shaderInfo.dstFac); - out.second += ", "; - out.second += PrimitiveToStr(shaderInfo.prim); - out.second += ", "; - out.second += ZTestToStr(shaderInfo.depthTest); - out.second += ",\n"; - out.second += BoolToStr(shaderInfo.depthWrite); - out.second += ", "; - out.second += BoolToStr(shaderInfo.colorWrite); - out.second += ", "; - out.second += BoolToStr(shaderInfo.alphaWrite); - out.second += ", "; - out.second += CullModeToStr(shaderInfo.culling); - out.second += ", "; - out.second += Format("%d, ", shaderInfo.patchSize); - out.second += BoolToStr(shaderInfo.overwriteAlpha); - out.second += ", "; - out.second += BoolToStr(shaderInfo.depthAttachment); - out.second += ", "; - out.second += "};\n\n"; + out.second << "};\n"; + fmt::print(out.second, fmt("const boo::VertexFormatInfo Shader_{}::VtxFmt = {{ {}_vtxfmtelems }};\n\n"), + shaderName, shaderName); + fmt::print(out.second, fmt("const boo::AdditionalPipelineInfo Shader_{}::PipelineInfo = {{\n"), shaderName); + out.second << BlendFactorToStr(shaderInfo.srcFac); + out.second << ", "; + out.second << BlendFactorToStr(shaderInfo.dstFac); + out.second << ", "; + out.second << PrimitiveToStr(shaderInfo.prim); + out.second << ", "; + out.second << ZTestToStr(shaderInfo.depthTest); + out.second << ",\n"; + out.second << BoolToStr(shaderInfo.depthWrite); + out.second << ", "; + out.second << BoolToStr(shaderInfo.colorWrite); + out.second << ", "; + out.second << BoolToStr(shaderInfo.alphaWrite); + out.second << ", "; + out.second << CullModeToStr(shaderInfo.culling); + out.second << ", "; + fmt::print(out.second, fmt("{}, "), shaderInfo.patchSize); + out.second << BoolToStr(shaderInfo.overwriteAlpha); + out.second << ", "; + out.second << BoolToStr(shaderInfo.depthAttachment); + out.second << ", "; + out.second << "};\n\n"; uses.stages.set(5); @@ -638,7 +631,7 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std else if (semantic == "modelview") shaderAttributes.push_back(std::make_pair(boo::VertexSemantic::ModelView | orsem, idxNum)); else { - Log.report(logvisor::Error, "Unrecognized vertex semantic '%s'", semantic.c_str()); + Log.report(logvisor::Error, fmt("Unrecognized vertex semantic '{}'"), semantic); return false; } return true; @@ -736,7 +729,7 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std char* endptr; shaderInfo.patchSize = uint32_t(strtoul(str.c_str(), &endptr, 0)); if (endptr == str.c_str()) { - Log.report(logvisor::Error, "Non-unsigned-integer value for #patchsize directive"); + Log.report(logvisor::Error, fmt("Non-unsigned-integer value for #patchsize directive")); return false; } } else if (std::regex_search(begin, nextBegin, subMatch, regOverwriteAlpha)) { @@ -772,42 +765,42 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std for (const auto& shader : shaderStageUses) { for (int i = 0; i < 5; ++i) { if (shader.second.stageHashes[i]) { - out.first += "template <> constexpr uint64_t Shader_"; - out.first += shader.first; - out.first += Format("::StageHash<%s>() { return 0x%016llX; }\n", StageNames[i], shader.second.stageHashes[i]); + out.first << "template <> constexpr uint64_t Shader_"; + out.first << shader.first; + fmt::print(out.first, fmt("::StageHash<{}>() {{ return 0x{:016X}; }}\n"), + StageNames[i], shader.second.stageHashes[i]); } } } - out.first += "\n"; + out.first << "\n"; - out.first += "#define UNIVERSAL_PIPELINES_"; - out.first += baseName; + out.first << "#define UNIVERSAL_PIPELINES_"; + out.first << baseName; for (const auto& shader : shaderStageUses) { - out.first += " \\\n"; - out.first += "::Shader_"; - out.first += shader.first; + out.first << " \\\n"; + out.first << "::Shader_"; + out.first << shader.first; } - out.first += "\n"; + out.first << "\n"; - out.first += "#define STAGES_"; - out.first += baseName; - out.first += "(P, S)"; + out.first << "#define STAGES_"; + out.first << baseName; + out.first << "(P, S)"; for (const auto& shader : shaderStageUses) { - out.first += " \\\n"; - out.first += "::StageObject_"; - out.first += shader.first; - out.first += ","; + out.first << " \\\n"; + out.first << "::StageObject_"; + out.first << shader.first; + out.first << ","; } - out.first += "\n"; - + out.first << "\n"; + return true; } -bool Compiler::compile(std::string_view baseName, std::pair& out) { - out = { - "#pragma once\n" - "#include \"hecl/PipelineBase.hpp\"\n\n", - Format("#include \"%s.hpp\"\n\n", baseName.data())}; +bool Compiler::compile(std::string_view baseName, std::pair& out) { + out.first << "#pragma once\n" + "#include \"hecl/PipelineBase.hpp\"\n\n"; + fmt::print(out.second, fmt("#include \"{}.hpp\"\n\n"), baseName); for (const auto& file : m_inputFiles) if (!compileFile(file, baseName, out)) diff --git a/hecl/shaderc/shaderc.hpp b/hecl/shaderc/shaderc.hpp index b07abb6a6..06a343512 100644 --- a/hecl/shaderc/shaderc.hpp +++ b/hecl/shaderc/shaderc.hpp @@ -15,17 +15,18 @@ class Compiler { std::unordered_map m_defines; template static bool StageAction(StageType type, const std::string& name, const std::string& basename, - const std::string& stage, std::string& implOut); + const std::string& stage, std::stringstream& implOut); template static bool StageAction(const std::string& platforms, StageType type, const std::string& name, - const std::string& basename, const std::string& stage, std::string& implOut); + const std::string& basename, const std::string& stage, std::stringstream& implOut); bool includeFile(SystemStringView file, std::string& out, int depth = 0); - bool compileFile(SystemStringView file, std::string_view baseName, std::pair& out); + bool compileFile(SystemStringView file, std::string_view baseName, + std::pair& out); public: void addInputFile(SystemStringView file); void addDefine(std::string_view var, std::string_view val); - bool compile(std::string_view baseName, std::pair& out); + bool compile(std::string_view baseName, std::pair& out); }; } // namespace hecl::shaderc