mirror of
https://github.com/NixOS/nix
synced 2025-06-28 13:41:15 +02:00
Replace src/libutil/json.cc with nlohmann json generation
This commit is contained in:
parent
62960f3291
commit
09f00dd4d0
25 changed files with 266 additions and 858 deletions
|
@ -7,7 +7,6 @@
|
|||
#include "globals.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "filetransfer.hh"
|
||||
#include "json.hh"
|
||||
#include "function-trace.hh"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -21,6 +20,7 @@
|
|||
#include <functional>
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#if HAVE_BOEHMGC
|
||||
|
||||
|
@ -35,6 +35,8 @@
|
|||
|
||||
#endif
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace nix {
|
||||
|
||||
static char * allocString(size_t size)
|
||||
|
@ -2441,97 +2443,97 @@ void EvalState::printStats()
|
|||
std::fstream fs;
|
||||
if (outPath != "-")
|
||||
fs.open(outPath, std::fstream::out);
|
||||
JSONObject topObj(outPath == "-" ? std::cerr : fs, true);
|
||||
topObj.attr("cpuTime",cpuTime);
|
||||
{
|
||||
auto envs = topObj.object("envs");
|
||||
envs.attr("number", nrEnvs);
|
||||
envs.attr("elements", nrValuesInEnvs);
|
||||
envs.attr("bytes", bEnvs);
|
||||
}
|
||||
{
|
||||
auto lists = topObj.object("list");
|
||||
lists.attr("elements", nrListElems);
|
||||
lists.attr("bytes", bLists);
|
||||
lists.attr("concats", nrListConcats);
|
||||
}
|
||||
{
|
||||
auto values = topObj.object("values");
|
||||
values.attr("number", nrValues);
|
||||
values.attr("bytes", bValues);
|
||||
}
|
||||
{
|
||||
auto syms = topObj.object("symbols");
|
||||
syms.attr("number", symbols.size());
|
||||
syms.attr("bytes", symbols.totalSize());
|
||||
}
|
||||
{
|
||||
auto sets = topObj.object("sets");
|
||||
sets.attr("number", nrAttrsets);
|
||||
sets.attr("bytes", bAttrsets);
|
||||
sets.attr("elements", nrAttrsInAttrsets);
|
||||
}
|
||||
{
|
||||
auto sizes = topObj.object("sizes");
|
||||
sizes.attr("Env", sizeof(Env));
|
||||
sizes.attr("Value", sizeof(Value));
|
||||
sizes.attr("Bindings", sizeof(Bindings));
|
||||
sizes.attr("Attr", sizeof(Attr));
|
||||
}
|
||||
topObj.attr("nrOpUpdates", nrOpUpdates);
|
||||
topObj.attr("nrOpUpdateValuesCopied", nrOpUpdateValuesCopied);
|
||||
topObj.attr("nrThunks", nrThunks);
|
||||
topObj.attr("nrAvoided", nrAvoided);
|
||||
topObj.attr("nrLookups", nrLookups);
|
||||
topObj.attr("nrPrimOpCalls", nrPrimOpCalls);
|
||||
topObj.attr("nrFunctionCalls", nrFunctionCalls);
|
||||
json topObj = json::object();
|
||||
topObj["cpuTime"] = cpuTime;
|
||||
topObj["envs"] = {
|
||||
{"number", nrEnvs},
|
||||
{"elements", nrValuesInEnvs},
|
||||
{"bytes", bEnvs},
|
||||
};
|
||||
topObj["list"] = {
|
||||
{"elements", nrListElems},
|
||||
{"bytes", bLists},
|
||||
{"concats", nrListConcats},
|
||||
};
|
||||
topObj["values"] = {
|
||||
{"number", nrValues},
|
||||
{"bytes", bValues},
|
||||
};
|
||||
topObj["symbols"] = {
|
||||
{"number", symbols.size()},
|
||||
{"bytes", symbols.totalSize()},
|
||||
};
|
||||
topObj["sets"] = {
|
||||
{"number", nrAttrsets},
|
||||
{"bytes", bAttrsets},
|
||||
{"elements", nrAttrsInAttrsets},
|
||||
};
|
||||
topObj["sizes"] = {
|
||||
{"Env", sizeof(Env)},
|
||||
{"Value", sizeof(Value)},
|
||||
{"Bindings", sizeof(Bindings)},
|
||||
{"Attr", sizeof(Attr)},
|
||||
};
|
||||
topObj["nrOpUpdates"] = nrOpUpdates;
|
||||
topObj["nrOpUpdateValuesCopied"] = nrOpUpdateValuesCopied;
|
||||
topObj["nrThunks"] = nrThunks;
|
||||
topObj["nrAvoided"] = nrAvoided;
|
||||
topObj["nrLookups"] = nrLookups;
|
||||
topObj["nrPrimOpCalls"] = nrPrimOpCalls;
|
||||
topObj["nrFunctionCalls"] = nrFunctionCalls;
|
||||
#if HAVE_BOEHMGC
|
||||
{
|
||||
auto gc = topObj.object("gc");
|
||||
gc.attr("heapSize", heapSize);
|
||||
gc.attr("totalBytes", totalBytes);
|
||||
}
|
||||
topObj["gc"] = {
|
||||
{"heapSize", heapSize},
|
||||
{"totalBytes", totalBytes},
|
||||
};
|
||||
#endif
|
||||
|
||||
if (countCalls) {
|
||||
topObj["primops"] = primOpCalls;
|
||||
{
|
||||
auto obj = topObj.object("primops");
|
||||
for (auto & i : primOpCalls)
|
||||
obj.attr(i.first, i.second);
|
||||
}
|
||||
{
|
||||
auto list = topObj.list("functions");
|
||||
auto& list = topObj["functions"];
|
||||
list = json::array();
|
||||
for (auto & [fun, count] : functionCalls) {
|
||||
auto obj = list.object();
|
||||
json obj = json::object();
|
||||
if (fun->name)
|
||||
obj.attr("name", (std::string_view) symbols[fun->name]);
|
||||
obj["name"] = (std::string_view) symbols[fun->name];
|
||||
else
|
||||
obj.attr("name", nullptr);
|
||||
obj["name"] = nullptr;
|
||||
if (auto pos = positions[fun->pos]) {
|
||||
obj.attr("file", (std::string_view) pos.file);
|
||||
obj.attr("line", pos.line);
|
||||
obj.attr("column", pos.column);
|
||||
obj["file"] = (std::string_view) pos.file;
|
||||
obj["line"] = pos.line;
|
||||
obj["column"] = pos.column;
|
||||
}
|
||||
obj.attr("count", count);
|
||||
obj["count"] = count;
|
||||
list.push_back(obj);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto list = topObj.list("attributes");
|
||||
auto list = topObj["attributes"];
|
||||
list = json::array();
|
||||
for (auto & i : attrSelects) {
|
||||
auto obj = list.object();
|
||||
json obj = json::object();
|
||||
if (auto pos = positions[i.first]) {
|
||||
obj.attr("file", (const std::string &) pos.file);
|
||||
obj.attr("line", pos.line);
|
||||
obj.attr("column", pos.column);
|
||||
obj["file"] = (const std::string &) pos.file;
|
||||
obj["line"] = pos.line;
|
||||
obj["column"] = pos.column;
|
||||
}
|
||||
obj.attr("count", i.second);
|
||||
obj["count"] = i.second;
|
||||
list.push_back(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getEnv("NIX_SHOW_SYMBOLS").value_or("0") != "0") {
|
||||
auto list = topObj.list("symbols");
|
||||
symbols.dump([&](const std::string & s) { list.elem(s); });
|
||||
// XXX: overrides earlier assignment
|
||||
topObj["symbols"] = json::array();
|
||||
auto &list = topObj["symbols"];
|
||||
symbols.dump([&](const std::string & s) { list.emplace_back(s); });
|
||||
}
|
||||
if (outPath == "-") {
|
||||
std::cerr << topObj.dump(2) << std::endl;
|
||||
} else {
|
||||
fs << topObj.dump(2) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
#include "references.hh"
|
||||
#include "store-api.hh"
|
||||
#include "util.hh"
|
||||
#include "json.hh"
|
||||
#include "value-to-json.hh"
|
||||
#include "value-to-xml.hh"
|
||||
#include "primops.hh"
|
||||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -1011,6 +1011,7 @@ static void prim_second(EvalState & state, const PosIdx pos, Value * * args, Val
|
|||
derivation. */
|
||||
static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
using nlohmann::json;
|
||||
state.forceAttrs(*args[0], pos);
|
||||
|
||||
/* Figure out the name first (for stack backtraces). */
|
||||
|
@ -1032,11 +1033,10 @@ static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value * *
|
|||
}
|
||||
|
||||
/* Check whether attributes should be passed as a JSON file. */
|
||||
std::ostringstream jsonBuf;
|
||||
std::unique_ptr<JSONObject> jsonObject;
|
||||
std::optional<json> jsonObject;
|
||||
attr = args[0]->attrs->find(state.sStructuredAttrs);
|
||||
if (attr != args[0]->attrs->end() && state.forceBool(*attr->value, pos))
|
||||
jsonObject = std::make_unique<JSONObject>(jsonBuf);
|
||||
jsonObject = json::object();
|
||||
|
||||
/* Check whether null attributes should be ignored. */
|
||||
bool ignoreNulls = false;
|
||||
|
@ -1138,8 +1138,7 @@ static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value * *
|
|||
|
||||
if (i->name == state.sStructuredAttrs) continue;
|
||||
|
||||
auto placeholder(jsonObject->placeholder(key));
|
||||
printValueAsJSON(state, true, *i->value, pos, placeholder, context);
|
||||
(*jsonObject)[key] = printValueAsJSON(state, true, *i->value, pos, context);
|
||||
|
||||
if (i->name == state.sBuilder)
|
||||
drv.builder = state.forceString(*i->value, context, posDrvName);
|
||||
|
@ -1183,8 +1182,8 @@ static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value * *
|
|||
}
|
||||
|
||||
if (jsonObject) {
|
||||
drv.env.emplace("__json", jsonObject->dump());
|
||||
jsonObject.reset();
|
||||
drv.env.emplace("__json", jsonBuf.str());
|
||||
}
|
||||
|
||||
/* Everything in the context of the strings in the derivation
|
||||
|
|
|
@ -1,84 +1,82 @@
|
|||
#include "value-to-json.hh"
|
||||
#include "json.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iomanip>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, JSONPlaceholder & out, PathSet & context, bool copyToStore)
|
||||
using json = nlohmann::json;
|
||||
json printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, PathSet & context, bool copyToStore)
|
||||
{
|
||||
checkInterrupt();
|
||||
|
||||
if (strict) state.forceValue(v, pos);
|
||||
|
||||
json out;
|
||||
|
||||
switch (v.type()) {
|
||||
|
||||
case nInt:
|
||||
out.write(v.integer);
|
||||
out = v.integer;
|
||||
break;
|
||||
|
||||
case nBool:
|
||||
out.write(v.boolean);
|
||||
out = v.boolean;
|
||||
break;
|
||||
|
||||
case nString:
|
||||
copyContext(v, context);
|
||||
out.write(v.string.s);
|
||||
out = v.string.s;
|
||||
break;
|
||||
|
||||
case nPath:
|
||||
if (copyToStore)
|
||||
out.write(state.copyPathToStore(context, v.path));
|
||||
out = state.copyPathToStore(context, v.path);
|
||||
else
|
||||
out.write(v.path);
|
||||
out = v.path;
|
||||
break;
|
||||
|
||||
case nNull:
|
||||
out.write(nullptr);
|
||||
break;
|
||||
|
||||
case nAttrs: {
|
||||
auto maybeString = state.tryAttrsToString(pos, v, context, false, false);
|
||||
if (maybeString) {
|
||||
out.write(*maybeString);
|
||||
out = *maybeString;
|
||||
break;
|
||||
}
|
||||
auto i = v.attrs->find(state.sOutPath);
|
||||
if (i == v.attrs->end()) {
|
||||
auto obj(out.object());
|
||||
out = json::object();
|
||||
StringSet names;
|
||||
for (auto & j : *v.attrs)
|
||||
names.emplace(state.symbols[j.name]);
|
||||
for (auto & j : names) {
|
||||
Attr & a(*v.attrs->find(state.symbols.create(j)));
|
||||
auto placeholder(obj.placeholder(j));
|
||||
printValueAsJSON(state, strict, *a.value, a.pos, placeholder, context, copyToStore);
|
||||
out[j] = printValueAsJSON(state, strict, *a.value, a.pos, context, copyToStore);
|
||||
}
|
||||
} else
|
||||
printValueAsJSON(state, strict, *i->value, i->pos, out, context, copyToStore);
|
||||
return printValueAsJSON(state, strict, *i->value, i->pos, context, copyToStore);
|
||||
break;
|
||||
}
|
||||
|
||||
case nList: {
|
||||
auto list(out.list());
|
||||
for (auto elem : v.listItems()) {
|
||||
auto placeholder(list.placeholder());
|
||||
printValueAsJSON(state, strict, *elem, pos, placeholder, context, copyToStore);
|
||||
}
|
||||
out = json::array();
|
||||
for (auto elem : v.listItems())
|
||||
out.push_back(printValueAsJSON(state, strict, *elem, pos, context, copyToStore));
|
||||
break;
|
||||
}
|
||||
|
||||
case nExternal:
|
||||
v.external->printValueAsJSON(state, strict, out, context, copyToStore);
|
||||
return v.external->printValueAsJSON(state, strict, context, copyToStore);
|
||||
break;
|
||||
|
||||
case nFloat:
|
||||
out.write(v.fpoint);
|
||||
out = v.fpoint;
|
||||
break;
|
||||
|
||||
case nThunk:
|
||||
|
@ -91,17 +89,17 @@ void printValueAsJSON(EvalState & state, bool strict,
|
|||
state.debugThrowLastTrace(e);
|
||||
throw e;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, std::ostream & str, PathSet & context, bool copyToStore)
|
||||
{
|
||||
JSONPlaceholder out(str);
|
||||
printValueAsJSON(state, strict, v, pos, out, context, copyToStore);
|
||||
str << printValueAsJSON(state, strict, v, pos, context, copyToStore);
|
||||
}
|
||||
|
||||
void ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
|
||||
JSONPlaceholder & out, PathSet & context, bool copyToStore) const
|
||||
json ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
|
||||
PathSet & context, bool copyToStore) const
|
||||
{
|
||||
state.debugThrowLastTrace(TypeError("cannot convert %1% to JSON", showType()));
|
||||
}
|
||||
|
|
|
@ -5,13 +5,12 @@
|
|||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
namespace nix {
|
||||
|
||||
class JSONPlaceholder;
|
||||
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, JSONPlaceholder & out, PathSet & context, bool copyToStore = true);
|
||||
nlohmann::json printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, PathSet & context, bool copyToStore = true);
|
||||
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, std::ostream & str, PathSet & context, bool copyToStore = true);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#if HAVE_BOEHMGC
|
||||
#include <gc/gc_allocator.h>
|
||||
#endif
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
@ -62,7 +63,6 @@ class StorePath;
|
|||
class Store;
|
||||
class EvalState;
|
||||
class XMLWriter;
|
||||
class JSONPlaceholder;
|
||||
|
||||
|
||||
typedef int64_t NixInt;
|
||||
|
@ -98,8 +98,8 @@ class ExternalValueBase
|
|||
virtual bool operator ==(const ExternalValueBase & b) const;
|
||||
|
||||
/* Print the value as JSON. Defaults to unconvertable, i.e. throws an error */
|
||||
virtual void printValueAsJSON(EvalState & state, bool strict,
|
||||
JSONPlaceholder & out, PathSet & context, bool copyToStore = true) const;
|
||||
virtual nlohmann::json printValueAsJSON(EvalState & state, bool strict,
|
||||
PathSet & context, bool copyToStore = true) const;
|
||||
|
||||
/* Print the value as XML. Defaults to unevaluated */
|
||||
virtual void printValueAsXML(EvalState & state, bool strict, bool location,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue