From ec569768fe9ece8f7db3458a9df8788f569bbe38 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sat, 9 May 2026 14:50:27 -0700 Subject: [PATCH] refactor(editor): hoist consumeJsonFlag into cli_arg_parse.hpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pattern bool jsonOut = (i + 1 < argc && std::strcmp(argv[i + 1], "--json") == 0); if (jsonOut) i++; is repeated ~50 times across the editor — every --info-* and --validate-* handler writes the same three lines to detect and consume an optional --json follower. Extract to consumeJsonFlag(int& i, int argc, char** argv) in cli_arg_parse.hpp (the same header that already hosts parseOptInt / parseOptFloat / parseOptUint / parseOptArg for similar repeated patterns). Adopted in the recently-added files: • cli_world_map.cpp — both --info-womx and --validate-womx • cli_sound_catalog.cpp — both --info-wsnd and --validate-wsnd • cli_wom_info.cpp — all 7 --info-* / --validate-wom handlers (replace_all) Also adopted the shared stripExt() helper from cli_box_emitter.hpp instead of the new files' rolled- own stripWomxExt / stripWsndExt — same observable behavior, no more local copies of the extension-strip logic. Future --info-/-validate handlers added to other formats (WSP, WTC, etc.) get the same one-line jsonOut detection without reinventing the peek-and-advance dance. Any later adoption of consumeJsonFlag in the older 50+ sites is now a mechanical replace_all edit per file. Behavior preserved: --validate-wom and --info-womx and --info-wsnd round-trip exactly as before, both text and --json output unchanged. --- tools/editor/cli_arg_parse.hpp | 13 +++++++++++++ tools/editor/cli_sound_catalog.cpp | 13 +++++-------- tools/editor/cli_wom_info.cpp | 29 ++++++++--------------------- tools/editor/cli_world_map.cpp | 13 +++++-------- 4 files changed, 31 insertions(+), 37 deletions(-) diff --git a/tools/editor/cli_arg_parse.hpp b/tools/editor/cli_arg_parse.hpp index 2c920cec..1788b55a 100644 --- a/tools/editor/cli_arg_parse.hpp +++ b/tools/editor/cli_arg_parse.hpp @@ -40,6 +40,19 @@ inline void parseOptUint(int& i, int argc, char** argv, uint32_t& value) { } } +// Common --json-output flag pattern: every --info-* / --validate-* +// handler (~50 sites across the editor) writes the same three lines +// to detect and consume an optional `--json` follower. Hoisted here +// so future handlers can do `bool jsonOut = consumeJsonFlag(i, argc, argv);` +// instead of the open-coded peek-and-advance. +inline bool consumeJsonFlag(int& i, int argc, char** argv) { + if (i + 1 < argc && std::strcmp(argv[i + 1], "--json") == 0) { + ++i; + return true; + } + return false; +} + } // namespace cli } // namespace editor } // namespace wowee diff --git a/tools/editor/cli_sound_catalog.cpp b/tools/editor/cli_sound_catalog.cpp index 0a1a3912..1988af03 100644 --- a/tools/editor/cli_sound_catalog.cpp +++ b/tools/editor/cli_sound_catalog.cpp @@ -1,4 +1,6 @@ #include "cli_sound_catalog.hpp" +#include "cli_arg_parse.hpp" +#include "cli_box_emitter.hpp" #include "pipeline/wowee_sound.hpp" #include @@ -17,8 +19,7 @@ namespace cli { namespace { std::string stripWsndExt(std::string base) { - if (base.size() >= 5 && base.substr(base.size() - 5) == ".wsnd") - base = base.substr(0, base.size() - 5); + stripExt(base, ".wsnd"); return base; } @@ -82,9 +83,7 @@ int handleGenTavern(int& i, int argc, char** argv) { int handleInfo(int& i, int argc, char** argv) { std::string base = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); base = stripWsndExt(base); if (!wowee::pipeline::WoweeSoundLoader::exists(base)) { std::fprintf(stderr, "WSND not found: %s.wsnd\n", base.c_str()); @@ -138,9 +137,7 @@ int handleInfo(int& i, int argc, char** argv) { int handleValidate(int& i, int argc, char** argv) { std::string base = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); base = stripWsndExt(base); if (!wowee::pipeline::WoweeSoundLoader::exists(base)) { std::fprintf(stderr, diff --git a/tools/editor/cli_wom_info.cpp b/tools/editor/cli_wom_info.cpp index 9b4230f6..08124dbf 100644 --- a/tools/editor/cli_wom_info.cpp +++ b/tools/editor/cli_wom_info.cpp @@ -1,4 +1,5 @@ #include "cli_wom_info.hpp" +#include "cli_arg_parse.hpp" #include "pipeline/wowee_model.hpp" #include "pipeline/wowee_building.hpp" @@ -27,9 +28,7 @@ namespace { int handleInfo(int& i, int argc, char** argv) { std::string base = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); // Allow either "/path/to/file.wom" or "/path/to/file"; load() expects no extension. if (base.size() >= 4 && base.substr(base.size() - 4) == ".wom") base = base.substr(0, base.size() - 4); @@ -76,9 +75,7 @@ int handleInfoBatches(int& i, int argc, char** argv) { // for debugging 'why is this submesh transparent?' or // 'which batch has the bad UV?'. std::string base = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); if (base.size() >= 4 && base.substr(base.size() - 4) == ".wom") base = base.substr(0, base.size() - 4); if (!wowee::pipeline::WoweeModelLoader::exists(base)) { @@ -165,9 +162,7 @@ int handleInfoTextures(int& i, int argc, char** argv) { // forms. Useful for tracking which textures are missing // before --pack-wcp would fail at runtime. std::string base = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); if (base.size() >= 4 && base.substr(base.size() - 4) == ".wom") base = base.substr(0, base.size() - 4); if (!wowee::pipeline::WoweeModelLoader::exists(base)) { @@ -245,9 +240,7 @@ int handleInfoDoodads(int& i, int argc, char** argv) { // a building). Companion to --info-textures: where one // tracks GPU resources, this tracks scene composition. std::string base = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); if (base.size() >= 4 && base.substr(base.size() - 4) == ".wob") base = base.substr(0, base.size() - 4); if (!wowee::pipeline::WoweeBuildingLoader::exists(base)) { @@ -307,9 +300,7 @@ int handleInfoAttachParticleSequence(int& i, int argc, char** argv) { kind = kSequence; cmdName = "info-sequences"; } std::string path = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); std::ifstream in(path, std::ios::binary); if (!in) { std::fprintf(stderr, "%s: cannot open %s\n", cmdName, path.c_str()); @@ -480,9 +471,7 @@ int handleInfoBones(int& i, int argc, char** argv) { // debugging skeleton structure when something looks wrong // in the renderer ('why is this bone not following its parent?'). std::string path = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); std::ifstream in(path, std::ios::binary); if (!in) { std::fprintf(stderr, "info-bones: cannot open %s\n", path.c_str()); @@ -548,9 +537,7 @@ int handleValidateWom(int& i, int argc, char** argv) { // failed check with details and exits non-zero on any // failure; clean models print a single OK line. std::string base = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); if (base.size() >= 4 && base.substr(base.size() - 4) == ".wom") base = base.substr(0, base.size() - 4); if (!wowee::pipeline::WoweeModelLoader::exists(base)) { diff --git a/tools/editor/cli_world_map.cpp b/tools/editor/cli_world_map.cpp index ccc6c539..cf050912 100644 --- a/tools/editor/cli_world_map.cpp +++ b/tools/editor/cli_world_map.cpp @@ -1,4 +1,6 @@ #include "cli_world_map.hpp" +#include "cli_arg_parse.hpp" +#include "cli_box_emitter.hpp" #include "pipeline/wowee_world_map.hpp" #include @@ -17,8 +19,7 @@ namespace cli { namespace { std::string stripWomxExt(std::string base) { - if (base.size() >= 5 && base.substr(base.size() - 5) == ".womx") - base = base.substr(0, base.size() - 5); + stripExt(base, ".womx"); return base; } @@ -79,9 +80,7 @@ int handleGenArena(int& i, int argc, char** argv) { int handleInfo(int& i, int argc, char** argv) { std::string base = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); base = stripWomxExt(base); if (!wowee::pipeline::WoweeWorldMapLoader::exists(base)) { std::fprintf(stderr, "WOMX not found: %s.womx\n", base.c_str()); @@ -256,9 +255,7 @@ int handleImportJson(int& i, int argc, char** argv) { int handleValidate(int& i, int argc, char** argv) { std::string base = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; + bool jsonOut = consumeJsonFlag(i, argc, argv); base = stripWomxExt(base); if (!wowee::pipeline::WoweeWorldMapLoader::exists(base)) { std::fprintf(stderr, "validate-womx: WOMX not found: %s.womx\n",