Catch exceptions in the main function

This commit is contained in:
Username404 2021-08-18 18:59:46 +02:00
parent 24d73a3f82
commit 989650dba6
Signed by: Username404-59
GPG Key ID: 7AB361FBB257A5D1
2 changed files with 38 additions and 14 deletions

View File

@ -17,8 +17,9 @@
namespace Yerbacon { namespace Yerbacon {
consteval const char* getVersion() noexcept { return YBCON_VERSION; } consteval const char* getVersion() noexcept { return YBCON_VERSION; }
class Exception: public std::exception { class Exception: public std::exception {
std::string exceptionCause; const std::string exceptionCause;
[[nodiscard]] const char* what() const noexcept override { public:
[[nodiscard]] const char* what() const noexcept final {
return exceptionCause.data(); return exceptionCause.data();
} }
public: public:

View File

@ -3,6 +3,7 @@
#include "headers/Yerbacon.hpp" #include "headers/Yerbacon.hpp"
#include <future> #include <future>
#include <sstream> #include <sstream>
#include <variant>
using namespace std; using namespace std;
#include "headers/misc.hpp" #include "headers/misc.hpp"
@ -23,36 +24,58 @@ int main(int argc, char* argv[]) {
currentArg = static_cast<string_view>(argv[i]); currentArg = static_cast<string_view>(argv[i]);
if (currentArg == ArgumentShort("printresult")) printResult = true; if (currentArg == ArgumentShort("printresult")) printResult = true;
else if (currentArg == ArgumentAssignable("target")) { else if (currentArg == ArgumentAssignable("target")) {
target.assign(string()); target.clear();
string value = ArgumentAssignable::getValueFor(currentArg.data()); string value = ArgumentAssignable::getValueFor(currentArg.data());
if (!value.empty()) (target = '.') += value; if (!value.empty()) (target = '.') += value;
} }
else if (currentArg == Argument("parallel")) parallel = true; else if (currentArg == Argument("parallel")) parallel = true;
else if (currentArg.ends_with(".ybcon")) files.push_back(currentArg); else if (currentArg.ends_with(".ybcon")) files.push_back(currentArg);
} }
const auto compile = [printResult, target](string_view& name) { const auto compile = [&target](string_view& name) {
const string transpiledString = transpile(parseString(getFileContent(name.data())), target); string transpiledString = transpile(parseString(getFileContent(name.data())), target);
stringstream consoleOutput;
if (printResult) consoleOutput << "~~~~[Yerbacon compilation result]~~~~\n\n" << "[WIP]\n" << transpiledString << "\n\n";
name.remove_suffix(6); name.remove_suffix(6);
string outputFile; string outputFile;
(outputFile = name).append(target); (outputFile = name).append(target);
outputFileContent(outputFile, transpiledString); outputFileContent(outputFile, transpiledString);
return consoleOutput.str(); return transpiledString;
}; };
if (!files.empty()) { if (!files.empty()) {
const set<string_view> uniqueFiles(files.begin(), files.end()); const set<string_view> uniqueFiles(files.begin(), files.end());
vector<future<string>> Units; vector<future<pair<string, optional<Yerbacon::Exception>>>> Units;
const launch& Policy = not parallel ? launch::deferred : launch::async; const launch& Policy = not parallel ? launch::deferred : launch::async;
for (string_view fileName: uniqueFiles) { for (string_view fileName: uniqueFiles) {
if (fileName != "none") { if (fileName != "none") {
future<string> newAsync = async(Policy, [&fileName, &compile]() { Units.push_back(async(Policy, [&fileName, &compile]() {
return compile(fileName); try {
}); return pair(compile(fileName), optional<Yerbacon::Exception>());
Units.push_back(move(newAsync)); } 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"; } else cout << "No valid file provided.\n";
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;