aboutsummaryrefslogtreecommitdiffstats
path: root/tools/rescompiler/main.cpp
diff options
context:
space:
mode:
authornechda <nechda@yandex-team.com>2025-02-02 19:59:53 +0300
committernechda <nechda@yandex-team.com>2025-02-02 20:17:55 +0300
commitb376b6fe5994a31f79310fb1e2b28e47dc63db5b (patch)
treebffb1f76a77d9332c5b776bf541227cf8da4924e /tools/rescompiler/main.cpp
parente249111c11224174f38e5fb2160fcf9348243f3d (diff)
downloadydb-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.cpp114
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;
}