summaryrefslogtreecommitdiff
path: root/nix/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'nix/libstore')
-rw-r--r--nix/libstore/build.cc433
-rw-r--r--nix/libstore/builtins.cc3
-rw-r--r--nix/libstore/builtins.hh1
-rw-r--r--nix/libstore/derivations.cc9
-rw-r--r--nix/libstore/gc.cc139
-rw-r--r--nix/libstore/globals.cc8
-rw-r--r--nix/libstore/local-store.cc162
-rw-r--r--nix/libstore/misc.cc17
-rw-r--r--nix/libstore/optimise-store.cc61
-rw-r--r--nix/libstore/pathlocks.cc20
-rw-r--r--nix/libstore/references.cc8
-rw-r--r--nix/libstore/sqlite.cc9
-rw-r--r--nix/libstore/sqlite.hh3
-rw-r--r--nix/libstore/store-api.cc15
14 files changed, 444 insertions, 444 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index f455343c18..bf2e9150d6 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -7,14 +7,14 @@
#include "local-store.hh"
#include "util.hh"
#include "archive.hh"
-#include "affinity.hh"
#include "builtins.hh"
#include "spawn.hh"
#include <map>
-#include <sstream>
#include <algorithm>
#include <regex>
+#include <format>
+#include <string_view>
#include <limits.h>
#include <time.h>
@@ -29,7 +29,7 @@
#include <errno.h>
#include <stdio.h>
#include <cstring>
-#include <stdint.h>
+#include <cassert>
#include <pwd.h>
#include <grp.h>
@@ -195,7 +195,7 @@ public:
abort();
}
- void trace(const format & f);
+ void trace(std::string_view s);
string getName()
{
@@ -372,8 +372,7 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
assert(waitees.find(waitee) != waitees.end());
waitees.erase(waitee);
- trace(format("waitee `%1%' done; %2% left") %
- waitee->name % waitees.size());
+ trace(std::format("waitee `{}' done; {} left", waitee->name, waitees.size()));
if (result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure) ++nrFailed;
@@ -414,9 +413,9 @@ void Goal::amDone(ExitCode result)
}
-void Goal::trace(const format & f)
+void Goal::trace(std::string_view f)
{
- debug(format("%1%: %2%") % name % f);
+ debug(std::format("{}: {}", name, f));
}
@@ -483,34 +482,34 @@ void UserLock::acquire()
/* Get the members of the build-users-group. */
struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
if (!gr)
- throw Error(format("the group `%1%' specified in `build-users-group' does not exist")
- % settings.buildUsersGroup);
+ throw Error(std::format("the group `{}' specified in `build-users-group' does not exist",
+ settings.buildUsersGroup));
gid = gr->gr_gid;
/* Copy the result of getgrnam. */
Strings users;
for (char * * p = gr->gr_mem; *p; ++p) {
- debug(format("found build user `%1%'") % *p);
+ debug(std::format("found build user `{}'", *p));
users.push_back(*p);
}
if (users.empty())
- throw Error(format("the build users group `%1%' has no members")
- % settings.buildUsersGroup);
+ throw Error(std::format("the build users group `{}' has no members",
+ settings.buildUsersGroup));
/* Find a user account that isn't currently in use for another
build. */
for (auto& i : users) {
- debug(format("trying user `%1%'") % i);
+ debug(std::format("trying user `{}'", i));
struct passwd * pw = getpwnam(i.c_str());
if (!pw)
- throw Error(format("the user `%1%' in the group `%2%' does not exist")
- % i % settings.buildUsersGroup);
+ throw Error(std::format("the user `{}' in the group `{}' does not exist",
+ i, settings.buildUsersGroup));
createDirs(settings.nixStateDir + "/userpool");
- fnUserLock = (format("%1%/userpool/%2%") % settings.nixStateDir % pw->pw_uid).str();
+ fnUserLock = std::format("{}/userpool/{}", settings.nixStateDir, pw->pw_uid);
if (lockedPaths.find(fnUserLock) != lockedPaths.end())
/* We already have a lock on this one. */
@@ -518,7 +517,7 @@ void UserLock::acquire()
AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT, 0600);
if (fd == -1)
- throw SysError(format("opening user lock `%1%'") % fnUserLock);
+ throw SysError(std::format("opening user lock `{}'", fnUserLock));
closeOnExec(fd);
if (lockFile(fd, ltWrite, false)) {
@@ -529,8 +528,8 @@ void UserLock::acquire()
/* Sanity check... */
if (uid == getuid() || uid == geteuid())
- throw Error(format("the build user should not be a member of `%1%'")
- % settings.buildUsersGroup);
+ throw Error(std::format("the build user should not be a member of `{}'",
+ settings.buildUsersGroup));
/* Get the list of supplementary groups of this build user. This
is usually either empty or contains a group such as "kvm". */
@@ -539,7 +538,7 @@ void UserLock::acquire()
int err = getgrouplist(pw->pw_name, pw->pw_gid,
supplementaryGIDs.data(), &ngroups);
if (err == -1)
- throw Error(format("failed to get list of supplementary groups for ‘%1%’") % pw->pw_name);
+ throw Error(std::format("failed to get list of supplementary groups for `{}'", pw->pw_name));
supplementaryGIDs.resize(ngroups);
@@ -547,9 +546,9 @@ void UserLock::acquire()
}
}
- throw Error(format("all build users are currently in use; "
- "consider creating additional users and adding them to the `%1%' group")
- % settings.buildUsersGroup);
+ throw Error(std::format("all build users are currently in use; "
+ "consider creating additional users and adding them to the `{}' group",
+ settings.buildUsersGroup));
}
@@ -582,7 +581,7 @@ string rewriteHashes(string s, const HashRewrites & rewrites)
assert(i.first.size() == i.second.size());
size_t j = 0;
while ((j = s.find(i.first, j)) != string::npos) {
- debug(format("rewriting @ %1%") % j);
+ debug(std::format("rewriting @ {}", j));
s.replace(j, i.second.size(), i.second);
}
}
@@ -716,7 +715,7 @@ public:
void timedOut() override;
- string key()
+ string key() override
{
/* Ensure that derivations get built in order of their name,
i.e. a derivation named "aardvark" always comes before
@@ -725,7 +724,7 @@ public:
return "b$" + storePathToName(drvPath) + "$" + drvPath;
}
- void work();
+ void work() override;
Path getDrvPath()
{
@@ -771,8 +770,8 @@ private:
void deleteTmpDir(bool force);
/* Callback used by the worker to write to the log. */
- void handleChildOutput(int fd, const string & data);
- void handleEOF(int fd);
+ void handleChildOutput(int fd, const string & data) override;
+ void handleEOF(int fd) override;
/* Return the set of (in)valid paths. */
PathSet checkPathValidity(bool returnValid, bool checkHash);
@@ -806,7 +805,7 @@ DerivationGoal::DerivationGoal(const Path & drvPath, const StringSet & wantedOut
{
this->drvPath = drvPath;
state = &DerivationGoal::init;
- name = (format("building of `%1%'") % drvPath).str();
+ name = std::format("building of `{}'", drvPath);
trace("created");
/* Prevent the .chroot directory from being
@@ -862,7 +861,7 @@ void DerivationGoal::killChild()
void DerivationGoal::timedOut()
{
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ build-failed %1% - timeout") % drvPath);
+ printMsg(lvlError, std::format("@ build-failed {} - timeout", drvPath));
killChild();
done(BuildResult::TimedOut);
}
@@ -896,7 +895,7 @@ void DerivationGoal::init()
trace("init");
if (settings.readOnlyMode)
- throw Error(format("cannot build derivation `%1%' - no write access to the store") % drvPath);
+ throw Error(std::format("cannot build derivation `{}' - no write access to the store", drvPath));
/* The first thing to do is to make sure that the derivation
exists. If it doesn't, it may be created through a
@@ -917,7 +916,7 @@ void DerivationGoal::haveDerivation()
trace("loading derivation");
if (nrFailed != 0) {
- printMsg(lvlError, format("cannot build missing derivation ‘%1%’") % drvPath);
+ printMsg(lvlError, std::format("cannot build missing derivation `{}'", drvPath));
done(BuildResult::MiscFailure);
return;
}
@@ -968,7 +967,7 @@ void DerivationGoal::outputsSubstituted()
trace("all outputs substituted (maybe)");
if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback)
- throw Error(format("some substitutes for the outputs of derivation `%1%' failed (usually happens due to networking issues); try `--fallback' to build derivation from source ") % drvPath);
+ throw Error(std::format("some substitutes for the outputs of derivation `{}' failed (usually happens due to networking issues); try `--fallback' to build derivation from source ", drvPath));
/* If the substitutes form an incomplete closure, then we should
build the dependencies of this derivation, but after that, we
@@ -993,7 +992,7 @@ void DerivationGoal::outputsSubstituted()
return;
}
if (buildMode == bmCheck && nrInvalid > 0)
- throw Error(format("`%1%' is missing outputs; build it normally before using `--check'") % drvPath);
+ throw Error(std::format("`{}' is missing outputs; build it normally before using `--check'", drvPath));
/* Otherwise, at least one of the output paths could not be
produced using a substitute. So we have to build instead. */
@@ -1051,7 +1050,7 @@ void DerivationGoal::repairClosure()
PathSet broken;
for (auto& i : outputClosure) {
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, std::format("found corrupted or missing path `{}' in the output closure of `{}'", i, drvPath));
Path drvPath2 = outputsToDrv[i];
if (drvPath2 == "")
addWaitee(worker.makeSubstitutionGoal(i, true));
@@ -1072,7 +1071,7 @@ void DerivationGoal::closureRepaired()
{
trace("closure repaired");
if (nrFailed > 0)
- throw Error(format("some paths in the output closure of derivation ‘%1%’ could not be repaired") % drvPath);
+ throw Error(std::format("some paths in the output closure of derivation `{}' could not be repaired", drvPath));
done(BuildResult::AlreadyValid);
}
@@ -1083,8 +1082,8 @@ void DerivationGoal::inputsRealised()
if (nrFailed != 0) {
printMsg(lvlError,
- format("cannot build derivation `%1%': %2% dependencies couldn't be built")
- % drvPath % nrFailed);
+ std::format("cannot build derivation `{}': {} dependencies couldn't be built",
+ drvPath, nrFailed));
done(BuildResult::DependencyFailed);
return;
}
@@ -1099,7 +1098,7 @@ void DerivationGoal::inputsRealised()
/* The outputs are referenceable paths. */
for (auto& i : drv.outputs) {
- debug(format("building path `%1%'") % i.second.path);
+ debug(std::format("building path `{}'", i.second.path));
allPaths.insert(i.second.path);
}
@@ -1117,15 +1116,15 @@ void DerivationGoal::inputsRealised()
computeFSClosure(worker.store, inDrv.outputs[j].path, inputPaths);
else
throw Error(
- format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'")
- % drvPath % j % i.first);
+ std::format("derivation `{}' requires non-existent output `{}' from input derivation `{}'",
+ drvPath, j, i.first));
}
/* Second, the input sources. */
for (auto& i : drv.inputSrcs)
computeFSClosure(worker.store, i, inputPaths);
- debug(format("added input paths %1%") % showPaths(inputPaths));
+ debug(std::format("added input paths {}", showPaths(inputPaths)));
allPaths.insert(inputPaths.begin(), inputPaths.end());
@@ -1187,8 +1186,8 @@ void DerivationGoal::tryToBuild()
goal to sleep until another goal finishes, then try again. */
for (auto& i : drv.outputs)
if (pathIsLockedByMe(i.second.path)) {
- debug(format("putting derivation `%1%' to sleep because `%2%' is locked by another goal")
- % drvPath % i.second.path);
+ debug(std::format("putting derivation `{}' to sleep because `{}' is locked by another goal",
+ drvPath, i.second.path));
worker.waitForAnyGoal(shared_from_this());
return;
}
@@ -1212,7 +1211,7 @@ void DerivationGoal::tryToBuild()
build this derivation, so no further checks are necessary. */
validPaths = checkPathValidity(true, buildMode == bmRepair);
if (buildMode != bmCheck && validPaths.size() == drv.outputs.size()) {
- debug(format("skipping build of derivation `%1%', someone beat us to it") % drvPath);
+ debug(std::format("skipping build of derivation `{}', someone beat us to it", drvPath));
outputLocks.setDeletion(true);
outputLocks.unlock();
done(BuildResult::AlreadyValid);
@@ -1229,7 +1228,7 @@ void DerivationGoal::tryToBuild()
Path path = i.second.path;
if (worker.store.isValidPath(path)) continue;
if (!pathExists(path)) continue;
- debug(format("removing invalid path `%1%'") % path);
+ debug(std::format("removing invalid path `{}'", path));
deletePath(path);
}
@@ -1284,8 +1283,8 @@ void DerivationGoal::tryToBuild()
outputLocks.unlock();
buildUser.release();
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ build-failed %1% - %2% %3%")
- % drvPath % 0 % e.msg());
+ printMsg(lvlError, std::format("@ build-failed {} - {} {}",
+ drvPath, 0, e.msg()));
worker.permanentFailure = true;
done(BuildResult::InputRejected, e.msg());
return;
@@ -1303,11 +1302,11 @@ void replaceValidPath(const Path & storePath, const Path tmpPath)
tmpPath (the replacement), so we have to move it out of the
way first. We'd better not be interrupted here, because if
we're repairing (say) Glibc, we end up with a broken system. */
- Path oldPath = (format("%1%.old-%2%-%3%") % storePath % getpid() % rand()).str();
+ Path oldPath = std::format("{}.old-{}-{}", storePath, getpid(), rand());
if (pathExists(storePath))
rename(storePath.c_str(), oldPath.c_str());
if (rename(tmpPath.c_str(), storePath.c_str()) == -1)
- throw SysError(format("moving `%1%' to `%2%'") % tmpPath % storePath);
+ throw SysError(std::format("moving `{}' to `{}'", tmpPath, storePath));
if (pathExists(oldPath))
deletePath(oldPath);
}
@@ -1349,7 +1348,7 @@ static void secureFilePerms(Path path, bool allowSpecialFiles = false)
/* FALLTHROUGH */
default:
- throw Error(format("file `%1%' has an unsupported type") % path);
+ throw Error(std::format("file `{}' has an unsupported type", path));
}
}
@@ -1373,7 +1372,7 @@ void DerivationGoal::buildDone()
status = pid.wait(true);
}
- debug(format("builder process for `%1%' finished") % drvPath);
+ debug(std::format("builder process for `{}' finished", drvPath));
/* So the child is gone now. */
worker.childTerminated(savedPid);
@@ -1436,8 +1435,8 @@ void DerivationGoal::buildDone()
if (diskFull)
printMsg(lvlError, "note: build failure may have been caused by lack of free disk space");
- throw BuildError(format("builder for `%1%' %2%")
- % drvPath % statusToString(status));
+ throw BuildError(std::format("builder for `{}' {}",
+ drvPath, statusToString(status)));
}
if (fixedOutput) {
@@ -1451,8 +1450,8 @@ void DerivationGoal::buildDone()
copyFileRecursively(output, pivot, true);
int err = rename(pivot.c_str(), output.c_str());
if (err != 0)
- throw SysError(format("renaming `%1%' to `%2%'")
- % pivot % output);
+ throw SysError(std::format("renaming `{}' to `{}'",
+ pivot, output));
}
}
}
@@ -1496,20 +1495,20 @@ void DerivationGoal::buildDone()
if (hook && WIFEXITED(status) && WEXITSTATUS(status) == 101) {
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ build-failed %1% - timeout") % drvPath);
+ printMsg(lvlError, std::format("@ build-failed {} - timeout", drvPath));
st = BuildResult::TimedOut;
}
else if (hook && (!WIFEXITED(status) || WEXITSTATUS(status) != 100)) {
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ hook-failed %1% - %2% %3%")
- % drvPath % status % e.msg());
+ printMsg(lvlError, std::format("@ hook-failed {} - {} {}",
+ drvPath, status, e.msg()));
}
else {
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ build-failed %1% - %2% %3%")
- % drvPath % 1 % e.msg());
+ printMsg(lvlError, std::format("@ build-failed {} - {} {}",
+ drvPath, 1, e.msg()));
st =
statusOk(status) ? BuildResult::OutputRejected :
@@ -1536,7 +1535,7 @@ void DerivationGoal::buildDone()
buildUser.release();
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ build-succeeded %1% -") % drvPath);
+ printMsg(lvlError, std::format("@ build-succeeded {} -", drvPath));
done(BuildResult::Built);
}
@@ -1549,10 +1548,10 @@ HookReply DerivationGoal::tryBuildHook()
if (!worker.hook) {
Strings args = {
"offload",
- settings.thisSystem.c_str(),
- (format("%1%") % settings.maxSilentTime).str().c_str(),
- (format("%1%") % settings.printBuildTrace).str().c_str(),
- (format("%1%") % settings.buildTimeout).str().c_str()
+ settings.thisSystem,
+ std::format("{}", settings.maxSilentTime),
+ std::format("{}", settings.printBuildTrace),
+ std::format("{}", settings.buildTimeout)
};
worker.hook = std::make_shared<Agent>(settings.guixProgram, args);
@@ -1565,9 +1564,9 @@ HookReply DerivationGoal::tryBuildHook()
for (auto& i : features) checkStoreName(i); /* !!! abuse */
/* Send the request to the hook. */
- writeLine(worker.hook->toAgent.writeSide, (format("%1% %2% %3% %4%")
- % (worker.getNrLocalBuilds() < settings.maxBuildJobs ? "1" : "0")
- % drv.platform % drvPath % concatStringsSep(",", features)).str());
+ writeLine(worker.hook->toAgent.writeSide, std::format("{} {} {} {}",
+ (worker.getNrLocalBuilds() < settings.maxBuildJobs ? "1" : "0"),
+ drv.platform, drvPath, concatStringsSep(",", features)));
/* Read the first line of input, which should be a word indicating
whether the hook wishes to perform the build. */
@@ -1582,14 +1581,14 @@ HookReply DerivationGoal::tryBuildHook()
writeToStderr(s);
}
- debug(format("hook reply is `%1%'") % reply);
+ debug(std::format("hook reply is `{}'", reply));
if (reply == "decline" || reply == "postpone")
return reply == "decline" ? rpDecline : rpPostpone;
else if (reply != "accept")
- throw Error(format("bad hook reply `%1%'") % reply);
+ throw Error(std::format("bad hook reply `{}'", reply));
- printMsg(lvlTalkative, format("using hook to build path(s) %1%") % showPaths(missingPaths));
+ printMsg(lvlTalkative, std::format("using hook to build path(s) {}", showPaths(missingPaths)));
hook = worker.hook;
worker.hook.reset();
@@ -1624,8 +1623,8 @@ HookReply DerivationGoal::tryBuildHook()
worker.childStarted(shared_from_this(), hook->pid, fds, false, true);
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ build-started %1% - %2% %3% %4%")
- % drvPath % drv.platform % logFile % hook->pid);
+ printMsg(lvlError, std::format("@ build-started {} - {} {} {}",
+ drvPath, drv.platform, logFile, pid_t(hook->pid)));
return rpAccept;
}
@@ -1634,7 +1633,7 @@ HookReply DerivationGoal::tryBuildHook()
void chmod_(const Path & path, mode_t mode)
{
if (chmod(path.c_str(), mode) == -1)
- throw SysError(format("setting permissions on `%1%'") % path);
+ throw SysError(std::format("setting permissions on `{}'", path));
}
@@ -1652,7 +1651,7 @@ static void initializeUserNamespace(pid_t child,
bool haveCapSetGID = false)
{
writeFile("/proc/" + std::to_string(child) + "/uid_map",
- (format("%d %d 1") % guestUID % hostUID).str());
+ std::format("{} {} 1", guestUID, hostUID));
if (!haveCapSetGID && !extraGIDs.empty()) {
try {
@@ -1668,8 +1667,8 @@ static void initializeUserNamespace(pid_t child,
runProgram("newgidmap", true, args);
printMsg(lvlChatty,
- format("mapped %1% extra GIDs into namespace of PID %2%")
- % extraGIDs.size() % child);
+ std::format("mapped {} extra GIDs into namespace of PID {}",
+ extraGIDs.size(), child));
return;
} catch (const ExecError &e) {
@@ -1680,10 +1679,10 @@ static void initializeUserNamespace(pid_t child,
if (!haveCapSetGID)
writeFile("/proc/" + std::to_string(child) + "/setgroups", "deny");
- auto content = (format("%d %d 1\n") % guestGID % hostGID).str();
+ auto content = std::format("{} {} 1\n", guestGID, hostGID);
if (haveCapSetGID) {
for (auto &mapping: extraGIDs) {
- content += (format("%d %d 1\n") % mapping.second % mapping.first).str();
+ content += std::format("{} {} 1\n", mapping.second, mapping.first);
}
}
writeFile("/proc/" + std::to_string(child) + "/gid_map", content);
@@ -1963,7 +1962,7 @@ static void prepareSlirpChrootAction(SpawnContext & sctx)
struct stat st;
if(stat(fs.c_str(), &st) != 0) {
if(errno == EACCES) continue; /* Not accessible anyway */
- else throw SysError(format("stat of `%1%'") % fs);
+ else throw SysError(std::format("stat of `{}'", fs));
}
ctx.readOnlyFilesInChroot.insert(fs);
@@ -2408,7 +2407,7 @@ void DerivationGoal::execBuilderOrBuiltin(SpawnContext & ctx)
buildDrv(drv, drvPath, output);
}
else
- throw Error(format("unsupported builtin function '%1%'") % string(drv.builder, 8));
+ throw Error(std::format("unsupported builtin function '{}'", string(drv.builder, 8)));
_exit(0);
} catch (std::exception & e) {
writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n");
@@ -2427,7 +2426,7 @@ void DerivationGoal::execBuilderOrBuiltin(SpawnContext & ctx)
chroot. */
ctx.program = canonPath(ctx.program, true);
if(!isInStore(ctx.program))
- throw Error(format("derivation builder `%1' is outside the store") % ctx.program);
+ throw Error(std::format("derivation builder `{}' is outside the store", ctx.program));
/* 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
architectures. However, if it targets a different operating
@@ -2450,13 +2449,13 @@ void DerivationGoal::execBuilderOrBuiltin(SpawnContext & ctx)
that invoke QEMU. */
if (error == ENOEXEC && !canBuildLocally(drv.platform)) {
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ unsupported-platform %1% %2%") % drvPath % drv.platform);
- throw Error(format("a `%1%' is required to build `%3%', but I am a `%2%'")
- % drv.platform % settings.thisSystem % drvPath);
+ printMsg(lvlError, std::format("@ unsupported-platform {} {}", drvPath, drv.platform));
+ throw Error(std::format("a `{}' is required to build `{}', but I am a `{}'",
+ drv.platform, settings.thisSystem, drvPath));
}
errno = error;
- throw SysError(format("executing `%1%'") % drv.builder);
+ throw SysError(std::format("executing `{}'", drv.builder));
}
@@ -2468,13 +2467,14 @@ void execBuilderOrBuiltinAction(SpawnContext & ctx)
void DerivationGoal::startBuilder()
{
- auto f = format(
- buildMode == bmRepair ? "repairing path(s) %1%" :
- buildMode == bmCheck ? "checking path(s) %1%" :
- nrRounds > 1 ? "building path(s) %1% (round %2%/%3%)" :
- "building path(s) %1%");
- f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
- startNest(nest, lvlInfo, f % showPaths(missingPaths) % curRound % nrRounds);
+ auto path = showPaths(missingPaths);
+ auto f = std::vformat(
+ buildMode == bmRepair ? "repairing path(s) {0}" :
+ buildMode == bmCheck ? "checking path(s) {0}" :
+ nrRounds > 1 ? "building path(s) {0} (round {1}/{2})" :
+ "building path(s) {0}",
+ std::make_format_args(path, curRound, nrRounds));
+ startNest(nest, lvlInfo, f);
/* A ChrootBuildSpawnContext reference can be passed to procedures
expecting a SpawnContext reference */
@@ -2558,7 +2558,7 @@ void DerivationGoal::startBuilder()
ctx.env["NIX_STORE"] = settings.nixStore;
/* The maximum number of cores to utilize for parallel building. */
- ctx.env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();
+ ctx.env["NIX_BUILD_CORES"] = std::format("{}", settings.buildCores);
/* Add all bindings specified in the derivation. */
for (auto& i : drv.env)
@@ -2630,7 +2630,7 @@ void DerivationGoal::startBuilder()
string s = get(drv.env, "exportReferencesGraph");
Strings ss = tokenizeString<Strings>(s);
if (ss.size() % 2 != 0)
- throw BuildError(format("odd number of tokens in `exportReferencesGraph': `%1%'") % s);
+ throw BuildError(std::format("odd number of tokens in `exportReferencesGraph': `{}'", s));
for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
string fileName = *i++;
checkStoreName(fileName); /* !!! abuse of this function */
@@ -2638,12 +2638,12 @@ void DerivationGoal::startBuilder()
/* Check that the store path is valid. */
Path storePath = *i++;
if (!isInStore(storePath))
- throw BuildError(format("`exportReferencesGraph' contains a non-store path `%1%'")
- % storePath);
+ throw BuildError(std::format("`exportReferencesGraph' contains a non-store path `{}'",
+ storePath));
storePath = toStorePath(storePath);
if (!worker.store.isValidPath(storePath))
- throw BuildError(format("`exportReferencesGraph' contains an invalid path `%1%'")
- % storePath);
+ throw BuildError(std::format("`exportReferencesGraph' contains an invalid path `{}'",
+ storePath));
/* If there are derivations in the graph, then include their
outputs as well. This is useful if you want to do things
@@ -2680,7 +2680,7 @@ void DerivationGoal::startBuilder()
/* Change ownership of the temporary build directory. */
if (chown(tmpDir.c_str(), buildUser.getUID(), buildUser.getGID()) == -1)
- throw SysError(format("cannot change ownership of '%1%'") % tmpDir);
+ throw SysError(std::format("cannot change ownership of '{}'", tmpDir));
ctx.setuid = true;
ctx.user = buildUser.getUID();
@@ -2711,7 +2711,7 @@ void DerivationGoal::startBuilder()
if(fixedOutput) {
if(findProgram(settings.slirp4netns) == "")
- printMsg(lvlError, format("`%1%' can't be found in PATH, network access disabled") % settings.slirp4netns);
+ printMsg(lvlError, std::format("`{}' can't be found in PATH, network access disabled", settings.slirp4netns));
else {
if(!pathExists("/dev/net/tun"))
printMsg(lvlError, "`/dev/net/tun' is missing, network access disabled");
@@ -2737,15 +2737,15 @@ void DerivationGoal::startBuilder()
ctx.hostname = "localhost";
ctx.domainname = "(none)"; /* kernel default */
- printMsg(lvlChatty, format("setting up chroot environment in `%1%'") % chrootRootDir);
+ printMsg(lvlChatty, std::format("setting up chroot environment in `{}'", chrootRootDir));
if (mkdir(chrootRootTop.c_str(), 0750) == -1)
- throw SysError(format("cannot create build root container '%1%'") % chrootRootTop);
+ throw SysError(std::format("cannot create build root container '{}'", chrootRootTop));
if (mkdir(chrootRootDir.c_str(), 0750) == -1)
- throw SysError(format("cannot create build root '%1%'") % chrootRootDir);
+ throw SysError(std::format("cannot create build root '{}'", chrootRootDir));
if (buildUser.enabled() && chown(chrootRootDir.c_str(), 0, buildUser.getGID()) == -1)
- throw SysError(format("cannot change ownership of ‘%1%’") % chrootRootDir);
+ throw SysError(std::format("cannot change ownership of `{}'", chrootRootDir));
/* Create a writable /tmp in the chroot. Many builders need
this. (Of course they should really respect $TMPDIR
@@ -2760,17 +2760,17 @@ void DerivationGoal::startBuilder()
createDirs(chrootRootDir + "/etc");
writeFile(chrootRootDir + "/etc/passwd",
- (format(
- "nixbld:x:%1%:%2%:Nix build user:/:/noshell\n"
- "nobody:x:65534:65534:Nobody:/:/noshell\n")
- % (buildUser.enabled() ? buildUser.getUID() : guestUID)
- % (buildUser.enabled() ? buildUser.getGID() : guestGID)).str());
+ std::format(
+ "nixbld:x:{}:{}:Nix build user:/:/noshell\n"
+ "nobody:x:65534:65534:Nobody:/:/noshell\n",
+ buildUser.enabled() ? buildUser.getUID() : guestUID,
+ buildUser.enabled() ? buildUser.getGID() : guestGID));
/* Declare the build user's group so that programs get a consistent
view of the system (e.g., "id -gn"). */
writeFile(chrootRootDir + "/etc/group",
- (format("nixbld:!:%1%:\n")
- % (buildUser.enabled() ? buildUser.getGID() : guestGID)).str());
+ std::format("nixbld:!:{}:\n",
+ buildUser.enabled() ? buildUser.getGID() : guestGID));
if (fixedOutput) {
/* Fixed-output derivations typically need to access the network,
@@ -2834,7 +2834,7 @@ void DerivationGoal::startBuilder()
if (buildUser.enabled() && chown(chrootStoreDir.c_str(), 0, buildUser.getGID()) == -1)
/* As an extra security precaution, make the fake store only
writable by the build user. */
- throw SysError(format("cannot change ownership of ‘%1%’") % chrootStoreDir);
+ throw SysError(std::format("cannot change ownership of `{}'", chrootStoreDir));
/* Make the closure of the inputs available in the chroot, rather than
the whole store. This prevents any access to undeclared
@@ -2902,7 +2902,7 @@ void DerivationGoal::startBuilder()
ctx.phases = getBasicSpawnPhases();
if (pathExists(homeDir))
- throw Error(format("directory `%1%' exists; please remove it") % homeDir);
+ throw Error(std::format("directory `{}' exists; please remove it", homeDir));
/* We're not doing a chroot build, but we have some valid
output paths. Since we can't just overwrite or delete
@@ -2930,7 +2930,7 @@ void DerivationGoal::startBuilder()
replacePhase(ctx.phases, "exec", execBuilderOrBuiltinAction);
/* Run the builder. */
- printMsg(lvlChatty, format("executing builder `%1%'") % drv.builder);
+ printMsg(lvlChatty, std::format("executing builder `{}'", drv.builder));
/* Create the log file. */
Path logFile = openLogFile();
@@ -3070,8 +3070,8 @@ void DerivationGoal::startBuilder()
if (!msg.empty()) throw Error(msg);
if (settings.printBuildTrace) {
- printMsg(lvlError, format("@ build-started %1% - %2% %3% %4%")
- % drvPath % drv.platform % logFile % pid);
+ printMsg(lvlError, std::format("@ build-started {} - {} {} {}",
+ drvPath, drv.platform, logFile, pid_t(pid)));
}
}
@@ -3090,8 +3090,7 @@ PathSet parseReferenceSpecifiers(const Derivation & drv, string attr)
else if (drv.outputs.find(i) != drv.outputs.end())
result.insert(drv.outputs.find(i)->second.path);
else throw BuildError(
- format("derivation contains an invalid reference specifier `%1%'")
- % i);
+ std::format("derivation contains an invalid reference specifier `{}'", i));
}
return result;
}
@@ -3142,9 +3141,9 @@ void DerivationGoal::registerOutputs()
if (lstat(actualPath.c_str(), &st) == -1) {
if (errno == ENOENT)
throw BuildError(
- format("builder for `%1%' failed to produce output path `%2%'")
- % drvPath % path);
- throw SysError(format("getting attributes of path `%1%'") % actualPath);
+ std::format("builder for `{}' failed to produce output path `{}'",
+ drvPath, path));
+ throw SysError(std::format("getting attributes of path `{}'", actualPath));
}
#ifndef __CYGWIN__
@@ -3154,13 +3153,13 @@ void DerivationGoal::registerOutputs()
user. */
if ((!S_ISLNK(st.st_mode) && (st.st_mode & (S_IWGRP | S_IWOTH))) ||
(buildUser.enabled() && st.st_uid != buildUser.getUID()))
- throw BuildError(format("suspicious ownership or permission on `%1%'; rejecting this build output") % path);
+ throw BuildError(std::format("suspicious ownership or permission on `{}'; rejecting this build output", path));
#endif
/* Apply hash rewriting if necessary. */
bool rewritten = false;
if (!rewritesFromTmp.empty()) {
- printMsg(lvlError, format("warning: rewriting hashes in `%1%'; cross fingers") % path);
+ printMsg(lvlError, std::format("warning: rewriting hashes in `{}'; cross fingers", path));
/* Canonicalise first. This ensures that the path we're
rewriting doesn't contain a hard link to /etc/shadow or
@@ -3179,7 +3178,7 @@ void DerivationGoal::registerOutputs()
}
startNest(nest, lvlTalkative,
- format("scanning for references inside `%1%'") % path);
+ std::format("scanning for references inside `{}'", path));
/* Check that fixed-output derivations produced the right
outputs (i.e., the content hash should match the specified
@@ -3194,17 +3193,17 @@ void DerivationGoal::registerOutputs()
execute permission. */
if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
throw BuildError(
- format("output path `%1% should be a non-executable regular file") % path);
+ std::format("output path `{}' should be a non-executable regular file", path));
}
/* Check the hash. */
Hash h2 = recursive ? hashPath(ht, actualPath).first : hashFile(ht, actualPath);
if (h != h2) {
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ hash-mismatch %1% %2% %3% %4%")
- % path % i.second.hashAlgo
- % printHash16or32(h) % printHash16or32(h2));
- throw BuildError(format("hash mismatch for store item '%1%'") % path);
+ printMsg(lvlError, std::format("@ hash-mismatch {} {} {} {}",
+ path, i.second.hashAlgo,
+ printHash16or32(h), printHash16or32(h2)));
+ throw BuildError(std::format("hash mismatch for store item '{}'", path));
}
}
@@ -3224,16 +3223,16 @@ void DerivationGoal::registerOutputs()
if (buildMode != bmCheck) {
if (S_ISDIR(st.st_mode)) {
if (lstat(actualPath.c_str(), &st) == -1)
- throw SysError(format("getting canonicalized permissions of directory `%1%'") % actualPath);
+ throw SysError(std::format("getting canonicalized permissions of directory `{}'", actualPath));
/* Change mode on the directory to allow for
rename(2). */
if (chmod(actualPath.c_str(), st.st_mode | 0700) == -1)
- throw SysError(format("making `%1%' writable for move from chroot to store") % actualPath);
+ throw SysError(std::format("making `{}' writable for move from chroot to store", actualPath));
}
if (rename(actualPath.c_str(), path.c_str()) == -1)
- throw SysError(format("moving build output `%1%' from the chroot to the store") % path);
+ throw SysError(std::format("moving build output `{}' from the chroot to the store", path));
if (S_ISDIR(st.st_mode) && chmod(path.c_str(), st.st_mode) == -1)
- throw SysError(format("restoring permissions on directory `%1%'") % actualPath);
+ throw SysError(std::format("restoring permissions on directory `{}'", actualPath));
}
}
if (buildMode != bmCheck) actualPath = path;
@@ -3254,16 +3253,16 @@ void DerivationGoal::registerOutputs()
Path dst = path + checkSuffix;
if (pathExists(dst)) deletePath(dst);
if (rename(actualPath.c_str(), dst.c_str()))
- throw SysError(format("renaming `%1%' to `%2%'") % actualPath % dst);
- throw Error(format("derivation `%1%' may not be deterministic: output `%2%' differs from `%3%'")
- % drvPath % path % dst);
+ throw SysError(std::format("renaming `{}' to `{}'", actualPath, dst));
+ throw Error(std::format("derivation `{}' may not be deterministic: output `{}' differs from `{}'",
+ drvPath, path, dst));
} else
- throw Error(format("derivation `%1%' may not be deterministic: output `%2%' differs")
- % drvPath % path);
+ throw Error(std::format("derivation `{}' may not be deterministic: output `{}' differs",
+ drvPath, path));
}
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ build-succeeded %1% -") % drvPath);
+ printMsg(lvlError, std::format("@ build-succeeded {} -", drvPath));
continue;
}
@@ -3273,9 +3272,9 @@ void DerivationGoal::registerOutputs()
for (auto& i : inputPaths) {
PathSet::iterator j = references.find(i);
if (j == references.end())
- debug(format("unreferenced input: `%1%'") % i);
+ debug(std::format("unreferenced input: `{}'", i));
else
- debug(format("referenced input: `%1%'") % i);
+ debug(std::format("referenced input: `{}'", i));
}
/* Enforce `allowedReferences' and friends. */
@@ -3297,10 +3296,10 @@ void DerivationGoal::registerOutputs()
for (auto & i : used)
if (allowed) {
if (spec.find(i) == spec.end())
- throw BuildError(format("output (`%1%') is not allowed to refer to path `%2%'") % actualPath % i);
+ throw BuildError(std::format("output (`{}') is not allowed to refer to path `{}'", actualPath, i));
} else {
if (spec.find(i) != spec.end())
- throw BuildError(format("output (`%1%') is not allowed to refer to path `%2%'") % actualPath % i);
+ throw BuildError(std::format("output (`{}') is not allowed to refer to path `{}'", actualPath, i));
}
};
@@ -3333,12 +3332,12 @@ void DerivationGoal::registerOutputs()
Path prev = i->path + checkSuffix;
if (pathExists(prev))
throw NotDeterministic(
- format("output ‘%1%’ of ‘%2%’ differs from ‘%3%’ from previous round")
- % i->path % drvPath % prev);
+ std::format("output `{}' of `{}' differs from `{}' from previous round",
+ i->path, drvPath, prev));
else
throw NotDeterministic(
- format("output ‘%1%’ of ‘%2%’ differs from previous round")
- % i->path % drvPath);
+ std::format("output `{}' of `{}' differs from previous round",
+ i->path, drvPath));
}
assert(false); // shouldn't happen
}
@@ -3350,7 +3349,7 @@ void DerivationGoal::registerOutputs()
if (curRound < nrRounds) {
Path dst = i.second.path + checkSuffix;
if (rename(i.second.path.c_str(), dst.c_str()))
- throw SysError(format("renaming ‘%1%’ to ‘%2%’") % i.second.path % dst);
+ throw SysError(std::format("renaming `{}' to `{}'", i.second.path, dst));
}
}
@@ -3380,20 +3379,20 @@ Path DerivationGoal::openLogFile()
string baseName = baseNameOf(drvPath);
/* Create a log file. */
- Path dir = (format("%1%/%2%/%3%/") % settings.nixLogDir % drvsLogDir % string(baseName, 0, 2)).str();
+ Path dir = std::format("{}/{}/{}/", settings.nixLogDir, drvsLogDir, string(baseName, 0, 2));
createDirs(dir);
switch (settings.logCompression)
{
case COMPRESSION_GZIP: {
- Path logFileName = (format("%1%/%2%.gz") % dir % string(baseName, 2)).str();
+ Path logFileName = std::format("{}/{}.gz", dir, string(baseName, 2));
AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
- if (fd == -1) throw SysError(format("creating log file `%1%'") % logFileName);
+ if (fd == -1) throw SysError(std::format("creating log file `{}'", logFileName));
closeOnExec(fd);
/* Note: FD will be closed by 'gzclose'. */
if (!(gzLogFile = gzdopen(fd.borrow(), "w")))
- throw Error(format("cannot open compressed log file `%1%'") % logFileName);
+ throw Error(std::format("cannot open compressed log file `{}'", logFileName));
gzbuffer(gzLogFile, 32768);
gzsetparams(gzLogFile, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY);
@@ -3403,26 +3402,26 @@ Path DerivationGoal::openLogFile()
#if HAVE_BZLIB_H
case COMPRESSION_BZIP2: {
- Path logFileName = (format("%1%/%2%.bz2") % dir % string(baseName, 2)).str();
+ Path logFileName = std::format("{}/{}.bz2", dir, string(baseName, 2));
AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
- if (fd == -1) throw SysError(format("creating log file `%1%'") % logFileName);
+ if (fd == -1) throw SysError(std::format("creating log file `{}'", logFileName));
closeOnExec(fd);
if (!(fLogFile = fdopen(fd.borrow(), "w")))
- throw SysError(format("opening log file `%1%'") % logFileName);
+ throw SysError(std::format("opening log file `{}'", logFileName));
int err;
if (!(bzLogFile = BZ2_bzWriteOpen(&err, fLogFile, 9, 0, 0)))
- throw Error(format("cannot open compressed log file `%1%'") % logFileName);
+ throw Error(std::format("cannot open compressed log file `{}'", logFileName));
return logFileName;
}
#endif
case COMPRESSION_NONE: {
- Path logFileName = (format("%1%/%2%") % dir % string(baseName, 2)).str();
+ Path logFileName = std::format("{}/{}", dir, string(baseName, 2));
fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
- if (fdLogFile == -1) throw SysError(format("creating log file `%1%'") % logFileName);
+ if (fdLogFile == -1) throw SysError(std::format("creating log file `{}'", logFileName));
closeOnExec(fdLogFile);
return logFileName;
}
@@ -3438,14 +3437,14 @@ void DerivationGoal::closeLogFile()
int err;
err = gzclose(gzLogFile);
gzLogFile = NULL;
- if (err != Z_OK) throw Error(format("cannot close compressed log file (gzip error = %1%)") % err);
+ if (err != Z_OK) throw Error(std::format("cannot close compressed log file (gzip error = {})", err));
}
#if HAVE_BZLIB_H
else if (bzLogFile) {
int err;
BZ2_bzWriteClose(&err, bzLogFile, 0, 0, 0);
bzLogFile = 0;
- if (err != BZ_OK) throw Error(format("cannot close compressed log file (BZip2 error = %1%)") % err);
+ if (err != BZ_OK) throw Error(std::format("cannot close compressed log file (BZip2 error = {})", err));
}
#endif
@@ -3463,7 +3462,7 @@ static void _chown(const Path & path, uid_t uid, gid_t gid)
checkInterrupt();
if (lchown(path.c_str(), uid, gid) == -1) {
- throw SysError(format("change owner and group of `%1%'") % path);
+ throw SysError(std::format("change owner and group of `{}'", path));
}
struct stat st = lstat(path);
if (S_ISDIR(st.st_mode)) {
@@ -3486,8 +3485,7 @@ void DerivationGoal::deleteTmpDir(bool force)
if (settings.keepFailed && !force) {
printMsg(lvlError,
- format("note: keeping build directory `%2%'")
- % drvPath % top);
+ std::format("note: keeping build directory `{}'", top));
chmod(tmpDir.c_str(), 0755);
// Change the ownership if clientUid is set. Never change the
@@ -3516,8 +3514,8 @@ void DerivationGoal::deleteTmpDir(bool force)
/* When running as an unprivileged user and without
CAP_CHOWN, we cannot chown the build tree. Print a
message and keep going. */
- printMsg(lvlInfo, format("cannot change ownership of build directory '%1%': %2%")
- % tmpDir % strerror(e.errNo));
+ printMsg(lvlInfo, std::format("cannot change ownership of build directory '{}': {}",
+ tmpDir, strerror(e.errNo)));
}
if (top != tmpDir) {
@@ -3568,8 +3566,8 @@ void DerivationGoal::handleChildOutput(int fd, const string & data)
logSize += data.size();
if (settings.maxLogSize && logSize > settings.maxLogSize) {
printMsg(lvlError,
- format("%1% killed after writing more than %2% bytes of log output")
- % getName() % settings.maxLogSize);
+ std::format("{} killed after writing more than {} bytes of log output",
+ getName(), settings.maxLogSize));
timedOut(); // not really a timeout, but close enough
return;
}
@@ -3580,13 +3578,13 @@ void DerivationGoal::handleChildOutput(int fd, const string & data)
if (data.size() > 0) {
int count, err;
count = gzwrite(gzLogFile, data.data(), data.size());
- if (count == 0) throw Error(format("cannot write to compressed log file (gzip error = %1%)") % gzerror(gzLogFile, &err));
+ if (count == 0) throw Error(std::format("cannot write to compressed log file (gzip error = {})", gzerror(gzLogFile, &err)));
}
#if HAVE_BZLIB_H
} else if (bzLogFile) {
int err;
BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size());
- if (err != BZ_OK) throw Error(format("cannot write to compressed log file (BZip2 error = %1%)") % err);
+ if (err != BZ_OK) throw Error(std::format("cannot write to compressed log file (BZip2 error = {})", err));
#endif
} else if (fdLogFile != -1)
writeFull(fdLogFile, data);
@@ -3623,10 +3621,10 @@ bool DerivationGoal::pathFailed(const Path & path)
if (!worker.store.hasPathFailed(path)) return false;
- printMsg(lvlError, format("builder for `%1%' failed previously (cached)") % path);
+ printMsg(lvlError, std::format("builder for `{}' failed previously (cached)", path));
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ build-failed %1% - cached") % drvPath);
+ printMsg(lvlError, std::format("@ build-failed {} - cached", drvPath));
done(BuildResult::CachedFailure);
@@ -3644,8 +3642,8 @@ Path DerivationGoal::addHashRewrite(const Path & path)
rewritesToTmp[h1] = h2;
rewritesFromTmp[h2] = h1;
redirectedOutputs[path] = p;
- printMsg(lvlChatty, format("output '%1%' redirected to '%2%'")
- % path % p);
+ printMsg(lvlChatty, std::format("output '{}' redirected to '{}'",
+ path, p));
return p;
}
@@ -3734,7 +3732,7 @@ SubstitutionGoal::SubstitutionGoal(const Path & storePath, Worker & worker, bool
{
this->storePath = storePath;
state = &SubstitutionGoal::init;
- name = (format("substitution of `%1%'") % storePath).str();
+ name = std::format("substitution of `{}'", storePath);
trace("created");
}
@@ -3748,7 +3746,7 @@ SubstitutionGoal::~SubstitutionGoal()
void SubstitutionGoal::timedOut()
{
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ substituter-failed %1% timeout") % storePath);
+ printMsg(lvlError, std::format("@ substituter-failed {} timeout", storePath));
if (substituter) {
pid_t savedPid = substituter->pid;
substituter.reset();
@@ -3777,7 +3775,7 @@ void SubstitutionGoal::init()
}
if (settings.readOnlyMode)
- throw Error(format("cannot substitute path `%1%' - no write access to the store") % storePath);
+ throw Error(std::format("cannot substitute path `{}' - no write access to the store", storePath));
tryNext();
}
@@ -3794,7 +3792,7 @@ void SubstitutionGoal::tryNext()
if (k == infos.end()) {
/* None left. Terminate this goal and let someone else deal
with it. */
- debug(format("path `%1%' is required, but there is no substituter that can build it") % storePath);
+ debug(std::format("path `{}' is required, but there is no substituter that can build it", storePath));
/* Hack: don't indicate failure if there were no substituters.
In that case the calling derivation should just do a
build. */
@@ -3823,7 +3821,7 @@ void SubstitutionGoal::referencesValid()
trace("all references realised");
if (nrFailed > 0) {
- debug(format("some references of path `%1%' could not be realised") % storePath);
+ debug(std::format("some references of path `{}' could not be realised", storePath));
amDone(nrNoSubstituters > 0 || nrIncompleteClosure > 0 ? ecIncompleteClosure : ecFailed);
return;
}
@@ -3855,8 +3853,8 @@ void SubstitutionGoal::tryToRun()
first, but let's be defensive). */
outputLock.reset(); // make sure this goal's lock is gone
if (pathIsLockedByMe(storePath)) {
- debug(format("restarting substitution of `%1%' because it's locked by another goal")
- % storePath);
+ debug(std::format("restarting substitution of `{}' because it's locked by another goal",
+ storePath));
worker.waitForAnyGoal(shared_from_this());
return; /* restart in the tryToRun() state when another goal finishes */
}
@@ -3870,14 +3868,14 @@ void SubstitutionGoal::tryToRun()
/* Check again whether the path is invalid. */
if (!repair && worker.store.isValidPath(storePath)) {
- debug(format("store path `%1%' has become valid") % storePath);
+ debug(std::format("store path `{}' has become valid", storePath));
outputLock->setDeletion(true);
outputLock.reset();
amDone(ecSuccess);
return;
}
- printMsg(lvlInfo, format("fetching path `%1%'...") % storePath);
+ printMsg(lvlInfo, std::format("fetching path `{}'...", storePath));
destPath = repair ? storePath + ".tmp" : storePath;
@@ -3901,7 +3899,7 @@ void SubstitutionGoal::tryToRun()
/* Send the request to the substituter. */
writeLine(substituter->toAgent.writeSide,
- (format("substitute %1% %2%") % storePath % destPath).str());
+ std::format("substitute {} {}", storePath, destPath));
set<int> fds;
fds.insert(substituter->fromAgent.readSide);
@@ -3913,7 +3911,7 @@ void SubstitutionGoal::tryToRun()
if (settings.printBuildTrace)
/* The second element in the message used to be the name of the
substituter but we're left with only one. */
- printMsg(lvlError, format("@ substituter-started %1% substitute") % storePath);
+ printMsg(lvlError, std::format("@ substituter-started {} substitute", storePath));
}
@@ -3939,35 +3937,33 @@ void SubstitutionGoal::finished()
auto statusList = tokenizeString<vector<string> >(status);
if (statusList.empty()) {
- throw SubstError(format("fetching path `%1%' (empty status)")
- % storePath);
+ throw SubstError(std::format("fetching path `{}' (empty status)", storePath));
} else if (statusList[0] == "hash-mismatch") {
if (settings.printBuildTrace) {
auto hashType = statusList[1];
auto expectedHash = statusList[2];
auto actualHash = statusList[3];
- printMsg(lvlError, format("@ hash-mismatch %1% %2% %3% %4%")
- % storePath
- % hashType % expectedHash % actualHash);
+ printMsg(lvlError, std::format("@ hash-mismatch {} {} {} {}",
+ storePath, hashType, expectedHash, actualHash));
}
- throw SubstError(format("hash mismatch for substituted item `%1%'") % storePath);
+ throw SubstError(std::format("hash mismatch for substituted item `{}'", storePath));
} else if (statusList[0] == "success") {
if (!pathExists(destPath))
- throw SubstError(format("substitute did not produce path `%1%'") % destPath);
+ throw SubstError(std::format("substitute did not produce path `{}'", destPath));
std::string hashStr = statusList[1];
size_t n = hashStr.find(':');
if (n == string::npos)
- throw Error(format("bad hash from substituter: %1%") % hashStr);
+ throw Error(std::format("bad hash from substituter: {}", hashStr));
HashType hashType = parseHashType(string(hashStr, 0, n));
switch (hashType) {
case htUnknown:
- throw Error(format("unknown hash algorithm in `%1%'") % hashStr);
+ throw Error(std::format("unknown hash algorithm in `{}'", hashStr));
case htSHA256:
hash.first = parseHash16or32(hashType, string(hashStr, n + 1));
if (!string2Int(statusList[2], hash.second))
- throw Error(format("invalid nar size for '%1%' substitute") % storePath);
+ throw Error(std::format("invalid nar size for '{}' substitute", storePath));
break;
default:
/* The database only stores SHA256 hashes, so compute it. */
@@ -3976,16 +3972,16 @@ void SubstitutionGoal::finished()
}
}
else
- throw SubstError(format("fetching path `%1%' (status: '%2%')")
- % storePath % status);
+ throw SubstError(std::format("fetching path `{}' (status: '{}')",
+ storePath, status));
} catch (SubstError & e) {
printMsg(lvlInfo, e.msg());
if (settings.printBuildTrace) {
- printMsg(lvlError, format("@ substituter-failed %1% %2% %3%")
- % storePath % status % e.msg());
+ printMsg(lvlError, std::format("@ substituter-failed {} {} {}",
+ storePath, status, e.msg()));
}
amDone(ecFailed);
@@ -4011,10 +4007,10 @@ void SubstitutionGoal::finished()
worker.store.markContentsGood(storePath);
printMsg(lvlChatty,
- format("substitution of path `%1%' succeeded") % storePath);
+ std::format("substitution of path `{}' succeeded", storePath));
if (settings.printBuildTrace)
- printMsg(lvlError, format("@ substituter-succeeded %1%") % storePath);
+ printMsg(lvlError, std::format("@ substituter-succeeded {}", storePath));
amDone(ecSuccess);
}
@@ -4042,7 +4038,7 @@ void SubstitutionGoal::handleChildOutput(int fd, const string & data)
status = trimmed;
worker.wakeUp(shared_from_this());
} else {
- printMsg(lvlError, format("unexpected substituter message '%1%'") % input);
+ printMsg(lvlError, std::format("unexpected substituter message '{}'", input));
}
input = (end != string::npos) ? input.substr(end + 1) : "";
@@ -4234,7 +4230,7 @@ void Worker::run(const Goals & _topGoals)
{
for (auto& i : _topGoals) topGoals.insert(i);
- startNest(nest, lvlDebug, format("entered goal loop"));
+ startNest(nest, lvlDebug, "entered goal loop");
while (1) {
@@ -4308,7 +4304,7 @@ void Worker::waitForInput()
if (nearest != LONG_MAX) {
timeout.tv_sec = std::max((time_t) 1, nearest - before);
useTimeout = true;
- printMsg(lvlVomit, format("sleeping %1% seconds") % timeout.tv_sec);
+ printMsg(lvlVomit, std::format("sleeping {} seconds", timeout.tv_sec));
}
/* If we are polling goals that are waiting for a lock, then wake
@@ -4365,15 +4361,14 @@ void Worker::waitForInput()
ssize_t rd = read(k, buffer, sizeof(buffer));
if (rd == -1) {
if (errno != EINTR)
- throw SysError(format("reading from %1%")
- % goal->getName());
+ throw SysError(std::format("reading from {}", goal->getName()));
} else if (rd == 0) {
- debug(format("%1%: got EOF") % goal->getName());
+ debug(std::format("{}: got EOF", goal->getName()));
goal->handleEOF(k);
j->second.fds.erase(k);
} else {
- printMsg(lvlVomit, format("%1%: read %2% bytes")
- % goal->getName() % rd);
+ printMsg(lvlVomit, std::format("{}: read {} bytes",
+ goal->getName(), rd));
string data((char *) buffer, rd);
j->second.lastOutput = after;
goal->handleChildOutput(k, data);
@@ -4387,8 +4382,8 @@ void Worker::waitForInput()
after - j->second.lastOutput >= (time_t) settings.maxSilentTime)
{
printMsg(lvlError,
- format("%1% timed out after %2% seconds of silence")
- % goal->getName() % settings.maxSilentTime);
+ std::format("{} timed out after {} seconds of silence",
+ goal->getName(), settings.maxSilentTime));
goal->timedOut();
}
@@ -4398,8 +4393,8 @@ void Worker::waitForInput()
after - j->second.timeStarted >= (time_t) settings.buildTimeout)
{
printMsg(lvlError,
- format("%1% timed out after %2% seconds")
- % goal->getName() % settings.buildTimeout);
+ std::format("{} timed out after %2% seconds",
+ goal->getName(), settings.buildTimeout));
goal->timedOut();
}
}
@@ -4427,7 +4422,7 @@ unsigned int Worker::exitStatus()
void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
{
startNest(nest, lvlDebug,
- format("building %1%") % showPaths(drvPaths));
+ std::format("building {}", showPaths(drvPaths)));
Worker worker(*this);
@@ -4451,7 +4446,7 @@ void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
}
if (!failed.empty())
- throw Error(format("build of %1% failed") % showPaths(failed), worker.exitStatus());
+ throw Error(std::format("build of {} failed", showPaths(failed)), worker.exitStatus());
}
@@ -4467,7 +4462,7 @@ void LocalStore::ensurePath(const Path & path)
worker.run(goals);
if (goal->getExitCode() != Goal::ecSuccess)
- throw Error(format("path `%1%' does not exist and cannot be created") % path, worker.exitStatus());
+ throw Error(std::format("path `{}' does not exist and cannot be created", path), worker.exitStatus());
}
@@ -4488,7 +4483,7 @@ void LocalStore::repairPath(const Path & path)
goals.insert(worker.makeDerivationGoal(deriver, StringSet(), bmRepair));
worker.run(goals);
} else
- throw Error(format("cannot repair path `%1%'") % path, worker.exitStatus());
+ throw Error(std::format("cannot repair path `{}'", path), worker.exitStatus());
}
}
diff --git a/nix/libstore/builtins.cc b/nix/libstore/builtins.cc
index 6bf467354a..b1a32480b5 100644
--- a/nix/libstore/builtins.cc
+++ b/nix/libstore/builtins.cc
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <cstdlib>
+#include <format>
namespace nix {
@@ -53,7 +54,7 @@ static void builtinDownload(const Derivation &drv,
const string program = settings.guixProgram;
execv(program.c_str(), (char *const *) argv);
- throw SysError(format("failed to run download program '%1%'") % program);
+ throw SysError(std::format("failed to run download program '{}'", program));
}
static const std::map<std::string, derivationBuilder> builtins =
diff --git a/nix/libstore/builtins.hh b/nix/libstore/builtins.hh
index 396ea14ebc..602a5a1c58 100644
--- a/nix/libstore/builtins.hh
+++ b/nix/libstore/builtins.hh
@@ -21,7 +21,6 @@
#pragma once
#include <derivations.hh>
-#include <map>
#include <string>
namespace nix {
diff --git a/nix/libstore/derivations.cc b/nix/libstore/derivations.cc
index 0c3a249228..c253a2a438 100644
--- a/nix/libstore/derivations.cc
+++ b/nix/libstore/derivations.cc
@@ -4,6 +4,9 @@
#include "util.hh"
#include "misc.hh"
+#include <format>
+
+#include <cassert>
namespace nix {
@@ -20,7 +23,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash
hashType = parseHashType(algo);
if (hashType == htUnknown)
- throw Error(format("unknown hash algorithm `%1%'") % algo);
+ throw Error(std::format("unknown hash algorithm `{}'", algo));
hash = parseHash(hashType, this->hash);
}
@@ -48,7 +51,7 @@ static Path parsePath(std::istream & str)
{
string s = parseString(str);
if (s.size() == 0 || s[0] != '/')
- throw FormatError(format("bad path `%1%' in derivation") % s);
+ throw FormatError(std::format("bad path `{}' in derivation", s));
return s;
}
@@ -117,7 +120,7 @@ Derivation readDerivation(const Path & drvPath)
try {
return parseDerivation(readFile(drvPath));
} catch (FormatError & e) {
- throw Error(format("error parsing derivation `%1%': %2%") % drvPath % e.msg());
+ throw Error(std::format("error parsing derivation `{}': {}", drvPath, e.msg()));
}
}
diff --git a/nix/libstore/gc.cc b/nix/libstore/gc.cc
index 610270f907..96440077fb 100644
--- a/nix/libstore/gc.cc
+++ b/nix/libstore/gc.cc
@@ -6,6 +6,7 @@
#include <queue>
#include <random>
#include <algorithm>
+#include <format>
#include <sys/types.h>
#include <sys/stat.h>
@@ -30,18 +31,17 @@ static string gcRootsDir = "gcroots";
yielded the GC lock. */
int LocalStore::openGCLock(LockType lockType)
{
- Path fnGCLock = (format("%1%/%2%")
- % settings.nixStateDir % gcLockName).str();
+ Path fnGCLock = std::format("{}/{}", settings.nixStateDir, gcLockName);
- debug(format("acquiring global GC lock `%1%'") % fnGCLock);
+ debug(std::format("acquiring global GC lock `{}'", fnGCLock));
AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT, 0600);
if (fdGCLock == -1)
- throw SysError(format("opening global GC lock `%1%'") % fnGCLock);
+ throw SysError(std::format("opening global GC lock `{}'", fnGCLock));
closeOnExec(fdGCLock);
if (!lockFile(fdGCLock, lockType, false)) {
- printMsg(lvlError, format("waiting for the big garbage collector lock..."));
+ printMsg(lvlError, "waiting for the big garbage collector lock...");
lockFile(fdGCLock, lockType, true);
}
@@ -59,14 +59,12 @@ static void makeSymlink(const Path & link, const Path & target)
createDirs(dirOf(link));
/* Create the new symlink. */
- Path tempLink = (format("%1%.tmp-%2%-%3%")
- % link % getpid() % rand()).str();
+ Path tempLink = std::format("{}.tmp-{}-{}", link, getpid(), rand());
createSymlink(target, tempLink);
/* Atomically replace the old one. */
if (rename(tempLink.c_str(), link.c_str()) == -1)
- throw SysError(format("cannot rename `%1%' to `%2%'")
- % tempLink % link);
+ throw SysError(std::format("cannot rename `{}' to `{}'", tempLink, link));
}
@@ -79,8 +77,8 @@ void LocalStore::syncWithGC()
void LocalStore::addIndirectRoot(const Path & path)
{
string hash = printHash32(hashString(htSHA1, path));
- Path realRoot = canonPath((format("%1%/%2%/auto/%3%")
- % settings.nixStateDir % gcRootsDir % hash).str());
+ Path realRoot = canonPath(std::format("{}/{}/auto/{}",
+ settings.nixStateDir, gcRootsDir, hash));
makeSymlink(realRoot, path);
}
@@ -93,28 +91,28 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
assertStorePath(storePath);
if (isInStore(gcRoot))
- throw Error(format(
- "creating a garbage collector root (%1%) in the store is forbidden "
- "(are you running nix-build inside the store?)") % gcRoot);
+ throw Error(std::format(
+ "creating a garbage collector root ({}) in the store is forbidden "
+ "(are you running nix-build inside the store?)", gcRoot));
if (indirect) {
/* Don't clobber the link if it already exists and doesn't
point to the store. */
if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot))))
- throw Error(format("cannot create symlink `%1%'; already exists") % gcRoot);
+ throw Error(std::format("cannot create symlink `{}'; already exists", gcRoot));
makeSymlink(gcRoot, storePath);
store.addIndirectRoot(gcRoot);
}
else {
if (!allowOutsideRootsDir) {
- Path rootsDir = canonPath((format("%1%/%2%") % settings.nixStateDir % gcRootsDir).str());
+ Path rootsDir = canonPath(std::format("{}/{}", settings.nixStateDir, gcRootsDir));
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
- throw Error(format(
- "path `%1%' is not a valid garbage collector root; "
- "it's not in the directory `%2%'")
- % gcRoot % rootsDir);
+ throw Error(std::format(
+ "path `{}' is not a valid garbage collector root; "
+ "it's not in the directory `{}'",
+ gcRoot, rootsDir));
}
if (baseNameOf(gcRoot) == baseNameOf(storePath))
@@ -132,10 +130,10 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
Roots roots = store.findRoots();
if (roots.find(gcRoot) == roots.end())
printMsg(lvlError,
- format(
- "warning: `%1%' is not in a directory where the garbage collector looks for roots; "
- "therefore, `%2%' might be removed by the garbage collector")
- % gcRoot % storePath);
+ std::format(
+ "warning: `{}' is not in a directory where the garbage collector looks for roots; "
+ "therefore, `{}' might be removed by the garbage collector",
+ gcRoot, storePath));
}
/* Grab the global GC root, causing us to block while a GC is in
@@ -153,11 +151,10 @@ void LocalStore::addTempRoot(const Path & path)
if (fdTempRoots == -1) {
while (1) {
- Path dir = (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str();
+ Path dir = std::format("{}/{}", settings.nixStateDir, tempRootsDir);
createDirs(dir);
- fnTempRoots = (format("%1%/%2%")
- % dir % getpid()).str();
+ fnTempRoots = std::format("{}/{}", dir, getpid());
AutoCloseFD fdGCLock = openGCLock(ltRead);
@@ -170,14 +167,14 @@ void LocalStore::addTempRoot(const Path & path)
fdGCLock.close();
- debug(format("acquiring read lock on `%1%'") % fnTempRoots);
+ debug(std::format("acquiring read lock on `{}'", fnTempRoots));
lockFile(fdTempRoots, ltRead, true);
/* Check whether the garbage collector didn't get in our
way. */
struct stat st;
if (fstat(fdTempRoots, &st) == -1)
- throw SysError(format("statting `%1%'") % fnTempRoots);
+ throw SysError(std::format("statting `{}'", fnTempRoots));
if (st.st_size == 0) break;
/* The garbage collector deleted this file before we could
@@ -189,14 +186,14 @@ void LocalStore::addTempRoot(const Path & path)
/* Upgrade the lock to a write lock. This will cause us to block
if the garbage collector is holding our lock. */
- debug(format("acquiring write lock on `%1%'") % fnTempRoots);
+ debug(std::format("acquiring write lock on `{}'", fnTempRoots));
lockFile(fdTempRoots, ltWrite, true);
string s = path + '\0';
writeFull(fdTempRoots, s);
/* Downgrade to a read lock. */
- debug(format("downgrading to read lock on `%1%'") % fnTempRoots);
+ debug(std::format("downgrading to read lock on `{}'", fnTempRoots));
lockFile(fdTempRoots, ltRead, true);
}
@@ -210,17 +207,17 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
/* Read the `temproots' directory for per-process temporary root
files. */
DirEntries tempRootFiles = readDirectory(
- (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str());
+ std::format("{}/{}", settings.nixStateDir, tempRootsDir));
for (auto & i : tempRootFiles) {
- Path path = (format("%1%/%2%/%3%") % settings.nixStateDir % tempRootsDir % i.name).str();
+ Path path = std::format("{}/{}/{}", settings.nixStateDir, tempRootsDir, i.name);
- debug(format("reading temporary root file `%1%'") % path);
+ debug(std::format("reading temporary root file `{}'", path));
FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666)));
if (*fd == -1) {
/* It's okay if the file has disappeared. */
if (errno == ENOENT) continue;
- throw SysError(format("opening temporary roots file `%1%'") % path);
+ throw SysError(std::format("opening temporary roots file `{}'", path));
}
/* This should work, but doesn't, for some reason. */
@@ -231,7 +228,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
only succeed if the owning process has died. In that case
we don't care about its temporary roots. */
if (lockFile(*fd, ltWrite, false)) {
- printMsg(lvlError, format("removing stale temporary roots file `%1%'") % path);
+ printMsg(lvlError, std::format("removing stale temporary roots file `{}'", path));
unlink(path.c_str());
writeFull(*fd, "d");
continue;
@@ -240,7 +237,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
/* Acquire a read lock. This will prevent the owning process
from upgrading to a write lock, therefore it will block in
addTempRoot(). */
- debug(format("waiting for read lock on `%1%'") % path);
+ debug(std::format("waiting for read lock on `{}'", path));
lockFile(*fd, ltRead, true);
/* Read the entire file. */
@@ -251,7 +248,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
while ((end = contents.find((char) 0, pos)) != string::npos) {
Path root(contents, pos, end - pos);
- debug(format("got temporary root `%1%'") % root);
+ debug(std::format("got temporary root `{}'", root));
assertStorePath(root);
tempRoots.insert(root);
pos = end + 1;
@@ -269,7 +266,7 @@ static void foundRoot(StoreAPI & store,
if (store.isValidPath(storePath))
roots[path] = storePath;
else
- printMsg(lvlInfo, format("skipping invalid root from `%1%' to `%2%'") % path % storePath);
+ printMsg(lvlInfo, std::format("skipping invalid root from `{}' to `{}'", path, storePath));
}
@@ -295,7 +292,7 @@ static void findRoots(StoreAPI & store, const Path & path, unsigned char type, R
target = absPath(target, dirOf(path));
if (!pathExists(target)) {
if (isInDir(path, settings.nixStateDir + "/" + gcRootsDir + "/auto")) {
- printMsg(lvlInfo, format("removing stale link from `%1%' to `%2%'") % path % target);
+ printMsg(lvlInfo, std::format("removing stale link from `{}' to `{}'", path, target));
unlink(path.c_str());
}
} else {
@@ -318,8 +315,8 @@ static void findRoots(StoreAPI & store, const Path & path, unsigned char type, R
catch (SysError & e) {
/* We only ignore permanent failures. */
if (e.errNo == EACCES || e.errNo == ENOENT || e.errNo == ENOTDIR)
- printMsg(lvlInfo, format("cannot read potential root '%1%': %2%")
- % path % strerror(e.errNo));
+ printMsg(lvlInfo, std::format("cannot read potential root '{}': {}",
+ path, strerror(e.errNo)));
else
throw;
}
@@ -342,8 +339,8 @@ Roots LocalStore::findRoots()
static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
{
- debug(format("executing `%1% gc --list-busy' to find additional roots")
- % settings.guixProgram);
+ debug(std::format("executing `{} gc --list-busy' to find additional roots",
+ settings.guixProgram));
const Strings args = { "gc", "--list-busy" };
string result = runProgram(settings.guixProgram, false, args);
@@ -354,7 +351,7 @@ static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
if (isInStore(i)) {
Path path = toStorePath(i);
if (roots.find(path) == roots.end() && store.isValidPath(path)) {
- debug(format("got additional root `%1%'") % path);
+ debug(std::format("got additional root `{}'", path));
roots.insert(path);
}
}
@@ -424,17 +421,17 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
struct stat st;
if (lstat(path.c_str(), &st)) {
if (errno == ENOENT) return;
- throw SysError(format("getting status of %1%") % path);
+ throw SysError(std::format("getting status of {}", path));
}
if (state.options.maxFreed != ULLONG_MAX) {
auto freed = state.results.bytesFreed + state.bytesInvalidated;
double fraction = ((double) freed) / (double) state.options.maxFreed;
unsigned int percentage = (fraction > 1. ? 1. : fraction) * 100.;
- printMsg(lvlInfo, format("[%1%%%] deleting '%2%'") % percentage % path);
+ printMsg(lvlInfo, std::format("[{}%] deleting '{}'", percentage, path));
} else {
auto freed = state.results.bytesFreed + state.bytesInvalidated;
- printMsg(lvlInfo, format("[%1%] deleting '%2%'") % showBytes(freed) % path);
+ printMsg(lvlInfo, std::format("[{}] deleting '{}'", showBytes(freed), path));
}
state.results.paths.insert(path);
@@ -450,17 +447,17 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
// size.
try {
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
- throw SysError(format("making `%1%' writable") % path);
+ throw SysError(std::format("making `{}' writable", path));
Path tmp = state.trashDir + "/" + baseNameOf(path);
if (rename(path.c_str(), tmp.c_str()))
- throw SysError(format("unable to rename `%1%' to `%2%'") % path % tmp);
+ throw SysError(std::format("unable to rename `{}' to `{}'", path, tmp));
state.bytesInvalidated += size;
} catch (SysError & e) {
/* In a Docker container, rename(2) returns EXDEV when the source
and destination are not both on the "top layer". See:
https://bugs.gnu.org/41607 */
if (e.errNo == ENOSPC || e.errNo == EXDEV) {
- printMsg(lvlInfo, format("note: can't create move `%1%': %2%") % path % e.msg());
+ printMsg(lvlInfo, std::format("note: can't create move `{}': {}", path, e.msg()));
deleteGarbage(state, path);
}
}
@@ -468,7 +465,7 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
deleteGarbage(state, path);
if (state.results.bytesFreed + state.bytesInvalidated > state.options.maxFreed) {
- printMsg(lvlInfo, format("deleted or invalidated more than %1% bytes; stopping") % state.options.maxFreed);
+ printMsg(lvlInfo, std::format("deleted or invalidated more than {} bytes; stopping", state.options.maxFreed));
throw GCLimitReached();
}
}
@@ -487,7 +484,7 @@ bool LocalStore::canReachRoot(GCState & state, PathSet & visited, const Path & p
}
if (state.roots.find(path) != state.roots.end()) {
- printMsg(lvlDebug, format("cannot delete `%1%' because it's a root") % path);
+ printMsg(lvlDebug, std::format("cannot delete `{}' because it's a root", path));
state.alive.insert(path);
return true;
}
@@ -535,7 +532,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
if (path == linksDir || path == state.trashDir) return;
- startNest(nest, lvlDebug, format("considering whether to delete `%1%'") % path);
+ startNest(nest, lvlDebug, std::format("considering whether to delete `{}'", path));
if (!isValidPath(path)) {
/* A lock file belonging to a path that we're building right
@@ -550,7 +547,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
PathSet visited;
if (canReachRoot(state, visited, path)) {
- printMsg(lvlDebug, format("cannot delete `%1%' because it's still reachable") % path);
+ printMsg(lvlDebug, std::format("cannot delete `{}' because it's still reachable", path));
} else {
/* No path we visited was a root, so everything is garbage.
But we only delete ‘path’ and its referrers here so that
@@ -571,7 +568,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
void LocalStore::removeUnusedLinks(const GCState & state)
{
AutoCloseDir dir = opendir(linksDir.c_str());
- if (!dir) throw SysError(format("opening directory `%1%'") % linksDir);
+ if (!dir) throw SysError(std::format("opening directory `{}'", linksDir));
long long actualSize = 0, unsharedSize = 0;
@@ -596,15 +593,15 @@ void LocalStore::removeUnusedLinks(const GCState & state)
statx_flags &= ~AT_STATX_DONT_SYNC;
if (statx(AT_FDCWD, path.c_str(), statx_flags,
STATX_SIZE | STATX_NLINK, &st) == -1)
- throw SysError(format("statting `%1%'") % path);
+ throw SysError(std::format("statting `{}'", path));
} else {
- throw SysError(format("statting `%1%'") % path);
+ throw SysError(std::format("statting `{}'", path));
}
}
#else
struct stat st;
if (lstat(path.c_str(), &st) == -1)
- throw SysError(format("statting `%1%'") % path);
+ throw SysError(std::format("statting `{}'", path));
#endif
/* Drop links for files smaller than 'deduplicationMinSize', even if
@@ -616,10 +613,10 @@ void LocalStore::removeUnusedLinks(const GCState & state)
continue;
}
- printMsg(lvlTalkative, format("deleting unused link `%1%'") % path);
+ printMsg(lvlTalkative, std::format("deleting unused link `{}'", path));
if (unlink(path.c_str()) == -1)
- throw SysError(format("deleting `%1%'") % path);
+ throw SysError(std::format("deleting `{}'", path));
state.results.bytesFreed += st.st_size;
#undef st_size
@@ -628,11 +625,11 @@ void LocalStore::removeUnusedLinks(const GCState & state)
struct stat st;
if (stat(linksDir.c_str(), &st) == -1)
- throw SysError(format("statting `%1%'") % linksDir);
+ throw SysError(std::format("statting `{}'", linksDir));
long long overhead = st.st_size;
long long freedbytes = (unsharedSize - actualSize - overhead);
- printMsg(lvlInfo, format("note: currently hard linking saves %1%") % showBytes(freedbytes));
+ printMsg(lvlInfo, std::format("note: currently hard linking saves {}", showBytes(freedbytes)));
}
@@ -662,7 +659,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
/* Find the roots. Since we've grabbed the GC lock, the set of
permanent roots cannot increase now. */
- printMsg(lvlError, format("finding garbage collector roots..."));
+ printMsg(lvlError, "finding garbage collector roots...");
Roots rootMap = options.ignoreLiveness ? Roots() : findRoots();
for (auto& i : rootMap) state.roots.insert(i.second);
@@ -690,7 +687,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
createDirs(state.trashDir);
} catch (SysError & e) {
if (e.errNo == ENOSPC) {
- printMsg(lvlInfo, format("note: can't create trash directory: %1%") % e.msg());
+ printMsg(lvlInfo, std::format("note: can't create trash directory: {}", e.msg()));
state.moveToTrash = false;
}
}
@@ -705,20 +702,20 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
assertStorePath(i);
tryToDelete(state, i);
if (state.dead.find(i) == state.dead.end())
- throw Error(format("cannot delete path `%1%' since it is still alive") % i);
+ throw Error(std::format("cannot delete path `{}' since it is still alive", i));
}
} else if (options.maxFreed > 0) {
if (state.shouldDelete)
- printMsg(lvlError, format("deleting garbage..."));
+ printMsg(lvlError, "deleting garbage...");
else
- printMsg(lvlError, format("determining live/dead paths..."));
+ printMsg(lvlError, "determining live/dead paths...");
try {
AutoCloseDir dir = opendir(settings.nixStore.c_str());
- if (!dir) throw SysError(format("opening directory `%1%'") % settings.nixStore);
+ if (!dir) throw SysError(std::format("opening directory `{}'", settings.nixStore));
/* Read the store and immediately delete all paths that
aren't valid. When using --max-freed etc., deleting
@@ -773,12 +770,12 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
fds.clear();
/* Delete the trash directory. */
- printMsg(lvlInfo, format("deleting `%1%'") % state.trashDir);
+ printMsg(lvlInfo, std::format("deleting `{}'", state.trashDir));
deleteGarbage(state, state.trashDir);
/* Clean up the links directory. */
if (options.action == GCOptions::gcDeleteDead || options.action == GCOptions::gcDeleteSpecific) {
- printMsg(lvlError, format("deleting unused links..."));
+ printMsg(lvlError, "deleting unused links...");
removeUnusedLinks(state);
}
diff --git a/nix/libstore/globals.cc b/nix/libstore/globals.cc
index 31da8d4769..16f43f6abc 100644
--- a/nix/libstore/globals.cc
+++ b/nix/libstore/globals.cc
@@ -6,7 +6,7 @@
#include <map>
#include <algorithm>
-
+#include <format>
namespace nix {
@@ -156,8 +156,8 @@ void Settings::_get(bool & res, const string & name)
if (i == settings.end()) return;
if (i->second == "true") res = true;
else if (i->second == "false") res = false;
- else throw Error(format("configuration option `%1%' should be either `true' or `false', not `%2%'")
- % name % i->second);
+ else throw Error(std::format("configuration option `{}' should be either `true' or `false', not `{}'",
+ name, i->second));
}
@@ -183,7 +183,7 @@ template<class N> void Settings::_get(N & res, const string & name)
SettingsMap::iterator i = settings.find(name);
if (i == settings.end()) return;
if (!string2Int(i->second, res))
- throw Error(format("configuration setting `%1%' should have an integer value") % name);
+ throw Error(std::format("configuration setting `{}' should have an integer value", name));
}
diff --git a/nix/libstore/local-store.cc b/nix/libstore/local-store.cc
index 50ef707fdf..f11f48bcf0 100644
--- a/nix/libstore/local-store.cc
+++ b/nix/libstore/local-store.cc
@@ -9,7 +9,9 @@
#include <iostream>
#include <algorithm>
+#include <format>
#include <cstring>
+#include <cassert>
#include <sys/types.h>
#include <sys/stat.h>
@@ -45,12 +47,12 @@ void checkStoreNotSymlink()
struct stat st;
while (path != "/") {
if (lstat(path.c_str(), &st))
- throw SysError(format("getting status of `%1%'") % path);
+ throw SysError(std::format("getting status of `{}'", path));
if (S_ISLNK(st.st_mode))
- throw Error(format(
- "the path `%1%' is a symlink; "
- "this is not allowed for the store and its parent directories")
- % path);
+ throw Error(std::format(
+ "the path `{}' is a symlink; "
+ "this is not allowed for the store and its parent directories",
+ path));
path = dirOf(path);
}
}
@@ -86,25 +88,24 @@ LocalStore::LocalStore(bool reserveSpace)
if (getuid() == 0 && settings.buildUsersGroup != "") {
if (chmod(perUserDir.c_str(), 0755) == -1)
- throw SysError(format("could not set permissions on '%1%' to 755")
- % perUserDir);
+ throw SysError(std::format("could not set permissions on '{}' to 755", perUserDir));
mode_t perm = 01775;
struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
if (!gr)
- throw Error(format("the group `%1%' specified in `build-users-group' does not exist")
- % settings.buildUsersGroup);
+ throw Error(std::format("the group `{}' specified in `build-users-group' does not exist",
+ settings.buildUsersGroup));
else {
struct stat st;
if (stat(settings.nixStore.c_str(), &st))
- throw SysError(format("getting attributes of path '%1%'") % settings.nixStore);
+ throw SysError(std::format("getting attributes of path '{}'", settings.nixStore));
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
if (chown(settings.nixStore.c_str(), 0, gr->gr_gid) == -1)
- throw SysError(format("changing ownership of path '%1%'") % settings.nixStore);
+ throw SysError(std::format("changing ownership of path '{}'", settings.nixStore));
if (chmod(settings.nixStore.c_str(), perm) == -1)
- throw SysError(format("changing permissions on path '%1%'") % settings.nixStore);
+ throw SysError(std::format("changing permissions on path '{}'", settings.nixStore));
}
}
}
@@ -159,20 +160,20 @@ LocalStore::LocalStore(bool reserveSpace)
upgrade. */
int curSchema = getSchema();
if (curSchema > nixSchemaVersion)
- throw Error(format("current store schema is version %1%, but I only support %2%")
- % curSchema % nixSchemaVersion);
+ throw Error(std::format("current store schema is version {}, but I only support {}",
+ curSchema, nixSchemaVersion));
else if (curSchema == 0) { /* new store */
curSchema = nixSchemaVersion;
openDB(true);
- writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str());
+ writeFile(schemaPath, std::format("{}", nixSchemaVersion));
}
else if (curSchema < nixSchemaVersion) {
/* Guix always used version 7 of the schema. */
throw Error(
- format("Your store database uses an implausibly old schema, version %1%.")
- % curSchema);
+ std::format("Your store database uses an implausibly old schema, version {}.",
+ curSchema));
}
else openDB(false);
@@ -198,7 +199,7 @@ int LocalStore::getSchema()
if (pathExists(schemaPath)) {
string s = readFile(schemaPath);
if (!string2Int(s, curSchema))
- throw Error(format("`%1%' is corrupt") % schemaPath);
+ throw Error(std::format("`{}' is corrupt", schemaPath));
}
return curSchema;
}
@@ -207,13 +208,13 @@ int LocalStore::getSchema()
void LocalStore::openDB(bool create)
{
if (access(settings.nixDBPath.c_str(), R_OK | W_OK))
- throw SysError(format("store database directory `%1%' is not writable") % settings.nixDBPath);
+ throw SysError(std::format("store database directory `{}' is not writable", settings.nixDBPath));
/* Open the store database. */
string dbPath = settings.nixDBPath + "/db.sqlite";
if (sqlite3_open_v2(dbPath.c_str(), &db.db,
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
- throw Error(format("cannot open store database `%1%'") % dbPath);
+ throw Error(std::format("cannot open store database `{}'", dbPath));
if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
throwSQLiteError(db, "setting timeout");
@@ -317,7 +318,7 @@ void LocalStore::makeStoreWritable()
throw SysError("setting up a private mount namespace");
if (mount(0, settings.nixStore.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
- throw SysError(format("remounting %1% writable") % settings.nixStore);
+ throw SysError(std::format("remounting {} writable", settings.nixStore));
}
#endif
}
@@ -338,7 +339,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
| 0444
| (st.st_mode & S_IXUSR ? 0111 : 0);
if (chmod(path.c_str(), mode) == -1)
- throw SysError(format("changing mode of `%1%' to %2$o") % path % mode);
+ throw SysError(std::format("changing mode of `{}' to {:o}", path, mode));
}
}
@@ -356,7 +357,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
#else
if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)
#endif
- throw SysError(format("changing modification time of `%1%'") % path);
+ throw SysError(std::format("changing modification time of `{}'", path));
}
}
@@ -365,7 +366,7 @@ void canonicaliseTimestampAndPermissions(const Path & path)
{
struct stat st;
if (lstat(path.c_str(), &st))
- throw SysError(format("getting attributes of path `%1%'") % path);
+ throw SysError(std::format("getting attributes of path `{}'", path));
canonicaliseTimestampAndPermissions(path, st);
}
@@ -376,11 +377,11 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
struct stat st;
if (lstat(path.c_str(), &st))
- throw SysError(format("getting attributes of path `%1%'") % path);
+ throw SysError(std::format("getting attributes of path `{}'", path));
/* Really make sure that the path is of a supported type. */
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)))
- throw Error(format("file ‘%1%’ has an unsupported type") % path);
+ throw Error(std::format("file `{}' has an unsupported type", path));
/* Fail if the file is not owned by the build user. This prevents
us from messing up the ownership/permissions of files
@@ -391,7 +392,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
if (fromUid != (uid_t) -1 && st.st_uid != fromUid) {
assert(!S_ISDIR(st.st_mode));
if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end())
- throw BuildError(format("invalid ownership on file `%1%'") % path);
+ throw BuildError(std::format("invalid ownership on file `{}'", path));
mode_t mode = st.st_mode & ~S_IFMT;
assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore));
return;
@@ -415,8 +416,8 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
if (!S_ISLNK(st.st_mode) &&
chown(path.c_str(), geteuid(), getegid()) == -1)
#endif
- throw SysError(format("changing owner of `%1%' to %2%")
- % path % geteuid());
+ throw SysError(std::format("changing owner of `{}' to {}",
+ path, geteuid()));
}
if (S_ISDIR(st.st_mode)) {
@@ -435,11 +436,11 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & ino
be a symlink, since we can't change its ownership. */
struct stat st;
if (lstat(path.c_str(), &st))
- throw SysError(format("getting attributes of path `%1%'") % path);
+ throw SysError(std::format("getting attributes of path `{}'", path));
if (st.st_uid != geteuid()) {
assert(S_ISLNK(st.st_mode));
- throw Error(format("wrong ownership of top-level store path `%1%'") % path);
+ throw Error(std::format("wrong ownership of top-level store path `{}'", path));
}
}
@@ -460,7 +461,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
if (isFixedOutputDrv(drv)) {
DerivationOutputs::const_iterator out = drv.outputs.find("out");
if (out == drv.outputs.end())
- throw Error(format("derivation `%1%' does not have an output named `out'") % drvPath);
+ throw Error(std::format("derivation `{}' does not have an output named `out'", drvPath));
bool recursive; HashType ht; Hash h;
out->second.parseHashInfo(recursive, ht, h);
@@ -468,8 +469,8 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
StringPairs::const_iterator j = drv.env.find("out");
if (out->second.path != outPath || j == drv.env.end() || j->second != outPath)
- throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'")
- % drvPath % out->second.path % outPath);
+ throw Error(std::format("derivation `{}' has incorrect output `{}', should be `{}'",
+ drvPath, out->second.path, outPath));
}
else {
@@ -485,8 +486,8 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
Path outPath = makeOutputPath(i.first, h, drvName);
StringPairs::const_iterator j = drv.env.find(i.first);
if (i.second.path != outPath || j == drv.env.end() || j->second != outPath)
- throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'")
- % drvPath % i.second.path % outPath);
+ throw Error(std::format("derivation `{}' has incorrect output `{}', should be `{}'",
+ drvPath, i.second.path, outPath));
}
}
}
@@ -583,12 +584,12 @@ Hash parseHashField(const Path & path, const string & s)
{
string::size_type colon = s.find(':');
if (colon == string::npos)
- throw Error(format("corrupt hash `%1%' in valid-path entry for `%2%'")
- % s % path);
+ throw Error(std::format("corrupt hash `{}' in valid-path entry for `{}'",
+ s, path));
HashType ht = parseHashType(string(s, 0, colon));
if (ht == htUnknown)
- throw Error(format("unknown hash type `%1%' in valid-path entry for `%2%'")
- % string(s, 0, colon) % path);
+ throw Error(std::format("unknown hash type `{}' in valid-path entry for `{}'",
+ string(s, 0, colon), path));
return parseHash(ht, string(s, colon + 1));
}
@@ -606,7 +607,7 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path)
auto useQueryPathInfo(stmtQueryPathInfo.use()(path));
if (!useQueryPathInfo.next())
- throw Error(format("path `%1%' is not valid") % path);
+ throw Error(std::format("path `{}' is not valid", path));
info.id = useQueryPathInfo.getInt(0);
@@ -647,7 +648,7 @@ uint64_t LocalStore::queryValidPathId(const Path & path)
{
auto use(stmtQueryPathInfo.use()(path));
if (!use.next())
- throw Error(format("path ‘%1%’ is not valid") % path);
+ throw Error(std::format("path `%1%' is not valid", path));
return use.getInt(0);
}
@@ -809,8 +810,8 @@ string LocalStore::getLineFromSubstituter(Agent & run)
if (errno == EINTR) continue;
throw SysError("reading from substituter's stderr");
}
- if (n == 0) throw EndOfFile(format("`%1% substitute' died unexpectedly")
- % settings.guixProgram);
+ if (n == 0) throw EndOfFile(std::format("`{} substitute' died unexpectedly",
+ settings.guixProgram));
err.append(buf, n);
string::size_type p;
while (((p = err.find('\n')) != string::npos)
@@ -840,7 +841,7 @@ template<class T> T LocalStore::getIntLineFromSubstituter(Agent & run)
string s = getLineFromSubstituter(run);
T res;
if (!string2Int(s, res))
- throw Error(format("integer expected from stream: %1%") % s);
+ throw Error(std::format("integer expected from stream: {}", s));
return res;
}
@@ -897,7 +898,7 @@ void LocalStore::querySubstitutablePathInfos(PathSet & paths, SubstitutablePathI
Path path = getLineFromSubstituter(run);
if (path == "") break;
if (paths.find(path) == paths.end())
- throw Error(format("got unexpected path `%1%' from substituter") % path);
+ throw Error(std::format("got unexpected path `{}' from substituter", path));
paths.erase(path);
SubstitutablePathInfo & info(infos[path]);
info.deriver = getLineFromSubstituter(run);
@@ -990,7 +991,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
there are no referrers. */
void LocalStore::invalidatePath(const Path & path)
{
- debug(format("invalidating path `%1%'") % path);
+ debug(std::format("invalidating path `{}'", path));
drvHashes.erase(path);
@@ -1060,7 +1061,7 @@ Path LocalStore::addToStore(const string & name, const Path & _srcPath,
bool recursive, HashType hashAlgo, PathFilter & filter, bool repair)
{
Path srcPath(absPath(_srcPath));
- debug(format("adding `%1%' to the store") % srcPath);
+ debug(std::format("adding `{}' to the store", srcPath));
/* Read the whole path into memory. This is not a very scalable
method for very large paths, but `copyPath' is mainly used for
@@ -1139,9 +1140,9 @@ static void checkSecrecy(const Path & path)
{
struct stat st;
if (stat(path.c_str(), &st))
- throw SysError(format("getting status of `%1%'") % path);
+ throw SysError(std::format("getting status of `{}'", path));
if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0)
- throw Error(format("file `%1%' should be secret (inaccessible to everybody else)!") % path);
+ throw Error(std::format("file `{}' should be secret (inaccessible to everybody else)!", path));
}
@@ -1212,9 +1213,9 @@ static std::string signHash(const string &secretKey, const Hash &hash)
auto hexHash = printHash(hash);
writeLine(agent->toAgent.writeSide,
- (format("sign %1%:%2% %3%:%4%")
- % secretKey.size() % secretKey
- % hexHash.size() % hexHash).str());
+ std::format("sign {}:{} {}:{}",
+ secretKey.size(), secretKey,
+ hexHash.size(), hexHash));
return readAuthenticateReply(agent->fromAgent.readSide);
}
@@ -1226,8 +1227,7 @@ static std::string verifySignature(const string &signature)
auto agent = authenticationAgent();
writeLine(agent->toAgent.writeSide,
- (format("verify %1%:%2%")
- % signature.size() % signature).str());
+ std::format("verify {}:{}", signature.size(), signature));
return readAuthenticateReply(agent->fromAgent.readSide);
}
@@ -1237,10 +1237,10 @@ void LocalStore::exportPath(const Path & path, bool sign,
{
assertStorePath(path);
- printMsg(lvlInfo, format("exporting path `%1%'") % path);
+ printMsg(lvlInfo, std::format("exporting path `{}'", path));
if (!isValidPath(path))
- throw Error(format("path `%1%' is not valid") % path);
+ throw Error(std::format("path `{}' is not valid", path));
HashAndWriteSink hashAndWriteSink(sink);
@@ -1252,8 +1252,8 @@ void LocalStore::exportPath(const Path & path, bool sign,
Hash hash = hashAndWriteSink.currentHash();
Hash storedHash = queryPathHash(path);
if (hash != storedHash && storedHash != Hash(storedHash.type))
- throw Error(format("hash of path `%1%' has changed from `%2%' to `%3%'!") % path
- % printHash(storedHash) % printHash(hash));
+ throw Error(std::format("hash of path `{}' has changed from `{}' to `{}'!",
+ path, printHash(storedHash), printHash(hash)));
writeInt(EXPORT_MAGIC, hashAndWriteSink);
@@ -1347,7 +1347,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
bool haveSignature = readInt(hashAndReadSource) == 1;
if (requireSignature && !haveSignature)
- throw Error(format("imported archive of `%1%' lacks a signature") % dstPath);
+ throw Error(std::format("imported archive of `{}' lacks a signature", dstPath));
if (haveSignature) {
string signature = readString(hashAndReadSource);
@@ -1387,8 +1387,8 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
if (pathExists(dstPath)) deletePath(dstPath);
if (rename(unpacked.c_str(), dstPath.c_str()) == -1)
- throw SysError(format("cannot move `%1%' to `%2%'")
- % unpacked % dstPath);
+ throw SysError(std::format("cannot move `{}' to `{}'",
+ unpacked, dstPath));
canonicalisePathMetaData(dstPath, -1);
@@ -1438,8 +1438,8 @@ void LocalStore::invalidatePathChecked(const Path & path)
PathSet referrers; queryReferrers_(path, referrers);
referrers.erase(path); /* ignore self-references */
if (!referrers.empty())
- throw PathInUse(format("cannot delete path `%1%' because it is in use by %2%")
- % path % showPaths(referrers));
+ throw PathInUse(std::format("cannot delete path `{}' because it is in use by {}",
+ path, showPaths(referrers)));
invalidatePath(path);
}
@@ -1450,7 +1450,7 @@ void LocalStore::invalidatePathChecked(const Path & path)
bool LocalStore::verifyStore(bool checkContents, bool repair)
{
- printMsg(lvlError, format("reading the store..."));
+ printMsg(lvlError, "reading the store...");
bool errors = false;
@@ -1483,13 +1483,13 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
ValidPathInfo info = queryPathInfo(i);
/* Check the content hash (optionally - slow). */
- printMsg(lvlTalkative, format("checking contents of `%1%'") % i);
+ printMsg(lvlTalkative, std::format("checking contents of `{}'", i));
HashResult current = hashPath(info.hash.type, i);
if (info.hash != nullHash && info.hash != current.first) {
- printMsg(lvlError, format("path `%1%' was modified! "
- "expected hash `%2%', got `%3%'")
- % i % printHash(info.hash) % printHash(current.first));
+ printMsg(lvlError, std::format("path `{}' was modified! "
+ "expected hash `{}', got `{}'",
+ i, printHash(info.hash), printHash(current.first)));
if (repair) repairPath(i); else errors = true;
} else {
@@ -1497,14 +1497,14 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
/* Fill in missing hashes. */
if (info.hash == nullHash) {
- printMsg(lvlError, format("fixing missing hash on `%1%'") % i);
+ printMsg(lvlError, std::format("fixing missing hash on `{}'", i));
info.hash = current.first;
update = true;
}
/* Fill in missing narSize fields (from old stores). */
if (info.narSize == 0) {
- printMsg(lvlError, format("updating size field on `%1%' to %2%") % i % current.second);
+ printMsg(lvlError, std::format("updating size field on `{}' to {}", i, current.second));
info.narSize = current.second;
update = true;
}
@@ -1517,9 +1517,9 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
/* It's possible that the path got GC'ed, so ignore
errors on invalid paths. */
if (isValidPath(i))
- printMsg(lvlError, format("error: %1%") % e.msg());
+ printMsg(lvlError, std::format("error: {}", e.msg()));
else
- printMsg(lvlError, format("warning: %1%") % e.msg());
+ printMsg(lvlError, std::format("warning: {}", e.msg()));
errors = true;
}
}
@@ -1538,7 +1538,7 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
done.insert(path);
if (!isStorePath(path)) {
- printMsg(lvlError, format("path `%1%' is not in the store") % path);
+ printMsg(lvlError, std::format("path `{}' is not in the store", path));
invalidatePath(path);
return;
}
@@ -1556,15 +1556,15 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
}
if (canInvalidate) {
- printMsg(lvlError, format("path `%1%' disappeared, removing from database...") % path);
+ printMsg(lvlError, std::format("path `{}' disappeared, removing from database...", path));
invalidatePath(path);
} else {
- printMsg(lvlError, format("path `%1%' disappeared, but it still has valid referrers!") % path);
+ printMsg(lvlError, std::format("path `{}' disappeared, but it still has valid referrers!", path));
if (repair)
try {
repairPath(path);
} catch (Error & e) {
- printMsg(lvlError, format("warning: %1%") % e.msg());
+ printMsg(lvlError, std::format("warning: {}", e.msg()));
errors = true;
}
else errors = true;
@@ -1581,7 +1581,7 @@ bool LocalStore::pathContentsGood(const Path & path)
{
std::map<Path, bool>::iterator i = pathContentsGoodCache.find(path);
if (i != pathContentsGoodCache.end()) return i->second;
- printMsg(lvlInfo, format("checking path `%1%'...") % path);
+ printMsg(lvlInfo, std::format("checking path `{}'...", path));
ValidPathInfo info = queryPathInfo(path);
bool res;
if (!pathExists(path))
@@ -1592,7 +1592,7 @@ bool LocalStore::pathContentsGood(const Path & path)
res = info.hash == nullHash || info.hash == current.first;
}
pathContentsGoodCache[path] = res;
- if (!res) printMsg(lvlError, format("path `%1%' is corrupted or missing!") % path);
+ if (!res) printMsg(lvlError, std::format("path `{}' is corrupted or missing!", path));
return res;
}
@@ -1617,14 +1617,14 @@ void LocalStore::createUser(const std::string & userName, uid_t userId)
auto created = createDirs(dir);
if (!created.empty()) {
if (chmod(dir.c_str(), 0755) == -1)
- throw SysError(format("changing permissions of directory '%s'") % dir);
+ throw SysError(std::format("changing permissions of directory '{}'", dir));
/* The following operation requires CAP_CHOWN or can be handled
manually by a user with CAP_CHOWN. */
if (chown(dir.c_str(), userId, -1) == -1) {
rmdir(dir.c_str());
string message = strerror(errno);
- printMsg(lvlInfo, format("failed to change owner of directory '%1%' to %2%: %3%") % dir % userId % message);
+ printMsg(lvlInfo, std::format("failed to change owner of directory '{}' to {}: {}", dir, userId, message));
}
}
}
diff --git a/nix/libstore/misc.cc b/nix/libstore/misc.cc
index e9904f3c4f..943fb9c971 100644
--- a/nix/libstore/misc.cc
+++ b/nix/libstore/misc.cc
@@ -4,6 +4,7 @@
#include "local-store.hh"
#include "globals.hh"
+#include <format>
namespace nix {
@@ -65,7 +66,7 @@ static void dfsVisit(StoreAPI & store, const PathSet & paths,
PathSet & parents)
{
if (parents.find(path) != parents.end())
- throw BuildError(format("cycle detected in the references of `%1%'") % path);
+ throw BuildError(std::format("cycle detected in the references of `{}'", path));
if (visited.find(path) != visited.end()) return;
visited.insert(path);
@@ -99,19 +100,19 @@ Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
string showBytes(long long bytes)
{
if (llabs(bytes > exp2l(60))) {
- return (format("%7.2f EiB") % (bytes / exp2l(60))).str();
+ return std::format("{:7.2f} EiB", bytes / exp2l(60));
} else if (llabs(bytes > exp2l(50))) {
- return (format("%7.2f PiB") % (bytes / exp2l(50))).str();
+ return std::format("{:7.2f} PiB", bytes / exp2l(50));
} else if (llabs(bytes > exp2l(40))) {
- return (format("%7.2f TiB") % (bytes / exp2l(40))).str();
+ return std::format("{:7.2f} TiB", bytes / exp2l(40));
} else if (llabs(bytes > exp2l(30))) {
- return (format("%7.2f GiB") % (bytes / exp2l(30))).str();
+ return std::format("{:7.2f} GiB", bytes / exp2l(30));
} else if (llabs(bytes > exp2l(20))) {
- return (format("%7.2f MiB") % (bytes / exp2l(20))).str();
+ return std::format("{:7.2f} MiB", bytes / exp2l(20));
} else if (llabs(bytes > exp2l(10))) {
- return (format("%7.2f KiB") % (bytes / exp2l(10))).str();
+ return std::format("{:7.2f} KiB", bytes / exp2l(10));
} else {
- return (format("%4f bytes") % bytes).str();
+ return std::format("{:4} bytes", bytes);
}
}
diff --git a/nix/libstore/optimise-store.cc b/nix/libstore/optimise-store.cc
index e17d9160d6..d69c43e997 100644
--- a/nix/libstore/optimise-store.cc
+++ b/nix/libstore/optimise-store.cc
@@ -12,7 +12,7 @@
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
-
+#include <format>
namespace nix {
@@ -24,9 +24,9 @@ static void makeWritable(const Path & path)
{
struct stat st;
if (lstat(path.c_str(), &st))
- throw SysError(format("getting attributes of path `%1%'") % path);
+ throw SysError(std::format("getting attributes of path `{}'", path));
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
- throw SysError(format("changing writability of `%1%'") % path);
+ throw SysError(std::format("changing writability of `{}'", path));
}
@@ -52,7 +52,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
InodeHash inodeHash;
AutoCloseDir dir = opendir(linksDir.c_str());
- if (!dir) throw SysError(format("opening directory `%1%'") % linksDir);
+ if (!dir) throw SysError(std::format("opening directory `{}'", linksDir));
struct dirent * dirent;
while (errno = 0, dirent = readdir(dir)) { /* sic */
@@ -60,9 +60,9 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
// We don't care if we hit non-hash files, anything goes
inodeHash.insert(dirent->d_ino);
}
- if (errno) throw SysError(format("reading directory `%1%'") % linksDir);
+ if (errno) throw SysError(std::format("reading directory `{}'", linksDir));
- printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size());
+ printMsg(lvlTalkative, std::format("loaded {} hash inodes", inodeHash.size()));
return inodeHash;
}
@@ -73,14 +73,14 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
Strings names;
AutoCloseDir dir = opendir(path.c_str());
- if (!dir) throw SysError(format("opening directory `%1%'") % path);
+ if (!dir) throw SysError(std::format("opening directory `{}'", path));
struct dirent * dirent;
while (errno = 0, dirent = readdir(dir)) { /* sic */
checkInterrupt();
if (inodeHash.count(dirent->d_ino)) {
- printMsg(lvlDebug, format("`%1%' is already linked") % dirent->d_name);
+ printMsg(lvlDebug, std::format("`{}' is already linked", dirent->d_name));
continue;
}
@@ -88,7 +88,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
if (name == "." || name == "..") continue;
names.push_back(name);
}
- if (errno) throw SysError(format("reading directory `%1%'") % path);
+ if (errno) throw SysError(std::format("reading directory `{}'", path));
return names;
}
@@ -100,7 +100,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
struct stat st;
if (lstat(path.c_str(), &st))
- throw SysError(format("getting attributes of path `%1%'") % path);
+ throw SysError(std::format("getting attributes of path `{}'", path));
if (S_ISDIR(st.st_mode)) {
Strings names = readDirectoryIgnoringInodes(path, inodeHash);
@@ -121,13 +121,13 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
Guix System (example: $fontconfig/var/cache being modified). Skip
those files. FIXME: check the modification time. */
if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) {
- printMsg(lvlError, format("skipping suspicious writable file `%1%'") % path);
+ printMsg(lvlError, std::format("skipping suspicious writable file `{}'", path));
return;
}
/* This can still happen on top-level files. */
if (st.st_nlink > 1 && inodeHash.count(st.st_ino)) {
- printMsg(lvlDebug, format("`%1%' is already linked, with %2% other file(s).") % path % (st.st_nlink - 2));
+ printMsg(lvlDebug, std::format("`{}' is already linked, with {} other file(s).", path, (st.st_nlink - 2)));
return;
}
@@ -141,7 +141,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
contents of the symlink (i.e. the result of readlink()), not
the contents of the target (which may not even exist). */
Hash hash = hashPath(htSHA256, path).first;
- printMsg(lvlDebug, format("`%1%' has hash `%2%'") % path % printHash(hash));
+ printMsg(lvlDebug, std::format("`{}' has hash `{}'", path, printHash(hash)));
/* Check if this is a known hash. */
Path linkPath = linksDir + "/" + printHash32(hash);
@@ -164,12 +164,12 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
/* On ext4, that probably means the directory index is full. When
that happens, it's fine to ignore it: we just effectively
disable deduplication of this file. */
- printMsg(lvlInfo, format("cannot link `%1%' to `%2%': %3%")
- % linkPath % path % strerror(ENOSPC));
+ printMsg(lvlInfo, std::format("cannot link `{}' to `{}': {}",
+ linkPath, path, strerror(ENOSPC)));
return;
default:
- throw SysError(format("cannot link `%1%' to `%2%'") % linkPath % path);
+ throw SysError(std::format("cannot link `{}' to `{}'", linkPath, path));
}
}
@@ -177,20 +177,20 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
current file with a hard link to that file. */
struct stat stLink;
if (lstat(linkPath.c_str(), &stLink))
- throw SysError(format("getting attributes of path `%1%'") % linkPath);
+ throw SysError(std::format("getting attributes of path `{}'", linkPath));
if (st.st_ino == stLink.st_ino) {
- printMsg(lvlDebug, format("`%1%' is already linked to `%2%'") % path % linkPath);
+ printMsg(lvlDebug, std::format("`{}' is already linked to `{}'", path, linkPath));
return;
}
if (st.st_size != stLink.st_size) {
- printMsg(lvlError, format("removing corrupted link ‘%1%’") % linkPath);
+ printMsg(lvlError, std::format("removing corrupted link `%1%'", linkPath));
unlink(linkPath.c_str());
goto retry;
}
- printMsg(lvlTalkative, format("linking ‘%1%’ to ‘%2%’") % path % linkPath);
+ printMsg(lvlTalkative, std::format("linking `%1%' to `%2%'", path, linkPath));
/* Make the containing directory writable, but only if it's not
the store itself (we don't want or need to mess with its
@@ -202,8 +202,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
its timestamp back to 0. */
MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : "");
- Path tempLink = (format("%1%/.tmp-link-%2%-%3%")
- % settings.nixStore % getpid() % rand()).str();
+ Path tempLink = std::format("{}/.tmp-link-{}-{}", settings.nixStore, getpid(), rand());
if (link(linkPath.c_str(), tempLink.c_str()) == -1) {
if (errno == EMLINK) {
@@ -211,27 +210,27 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
systems). This is likely to happen with empty files.
Just shrug and ignore. */
if (st.st_size)
- printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath);
+ printMsg(lvlInfo, std::format("`{}' has maximum number of links", linkPath));
return;
}
- throw SysError(format("cannot link `%1%' to `%2%'") % tempLink % linkPath);
+ throw SysError(std::format("cannot link `{}' to `{}'", tempLink, linkPath));
}
/* Atomically replace the old file with the new hard link. */
if (rename(tempLink.c_str(), path.c_str()) == -1) {
int renameErrno = errno;
if (unlink(tempLink.c_str()) == -1)
- printMsg(lvlError, format("unable to unlink `%1%'") % tempLink);
+ printMsg(lvlError, std::format("unable to unlink `{}'", tempLink));
if (renameErrno == EMLINK) {
/* Some filesystems generate too many links on the rename,
rather than on the original link. (Probably it
temporarily increases the st_nlink field before
decreasing it again.) */
if (st.st_size)
- printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath);
+ printMsg(lvlInfo, std::format("`{}' has maximum number of links", linkPath));
return;
}
- throw SysError(format("cannot rename `%1%' to `%2%'") % tempLink % path);
+ throw SysError(std::format("cannot rename `{}' to `{}'", tempLink, path));
}
stats.filesLinked++;
@@ -248,7 +247,7 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
for (auto& i : paths) {
addTempRoot(i);
if (!isValidPath(i)) continue; /* path was GC'ed, probably */
- startNest(nest, lvlChatty, format("hashing files in `%1%'") % i);
+ startNest(nest, lvlChatty, std::format("hashing files in `{}'", i));
optimisePath_(stats, i, inodeHash);
}
}
@@ -260,9 +259,9 @@ void LocalStore::optimiseStore()
optimiseStore(stats);
printMsg(lvlError,
- format("%1% freed by hard-linking %2% files")
- % showBytes(stats.bytesFreed)
- % stats.filesLinked);
+ std::format("{} freed by hard-linking {} files",
+ showBytes(stats.bytesFreed),
+ stats.filesLinked));
}
void LocalStore::optimisePath(const Path & path)
diff --git a/nix/libstore/pathlocks.cc b/nix/libstore/pathlocks.cc
index c07f047192..ce4671e209 100644
--- a/nix/libstore/pathlocks.cc
+++ b/nix/libstore/pathlocks.cc
@@ -3,6 +3,8 @@
#include <cerrno>
#include <cstdlib>
+#include <cassert>
+#include <format>
#include <sys/types.h>
#include <sys/stat.h>
@@ -18,7 +20,7 @@ int openLockFile(const Path & path, bool create)
fd = open(path.c_str(), O_RDWR | (create ? O_CREAT : 0), 0600);
if (fd == -1 && (create || errno != ENOENT))
- throw SysError(format("opening lock file `%1%'") % path);
+ throw SysError(std::format("opening lock file `{}'", path));
closeOnExec(fd);
@@ -54,14 +56,14 @@ bool lockFile(int fd, LockType lockType, bool wait)
while (fcntl(fd, F_SETLKW, &lock) != 0) {
checkInterrupt();
if (errno != EINTR)
- throw SysError(format("acquiring/releasing lock"));
+ throw SysError("acquiring/releasing lock");
}
} else {
while (fcntl(fd, F_SETLK, &lock) != 0) {
checkInterrupt();
if (errno == EACCES || errno == EAGAIN) return false;
if (errno != EINTR)
- throw SysError(format("acquiring/releasing lock"));
+ throw SysError("acquiring/releasing lock");
}
}
@@ -109,7 +111,7 @@ bool PathLocks::lockPaths(const PathSet & _paths,
Path path = i;
Path lockPath = path + ".lock";
- debug(format("locking path `%1%'") % path);
+ debug(std::format("locking path `{}'", path));
if (lockedPaths.find(lockPath) != lockedPaths.end())
throw Error("deadlock: trying to re-acquire self-held lock");
@@ -134,19 +136,19 @@ bool PathLocks::lockPaths(const PathSet & _paths,
}
}
- debug(format("lock acquired on `%1%'") % lockPath);
+ debug(std::format("lock acquired on `{}'", lockPath));
/* Check that the lock file hasn't become stale (i.e.,
hasn't been unlinked). */
struct stat st;
if (fstat(fd, &st) == -1)
- throw SysError(format("statting lock file `%1%'") % lockPath);
+ throw SysError(std::format("statting lock file `{}'", lockPath));
if (st.st_size != 0)
/* This lock file has been unlinked, so we're holding
a lock on a deleted file. This means that other
processes may create and acquire a lock on
`lockPath', and proceed. So we must retry. */
- debug(format("open lock file `%1%' has become stale") % lockPath);
+ debug(std::format("open lock file `{}' has become stale", lockPath));
else
break;
}
@@ -178,9 +180,9 @@ void PathLocks::unlock()
lockedPaths.erase(i.second);
if (close(i.first) == -1)
printMsg(lvlError,
- format("error (ignored): cannot close lock file on `%1%'") % i.second);
+ std::format("error (ignored): cannot close lock file on `{}'", i.second));
- debug(format("lock released on `%1%'") % i.second);
+ debug(std::format("lock released on `{}'", i.second));
}
fds.clear();
diff --git a/nix/libstore/references.cc b/nix/libstore/references.cc
index d9c8a9fbe3..a8ec39ee34 100644
--- a/nix/libstore/references.cc
+++ b/nix/libstore/references.cc
@@ -5,7 +5,8 @@
#include <map>
#include <cstdlib>
-
+#include <cassert>
+#include <format>
namespace nix {
@@ -37,8 +38,7 @@ static void search(const unsigned char * s, unsigned int len,
if (!match) continue;
string ref((const char *) s + i, refLength);
if (hashes.find(ref) != hashes.end()) {
- debug(format("found reference to `%1%' at offset `%2%'")
- % ref % i);
+ debug(std::format("found reference to `{}' at offset `{}'", ref, i));
seen.insert(ref);
hashes.erase(ref);
}
@@ -93,7 +93,7 @@ PathSet scanForReferences(const string & path,
string baseName = baseNameOf(i);
string::size_type pos = baseName.find('-');
if (pos == string::npos)
- throw Error(format("bad reference `%1%'") % i);
+ throw Error(std::format("bad reference `{}'", i));
string s = string(baseName, 0, pos);
assert(s.size() == refLength);
assert(backMap.find(s) == backMap.end());
diff --git a/nix/libstore/sqlite.cc b/nix/libstore/sqlite.cc
index e08c67f40e..cbd768155e 100644
--- a/nix/libstore/sqlite.cc
+++ b/nix/libstore/sqlite.cc
@@ -1,11 +1,14 @@
#include "sqlite.hh"
#include "util.hh"
+#include <format>
+#include <cassert>
+
#include <sqlite3.h>
namespace nix {
-[[noreturn]] void throwSQLiteError(sqlite3 * db, const format & f)
+[[noreturn]] void throwSQLiteError(sqlite3 * db, std::string_view f)
{
int err = sqlite3_errcode(db);
if (err == SQLITE_BUSY || err == SQLITE_PROTOCOL) {
@@ -28,10 +31,10 @@ namespace nix {
#else
sleep(1);
#endif
- throw SQLiteBusy(format("%1%: %2%") % f.str() % sqlite3_errmsg(db));
+ throw SQLiteBusy(std::format("{}: {}", f, sqlite3_errmsg(db)));
}
else
- throw SQLiteError(format("%1%: %2%") % f.str() % sqlite3_errmsg(db));
+ throw SQLiteError(std::format("{}: {}", f, sqlite3_errmsg(db)));
}
SQLite::~SQLite()
diff --git a/nix/libstore/sqlite.hh b/nix/libstore/sqlite.hh
index 6cadba6849..0c0bc9e6f5 100644
--- a/nix/libstore/sqlite.hh
+++ b/nix/libstore/sqlite.hh
@@ -3,6 +3,7 @@
#include <functional>
#include <string>
#include <cstdint>
+#include <string_view>
#include "types.hh"
@@ -85,7 +86,7 @@ struct SQLiteTxn
MakeError(SQLiteError, Error);
MakeError(SQLiteBusy, SQLiteError);
-[[noreturn]] void throwSQLiteError(sqlite3 * db, const format & f);
+[[noreturn]] void throwSQLiteError(sqlite3 * db, std::string_view f);
/* Convenience function for retrying a SQLite transaction when the
database is busy. */
diff --git a/nix/libstore/store-api.cc b/nix/libstore/store-api.cc
index 7282188fb3..0596678b8b 100644
--- a/nix/libstore/store-api.cc
+++ b/nix/libstore/store-api.cc
@@ -3,7 +3,7 @@
#include "util.hh"
#include <climits>
-
+#include <format>
namespace nix {
@@ -32,14 +32,14 @@ bool isStorePath(const Path & path)
void assertStorePath(const Path & path)
{
if (!isStorePath(path))
- throw Error(format("path `%1%' is not in the store") % path);
+ throw Error(std::format("path `{}' is not in the store", path));
}
Path toStorePath(const Path & path)
{
if (!isInStore(path))
- throw Error(format("path `%1%' is not in the store") % path);
+ throw Error(std::format("path `{}' is not in the store", path));
Path::size_type slash = path.find('/', settings.nixStore.size() + 1);
if (slash == Path::npos)
return path;
@@ -61,15 +61,14 @@ void checkStoreName(const string & name)
/* Disallow names starting with a dot for possible security
reasons (e.g., "." and ".."). */
if (string(name, 0, 1) == ".")
- throw Error(format("invalid name: `%1%' (can't begin with dot)") % name);
+ throw Error(std::format("invalid name: `{}' (can't begin with dot)", name));
for (const auto& i : name)
if (!((i >= 'A' && i <= 'Z') ||
(i >= 'a' && i <= 'z') ||
(i >= '0' && i <= '9') ||
validChars.find(i) != string::npos))
{
- throw Error(format("invalid character `%1%' in name `%2%'")
- % i % name);
+ throw Error(std::format("invalid character `{}' in name `{}'", i, name));
}
}
@@ -211,13 +210,13 @@ string StoreAPI::makeValidityRegistration(const PathSet & paths,
if (showHash) {
s += printHash(info.hash) + "\n";
- s += (format("%1%\n") % info.narSize).str();
+ s += std::format("{}\n", info.narSize);
}
Path deriver = showDerivers ? info.deriver : "";
s += deriver + "\n";
- s += (format("%1%\n") % info.references.size()).str();
+ s += std::format("{}\n", info.references.size());
for (auto& j : info.references)
s += j + "\n";