1
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-06-28 12:06:38 +03:00

Reformat for 4-space indentation

Specifically, with
  clang-format --style='{ IndentWidth: 4, BreakBeforeBraces: Mozilla, ColumnLimit: 120, PointerAlignment: Middle }'
which was the clang-format invocation that produced the fewest diffs on
the nix source out of ~20 that I tried.
This commit is contained in:
Chuck 2019-09-06 09:45:05 -07:00 committed by Linus Heckemann
parent 74f05df671
commit 4af8dbf896
3 changed files with 534 additions and 529 deletions

View file

@ -21,7 +21,8 @@ using nix::Strings;
using std::string; using std::string;
// From nix/src/libexpr/attr-path.cc // From nix/src/libexpr/attr-path.cc
Strings parseAttrPath(const string &s) { Strings parseAttrPath(const string & s)
{
Strings res; Strings res;
string cur; string cur;
string::const_iterator i = s.begin(); string::const_iterator i = s.begin();
@ -33,8 +34,7 @@ Strings parseAttrPath(const string &s) {
++i; ++i;
while (1) { while (1) {
if (i == s.end()) if (i == s.end())
throw Error(format("missing closing quote in selection path '%1%'") % throw Error(format("missing closing quote in selection path '%1%'") % s);
s);
if (*i == '"') if (*i == '"')
break; break;
cur.push_back(*i++); cur.push_back(*i++);
@ -49,23 +49,25 @@ Strings parseAttrPath(const string &s) {
} }
// From nix/src/nix/repl.cc // From nix/src/nix/repl.cc
bool isVarName(const string &s) { bool isVarName(const string & s)
{
if (s.size() == 0) if (s.size() == 0)
return false; return false;
char c = s[0]; char c = s[0];
if ((c >= '0' && c <= '9') || c == '-' || c == '\'') if ((c >= '0' && c <= '9') || c == '-' || c == '\'')
return false; return false;
for (auto &i : s) for (auto & i : s)
if (!((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z') || if (!((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z') || (i >= '0' && i <= '9') || i == '_' || i == '-' ||
(i >= '0' && i <= '9') || i == '_' || i == '-' || i == '\'')) i == '\''))
return false; return false;
return true; return true;
} }
// From nix/src/nix/repl.cc // From nix/src/nix/repl.cc
std::ostream &printStringValue(std::ostream &str, const char *string) { std::ostream & printStringValue(std::ostream & str, const char * string)
{
str << "\""; str << "\"";
for (const char *i = string; *i; i++) for (const char * i = string; *i; i++)
if (*i == '\"' || *i == '\\') if (*i == '\"' || *i == '\\')
str << "\\" << *i; str << "\\" << *i;
else if (*i == '\n') else if (*i == '\n')

View file

@ -4,6 +4,6 @@
#include <nix/types.hh> #include <nix/types.hh>
#include <string> #include <string>
nix::Strings parseAttrPath(const std::string &s); nix::Strings parseAttrPath(const std::string & s);
bool isVarName(const std::string &s); bool isVarName(const std::string & s);
std::ostream &printStringValue(std::ostream &str, const char *string); std::ostream & printStringValue(std::ostream & str, const char * string);

View file

@ -42,33 +42,39 @@ using nix::UsageError;
using nix::Value; using nix::Value;
// An ostream wrapper to handle nested indentation // An ostream wrapper to handle nested indentation
class Out { class Out
public: {
class Separator {}; public:
class Separator
{};
const static Separator sep; const static Separator sep;
enum LinePolicy { ONE_LINE, MULTI_LINE }; enum LinePolicy
explicit Out(std::ostream &ostream) {
: ostream(ostream), policy(ONE_LINE), write_since_sep(true) {} ONE_LINE,
Out(Out &o, std::string const &start, std::string const &end, MULTI_LINE
LinePolicy policy); };
Out(Out &o, std::string const &start, std::string const &end, int count) explicit Out(std::ostream & ostream) : ostream(ostream), policy(ONE_LINE), write_since_sep(true) {}
: Out(o, start, end, count < 2 ? ONE_LINE : MULTI_LINE) {} Out(Out & o, std::string const & start, std::string const & end, LinePolicy policy);
Out(Out & o, std::string const & start, std::string const & end, int count)
: Out(o, start, end, count < 2 ? ONE_LINE : MULTI_LINE)
{}
Out(Out const &) = delete; Out(Out const &) = delete;
Out(Out &&) = default; Out(Out &&) = default;
Out &operator=(Out const &) = delete; Out & operator=(Out const &) = delete;
Out &operator=(Out &&) = delete; Out & operator=(Out &&) = delete;
~Out() { ostream << end; } ~Out() { ostream << end; }
private: private:
std::ostream &ostream; std::ostream & ostream;
std::string indentation; std::string indentation;
std::string end; std::string end;
LinePolicy policy; LinePolicy policy;
bool write_since_sep; bool write_since_sep;
template <typename T> friend Out &operator<<(Out &o, T thing); template <typename T> friend Out & operator<<(Out & o, T thing);
}; };
template <typename T> Out &operator<<(Out &o, T thing) { template <typename T> Out & operator<<(Out & o, T thing)
{
if (!o.write_since_sep && o.policy == Out::MULTI_LINE) { if (!o.write_since_sep && o.policy == Out::MULTI_LINE) {
o.ostream << o.indentation; o.ostream << o.indentation;
} }
@ -77,38 +83,37 @@ template <typename T> Out &operator<<(Out &o, T thing) {
return o; return o;
} }
template <> template <> Out & operator<<<Out::Separator>(Out & o, Out::Separator /* thing */)
Out &operator<<<Out::Separator>(Out &o, Out::Separator /* thing */) { {
o.ostream << (o.policy == Out::ONE_LINE ? " " : "\n"); o.ostream << (o.policy == Out::ONE_LINE ? " " : "\n");
o.write_since_sep = false; o.write_since_sep = false;
return o; return o;
} }
Out::Out(Out &o, std::string const &start, std::string const &end, Out::Out(Out & o, std::string const & start, std::string const & end, LinePolicy policy)
LinePolicy policy) : ostream(o.ostream), indentation(policy == ONE_LINE ? o.indentation : o.indentation + " "),
: ostream(o.ostream), end(policy == ONE_LINE ? end : o.indentation + end), policy(policy), write_since_sep(true)
indentation(policy == ONE_LINE ? o.indentation : o.indentation + " "), {
end(policy == ONE_LINE ? end : o.indentation + end), policy(policy),
write_since_sep(true) {
o << start; o << start;
*this << Out::sep; *this << Out::sep;
} }
// Stuff needed for evaluation // Stuff needed for evaluation
struct Context { struct Context
Context(EvalState *state, Bindings *autoArgs, Value options_root, {
Value config_root) Context(EvalState * state, Bindings * autoArgs, Value options_root, Value config_root)
: state(state), autoArgs(autoArgs), options_root(options_root), : state(state), autoArgs(autoArgs), options_root(options_root), config_root(config_root),
config_root(config_root), underscore_type(state->symbols.create("_type"))
underscore_type(state->symbols.create("_type")) {} {}
EvalState *state; EvalState * state;
Bindings *autoArgs; Bindings * autoArgs;
Value options_root; Value options_root;
Value config_root; Value config_root;
Symbol underscore_type; Symbol underscore_type;
}; };
Value evaluateValue(Context *ctx, Value *v) { Value evaluateValue(Context * ctx, Value * v)
{
ctx->state->forceValue(*v); ctx->state->forceValue(*v);
if (ctx->autoArgs->empty()) { if (ctx->autoArgs->empty()) {
return *v; return *v;
@ -118,11 +123,12 @@ Value evaluateValue(Context *ctx, Value *v) {
return called; return called;
} }
bool isOption(Context *ctx, Value const &v) { bool isOption(Context * ctx, Value const & v)
{
if (v.type != tAttrs) { if (v.type != tAttrs) {
return false; return false;
} }
auto const &actual_type = v.attrs->find(ctx->underscore_type); auto const & actual_type = v.attrs->find(ctx->underscore_type);
if (actual_type == v.attrs->end()) { if (actual_type == v.attrs->end()) {
return false; return false;
} }
@ -141,7 +147,8 @@ bool isOption(Context *ctx, Value const &v) {
// These are needed for paths like: // These are needed for paths like:
// fileSystems."/".fsType // fileSystems."/".fsType
// systemd.units."dbus.service".text // systemd.units."dbus.service".text
std::string quoteAttribute(std::string const &attribute) { std::string quoteAttribute(std::string const & attribute)
{
if (isVarName(attribute)) { if (isVarName(attribute)) {
return attribute; return attribute;
} }
@ -150,25 +157,23 @@ std::string quoteAttribute(std::string const &attribute) {
return buf.str(); return buf.str();
} }
std::string const appendPath(std::string const &prefix, std::string const appendPath(std::string const & prefix, std::string const & suffix)
std::string const &suffix) { {
if (prefix.empty()) { if (prefix.empty()) {
return quoteAttribute(suffix); return quoteAttribute(suffix);
} }
return prefix + "." + quoteAttribute(suffix); return prefix + "." + quoteAttribute(suffix);
} }
bool forbiddenRecursionName(std::string name) { bool forbiddenRecursionName(std::string name) { return (!name.empty() && name[0] == '_') || name == "haskellPackages"; }
return (!name.empty() && name[0] == '_') || name == "haskellPackages";
}
void recurse(const std::function<bool(std::string const &path, void recurse(const std::function<bool(std::string const & path, std::variant<Value, Error>)> & f, Context * ctx,
std::variant<Value, Error>)> &f, Value v, std::string const & path)
Context *ctx, Value v, std::string const &path) { {
std::variant<Value, Error> evaluated; std::variant<Value, Error> evaluated;
try { try {
evaluated = evaluateValue(ctx, &v); evaluated = evaluateValue(ctx, &v);
} catch (Error &e) { } catch (Error & e) {
evaluated = e; evaluated = e;
} }
if (!f(path, evaluated)) { if (!f(path, evaluated)) {
@ -177,11 +182,11 @@ void recurse(const std::function<bool(std::string const &path,
if (std::holds_alternative<Error>(evaluated)) { if (std::holds_alternative<Error>(evaluated)) {
return; return;
} }
Value const &evaluated_value = std::get<Value>(evaluated); Value const & evaluated_value = std::get<Value>(evaluated);
if (evaluated_value.type != tAttrs) { if (evaluated_value.type != tAttrs) {
return; return;
} }
for (auto const &child : evaluated_value.attrs->lexicographicOrder()) { for (auto const & child : evaluated_value.attrs->lexicographicOrder()) {
if (forbiddenRecursionName(child->name)) { if (forbiddenRecursionName(child->name)) {
continue; continue;
} }
@ -190,12 +195,11 @@ void recurse(const std::function<bool(std::string const &path,
} }
// Calls f on all the option names // Calls f on all the option names
void mapOptions(const std::function<void(std::string const &path)> &f, void mapOptions(const std::function<void(std::string const & path)> & f, Context * ctx, Value root)
Context *ctx, Value root) { {
recurse( recurse(
[f, ctx](std::string const &path, std::variant<Value, Error> v) { [f, ctx](std::string const & path, std::variant<Value, Error> v) {
bool isOpt = std::holds_alternative<Error>(v) || bool isOpt = std::holds_alternative<Error>(v) || isOption(ctx, std::get<Value>(v));
isOption(ctx, std::get<Value>(v));
if (isOpt) { if (isOpt) {
f(path); f(path);
} }
@ -225,22 +229,19 @@ void mapOptions(const std::function<void(std::string const &path)> &f,
// users.users.nixbld1 = ... .. ... // users.users.nixbld1 = ... .. ...
// ... // ...
// users.users.systemd-timesync = ... .. ... // users.users.systemd-timesync = ... .. ...
void mapConfigValuesInOption( void mapConfigValuesInOption(const std::function<void(std::string const & path, std::variant<Value, Error> v)> & f,
const std::function<void(std::string const &path, std::string const & path, Context * ctx)
std::variant<Value, Error> v)> &f, {
std::string const &path, Context *ctx) { Value * option;
Value *option;
try { try {
option = option = findAlongAttrPath(*ctx->state, path, *ctx->autoArgs, ctx->config_root);
findAlongAttrPath(*ctx->state, path, *ctx->autoArgs, ctx->config_root); } catch (Error & e) {
} catch (Error &e) {
f(path, e); f(path, e);
return; return;
} }
recurse( recurse(
[f, ctx](std::string const &path, std::variant<Value, Error> v) { [f, ctx](std::string const & path, std::variant<Value, Error> v) {
bool leaf = std::holds_alternative<Error>(v) || bool leaf = std::holds_alternative<Error>(v) || std::get<Value>(v).type != tAttrs ||
std::get<Value>(v).type != tAttrs ||
ctx->state->isDerivation(std::get<Value>(v)); ctx->state->isDerivation(std::get<Value>(v));
if (!leaf) { if (!leaf) {
return true; // Keep digging return true; // Keep digging
@ -251,33 +252,32 @@ void mapConfigValuesInOption(
ctx, *option, path); ctx, *option, path);
} }
std::string describeError(Error const &e) { return "«error: " + e.msg() + "»"; } std::string describeError(Error const & e) { return "«error: " + e.msg() + "»"; }
void describeDerivation(Context *ctx, Out &out, Value v) { void describeDerivation(Context * ctx, Out & out, Value v)
{
// Copy-pasted from nix/src/nix/repl.cc :( // Copy-pasted from nix/src/nix/repl.cc :(
Bindings::iterator i = v.attrs->find(ctx->state->sDrvPath); Bindings::iterator i = v.attrs->find(ctx->state->sDrvPath);
PathSet pathset; PathSet pathset;
try { try {
Path drvPath = i != v.attrs->end() Path drvPath = i != v.attrs->end() ? ctx->state->coerceToPath(*i->pos, *i->value, pathset) : "???";
? ctx->state->coerceToPath(*i->pos, *i->value, pathset)
: "???";
out << "«derivation " << drvPath << "»"; out << "«derivation " << drvPath << "»";
} catch (Error &e) { } catch (Error & e) {
out << describeError(e); out << describeError(e);
} }
} }
Value parseAndEval(EvalState *state, std::string const &expression, Value parseAndEval(EvalState * state, std::string const & expression, std::string const & path)
std::string const &path) { {
Value v{}; Value v{};
state->eval(state->parseExprFromString(expression, absPath(path)), v); state->eval(state->parseExprFromString(expression, absPath(path)), v);
return v; return v;
} }
void printValue(Context *ctx, Out &out, std::variant<Value, Error> maybe_value, void printValue(Context * ctx, Out & out, std::variant<Value, Error> maybe_value, std::string const & path);
std::string const &path);
void printUnsortedList(Context *ctx, Out &out, Value &v) { void printUnsortedList(Context * ctx, Out & out, Value & v)
{
Out list_out(out, "[", "]", v.listSize()); Out list_out(out, "[", "]", v.listSize());
for (unsigned int n = 0; n < v.listSize(); ++n) { for (unsigned int n = 0; n < v.listSize(); ++n) {
printValue(ctx, list_out, *v.listElems()[n], ""); printValue(ctx, list_out, *v.listElems()[n], "");
@ -285,7 +285,8 @@ void printUnsortedList(Context *ctx, Out &out, Value &v) {
} }
} }
void printSortedList(Context *ctx, Out &out, Value &v) { void printSortedList(Context * ctx, Out & out, Value & v)
{
std::vector<std::string> results; std::vector<std::string> results;
for (unsigned int n = 0; n < v.listSize(); ++n) { for (unsigned int n = 0; n < v.listSize(); ++n) {
std::ostringstream buf; std::ostringstream buf;
@ -295,12 +296,13 @@ void printSortedList(Context *ctx, Out &out, Value &v) {
} }
std::sort(results.begin(), results.end()); std::sort(results.begin(), results.end());
Out list_out(out, "[", "]", v.listSize()); Out list_out(out, "[", "]", v.listSize());
for (auto const &v : results) { for (auto const & v : results) {
list_out << v << Out::sep; list_out << v << Out::sep;
} }
} }
bool shouldSort(Context *ctx, Value &v) { bool shouldSort(Context * ctx, Value & v)
{
// Some lists should clearly be printed in sorted order, like // Some lists should clearly be printed in sorted order, like
// environment.systemPackages. Some clearly should not, like // environment.systemPackages. Some clearly should not, like
// services.xserver.multitouch.buttonsMap. As a conservative heuristic, sort // services.xserver.multitouch.buttonsMap. As a conservative heuristic, sort
@ -308,7 +310,8 @@ bool shouldSort(Context *ctx, Value &v) {
return v.listSize() > 0 && ctx->state->isDerivation(*v.listElems()[0]); return v.listSize() > 0 && ctx->state->isDerivation(*v.listElems()[0]);
} }
void printList(Context *ctx, Out &out, Value &v) { void printList(Context * ctx, Out & out, Value & v)
{
if (shouldSort(ctx, v)) { if (shouldSort(ctx, v)) {
printSortedList(ctx, out, v); printSortedList(ctx, out, v);
} else { } else {
@ -316,9 +319,10 @@ void printList(Context *ctx, Out &out, Value &v) {
} }
} }
void printAttrs(Context *ctx, Out &out, Value &v, std::string const &path) { void printAttrs(Context * ctx, Out & out, Value & v, std::string const & path)
{
Out attrs_out(out, "{", "}", v.attrs->size()); Out attrs_out(out, "{", "}", v.attrs->size());
for (const auto &a : v.attrs->lexicographicOrder()) { for (const auto & a : v.attrs->lexicographicOrder()) {
std::string name = a->name; std::string name = a->name;
attrs_out << name << " = "; attrs_out << name << " = ";
printValue(ctx, attrs_out, *a->value, appendPath(path, name)); printValue(ctx, attrs_out, *a->value, appendPath(path, name));
@ -326,7 +330,8 @@ void printAttrs(Context *ctx, Out &out, Value &v, std::string const &path) {
} }
} }
void multiLineStringEscape(Out &out, std::string const &s) { void multiLineStringEscape(Out & out, std::string const & s)
{
int i; int i;
for (i = 1; i < s.size(); i++) { for (i = 1; i < s.size(); i++) {
if (s[i - 1] == '$' && s[i] == '{') { if (s[i - 1] == '$' && s[i] == '{') {
@ -344,7 +349,8 @@ void multiLineStringEscape(Out &out, std::string const &s) {
} }
} }
void printMultiLineString(Out &out, Value const &v) { void printMultiLineString(Out & out, Value const & v)
{
std::string s = v.string.s; std::string s = v.string.s;
Out str_out(out, "''", "''", Out::MULTI_LINE); Out str_out(out, "''", "''", Out::MULTI_LINE);
std::string::size_type begin = 0; std::string::size_type begin = 0;
@ -360,8 +366,8 @@ void printMultiLineString(Out &out, Value const &v) {
} }
} }
void printValue(Context *ctx, Out &out, std::variant<Value, Error> maybe_value, void printValue(Context * ctx, Out & out, std::variant<Value, Error> maybe_value, std::string const & path)
std::string const &path) { {
try { try {
if (std::holds_alternative<Error>(maybe_value)) { if (std::holds_alternative<Error>(maybe_value)) {
throw Error{std::get<Error>(maybe_value)}; throw Error{std::get<Error>(maybe_value)};
@ -373,14 +379,13 @@ void printValue(Context *ctx, Out &out, std::variant<Value, Error> maybe_value,
printList(ctx, out, v); printList(ctx, out, v);
} else if (v.type == tAttrs) { } else if (v.type == tAttrs) {
printAttrs(ctx, out, v, path); printAttrs(ctx, out, v, path);
} else if (v.type == tString && } else if (v.type == tString && std::string(v.string.s).find('\n') != std::string::npos) {
std::string(v.string.s).find('\n') != std::string::npos) {
printMultiLineString(out, v); printMultiLineString(out, v);
} else { } else {
ctx->state->forceValueDeep(v); ctx->state->forceValueDeep(v);
out << v; out << v;
} }
} catch (Error &e) { } catch (Error & e) {
if (e.msg() == "The option `" + path + "' is used but not defined.") { if (e.msg() == "The option `" + path + "' is used but not defined.") {
// 93% of errors are this, and just letting this message through would be // 93% of errors are this, and just letting this message through would be
// misleading. These values may or may not actually be "used" in the // misleading. These values may or may not actually be "used" in the
@ -396,19 +401,19 @@ void printValue(Context *ctx, Out &out, std::variant<Value, Error> maybe_value,
} }
} }
void printConfigValue(Context *ctx, Out &out, std::string const &path, void printConfigValue(Context * ctx, Out & out, std::string const & path, std::variant<Value, Error> v)
std::variant<Value, Error> v) { {
out << path << " = "; out << path << " = ";
printValue(ctx, out, std::move(v), path); printValue(ctx, out, std::move(v), path);
out << ";\n"; out << ";\n";
} }
void printAll(Context *ctx, Out &out) { void printAll(Context * ctx, Out & out)
{
mapOptions( mapOptions(
[ctx, &out](std::string const &option_path) { [ctx, &out](std::string const & option_path) {
mapConfigValuesInOption( mapConfigValuesInOption(
[ctx, &out](std::string const &config_path, [ctx, &out](std::string const & config_path, std::variant<Value, Error> v) {
std::variant<Value, Error> v) {
printConfigValue(ctx, out, config_path, v); printConfigValue(ctx, out, config_path, v);
}, },
option_path, ctx); option_path, ctx);
@ -416,18 +421,17 @@ void printAll(Context *ctx, Out &out) {
ctx, ctx->options_root); ctx, ctx->options_root);
} }
void printAttr(Context *ctx, Out &out, std::string const &path, Value *root) { void printAttr(Context * ctx, Out & out, std::string const & path, Value * root)
{
try { try {
printValue(ctx, out, printValue(ctx, out, *findAlongAttrPath(*ctx->state, path, *ctx->autoArgs, *root), path);
*findAlongAttrPath(*ctx->state, path, *ctx->autoArgs, *root), } catch (Error & e) {
path);
} catch (Error &e) {
out << describeError(e); out << describeError(e);
} }
} }
void printOption(Context *ctx, Out &out, std::string const &path, void printOption(Context * ctx, Out & out, std::string const & path, Value * option)
Value *option) { {
out << "Value:\n"; out << "Value:\n";
printAttr(ctx, out, path, &ctx->config_root); printAttr(ctx, out, path, &ctx->config_root);
@ -451,11 +455,12 @@ void printOption(Context *ctx, Out &out, std::string const &path,
out << "\n"; out << "\n";
} }
void printListing(Out &out, Value *v) { void printListing(Out & out, Value * v)
{
// Print this header on stderr rather than stdout because the old shell script // Print this header on stderr rather than stdout because the old shell script
// implementation did. I don't know why. // implementation did. I don't know why.
std::cerr << "This attribute set contains:\n"; std::cerr << "This attribute set contains:\n";
for (const auto &a : v->attrs->lexicographicOrder()) { for (const auto & a : v->attrs->lexicographicOrder()) {
std::string name = a->name; std::string name = a->name;
if (!name.empty() && name[0] != '_') { if (!name.empty() && name[0] != '_') {
out << name << "\n"; out << name << "\n";
@ -465,23 +470,22 @@ void printListing(Out &out, Value *v) {
// Carefully walk an option path, looking for sub-options when a path walks past // Carefully walk an option path, looking for sub-options when a path walks past
// an option value. // an option value.
Value findAlongOptionPath(Context *ctx, std::string const &path) { Value findAlongOptionPath(Context * ctx, std::string const & path)
{
Strings tokens = parseAttrPath(path); Strings tokens = parseAttrPath(path);
Value v = ctx->options_root; Value v = ctx->options_root;
for (auto i = tokens.begin(); i != tokens.end(); i++) { for (auto i = tokens.begin(); i != tokens.end(); i++) {
bool last_attribute = std::next(i) == tokens.end(); bool last_attribute = std::next(i) == tokens.end();
auto const &attr = *i; auto const & attr = *i;
v = evaluateValue(ctx, &v); v = evaluateValue(ctx, &v);
if (attr.empty()) { if (attr.empty()) {
throw Error("empty attribute name in selection path '" + path + "'"); throw Error("empty attribute name in selection path '" + path + "'");
} }
if (isOption(ctx, v) && !last_attribute) { if (isOption(ctx, v) && !last_attribute) {
Value getSubOptions = evaluateValue( Value getSubOptions =
ctx, findAlongAttrPath(*ctx->state, "type.getSubOptions", evaluateValue(ctx, findAlongAttrPath(*ctx->state, "type.getSubOptions", *ctx->autoArgs, v));
*ctx->autoArgs, v));
if (getSubOptions.type != tLambda) { if (getSubOptions.type != tLambda) {
throw Error("Option's type.getSubOptions isn't a function at '" + attr + throw Error("Option's type.getSubOptions isn't a function at '" + attr + "' in path '" + path + "'");
"' in path '" + path + "'");
} }
Value emptyString{}; Value emptyString{};
nix::mkString(emptyString, ""); nix::mkString(emptyString, "");
@ -489,13 +493,11 @@ Value findAlongOptionPath(Context *ctx, std::string const &path) {
// Note that we've consumed attr, but didn't actually use it. // Note that we've consumed attr, but didn't actually use it.
} else if (v.type != tAttrs) { } else if (v.type != tAttrs) {
throw Error("attribute '" + attr + "' in path '" + path + throw Error("attribute '" + attr + "' in path '" + path +
"' attempts to index a value that should be a set but is " + "' attempts to index a value that should be a set but is " + showType(v));
showType(v));
} else { } else {
auto const &next = v.attrs->find(ctx->state->symbols.create(attr)); auto const & next = v.attrs->find(ctx->state->symbols.create(attr));
if (next == v.attrs->end()) { if (next == v.attrs->end()) {
throw Error("attribute '" + attr + "' in path '" + path + throw Error("attribute '" + attr + "' in path '" + path + "' not found");
"' not found");
} }
v = *next->value; v = *next->value;
} }
@ -503,7 +505,8 @@ Value findAlongOptionPath(Context *ctx, std::string const &path) {
return v; return v;
} }
void printOne(Context *ctx, Out &out, std::string const &path) { void printOne(Context * ctx, Out & out, std::string const & path)
{
try { try {
Value option = findAlongOptionPath(ctx, path); Value option = findAlongOptionPath(ctx, path);
option = evaluateValue(ctx, &option); option = evaluateValue(ctx, &option);
@ -512,7 +515,7 @@ void printOne(Context *ctx, Out &out, std::string const &path) {
} else { } else {
printListing(out, &option); printListing(out, &option);
} }
} catch (Error &e) { } catch (Error & e) {
std::cerr << "error: " << e.msg() std::cerr << "error: " << e.msg()
<< "\nAn error occurred while looking for attribute names. Are " << "\nAn error occurred while looking for attribute names. Are "
"you sure that '" "you sure that '"
@ -520,19 +523,20 @@ void printOne(Context *ctx, Out &out, std::string const &path) {
} }
} }
int main(int argc, char **argv) { int main(int argc, char ** argv)
{
bool all = false; bool all = false;
std::string path = "."; std::string path = ".";
std::string options_expr = "(import <nixpkgs/nixos> {}).options"; std::string options_expr = "(import <nixpkgs/nixos> {}).options";
std::string config_expr = "(import <nixpkgs/nixos> {}).config"; std::string config_expr = "(import <nixpkgs/nixos> {}).config";
std::vector<std::string> args; std::vector<std::string> args;
struct MyArgs : nix::LegacyArgs, nix::MixEvalArgs { struct MyArgs : nix::LegacyArgs, nix::MixEvalArgs
{
using nix::LegacyArgs::LegacyArgs; using nix::LegacyArgs::LegacyArgs;
}; };
MyArgs myArgs(nix::baseNameOf(argv[0]), MyArgs myArgs(nix::baseNameOf(argv[0]), [&](Strings::iterator & arg, const Strings::iterator & end) {
[&](Strings::iterator &arg, const Strings::iterator &end) {
if (*arg == "--help") { if (*arg == "--help") {
nix::showManPage("nixos-option"); nix::showManPage("nixos-option");
} else if (*arg == "--version") { } else if (*arg == "--version") {
@ -564,8 +568,7 @@ int main(int argc, char **argv) {
Value options_root = parseAndEval(state.get(), options_expr, path); Value options_root = parseAndEval(state.get(), options_expr, path);
Value config_root = parseAndEval(state.get(), config_expr, path); Value config_root = parseAndEval(state.get(), config_expr, path);
Context ctx{state.get(), myArgs.getAutoArgs(*state), options_root, Context ctx{state.get(), myArgs.getAutoArgs(*state), options_root, config_root};
config_root};
Out out(std::cout); Out out(std::cout);
if (all) { if (all) {
@ -577,7 +580,7 @@ int main(int argc, char **argv) {
if (args.empty()) { if (args.empty()) {
printOne(&ctx, out, ""); printOne(&ctx, out, "");
} }
for (auto const &arg : args) { for (auto const & arg : args) {
printOne(&ctx, out, arg); printOne(&ctx, out, arg);
} }
} }