daemon: Remove ‘foreach’ and ‘foreach_reverse’

‘foreach_reverse’ is not used anywhere

* nix/libutil/util.hh (foreach, foreach_reverse): Remove.
* nix/libstore/build.cc (addToWeakGoals): Use ‘std::none_of’ instead of macro ‘foreach’.
(Goal::waiteeDone, Goal::amDone, UserLock::acquire, rewriteHashes,
DerivationGoal::addWantedOutputs, DerivationGoal::haveDerivation,
DerivationGoal::outputsSubstituted, DerivationGoal::repairClosure,
DerivationGoal::inputsRealised, DerivationGoal::tryToBuild,
DerivationGoal::buildDone, DerivationGoal::tryBuildHook,
DerivationGoal::startBuilder, DerivationGoal::runChild,
parseReferenceSpecifiers, DerivationGoal::registerOutputs,
DerivationGoal::checkPathValidity, SubstitutionGoal::tryNext,
SubstitutionGoal::referencesValid, Worker::removeGoal,
Worker::childTerminated, Worker::run, Worker::waitForInput): Use range-based
‘for’ instead of macro ‘foreach’.
* nix/libstore/derivations.cc (writeDerivation, unparseDerivation,
hashDerivationModulo): Likewise.
* nix/libstore/gc.cc (addAdditionalRoots, LocalStore::deletePathRecursive,
LocalStore::canReachRoot, LocalStore::collectGarbage): Likewise.
* nix/libstore/globals.cc (Settings::pack): Likewise.
* nix/libstore/local-store.cc (checkDerivationOutputs, queryValidPaths,
querySubstitutablePaths, querySubstitutablePathInfos, registerValidPaths, verifyStore,
verifyPath): Likewise.
* nix/libstore/misc.cc (computeFSClosure, dfsVisit, topoSortPaths): Likewise.
* nix/libstore/optimise-store.cc (LocalStore::optimisePath_, LocalStore::optimiseStore): Likewise.
* nix/libstore/pathlocks.cc (PathLocks::lockPaths, PathLocks::~PathLocks): Likewise.
* nix/libstore/references.cc (search, scanForReferences): Likewise.
* nix/libstore/store-api.cc (checkStoreName, computeStorePathForText,
StoreAPI::makeValidityRegistration, showPaths, readStorePaths): Likewise.
* nix/libutil/serialise.cc (writeStrings): Likewise.
* nix/libutil/util.cc (concatStringsSep): Likewise.
* nix/nix-daemon/nix-daemon.cc (performOp): Likewise.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Congcong Kuo 2025-05-29 23:46:21 +08:00 committed by Ludovic Courtès
parent 1708653177
commit 3721eb1d6a
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
14 changed files with 327 additions and 334 deletions

View file

@ -336,9 +336,9 @@ void addToWeakGoals(WeakGoals & goals, GoalPtr p)
{ {
// FIXME: necessary? // FIXME: necessary?
// FIXME: O(n) // FIXME: O(n)
foreach (WeakGoals::iterator, i, goals) bool b = std::none_of(goals.begin(), goals.end(),
if (i->lock() == p) return; [p](WeakGoalPtr i) { return i.lock() == p; });
goals.push_back(p); if (b) goals.push_back(p); else return;
} }
@ -367,11 +367,11 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
/* If we failed and keepGoing is not set, we remove all /* If we failed and keepGoing is not set, we remove all
remaining waitees. */ remaining waitees. */
foreach (Goals::iterator, i, waitees) { for (auto& i : waitees) {
GoalPtr goal = *i; GoalPtr goal = i;
WeakGoals waiters2; WeakGoals waiters2;
foreach (WeakGoals::iterator, j, goal->waiters) for (auto& j : goal->waiters)
if (j->lock() != shared_from_this()) waiters2.push_back(*j); if (j.lock() != shared_from_this()) waiters2.push_back(j);
goal->waiters = waiters2; goal->waiters = waiters2;
} }
waitees.clear(); waitees.clear();
@ -387,8 +387,8 @@ void Goal::amDone(ExitCode result)
assert(exitCode == ecBusy); assert(exitCode == ecBusy);
assert(result == ecSuccess || result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure); assert(result == ecSuccess || result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure);
exitCode = result; exitCode = result;
foreach (WeakGoals::iterator, i, waiters) { for (auto& i : waiters) {
GoalPtr goal = i->lock(); GoalPtr goal = i.lock();
if (goal) goal->waiteeDone(shared_from_this(), result); if (goal) goal->waiteeDone(shared_from_this(), result);
} }
waiters.clear(); waiters.clear();
@ -498,13 +498,13 @@ void UserLock::acquire()
/* Find a user account that isn't currently in use for another /* Find a user account that isn't currently in use for another
build. */ build. */
foreach (Strings::iterator, i, users) { for (auto& i : users) {
debug(format("trying user `%1%'") % *i); debug(format("trying user `%1%'") % i);
struct passwd * pw = getpwnam(i->c_str()); struct passwd * pw = getpwnam(i.c_str());
if (!pw) if (!pw)
throw Error(format("the user `%1%' in the group `%2%' does not exist") throw Error(format("the user `%1%' in the group `%2%' does not exist")
% *i % settings.buildUsersGroup); % i % settings.buildUsersGroup);
createDirs(settings.nixStateDir + "/userpool"); createDirs(settings.nixStateDir + "/userpool");
@ -522,7 +522,7 @@ void UserLock::acquire()
if (lockFile(fd, ltWrite, false)) { if (lockFile(fd, ltWrite, false)) {
fdUserLock = fd.borrow(); fdUserLock = fd.borrow();
lockedPaths.insert(fnUserLock); lockedPaths.insert(fnUserLock);
user = *i; user = i;
uid = pw->pw_uid; uid = pw->pw_uid;
/* Sanity check... */ /* Sanity check... */
@ -576,12 +576,12 @@ typedef map<string, string> HashRewrites;
string rewriteHashes(string s, const HashRewrites & rewrites) string rewriteHashes(string s, const HashRewrites & rewrites)
{ {
foreach (HashRewrites::const_iterator, i, rewrites) { for (auto& i : rewrites) {
assert(i->first.size() == i->second.size()); assert(i.first.size() == i.second.size());
size_t j = 0; size_t j = 0;
while ((j = s.find(i->first, j)) != string::npos) { while ((j = s.find(i.first, j)) != string::npos) {
debug(format("rewriting @ %1%") % j); debug(format("rewriting @ %1%") % j);
s.replace(j, i->second.size(), i->second); s.replace(j, i.second.size(), i.second);
} }
} }
return s; return s;
@ -884,9 +884,9 @@ void DerivationGoal::addWantedOutputs(const StringSet & outputs)
wantedOutputs.clear(); wantedOutputs.clear();
needRestart = true; needRestart = true;
} else } else
foreach (StringSet::const_iterator, i, outputs) for (const auto& i : outputs)
if (wantedOutputs.find(*i) == wantedOutputs.end()) { if (wantedOutputs.find(i) == wantedOutputs.end()) {
wantedOutputs.insert(*i); wantedOutputs.insert(i);
needRestart = true; needRestart = true;
} }
} }
@ -933,8 +933,8 @@ void DerivationGoal::haveDerivation()
/* Get the derivation. */ /* Get the derivation. */
drv = derivationFromPath(worker.store, drvPath); drv = derivationFromPath(worker.store, drvPath);
foreach (DerivationOutputs::iterator, i, drv.outputs) for (auto& i : drv.outputs)
worker.store.addTempRoot(i->second.path); worker.store.addTempRoot(i.second.path);
/* Check what outputs paths are not already valid. */ /* Check what outputs paths are not already valid. */
PathSet invalidOutputs = checkPathValidity(false, buildMode == bmRepair); PathSet invalidOutputs = checkPathValidity(false, buildMode == bmRepair);
@ -947,15 +947,15 @@ void DerivationGoal::haveDerivation()
/* Check whether any output previously failed to build. If so, /* Check whether any output previously failed to build. If so,
don't bother. */ don't bother. */
foreach (PathSet::iterator, i, invalidOutputs) for (auto& i : invalidOutputs)
if (pathFailed(*i)) return; if (pathFailed(i)) return;
/* We are first going to try to create the invalid output paths /* We are first going to try to create the invalid output paths
through substitutes. If that doesn't work, we'll build through substitutes. If that doesn't work, we'll build
them. */ them. */
if (settings.useSubstitutes && substitutesAllowed(drv)) if (settings.useSubstitutes && substitutesAllowed(drv))
foreach (PathSet::iterator, i, invalidOutputs) for (auto& i : invalidOutputs)
addWaitee(worker.makeSubstitutionGoal(*i, buildMode == bmRepair)); addWaitee(worker.makeSubstitutionGoal(i, buildMode == bmRepair));
if (waitees.empty()) /* to prevent hang (no wake-up event) */ if (waitees.empty()) /* to prevent hang (no wake-up event) */
outputsSubstituted(); outputsSubstituted();
@ -1004,11 +1004,11 @@ void DerivationGoal::outputsSubstituted()
wantedOutputs = PathSet(); wantedOutputs = PathSet();
/* The inputs must be built before we can build this goal. */ /* The inputs must be built before we can build this goal. */
foreach (DerivationInputs::iterator, i, drv.inputDrvs) for (auto& i : drv.inputDrvs)
addWaitee(worker.makeDerivationGoal(i->first, i->second, buildMode == bmRepair ? bmRepair : bmNormal)); addWaitee(worker.makeDerivationGoal(i.first, i.second, buildMode == bmRepair ? bmRepair : bmNormal));
foreach (PathSet::iterator, i, drv.inputSrcs) for (auto& i : drv.inputSrcs)
addWaitee(worker.makeSubstitutionGoal(*i)); addWaitee(worker.makeSubstitutionGoal(i));
if (waitees.empty()) /* to prevent hang (no wake-up event) */ if (waitees.empty()) /* to prevent hang (no wake-up event) */
inputsRealised(); inputsRealised();
@ -1026,14 +1026,14 @@ void DerivationGoal::repairClosure()
/* Get the output closure. */ /* Get the output closure. */
PathSet outputClosure; PathSet outputClosure;
foreach (DerivationOutputs::iterator, i, drv.outputs) { for (auto& i : drv.outputs) {
if (!wantOutput(i->first, wantedOutputs)) continue; if (!wantOutput(i.first, wantedOutputs)) continue;
computeFSClosure(worker.store, i->second.path, outputClosure); computeFSClosure(worker.store, i.second.path, outputClosure);
} }
/* Filter out our own outputs (which we have already checked). */ /* Filter out our own outputs (which we have already checked). */
foreach (DerivationOutputs::iterator, i, drv.outputs) for (auto& i : drv.outputs)
outputClosure.erase(i->second.path); outputClosure.erase(i.second.path);
/* Get all dependencies of this derivation so that we know which /* Get all dependencies of this derivation so that we know which
derivation is responsible for which path in the output derivation is responsible for which path in the output
@ -1041,21 +1041,21 @@ void DerivationGoal::repairClosure()
PathSet inputClosure; PathSet inputClosure;
computeFSClosure(worker.store, drvPath, inputClosure); computeFSClosure(worker.store, drvPath, inputClosure);
std::map<Path, Path> outputsToDrv; std::map<Path, Path> outputsToDrv;
foreach (PathSet::iterator, i, inputClosure) for (auto& i : inputClosure)
if (isDerivation(*i)) { if (isDerivation(i)) {
Derivation drv = derivationFromPath(worker.store, *i); Derivation drv = derivationFromPath(worker.store, i);
foreach (DerivationOutputs::iterator, j, drv.outputs) for (auto& j : drv.outputs)
outputsToDrv[j->second.path] = *i; outputsToDrv[j.second.path] = i;
} }
/* Check each path (slow!). */ /* Check each path (slow!). */
PathSet broken; PathSet broken;
foreach (PathSet::iterator, i, outputClosure) { for (auto& i : outputClosure) {
if (worker.store.pathContentsGood(*i)) continue; if (worker.store.pathContentsGood(i)) continue;
printMsg(lvlError, format("found corrupted or missing path `%1%' in the output closure of `%2%'") % *i % drvPath); printMsg(lvlError, format("found corrupted or missing path `%1%' in the output closure of `%2%'") % i % drvPath);
Path drvPath2 = outputsToDrv[*i]; Path drvPath2 = outputsToDrv[i];
if (drvPath2 == "") if (drvPath2 == "")
addWaitee(worker.makeSubstitutionGoal(*i, true)); addWaitee(worker.makeSubstitutionGoal(i, true));
else else
addWaitee(worker.makeDerivationGoal(drvPath2, PathSet(), bmRepair)); addWaitee(worker.makeDerivationGoal(drvPath2, PathSet(), bmRepair));
} }
@ -1099,32 +1099,32 @@ void DerivationGoal::inputsRealised()
running the build hook. */ running the build hook. */
/* The outputs are referenceable paths. */ /* The outputs are referenceable paths. */
foreach (DerivationOutputs::iterator, i, drv.outputs) { for (auto& i : drv.outputs) {
debug(format("building path `%1%'") % i->second.path); debug(format("building path `%1%'") % i.second.path);
allPaths.insert(i->second.path); allPaths.insert(i.second.path);
} }
/* Determine the full set of input paths. */ /* Determine the full set of input paths. */
/* First, the input derivations. */ /* First, the input derivations. */
foreach (DerivationInputs::iterator, i, drv.inputDrvs) { for (auto& i : drv.inputDrvs) {
/* Add the relevant output closures of the input derivation /* Add the relevant output closures of the input derivation
`*i' as input paths. Only add the closures of output paths `*i' as input paths. Only add the closures of output paths
that are specified as inputs. */ that are specified as inputs. */
assert(worker.store.isValidPath(i->first)); assert(worker.store.isValidPath(i.first));
Derivation inDrv = derivationFromPath(worker.store, i->first); Derivation inDrv = derivationFromPath(worker.store, i.first);
foreach (StringSet::iterator, j, i->second) for (auto& j : i.second)
if (inDrv.outputs.find(*j) != inDrv.outputs.end()) if (inDrv.outputs.find(j) != inDrv.outputs.end())
computeFSClosure(worker.store, inDrv.outputs[*j].path, inputPaths); computeFSClosure(worker.store, inDrv.outputs[j].path, inputPaths);
else else
throw Error( throw Error(
format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'") format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'")
% drvPath % *j % i->first); % drvPath % j % i.first);
} }
/* Second, the input sources. */ /* Second, the input sources. */
foreach (PathSet::iterator, i, drv.inputSrcs) for (auto& i : drv.inputSrcs)
computeFSClosure(worker.store, *i, inputPaths); computeFSClosure(worker.store, i, inputPaths);
debug(format("added input paths %1%") % showPaths(inputPaths)); debug(format("added input paths %1%") % showPaths(inputPaths));
@ -1186,10 +1186,10 @@ void DerivationGoal::tryToBuild()
(It can't happen between here and the lockPaths() call below (It can't happen between here and the lockPaths() call below
because we're not allowing multi-threading.) If so, put this because we're not allowing multi-threading.) If so, put this
goal to sleep until another goal finishes, then try again. */ goal to sleep until another goal finishes, then try again. */
foreach (DerivationOutputs::iterator, i, drv.outputs) for (auto& i : drv.outputs)
if (pathIsLockedByMe(i->second.path)) { if (pathIsLockedByMe(i.second.path)) {
debug(format("putting derivation `%1%' to sleep because `%2%' is locked by another goal") debug(format("putting derivation `%1%' to sleep because `%2%' is locked by another goal")
% drvPath % i->second.path); % drvPath % i.second.path);
worker.waitForAnyGoal(shared_from_this()); worker.waitForAnyGoal(shared_from_this());
return; return;
} }
@ -1222,12 +1222,12 @@ void DerivationGoal::tryToBuild()
missingPaths = outputPaths(drv); missingPaths = outputPaths(drv);
if (buildMode != bmCheck) if (buildMode != bmCheck)
foreach (PathSet::iterator, i, validPaths) missingPaths.erase(*i); for (auto& i : validPaths) missingPaths.erase(i);
/* If any of the outputs already exist but are not valid, delete /* If any of the outputs already exist but are not valid, delete
them. */ them. */
foreach (DerivationOutputs::iterator, i, drv.outputs) { for (auto& i : drv.outputs) {
Path path = i->second.path; Path path = i.second.path;
if (worker.store.isValidPath(path)) continue; if (worker.store.isValidPath(path)) continue;
if (!pathExists(path)) continue; if (!pathExists(path)) continue;
debug(format("removing invalid path `%1%'") % path); debug(format("removing invalid path `%1%'") % path);
@ -1237,8 +1237,8 @@ void DerivationGoal::tryToBuild()
/* Check again whether any output previously failed to build, /* Check again whether any output previously failed to build,
because some other process may have tried and failed before we because some other process may have tried and failed before we
acquired the lock. */ acquired the lock. */
foreach (DerivationOutputs::iterator, i, drv.outputs) for (auto& i : drv.outputs)
if (pathFailed(i->second.path)) return; if (pathFailed(i.second.path)) return;
/* Don't do a remote build if the derivation has the attribute /* Don't do a remote build if the derivation has the attribute
`preferLocalBuild' set. Also, check and repair modes are only `preferLocalBuild' set. Also, check and repair modes are only
@ -1415,11 +1415,11 @@ void DerivationGoal::buildDone()
/* Move paths out of the chroot for easier debugging of /* Move paths out of the chroot for easier debugging of
build failures. */ build failures. */
if (useChroot && buildMode == bmNormal) if (useChroot && buildMode == bmNormal)
foreach (PathSet::iterator, i, missingPaths) for (auto& i : missingPaths)
if (pathExists(chrootRootDir + *i)) { if (pathExists(chrootRootDir + i)) {
try { try {
secureFilePerms(chrootRootDir + *i); secureFilePerms(chrootRootDir + i);
rename((chrootRootDir + *i).c_str(), i->c_str()); rename((chrootRootDir + i).c_str(), i.c_str());
} catch(Error & e) { } catch(Error & e) {
printMsg(lvlError, e.msg()); printMsg(lvlError, e.msg());
} }
@ -1436,8 +1436,8 @@ void DerivationGoal::buildDone()
/* Replace the output, if it exists, by a fresh copy of itself to /* Replace the output, if it exists, by a fresh copy of itself to
make sure that there's no stale file descriptor pointing to it make sure that there's no stale file descriptor pointing to it
(CVE-2024-27297). */ (CVE-2024-27297). */
foreach (DerivationOutputs::iterator, i, drv.outputs) { for (auto& i : drv.outputs) {
Path output = chrootRootDir + i->second.path; Path output = chrootRootDir + i.second.path;
if (pathExists(output)) { if (pathExists(output)) {
Path pivot = output + ".tmp"; Path pivot = output + ".tmp";
copyFileRecursively(output, pivot, true); copyFileRecursively(output, pivot, true);
@ -1454,8 +1454,8 @@ void DerivationGoal::buildDone()
registerOutputs(); registerOutputs();
/* Delete unused redirected outputs (when doing hash rewriting). */ /* Delete unused redirected outputs (when doing hash rewriting). */
foreach (RedirectedOutputs::iterator, i, redirectedOutputs) for (auto& i : redirectedOutputs)
if (pathExists(i->second)) deletePath(i->second); if (pathExists(i.second)) deletePath(i.second);
/* Delete the chroot (if we were using one). */ /* Delete the chroot (if we were using one). */
autoDelChroot.reset(); /* this runs the destructor */ autoDelChroot.reset(); /* this runs the destructor */
@ -1516,8 +1516,8 @@ void DerivationGoal::buildDone()
Hook errors (like communication problems with the Hook errors (like communication problems with the
remote machine) shouldn't be cached either. */ remote machine) shouldn't be cached either. */
if (settings.cacheFailure && !fixedOutput && !diskFull) if (settings.cacheFailure && !fixedOutput && !diskFull)
foreach (DerivationOutputs::iterator, i, drv.outputs) for (auto& i : drv.outputs)
worker.store.registerFailedPath(i->second.path); worker.store.registerFailedPath(i.second.path);
} }
done(st, e.msg()); done(st, e.msg());
@ -1554,7 +1554,7 @@ HookReply DerivationGoal::tryBuildHook()
required from the build machine. (The hook could parse the required from the build machine. (The hook could parse the
drv file itself, but this is easier.) */ drv file itself, but this is easier.) */
Strings features = tokenizeString<Strings>(get(drv.env, "requiredSystemFeatures")); Strings features = tokenizeString<Strings>(get(drv.env, "requiredSystemFeatures"));
foreach (Strings::iterator, i, features) checkStoreName(*i); /* !!! abuse */ for (auto& i : features) checkStoreName(i); /* !!! abuse */
/* Send the request to the hook. */ /* Send the request to the hook. */
writeLine(worker.hook->toAgent.writeSide, (format("%1% %2% %3% %4%") writeLine(worker.hook->toAgent.writeSide, (format("%1% %2% %3% %4%")
@ -1596,13 +1596,13 @@ HookReply DerivationGoal::tryBuildHook()
computeFSClosure(worker.store, drvPath, allInputs); computeFSClosure(worker.store, drvPath, allInputs);
string s; string s;
foreach (PathSet::iterator, i, allInputs) { s += *i; s += ' '; } for (auto& i : allInputs) { s += i; s += ' '; }
writeLine(hook->toAgent.writeSide, s); writeLine(hook->toAgent.writeSide, s);
/* Tell the hooks the missing outputs that have to be copied back /* Tell the hooks the missing outputs that have to be copied back
from the remote system. */ from the remote system. */
s = ""; s = "";
foreach (PathSet::iterator, i, missingPaths) { s += *i; s += ' '; } for (auto& i : missingPaths) { s += i; s += ' '; }
writeLine(hook->toAgent.writeSide, s); writeLine(hook->toAgent.writeSide, s);
hook->toAgent.writeSide.close(); hook->toAgent.writeSide.close();
@ -1698,8 +1698,8 @@ void DerivationGoal::startBuilder()
env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str(); env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();
/* Add all bindings specified in the derivation. */ /* Add all bindings specified in the derivation. */
foreach (StringPairs::iterator, i, drv.env) for (auto& i : drv.env)
env[i->first] = i->second; env[i.first] = i.second;
/* Create a temporary directory where the build will take /* Create a temporary directory where the build will take
place. */ place. */
@ -1752,7 +1752,7 @@ void DerivationGoal::startBuilder()
already know the cryptographic hash of the output). */ already know the cryptographic hash of the output). */
if (fixedOutput) { if (fixedOutput) {
Strings varNames = tokenizeString<Strings>(get(drv.env, "impureEnvVars")); Strings varNames = tokenizeString<Strings>(get(drv.env, "impureEnvVars"));
foreach (Strings::iterator, i, varNames) env[*i] = getEnv(*i); for (auto& i : varNames) env[i] = getEnv(i);
} }
/* The `exportReferencesGraph' feature allows the references graph /* The `exportReferencesGraph' feature allows the references graph
@ -1788,11 +1788,11 @@ void DerivationGoal::startBuilder()
computeFSClosure(worker.store, storePath, paths); computeFSClosure(worker.store, storePath, paths);
paths2 = paths; paths2 = paths;
foreach (PathSet::iterator, j, paths2) { for (auto& j : paths2) {
if (isDerivation(*j)) { if (isDerivation(j)) {
Derivation drv = derivationFromPath(worker.store, *j); Derivation drv = derivationFromPath(worker.store, j);
foreach (DerivationOutputs::iterator, k, drv.outputs) for (auto& k : drv.outputs)
computeFSClosure(worker.store, k->second.path, paths); computeFSClosure(worker.store, k.second.path, paths);
} }
} }
@ -1896,10 +1896,10 @@ void DerivationGoal::startBuilder()
/* Make the closure of the inputs available in the chroot, rather than /* Make the closure of the inputs available in the chroot, rather than
the whole store. This prevents any access to undeclared the whole store. This prevents any access to undeclared
dependencies. */ dependencies. */
foreach (PathSet::iterator, i, inputPaths) { for (auto& i : inputPaths) {
struct stat st; struct stat st;
if (lstat(i->c_str(), &st)) if (lstat(i.c_str(), &st))
throw SysError(format("getting attributes of path `%1%'") % *i); throw SysError(format("getting attributes of path `%1%'") % i);
if (S_ISLNK(st.st_mode)) { if (S_ISLNK(st.st_mode)) {
/* Since bind-mounts follow symlinks, thus representing their /* Since bind-mounts follow symlinks, thus representing their
@ -1907,12 +1907,12 @@ void DerivationGoal::startBuilder()
symlinks. XXX: When running unprivileged, TARGET can be symlinks. XXX: When running unprivileged, TARGET can be
deleted by the build process. Use 'open_tree' & co. when deleted by the build process. Use 'open_tree' & co. when
it's more widely available. */ it's more widely available. */
Path target = chrootRootDir + *i; Path target = chrootRootDir + i;
if (symlink(readLink(*i).c_str(), target.c_str()) == -1) if (symlink(readLink(i).c_str(), target.c_str()) == -1)
throw SysError(format("failed to create symlink '%1%' to '%2%'") % target % readLink(*i)); throw SysError(format("failed to create symlink '%1%' to '%2%'") % target % readLink(i));
} }
else else
dirsInChroot[*i] = *i; dirsInChroot[i] = i;
} }
/* If we're repairing, checking or rebuilding part of a /* If we're repairing, checking or rebuilding part of a
@ -1943,16 +1943,16 @@ void DerivationGoal::startBuilder()
contents of the new outputs to replace the dummy strings contents of the new outputs to replace the dummy strings
with the actual hashes. */ with the actual hashes. */
if (validPaths.size() > 0) if (validPaths.size() > 0)
foreach (PathSet::iterator, i, validPaths) for (auto i : validPaths)
addHashRewrite(*i); addHashRewrite(i);
/* If we're repairing, then we don't want to delete the /* If we're repairing, then we don't want to delete the
corrupt outputs in advance. So rewrite them as well. */ corrupt outputs in advance. So rewrite them as well. */
if (buildMode == bmRepair) if (buildMode == bmRepair)
foreach (PathSet::iterator, i, missingPaths) for (auto& i : missingPaths)
if (worker.store.isValidPath(*i) && pathExists(*i)) { if (worker.store.isValidPath(i) && pathExists(i)) {
addHashRewrite(*i); addHashRewrite(i);
redirectedBadOutputs.insert(*i); redirectedBadOutputs.insert(i);
} }
} }
@ -2186,10 +2186,10 @@ void DerivationGoal::runChild()
/* Bind-mount all the directories from the "host" /* Bind-mount all the directories from the "host"
filesystem that we want in the chroot filesystem that we want in the chroot
environment. */ environment. */
foreach (DirsInChroot::iterator, i, dirsInChroot) { for (auto& i : dirsInChroot) {
struct stat st; struct stat st;
Path source = i->second; Path source = i.second;
Path target = chrootRootDir + i->first; Path target = chrootRootDir + i.first;
if (source == "/proc") continue; // backwards compatibility if (source == "/proc") continue; // backwards compatibility
if (stat(source.c_str(), &st) == -1) if (stat(source.c_str(), &st) == -1)
throw SysError(format("getting attributes of path `%1%'") % source); throw SysError(format("getting attributes of path `%1%'") % source);
@ -2340,8 +2340,8 @@ void DerivationGoal::runChild()
/* Fill in the environment. */ /* Fill in the environment. */
Strings envStrs; Strings envStrs;
foreach (Environment::const_iterator, i, env) for (const auto& i : env)
envStrs.push_back(rewriteHashes(i->first + "=" + i->second, rewritesToTmp)); envStrs.push_back(rewriteHashes(i.first + "=" + i.second, rewritesToTmp));
/* If we are running in `build-users' mode, then switch to the /* If we are running in `build-users' mode, then switch to the
user we allocated above. Make sure that we drop all root user we allocated above. Make sure that we drop all root
@ -2420,8 +2420,8 @@ void DerivationGoal::runChild()
/* Fill in the arguments. */ /* Fill in the arguments. */
Strings args; Strings args;
args.push_back(builderBasename); args.push_back(builderBasename);
foreach (Strings::iterator, i, drv.args) for (auto& i : drv.args)
args.push_back(rewriteHashes(*i, rewritesToTmp)); args.push_back(rewriteHashes(i, rewritesToTmp));
/* If DRV targets the same operating system kernel, try to execute it: /* If DRV targets the same operating system kernel, try to execute it:
there might be binfmt_misc set up for user-land emulation of other there might be binfmt_misc set up for user-land emulation of other
@ -2468,14 +2468,14 @@ PathSet parseReferenceSpecifiers(const Derivation & drv, string attr)
{ {
PathSet result; PathSet result;
Paths paths = tokenizeString<Paths>(attr); Paths paths = tokenizeString<Paths>(attr);
foreach (Strings::iterator, i, paths) { for (auto& i : paths) {
if (isStorePath(*i)) if (isStorePath(i))
result.insert(*i); result.insert(i);
else if (drv.outputs.find(*i) != drv.outputs.end()) else if (drv.outputs.find(i) != drv.outputs.end())
result.insert(drv.outputs.find(*i)->second.path); result.insert(drv.outputs.find(i)->second.path);
else throw BuildError( else throw BuildError(
format("derivation contains an invalid reference specifier `%1%'") format("derivation contains an invalid reference specifier `%1%'")
% *i); % i);
} }
return result; return result;
} }
@ -2488,8 +2488,8 @@ void DerivationGoal::registerOutputs()
to do anything here. */ to do anything here. */
if (hook) { if (hook) {
bool allValid = true; bool allValid = true;
foreach (DerivationOutputs::iterator, i, drv.outputs) for (auto& i : drv.outputs)
if (!worker.store.isValidPath(i->second.path)) allValid = false; if (!worker.store.isValidPath(i.second.path)) allValid = false;
if (allValid) return; if (allValid) return;
} }
@ -2505,8 +2505,8 @@ void DerivationGoal::registerOutputs()
/* Check whether the output paths were created, and grep each /* Check whether the output paths were created, and grep each
output path to determine what other paths it references. Also make all output path to determine what other paths it references. Also make all
output paths read-only. */ output paths read-only. */
foreach (DerivationOutputs::iterator, i, drv.outputs) { for (auto& i : drv.outputs) {
Path path = i->second.path; Path path = i.second.path;
if (missingPaths.find(path) == missingPaths.end()) continue; if (missingPaths.find(path) == missingPaths.end()) continue;
Path actualPath = path; Path actualPath = path;
@ -2568,10 +2568,10 @@ void DerivationGoal::registerOutputs()
/* Check that fixed-output derivations produced the right /* Check that fixed-output derivations produced the right
outputs (i.e., the content hash should match the specified outputs (i.e., the content hash should match the specified
hash). */ hash). */
if (i->second.hash != "") { if (i.second.hash != "") {
bool recursive; HashType ht; Hash h; bool recursive; HashType ht; Hash h;
i->second.parseHashInfo(recursive, ht, h); i.second.parseHashInfo(recursive, ht, h);
if (!recursive) { if (!recursive) {
/* The output path should be a regular file without /* The output path should be a regular file without
@ -2586,7 +2586,7 @@ void DerivationGoal::registerOutputs()
if (h != h2) { if (h != h2) {
if (settings.printBuildTrace) if (settings.printBuildTrace)
printMsg(lvlError, format("@ hash-mismatch %1% %2% %3% %4%") printMsg(lvlError, format("@ hash-mismatch %1% %2% %3% %4%")
% path % i->second.hashAlgo % path % i.second.hashAlgo
% printHash16or32(h) % printHash16or32(h2)); % printHash16or32(h) % printHash16or32(h2));
throw BuildError(format("hash mismatch for store item '%1%'") % path); throw BuildError(format("hash mismatch for store item '%1%'") % path);
} }
@ -2650,12 +2650,12 @@ void DerivationGoal::registerOutputs()
/* For debugging, print out the referenced and unreferenced /* For debugging, print out the referenced and unreferenced
paths. */ paths. */
foreach (PathSet::iterator, i, inputPaths) { for (auto& i : inputPaths) {
PathSet::iterator j = references.find(*i); PathSet::iterator j = references.find(i);
if (j == references.end()) if (j == references.end())
debug(format("unreferenced input: `%1%'") % *i); debug(format("unreferenced input: `%1%'") % i);
else else
debug(format("referenced input: `%1%'") % *i); debug(format("referenced input: `%1%'") % i);
} }
/* Enforce `allowedReferences' and friends. */ /* Enforce `allowedReferences' and friends. */
@ -2985,12 +2985,12 @@ void DerivationGoal::handleEOF(int fd)
PathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash) PathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash)
{ {
PathSet result; PathSet result;
foreach (DerivationOutputs::iterator, i, drv.outputs) { for (auto& i : drv.outputs) {
if (!wantOutput(i->first, wantedOutputs)) continue; if (!wantOutput(i.first, wantedOutputs)) continue;
bool good = bool good =
worker.store.isValidPath(i->second.path) && worker.store.isValidPath(i.second.path) &&
(!checkHash || worker.store.pathContentsGood(i->second.path)); (!checkHash || worker.store.pathContentsGood(i.second.path));
if (good == returnValid) result.insert(i->second.path); if (good == returnValid) result.insert(i.second.path);
} }
return result; return result;
} }
@ -3186,9 +3186,9 @@ void SubstitutionGoal::tryNext()
/* To maintain the closure invariant, we first have to realise the /* To maintain the closure invariant, we first have to realise the
paths referenced by this one. */ paths referenced by this one. */
foreach (PathSet::iterator, i, info.references) for (auto& i : info.references)
if (*i != storePath) /* ignore self-references */ if (i != storePath) /* ignore self-references */
addWaitee(worker.makeSubstitutionGoal(*i)); addWaitee(worker.makeSubstitutionGoal(i));
if (waitees.empty()) /* to prevent hang (no wake-up event) */ if (waitees.empty()) /* to prevent hang (no wake-up event) */
referencesValid(); referencesValid();
@ -3207,9 +3207,9 @@ void SubstitutionGoal::referencesValid()
return; return;
} }
foreach (PathSet::iterator, i, info.references) for (auto& i : info.references)
if (*i != storePath) /* ignore self-references */ if (i != storePath) /* ignore self-references */
assert(worker.store.isValidPath(*i)); assert(worker.store.isValidPath(i));
state = &SubstitutionGoal::tryToRun; state = &SubstitutionGoal::tryToRun;
worker.wakeUp(shared_from_this()); worker.wakeUp(shared_from_this());
@ -3521,8 +3521,8 @@ void Worker::removeGoal(GoalPtr goal)
} }
/* Wake up goals waiting for any goal to finish. */ /* Wake up goals waiting for any goal to finish. */
foreach (WeakGoals::iterator, i, waitingForAnyGoal) { for (auto& i : waitingForAnyGoal) {
GoalPtr goal = i->lock(); GoalPtr goal = i.lock();
if (goal) wakeUp(goal); if (goal) wakeUp(goal);
} }
@ -3575,8 +3575,8 @@ void Worker::childTerminated(pid_t pid, bool wakeSleepers)
if (wakeSleepers) { if (wakeSleepers) {
/* Wake up goals waiting for a build slot. */ /* Wake up goals waiting for a build slot. */
foreach (WeakGoals::iterator, i, wantingToBuild) { for (auto& i : wantingToBuild) {
GoalPtr goal = i->lock(); GoalPtr goal = i.lock();
if (goal) wakeUp(goal); if (goal) wakeUp(goal);
} }
@ -3611,7 +3611,7 @@ void Worker::waitForAWhile(GoalPtr goal)
void Worker::run(const Goals & _topGoals) void Worker::run(const Goals & _topGoals)
{ {
foreach (Goals::iterator, i, _topGoals) topGoals.insert(*i); for (auto& i : _topGoals) topGoals.insert(i);
startNest(nest, lvlDebug, format("entered goal loop")); startNest(nest, lvlDebug, format("entered goal loop"));
@ -3677,12 +3677,12 @@ void Worker::waitForInput()
deadline for any child. */ deadline for any child. */
assert(sizeof(time_t) >= sizeof(long)); assert(sizeof(time_t) >= sizeof(long));
time_t nearest = LONG_MAX; // nearest deadline time_t nearest = LONG_MAX; // nearest deadline
foreach (Children::iterator, i, children) { for (auto& i : children) {
if (!i->second.respectTimeouts) continue; if (!i.second.respectTimeouts) continue;
if (settings.maxSilentTime != 0) if (settings.maxSilentTime != 0)
nearest = std::min(nearest, i->second.lastOutput + settings.maxSilentTime); nearest = std::min(nearest, i.second.lastOutput + settings.maxSilentTime);
if (settings.buildTimeout != 0) if (settings.buildTimeout != 0)
nearest = std::min(nearest, i->second.timeStarted + settings.buildTimeout); nearest = std::min(nearest, i.second.timeStarted + settings.buildTimeout);
} }
if (nearest != LONG_MAX) { if (nearest != LONG_MAX) {
timeout.tv_sec = std::max((time_t) 1, nearest - before); timeout.tv_sec = std::max((time_t) 1, nearest - before);
@ -3707,10 +3707,10 @@ void Worker::waitForInput()
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
int fdMax = 0; int fdMax = 0;
foreach (Children::iterator, i, children) { for (auto& i : children) {
foreach (set<int>::iterator, j, i->second.fds) { for (auto& j : i.second.fds) {
FD_SET(*j, &fds); FD_SET(j, &fds);
if (*j >= fdMax) fdMax = *j + 1; if (j >= fdMax) fdMax = j + 1;
} }
} }
@ -3728,34 +3728,34 @@ void Worker::waitForInput()
careful that we don't keep iterators alive across calls to careful that we don't keep iterators alive across calls to
timedOut(). */ timedOut(). */
set<pid_t> pids; set<pid_t> pids;
foreach (Children::iterator, i, children) pids.insert(i->first); for (auto& i : children) pids.insert(i.first);
foreach (set<pid_t>::iterator, i, pids) { for (auto& i : pids) {
checkInterrupt(); checkInterrupt();
Children::iterator j = children.find(*i); Children::iterator j = children.find(i);
if (j == children.end()) continue; // child destroyed if (j == children.end()) continue; // child destroyed
GoalPtr goal = j->second.goal.lock(); GoalPtr goal = j->second.goal.lock();
assert(goal); assert(goal);
set<int> fds2(j->second.fds); set<int> fds2(j->second.fds);
foreach (set<int>::iterator, k, fds2) { for (auto& k : fds2) {
if (FD_ISSET(*k, &fds)) { if (FD_ISSET(k, &fds)) {
unsigned char buffer[4096]; unsigned char buffer[4096];
ssize_t rd = read(*k, buffer, sizeof(buffer)); ssize_t rd = read(k, buffer, sizeof(buffer));
if (rd == -1) { if (rd == -1) {
if (errno != EINTR) if (errno != EINTR)
throw SysError(format("reading from %1%") throw SysError(format("reading from %1%")
% goal->getName()); % goal->getName());
} else if (rd == 0) { } else if (rd == 0) {
debug(format("%1%: got EOF") % goal->getName()); debug(format("%1%: got EOF") % goal->getName());
goal->handleEOF(*k); goal->handleEOF(k);
j->second.fds.erase(*k); j->second.fds.erase(k);
} else { } else {
printMsg(lvlVomit, format("%1%: read %2% bytes") printMsg(lvlVomit, format("%1%: read %2% bytes")
% goal->getName() % rd); % goal->getName() % rd);
string data((char *) buffer, rd); string data((char *) buffer, rd);
j->second.lastOutput = after; j->second.lastOutput = after;
goal->handleChildOutput(*k, data); goal->handleChildOutput(k, data);
} }
} }
} }
@ -3785,8 +3785,8 @@ void Worker::waitForInput()
if (!waitingForAWhile.empty() && lastWokenUp + settings.pollInterval <= after) { if (!waitingForAWhile.empty() && lastWokenUp + settings.pollInterval <= after) {
lastWokenUp = after; lastWokenUp = after;
foreach (WeakGoals::iterator, i, waitingForAWhile) { for (auto& i : waitingForAWhile) {
GoalPtr goal = i->lock(); GoalPtr goal = i.lock();
if (goal) wakeUp(goal); if (goal) wakeUp(goal);
} }
waitingForAWhile.clear(); waitingForAWhile.clear();
@ -3811,22 +3811,22 @@ void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
Worker worker(*this); Worker worker(*this);
Goals goals; Goals goals;
foreach (PathSet::const_iterator, i, drvPaths) { for (auto& i : drvPaths) {
DrvPathWithOutputs i2 = parseDrvPathWithOutputs(*i); DrvPathWithOutputs i2 = parseDrvPathWithOutputs(i);
if (isDerivation(i2.first)) if (isDerivation(i2.first))
goals.insert(worker.makeDerivationGoal(i2.first, i2.second, buildMode)); goals.insert(worker.makeDerivationGoal(i2.first, i2.second, buildMode));
else else
goals.insert(worker.makeSubstitutionGoal(*i, buildMode)); goals.insert(worker.makeSubstitutionGoal(i, buildMode));
} }
worker.run(goals); worker.run(goals);
PathSet failed; PathSet failed;
foreach (Goals::iterator, i, goals) for (auto& i : goals)
if ((*i)->getExitCode() == Goal::ecFailed) { if (i->getExitCode() == Goal::ecFailed) {
DerivationGoal * i2 = dynamic_cast<DerivationGoal *>(i->get()); DerivationGoal * i2 = dynamic_cast<DerivationGoal *>(i.get());
if (i2) failed.insert(i2->getDrvPath()); if (i2) failed.insert(i2->getDrvPath());
else failed.insert(dynamic_cast<SubstitutionGoal *>(i->get())->getStorePath()); else failed.insert(dynamic_cast<SubstitutionGoal *>(i.get())->getStorePath());
} }
if (!failed.empty()) if (!failed.empty())

View file

@ -31,8 +31,8 @@ Path writeDerivation(StoreAPI & store,
{ {
PathSet references; PathSet references;
references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end()); references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) for (const auto& i : drv.inputDrvs)
references.insert(i->first); references.insert(i.first);
/* Note that the outputs of a derivation are *not* references /* Note that the outputs of a derivation are *not* references
(that can be missing (of course) and should not necessarily be (that can be missing (of course) and should not necessarily be
held during a garbage collection). */ held during a garbage collection). */
@ -155,21 +155,21 @@ string unparseDerivation(const Derivation & drv)
s += "Derive(["; s += "Derive([";
bool first = true; bool first = true;
foreach (DerivationOutputs::const_iterator, i, drv.outputs) { for (const auto& i : drv.outputs) {
if (first) first = false; else s += ','; if (first) first = false; else s += ',';
s += '('; printString(s, i->first); s += '('; printString(s, i.first);
s += ','; printString(s, i->second.path); s += ','; printString(s, i.second.path);
s += ','; printString(s, i->second.hashAlgo); s += ','; printString(s, i.second.hashAlgo);
s += ','; printString(s, i->second.hash); s += ','; printString(s, i.second.hash);
s += ')'; s += ')';
} }
s += "],["; s += "],[";
first = true; first = true;
foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) { for (const auto& i : drv.inputDrvs) {
if (first) first = false; else s += ','; if (first) first = false; else s += ',';
s += '('; printString(s, i->first); s += '('; printString(s, i.first);
s += ','; printStrings(s, i->second.begin(), i->second.end()); s += ','; printStrings(s, i.second.begin(), i.second.end());
s += ')'; s += ')';
} }
@ -182,10 +182,10 @@ string unparseDerivation(const Derivation & drv)
s += ",["; s += ",[";
first = true; first = true;
foreach (StringPairs::const_iterator, i, drv.env) { for (const auto& i : drv.env) {
if (first) first = false; else s += ','; if (first) first = false; else s += ',';
s += '('; printString(s, i->first); s += '('; printString(s, i.first);
s += ','; printString(s, i->second); s += ','; printString(s, i.second);
s += ')'; s += ')';
} }
@ -246,15 +246,15 @@ Hash hashDerivationModulo(StoreAPI & store, Derivation drv)
/* For other derivations, replace the inputs paths with recursive /* For other derivations, replace the inputs paths with recursive
calls to this function.*/ calls to this function.*/
DerivationInputs inputs2; DerivationInputs inputs2;
foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) { for (const auto& i : drv.inputDrvs) {
Hash h = drvHashes[i->first]; Hash h = drvHashes[i.first];
if (h.type == htUnknown) { if (h.type == htUnknown) {
assert(store.isValidPath(i->first)); assert(store.isValidPath(i.first));
Derivation drv2 = readDerivation(i->first); Derivation drv2 = readDerivation(i.first);
h = hashDerivationModulo(store, drv2); h = hashDerivationModulo(store, drv2);
drvHashes[i->first] = h; drvHashes[i.first] = h;
} }
inputs2[printHash(h)] = i->second; inputs2[printHash(h)] = i.second;
} }
drv.inputDrvs = inputs2; drv.inputDrvs = inputs2;

View file

@ -349,9 +349,9 @@ static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
StringSet paths = tokenizeString<StringSet>(result, "\n"); StringSet paths = tokenizeString<StringSet>(result, "\n");
foreach (StringSet::iterator, i, paths) { for (auto i : paths) {
if (isInStore(*i)) { if (isInStore(i)) {
Path path = toStorePath(*i); Path path = toStorePath(i);
if (roots.find(path) == roots.end() && store.isValidPath(path)) { if (roots.find(path) == roots.end() && store.isValidPath(path)) {
debug(format("got additional root `%1%'") % path); debug(format("got additional root `%1%'") % path);
roots.insert(path); roots.insert(path);
@ -414,8 +414,8 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
if (isValidPath(path)) { if (isValidPath(path)) {
PathSet referrers; PathSet referrers;
queryReferrers(path, referrers); queryReferrers(path, referrers);
foreach (PathSet::iterator, i, referrers) for (auto& i : referrers)
if (*i != path) deletePathRecursive(state, *i); if (i != path) deletePathRecursive(state, i);
size = queryPathInfo(path).narSize; size = queryPathInfo(path).narSize;
invalidatePathChecked(path); invalidatePathChecked(path);
} }
@ -505,22 +505,22 @@ bool LocalStore::canReachRoot(GCState & state, PathSet & visited, const Path & p
don't delete the derivation if any of the outputs are alive. */ don't delete the derivation if any of the outputs are alive. */
if (state.gcKeepDerivations && isDerivation(path)) { if (state.gcKeepDerivations && isDerivation(path)) {
PathSet outputs = queryDerivationOutputs(path); PathSet outputs = queryDerivationOutputs(path);
foreach (PathSet::iterator, i, outputs) for (auto& i : outputs)
if (isValidPath(*i) && queryDeriver(*i) == path) if (isValidPath(i) && queryDeriver(i) == path)
incoming.insert(*i); incoming.insert(i);
} }
/* If gc-keep-outputs is set, then don't delete this path if there /* If gc-keep-outputs is set, then don't delete this path if there
are derivers of this path that are not garbage. */ are derivers of this path that are not garbage. */
if (state.gcKeepOutputs) { if (state.gcKeepOutputs) {
PathSet derivers = queryValidDerivers(path); PathSet derivers = queryValidDerivers(path);
foreach (PathSet::iterator, i, derivers) for (auto& i : derivers)
incoming.insert(*i); incoming.insert(i);
} }
foreach (PathSet::iterator, i, incoming) for (auto& i : incoming)
if (*i != path) if (i != path)
if (canReachRoot(state, visited, *i)) { if (canReachRoot(state, visited, i)) {
state.alive.insert(path); state.alive.insert(path);
return true; return true;
} }
@ -664,7 +664,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
printMsg(lvlError, format("finding garbage collector roots...")); printMsg(lvlError, format("finding garbage collector roots..."));
Roots rootMap = options.ignoreLiveness ? Roots() : findRoots(); Roots rootMap = options.ignoreLiveness ? Roots() : findRoots();
foreach (Roots::iterator, i, rootMap) state.roots.insert(i->second); for (auto& i : rootMap) state.roots.insert(i.second);
/* Add additional roots returned by 'guix gc --list-busy'. This is /* Add additional roots returned by 'guix gc --list-busy'. This is
typically used to add running programs to the set of roots (to prevent typically used to add running programs to the set of roots (to prevent
@ -700,11 +700,11 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
if (options.action == GCOptions::gcDeleteSpecific) { if (options.action == GCOptions::gcDeleteSpecific) {
foreach (PathSet::iterator, i, options.pathsToDelete) { for (auto& i : options.pathsToDelete) {
assertStorePath(*i); assertStorePath(i);
tryToDelete(state, *i); tryToDelete(state, i);
if (state.dead.find(*i) == state.dead.end()) if (state.dead.find(i) == state.dead.end())
throw Error(format("cannot delete path `%1%' since it is still alive") % *i); throw Error(format("cannot delete path `%1%' since it is still alive") % i);
} }
} else if (options.maxFreed > 0) { } else if (options.maxFreed > 0) {
@ -750,8 +750,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
std::default_random_engine generator(seeder()); std::default_random_engine generator(seeder());
std::shuffle(entries_.begin(), entries_.end(), generator); std::shuffle(entries_.begin(), entries_.end(), generator);
foreach (vector<Path>::iterator, i, entries_) for (auto& i : entries_)
tryToDelete(state, *i); tryToDelete(state, i);
} catch (GCLimitReached & e) { } catch (GCLimitReached & e) {
} }

View file

@ -188,12 +188,12 @@ template<class N> void Settings::_get(N & res, const string & name)
string Settings::pack() string Settings::pack()
{ {
string s; string s;
foreach (SettingsMap::iterator, i, settings) { for (auto& i : settings) {
if (i->first.find('\n') != string::npos || if (i.first.find('\n') != string::npos ||
i->first.find('=') != string::npos || i.first.find('=') != string::npos ||
i->second.find('\n') != string::npos) i.second.find('\n') != string::npos)
throw Error("invalid option name/value"); throw Error("invalid option name/value");
s += i->first; s += '='; s += i->second; s += '\n'; s += i.first; s += '='; s += i.second; s += '\n';
} }
return s; return s;
} }

View file

@ -474,19 +474,19 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
else { else {
Derivation drvCopy(drv); Derivation drvCopy(drv);
foreach (DerivationOutputs::iterator, i, drvCopy.outputs) { for (auto& i : drvCopy.outputs) {
i->second.path = ""; i.second.path = "";
drvCopy.env[i->first] = ""; drvCopy.env[i.first] = "";
} }
Hash h = hashDerivationModulo(*this, drvCopy); Hash h = hashDerivationModulo(*this, drvCopy);
foreach (DerivationOutputs::const_iterator, i, drv.outputs) { for (const auto& i : drv.outputs) {
Path outPath = makeOutputPath(i->first, h, drvName); Path outPath = makeOutputPath(i.first, h, drvName);
StringPairs::const_iterator j = drv.env.find(i->first); StringPairs::const_iterator j = drv.env.find(i.first);
if (i->second.path != outPath || j == drv.env.end() || j->second != outPath) if (i.second.path != outPath || j == drv.env.end() || j->second != outPath)
throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'") throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'")
% drvPath % i->second.path % outPath); % drvPath % i.second.path % outPath);
} }
} }
} }
@ -670,8 +670,8 @@ PathSet LocalStore::queryValidPaths(const PathSet & paths)
{ {
return retrySQLite<PathSet>([&]() { return retrySQLite<PathSet>([&]() {
PathSet res; PathSet res;
foreach (PathSet::const_iterator, i, paths) for (const auto& i : paths)
if (isValidPath_(*i)) res.insert(*i); if (isValidPath_(i)) res.insert(i);
return res; return res;
}); });
} }
@ -854,8 +854,8 @@ PathSet LocalStore::querySubstitutablePaths(const PathSet & paths)
Agent & run = *substituter(); Agent & run = *substituter();
string s = "have "; string s = "have ";
foreach (PathSet::const_iterator, j, paths) for (const auto& j : paths)
if (res.find(*j) == res.end()) { s += *j; s += " "; } if (res.find(j) == res.end()) { s += j; s += " "; }
writeLine(run.toAgent.writeSide, s); writeLine(run.toAgent.writeSide, s);
while (true) { while (true) {
/* FIXME: we only read stderr when an error occurs, so /* FIXME: we only read stderr when an error occurs, so
@ -889,8 +889,8 @@ void LocalStore::querySubstitutablePathInfos(PathSet & paths, SubstitutablePathI
Agent & run = *substituter(); Agent & run = *substituter();
string s = "info "; string s = "info ";
foreach (PathSet::const_iterator, i, paths) for (const auto& i : paths)
if (infos.find(*i) == infos.end()) { s += *i; s += " "; } if (infos.find(i) == infos.end()) { s += i; s += " "; }
writeLine(run.toAgent.writeSide, s); writeLine(run.toAgent.writeSide, s);
while (true) { while (true) {
@ -949,13 +949,13 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
SQLiteTxn txn(db); SQLiteTxn txn(db);
PathSet paths; PathSet paths;
foreach (ValidPathInfos::const_iterator, i, infos) { for (const auto& i : infos) {
assert(i->hash.type == htSHA256); assert(i.hash.type == htSHA256);
if (isValidPath_(i->path)) if (isValidPath_(i.path))
updatePathInfo(*i); updatePathInfo(i);
else else
addValidPath(*i, false); addValidPath(i, false);
paths.insert(i->path); paths.insert(i.path);
} }
for (auto & i : infos) { for (auto & i : infos) {
@ -967,12 +967,12 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
/* Check that the derivation outputs are correct. We can't do /* Check that the derivation outputs are correct. We can't do
this in addValidPath() above, because the references might this in addValidPath() above, because the references might
not be valid yet. */ not be valid yet. */
foreach (ValidPathInfos::const_iterator, i, infos) for (const auto& i : infos)
if (isDerivation(i->path)) { if (isDerivation(i.path)) {
// FIXME: inefficient; we already loaded the // FIXME: inefficient; we already loaded the
// derivation in addValidPath(). // derivation in addValidPath().
Derivation drv = readDerivation(i->path); Derivation drv = readDerivation(i.path);
checkDerivationOutputs(i->path, drv); checkDerivationOutputs(i.path, drv);
} }
/* Do a topological sort of the paths. This will throw an /* Do a topological sort of the paths. This will throw an
@ -1465,8 +1465,8 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
PathSet validPaths2 = queryAllValidPaths(), validPaths, done; PathSet validPaths2 = queryAllValidPaths(), validPaths, done;
foreach (PathSet::iterator, i, validPaths2) for (auto& i : validPaths2)
verifyPath(*i, store, done, validPaths, repair, errors); verifyPath(i, store, done, validPaths, repair, errors);
/* Release the GC lock so that checking content hashes (which can /* Release the GC lock so that checking content hashes (which can
take ages) doesn't block the GC or builds. */ take ages) doesn't block the GC or builds. */
@ -1478,33 +1478,33 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
Hash nullHash(htSHA256); Hash nullHash(htSHA256);
foreach (PathSet::iterator, i, validPaths) { for (auto& i : validPaths) {
try { try {
ValidPathInfo info = queryPathInfo(*i); ValidPathInfo info = queryPathInfo(i);
/* Check the content hash (optionally - slow). */ /* Check the content hash (optionally - slow). */
printMsg(lvlTalkative, format("checking contents of `%1%'") % *i); printMsg(lvlTalkative, format("checking contents of `%1%'") % i);
HashResult current = hashPath(info.hash.type, *i); HashResult current = hashPath(info.hash.type, i);
if (info.hash != nullHash && info.hash != current.first) { if (info.hash != nullHash && info.hash != current.first) {
printMsg(lvlError, format("path `%1%' was modified! " printMsg(lvlError, format("path `%1%' was modified! "
"expected hash `%2%', got `%3%'") "expected hash `%2%', got `%3%'")
% *i % printHash(info.hash) % printHash(current.first)); % i % printHash(info.hash) % printHash(current.first));
if (repair) repairPath(*i); else errors = true; if (repair) repairPath(i); else errors = true;
} else { } else {
bool update = false; bool update = false;
/* Fill in missing hashes. */ /* Fill in missing hashes. */
if (info.hash == nullHash) { if (info.hash == nullHash) {
printMsg(lvlError, format("fixing missing hash on `%1%'") % *i); printMsg(lvlError, format("fixing missing hash on `%1%'") % i);
info.hash = current.first; info.hash = current.first;
update = true; update = true;
} }
/* Fill in missing narSize fields (from old stores). */ /* Fill in missing narSize fields (from old stores). */
if (info.narSize == 0) { if (info.narSize == 0) {
printMsg(lvlError, format("updating size field on `%1%' to %2%") % *i % current.second); printMsg(lvlError, format("updating size field on `%1%' to %2%") % i % current.second);
info.narSize = current.second; info.narSize = current.second;
update = true; update = true;
} }
@ -1516,7 +1516,7 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
} catch (Error & e) { } catch (Error & e) {
/* It's possible that the path got GC'ed, so ignore /* It's possible that the path got GC'ed, so ignore
errors on invalid paths. */ errors on invalid paths. */
if (isValidPath(*i)) if (isValidPath(i))
printMsg(lvlError, format("error: %1%") % e.msg()); printMsg(lvlError, format("error: %1%") % e.msg());
else else
printMsg(lvlError, format("warning: %1%") % e.msg()); printMsg(lvlError, format("warning: %1%") % e.msg());
@ -1548,10 +1548,10 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
first, then we can invalidate this path as well. */ first, then we can invalidate this path as well. */
bool canInvalidate = true; bool canInvalidate = true;
PathSet referrers; queryReferrers(path, referrers); PathSet referrers; queryReferrers(path, referrers);
foreach (PathSet::iterator, i, referrers) for (auto& i : referrers)
if (*i != path) { if (i != path) {
verifyPath(*i, store, done, validPaths, repair, errors); verifyPath(i, store, done, validPaths, repair, errors);
if (validPaths.find(*i) != validPaths.end()) if (validPaths.find(i) != validPaths.end())
canInvalidate = false; canInvalidate = false;
} }

View file

@ -28,15 +28,15 @@ void computeFSClosure(StoreAPI & store, const Path & path,
if (includeOutputs) { if (includeOutputs) {
PathSet derivers = store.queryValidDerivers(path); PathSet derivers = store.queryValidDerivers(path);
foreach (PathSet::iterator, i, derivers) for (auto& i : derivers)
edges.insert(*i); edges.insert(i);
} }
if (includeDerivers && isDerivation(path)) { if (includeDerivers && isDerivation(path)) {
PathSet outputs = store.queryDerivationOutputs(path); PathSet outputs = store.queryDerivationOutputs(path);
foreach (PathSet::iterator, i, outputs) for (auto& i : outputs)
if (store.isValidPath(*i) && store.queryDeriver(*i) == path) if (store.isValidPath(i) && store.queryDeriver(i) == path)
edges.insert(*i); edges.insert(i);
} }
} else { } else {
@ -44,8 +44,8 @@ void computeFSClosure(StoreAPI & store, const Path & path,
if (includeOutputs && isDerivation(path)) { if (includeOutputs && isDerivation(path)) {
PathSet outputs = store.queryDerivationOutputs(path); PathSet outputs = store.queryDerivationOutputs(path);
foreach (PathSet::iterator, i, outputs) for (auto& i : outputs)
if (store.isValidPath(*i)) edges.insert(*i); if (store.isValidPath(i)) edges.insert(i);
} }
if (includeDerivers) { if (includeDerivers) {
@ -54,8 +54,8 @@ void computeFSClosure(StoreAPI & store, const Path & path,
} }
} }
foreach (PathSet::iterator, i, edges) for (auto& i : edges)
computeFSClosure(store, *i, paths, flipDirection, includeOutputs, includeDerivers); computeFSClosure(store, i, paths, flipDirection, includeOutputs, includeDerivers);
} }
@ -74,11 +74,11 @@ static void dfsVisit(StoreAPI & store, const PathSet & paths,
if (store.isValidPath(path)) if (store.isValidPath(path))
store.queryReferences(path, references); store.queryReferences(path, references);
foreach (PathSet::iterator, i, references) for (auto& i : references)
/* Don't traverse into paths that don't exist. That can /* Don't traverse into paths that don't exist. That can
happen due to substitutes for non-existent paths. */ happen due to substitutes for non-existent paths. */
if (*i != path && paths.find(*i) != paths.end()) if (i != path && paths.find(i) != paths.end())
dfsVisit(store, paths, *i, visited, sorted, parents); dfsVisit(store, paths, i, visited, sorted, parents);
sorted.push_front(path); sorted.push_front(path);
parents.erase(path); parents.erase(path);
@ -89,8 +89,8 @@ Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
{ {
Paths sorted; Paths sorted;
PathSet visited, parents; PathSet visited, parents;
foreach (PathSet::const_iterator, i, paths) for (const auto& i : paths)
dfsVisit(store, paths, *i, visited, sorted, parents); dfsVisit(store, paths, i, visited, sorted, parents);
return sorted; return sorted;
} }

View file

@ -103,8 +103,8 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode)) {
Strings names = readDirectoryIgnoringInodes(path, inodeHash); Strings names = readDirectoryIgnoringInodes(path, inodeHash);
foreach (Strings::iterator, i, names) for (auto& i : names)
optimisePath_(stats, path + "/" + *i, inodeHash); optimisePath_(stats, path + "/" + i, inodeHash);
return; return;
} }
@ -244,11 +244,11 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
PathSet paths = queryAllValidPaths(); PathSet paths = queryAllValidPaths();
InodeHash inodeHash = loadInodeHash(); InodeHash inodeHash = loadInodeHash();
foreach (PathSet::iterator, i, paths) { for (auto& i : paths) {
addTempRoot(*i); addTempRoot(i);
if (!isValidPath(*i)) continue; /* path was GC'ed, probably */ if (!isValidPath(i)) continue; /* path was GC'ed, probably */
startNest(nest, lvlChatty, format("hashing files in `%1%'") % *i); startNest(nest, lvlChatty, format("hashing files in `%1%'") % i);
optimisePath_(stats, *i, inodeHash); optimisePath_(stats, i, inodeHash);
} }
} }

View file

@ -104,9 +104,9 @@ bool PathLocks::lockPaths(const PathSet & _paths,
paths.sort(); paths.sort();
/* Acquire the lock for each path. */ /* Acquire the lock for each path. */
foreach (Paths::iterator, i, paths) { for (auto& i : paths) {
checkInterrupt(); checkInterrupt();
Path path = *i; Path path = i;
Path lockPath = path + ".lock"; Path lockPath = path + ".lock";
debug(format("locking path `%1%'") % path); debug(format("locking path `%1%'") % path);
@ -172,15 +172,15 @@ PathLocks::~PathLocks()
void PathLocks::unlock() void PathLocks::unlock()
{ {
foreach (list<FDPair>::iterator, i, fds) { for (auto& i : fds) {
if (deletePaths) deleteLockFile(i->second, i->first); if (deletePaths) deleteLockFile(i.second, i.first);
lockedPaths.erase(i->second); lockedPaths.erase(i.second);
if (close(i->first) == -1) if (close(i.first) == -1)
printMsg(lvlError, printMsg(lvlError,
format("error (ignored): cannot close lock file on `%1%'") % i->second); format("error (ignored): cannot close lock file on `%1%'") % i.second);
debug(format("lock released on `%1%'") % i->second); debug(format("lock released on `%1%'") % i.second);
} }
fds.clear(); fds.clear();

View file

@ -89,17 +89,17 @@ PathSet scanForReferences(const string & path,
/* For efficiency (and a higher hit rate), just search for the /* For efficiency (and a higher hit rate), just search for the
hash part of the file name. (This assumes that all references hash part of the file name. (This assumes that all references
have the form `HASH-bla'). */ have the form `HASH-bla'). */
foreach (PathSet::const_iterator, i, refs) { for (const auto& i : refs) {
string baseName = baseNameOf(*i); string baseName = baseNameOf(i);
string::size_type pos = baseName.find('-'); string::size_type pos = baseName.find('-');
if (pos == string::npos) if (pos == string::npos)
throw Error(format("bad reference `%1%'") % *i); throw Error(format("bad reference `%1%'") % i);
string s = string(baseName, 0, pos); string s = string(baseName, 0, pos);
assert(s.size() == refLength); assert(s.size() == refLength);
assert(backMap.find(s) == backMap.end()); assert(backMap.find(s) == backMap.end());
// parseHash(htSHA256, s); // parseHash(htSHA256, s);
sink.hashes.insert(s); sink.hashes.insert(s);
backMap[s] = *i; backMap[s] = i;
} }
/* Look for the hashes in the NAR dump of the path. */ /* Look for the hashes in the NAR dump of the path. */
@ -107,9 +107,9 @@ PathSet scanForReferences(const string & path,
/* Map the hashes found back to their store paths. */ /* Map the hashes found back to their store paths. */
PathSet found; PathSet found;
foreach (StringSet::iterator, i, sink.seen) { for (auto& i : sink.seen) {
std::map<string, Path>::iterator j; std::map<string, Path>::iterator j;
if ((j = backMap.find(*i)) == backMap.end()) abort(); if ((j = backMap.find(i)) == backMap.end()) abort();
found.insert(j->second); found.insert(j->second);
} }

View file

@ -62,14 +62,14 @@ void checkStoreName(const string & name)
reasons (e.g., "." and ".."). */ reasons (e.g., "." and ".."). */
if (string(name, 0, 1) == ".") if (string(name, 0, 1) == ".")
throw Error(format("invalid name: `%1%' (can't begin with dot)") % name); throw Error(format("invalid name: `%1%' (can't begin with dot)") % name);
foreach (string::const_iterator, i, name) for (const auto& i : name)
if (!((*i >= 'A' && *i <= 'Z') || if (!((i >= 'A' && i <= 'Z') ||
(*i >= 'a' && *i <= 'z') || (i >= 'a' && i <= 'z') ||
(*i >= '0' && *i <= '9') || (i >= '0' && i <= '9') ||
validChars.find(*i) != string::npos)) validChars.find(i) != string::npos))
{ {
throw Error(format("invalid character `%1%' in name `%2%'") throw Error(format("invalid character `%1%' in name `%2%'")
% *i % name); % i % name);
} }
} }
@ -188,9 +188,9 @@ Path computeStorePathForText(const string & name, const string & s,
hacky, but we can't put them in `s' since that would be hacky, but we can't put them in `s' since that would be
ambiguous. */ ambiguous. */
string type = "text"; string type = "text";
foreach (PathSet::const_iterator, i, references) { for (const auto& i : references) {
type += ":"; type += ":";
type += *i; type += i;
} }
return makeStorePath(type, hash, name); return makeStorePath(type, hash, name);
} }
@ -204,10 +204,10 @@ string StoreAPI::makeValidityRegistration(const PathSet & paths,
{ {
string s = ""; string s = "";
foreach (PathSet::iterator, i, paths) { for (auto& i : paths) {
s += *i + "\n"; s += i + "\n";
ValidPathInfo info = queryPathInfo(*i); ValidPathInfo info = queryPathInfo(i);
if (showHash) { if (showHash) {
s += printHash(info.hash) + "\n"; s += printHash(info.hash) + "\n";
@ -219,8 +219,8 @@ string StoreAPI::makeValidityRegistration(const PathSet & paths,
s += (format("%1%\n") % info.references.size()).str(); s += (format("%1%\n") % info.references.size()).str();
foreach (PathSet::iterator, j, info.references) for (auto& j : info.references)
s += *j + "\n"; s += j + "\n";
} }
return s; return s;
@ -229,9 +229,9 @@ string StoreAPI::makeValidityRegistration(const PathSet & paths,
string showPaths(const PathSet & paths) string showPaths(const PathSet & paths)
{ {
string s; string s;
foreach (PathSet::const_iterator, i, paths) { for (const auto& i : paths) {
if (s.size() != 0) s += ", "; if (s.size() != 0) s += ", ";
s += "`" + *i + "'"; s += "`" + i + "'";
} }
return s; return s;
} }
@ -247,7 +247,7 @@ Path readStorePath(Source & from)
template<class T> T readStorePaths(Source & from) template<class T> T readStorePaths(Source & from)
{ {
T paths = readStrings<T>(from); T paths = readStrings<T>(from);
foreach (typename T::iterator, i, paths) assertStorePath(*i); for (auto& i : paths) assertStorePath(i);
return paths; return paths;
} }

View file

@ -188,8 +188,8 @@ void writeString(const string & s, Sink & sink)
template<class T> void writeStrings(const T & ss, Sink & sink) template<class T> void writeStrings(const T & ss, Sink & sink)
{ {
writeInt(ss.size(), sink); writeInt(ss.size(), sink);
foreach (typename T::const_iterator, i, ss) for (auto& i : ss)
writeString(*i, sink); writeString(i, sink);
} }
template void writeStrings(const Paths & ss, Sink & sink); template void writeStrings(const Paths & ss, Sink & sink);

View file

@ -1158,9 +1158,9 @@ template vector<string> tokenizeString(const string & s, const string & separato
string concatStringsSep(const string & sep, const Strings & ss) string concatStringsSep(const string & sep, const Strings & ss)
{ {
string s; string s;
foreach (Strings::const_iterator, i, ss) { for (const auto& i : ss) {
if (s.size() != 0) s += sep; if (s.size() != 0) s += sep;
s += *i; s += i;
} }
return s; return s;
} }
@ -1169,9 +1169,9 @@ string concatStringsSep(const string & sep, const Strings & ss)
string concatStringsSep(const string & sep, const StringSet & ss) string concatStringsSep(const string & sep, const StringSet & ss)
{ {
string s; string s;
foreach (StringSet::const_iterator, i, ss) { for (const auto& i : ss) {
if (s.size() != 0) s += sep; if (s.size() != 0) s += sep;
s += *i; s += i;
} }
return s; return s;
} }

View file

@ -16,13 +16,6 @@
namespace nix { namespace nix {
#define foreach(it_type, it, collection) \
for (it_type it = (collection).begin(); it != (collection).end(); ++it)
#define foreach_reverse(it_type, it, collection) \
for (it_type it = (collection).rbegin(); it != (collection).rend(); ++it)
/* Return an environment variable. */ /* Return an environment variable. */
string getEnv(const string & key, const string & def = ""); string getEnv(const string & key, const string & def = "");

View file

@ -679,12 +679,12 @@ static void performOp(bool trusted, unsigned int clientVersion,
store->querySubstitutablePathInfos(paths, infos); store->querySubstitutablePathInfos(paths, infos);
stopWork(); stopWork();
writeInt(infos.size(), to); writeInt(infos.size(), to);
foreach (SubstitutablePathInfos::iterator, i, infos) { for (auto& i : infos) {
writeString(i->first, to); writeString(i.first, to);
writeString(i->second.deriver, to); writeString(i.second.deriver, to);
writeStrings(i->second.references, to); writeStrings(i.second.references, to);
writeLongLong(i->second.downloadSize, to); writeLongLong(i.second.downloadSize, to);
writeLongLong(i->second.narSize, to); writeLongLong(i.second.narSize, to);
} }
break; break;
} }