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:
parent
74f05df671
commit
4af8dbf896
3 changed files with 534 additions and 529 deletions
|
@ -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')
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue