diff options
Diffstat (limited to 'src/zen/zen.h')
| -rw-r--r-- | src/zen/zen.h | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/src/zen/zen.h b/src/zen/zen.h index 80178910a..5cf3b99ed 100644 --- a/src/zen/zen.h +++ b/src/zen/zen.h @@ -9,12 +9,15 @@ #include <zenutil/config/commandlineoptions.h> #include <zenutil/config/loggingconfig.h> +#include <csignal> + namespace zen { struct ZenCliOptions { - bool IsDebug = false; - bool IsVerbose = false; + bool IsDebug = false; + bool IsVerbose = false; + bool EnableExecutionHistory = true; ZenLoggingConfig LoggingConfig; @@ -37,6 +40,33 @@ extern ZenCmdCategory g_ProjectStoreCategory; extern ZenCmdCategory g_CacheStoreCategory; extern ZenCmdCategory g_StorageCategory; +// RAII wrapper around `signal(2)` that restores the previous handler on scope +// exit. Use in command Run() methods so an exception during option parsing or +// execution doesn't leave a handler installed whose flag is scoped to a +// now-dead lifetime. +class ScopedSignalHandler +{ +public: + using Handler = void (*)(int); + + ScopedSignalHandler(int SigNum, Handler NewHandler) : m_SigNum(SigNum), m_PrevHandler(std::signal(SigNum, NewHandler)) {} + + ~ScopedSignalHandler() + { + if (m_PrevHandler != SIG_ERR) + { + std::signal(m_SigNum, m_PrevHandler); + } + } + + ScopedSignalHandler(const ScopedSignalHandler&) = delete; + ScopedSignalHandler& operator=(const ScopedSignalHandler&) = delete; + +private: + int m_SigNum; + Handler m_PrevHandler; +}; + class ErrorWithReturnCode : public std::runtime_error { public: @@ -58,6 +88,11 @@ public: virtual cxxopts::Options& Options() = 0; virtual ZenCmdCategory& CommandCategory() const; + // Hidden commands are dispatched normally but omitted from the top-level + // `zen --help` listing. Used for deprecated aliases that remain functional + // but should not be advertised. + virtual bool IsHidden() const { return false; } + bool ParseOptions(int argc, char** argv); static bool ParseOptions(cxxopts::Options& Options, int argc, char** argv); static bool ParseOptionsPermissive(cxxopts::Options& Options, int argc, char** argv, std::vector<std::string>& OutUnmatched); @@ -103,15 +138,19 @@ class ZenSubCmdBase public: ZenSubCmdBase(std::string_view Name, std::string_view Description); virtual ~ZenSubCmdBase() = default; - cxxopts::Options& SubOptions() { return m_SubOptions; } - std::string_view Description() const { return m_Description; } - virtual void Run(const ZenCliOptions& GlobalOptions) = 0; + cxxopts::Options& SubOptions() { return m_SubOptions; } + std::string_view Description() const { return m_Description; } + const std::vector<std::string>& Aliases() const { return m_Aliases; } + virtual void Run(const ZenCliOptions& GlobalOptions) = 0; protected: + void AddAlias(std::string Alias) { m_Aliases.push_back(std::move(Alias)); } + cxxopts::Options m_SubOptions; private: - std::string m_Description; + std::string m_Description; + std::vector<std::string> m_Aliases; }; // Base for commands that host subcommands - handles all dispatch boilerplate |