aboutsummaryrefslogtreecommitdiff
path: root/src/zen/zen.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/zen/zen.h')
-rw-r--r--src/zen/zen.h51
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