about summary refs log tree commit diff
path: root/src/libutil/args.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/args.hh')
-rw-r--r--src/libutil/args.hh83
1 files changed, 57 insertions, 26 deletions
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index f70bb7823dc0..aa11373d5f1f 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -29,15 +29,18 @@ protected:
     /* Flags. */
     struct Flag
     {
-        char shortName;
+        typedef std::shared_ptr<Flag> ptr;
+        std::string longName;
+        char shortName = 0;
         std::string description;
         Strings labels;
-        size_t arity;
+        size_t arity = 0;
         std::function<void(Strings)> handler;
+        std::string category;
     };
 
-    std::map<std::string, Flag> longFlags;
-    std::map<char, Flag> shortFlags;
+    std::map<std::string, Flag::ptr> longFlags;
+    std::map<char, Flag::ptr> shortFlags;
 
     virtual bool processFlag(Strings::iterator & pos, Strings::iterator end);
 
@@ -55,33 +58,53 @@ protected:
 
     virtual bool processArgs(const Strings & args, bool finish);
 
+    std::set<std::string> hiddenCategories;
+
 public:
 
+    class FlagMaker
+    {
+        Args & args;
+        Flag::ptr flag;
+        friend class Args;
+        FlagMaker(Args & args) : args(args), flag(std::make_shared<Flag>()) { };
+    public:
+        ~FlagMaker();
+        FlagMaker & longName(const std::string & s) { flag->longName = s; return *this; };
+        FlagMaker & shortName(char s) { flag->shortName = s; return *this; };
+        FlagMaker & description(const std::string & s) { flag->description = s; return *this; };
+        FlagMaker & labels(const Strings & ls) { flag->labels = ls; return *this; };
+        FlagMaker & arity(size_t arity) { flag->arity = arity; return *this; };
+        FlagMaker & handler(std::function<void(Strings)> handler) { flag->handler = handler; return *this; };
+        FlagMaker & category(const std::string & s) { flag->category = s; return *this; };
+    };
+
+    FlagMaker mkFlag();
+
     /* Helper functions for constructing flags / positional
        arguments. */
 
     void mkFlag(char shortName, const std::string & longName,
-        const Strings & labels, const std::string & description,
-        size_t arity, std::function<void(Strings)> handler)
-    {
-        auto flag = Flag{shortName, description, labels, arity, handler};
-        if (shortName) shortFlags[shortName] = flag;
-        longFlags[longName] = flag;
-    }
-
-    void mkFlag(char shortName, const std::string & longName,
         const std::string & description, std::function<void()> fun)
     {
-        mkFlag(shortName, longName, {}, description, 0, std::bind(fun));
+        mkFlag()
+            .shortName(shortName)
+            .longName(longName)
+            .description(description)
+            .handler(std::bind(fun));
     }
 
     void mkFlag1(char shortName, const std::string & longName,
         const std::string & label, const std::string & description,
         std::function<void(std::string)> fun)
     {
-        mkFlag(shortName, longName, {label}, description, 1, [=](Strings ss) {
-            fun(ss.front());
-        });
+        mkFlag()
+            .shortName(shortName)
+            .longName(longName)
+            .labels({label})
+            .description(description)
+            .arity(1)
+            .handler([=](Strings ss) { fun(ss.front()); });
     }
 
     void mkFlag(char shortName, const std::string & name,
@@ -105,9 +128,11 @@ public:
     void mkFlag(char shortName, const std::string & longName, const std::string & description,
         T * dest, const T & value)
     {
-        mkFlag(shortName, longName, {}, description, 0, [=](Strings ss) {
-            *dest = value;
-        });
+        mkFlag()
+            .shortName(shortName)
+            .longName(longName)
+            .description(description)
+            .handler([=](Strings ss) { *dest = value; });
     }
 
     template<class I>
@@ -123,12 +148,18 @@ public:
     void mkFlag(char shortName, const std::string & longName,
         const std::string & description, std::function<void(I)> fun)
     {
-        mkFlag(shortName, longName, {"N"}, description, 1, [=](Strings ss) {
-            I n;
-            if (!string2Int(ss.front(), n))
-                throw UsageError(format("flag ‘--%1%’ requires a integer argument") % longName);
-            fun(n);
-        });
+        mkFlag()
+            .shortName(shortName)
+            .longName(longName)
+            .labels({"N"})
+            .description(description)
+            .arity(1)
+            .handler([=](Strings ss) {
+                I n;
+                if (!string2Int(ss.front(), n))
+                    throw UsageError(format("flag ‘--%1%’ requires a integer argument") % longName);
+                fun(n);
+            });
     }
 
     /* Expect a string argument. */