aboutsummaryrefslogtreecommitdiff
path: root/buildtools/codegen/main.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-05-30 13:09:26 -0700
committerrtk0c <[email protected]>2022-05-30 13:09:26 -0700
commitce9559e8c2b69d46cff064241bd9a04c014af44f (patch)
tree370c793d4fde63f4bd4d988d73a3c4d9353ede56 /buildtools/codegen/main.cpp
parentcdd84f25ab1d2a57ee5c7b4c954e35a8d7e2dca3 (diff)
Changeset: 51 Add integration into the main game
Diffstat (limited to 'buildtools/codegen/main.cpp')
-rw-r--r--buildtools/codegen/main.cpp154
1 files changed, 44 insertions, 110 deletions
diff --git a/buildtools/codegen/main.cpp b/buildtools/codegen/main.cpp
index 298f19e..3a3e443 100644
--- a/buildtools/codegen/main.cpp
+++ b/buildtools/codegen/main.cpp
@@ -4,6 +4,7 @@
#include "CodegenInput.inl"
#include "CodegenOutput.inl"
+#include "CodegenUtils.inl"
#include <Enum.hpp>
#include <LookupTable.hpp>
@@ -27,10 +28,12 @@ using namespace std::literals;
namespace fs = std::filesystem;
// TODO handle namespace
+// TODO support codegen target in .cpp files
struct AppState {
- CodegenOutput headerOutput;
- CodegenOutput sourceOutput;
+ std::string_view outputDir;
+ CodegenOutput mainHeaderOutput;
+ CodegenOutput mainSourceOutput;
};
enum {
@@ -113,7 +116,7 @@ bool StbTokenIsMultiChar(int lexerToken) {
void CheckBraceDepth(int braceDpeth) {
if (braceDpeth < 0) {
- printf("[WARNING] unbalanced brace");
+ printf("[WARNING] unbalanced brace\n");
}
}
@@ -197,7 +200,7 @@ std::vector<StbLexerToken> RecordTokens(std::string_view source) {
}
if (lexer.token == CLEX_parse_error) {
- printf("[ERROR] stb_c_lexer countered a parse error.");
+ printf("[ERROR] stb_c_lexer countered a parse error.\n");
// TODO how to handle?
continue;
}
@@ -292,11 +295,6 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D
maxVal = decl.elements[decl.elements.size() - 2].value;
}
- CodegenOutputThing lookupFunctionDecl;
- auto& o1 = lookupFunctionDecl.text;
- APPEND_LIT_LN(o1, "template <>");
- APPEND_FMT_LN(o1, "std::string_view Metadata::EnumToString<%s>(%s);", decl.name.c_str(), decl.name.c_str());
-
CodegenOutputThing lookupFunctionDef;
auto& o2 = lookupFunctionDef.text;
APPEND_LIT_LN(o2, "template <>");
@@ -305,7 +303,6 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D
APPEND_FMT_LN(o2, " return %s[value - %d];", arrayName.c_str(), minVal);
APPEND_LIT_LN(o2, "}");
- headerOut.AddOutputThing(std::move(lookupFunctionDecl));
sourceOut.AddOutputThing(std::move(lookupFunctionDef));
} break;
@@ -337,11 +334,6 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D
APPEND_LIT_LN(o1, "};");
// Generate lookup function
- CodegenOutputThing lookupFunctionDecl;
- auto& o2 = lookupFunctionDecl.text;
- APPEND_LIT_LN(o2, "template <>");
- APPEND_FMT_LN(o2, "std::optional<%s> Metadata::EnumFromString<%s>(std::string_view);", decl.name.c_str(), decl.name.c_str());
-
CodegenOutputThing lookupFunctionDef;
auto& o3 = lookupFunctionDef.text;
APPEND_LIT_LN(o3, "template <>");
@@ -355,12 +347,11 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D
APPEND_LIT_LN(o3, "}");
sourceOut.AddOutputThing(std::move(lookupTable));
- headerOut.AddOutputThing(std::move(lookupFunctionDecl));
sourceOut.AddOutputThing(std::move(lookupFunctionDef));
}
}
-void HandleInputFile(AppState& state, std::string_view source) {
+void HandleInputFile(AppState& state, std::string_view filenameStem, std::string_view source) {
auto tokens = RecordTokens(source);
size_t idx = 0;
@@ -373,8 +364,10 @@ void HandleInputFile(AppState& state, std::string_view source) {
#endif
CodegenInput cgInput;
- auto& cgHeaderOutput = state.headerOutput;
- auto& cgSourceOutput = state.sourceOutput;
+ CodegenOutput cgHeaderOutput;
+ Utils::ProduceGeneratedHeaderFileHeader(cgHeaderOutput);
+ CodegenOutput cgSourceOutput;
+ Utils::ProduceGeneratedSourceFileHeader(cgSourceOutput);
int bracePairDepth = 0;
while (idx < tokens.size()) {
@@ -545,21 +538,9 @@ void HandleInputFile(AppState& state, std::string_view source) {
if (bracePairDepth != 0) {
printf("[WARNING] unbalanced brace at end of file.");
}
-}
-
-std::string ReadFileAtOnce(const fs::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;
+ Utils::WriteOutputFile(cgHeaderOutput, state.outputDir, filenameStem, ".gh.inl"sv);
+ Utils::WriteOutputFile(cgSourceOutput, state.outputDir, filenameStem, ".gs.inl"sv);
}
enum InputOpcode {
@@ -571,12 +552,17 @@ enum InputOpcode {
void HandleArgument(AppState& state, InputOpcode opcode, std::string_view operand) {
switch (opcode) {
case IOP_ProcessSingleFile: {
- fs::path filePath(operand);
- auto source = ReadFileAtOnce(filePath);
- HandleInputFile(state, source);
+ DEBUG_PRINTF("Processing single file %.*s\n", PRINTF_STRING_VIEW(operand));
+
+ fs::path path(operand);
+ auto filenameStem = path.stem().string();
+ auto source = Utils::ReadFileAsString(path);
+ HandleInputFile(state, filenameStem, source);
} break;
case IOP_ProcessRecursively: {
+ DEBUG_PRINTF("Recursively processing folder %.*s\n", PRINTF_STRING_VIEW(operand));
+
fs::path startPath(operand);
for (auto& item : fs::recursive_directory_iterator(startPath)) {
if (!item.is_regular_file()) {
@@ -584,15 +570,19 @@ void HandleArgument(AppState& state, InputOpcode opcode, std::string_view operan
}
auto& path = item.path();
- auto filename = path.filename().string();
- if (filename != ".c" ||
- filename != ".cpp")
+ auto pathExt = path.extension();
+ auto pathStem = path.stem();
+ if (pathExt != ".h" &&
+ pathExt != ".hpp")
{
continue;
}
- auto source = ReadFileAtOnce(path);
- HandleInputFile(state, source);
+ DEBUG_PRINTF("Processing subfile %s\n", path.string().c_str());
+
+ auto filenameStem = pathStem.string();
+ auto source = Utils::ReadFileAsString(path);
+ HandleInputFile(state, filenameStem, source);
}
} break;
@@ -605,25 +595,10 @@ InputOpcode ParseInputOpcode(std::string_view text) {
return IOP_ProcessSingleFile;
} else if (text == "rec"sv) {
return IOP_ProcessRecursively;
+ } else {
+ DEBUG_PRINTF("Unknown input opcode %s\n", text.data());
+ throw std::runtime_error("Unknown input opcode");
}
- return IOP_COUNT;
-}
-
-bool WriteOutputFile(const CodegenOutput& output, const char* dirPath, const char* fileName) {
- char path[2048];
- snprintf(path, sizeof(path), "%s/%s", dirPath, fileName);
-
- auto outputFile = Utils::OpenCstdioFile(path, Utils::WriteTruncate);
- if (!outputFile) {
- printf("[ERROR] unable to open output file %s", path);
- return false;
- }
- DEFER { fclose(outputFile); };
-
- DEBUG_PRINTF("Writing output %s", path);
- output.Write(outputFile);
-
- return true;
}
int main(int argc, char* argv[]) {
@@ -639,25 +614,8 @@ int main(int argc, char* argv[]) {
AppState state;
- state.headerOutput.AddOutputThing(CodegenOutputThing{
- .text = &R"""(
-// This file is generated. Any changes will be overidden when building.
-#pragma once
-
-#include <MetadataBase.hpp>
-)"""[1],
- });
-
- state.sourceOutput.AddOutputThing(CodegenOutputThing{
- .text = &R"""(
-// This file is generated. Any changes will be overidden when building.
-#include "MetadataImpl.hpp"
-
-#include <frozen/string.h>
-#include <frozen/unordered_map.h>
-using namespace std::literals;
- )"""[1],
- });
+ Utils::ProduceGeneratedHeaderFileHeader(state.mainHeaderOutput);
+ Utils::ProduceGeneratedSourceFileHeader(state.mainSourceOutput);
// If no cli is provided (argv[0] conventionally but not mandatorily the cli), this will do thing
// Otherwise, start with the 2nd element in the array, which is the 1st actual argument
@@ -668,55 +626,31 @@ USAGE: codegen.exe <output path> [<opcode>:<input path>]...
where <output path>: the directory to write generated contents to. This will NOT automatically create the directory.
<opcode> is one of:
"single" process this <input path> file only
- "rec" starting at the given directory <input path>, recursively process all .h .c .hpp .cpp files
+ "rec" starting at the given directory <input path>, recursively process all .h .hpp files
)"""[1]);
return -1;
}
- const char* outputDir = argv[1];
+ state.outputDir = std::string_view(argv[1]);
DEBUG_PRINTF("Outputting to directory %s.\n", outputDir);
- {
- char path[2048];
- snprintf(path, sizeof(path), "%s/%s", outputDir, "Metadata.hpp");
-
- auto fileContent = R"""(
-// This file is generated. Any changes will be overidden when building.
-// This file is an umbrella header for all generated metadata. End users simply include this file to get access to everything.
-#pragma once
-
-#include <MetadataBase.hpp>
-
-#include <generated/MetadataImpl.hpp>
-)"""sv.substr(1); // Get rid of the \n at the beginning
-
- auto file = Utils::OpenCstdioFile(path, Utils::WriteTruncate);
- if (!file) {
- printf("[ERROR] unable to open output file %s", path);
- return -1;
- }
- DEFER { fclose(file); };
-
- DEBUG_PRINTF("Writing output file %s", path);
- fwrite(fileContent.data(), sizeof(decltype(fileContent)::value_type), fileContent.size(), file);
- }
-
for (int i = 2; i < argc; ++i) {
- std::string_view arg(argv[i]);
+ const char* argRaw = argv[i];
+ std::string_view arg(argRaw);
+ DEBUG_PRINTF("Processing input command %s\n", argRaw);
+
auto separatorLoc = arg.find(':');
if (separatorLoc != std::string_view::npos) {
auto opcodeString = arg.substr(0, separatorLoc);
auto opcode = ParseInputOpcode(opcodeString);
auto operand = arg.substr(separatorLoc + 1);
- DEBUG_PRINTF("Processing input command %.*s at path %.*s\n", (int)opcodeString.size(), opcodeString.data(), (int)operand.size(), operand.data());
-
HandleArgument(state, opcode, operand);
}
}
- WriteOutputFile(state.headerOutput, outputDir, "MetadataImpl.hpp");
- WriteOutputFile(state.sourceOutput, outputDir, "MetadataImpl.cpp");
+ Utils::WriteOutputFile(state.mainHeaderOutput, state.outputDir, "GeneratedCode.hpp"sv);
+ Utils::WriteOutputFile(state.mainSourceOutput, state.outputDir, "GeneratedCode.cpp"sv);
return 0;
}