From 989650dba64c286cce12afdd2ef6367242562d95 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 18 Aug 2021 18:59:46 +0200 Subject: [PATCH] Catch exceptions in the main function --- src/headers/Yerbacon.hpp | 5 +++-- src/main.cpp | 47 ++++++++++++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/headers/Yerbacon.hpp b/src/headers/Yerbacon.hpp index 04b65f2..69f84d7 100644 --- a/src/headers/Yerbacon.hpp +++ b/src/headers/Yerbacon.hpp @@ -17,8 +17,9 @@ namespace Yerbacon { consteval const char* getVersion() noexcept { return YBCON_VERSION; } class Exception: public std::exception { - std::string exceptionCause; - [[nodiscard]] const char* what() const noexcept override { + const std::string exceptionCause; + public: + [[nodiscard]] const char* what() const noexcept final { return exceptionCause.data(); } public: diff --git a/src/main.cpp b/src/main.cpp index 9e2d23d..bb66e33 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ #include "headers/Yerbacon.hpp" #include #include +#include using namespace std; #include "headers/misc.hpp" @@ -23,36 +24,58 @@ int main(int argc, char* argv[]) { currentArg = static_cast(argv[i]); if (currentArg == ArgumentShort("printresult")) printResult = true; else if (currentArg == ArgumentAssignable("target")) { - target.assign(string()); + target.clear(); string value = ArgumentAssignable::getValueFor(currentArg.data()); if (!value.empty()) (target = '.') += value; } else if (currentArg == Argument("parallel")) parallel = true; else if (currentArg.ends_with(".ybcon")) files.push_back(currentArg); } - const auto compile = [printResult, target](string_view& name) { - const string transpiledString = transpile(parseString(getFileContent(name.data())), target); - stringstream consoleOutput; - if (printResult) consoleOutput << "~~~~[Yerbacon compilation result]~~~~\n\n" << "[WIP]\n" << transpiledString << "\n\n"; + const auto compile = [&target](string_view& name) { + string transpiledString = transpile(parseString(getFileContent(name.data())), target); name.remove_suffix(6); string outputFile; (outputFile = name).append(target); outputFileContent(outputFile, transpiledString); - return consoleOutput.str(); + return transpiledString; }; if (!files.empty()) { const set uniqueFiles(files.begin(), files.end()); - vector> Units; + vector>>> Units; const launch& Policy = not parallel ? launch::deferred : launch::async; for (string_view fileName: uniqueFiles) { if (fileName != "none") { - future newAsync = async(Policy, [&fileName, &compile]() { - return compile(fileName); - }); - Units.push_back(move(newAsync)); + Units.push_back(async(Policy, [&fileName, &compile]() { + try { + return pair(compile(fileName), optional()); + } catch (const Yerbacon::Exception& e) { + unsigned long lastSlash = 0; + unsigned long position1 = fileName.find_last_of('/'); + if (cmp_not_equal(position1, string_view::npos)) { + #ifndef _WIN32 + lastSlash = position1; + #else + unsigned long position2 = fileName.find_last_of('\\'); + if (cmp_not_equal(position2, string_view::npos)) { + lastSlash = (position1 > position2) ? position1 : position2; + } + #endif + } + return pair(string(fileName.substr(lastSlash + 1)), make_optional(e)); + } + })); } } - for (auto& currentFuture: Units) cout << currentFuture.get(); + if (printResult) cout << "~~~~[Yerbacon compilation result]~~~~\n\n"; + for (auto& currentFuture: Units) { + const auto&& result = currentFuture.get(); + if (not result.second.has_value()) { + cout << result.first; + } else { + cout << "Compilation of " << result.first << " has failed with the following error:\n" << result.second.value().what(); + } + cout << "\n\n"; + } } else cout << "No valid file provided.\n"; } return EXIT_SUCCESS;