-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restore ambiguous value printer for
nix-instantiate
The Nix team has requested that this output format remain unchanged. I've added a warning to the man page explaining that `nix-instantiate --eval` output will not parse correctly in many situations.
- Loading branch information
Showing
6 changed files
with
189 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#include "print-ambiguous.hh" | ||
#include "print.hh" | ||
#include "signals.hh" | ||
|
||
namespace nix { | ||
|
||
// See: https://github.com/NixOS/nix/issues/9730 | ||
void printAmbiguous( | ||
Value &v, | ||
const SymbolTable &symbols, | ||
std::ostream &str, | ||
std::set<const void *> *seen, | ||
int depth) | ||
{ | ||
checkInterrupt(); | ||
|
||
if (depth <= 0) { | ||
str << "«too deep»"; | ||
return; | ||
} | ||
switch (v.type()) { | ||
case nInt: | ||
str << v.integer; | ||
break; | ||
case nBool: | ||
printLiteralBool(str, v.boolean); | ||
break; | ||
case nString: | ||
printLiteralString(str, v.string_view()); | ||
break; | ||
case nPath: | ||
str << v.path().to_string(); // !!! escaping? | ||
break; | ||
case nNull: | ||
str << "null"; | ||
break; | ||
case nAttrs: { | ||
if (seen && !v.attrs->empty() && !seen->insert(v.attrs).second) | ||
str << "«repeated»"; | ||
else { | ||
str << "{ "; | ||
for (auto & i : v.attrs->lexicographicOrder(symbols)) { | ||
str << symbols[i->name] << " = "; | ||
printAmbiguous(*i->value, symbols, str, seen, depth - 1); | ||
str << "; "; | ||
} | ||
str << "}"; | ||
} | ||
break; | ||
} | ||
case nList: | ||
if (seen && v.listSize() && !seen->insert(v.listElems()).second) | ||
str << "«repeated»"; | ||
else { | ||
str << "[ "; | ||
for (auto v2 : v.listItems()) { | ||
if (v2) | ||
printAmbiguous(*v2, symbols, str, seen, depth - 1); | ||
else | ||
str << "(nullptr)"; | ||
str << " "; | ||
} | ||
str << "]"; | ||
} | ||
break; | ||
case nThunk: | ||
if (!v.isBlackhole()) { | ||
str << "<CODE>"; | ||
} else { | ||
// Although we know for sure that it's going to be an infinite recursion | ||
// when this value is accessed _in the current context_, it's likely | ||
// that the user will misinterpret a simpler «infinite recursion» output | ||
// as a definitive statement about the value, while in fact it may be | ||
// a valid value after `builtins.trace` and perhaps some other steps | ||
// have completed. | ||
str << "«potential infinite recursion»"; | ||
} | ||
break; | ||
case nFunction: | ||
if (v.isLambda()) { | ||
str << "<LAMBDA>"; | ||
} else if (v.isPrimOp()) { | ||
str << "<PRIMOP>"; | ||
} else if (v.isPrimOpApp()) { | ||
str << "<PRIMOP-APP>"; | ||
} | ||
break; | ||
case nExternal: | ||
str << *v.external; | ||
break; | ||
case nFloat: | ||
str << v.fpoint; | ||
break; | ||
default: | ||
printError("Nix evaluator internal error: printAmbiguous: invalid value type"); | ||
abort(); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#pragma once | ||
|
||
#include "value.hh" | ||
|
||
namespace nix { | ||
|
||
/** | ||
* Print a value in the deprecated format used by `nix-instantiate --eval` and | ||
* `nix-env` (for manifests). | ||
* | ||
* This output can't be changed because it's part of the `nix-instantiate` API, | ||
* but it produces ambiguous output; unevaluated thunks and lambdas (and a few | ||
* other types) are printed as Nix path syntax like `<CODE>`. | ||
* | ||
* See: https://github.com/NixOS/nix/issues/9730 | ||
*/ | ||
void printAmbiguous( | ||
Value &v, | ||
const SymbolTable &symbols, | ||
std::ostream &str, | ||
std::set<const void *> *seen, | ||
int depth); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
[ null «primop toString» «partially applied primop deepSeq» «lambda @ /pwd/lang/eval-okay-print.nix:1:61» [ [ «repeated» ] ] ] | ||
[ null <PRIMOP> <PRIMOP-APP> <LAMBDA> [ [ «repeated» ] ] ] |