Files
WoWee/tools/framexml_compile_check.cpp
Kelsi ab81f0e60b fix: report why each FrameXML file failed, and imply the API fallback
Sixty-seven failures arrived with their reasons scattered across thousands
of log lines, and one broken script takes down every file referencing it,
so what matters is seeing them together. Collect a reason per file and
print them as one block; carry the real cause up through includes and
referenced scripts rather than naming the file that referenced them.

WOWEE_LOAD_FRAMEXML now implies WOWEE_LUA_API_FALLBACK. FrameXML cannot
get through its own load without it, so two switches where one is useless
alone was only a way to be handed a wall of failures for setting the
obvious one.

The compile checker counted a file it could not parse as neither pass nor
fail, reporting a clean run over files that never loaded.
2026-08-01 13:34:52 -07:00

59 lines
2.4 KiB
C++

// Does the Lua we generate from FrameXML actually compile?
//
// The unit tests check the shape of the output against cases someone thought
// of. This asks Lua itself about every real file, which is a different and
// harsher question — it found an empty function attribute emitting
// SetScript("X", ), and temporaries running into Lua's limit of 200 locals per
// function. Neither degrades: the whole chunk refuses to compile.
//
// Build (needs the project's lua51 built):
// g++ -std=c++20 -Iinclude -Iextern/lua-5.1.5/src \
// tools/framexml_compile_check.cpp src/ui/xml_parser.cpp \
// src/ui/framexml_emitter.cpp build/lib/liblua51.a -o /tmp/fxcheck
// /tmp/fxcheck Data/interface/framexml
// Emits every FrameXML file and asks Lua whether the result compiles.
extern "C" {
#include "lua.h"
#include "lauxlib.h"
}
#include "ui/xml_parser.hpp"
#include "ui/framexml_emitter.hpp"
#include <cstdio>
#include <filesystem>
#include <fstream>
#include <sstream>
int main(int argc, char** argv) {
lua_State* L = luaL_newstate();
int ok = 0, bad = 0, shown = 0, unparsed = 0;
for (auto& e : std::filesystem::directory_iterator(argv[1])) {
if (e.path().extension() != ".xml") continue;
std::ifstream f(e.path()); std::stringstream ss; ss << f.rdbuf();
wowee::ui::XmlNode root; std::string err;
// Counted, not skipped. A file the reader cannot get through never
// reaches the compiler at all, so passing over it quietly reports a
// clean run on files that in fact never loaded.
if (!wowee::ui::parseXml(ss.str(), root, err)) {
++unparsed;
printf(" UNPARSED %-30s %s\n", e.path().filename().string().c_str(),
err.c_str());
continue;
}
auto r = wowee::ui::emitFrameXml(root);
if (r.lua.empty()) { ++ok; continue; }
std::string chunk = "local __WoweeTemplates={} "
"local function __WoweeMissingTemplate() end\n" + r.lua;
if (luaL_loadbuffer(L, chunk.c_str(), chunk.size(), "=chunk") == 0) { ++ok; }
else {
++bad;
if (shown++ < 6)
printf(" FAIL %-34s %s\n", e.path().filename().string().c_str(),
lua_tostring(L, -1));
}
lua_settop(L, 0);
}
printf("emitted Lua compiles: %d fails: %d unparsed XML: %d\n",
ok, bad, unparsed);
return 0;
}