aboutsummaryrefslogtreecommitdiff
path: root/buildtools/codegen/main.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-05-24 21:47:55 -0700
committerrtk0c <[email protected]>2022-05-24 21:47:55 -0700
commitd18a28a9659092952aef70a30a47726e7c16d31a (patch)
treeb1d6304e631961a797225912ed1ef7ee55864f86 /buildtools/codegen/main.cpp
parent123f741e3f5374b93ac39887b62bfa0d66762ae2 (diff)
Changeset: 38 Branch comment: [] Add infrastructure for codegen
Diffstat (limited to 'buildtools/codegen/main.cpp')
-rw-r--r--buildtools/codegen/main.cpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/buildtools/codegen/main.cpp b/buildtools/codegen/main.cpp
new file mode 100644
index 0000000..4a1d486
--- /dev/null
+++ b/buildtools/codegen/main.cpp
@@ -0,0 +1,102 @@
+#include "ScopeGuard.hpp"
+#include "Utils.hpp"
+
+#include <stb_c_lexer.h>
+#include <filesystem>
+#include <string>
+#include <string_view>
+
+using namespace std::literals;
+namespace fs = std::filesystem;
+
+enum InputOpcode {
+ IOP_ProcessSingleFile,
+ IOP_ProcessRecursively,
+ IOP_COUNT,
+};
+
+InputOpcode ParseInputOpcode(std::string_view text) {
+ if (text == "single"sv) {
+ return IOP_ProcessSingleFile;
+ } else if (text == "rec"sv) {
+ return IOP_ProcessRecursively;
+ }
+ return IOP_COUNT;
+}
+
+void HandleInputFile(std::string_view source) {
+ stb_lexer lexer;
+ char stringStorage[65536];
+ const char* srcBegin = source.data();
+ const char* srcEnd = srcBegin + source.length();
+ stb_c_lexer_init(&lexer, srcBegin, srcEnd, stringStorage, sizeof(stringStorage));
+
+ // TODO
+}
+
+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;
+}
+
+void HandleArgument(InputOpcode opcode, std::string_view operand) {
+ switch (opcode) {
+ case IOP_ProcessSingleFile: {
+ fs::path filePath(operand);
+ auto source = ReadFileAtOnce(filePath);
+ HandleInputFile(source);
+ } break;
+
+ case IOP_ProcessRecursively: {
+ fs::path startPath(operand);
+ for (auto& item : fs::directory_iterator(startPath)) {
+ if (!item.is_regular_file()) {
+ continue;
+ }
+
+ auto& path = item.path();
+ auto filename = path.filename().string();
+ if (filename != ".c" ||
+ filename != ".cpp")
+ {
+ continue;
+ }
+
+ auto source = ReadFileAtOnce(path);
+ HandleInputFile(source);
+ }
+ } break;
+
+ case IOP_COUNT: break;
+ }
+}
+
+int main(int argc, char* argv[]) {
+ // TODO better arg parser
+ // option 1: use cxxopts and positional arguments
+ // option 1: take one argument only, being a json objecet
+
+ // If no cli is provided (argv[0]), this loop will do nothing
+ // Otherwise, start with the 2nd element which is the 1st argument
+ for (int i = 1; i < argc; ++i) {
+ std::string_view arg(argv[i]);
+ auto separatorLoc = arg.find(':');
+ if (separatorLoc != std::string_view::npos) {
+ auto opcode = ParseInputOpcode(arg.substr(0, separatorLoc));
+ auto operand = arg.substr(separatorLoc);
+ HandleArgument(opcode, operand);
+ }
+ }
+
+ return 0;
+}