aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/args.cc26
-rw-r--r--src/libutil/args.hh83
-rw-r--r--src/libutil/config.cc29
-rw-r--r--src/libutil/config.hh6
4 files changed, 101 insertions, 43 deletions
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index 115484f9e..df7e04087 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -3,6 +3,18 @@
namespace nix {
+Args::FlagMaker Args::mkFlag()
+{
+ return FlagMaker(*this);
+}
+
+Args::FlagMaker::~FlagMaker()
+{
+ assert(flag->longName != "");
+ args.longFlags[flag->longName] = flag;
+ if (flag->shortName) args.shortFlags[flag->shortName] = flag;
+}
+
void Args::parseCmdline(const Strings & _cmdline)
{
Strings pendingArgs;
@@ -71,11 +83,13 @@ void Args::printHelp(const string & programName, std::ostream & out)
void Args::printFlags(std::ostream & out)
{
Table2 table;
- for (auto & flag : longFlags)
+ for (auto & flag : longFlags) {
+ if (hiddenCategories.count(flag.second->category)) continue;
table.push_back(std::make_pair(
- (flag.second.shortName ? std::string("-") + flag.second.shortName + ", " : " ")
- + "--" + flag.first + renderLabels(flag.second.labels),
- flag.second.description));
+ (flag.second->shortName ? std::string("-") + flag.second->shortName + ", " : " ")
+ + "--" + flag.first + renderLabels(flag.second->labels),
+ flag.second->description));
+ }
printTable(out, table);
}
@@ -99,14 +113,14 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
if (string(*pos, 0, 2) == "--") {
auto i = longFlags.find(string(*pos, 2));
if (i == longFlags.end()) return false;
- return process("--" + i->first, i->second);
+ return process("--" + i->first, *i->second);
}
if (string(*pos, 0, 1) == "-" && pos->size() == 2) {
auto c = (*pos)[1];
auto i = shortFlags.find(c);
if (i == shortFlags.end()) return false;
- return process(std::string("-") + c, i->second);
+ return process(std::string("-") + c, *i->second);
}
return false;
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index f70bb7823..aa11373d5 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. */
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index 612fb6e68..0682bcd5d 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -115,11 +115,11 @@ void Config::toJSON(JSONObject & out)
}
}
-void Config::convertToArgs(Args & args)
+void Config::convertToArgs(Args & args, const std::string & category)
{
for (auto & s : _settings)
if (!s.second.isAlias)
- s.second.setting->convertToArg(args);
+ s.second.setting->convertToArg(args, category);
}
AbstractSetting::AbstractSetting(
@@ -135,7 +135,7 @@ void AbstractSetting::toJSON(JSONPlaceholder & out)
out.write(to_string());
}
-void AbstractSetting::convertToArg(Args & args)
+void AbstractSetting::convertToArg(Args & args, const std::string & category)
{
}
@@ -146,9 +146,14 @@ void BaseSetting<T>::toJSON(JSONPlaceholder & out)
}
template<typename T>
-void BaseSetting<T>::convertToArg(Args & args)
+void BaseSetting<T>::convertToArg(Args & args, const std::string & category)
{
- args.mkFlag(0, name, {}, description, 1, [=](Strings ss) { set(*ss.begin()); });
+ args.mkFlag()
+ .longName(name)
+ .description(description)
+ .arity(1)
+ .handler([=](Strings ss) { set(*ss.begin()); })
+ .category(category);
}
template<> void BaseSetting<std::string>::set(const std::string & str)
@@ -191,10 +196,18 @@ template<> std::string BaseSetting<bool>::to_string()
return value ? "true" : "false";
}
-template<> void BaseSetting<bool>::convertToArg(Args & args)
+template<> void BaseSetting<bool>::convertToArg(Args & args, const std::string & category)
{
- args.mkFlag(0, name, {}, description, 0, [=](Strings ss) { value = true; });
- args.mkFlag(0, "no-" + name, {}, description, 0, [=](Strings ss) { value = false; });
+ args.mkFlag()
+ .longName(name)
+ .description(description)
+ .handler([=](Strings ss) { value = true; })
+ .category(category);
+ args.mkFlag()
+ .longName("no-" + name)
+ .description(description)
+ .handler([=](Strings ss) { value = false; })
+ .category(category);
}
template<> void BaseSetting<Strings>::set(const std::string & str)
diff --git a/src/libutil/config.hh b/src/libutil/config.hh
index 994eab911..99850c1cd 100644
--- a/src/libutil/config.hh
+++ b/src/libutil/config.hh
@@ -72,7 +72,7 @@ public:
void toJSON(JSONObject & out);
- void convertToArgs(Args & args);
+ void convertToArgs(Args & args, const std::string & category);
};
class AbstractSetting
@@ -109,7 +109,7 @@ protected:
virtual void toJSON(JSONPlaceholder & out);
- virtual void convertToArg(Args & args);
+ virtual void convertToArg(Args & args, const std::string & category);
bool isOverriden() { return overriden; }
};
@@ -144,7 +144,7 @@ public:
std::string to_string() override;
- void convertToArg(Args & args) override;
+ void convertToArg(Args & args, const std::string & category) override;
void toJSON(JSONPlaceholder & out) override;
};