#include "ScopeGuard.hpp" #include "Utils.hpp" #include #include #include #include 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; }