aboutsummaryrefslogtreecommitdiff
path: root/buildtools/codegen/CodegenUtils.inl
diff options
context:
space:
mode:
Diffstat (limited to 'buildtools/codegen/CodegenUtils.inl')
-rw-r--r--buildtools/codegen/CodegenUtils.inl106
1 files changed, 106 insertions, 0 deletions
diff --git a/buildtools/codegen/CodegenUtils.inl b/buildtools/codegen/CodegenUtils.inl
new file mode 100644
index 0000000..f9d913e
--- /dev/null
+++ b/buildtools/codegen/CodegenUtils.inl
@@ -0,0 +1,106 @@
+#pragma once
+
+#include "CodegenConfig.hpp"
+#include "CodegenMacros.hpp"
+
+#include "CodegenOutput.inl"
+
+#include <Macros.hpp>
+#include <ScopeGuard.hpp>
+
+#include <cstdio>
+#include <cstdlib>
+#include <filesystem>
+
+namespace Utils {
+
+std::string ReadFileAsString(const std::filesystem::path& path) {
+ auto file = Utils::OpenCstdioFile(path, Utils::Read);
+ if (!file) throw std::runtime_error("Failed to open source file.");
+ DEFER { fclose(file); };
+
+ fseek(file, 0, SEEK_END);
+ auto fileSize = ftell(file);
+ rewind(file);
+
+ std::string result(fileSize, '\0');
+ fread(result.data(), fileSize, 1, file);
+
+ return result;
+}
+
+bool WriteOutputFile(const CodegenOutput& output, std::string_view dir, std::string_view filename, std::string_view additionalSuffix = {}) {
+ char path[2048];
+ snprintf(path, sizeof(path), "%.*s/%.*s%.*s", PRINTF_STRING_VIEW(dir), PRINTF_STRING_VIEW(filename), PRINTF_STRING_VIEW(additionalSuffix));
+
+ auto outputFile = Utils::OpenCstdioFile(path, Utils::WriteTruncate);
+ if (!outputFile) {
+ printf("[ERROR] unable to open output file %s\n", path);
+ return false;
+ }
+ DEFER { fclose(outputFile); };
+
+ DEBUG_PRINTF("Writing output %s\n", path);
+ output.Write(outputFile);
+
+ return true;
+}
+
+std::string MakeFullName(std::string_view name, DeclNamespace* ns = nullptr) {
+ size_t length = 0;
+ std::vector<std::string_view> components;
+ if (!name.empty()) {
+ components.push_back(name);
+ length += name.length();
+ }
+
+ DeclNamespace* currentNamespace = ns;
+ while (currentNamespace) {
+ components.push_back(currentNamespace->name);
+ length += currentNamespace->name.size() + /*::*/ 2;
+ currentNamespace = currentNamespace->container;
+ }
+
+ std::string fullname;
+ fullname.reserve(length);
+ for (auto it = components.rbegin(); it != components.rend(); ++it) {
+ fullname += *it;
+ fullname += "::";
+ }
+ // Get rid of the last "::"
+ fullname.pop_back();
+ fullname.pop_back();
+
+ return fullname;
+}
+
+void ProduceGeneratedHeaderFileHeader(CodegenOutput& output) {
+ output.AddOutputThing(CodegenOutputThing{
+ .text = &R"""(
+// This file is generated. Any changes will be overidden when building.
+#pragma once
+
+#include <MetadataBase.hpp>
+
+#include <cstddef>
+#include <cstdint>
+)"""[1],
+ });
+}
+
+void ProduceGeneratedSourceFileHeader(CodegenOutput& output) {
+ output.AddOutputThing(CodegenOutputThing{
+ .text = &R"""(
+// This file is generated. Any changes will be overidden when building.
+#include "GeneratedCode.hpp"
+
+#include <cstddef>
+#include <cstdint>
+#include <frozen/string.h>
+#include <frozen/unordered_map.h>
+using namespace std::literals;
+ )"""[1],
+ });
+}
+
+} // namespace Utils