diff options
author | nechda <nechda@yandex-team.com> | 2025-02-02 19:59:53 +0300 |
---|---|---|
committer | nechda <nechda@yandex-team.com> | 2025-02-02 20:17:55 +0300 |
commit | b376b6fe5994a31f79310fb1e2b28e47dc63db5b (patch) | |
tree | bffb1f76a77d9332c5b776bf541227cf8da4924e /tools/rescompiler/main.cpp | |
parent | e249111c11224174f38e5fb2160fcf9348243f3d (diff) | |
download | ydb-b376b6fe5994a31f79310fb1e2b28e47dc63db5b.tar.gz |
Gen only symbol decls in rescompiler
commit_hash:dad3368a28275822296201186f2b0645f7404837
Diffstat (limited to 'tools/rescompiler/main.cpp')
-rw-r--r-- | tools/rescompiler/main.cpp | 114 |
1 files changed, 95 insertions, 19 deletions
diff --git a/tools/rescompiler/main.cpp b/tools/rescompiler/main.cpp index 98a5b9413b..31d07680c8 100644 --- a/tools/rescompiler/main.cpp +++ b/tools/rescompiler/main.cpp @@ -8,52 +8,128 @@ #include <util/string/vector.h> #include <util/string/split.h> +static inline void Formatter(IOutputStream& stream, std::string_view fmt, TVector<std::string_view>&& views) { + constexpr auto INF = std::string::npos; + size_t pos = 0; + auto view = views.begin(); + while (pos != INF && pos < fmt.size()) { + size_t found = fmt.find("{}", pos); + stream << fmt.substr(pos, found == INF ? INF : found - pos); + pos = found == INF ? INF : found + 2; + if (view != views.end()) { + stream << *view; + ++view; + } + } +} + using namespace NResource; -static inline void GenOne(const TString& data, const TString& key, IOutputStream& out) { - const TString name = "name" + ToString(CityHash64(key.data(), key.size())); +static inline void EmitHex(IOutputStream& stream, const TString& view) { + const unsigned char* data = reinterpret_cast<const unsigned char*>(view.data()); + size_t len = view.size(); - out << "static const unsigned char " << name << "[] = {"; + constexpr size_t CHAR2HEX = 5; // len('0x??,') == 5 + constexpr size_t MAX_STEP = 16; + constexpr size_t STEPS[] = {MAX_STEP, 1}; - const TString c = Compress(data); - char buf[16]; + auto print = [](char* out, const unsigned char* iter, const unsigned char* end) { + char templ[CHAR2HEX + 1] = "0x??,"; + while (iter != end) { + HexEncode(iter, 1ULL, templ + 2ULL); + memcpy(out, templ, CHAR2HEX); + iter++; + out += CHAR2HEX; + } + }; - for (size_t i = 0; i < c.size(); ++i) { - if ((i % 10) == 0) { - out << "\n "; + char buf[CHAR2HEX * MAX_STEP + 4] = {}; + for (size_t step : STEPS) { + while (len >= step) { + print(buf, data, data + step); + buf[CHAR2HEX * step] = 0; + len -= step; + data += step; + stream << buf << (step > 1 ? "\n" : ""); } + } + stream << '\n'; +} - const char ch = c[i]; +static inline void EmitHexArray(const TString& data, const TString& varName, IOutputStream& out) { + const TString c = Compress(data); + out << "static const unsigned char " << varName << "[] = {\n"; + EmitHex(out, c); + out << "};\n"; +} - out << "0x" << TStringBuf(buf, HexEncode(&ch, 1, buf)) << ", "; +static inline void GenOne(const TString& data, const TString& key, IOutputStream& out, bool isFile, bool useSections) { + const TString name = "name" + ToString(CityHash64(key.data(), key.size())); + + if (useSections) { + if (isFile) { + Formatter(out, R"__( + extern "C" const char {}[]; + extern "C" const char {}_end[]; + static const int REG_{} = NResource::LightRegisterI("{}", {}, {}_end); + )__", {data, data, name, key, data, data}); + } else { + EmitHexArray(data, name, out); + Formatter(out, R"__( + static const int REG_{} = NResource::LightRegisterS("{}", (const char*){}, sizeof({})); + )__", {name, key, name, name}); + } + return; } - out << "\n};\n\nstatic const NResource::TRegHelper REG_" << name << "(\"" << key << "\", TStringBuf((const char*)" << name << ", sizeof(" << name << ")));\n"; + EmitHexArray(data, name, out); + Formatter(out, R"__( + static const NResource::TRegHelper REG_{}("{}", TStringBuf((const char*){}, sizeof({}))); + )__", {name, key, name, name}); } -int main(int argc, char** argv) { - if ((argc < 4) || (argc % 2)) { - Cerr << "usage: " << argv[0] << " outfile [infile path]+ [- key=value]+" << Endl; +static inline void EmitHeader(IOutputStream& out, bool useSections) { + if (useSections) { + out << R"__( + // This function are defined in "library/cpp/resource/registry.cpp" + namespace NResource { + int LightRegisterS(const char*, const char*, unsigned long); + int LightRegisterI(const char*, const char*, const char*); + } + )__"; + } else { + out << "#include <library/cpp/resource/registry.h>\n"; + } +} +int main(int argc, char** argv) { + if (argc < 4) { + Cerr << "usage: " << argv[0] << " outfile [?--use-sections] [infile path]+ [- key=value]+" << Endl; return 1; } TFixedBufferFileOutput out(argv[1]); + bool useSections = false; + if (TStringBuf(argv[2]) == "--use-sections") { + useSections = true; + argv += 3; + } else { + argv += 2; + } - argv = argv + 2; - - out << "#include <library/cpp/resource/registry.h>\n\n"; + EmitHeader(out, useSections); while (*argv) { if ("-"sv == *argv) { TVector<TString> items = StringSplitter(TString(*(argv + 1))).Split('=').Limit(2).ToList<TString>(); - GenOne(TString(items[1]), TString(items[0]), out); + GenOne(TString(items[1]), TString(items[0]), out, false /*isFile*/, useSections); } else { const char* key = *(argv + 1); if (*key == '-') { ++key; } - GenOne(TUnbufferedFileInput(*argv).ReadAll(), key, out); + TString data = useSections ? *argv : TUnbufferedFileInput(*argv).ReadAll(); + GenOne(data, key, out, true /*isFile*/, useSections); } argv += 2; } |