#pragma once #include "CodegenConfig.hpp" #include "CodegenMacros.hpp" #include "CodegenOutput.inl" #include #include #include #include #include namespace Utils { bool WriteOutputFile(const CodegenOutput& output, const char* path) { 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 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 ProduceGeneratedHeader(const char* headerFilename, CodegenOutput& header, const char* sourceFilename, CodegenOutput& source) { CodegenOutputThing headerOut; headerOut.text += &R"""( // This file is generated. Any changes will be overidden when building. #pragma once #include #include #include )"""[1]; CodegenOutputThing sourceOut; APPEND_LIT_LN(sourceOut.text, "// This file is generated. Any changes will be overidden when building."); APPEND_FMT_LN(sourceOut.text, "#include \"%s\"", headerFilename); sourceOut.text += &R"""( #include #include using namespace std::literals; )"""[1]; header.AddOutputThing(std::move(headerOut)); source.AddOutputThing(std::move(sourceOut)); } } // namespace Utils