libexpr: extend Value::print
to allow limited depth
This commit is contained in:
parent
c48277c1c1
commit
1400fde144
|
@ -96,10 +96,15 @@ RootValue allocRootValue(Value * v)
|
|||
}
|
||||
|
||||
void Value::print(const SymbolTable &symbols, std::ostream &str,
|
||||
std::set<const void *> * seen) const
|
||||
std::set<const void *> *seen, int depth) const
|
||||
|
||||
{
|
||||
checkInterrupt();
|
||||
|
||||
if (depth <= 0) {
|
||||
str << "«too deep»";
|
||||
return;
|
||||
}
|
||||
switch (internalType) {
|
||||
case tInt:
|
||||
str << integer;
|
||||
|
@ -123,7 +128,7 @@ void Value::print(const SymbolTable & symbols, std::ostream & str,
|
|||
str << "{ ";
|
||||
for (auto & i : attrs->lexicographicOrder(symbols)) {
|
||||
str << symbols[i->name] << " = ";
|
||||
i->value->print(symbols, str, seen);
|
||||
i->value->print(symbols, str, seen, depth - 1);
|
||||
str << "; ";
|
||||
}
|
||||
str << "}";
|
||||
|
@ -139,7 +144,7 @@ void Value::print(const SymbolTable & symbols, std::ostream & str,
|
|||
str << "[ ";
|
||||
for (auto v2 : listItems()) {
|
||||
if (v2)
|
||||
v2->print(symbols, str, seen);
|
||||
v2->print(symbols, str, seen, depth - 1);
|
||||
else
|
||||
str << "(nullptr)";
|
||||
str << " ";
|
||||
|
@ -181,11 +186,10 @@ void Value::print(const SymbolTable & symbols, std::ostream & str,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Value::print(const SymbolTable & symbols, std::ostream & str, bool showRepeated) const
|
||||
{
|
||||
void Value::print(const SymbolTable &symbols, std::ostream &str,
|
||||
bool showRepeated, int depth) const {
|
||||
std::set<const void *> seen;
|
||||
print(symbols, str, showRepeated ? nullptr : &seen);
|
||||
print(symbols, str, showRepeated ? nullptr : &seen, depth);
|
||||
}
|
||||
|
||||
// Pretty print types for assertion errors
|
||||
|
|
|
@ -167,4 +167,70 @@ TEST_F(ValuePrintingTests, vBlackhole)
|
|||
test(vBlackhole, "«potential infinite recursion»");
|
||||
}
|
||||
|
||||
TEST_F(ValuePrintingTests, depthAttrs)
|
||||
{
|
||||
Value vOne;
|
||||
vOne.mkInt(1);
|
||||
|
||||
Value vTwo;
|
||||
vTwo.mkInt(2);
|
||||
|
||||
BindingsBuilder builder(state, state.allocBindings(10));
|
||||
builder.insert(state.symbols.create("one"), &vOne);
|
||||
builder.insert(state.symbols.create("two"), &vTwo);
|
||||
|
||||
Value vAttrs;
|
||||
vAttrs.mkAttrs(builder.finish());
|
||||
|
||||
BindingsBuilder builder2(state, state.allocBindings(10));
|
||||
builder2.insert(state.symbols.create("one"), &vOne);
|
||||
builder2.insert(state.symbols.create("two"), &vTwo);
|
||||
builder2.insert(state.symbols.create("nested"), &vAttrs);
|
||||
|
||||
Value vNested;
|
||||
vNested.mkAttrs(builder2.finish());
|
||||
|
||||
test(vNested, "{ nested = «too deep»; one = «too deep»; two = «too deep»; }", false, 1);
|
||||
test(vNested, "{ nested = { one = «too deep»; two = «too deep»; }; one = 1; two = 2; }", false, 2);
|
||||
test(vNested, "{ nested = { one = 1; two = 2; }; one = 1; two = 2; }", false, 3);
|
||||
test(vNested, "{ nested = { one = 1; two = 2; }; one = 1; two = 2; }", false, 4);
|
||||
}
|
||||
|
||||
TEST_F(ValuePrintingTests, depthList)
|
||||
{
|
||||
Value vOne;
|
||||
vOne.mkInt(1);
|
||||
|
||||
Value vTwo;
|
||||
vTwo.mkInt(2);
|
||||
|
||||
BindingsBuilder builder(state, state.allocBindings(10));
|
||||
builder.insert(state.symbols.create("one"), &vOne);
|
||||
builder.insert(state.symbols.create("two"), &vTwo);
|
||||
|
||||
Value vAttrs;
|
||||
vAttrs.mkAttrs(builder.finish());
|
||||
|
||||
BindingsBuilder builder2(state, state.allocBindings(10));
|
||||
builder2.insert(state.symbols.create("one"), &vOne);
|
||||
builder2.insert(state.symbols.create("two"), &vTwo);
|
||||
builder2.insert(state.symbols.create("nested"), &vAttrs);
|
||||
|
||||
Value vNested;
|
||||
vNested.mkAttrs(builder2.finish());
|
||||
|
||||
Value vList;
|
||||
state.mkList(vList, 5);
|
||||
vList.bigList.elems[0] = &vOne;
|
||||
vList.bigList.elems[1] = &vTwo;
|
||||
vList.bigList.elems[2] = &vNested;
|
||||
vList.bigList.size = 3;
|
||||
|
||||
test(vList, "[ «too deep» «too deep» «too deep» ]", false, 1);
|
||||
test(vList, "[ 1 2 { nested = «too deep»; one = «too deep»; two = «too deep»; } ]", false, 2);
|
||||
test(vList, "[ 1 2 { nested = { one = «too deep»; two = «too deep»; }; one = 1; two = 2; } ]", false, 3);
|
||||
test(vList, "[ 1 2 { nested = { one = 1; two = 2; }; one = 1; two = 2; } ]", false, 4);
|
||||
test(vList, "[ 1 2 { nested = { one = 1; two = 2; }; one = 1; two = 2; } ]", false, 5);
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
///@file
|
||||
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
|
||||
#include "symbol-table.hh"
|
||||
#include "value/context.hh"
|
||||
|
@ -137,11 +138,11 @@ private:
|
|||
|
||||
friend std::string showType(const Value & v);
|
||||
|
||||
void print(const SymbolTable & symbols, std::ostream & str, std::set<const void *> * seen) const;
|
||||
void print(const SymbolTable &symbols, std::ostream &str, std::set<const void *> *seen, int depth) const;
|
||||
|
||||
public:
|
||||
|
||||
void print(const SymbolTable & symbols, std::ostream & str, bool showRepeated = false) const;
|
||||
void print(const SymbolTable &symbols, std::ostream &str, bool showRepeated = false, int depth = INT_MAX) const;
|
||||
|
||||
// Functions needed to distinguish the type
|
||||
// These should be removed eventually, by putting the functionality that's
|
||||
|
|
Loading…
Reference in a new issue