Modernize: use std::format instead of printf formatting

This commit is contained in:
Will Toohey
2026-06-27 00:39:26 +10:00
parent 2d1ad2d326
commit 56311746bb
17 changed files with 164 additions and 173 deletions

View File

@@ -1,6 +1,6 @@
project('layeredfs', 'c', 'cpp', version: '4.1',
default_options: [
'cpp_std=c++23',
'cpp_std=c++26',
'buildtype=release',
'strip=true',
'werror=true',

View File

@@ -34,11 +34,11 @@ std::optional<ArcArchive> ArcArchive::from_stream(std::istream &stream) {
return std::nullopt;
}
if (hdr.magic != ARC_MAGIC) {
log_warning("arc: bad magic %08x", hdr.magic);
log_warning("arc: bad magic {:08x}", hdr.magic);
return std::nullopt;
}
if (hdr.compression != ARC_COMPRESSION_NONE && hdr.compression != ARC_COMPRESSION_AVSLZ) {
log_warning("arc: unknown compression %u", hdr.compression);
log_warning("arc: unknown compression {}", hdr.compression);
return std::nullopt;
}
@@ -57,7 +57,7 @@ std::optional<ArcArchive> ArcArchive::from_stream(std::istream &stream) {
stream.seekg(e.file_offset);
std::vector<uint8_t> packed(e.packed_size);
if (!stream.read(reinterpret_cast<char*>(packed.data()), e.packed_size)) {
log_warning("arc: couldn't read data for '%s'", name.c_str());
log_warning("arc: couldn't read data for '{}'", name);
return std::nullopt;
}
@@ -65,7 +65,7 @@ std::optional<ArcArchive> ArcArchive::from_stream(std::istream &stream) {
size_t out_size = e.unpacked_size;
auto raw = lz_decompress(packed.data(), packed.size(), &out_size);
if (!raw || out_size != e.unpacked_size) {
log_warning("arc: decompression failed for '%s'", name.c_str());
log_warning("arc: decompression failed for '{}'", name);
if (raw) free(raw);
return std::nullopt;
}
@@ -92,7 +92,7 @@ static uint32_t align_up(uint32_t v, uint32_t align) {
bool ArcArchive::save(const char* path) {
std::ofstream f(path, std::ios::binary);
if (!f) {
log_warning("arc: couldn't open '%s' for writing", path);
log_warning("arc: couldn't open '{}' for writing", path);
return false;
}

View File

@@ -209,12 +209,6 @@ const avs_exports_t avs_exports[] = {
FOREACH_AVS_FUNC(AVS_FUNC_PTR)
FOREACH_AVS_FUNC_OPTIONAL(AVS_FUNC_PTR)
/*void* (*avs_fs_mount)(char* mountpoint, char* fsroot, char* fstype, int a5);
void* hook_avs_fs_mount(char* mountpoint, char* fsroot, char* fstype, int a5) {
log_misc("Mounting %s at %s with type %s", fsroot, mountpoint, fstype);
return avs_fs_mount(mountpoint, fsroot, fstype, a5);
}*/
#define TEST_HOOK_AND_APPLY(func) if (MH_CreateHookApi(dll_name, avs_exports[i].func, (LPVOID)hook_ ## func, (LPVOID*)&func) != MH_OK || func == NULL) continue
#define LOAD_FUNC(func) if( (func = (decltype(func))GetProcAddress(mod_handle, avs_exports[i].func)) == NULL) continue
#define CHECK_UNIQUE(func) if( avs_exports[i].func != NULL && GetProcAddress(mod_handle, avs_exports[i].func) == NULL) continue
@@ -227,7 +221,7 @@ bool init_avs(void) {
#ifdef _DEBUG
for (int i = 0; i < lenof(avs_exports); i++) {
#define VERBOSE_EXPORT_CHECK(ret_type, name, ...) if(avs_exports[i]. ## name == NULL) log_warning("MISSING EXPORT %d: %s", i, #name);
#define VERBOSE_EXPORT_CHECK(ret_type, name, ...) if(avs_exports[i]. ## name == NULL) log_warning("MISSING EXPORT {}: {}", i, #name);
FOREACH_AVS_FUNC(VERBOSE_EXPORT_CHECK)
FOREACH_AVS_FUNC_OPTIONAL(VERBOSE_EXPORT_CHECK)
}
@@ -291,7 +285,7 @@ property_t prop_from_file_handle(AVS_FILE f) {
avs_fs_lseek(f, 0, SEEK_SET);
memsize = property_read_query_memsize(avs_fs_read, f, NULL, NULL);
if (memsize < 0) {
log_warning("Couldn't get memsize %08X (%s)", memsize, get_prop_error_str(memsize));
log_warning("Couldn't get memsize {:08X} ({})", memsize, get_prop_error_str(memsize));
goto FAIL;
}
}
@@ -305,7 +299,7 @@ property_t prop_from_file_handle(AVS_FILE f) {
prop = property_create(flags, prop_buffer, memsize);
if (!prop) {
// double cast to squash truncation warning
log_warning("Couldn't create prop (%s)", get_prop_error_str((int32_t)(size_t)prop));
log_warning("Couldn't create prop ({})", get_prop_error_str((int32_t)(size_t)prop));
goto FAIL;
}
@@ -314,7 +308,7 @@ property_t prop_from_file_handle(AVS_FILE f) {
avs_fs_close(f);
if (ret < 0) {
log_warning("Couldn't read prop (%s)", get_prop_error_str(ret));
log_warning("Couldn't read prop ({})", get_prop_error_str(ret));
goto FAIL;
}
@@ -349,7 +343,7 @@ char* prop_to_xml_string(property_t prop, rapidxml::xml_document<>& allocator) {
}
else {
xml[0] = '\0';
log_warning("property_mem_write failed (%s)", get_prop_error_str(written));
log_warning("property_mem_write failed ({})", get_prop_error_str(written));
}
return xml;

View File

@@ -272,7 +272,7 @@ bool rapidxml_from_avs_file(
try {
doc.parse<Flags>(xml);
} catch (const rapidxml::parse_error& e) {
log_warning("Couldn't parse xml (%s byte %d)", e.what(), (int)(e.where<char>() - xml));
log_warning("Couldn't parse xml ({} byte {})", e.what(), (int)(e.where<char>() - xml));
auto f = fopen("debug.xml", "wb");
fwrite(xml, strlen(xml), 1, f);
return false;

View File

@@ -157,7 +157,7 @@ LONG WINAPI exc_handler(_EXCEPTION_POINTERS *ExceptionInfo) {
case DBG_PRINTEXCEPTION_C:
break;
default:
log_warning("Unhandled exception code 0x%lX at %p\n",
log_warning("Unhandled exception code {:#x} at {:p}",
ExceptionInfo->ExceptionRecord->ExceptionCode,
ExceptionInfo->ExceptionRecord->ExceptionAddress
);

View File

@@ -120,13 +120,14 @@ void load_config(void) {
}
void print_config(void) {
log_info("Options: %s=%d %s=%d %s=%d %s=%s %s=%s %s=%s %s=%s",
log_info("Options: {}={} {}={} {}={} {}={} {}={} {}={} {}={}",
VERBOSE_FLAG, config.verbose_logs,
DEVMODE_FLAG, config.developer_mode,
DISABLE_FLAG, config.disable,
LOGFILE_FLAG, config.logfile,
ALLOWLIST_FLAG, allowlist,
BLOCKLIST_FLAG, blocklist,
// TODO: std::optional
LOGFILE_FLAG, config.logfile ? config.logfile : "(null)",
ALLOWLIST_FLAG, allowlist ? allowlist : "(null)",
BLOCKLIST_FLAG, blocklist ? blocklist : "(null)",
MOD_FOLDER_FLAG, config.get_mod_folder().c_str()
);
}

View File

@@ -63,7 +63,7 @@ class PkfsHookFile final : public HookFile {
log_if_modfile();
auto ret = pkfs_fs_open(get_path_to_open().c_str());
if(ret == 0) {
log_verbose("pkfs_fs_open(%s) failed in call_real", get_path_to_open().c_str());
log_verbose("pkfs_fs_open({}) failed in call_real", get_path_to_open());
}
return ret;
}
@@ -86,7 +86,7 @@ class PkfsHookFile final : public HookFile {
// This of course is racey, so if there is a *real* error in another
// thread, this resets it. But it's a tight race, and I'll take that
// chance.
log_verbose("pkfs_open(%s) failed in load_to_vec, clearing HDD error", get_path_to_open().c_str());
log_verbose("pkfs_open({}) failed in load_to_vec, clearing HDD error", get_path_to_open());
pkfs_clear_hdd_error();
return nullopt;
}
@@ -233,7 +233,7 @@ void handle_arc(HookFile &file) {
}
arc = std::move(*_arc);
} else {
log_info("arc: no original file, creating from scratch: \"%s\"", file.norm_path.c_str());
log_info("arc: no original file, creating from scratch: \"{}\"", file.norm_path);
}
auto out_folder = out.substr(0, out.rfind("/"));
@@ -296,13 +296,13 @@ void handle_arc(HookFile &file) {
auto out_folder = xml_orig.substr(0, xml_orig.rfind("/"));
if (!mkdir_p(out_folder)) {
log_warning("Couldn't create arc xml cache folder %s", out_folder.c_str());
log_warning("Couldn't create arc xml cache folder {}", out_folder);
continue;
}
FILE *f = fopen(xml_orig.c_str(), "wb");
if (!f) {
log_warning("Couldn't create arc xml base at %s", xml_orig.c_str());
log_warning("Couldn't create arc xml base at {}", xml_orig);
continue;
}
fwrite(arc_file.second.data(), 1, arc_file.second.size(), f);
@@ -324,7 +324,7 @@ void handle_arc(HookFile &file) {
auto data = f.load_to_vec();
if (!data) {
log_warning("arc: couldn't load mod file '%s'", path.first.c_str());
log_warning("arc: couldn't load mod file '{}'", path.first);
continue;
}
arc.add_or_replace(name, std::move(*data));
@@ -338,7 +338,7 @@ void handle_arc(HookFile &file) {
cache_hasher.commit();
file.mod_path = out;
log_misc("arc generation took %d ms", time() - start);
log_misc("arc generation took {} ms", time() - start);
}
void handle_texbin(HookFile &file) {
@@ -413,7 +413,7 @@ void handle_texbin(HookFile &file) {
}
texbin = *_texbin;
} else {
log_info("Found texbin mods but no original file, creating from scratch: \"%s\"", file.norm_path.c_str());
log_info("Found texbin mods but no original file, creating from scratch: \"{}\"", file.norm_path);
}
auto folder_terminator = out.rfind("/");
@@ -438,7 +438,7 @@ void handle_texbin(HookFile &file) {
cache_hasher.commit();
file.mod_path = out;
log_misc("Texbin generation took %d ms", time() - start);
log_misc("Texbin generation took {} ms", time() - start);
}
uint32_t handle_file_open(HookFile &file) {
@@ -474,7 +474,7 @@ uint32_t handle_file_open(HookFile &file) {
if(file.ramfs_demangle()) {
ramfs_demangler_on_fs_open(file.path, ret);
}
// log_verbose("(returned %d)", ret);
// log_verbose("(returned {})", ret);
return ret;
}
@@ -482,7 +482,7 @@ int hook_avs_fs_lstat(const char* name, struct avs_stat *st) {
if (name == NULL)
return avs_fs_lstat(name, st);
log_verbose("statting %s", name);
log_verbose("statting {}", name);
string path = name;
// can it be modded ie is it under /data ?
@@ -499,7 +499,7 @@ int hook_avs_fs_convert_path(char dest_name[256], const char *name) {
if (name == NULL)
return avs_fs_convert_path(dest_name, name);
log_verbose("convert_path %s", name);
log_verbose("convert_path {}", name);
string path = name;
// can it be modded ie is it under /data ?
@@ -513,7 +513,7 @@ int hook_avs_fs_convert_path(char dest_name[256], const char *name) {
}
int hook_avs_fs_mount(const char* mountpoint, const char* fsroot, const char* fstype, const char* args) {
log_verbose("mounting %s to %s with type %s and args %s", fsroot, mountpoint, fstype, args);
log_verbose("mounting {} to {} with type {} and args {}", fsroot, mountpoint, fstype, args ? args : "(null)");
ramfs_demangler_on_fs_mount(mountpoint, fsroot, fstype, args);
// In new jubeat, a modded IFS file will be loaded as such:
@@ -559,7 +559,7 @@ DWORD WINAPI hook_GetLongPathNameA(LPCSTR lpszShortPath, LPSTR lpszLongPath, DWO
AVS_FILE hook_avs_fs_open(const char* name, uint16_t mode, int flags) {
if(name == NULL || inside_pkfs_hook)
return avs_fs_open(name, mode, flags);
log_verbose("opening %s mode %d flags %d", name, mode, flags);
log_verbose("opening {} mode {} flags {}", name, mode, flags);
// only touch reads
if (mode != avs_open_mode_read()) {
return avs_fs_open(name, mode, flags);
@@ -577,7 +577,7 @@ AVS_FILE hook_avs_fs_open(const char* name, uint16_t mode, int flags) {
}
unsigned int hook_pkfs_open(const char *name) {
log_verbose("pkfs_open %s", name);
log_verbose("pkfs_open {}", name);
string path = name;
@@ -630,7 +630,8 @@ static void dump_loaded_dll_info() {
bool first = true;
for(auto mod = head; mod && (first || mod != head); mod = mod->Flink) {
auto ldr = reinterpret_cast<PLDR_DATA_TABLE_ENTRY>(mod);
log_verbose(" %.*ls", ldr->FullDllName.Length, ldr->FullDllName.Buffer);
std::string narrow_dll_name(ldr->FullDllName.Buffer, ldr->FullDllName.Buffer + ldr->FullDllName.Length);
log_verbose(" {}", narrow_dll_name);
first = false;
}
}
@@ -667,7 +668,7 @@ extern "C" {
#ifdef SPECIAL_VER
log_info("Build config: " SPECIAL_VER);
#endif
log_info("AVS DLL detected: %s", avs_loaded_dll_name);
log_info("AVS DLL detected: {}", avs_loaded_dll_name);
print_config();
#ifdef UNPAK
log_info(".pak dumper mode enabled");
@@ -714,7 +715,7 @@ extern "C" {
log_info("Detected mod folders:");
for (auto &p : available_mods()) {
log_info("%s", p.c_str());
log_info("{}", p);
}
return 0;

View File

@@ -59,7 +59,7 @@ class HookFile {
void log_if_modfile() {
if (mod_path) {
log_verbose("Using %s", mod_path->c_str());
log_verbose("Using {}", *mod_path);
}
}

View File

@@ -88,7 +88,7 @@ bool add_images_to_list(string_set &extra_pngs, rapidxml::xml_node<> *texturelis
vector<Bitmap*> textures;
for (auto it = extra_pngs.begin(); it != extra_pngs.end(); ++it) {
log_verbose("New image: %s", it->c_str());
log_verbose("New image: {}", *it);
string png_tex = *it + ".png";
auto png_loc = find_first_modfile(ifs_mod_path + "/" + png_tex);
@@ -122,7 +122,7 @@ bool add_images_to_list(string_set &extra_pngs, rapidxml::xml_node<> *texturelis
log_warning("Couldn't pack textures :(");
return false;
}
log_misc("Texture packing %d ms", time() - pack_start);
log_misc("Texture packing {} ms", time() - pack_start);
// because the property API, being
// a) written by Konami
@@ -187,7 +187,7 @@ bool add_images_to_list(string_set &extra_pngs, rapidxml::xml_node<> *texturelis
}
}
log_misc("Texture extend total time %d ms", time() - start);
log_misc("Texture extend total time {} ms", time() - start);
return true;
}
@@ -198,7 +198,7 @@ void parse_texturelist(HookFile &file) {
auto ifs_path = file.norm_path;
// truncate
ifs_path.resize(ifs_path.size() - strlen("/tex/texturelist.xml"));
// log_misc("Reading ifs %s", ifs_path.c_str());
// log_misc("Reading ifs {}", ifs_path);
auto ifs_mod_path = ifs_path;
string_replace(ifs_mod_path, ".ifs", "_ifs");
@@ -240,14 +240,14 @@ void parse_texturelist(HookFile &file) {
auto format = texture->first_attribute("format");
if (!format) {
log_warning("Texture missing format %s", path_to_open.c_str());
log_warning("Texture missing format {}", path_to_open);
continue;
}
//<size __type="2u16">128 128</size>
auto size = texture->first_node("size");
if (!size) {
log_warning("Texture missing size %s", path_to_open.c_str());
log_warning("Texture missing size {}", path_to_open);
continue;
}
@@ -263,7 +263,7 @@ void parse_texturelist(HookFile &file) {
image = image->next_sibling("image")) {
auto name = image->first_attribute("name");
if (!name) {
log_warning("Texture missing name %s", path_to_open.c_str());
log_warning("Texture missing name {}", path_to_open);
continue;
}
@@ -271,14 +271,14 @@ void parse_texturelist(HookFile &file) {
auto imgrect = image->first_node("imgrect");
auto uvrect = image->first_node("uvrect");
if (!imgrect || !uvrect) {
log_warning("Texture missing dimensions %s", path_to_open.c_str());
log_warning("Texture missing dimensions {}", path_to_open);
continue;
}
// it's a 4u16
sscanf(imgrect->value(), "%" SCNu16 " %" SCNu16 " %" SCNu16 " %" SCNu16, &dimensions[0], &dimensions[1], &dimensions[2], &dimensions[3]);
// log_misc("Image '%s' compress %d format %d", name->value(), compress, format_type);
// log_misc("Image '{}' compress {} format {}", name->value(), compress, format_type);
image_t image_info;
image_info.name = name->value();
MD5 md5;
@@ -297,7 +297,7 @@ void parse_texturelist(HookFile &file) {
}
}
log_verbose("%d added PNGs", extra_pngs.size());
log_verbose("{} added PNGs", extra_pngs.size());
if (extra_pngs.size() > 0) {
if (add_images_to_list(extra_pngs, texturelist_node, ifs_path, ifs_mod_path, compress))
prop_was_rewritten = true;
@@ -341,12 +341,12 @@ bool cache_texture(string const&png_path, image_t const&tex) {
error = lodepng_decode32_file(&image, &width, &height, png_path.c_str());
if (error) {
log_warning("can't load png %u: %s\n", error, lodepng_error_text(error));
log_warning("can't load png {}: {}\n", error, lodepng_error_text(error));
return false;
}
if ((int)width != tex.width || (int)height != tex.height) {
log_warning("Loaded png (%dx%d) doesn't match texturelist.xml (%dx%d), ignoring", width, height, tex.width, tex.height);
log_warning("Loaded png ({}x{}) doesn't match texturelist.xml ({}x{}), ignoring", width, height, tex.width, tex.height);
return false;
}
@@ -420,7 +420,7 @@ void parse_afplist(HookFile &file) {
auto ifs_path = file.norm_path;
// truncate
ifs_path.resize(ifs_path.size() - strlen("/tex/afplist.xml"));
// log_misc("Reading ifs %s", ifs_path.c_str());
// log_misc("Reading ifs {}", ifs_path);
auto ifs_mod_path = ifs_path;
string_replace(ifs_mod_path, ".ifs", "_ifs");
@@ -452,14 +452,14 @@ void parse_afplist(HookFile &file) {
auto name = afp->first_attribute("name");
if (!name) {
log_warning("AFP missing name %s", path_to_open.c_str());
log_warning("AFP missing name {}", path_to_open);
continue;
}
// <geo __type="u16" __count="5">5 8 11 16 19</geo>
auto geo = afp->first_node("geo");
if (!geo) {
log_warning("AFP missing geo %s", path_to_open.c_str());
log_warning("AFP missing geo {}", path_to_open);
continue;
}
@@ -469,7 +469,7 @@ void parse_afplist(HookFile &file) {
.mod_path = ifs_mod_path + folder + file,
});
mapped++;
// log_info("AFP %s -> %s", md5_path.c_str(), (ifs_mod_path + folder + file).c_str());
// log_info("AFP {} -> {}", md5_path, ifs_mod_path + folder + file);
};
std::lock_guard lock(afp_md5_names_mtx);
@@ -485,7 +485,7 @@ void parse_afplist(HookFile &file) {
}
}
log_verbose("Mapped %d AFP filenames", mapped);
log_verbose("Mapped {} AFP filenames", mapped);
}
std::optional<std::tuple<std::string, std::shared_ptr<image_t>>> lookup_png_from_md5(HookFile &file) {
@@ -495,7 +495,7 @@ std::optional<std::tuple<std::string, std::shared_ptr<image_t>>> lookup_png_from
return std::nullopt;
}
//log_misc("Mapped file %s is found!", norm_path.c_str());
//log_misc("Mapped file {} is found!", norm_path);
auto tex = tex_search->second;
lock.unlock(); // is it safe to unlock this early? Time will tell...
@@ -519,15 +519,15 @@ void handle_texture(HookFile &file) {
auto &[png_path, tex] = *lookup;
if (tex->compression == UNSUPPORTED_COMPRESS) {
log_warning("Unsupported compression for %s", png_path.c_str());
log_warning("Unsupported compression for {}", png_path);
return;
}
if (tex->format == UNSUPPORTED_FORMAT) {
log_warning("Unsupported texture format for %s", png_path.c_str());
log_warning("Unsupported texture format for {}", png_path);
return;
}
log_verbose("Mapped file %s found!", png_path.c_str());
log_verbose("Mapped file {} found!", png_path);
if (cache_texture(png_path, *tex)) {
file.mod_path = tex->cache_file();
}
@@ -541,7 +541,7 @@ std::optional<std::string> lookup_afp_from_md5(HookFile &file) {
return std::nullopt;
}
//log_misc("Mapped file %s is found!", norm_path.c_str());
//log_misc("Mapped file {} is found!", norm_path);
auto afp = afp_search->second;
lock.unlock(); // is it safe to unlock this early? Time will tell...
@@ -553,7 +553,7 @@ void handle_afp(HookFile &file) {
if(!lookup)
return;
log_verbose("Mapped file %s found!", lookup->c_str());
log_verbose("Mapped file {} found!", *lookup);
file.mod_path = *lookup;
return;
}
@@ -584,9 +584,9 @@ void merge_xmls(HookFile &file) {
auto cache_hasher = CacheHasher(out_hashed);
cache_hasher.add(starting); // don't forget to take the input into account
log_info("Merging into %s", starting.c_str());
log_info("Merging into {}", starting);
for (auto &path : to_merge) {
log_info(" %s", path.c_str());
log_info(" {}", path);
cache_hasher.add(path);
}
cache_hasher.finish();
@@ -600,7 +600,7 @@ void merge_xmls(HookFile &file) {
auto first_result = rapidxml_from_avs_filepath(starting, merged_xml, merged_xml);
if (!first_result) {
log_warning("Couldn't merge (can't load first xml %s)", starting.c_str());
log_warning("Couldn't merge (can't load first xml {})", starting);
return;
}
@@ -608,7 +608,7 @@ void merge_xmls(HookFile &file) {
rapidxml::xml_document<> rapid_to_merge;
auto merge_load_result = rapidxml_from_avs_filepath(path, rapid_to_merge, merged_xml);
if (!merge_load_result) {
log_warning("Couldn't merge (can't load xml) %s", path.c_str());
log_warning("Couldn't merge (can't load xml) {}", path);
return;
}
@@ -630,5 +630,5 @@ void merge_xmls(HookFile &file) {
cache_hasher.commit();
file.mod_path = out;
log_misc("Merge took %d ms", time() - start);
log_misc("Merge took {} ms", time() - start);
}

View File

@@ -1,24 +1,35 @@
#pragma once
#include "config.hpp" // since log_verbose uses it
#include <format>
#ifndef LOG_MODULE
#define LOG_MODULE "layeredfs"
#endif
inline constexpr char _log_module[] = LOG_MODULE;
using log_formatter_t = void (*)(const char *module, const char *fmt, ...);
template<log_formatter_t* Logger, const char *Module, class... Args>
void log_base(std::format_string<Args...> fmt, Args&&... args) {
(*Logger)(Module, "%s", std::format(fmt, std::forward<Args>(args)...).c_str());
}
// functions that default to file output, but will be overriden to point to AVS
// logging functions if the user doesn't specify their own log file
#define log_fatal(...) imp_log_body_fatal(LOG_MODULE, __VA_ARGS__)
#define log_warning(...) imp_log_body_warning(LOG_MODULE, __VA_ARGS__)
#define log_info(...) imp_log_body_info(LOG_MODULE, __VA_ARGS__)
#define log_misc(...) imp_log_body_misc(LOG_MODULE, __VA_ARGS__)
extern log_formatter_t imp_log_body_fatal;
extern log_formatter_t imp_log_body_warning;
extern log_formatter_t imp_log_body_info;
extern log_formatter_t imp_log_body_misc;
#define log_fatal(...) log_base<&imp_log_body_fatal, _log_module>(__VA_ARGS__);
#define log_warning(...) log_base<&imp_log_body_warning, _log_module>(__VA_ARGS__);
#define log_info(...) log_base<&imp_log_body_info, _log_module>(__VA_ARGS__);
#define log_misc(...) log_base<&imp_log_body_misc, _log_module>(__VA_ARGS__);
// layeredfs super-verbose (since most people have loglevel misc already)
#define log_verbose(...) if(config.verbose_logs) {log_misc(__VA_ARGS__);}
// for the playpen
void log_to_stdout(void);
typedef void (*log_formatter_t)(const char *module, const char *fmt, ...);
extern log_formatter_t imp_log_body_fatal;
extern log_formatter_t imp_log_body_warning;
extern log_formatter_t imp_log_body_info;
extern log_formatter_t imp_log_body_misc;

View File

@@ -39,13 +39,13 @@ std::set<string, CaseInsensitiveCompare> walk_dir(const string &path, const stri
log_warning("\"data\" folder detected in mod root. Move all files inside to the mod root, or it will not work");
}
result_path = root + ffd.cFileName + "/";
log_verbose(" %s", result_path.c_str());
log_verbose(" {}", result_path);
auto subdir_walk = walk_dir(path + "/" + ffd.cFileName, result_path);
result.insert(subdir_walk.begin(), subdir_walk.end());
}
else {
result_path = root + ffd.cFileName;
log_verbose(" %s", result_path.c_str());
log_verbose(" {}", result_path);
}
result.insert(result_path);
} while (FindNextFileA(contents, &ffd) != 0);
@@ -64,7 +64,7 @@ void cache_mods(void) {
config.developer_mode = devmode;
for (auto &dir : avail_mods) {
log_verbose("Walking %s", dir.c_str());
log_verbose("Walking {}", dir);
mod_contents_t mod;
mod.name = dir;
// even in developer mode we want to walk the mods directory for effective logging
@@ -82,7 +82,7 @@ static vector<string> game_folders;
void init_modpath_handler(void) {
log_verbose("Top level folders:");
for (auto folder : folders_in_folder(".")) {
log_verbose(" %s", folder.c_str());
log_verbose(" {}", folder);
// data is the normal case we transparently handle
if (!strcasecmp(folder.c_str(), "data")) {
@@ -149,7 +149,7 @@ vector<string> available_mods() {
// if there is an allowlist, is this mod on it?
if (!config.allowlist.empty() && config.allowlist.find(folder) == config.allowlist.end()) {
if (first_search)
log_info("Ignoring non-allowlisted mod %s", folder.c_str());
log_info("Ignoring non-allowlisted mod {}", folder);
continue;
}
@@ -157,7 +157,7 @@ vector<string> available_mods() {
// is this mod in the blocklist?
if (config.blocklist.find(folder) != config.blocklist.end()) {
if (first_search)
log_info("Ignoring blocklisted mod %s", folder.c_str());
log_info("Ignoring blocklisted mod {}", folder);
continue;
}
@@ -220,7 +220,7 @@ optional<string> find_first_cached_item(const string &norm_path) {
}
optional<string> find_first_modfile(const string &norm_path) {
//log_verbose("%s(%s)", __FUNCTION__, norm_path.c_str());
//log_verbose("{}({})", __FUNCTION__, norm_path);
if (config.developer_mode) {
for (auto &dir : available_mods()) {
auto mod_path = dir + "/" + norm_path;

View File

@@ -35,7 +35,7 @@ void lz_unfuck(uint8_t *buf, size_t len) {
}
}
log_info("unfucked %d bytes", repl);
log_info("unfucked {} bytes", repl);
}
optional<std::vector<uint8_t>> readFile(const char* filename)
@@ -45,7 +45,7 @@ optional<std::vector<uint8_t>> readFile(const char* filename)
std::ifstream file(filename, std::ios::binary);
if(!file) {
log_warning("Couldn't open %s", filename);
log_warning("Couldn't open {}", filename);
return nullopt;
}
@@ -96,16 +96,16 @@ void avs_playpen() {
// return;
// }
// auto debug = *_debug;
// log_info("Loaded %d bytes", debug.size());
// log_info("Loaded {} bytes", debug.size());
// // lz_unfuck(&debug[8], comp_sz);
// // auto decomp = lz_decompress(&debug[8], comp_sz, &decomp_sz);
// auto decomp = texbin_lz77_decompress(debug);
// log_info("Decomp to %u", decomp.size());
// log_info("Decomp to {}", decomp.size());
// auto comp = texbin_lz77_compress(decomp);
// log_info("Comp again to %u", comp.size());
// log_info("Comp again to {}", comp.size());
// auto decomp2 = texbin_lz77_decompress(comp);
// log_info("Final decomp to %u", decomp2.size());
// log_info("Final decomp to {}", decomp2.size());
// auto f = fopen("debug.out.bin", "wb");
// fwrite(&decomp[0], 1, decomp.size(), f);
@@ -142,7 +142,7 @@ void avs_playpen() {
auto memsize = property_read_query_memsize(avs_fs_read, f, NULL, NULL);
if (memsize < 0) {
log_warning("Couldn't get memsize %08X", memsize);
log_warning("Couldn't get memsize {:08X}", memsize);
goto FAIL;
}
@@ -176,7 +176,7 @@ FAIL:
return;
}
for (char* n = avs_fs_readdir(d); n; n = avs_fs_readdir(d))
log_info("dir %s", n);
log_info("dir {}", n);
avs_fs_closedir(d);*/
//char name[64];
//auto playpen = prop_from_file("playpen.xml");
@@ -188,15 +188,15 @@ FAIL:
//print_node(end);
/*for (int i = 0; i <= 8; i++) {
if (i == 6 || i == 3) continue;
log_info("Traverse: %d", i);
log_info("Traverse: {}", i);
auto node = property_search(playpen, NULL, "/root/t2");
auto nnn = property_node_traversal(node, 8);
auto nna = property_node_traversal(nnn, TRAVERSE_FIRST_ATTR);
property_node_name(nna, name, 64);
log_info("bloop %s", name);
log_info("bloop {}", name);
for (;node;node = property_node_traversal(node, i)) {
if (!property_node_name(node, name, 64)) {
log_info(" %s", name);
log_info(" {}", name);
}
}
}*/

View File

@@ -110,11 +110,11 @@ void ramfs_demangler_register_arc_inner_ifs(const std::string& basename, const s
std::lock_guard lock(mangling_mtx);
auto existing = arc_inner_by_basename.find(basename);
if (existing != arc_inner_by_basename.end() && existing->second != demangled_path) {
log_warning("arc demangle: basename collision for '%s' (%s vs %s), later one wins",
basename.c_str(), existing->second.c_str(), demangled_path.c_str());
log_warning("arc demangle: basename collision for '{}' ({} vs {}), later one wins",
basename, existing->second, demangled_path);
}
arc_inner_by_basename[basename] = demangled_path;
log_verbose("arc inner basename '%s' -> %s", basename.c_str(), demangled_path.c_str());
log_verbose("arc inner basename '{}' -> {}", basename, demangled_path);
}
void ramfs_demangler_on_fs_read(AVS_FILE context, void* dest) {
@@ -124,7 +124,7 @@ void ramfs_demangler_on_fs_read(AVS_FILE context, void* dest) {
if (find != open_file_map.end()) {
auto path = find->second;
// even this is too verbose
//log_verbose("Mapped %p to %s", dest, path.c_str());
// log_verbose("Mapped {:p} to {}", dest, path);
ram_load_map[dest] = path;
auto cleanup = cleanup_map.find(path);
@@ -160,7 +160,7 @@ void ramfs_demangler_on_fs_mount(const char* mountpoint, const char* fsroot, con
auto find = ram_load_map.find(buffer);
if (find != ram_load_map.end()) {
auto orig_path = find->second;
log_verbose("ramfs mount mapped to %s", orig_path.c_str());
log_verbose("ramfs mount mapped to {}", orig_path);
ramfs_map[mount_path.c_str()] = orig_path;
auto cleanup = cleanup_map.find(orig_path);
@@ -184,7 +184,7 @@ void ramfs_demangler_on_fs_mount(const char* mountpoint, const char* fsroot, con
: arc_inner_by_basename.find(bn);
if (by_name != arc_inner_by_basename.end()) {
auto orig_path = by_name->second;
log_verbose("ramfs mount basename '%s' mapped to %s", bn.c_str(), orig_path.c_str());
log_verbose("ramfs mount basename '{}' mapped to {}", bn, orig_path);
ramfs_map[mount_path.c_str()] = orig_path;
// No cleanup_map entry: we never saw the open for this inner ifs.
}
@@ -194,7 +194,7 @@ void ramfs_demangler_on_fs_mount(const char* mountpoint, const char* fsroot, con
auto find = ramfs_map.find(fsroot);
if (find != ramfs_map.end()) {
auto orig_path = *find;
log_verbose("link mount mapped to %s", orig_path.c_str());
log_verbose("link mount mapped to {}", orig_path);
ramfs_map[mountpoint] = orig_path;
auto cleanup = cleanup_map.find(orig_path);
@@ -207,7 +207,7 @@ void ramfs_demangler_on_fs_mount(const char* mountpoint, const char* fsroot, con
auto find = ramfs_map.longest_prefix(fsroot);
if (find != ramfs_map.end()) {
auto orig_path = *find;
log_verbose("imagefs mount mapped to %s", orig_path.c_str());
log_verbose("imagefs mount mapped to {}", orig_path);
mangling_map[mountpoint] = orig_path;
auto cleanup = cleanup_map.find(orig_path);
@@ -228,7 +228,7 @@ void ramfs_demangler_on_fs_mount(const char* mountpoint, const char* fsroot, con
string root = (string)fsroot;
ramfs_demangler_demangle_if_possible_nolock(root);
if (normalise_path(root, /* demangle */ false)) {
log_verbose("imagefs mount mapped to %s", root.c_str());
log_verbose("imagefs mount mapped to {}", root);
mangling_map[mountpoint] = root;
}
}
@@ -240,7 +240,7 @@ void ramfs_demangler_demangle_if_possible(std::string& raw_path) {
auto search = mangling_map.longest_prefix(raw_path);
if (search != mangling_map.end()) {
// log_verbose("can demangle %s to %s", search.key().c_str(), search->c_str());
// log_verbose("can demangle {} to {}", search.key(), *search);
string_replace(raw_path, search.key().c_str(), search->c_str());
}
}

View File

@@ -28,7 +28,7 @@ FOREACH_EXTRA_FUNC(AVS_FUNC_PTR)
class LogTestName : public testing::EmptyTestEventListener {
void OnTestStart(const testing::TestInfo& info) override {
log_misc("--------- Running %s.%s", info.test_suite_name(), info.name());
log_misc("--------- Running {}.{}", info.test_suite_name(), info.name());
}
};
@@ -133,7 +133,7 @@ TEST(ImageFs, MD5DemanglingWorks) {
if(!norm) return std::string();
TestHookFile file(path, *norm);
log_info("Lookup %s norm %s", path.c_str(), norm->c_str());
log_info("Lookup {} norm {}", path, *norm);
auto lookup = lookup_png_from_md5(file);
EXPECT_NE(lookup, std::nullopt);
if(!lookup) return std::string();
@@ -150,7 +150,7 @@ TEST(ImageFs, MD5DemanglingWorks) {
if(!norm) return std::string();
TestHookFile file(path, *norm);
log_info("Lookup %s norm %s", path.c_str(), norm->c_str());
log_info("Lookup {} norm {}", path, *norm);
auto lookup = lookup_afp_from_md5(file);
EXPECT_NE(lookup, std::nullopt);
if(!lookup) return std::string();
@@ -230,9 +230,8 @@ TEST(RamFs, DemanglingWorks) {
ramfs_demangler_on_fs_open("./data/test.ifs", fake_handle);
ramfs_demangler_on_fs_read(fake_handle, fake_buffer);
char* flags = snprintf_auto("base=0x%llx", (unsigned long long)(uintptr_t)fake_buffer);
ramfs_demangler_on_fs_mount("/sd0", "test.ifs", "ramfs", flags);
free(flags);
std::string flags = std::format("base={:#x}", (uintptr_t)fake_buffer);
ramfs_demangler_on_fs_mount("/sd0", "test.ifs", "ramfs", flags.c_str());
ramfs_demangler_on_fs_mount("/game/test", "/sd0/test.ifs", "imagefs", nullptr);
@@ -264,9 +263,8 @@ TEST(RamFs, DemanglingWorksNabla) {
ramfs_demangler_on_fs_open("/data/graphics/ver07/logo.ifs", fake_handle);
ramfs_demangler_on_fs_read(fake_handle, fake_buffer);
char* flags = snprintf_auto("base=0x%llx", (unsigned long long)(uintptr_t)fake_buffer);
ramfs_demangler_on_fs_mount("/mnt/bm2d/rmp_89_2714881", "image.bin", "ramfs", flags);
free(flags);
std::string flags = std::format("base={:#x}", (uintptr_t)fake_buffer);
ramfs_demangler_on_fs_mount("/mnt/bm2d/rmp_89_2714881", "image.bin", "ramfs", flags.c_str());
ramfs_demangler_on_fs_mount("/mnt/bm2d/rfs88r89/logo.ifs", "/mnt/bm2d/rmp_89_2714881/image.bin", "link", "");
ramfs_demangler_on_fs_mount("/mnt/bm2d/ngp88/logo.ifs", "/mnt/bm2d/rfs88r89/logo.ifs", "imagefs", nullptr);
@@ -382,9 +380,8 @@ TEST(ArcArchive, MergedXmlInsideArcWithOriginalInsideArc) {
static void exercise_inner_ifs_demangle(std::string const& arc_path) {
// The buffer pointer doesn't matter — basename lookup is the fallback path
uint8_t fake_buffer[1];
char* flags = snprintf_auto("base=0x%llx", (unsigned long long)(uintptr_t)fake_buffer);
ramfs_demangler_on_fs_mount("/sd9", "inner.ifs", "ramfs", flags);
free(flags);
std::string flags = std::format("base={:#x}", (uintptr_t)fake_buffer);
ramfs_demangler_on_fs_mount("/sd9", "inner.ifs", "ramfs", flags.c_str());
ramfs_demangler_on_fs_mount("/game/inner_test", "/sd9/inner.ifs", "imagefs", nullptr);
std::string p = "/game/inner_test/some_subfile";

View File

@@ -50,12 +50,12 @@ class TexbinHdr {
void debug() {
log_misc("texbin hdr");
log_misc(" archive size: %" PRId32, archive_size);
log_misc(" file count: %" PRId32, file_count);
log_misc(" data offset: %" PRId32, data_offset);
log_misc(" rect offset: %" PRId32, rect_offset);
log_misc(" name offset: %" PRId32, name_offset);
log_misc(" data entry offset: %" PRId32, data_entry_offset);
log_misc(" archive size: {}", archive_size);
log_misc(" file count: {}", file_count);
log_misc(" data offset: {}", data_offset);
log_misc(" rect offset: {}", rect_offset);
log_misc(" name offset: {}", name_offset);
log_misc(" data entry offset: {}", data_entry_offset);
}
};
@@ -73,8 +73,8 @@ class TexbinNamesHdr {
void debug() {
log_misc("texbin names hdr");
log_misc(" section size: %" PRId32, sect_size);
log_misc(" names count: %" PRId32, names_count);
log_misc(" section size: {}", sect_size);
log_misc(" names count: {}", names_count);
}
};
@@ -90,10 +90,10 @@ class TexbinRectHdr {
void debug() {
log_misc("texbin rect hdr");
log_misc(" section size: %" PRId32, sect_size);
log_misc(" image count: %" PRId32, image_count);
log_misc(" name offset: %" PRId32, name_offset);
log_misc(" entries offset: %" PRId32, rect_entry_offset);
log_misc(" section size: {}", sect_size);
log_misc(" image count: {}", image_count);
log_misc(" name offset: {}", name_offset);
log_misc(" entries offset: {}", rect_entry_offset);
}
};
@@ -227,7 +227,7 @@ static vector<string> load_names(istream &f, uint32_t name_offset) {
TexbinNameEntry entry;
for(uint32_t i = 0; i < name_hdr.names_count; i++) {
if(!f.read((char*)&entry, sizeof(entry))) {
log_warning("bad name entry at %" PRId32, i);
log_warning("bad name entry at {}", i);
return ret;
}
auto pos = f.tellg();
@@ -239,7 +239,7 @@ static vector<string> load_names(istream &f, uint32_t name_offset) {
name += ch;
}
if(!f) {
log_warning("bad name entry at %" PRId32, i);
log_warning("bad name entry at {}", i);
return ret;
}
ret[entry.id] = name;
@@ -261,7 +261,7 @@ static vector<vector<uint8_t>> load_data(istream &f, const TexbinHdr& hdr) {
TexbinDataEntry entry;
for(uint32_t i = 0; i < hdr.file_count; i++) {
if(!f.read((char*)&entry, sizeof(entry))) {
log_warning("bad data entry at %" PRId32, i);
log_warning("bad data entry at {}", i);
return ret;
}
auto pos = f.tellg();
@@ -274,9 +274,7 @@ static vector<vector<uint8_t>> load_data(istream &f, const TexbinHdr& hdr) {
// actual data len, so they're not broken.
uint32_t sizes[2];
if(!f.read((char*)&sizes[0], sizeof(sizes))) {
log_warning("can't read data at i %" PRId32 " offset %" PRId32,
i, entry.offset
);
log_warning("can't read data at i {} offset {}", i, entry.offset);
return ret;
}
@@ -293,9 +291,7 @@ static vector<vector<uint8_t>> load_data(istream &f, const TexbinHdr& hdr) {
vector<uint8_t> data;
data.resize(entry.size);
if(!f.read((char*)&data[0], entry.size)) {
log_warning("can't read data at i %" PRId32 " offset %" PRId32 " len %" PRId32,
i, entry.offset, entry.size
);
log_warning("can't read data at i {} offset {} len {}", i, entry.offset, entry.size);
return ret;
}
ret.push_back(data);
@@ -388,7 +384,7 @@ bool Texbin::add_or_replace_image(const char *image_name, const char *png_path)
unsigned width, height;
error = lodepng::decode(image, width, height, png_path);
if (error) {
log_warning("Can't load png %u: %s\n", error, lodepng_error_text(error));
log_warning("Can't load png {}: {}", error, lodepng_error_text(error));
return false;
}
@@ -397,25 +393,25 @@ bool Texbin::add_or_replace_image(const char *image_name, const char *png_path)
// rect image names may shadow normal image names, so check them first
if(existing_rect != rects.end()) {
if(width != existing_rect->second.w || height != existing_rect->second.h) {
log_info("Replacement rect image %s has dimensions %dx%d but original is %dx%d, ignoring",
log_info("Replacement rect image {} has dimensions {}x{} but original is {}x{}, ignoring",
image_name, width, height, existing_rect->second.w, existing_rect->second.h
);
return false;
}
log_info("Replacing rect image %s", image_name);
log_info("Replacing rect image {}", image_name);
existing_rect->second.dirty_data = image;
} else if(existing_image != images.end()) {
auto [w, h] = existing_image->second.peek_dimensions();
if(width != w || height != h) {
log_info("Replacement image %s has dimensions %dx%d but original is %dx%d, repacking anyway",
log_info("Replacement image {} has dimensions {}x{} but original is {}x{}, repacking anyway",
image_name, width, height, w, h
);
}
log_info("Replacing %s", image_name);
log_info("Replacing {}", image_name);
images[image_name] = ImageEntryParsed(argb8888_to_texture_data(&image[0], width, height));
} else{
log_info("Adding new image %s", image_name);
log_info("Adding new image {}", image_name);
images[image_name] = ImageEntryParsed(argb8888_to_texture_data(&image[0], width, height));
}
@@ -459,7 +455,11 @@ optional<Texbin> Texbin::from_stream(istream &f) {
}
if(hdr.archive_size != file_len) {
log_warning("bad archive size (file said %d stream said %d)", hdr.archive_size, file_len);
log_warning("bad archive size (file said {} stream said {})",
hdr.archive_size,
// TODO: hope that P3374R1 is implemented for C++26?
static_cast<std::streamoff>(file_len)
);
return nullopt;
}
@@ -520,7 +520,7 @@ optional<Texbin> Texbin::from_stream(istream &f) {
}
if(entry.x1 >= entry.x2 || entry.y1 >= entry.y2) {
log_warning("rect entry has invalid dimensions (%d,%d,%d,%d)",
log_warning("rect entry has invalid dimensions ({},{},{},{})",
entry.x1, entry.x2, entry.y1, entry.y2
);
return nullopt;
@@ -546,7 +546,7 @@ optional<Texbin> Texbin::from_stream(istream &f) {
optional<Texbin> Texbin::from_path(const char *path) {
// there are a handful of .bin files we might try to parse that *aren't*
// texbins, so gate all logs before header magic check behind log_verbose
log_verbose("Opening %s", path);
log_verbose("Opening {}", path);
ifstream f (path, ios::binary);
if(!f) {
log_verbose("cannot open");
@@ -568,21 +568,21 @@ void Texbin::process_dirty_rects() {
for(auto &[rect_name, rects] : updates) {
auto _image = images.find(rect_name);
if(_image == images.end()) {
log_warning("Can't update rect %s: no tex???", rect_name.c_str());
log_warning("Can't update rect {}: no tex???", rect_name);
continue;
}
auto image = &_image->second;
auto _tex = image->tex_to_argb8888();
if(!_tex) {
log_warning("Can't update rect %s: cannot load tex", rect_name.c_str());
log_warning("Can't update rect {}: cannot load tex", rect_name);
continue;
}
auto [tex, width, height] = *_tex;
for(auto &rect : rects) {
if(rect->x2() > width || rect->y2() > height) {
log_warning("Can't update rect in %s: out of bounds (canvas is %dx%d, rect is x1,x2,y1,y2 %d,%d,%d,%d)",
rect_name.c_str(),
log_warning("Can't update rect in {}: out of bounds (canvas is {}x{}, rect is x1,x2,y1,y2 {},{},{},{})",
rect_name,
width,
height,
rect->x, rect->x2(), rect->y, rect->y2()
@@ -657,8 +657,8 @@ bool Texbin::save(const char *dest) {
for(auto &[name, rect] : rects) {
auto parent = images.find(rect.parent_name);
if(parent == images.end()) {
log_warning("Rect entry \"%s\" has an invalid parent name \"%s\"",
name.c_str(), rect.parent_name.c_str()
log_warning("Rect entry \"{}\" has an invalid parent name \"{}\"",
name, rect.parent_name
);
return false;
}
@@ -891,7 +891,7 @@ optional<tuple<vector<uint8_t>, uint16_t, uint16_t>> ImageEntryParsed::tex_to_ar
break;
default:
log_warning("Unsupported tex format type 0x%X", hdr->format1 & 0xFF);
log_warning("Unsupported tex format type {:#x}", hdr->format1 & 0xFF);
return nullopt;
}

View File

@@ -4,21 +4,9 @@
#include <algorithm>
#include "utils.hpp"
#include "log.hpp"
#include "avs.h"
#include "hook.h"
char* snprintf_auto(const char* fmt, ...) {
va_list argList;
va_start(argList, fmt);
size_t len = vsnprintf(NULL, 0, fmt, argList);
auto s = (char*)malloc(len + 1);
vsnprintf(s, len + 1, fmt, argList);
va_end(argList);
return s;
}
bool string_ends_with(const char * str, const char * suffix) {
size_t str_len = strlen(str);
size_t suffix_len = strlen(suffix);
@@ -227,7 +215,7 @@ uint64_t file_time(const char* path) {
ULARGE_INTEGER result;
result.LowPart = mtime.dwLowDateTime;
result.HighPart = mtime.dwHighDateTime;
// log_verbose("file time %lu for %s", result.QuadPart, path);
// log_verbose("file time {} for {}", result.QuadPart, path);
return result.QuadPart;
// NOTE: can't use this method because the DLL time is taken before AVS is
@@ -236,7 +224,7 @@ uint64_t file_time(const char* path) {
// struct avs_stat st;
// auto res = avs_fs_lstat(path, &st);
// if (res) {
// log_verbose("file time %ld for %s", st.st_mtime, path);
// log_verbose("file time {} for {}", st.st_mtime, path);
// return st.st_mtime;
// } else {
// return 0;

View File

@@ -13,7 +13,6 @@
#define lenof(x) (sizeof(x) / sizeof(*x))
char* snprintf_auto(const char* fmt, ...);
bool string_ends_with(const char * str, const char * suffix);
bool string_ends_with(const std::string &str, const char * suffix);
// case insensitive