From 5db7bc2d4c1bbe668bcc8e43d4ad21d44127a42c Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 19 Jun 2023 20:56:51 +0200 Subject: [PATCH] Add Decompiler and Compiler tools --- premake5.lua | 4 ++ src/Compiler.lua | 46 +++++++++++++++++++++ src/Compiler/Compiler.cpp | 22 ++++++++++ src/Compiler/Compiler.h | 25 ++++++++++++ src/Compiler/CompilerArgs.cpp | 68 +++++++++++++++++++++++++++++++ src/Compiler/CompilerArgs.h | 21 ++++++++++ src/Compiler/main.cpp | 8 ++++ src/Decompiler.lua | 46 +++++++++++++++++++++ src/Decompiler/Decompiler.cpp | 22 ++++++++++ src/Decompiler/Decompiler.h | 25 ++++++++++++ src/Decompiler/DecompilerArgs.cpp | 68 +++++++++++++++++++++++++++++++ src/Decompiler/DecompilerArgs.h | 21 ++++++++++ src/Decompiler/main.cpp | 8 ++++ 13 files changed, 384 insertions(+) create mode 100644 src/Compiler.lua create mode 100644 src/Compiler/Compiler.cpp create mode 100644 src/Compiler/Compiler.h create mode 100644 src/Compiler/CompilerArgs.cpp create mode 100644 src/Compiler/CompilerArgs.h create mode 100644 src/Compiler/main.cpp create mode 100644 src/Decompiler.lua create mode 100644 src/Decompiler/Decompiler.cpp create mode 100644 src/Decompiler/Decompiler.h create mode 100644 src/Decompiler/DecompilerArgs.cpp create mode 100644 src/Decompiler/DecompilerArgs.h create mode 100644 src/Decompiler/main.cpp diff --git a/premake5.lua b/premake5.lua index a995bf14..ec8af45b 100644 --- a/premake5.lua +++ b/premake5.lua @@ -98,7 +98,9 @@ group "" -- Projects -- ======================== include "src/Common.lua" +include "src/Compiler.lua" include "src/Crypto.lua" +include "src/Decompiler.lua" include "src/Linker.lua" include "src/Parser.lua" include "src/RawTemplater.lua" @@ -140,6 +142,8 @@ group "" -- Tools group: All projects that compile into the final tools group "Tools" + Compiler:project() + Decompiler:project() Linker:project() Unlinker:project() group "" diff --git a/src/Compiler.lua b/src/Compiler.lua new file mode 100644 index 00000000..9bf62fd3 --- /dev/null +++ b/src/Compiler.lua @@ -0,0 +1,46 @@ +Compiler = {} + +function Compiler:include(includes) + if includes:handle(self:name()) then + includedirs { + path.join(ProjectFolder(), "Compiler") + } + end +end + +function Compiler:link(links) + +end + +function Compiler:use() + dependson(self:name()) +end + +function Compiler:name() + return "Compiler" +end + +function Compiler:project() + local folder = ProjectFolder() + local includes = Includes:create() + local links = Links:create() + + project(self:name()) + targetdir(TargetDirectoryBin) + location "%{wks.location}/src/%{prj.name}" + kind "ConsoleApp" + language "C++" + + files { + path.join(folder, "Compiler/**.h"), + path.join(folder, "Compiler/**.cpp") + } + + self:include(includes) + Utils:include(includes) + + Raw:use() + + links:linkto(Utils) + links:linkall() +end diff --git a/src/Compiler/Compiler.cpp b/src/Compiler/Compiler.cpp new file mode 100644 index 00000000..2e2a549b --- /dev/null +++ b/src/Compiler/Compiler.cpp @@ -0,0 +1,22 @@ +#include "Compiler.h" + +#include "CompilerArgs.h" + +class CompilerImpl final : public Compiler +{ + CompilerArgs m_args; + +public: + bool Start(const int argc, const char** argv) override + { + if (!m_args.ParseArgs(argc, argv)) + return false; + + return true; + } +}; + +std::unique_ptr Compiler::Create() +{ + return std::make_unique(); +} diff --git a/src/Compiler/Compiler.h b/src/Compiler/Compiler.h new file mode 100644 index 00000000..84054b8c --- /dev/null +++ b/src/Compiler/Compiler.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +class Compiler +{ +public: + Compiler() = default; + virtual ~Compiler() = default; + + Compiler(const Compiler& other) = default; + Compiler(Compiler&& other) noexcept = default; + Compiler& operator=(const Compiler& other) = default; + Compiler& operator=(Compiler&& other) noexcept = default; + + static std::unique_ptr Create(); + + /** + * \brief Starts the Compiler application logic. + * \param argc The amount of command line arguments specified. + * \param argv The command line arguments. + * \return \c true if the application was successful or \c false if an error occurred. + */ + virtual bool Start(int argc, const char** argv) = 0; +}; \ No newline at end of file diff --git a/src/Compiler/CompilerArgs.cpp b/src/Compiler/CompilerArgs.cpp new file mode 100644 index 00000000..20889b5a --- /dev/null +++ b/src/Compiler/CompilerArgs.cpp @@ -0,0 +1,68 @@ +#include "CompilerArgs.h" + +#include "Utils/Arguments/UsageInformation.h" +#include "Utils/FileUtils.h" + +const CommandLineOption* const OPTION_HELP = + CommandLineOption::Builder::Create() + .WithShortName("?") + .WithLongName("help") + .WithDescription("Displays usage information.") + .Build(); + +const CommandLineOption* const OPTION_VERBOSE = + CommandLineOption::Builder::Create() + .WithShortName("v") + .WithLongName("verbose") + .WithDescription("Outputs a lot more and more detailed messages.") + .Build(); + +const CommandLineOption* const COMMAND_LINE_OPTIONS[] +{ + OPTION_HELP, + OPTION_VERBOSE +}; + +CompilerArgs::CompilerArgs() + : m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v), + m_verbose(false) +{ +} + +void CompilerArgs::PrintUsage() +{ + UsageInformation usage("Compiler.exe"); + + for (const auto* commandLineOption : COMMAND_LINE_OPTIONS) + { + usage.AddCommandLineOption(commandLineOption); + } + + usage.Print(); +} + +void CompilerArgs::SetVerbose(const bool isVerbose) +{ + m_verbose = isVerbose; +} + +bool CompilerArgs::ParseArgs(const int argc, const char** argv) +{ + if (!m_argument_parser.ParseArguments(argc - 1, &argv[1])) + { + PrintUsage(); + return false; + } + + // Check if the user requested help + if (m_argument_parser.IsOptionSpecified(OPTION_HELP)) + { + PrintUsage(); + return false; + } + + // -v; --verbose + SetVerbose(m_argument_parser.IsOptionSpecified(OPTION_VERBOSE)); + + return true; +} diff --git a/src/Compiler/CompilerArgs.h b/src/Compiler/CompilerArgs.h new file mode 100644 index 00000000..4e93375a --- /dev/null +++ b/src/Compiler/CompilerArgs.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Utils/Arguments/ArgumentParser.h" + +class CompilerArgs +{ + ArgumentParser m_argument_parser; + + /** + * \brief Prints a command line usage help text for the Compiler tool to stdout. + */ + static void PrintUsage(); + + void SetVerbose(bool isVerbose); + +public: + bool m_verbose; + + CompilerArgs(); + bool ParseArgs(int argc, const char** argv); +}; diff --git a/src/Compiler/main.cpp b/src/Compiler/main.cpp new file mode 100644 index 00000000..d833cfe0 --- /dev/null +++ b/src/Compiler/main.cpp @@ -0,0 +1,8 @@ +#include "Compiler.h" + +int main(const int argc, const char** argv) +{ + const auto compiler = Compiler::Create(); + + return compiler->Start(argc, argv) ? 0 : 1; +} diff --git a/src/Decompiler.lua b/src/Decompiler.lua new file mode 100644 index 00000000..55550b3f --- /dev/null +++ b/src/Decompiler.lua @@ -0,0 +1,46 @@ +Decompiler = {} + +function Decompiler:include(includes) + if includes:handle(self:name()) then + includedirs { + path.join(ProjectFolder(), "Decompiler") + } + end +end + +function Decompiler:link(links) + +end + +function Decompiler:use() + dependson(self:name()) +end + +function Decompiler:name() + return "Decompiler" +end + +function Decompiler:project() + local folder = ProjectFolder() + local includes = Includes:create() + local links = Links:create() + + project(self:name()) + targetdir(TargetDirectoryBin) + location "%{wks.location}/src/%{prj.name}" + kind "ConsoleApp" + language "C++" + + files { + path.join(folder, "Decompiler/**.h"), + path.join(folder, "Decompiler/**.cpp") + } + + self:include(includes) + Utils:include(includes) + + Raw:use() + + links:linkto(Utils) + links:linkall() +end diff --git a/src/Decompiler/Decompiler.cpp b/src/Decompiler/Decompiler.cpp new file mode 100644 index 00000000..04fe8bd7 --- /dev/null +++ b/src/Decompiler/Decompiler.cpp @@ -0,0 +1,22 @@ +#include "Decompiler.h" + +#include "DecompilerArgs.h" + +class DecompilerImpl final : public Decompiler +{ + DecompilerArgs m_args; + +public: + bool Start(const int argc, const char** argv) override + { + if (!m_args.ParseArgs(argc, argv)) + return false; + + return true; + } +}; + +std::unique_ptr Decompiler::Create() +{ + return std::make_unique(); +} diff --git a/src/Decompiler/Decompiler.h b/src/Decompiler/Decompiler.h new file mode 100644 index 00000000..13f144a4 --- /dev/null +++ b/src/Decompiler/Decompiler.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +class Decompiler +{ +public: + Decompiler() = default; + virtual ~Decompiler() = default; + + Decompiler(const Decompiler& other) = default; + Decompiler(Decompiler&& other) noexcept = default; + Decompiler& operator=(const Decompiler& other) = default; + Decompiler& operator=(Decompiler&& other) noexcept = default; + + static std::unique_ptr Create(); + + /** + * \brief Starts the Decompiler application logic. + * \param argc The amount of command line arguments specified. + * \param argv The command line arguments. + * \return \c true if the application was successful or \c false if an error occurred. + */ + virtual bool Start(int argc, const char** argv) = 0; +}; \ No newline at end of file diff --git a/src/Decompiler/DecompilerArgs.cpp b/src/Decompiler/DecompilerArgs.cpp new file mode 100644 index 00000000..c2996c68 --- /dev/null +++ b/src/Decompiler/DecompilerArgs.cpp @@ -0,0 +1,68 @@ +#include "DecompilerArgs.h" + +#include "Utils/Arguments/UsageInformation.h" +#include "Utils/FileUtils.h" + +const CommandLineOption* const OPTION_HELP = + CommandLineOption::Builder::Create() + .WithShortName("?") + .WithLongName("help") + .WithDescription("Displays usage information.") + .Build(); + +const CommandLineOption* const OPTION_VERBOSE = + CommandLineOption::Builder::Create() + .WithShortName("v") + .WithLongName("verbose") + .WithDescription("Outputs a lot more and more detailed messages.") + .Build(); + +const CommandLineOption* const COMMAND_LINE_OPTIONS[] +{ + OPTION_HELP, + OPTION_VERBOSE +}; + +DecompilerArgs::DecompilerArgs() + : m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v), + m_verbose(false) +{ +} + +void DecompilerArgs::PrintUsage() +{ + UsageInformation usage("Decompiler.exe"); + + for (const auto* commandLineOption : COMMAND_LINE_OPTIONS) + { + usage.AddCommandLineOption(commandLineOption); + } + + usage.Print(); +} + +void DecompilerArgs::SetVerbose(const bool isVerbose) +{ + m_verbose = isVerbose; +} + +bool DecompilerArgs::ParseArgs(const int argc, const char** argv) +{ + if (!m_argument_parser.ParseArguments(argc - 1, &argv[1])) + { + PrintUsage(); + return false; + } + + // Check if the user requested help + if (m_argument_parser.IsOptionSpecified(OPTION_HELP)) + { + PrintUsage(); + return false; + } + + // -v; --verbose + SetVerbose(m_argument_parser.IsOptionSpecified(OPTION_VERBOSE)); + + return true; +} diff --git a/src/Decompiler/DecompilerArgs.h b/src/Decompiler/DecompilerArgs.h new file mode 100644 index 00000000..8d482093 --- /dev/null +++ b/src/Decompiler/DecompilerArgs.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Utils/Arguments/ArgumentParser.h" + +class DecompilerArgs +{ + ArgumentParser m_argument_parser; + + /** + * \brief Prints a command line usage help text for the Decompiler tool to stdout. + */ + static void PrintUsage(); + + void SetVerbose(bool isVerbose); + +public: + bool m_verbose; + + DecompilerArgs(); + bool ParseArgs(int argc, const char** argv); +}; diff --git a/src/Decompiler/main.cpp b/src/Decompiler/main.cpp new file mode 100644 index 00000000..34107632 --- /dev/null +++ b/src/Decompiler/main.cpp @@ -0,0 +1,8 @@ +#include "Decompiler.h" + +int main(const int argc, const char** argv) +{ + const auto decompiler = Decompiler::Create(); + + return decompiler->Start(argc, argv) ? 0 : 1; +}