mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
Merge pull request #14444 from NixOS/less-c_str
Use less `c_str()` in the evaluator, and other cleanups
This commit is contained in:
commit
7c85ac23e2
16 changed files with 64 additions and 38 deletions
|
|
@ -235,7 +235,7 @@ nix_get_string(nix_c_context * context, const nix_value * value, nix_get_string_
|
||||||
try {
|
try {
|
||||||
auto & v = check_value_in(value);
|
auto & v = check_value_in(value);
|
||||||
assert(v.type() == nix::nString);
|
assert(v.type() == nix::nString);
|
||||||
call_nix_get_string_callback(v.c_str(), callback, user_data);
|
call_nix_get_string_callback(v.string_view(), callback, user_data);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ MATCHER_P(IsStringEq, s, fmt("The string is equal to \"%1%\"", s))
|
||||||
if (arg.type() != nString) {
|
if (arg.type() != nString) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return std::string_view(arg.c_str()) == s;
|
return arg.string_view() == s;
|
||||||
}
|
}
|
||||||
|
|
||||||
MATCHER_P(IsIntEq, v, fmt("The string is equal to \"%1%\"", v))
|
MATCHER_P(IsIntEq, v, fmt("The string is equal to \"%1%\"", v))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "nix/expr/value.hh"
|
#include "nix/expr/value.hh"
|
||||||
|
|
||||||
#include "nix/store/tests/libstore.hh"
|
#include "nix/store/tests/libstore.hh"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
@ -22,4 +23,21 @@ TEST_F(ValueTest, vInt)
|
||||||
ASSERT_EQ(true, vInt.isValid());
|
ASSERT_EQ(true, vInt.isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ValueTest, staticString)
|
||||||
|
{
|
||||||
|
Value vStr1;
|
||||||
|
Value vStr2;
|
||||||
|
vStr1.mkStringNoCopy("foo");
|
||||||
|
vStr2.mkStringNoCopy("foo");
|
||||||
|
|
||||||
|
auto sd1 = vStr1.string_view();
|
||||||
|
auto sd2 = vStr2.string_view();
|
||||||
|
|
||||||
|
// The strings should be the same
|
||||||
|
ASSERT_EQ(sd1, sd2);
|
||||||
|
|
||||||
|
// The strings should also be backed by the same (static) allocation
|
||||||
|
ASSERT_EQ(sd1.data(), sd2.data());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
|
||||||
|
|
@ -406,7 +406,7 @@ Value & AttrCursor::forceValue()
|
||||||
|
|
||||||
if (root->db && (!cachedValue || std::get_if<placeholder_t>(&cachedValue->second))) {
|
if (root->db && (!cachedValue || std::get_if<placeholder_t>(&cachedValue->second))) {
|
||||||
if (v.type() == nString)
|
if (v.type() == nString)
|
||||||
cachedValue = {root->db->setString(getKey(), v.c_str(), v.context()), string_t{v.c_str(), {}}};
|
cachedValue = {root->db->setString(getKey(), v.string_view(), v.context()), string_t{v.string_view(), {}}};
|
||||||
else if (v.type() == nPath) {
|
else if (v.type() == nPath) {
|
||||||
auto path = v.path().path;
|
auto path = v.path().path;
|
||||||
cachedValue = {root->db->setString(getKey(), path.abs()), string_t{path.abs(), {}}};
|
cachedValue = {root->db->setString(getKey(), path.abs()), string_t{path.abs(), {}}};
|
||||||
|
|
@ -541,7 +541,7 @@ std::string AttrCursor::getString()
|
||||||
if (v.type() != nString && v.type() != nPath)
|
if (v.type() != nString && v.type() != nPath)
|
||||||
root->state.error<TypeError>("'%s' is not a string but %s", getAttrPathStr(), showType(v)).debugThrow();
|
root->state.error<TypeError>("'%s' is not a string but %s", getAttrPathStr(), showType(v)).debugThrow();
|
||||||
|
|
||||||
return v.type() == nString ? v.c_str() : v.path().to_string();
|
return v.type() == nString ? std::string(v.string_view()) : v.path().to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t AttrCursor::getStringWithContext()
|
string_t AttrCursor::getStringWithContext()
|
||||||
|
|
@ -580,7 +580,7 @@ string_t AttrCursor::getStringWithContext()
|
||||||
if (v.type() == nString) {
|
if (v.type() == nString) {
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
copyContext(v, context);
|
copyContext(v, context);
|
||||||
return {v.c_str(), std::move(context)};
|
return {std::string{v.string_view()}, std::move(context)};
|
||||||
} else if (v.type() == nPath)
|
} else if (v.type() == nPath)
|
||||||
return {v.path().to_string(), {}};
|
return {v.path().to_string(), {}};
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -2366,12 +2366,15 @@ BackedStringView EvalState::coerceToString(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.type() == nPath) {
|
if (v.type() == nPath) {
|
||||||
return !canonicalizePath && !copyToStore
|
if (!canonicalizePath && !copyToStore) {
|
||||||
? // FIXME: hack to preserve path literals that end in a
|
// FIXME: hack to preserve path literals that end in a
|
||||||
// slash, as in /foo/${x}.
|
// slash, as in /foo/${x}.
|
||||||
v.pathStr()
|
return v.pathStrView();
|
||||||
: copyToStore ? store->printStorePath(copyPathToStore(context, v.path()))
|
} else if (copyToStore) {
|
||||||
: std::string(v.path().path.abs());
|
return store->printStorePath(copyPathToStore(context, v.path()));
|
||||||
|
} else {
|
||||||
|
return std::string{v.path().path.abs()};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.type() == nAttrs) {
|
if (v.type() == nAttrs) {
|
||||||
|
|
@ -2624,7 +2627,7 @@ void EvalState::assertEqValues(Value & v1, Value & v2, const PosIdx pos, std::st
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case nString:
|
case nString:
|
||||||
if (strcmp(v1.c_str(), v2.c_str()) != 0) {
|
if (v1.string_view() != v2.string_view()) {
|
||||||
error<AssertionError>(
|
error<AssertionError>(
|
||||||
"string '%s' is not equal to string '%s'",
|
"string '%s' is not equal to string '%s'",
|
||||||
ValuePrinter(*this, v1, errorPrintOptions),
|
ValuePrinter(*this, v1, errorPrintOptions),
|
||||||
|
|
@ -2641,7 +2644,7 @@ void EvalState::assertEqValues(Value & v1, Value & v2, const PosIdx pos, std::st
|
||||||
ValuePrinter(*this, v2, errorPrintOptions))
|
ValuePrinter(*this, v2, errorPrintOptions))
|
||||||
.debugThrow();
|
.debugThrow();
|
||||||
}
|
}
|
||||||
if (strcmp(v1.pathStr(), v2.pathStr()) != 0) {
|
if (v1.pathStrView() != v2.pathStrView()) {
|
||||||
error<AssertionError>(
|
error<AssertionError>(
|
||||||
"path '%s' is not equal to path '%s'",
|
"path '%s' is not equal to path '%s'",
|
||||||
ValuePrinter(*this, v1, errorPrintOptions),
|
ValuePrinter(*this, v1, errorPrintOptions),
|
||||||
|
|
@ -2807,12 +2810,12 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
|
||||||
return v1.boolean() == v2.boolean();
|
return v1.boolean() == v2.boolean();
|
||||||
|
|
||||||
case nString:
|
case nString:
|
||||||
return strcmp(v1.c_str(), v2.c_str()) == 0;
|
return v1.string_view() == v2.string_view();
|
||||||
|
|
||||||
case nPath:
|
case nPath:
|
||||||
return
|
return
|
||||||
// FIXME: compare accessors by their fingerprint.
|
// FIXME: compare accessors by their fingerprint.
|
||||||
v1.pathAccessor() == v2.pathAccessor() && strcmp(v1.pathStr(), v2.pathStr()) == 0;
|
v1.pathAccessor() == v2.pathAccessor() && v1.pathStrView() == v2.pathStrView();
|
||||||
|
|
||||||
case nNull:
|
case nNull:
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ PackageInfo::Outputs PackageInfo::queryOutputs(bool withPaths, bool onlyOutputsT
|
||||||
for (auto elem : outTI->listView()) {
|
for (auto elem : outTI->listView()) {
|
||||||
if (elem->type() != nString)
|
if (elem->type() != nString)
|
||||||
throw errMsg;
|
throw errMsg;
|
||||||
auto out = outputs.find(elem->c_str());
|
auto out = outputs.find(elem->string_view());
|
||||||
if (out == outputs.end())
|
if (out == outputs.end())
|
||||||
throw errMsg;
|
throw errMsg;
|
||||||
result.insert(*out);
|
result.insert(*out);
|
||||||
|
|
@ -245,7 +245,7 @@ std::string PackageInfo::queryMetaString(const std::string & name)
|
||||||
Value * v = queryMeta(name);
|
Value * v = queryMeta(name);
|
||||||
if (!v || v->type() != nString)
|
if (!v || v->type() != nString)
|
||||||
return "";
|
return "";
|
||||||
return v->c_str();
|
return std::string{v->string_view()};
|
||||||
}
|
}
|
||||||
|
|
||||||
NixInt PackageInfo::queryMetaInt(const std::string & name, NixInt def)
|
NixInt PackageInfo::queryMetaInt(const std::string & name, NixInt def)
|
||||||
|
|
@ -258,7 +258,7 @@ NixInt PackageInfo::queryMetaInt(const std::string & name, NixInt def)
|
||||||
if (v->type() == nString) {
|
if (v->type() == nString) {
|
||||||
/* Backwards compatibility with before we had support for
|
/* Backwards compatibility with before we had support for
|
||||||
integer meta fields. */
|
integer meta fields. */
|
||||||
if (auto n = string2Int<NixInt::Inner>(v->c_str()))
|
if (auto n = string2Int<NixInt::Inner>(v->string_view()))
|
||||||
return NixInt{*n};
|
return NixInt{*n};
|
||||||
}
|
}
|
||||||
return def;
|
return def;
|
||||||
|
|
@ -274,7 +274,7 @@ NixFloat PackageInfo::queryMetaFloat(const std::string & name, NixFloat def)
|
||||||
if (v->type() == nString) {
|
if (v->type() == nString) {
|
||||||
/* Backwards compatibility with before we had support for
|
/* Backwards compatibility with before we had support for
|
||||||
float meta fields. */
|
float meta fields. */
|
||||||
if (auto n = string2Float<NixFloat>(v->c_str()))
|
if (auto n = string2Float<NixFloat>(v->string_view()))
|
||||||
return *n;
|
return *n;
|
||||||
}
|
}
|
||||||
return def;
|
return def;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ namespace nix {
|
||||||
struct PackageInfo
|
struct PackageInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<std::string, std::optional<StorePath>> Outputs;
|
typedef std::map<std::string, std::optional<StorePath>, std::less<>> Outputs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EvalState * state;
|
EvalState * state;
|
||||||
|
|
|
||||||
|
|
@ -1109,7 +1109,7 @@ public:
|
||||||
|
|
||||||
std::string_view string_view() const noexcept
|
std::string_view string_view() const noexcept
|
||||||
{
|
{
|
||||||
return std::string_view(getStorage<StringWithContext>().c_str);
|
return std::string_view{getStorage<StringWithContext>().c_str};
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * c_str() const noexcept
|
const char * c_str() const noexcept
|
||||||
|
|
@ -1177,6 +1177,11 @@ public:
|
||||||
return getStorage<Path>().path;
|
return getStorage<Path>().path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string_view pathStrView() const noexcept
|
||||||
|
{
|
||||||
|
return std::string_view{getStorage<Path>().path};
|
||||||
|
}
|
||||||
|
|
||||||
SourceAccessor * pathAccessor() const noexcept
|
SourceAccessor * pathAccessor() const noexcept
|
||||||
{
|
{
|
||||||
return getStorage<Path>().accessor;
|
return getStorage<Path>().accessor;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ void ExprString::show(const SymbolTable & symbols, std::ostream & str) const
|
||||||
|
|
||||||
void ExprPath::show(const SymbolTable & symbols, std::ostream & str) const
|
void ExprPath::show(const SymbolTable & symbols, std::ostream & str) const
|
||||||
{
|
{
|
||||||
str << v.pathStr();
|
str << v.pathStrView();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprVar::show(const SymbolTable & symbols, std::ostream & str) const
|
void ExprVar::show(const SymbolTable & symbols, std::ostream & str) const
|
||||||
|
|
|
||||||
|
|
@ -691,12 +691,12 @@ struct CompareValues
|
||||||
case nFloat:
|
case nFloat:
|
||||||
return v1->fpoint() < v2->fpoint();
|
return v1->fpoint() < v2->fpoint();
|
||||||
case nString:
|
case nString:
|
||||||
return strcmp(v1->c_str(), v2->c_str()) < 0;
|
return v1->string_view() < v2->string_view();
|
||||||
case nPath:
|
case nPath:
|
||||||
// Note: we don't take the accessor into account
|
// Note: we don't take the accessor into account
|
||||||
// since it's not obvious how to compare them in a
|
// since it's not obvious how to compare them in a
|
||||||
// reproducible way.
|
// reproducible way.
|
||||||
return strcmp(v1->pathStr(), v2->pathStr()) < 0;
|
return v1->pathStrView() < v2->pathStrView();
|
||||||
case nList:
|
case nList:
|
||||||
// Lexicographic comparison
|
// Lexicographic comparison
|
||||||
for (size_t i = 0;; i++) {
|
for (size_t i = 0;; i++) {
|
||||||
|
|
@ -2930,7 +2930,7 @@ static void prim_attrNames(EvalState & state, const PosIdx pos, Value ** args, V
|
||||||
for (const auto & [n, i] : enumerate(*args[0]->attrs()))
|
for (const auto & [n, i] : enumerate(*args[0]->attrs()))
|
||||||
list[n] = Value::toPtr(state.symbols[i.name]);
|
list[n] = Value::toPtr(state.symbols[i.name]);
|
||||||
|
|
||||||
std::sort(list.begin(), list.end(), [](Value * v1, Value * v2) { return strcmp(v1->c_str(), v2->c_str()) < 0; });
|
std::sort(list.begin(), list.end(), [](Value * v1, Value * v2) { return v1->string_view() < v2->string_view(); });
|
||||||
|
|
||||||
v.mkList(list);
|
v.mkList(list);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ json printValueAsJSON(
|
||||||
|
|
||||||
case nString:
|
case nString:
|
||||||
copyContext(v, context);
|
copyContext(v, context);
|
||||||
out = v.c_str();
|
out = v.string_view();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nPath:
|
case nPath:
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ static void printValueAsXML(
|
||||||
case nString:
|
case nString:
|
||||||
/* !!! show the context? */
|
/* !!! show the context? */
|
||||||
copyContext(v, context);
|
copyContext(v, context);
|
||||||
doc.writeEmptyElement("string", singletonAttrs("value", v.c_str()));
|
doc.writeEmptyElement("string", singletonAttrs("value", v.string_view()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nPath:
|
case nPath:
|
||||||
|
|
@ -102,14 +102,14 @@ static void printValueAsXML(
|
||||||
if (strict)
|
if (strict)
|
||||||
state.forceValue(*a->value, a->pos);
|
state.forceValue(*a->value, a->pos);
|
||||||
if (a->value->type() == nString)
|
if (a->value->type() == nString)
|
||||||
xmlAttrs["drvPath"] = drvPath = a->value->c_str();
|
xmlAttrs["drvPath"] = drvPath = a->value->string_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto a = v.attrs()->get(state.s.outPath)) {
|
if (auto a = v.attrs()->get(state.s.outPath)) {
|
||||||
if (strict)
|
if (strict)
|
||||||
state.forceValue(*a->value, a->pos);
|
state.forceValue(*a->value, a->pos);
|
||||||
if (a->value->type() == nString)
|
if (a->value->type() == nString)
|
||||||
xmlAttrs["outPath"] = a->value->c_str();
|
xmlAttrs["outPath"] = a->value->string_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLOpenElement _(doc, "derivation", xmlAttrs);
|
XMLOpenElement _(doc, "derivation", xmlAttrs);
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ static void parseFlakeInputAttr(EvalState & state, const Attr & attr, fetchers::
|
||||||
#pragma GCC diagnostic ignored "-Wswitch-enum"
|
#pragma GCC diagnostic ignored "-Wswitch-enum"
|
||||||
switch (attr.value->type()) {
|
switch (attr.value->type()) {
|
||||||
case nString:
|
case nString:
|
||||||
attrs.emplace(state.symbols[attr.name], attr.value->c_str());
|
attrs.emplace(state.symbols[attr.name], std::string(attr.value->string_view()));
|
||||||
break;
|
break;
|
||||||
case nBool:
|
case nBool:
|
||||||
attrs.emplace(state.symbols[attr.name], Explicit<bool>{attr.value->boolean()});
|
attrs.emplace(state.symbols[attr.name], Explicit<bool>{attr.value->boolean()});
|
||||||
|
|
@ -177,7 +177,7 @@ static FlakeInput parseFlakeInput(
|
||||||
parseFlakeInputs(state, attr.value, attr.pos, lockRootAttrPath, flakeDir, false).first;
|
parseFlakeInputs(state, attr.value, attr.pos, lockRootAttrPath, flakeDir, false).first;
|
||||||
} else if (attr.name == sFollows) {
|
} else if (attr.name == sFollows) {
|
||||||
expectType(state, nString, *attr.value, attr.pos);
|
expectType(state, nString, *attr.value, attr.pos);
|
||||||
auto follows(parseInputAttrPath(attr.value->c_str()));
|
auto follows(parseInputAttrPath(attr.value->string_view()));
|
||||||
follows.insert(follows.begin(), lockRootAttrPath.begin(), lockRootAttrPath.end());
|
follows.insert(follows.begin(), lockRootAttrPath.begin(), lockRootAttrPath.end());
|
||||||
input.follows = follows;
|
input.follows = follows;
|
||||||
} else
|
} else
|
||||||
|
|
@ -264,7 +264,7 @@ static Flake readFlake(
|
||||||
|
|
||||||
if (auto description = vInfo.attrs()->get(state.s.description)) {
|
if (auto description = vInfo.attrs()->get(state.s.description)) {
|
||||||
expectType(state, nString, *description->value, description->pos);
|
expectType(state, nString, *description->value, description->pos);
|
||||||
flake.description = description->value->c_str();
|
flake.description = description->value->string_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sInputs = state.symbols.create("inputs");
|
auto sInputs = state.symbols.create("inputs");
|
||||||
|
|
|
||||||
|
|
@ -153,9 +153,9 @@ nix_err nix_err_code(const nix_c_context * read_context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
nix_err call_nix_get_string_callback(const std::string str, nix_get_string_callback callback, void * user_data)
|
nix_err call_nix_get_string_callback(const std::string_view str, nix_get_string_callback callback, void * user_data)
|
||||||
{
|
{
|
||||||
callback(str.c_str(), str.size(), user_data);
|
callback(str.data(), str.size(), user_data);
|
||||||
return NIX_OK;
|
return NIX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ nix_err nix_context_error(nix_c_context * context);
|
||||||
* @return NIX_OK if there were no errors.
|
* @return NIX_OK if there were no errors.
|
||||||
* @see nix_get_string_callback
|
* @see nix_get_string_callback
|
||||||
*/
|
*/
|
||||||
nix_err call_nix_get_string_callback(const std::string str, nix_get_string_callback callback, void * user_data);
|
nix_err call_nix_get_string_callback(const std::string_view str, nix_get_string_callback callback, void * user_data);
|
||||||
|
|
||||||
#define NIXC_CATCH_ERRS \
|
#define NIXC_CATCH_ERRS \
|
||||||
catch (...) \
|
catch (...) \
|
||||||
|
|
|
||||||
|
|
@ -1228,7 +1228,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
else {
|
else {
|
||||||
if (v->type() == nString) {
|
if (v->type() == nString) {
|
||||||
attrs2["type"] = "string";
|
attrs2["type"] = "string";
|
||||||
attrs2["value"] = v->c_str();
|
attrs2["value"] = v->string_view();
|
||||||
xml.writeEmptyElement("meta", attrs2);
|
xml.writeEmptyElement("meta", attrs2);
|
||||||
} else if (v->type() == nInt) {
|
} else if (v->type() == nInt) {
|
||||||
attrs2["type"] = "int";
|
attrs2["type"] = "int";
|
||||||
|
|
@ -1249,7 +1249,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
if (elem->type() != nString)
|
if (elem->type() != nString)
|
||||||
continue;
|
continue;
|
||||||
XMLAttrs attrs3;
|
XMLAttrs attrs3;
|
||||||
attrs3["value"] = elem->c_str();
|
attrs3["value"] = elem->string_view();
|
||||||
xml.writeEmptyElement("string", attrs3);
|
xml.writeEmptyElement("string", attrs3);
|
||||||
}
|
}
|
||||||
} else if (v->type() == nAttrs) {
|
} else if (v->type() == nAttrs) {
|
||||||
|
|
@ -1260,7 +1260,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
continue;
|
continue;
|
||||||
XMLAttrs attrs3;
|
XMLAttrs attrs3;
|
||||||
attrs3["type"] = globals.state->symbols[i.name];
|
attrs3["type"] = globals.state->symbols[i.name];
|
||||||
attrs3["value"] = i.value->c_str();
|
attrs3["value"] = i.value->string_view();
|
||||||
xml.writeEmptyElement("string", attrs3);
|
xml.writeEmptyElement("string", attrs3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue