forked from lix-project/lix
Merge remote-tracking branch 'origin/master' into flakes
This commit is contained in:
commit
73b6d87e17
|
@ -13,4 +13,5 @@
|
||||||
(eval . (c-set-offset 'arglist-cont-nonempty '+))
|
(eval . (c-set-offset 'arglist-cont-nonempty '+))
|
||||||
(eval . (c-set-offset 'substatement-open 0))
|
(eval . (c-set-offset 'substatement-open 0))
|
||||||
(eval . (c-set-offset 'access-label '-))
|
(eval . (c-set-offset 'access-label '-))
|
||||||
|
(eval . (c-set-offset 'inlambda 0))
|
||||||
)))
|
)))
|
||||||
|
|
|
@ -116,6 +116,9 @@ private:
|
||||||
/* Cache used by checkSourcePath(). */
|
/* Cache used by checkSourcePath(). */
|
||||||
std::unordered_map<Path, Path> resolvedPaths;
|
std::unordered_map<Path, Path> resolvedPaths;
|
||||||
|
|
||||||
|
/* Cache used by prim_match(). */
|
||||||
|
std::unordered_map<std::string, std::regex> regexCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EvalState(const Strings & _searchPath, ref<Store> store);
|
EvalState(const Strings & _searchPath, ref<Store> store);
|
||||||
|
@ -318,6 +321,7 @@ private:
|
||||||
friend struct ExprOpConcatLists;
|
friend struct ExprOpConcatLists;
|
||||||
friend struct ExprSelect;
|
friend struct ExprSelect;
|
||||||
friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
||||||
|
friend void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1812,19 +1812,21 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
|
||||||
|
|
||||||
/* Match a regular expression against a string and return either
|
/* Match a regular expression against a string and return either
|
||||||
‘null’ or a list containing substring matches. */
|
‘null’ or a list containing substring matches. */
|
||||||
static void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
auto re = state.forceStringNoCtx(*args[0], pos);
|
auto re = state.forceStringNoCtx(*args[0], pos);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
std::regex regex(re, std::regex::extended);
|
auto regex = state.regexCache.find(re);
|
||||||
|
if (regex == state.regexCache.end())
|
||||||
|
regex = state.regexCache.emplace(re, std::regex(re, std::regex::extended)).first;
|
||||||
|
|
||||||
PathSet context;
|
PathSet context;
|
||||||
const std::string str = state.forceString(*args[1], context, pos);
|
const std::string str = state.forceString(*args[1], context, pos);
|
||||||
|
|
||||||
std::smatch match;
|
std::smatch match;
|
||||||
if (!std::regex_match(str, match, regex)) {
|
if (!std::regex_match(str, match, regex->second)) {
|
||||||
mkNull(v);
|
mkNull(v);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,15 +213,26 @@ Derivation Store::derivationFromPath(const StorePath & drvPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void printString(string & res, const string & s)
|
static void printString(string & res, std::string_view s)
|
||||||
|
{
|
||||||
|
char buf[s.size() * 2 + 2];
|
||||||
|
char * p = buf;
|
||||||
|
*p++ = '"';
|
||||||
|
for (auto c : s)
|
||||||
|
if (c == '\"' || c == '\\') { *p++ = '\\'; *p++ = c; }
|
||||||
|
else if (c == '\n') { *p++ = '\\'; *p++ = 'n'; }
|
||||||
|
else if (c == '\r') { *p++ = '\\'; *p++ = 'r'; }
|
||||||
|
else if (c == '\t') { *p++ = '\\'; *p++ = 't'; }
|
||||||
|
else *p++ = c;
|
||||||
|
*p++ = '"';
|
||||||
|
res.append(buf, p - buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void printUnquotedString(string & res, std::string_view s)
|
||||||
{
|
{
|
||||||
res += '"';
|
res += '"';
|
||||||
for (const char * i = s.c_str(); *i; i++)
|
res.append(s);
|
||||||
if (*i == '\"' || *i == '\\') { res += "\\"; res += *i; }
|
|
||||||
else if (*i == '\n') res += "\\n";
|
|
||||||
else if (*i == '\r') res += "\\r";
|
|
||||||
else if (*i == '\t') res += "\\t";
|
|
||||||
else res += *i;
|
|
||||||
res += '"';
|
res += '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +250,19 @@ static void printStrings(string & res, ForwardIterator i, ForwardIterator j)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class ForwardIterator>
|
||||||
|
static void printUnquotedStrings(string & res, ForwardIterator i, ForwardIterator j)
|
||||||
|
{
|
||||||
|
res += '[';
|
||||||
|
bool first = true;
|
||||||
|
for ( ; i != j; ++i) {
|
||||||
|
if (first) first = false; else res += ',';
|
||||||
|
printUnquotedString(res, *i);
|
||||||
|
}
|
||||||
|
res += ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string Derivation::unparse(const Store & store, bool maskOutputs,
|
string Derivation::unparse(const Store & store, bool maskOutputs,
|
||||||
std::map<std::string, StringSet> * actualInputs) const
|
std::map<std::string, StringSet> * actualInputs) const
|
||||||
{
|
{
|
||||||
|
@ -249,10 +273,10 @@ string Derivation::unparse(const Store & store, bool maskOutputs,
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto & i : outputs) {
|
for (auto & i : outputs) {
|
||||||
if (first) first = false; else s += ',';
|
if (first) first = false; else s += ',';
|
||||||
s += '('; printString(s, i.first);
|
s += '('; printUnquotedString(s, i.first);
|
||||||
s += ','; printString(s, maskOutputs ? "" : store.printStorePath(i.second.path));
|
s += ','; printUnquotedString(s, maskOutputs ? "" : store.printStorePath(i.second.path));
|
||||||
s += ','; printString(s, i.second.hashAlgo);
|
s += ','; printUnquotedString(s, i.second.hashAlgo);
|
||||||
s += ','; printString(s, i.second.hash);
|
s += ','; printUnquotedString(s, i.second.hash);
|
||||||
s += ')';
|
s += ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,24 +285,24 @@ string Derivation::unparse(const Store & store, bool maskOutputs,
|
||||||
if (actualInputs) {
|
if (actualInputs) {
|
||||||
for (auto & i : *actualInputs) {
|
for (auto & i : *actualInputs) {
|
||||||
if (first) first = false; else s += ',';
|
if (first) first = false; else s += ',';
|
||||||
s += '('; printString(s, i.first);
|
s += '('; printUnquotedString(s, i.first);
|
||||||
s += ','; printStrings(s, i.second.begin(), i.second.end());
|
s += ','; printUnquotedStrings(s, i.second.begin(), i.second.end());
|
||||||
s += ')';
|
s += ')';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto & i : inputDrvs) {
|
for (auto & i : inputDrvs) {
|
||||||
if (first) first = false; else s += ',';
|
if (first) first = false; else s += ',';
|
||||||
s += '('; printString(s, store.printStorePath(i.first));
|
s += '('; printUnquotedString(s, store.printStorePath(i.first));
|
||||||
s += ','; printStrings(s, i.second.begin(), i.second.end());
|
s += ','; printUnquotedStrings(s, i.second.begin(), i.second.end());
|
||||||
s += ')';
|
s += ')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s += "],";
|
s += "],";
|
||||||
auto paths = store.printStorePathSet(inputSrcs); // FIXME: slow
|
auto paths = store.printStorePathSet(inputSrcs); // FIXME: slow
|
||||||
printStrings(s, paths.begin(), paths.end());
|
printUnquotedStrings(s, paths.begin(), paths.end());
|
||||||
|
|
||||||
s += ','; printString(s, platform);
|
s += ','; printUnquotedString(s, platform);
|
||||||
s += ','; printString(s, builder);
|
s += ','; printString(s, builder);
|
||||||
s += ','; printStrings(s, args.begin(), args.end());
|
s += ','; printStrings(s, args.begin(), args.end());
|
||||||
|
|
||||||
|
|
|
@ -255,12 +255,11 @@ void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots, bool censor)
|
||||||
void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
||||||
{
|
{
|
||||||
auto foundRoot = [&](const Path & path, const Path & target) {
|
auto foundRoot = [&](const Path & path, const Path & target) {
|
||||||
Path storePath = toStorePath(target);
|
auto storePath = maybeParseStorePath(toStorePath(target));
|
||||||
// FIXME
|
if (storePath && isValidPath(*storePath))
|
||||||
if (isStorePath(storePath) && isValidPath(parseStorePath(storePath)))
|
roots[std::move(*storePath)].emplace(path);
|
||||||
roots[parseStorePath(storePath)].emplace(path);
|
|
||||||
else
|
else
|
||||||
printInfo("skipping invalid root from '%1%' to '%2%'", path, storePath);
|
printInfo("skipping invalid root from '%1%' to '%2%'", path, target);
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -296,10 +295,9 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (type == DT_REG) {
|
else if (type == DT_REG) {
|
||||||
Path storePath = storeDir + "/" + std::string(baseNameOf(path));
|
auto storePath = maybeParseStorePath(storeDir + "/" + std::string(baseNameOf(path)));
|
||||||
// FIXME
|
if (storePath && isValidPath(*storePath))
|
||||||
if (isStorePath(storePath) && isValidPath(parseStorePath(storePath)))
|
roots[std::move(*storePath)].emplace(path);
|
||||||
roots[parseStorePath(storePath)].emplace(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -523,14 +521,14 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
|
||||||
|
|
||||||
unsigned long long size = 0;
|
unsigned long long size = 0;
|
||||||
|
|
||||||
// FIXME
|
auto storePath = maybeParseStorePath(path);
|
||||||
if (isStorePath(path) && isValidPath(parseStorePath(path))) {
|
if (storePath && isValidPath(*storePath)) {
|
||||||
StorePathSet referrers;
|
StorePathSet referrers;
|
||||||
queryReferrers(parseStorePath(path), referrers);
|
queryReferrers(*storePath, referrers);
|
||||||
for (auto & i : referrers)
|
for (auto & i : referrers)
|
||||||
if (printStorePath(i) != path) deletePathRecursive(state, printStorePath(i));
|
if (printStorePath(i) != path) deletePathRecursive(state, printStorePath(i));
|
||||||
size = queryPathInfo(parseStorePath(path))->narSize;
|
size = queryPathInfo(*storePath)->narSize;
|
||||||
invalidatePathChecked(parseStorePath(path));
|
invalidatePathChecked(*storePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path realPath = realStoreDir + "/" + std::string(baseNameOf(path));
|
Path realPath = realStoreDir + "/" + std::string(baseNameOf(path));
|
||||||
|
@ -593,8 +591,7 @@ bool LocalStore::canReachRoot(GCState & state, StorePathSet & visited, const Sto
|
||||||
|
|
||||||
visited.insert(path.clone());
|
visited.insert(path.clone());
|
||||||
|
|
||||||
//FIXME
|
if (!isValidPath(path)) return false;
|
||||||
if (!isStorePath(printStorePath(path)) || !isValidPath(path)) return false;
|
|
||||||
|
|
||||||
StorePathSet incoming;
|
StorePathSet incoming;
|
||||||
|
|
||||||
|
@ -637,8 +634,9 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||||
|
|
||||||
//Activity act(*logger, lvlDebug, format("considering whether to delete '%1%'") % path);
|
//Activity act(*logger, lvlDebug, format("considering whether to delete '%1%'") % path);
|
||||||
|
|
||||||
// FIXME
|
auto storePath = maybeParseStorePath(path);
|
||||||
if (!isStorePath(path) || !isValidPath(parseStorePath(path))) {
|
|
||||||
|
if (!storePath || !isValidPath(*storePath)) {
|
||||||
/* A lock file belonging to a path that we're building right
|
/* A lock file belonging to a path that we're building right
|
||||||
now isn't garbage. */
|
now isn't garbage. */
|
||||||
if (isActiveTempFile(state, path, ".lock")) return;
|
if (isActiveTempFile(state, path, ".lock")) return;
|
||||||
|
@ -655,7 +653,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||||
|
|
||||||
StorePathSet visited;
|
StorePathSet visited;
|
||||||
|
|
||||||
if (canReachRoot(state, visited, parseStorePath(path))) {
|
if (storePath && canReachRoot(state, visited, *storePath)) {
|
||||||
debug("cannot delete '%s' because it's still reachable", path);
|
debug("cannot delete '%s' because it's still reachable", path);
|
||||||
} else {
|
} else {
|
||||||
/* No path we visited was a root, so everything is garbage.
|
/* No path we visited was a root, so everything is garbage.
|
||||||
|
@ -818,8 +816,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
string name = dirent->d_name;
|
string name = dirent->d_name;
|
||||||
if (name == "." || name == "..") continue;
|
if (name == "." || name == "..") continue;
|
||||||
Path path = storeDir + "/" + name;
|
Path path = storeDir + "/" + name;
|
||||||
// FIXME
|
auto storePath = maybeParseStorePath(path);
|
||||||
if (isStorePath(path) && isValidPath(parseStorePath(path)))
|
if (storePath && isValidPath(*storePath))
|
||||||
entries.push_back(path);
|
entries.push_back(path);
|
||||||
else
|
else
|
||||||
tryToDelete(state, path);
|
tryToDelete(state, path);
|
||||||
|
|
|
@ -55,6 +55,20 @@ StorePath Store::parseStorePath(std::string_view path) const
|
||||||
return StorePath::make(path, storeDir);
|
return StorePath::make(path, storeDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<StorePath> Store::maybeParseStorePath(std::string_view path) const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return parseStorePath(path);
|
||||||
|
} catch (Error &) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Store::isStorePath(std::string_view path) const
|
||||||
|
{
|
||||||
|
return (bool) maybeParseStorePath(path);
|
||||||
|
}
|
||||||
|
|
||||||
StorePathSet Store::parseStorePathSet(const PathSet & paths) const
|
StorePathSet Store::parseStorePathSet(const PathSet & paths) const
|
||||||
{
|
{
|
||||||
StorePathSet res;
|
StorePathSet res;
|
||||||
|
|
|
@ -20,14 +20,6 @@ bool Store::isInStore(const Path & path) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Store::isStorePath(const Path & path) const
|
|
||||||
{
|
|
||||||
return isInStore(path)
|
|
||||||
&& path.size() >= storeDir.size() + 1 + storePathHashLen
|
|
||||||
&& path.find('/', storeDir.size() + 1) == Path::npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Path Store::toStorePath(const Path & path) const
|
Path Store::toStorePath(const Path & path) const
|
||||||
{
|
{
|
||||||
if (!isInStore(path))
|
if (!isInStore(path))
|
||||||
|
|
|
@ -282,6 +282,8 @@ public:
|
||||||
|
|
||||||
StorePath parseStorePath(std::string_view path) const;
|
StorePath parseStorePath(std::string_view path) const;
|
||||||
|
|
||||||
|
std::optional<StorePath> maybeParseStorePath(std::string_view path) const;
|
||||||
|
|
||||||
std::string printStorePath(const StorePath & path) const;
|
std::string printStorePath(const StorePath & path) const;
|
||||||
|
|
||||||
// FIXME: remove
|
// FIXME: remove
|
||||||
|
@ -304,7 +306,7 @@ public:
|
||||||
|
|
||||||
/* Return true if ‘path’ is a store path, i.e. a direct child of
|
/* Return true if ‘path’ is a store path, i.e. a direct child of
|
||||||
the Nix store. */
|
the Nix store. */
|
||||||
bool isStorePath(const Path & path) const;
|
bool isStorePath(std::string_view path) const;
|
||||||
|
|
||||||
/* Chop off the parts after the top-level store name, e.g.,
|
/* Chop off the parts after the top-level store name, e.g.,
|
||||||
/nix/store/abcd-foo/bar => /nix/store/abcd-foo. */
|
/nix/store/abcd-foo/bar => /nix/store/abcd-foo. */
|
||||||
|
|
|
@ -295,7 +295,8 @@ static void _main(int argc, char * * argv)
|
||||||
try {
|
try {
|
||||||
absolute = canonPath(absPath(i), true);
|
absolute = canonPath(absPath(i), true);
|
||||||
} catch (Error & e) {};
|
} catch (Error & e) {};
|
||||||
if (store->isStorePath(absolute) && std::regex_match(absolute, std::regex(".*\\.drv(!.*)?")))
|
auto [path, outputNames] = parsePathWithOutputs(absolute);
|
||||||
|
if (store->isStorePath(path) && hasSuffix(path, ".drv"))
|
||||||
drvs.push_back(DrvInfo(*state, store, absolute));
|
drvs.push_back(DrvInfo(*state, store, absolute));
|
||||||
else
|
else
|
||||||
/* If we're in a #! script, interpret filenames
|
/* If we're in a #! script, interpret filenames
|
||||||
|
|
1
tests/lang/eval-okay-foldlStrict.exp
Normal file
1
tests/lang/eval-okay-foldlStrict.exp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
500500
|
3
tests/lang/eval-okay-foldlStrict.nix
Normal file
3
tests/lang/eval-okay-foldlStrict.nix
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
with import ./lib.nix;
|
||||||
|
|
||||||
|
builtins.foldl' (x: y: x + y) 0 (range 1 1000)
|
Loading…
Reference in a new issue