From d029ab0dfcb9d50ff88056aef377a8dae8f71d93 Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Thu, 19 Jan 2023 19:17:45 +0800 Subject: [PATCH] feat(miscellaneous): add program support utilities such as Abort() or System() etc --- .../Public/Miscellaneous/ProgramSupport.h | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 Redcraft.Utility/Source/Public/Miscellaneous/ProgramSupport.h diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/ProgramSupport.h b/Redcraft.Utility/Source/Public/Miscellaneous/ProgramSupport.h new file mode 100644 index 0000000..7f37732 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Miscellaneous/ProgramSupport.h @@ -0,0 +1,118 @@ +#pragma once + +#include "CoreTypes.h" + +#include +#include +#include + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +#pragma warning(push) +#pragma warning(disable : 4996) + +using FAtexitHandler = void(); +using FSignalHandler = void(int);; + +/** Indicates program execution status. */ +enum class EExitCode : int +{ + Success = EXIT_SUCCESS, + Failure = EXIT_FAILURE, +}; + +/** Defines signal types. */ +enum class ESignalType : int +{ + SoftwareTermination = SIGTERM, // Termination request, sent to the program. + SegmentationFault = SIGSEGV, // Invalid memory access as segmentation fault. + ExternalInterrupt = SIGINT, // External interrupt, usually initiated by the user. + IllegalInstruction = SIGILL, // Invalid program image, such as invalid instruction. + AbnormalTermination = SIGABRT, // Abnormal termination condition, as is e.g. initiated by Abort(). + ArithmeticException = SIGFPE, // Erroneous arithmetic operation such as divide by zero. +}; + +FSignalHandler* GSignalDefault = SIG_DFL; // Defines default signal handling strategies. +FSignalHandler* GSignalIgnored = SIG_IGN; // Defines Signal is ignored strategies. +FSignalHandler* GSignalError = SIG_ERR; // Return value of signal specifying that an error was encountered. + +/** The integer type that can be accessed as an atomic entity from an asynchronous signal handler. */ +using FSignalAtomic = NAMESPACE_STD::sig_atomic_t; + +/** Causes abnormal program termination without cleaning up. */ +NORETURN FORCEINLINE void Abort() +{ + NAMESPACE_STD::abort(); +} + +/** Causes normal program termination with cleaning up. */ +NORETURN FORCEINLINE void Exit(EExitCode ExitCode) +{ + NAMESPACE_STD::exit(static_cast(ExitCode)); +}; + +/** Causes quick program termination without completely cleaning up. */ +NORETURN FORCEINLINE void QuickExit(EExitCode ExitCode) +{ + NAMESPACE_STD::quick_exit(static_cast(ExitCode)); +}; + +/** Causes normal program termination without cleaning up. */ +NORETURN FORCEINLINE void QuickExitWithoutCleaning(EExitCode ExitCode) +{ + NAMESPACE_STD::_Exit(static_cast(ExitCode)); +}; + +/** Registers a function to be called on Exit() invocation. */ +FORCEINLINE bool AtExit(FAtexitHandler* InFunc) +{ + return NAMESPACE_STD::atexit(InFunc) == 0; +} + +/** Registers a function to be called on QuickExit invocation. */ +FORCEINLINE bool AtQuickExit(FAtexitHandler* InFunc) +{ + return NAMESPACE_STD::at_quick_exit(InFunc) == 0; +} + +/** Marks unreachable point of execution. */ +NORETURN FORCEINLINE void Unreachable() +{ +# ifdef __cpp_lib_unreachable + { + NAMESPACE_STD::unreachable(); + } +# endif +} + +/** Calls the host environment's command processor. */ +FORCEINLINE EExitCode System(const char* InCommand) +{ + return static_cast(NAMESPACE_STD::system(InCommand)); +} + +/** Access to the list of environment variables. */ +NODISCARD FORCEINLINE const char* GetEnv(const char* InEnv) +{ + return NAMESPACE_STD::getenv(InEnv); +} + +/** Sets a signal handler for particular signal. */ +FORCEINLINE FSignalHandler* Signal(ESignalType InType, FSignalHandler* InFunc) +{ + return NAMESPACE_STD::signal(static_cast(InType), InFunc); +} + +/** Runs the signal handler for particular signal. */ +FORCEINLINE bool Raise(ESignalType InType) +{ + return NAMESPACE_STD::raise(static_cast(InType)) == 0; +} + +#pragma warning(pop) + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END