aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJade Lovelace <lix@jade.fyi>2024-03-17 19:14:18 -0700
committerJade Lovelace <lix@jade.fyi>2024-03-17 20:17:19 -0700
commit61e21b25576f7f3491f6a837bf59d8b44c6897a0 (patch)
tree3f62d83b3bab84afcf1011b5c2353226b84313b3
parent706cee5c493b39e25bdb0add55d2e1771dc31696 (diff)
Delete hasPrefix and hasSuffix from the codebase
These now have equivalents in the standard lib in C++20. This change was performed with a custom clang-tidy check which I will submit later. Executed like so: ninja -C build && run-clang-tidy -checks='-*,nix-*' -load=build/libnix-clang-tidy.so -p .. -fix ../tests | tee -a clang-tidy-result Change-Id: I62679e315ff9e7ce72a40b91b79c3e9fc01b27e9
-rw-r--r--src/libcmd/common-eval-args.cc2
-rw-r--r--src/libcmd/installables.cc12
-rw-r--r--src/libcmd/repl.cc2
-rw-r--r--src/libexpr/eval-settings.cc4
-rw-r--r--src/libexpr/eval.cc16
-rw-r--r--src/libexpr/flake/config.cc2
-rw-r--r--src/libexpr/flake/flakeref.cc2
-rw-r--r--src/libfetchers/git.cc6
-rw-r--r--src/libfetchers/mercurial.cc4
-rw-r--r--src/libfetchers/registry.cc2
-rw-r--r--src/libfetchers/tarball.cc8
-rw-r--r--src/libmain/common-args.cc2
-rw-r--r--src/libmain/progress-bar.cc6
-rw-r--r--src/libstore/build/local-derivation-goal.cc2
-rw-r--r--src/libstore/builtins/buildenv.cc14
-rw-r--r--src/libstore/builtins/fetchurl.cc4
-rw-r--r--src/libstore/daemon.cc2
-rw-r--r--src/libstore/derivations.cc4
-rw-r--r--src/libstore/filetransfer.cc6
-rw-r--r--src/libstore/globals.cc4
-rw-r--r--src/libstore/http-binary-cache-store.cc2
-rw-r--r--src/libstore/local-binary-cache-store.cc2
-rw-r--r--src/libstore/machines.cc12
-rw-r--r--src/libstore/path.cc2
-rw-r--r--src/libstore/s3-binary-cache-store.cc12
-rw-r--r--src/libstore/ssh.cc2
-rw-r--r--src/libutil/args.cc6
-rw-r--r--src/libutil/cgroup.cc6
-rw-r--r--src/libutil/config.cc2
-rw-r--r--src/libutil/logging.cc2
-rw-r--r--src/libutil/source-path.cc2
-rw-r--r--src/libutil/split.hh2
-rw-r--r--src/libutil/util.cc13
-rw-r--r--src/libutil/util.hh13
-rw-r--r--src/nix-build/nix-build.cc2
-rw-r--r--src/nix-channel/nix-channel.cc2
-rw-r--r--src/nix-env/nix-env.cc6
-rw-r--r--src/nix/develop.cc2
-rw-r--r--src/nix/doctor.cc2
-rw-r--r--src/nix/flake.cc2
-rw-r--r--src/nix/prefetch.cc2
-rw-r--r--src/nix/upgrade-nix.cc4
-rw-r--r--src/resolve-system-dependencies/resolve-system-dependencies.cc4
-rw-r--r--tests/unit/libutil/tests.cc30
44 files changed, 91 insertions, 147 deletions
diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc
index e36bda52f..07161cba9 100644
--- a/src/libcmd/common-eval-args.cc
+++ b/src/libcmd/common-eval-args.cc
@@ -172,7 +172,7 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s)
return state.rootPath(CanonPath(state.store->toRealPath(storePath)));
}
- else if (hasPrefix(s, "flake:")) {
+ else if (s.starts_with("flake:")) {
experimentalFeatureSettings.require(Xp::Flakes);
auto flakeRef = parseFlakeRef(std::string(s.substr(6)), {}, true, false);
auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first.storePath;
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index f40136411..973db62b0 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -159,7 +159,7 @@ void MixFlakeOptions::completeFlakeInput(std::string_view prefix)
auto flakeRef = parseFlakeRefWithFragment(expandTilde(flakeRefS), absPath(".")).first;
auto flake = flake::getFlake(*evalState, flakeRef, true);
for (auto & input : flake.inputs)
- if (hasPrefix(input.first, prefix))
+ if (input.first.starts_with(prefix))
completions->add(input.first);
}
}
@@ -320,7 +320,7 @@ void completeFlakeRefWithFragment(
auto attrPath = parseAttrPath(*evalState, attrPathS);
std::string lastAttr;
- if (!attrPath.empty() && !hasSuffix(attrPathS, ".")) {
+ if (!attrPath.empty() && !attrPathS.ends_with(".")) {
lastAttr = evalState->symbols[attrPath.back()];
attrPath.pop_back();
}
@@ -329,7 +329,7 @@ void completeFlakeRefWithFragment(
if (!attr) continue;
for (auto & attr2 : (*attr)->getAttrs()) {
- if (hasPrefix(evalState->symbols[attr2], lastAttr)) {
+ if (std::string_view(evalState->symbols[attr2]).starts_with(lastAttr)) {
auto attrPath2 = (*attr)->getAttrPath(attr2);
/* Strip the attrpath prefix. */
attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
@@ -367,12 +367,12 @@ void completeFlakeRef(ref<Store> store, std::string_view prefix)
for (auto & registry : fetchers::getRegistries(store)) {
for (auto & entry : registry->entries) {
auto from = entry.from.to_string();
- if (!hasPrefix(prefix, "flake:") && hasPrefix(from, "flake:")) {
+ if (!prefix.starts_with("flake:") && from.starts_with("flake:")) {
std::string from2(from, 6);
- if (hasPrefix(from2, prefix))
+ if (from2.starts_with(prefix))
completions->add(from2);
} else {
- if (hasPrefix(from, prefix))
+ if (from.starts_with(prefix))
completions->add(from);
}
}
diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc
index 9e5599152..f5738963e 100644
--- a/src/libcmd/repl.cc
+++ b/src/libcmd/repl.cc
@@ -272,7 +272,7 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
auto dir = std::string(cur, 0, slash);
auto prefix2 = std::string(cur, slash + 1);
for (auto & entry : readDirectory(dir == "" ? "/" : dir)) {
- if (entry.name[0] != '.' && hasPrefix(entry.name, prefix2))
+ if (entry.name[0] != '.' && entry.name.starts_with(prefix2))
completions.insert(prev + dir + "/" + entry.name);
}
} catch (Error &) {
diff --git a/src/libexpr/eval-settings.cc b/src/libexpr/eval-settings.cc
index 89ca198d8..046ca557d 100644
--- a/src/libexpr/eval-settings.cc
+++ b/src/libexpr/eval-settings.cc
@@ -29,7 +29,7 @@ static Strings parseNixPath(const std::string & s)
if (*p == ':') {
auto prefix = std::string(start2, s.end());
- if (EvalSettings::isPseudoUrl(prefix) || hasPrefix(prefix, "flake:")) {
+ if (EvalSettings::isPseudoUrl(prefix) || prefix.starts_with("flake:")) {
++p;
while (p != s.end() && *p != ':') ++p;
}
@@ -82,7 +82,7 @@ bool EvalSettings::isPseudoUrl(std::string_view s)
std::string EvalSettings::resolvePseudoUrl(std::string_view url)
{
- if (hasPrefix(url, "channel:"))
+ if (url.starts_with("channel:"))
return "https://nixos.org/channels/" + std::string(url.substr(8)) + "/nixexprs.tar.xz";
else
return std::string(url);
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 1739a04fa..d88f4f84b 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -484,7 +484,7 @@ SourcePath EvalState::checkSourcePath(const SourcePath & path_)
*/
Path abspath = canonPath(path_.path.abs());
- if (hasPrefix(abspath, corepkgsPrefix)) return CanonPath(abspath);
+ if (abspath.starts_with(corepkgsPrefix)) return CanonPath(abspath);
for (auto & i : *allowedPaths) {
if (isDirOrInDir(abspath, i)) {
@@ -527,18 +527,18 @@ void EvalState::checkURI(const std::string & uri)
if (uri == prefix ||
(uri.size() > prefix.size()
&& prefix.size() > 0
- && hasPrefix(uri, prefix)
+ && uri.starts_with(prefix)
&& (prefix[prefix.size() - 1] == '/' || uri[prefix.size()] == '/')))
return;
/* If the URI is a path, then check it against allowedPaths as
well. */
- if (hasPrefix(uri, "/")) {
+ if (uri.starts_with("/")) {
checkSourcePath(CanonPath(uri));
return;
}
- if (hasPrefix(uri, "file://")) {
+ if (uri.starts_with("file://")) {
checkSourcePath(CanonPath(std::string(uri, 7)));
return;
}
@@ -642,7 +642,7 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
}
auto envName = symbols.create(primOp.name);
- if (hasPrefix(primOp.name, "__"))
+ if (primOp.name.starts_with("__"))
primOp.name = primOp.name.substr(2);
Value * v = allocValue();
@@ -719,7 +719,7 @@ void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env &
// for the top level, don't print the double underscore ones;
// they are in builtins.
for (auto & i : se.vars)
- if (!hasPrefix(st[i.first], "__"))
+ if (!std::string_view(st[i.first]).starts_with("__"))
std::cout << st[i.first] << " ";
std::cout << ANSI_NORMAL;
std::cout << std::endl;
@@ -2790,7 +2790,7 @@ SourcePath EvalState::findFile(const SearchPath & searchPath, const std::string_
if (pathExists(res)) return CanonPath(canonPath(res));
}
- if (hasPrefix(path, "nix/"))
+ if (path.starts_with("nix/"))
return CanonPath(concatStrings(corepkgsPrefix, path.substr(4)));
error<ThrownError>(
@@ -2823,7 +2823,7 @@ std::optional<std::string> EvalState::resolveSearchPathPath(const SearchPath::Pa
}
}
- else if (hasPrefix(value, "flake:")) {
+ else if (value.starts_with("flake:")) {
experimentalFeatureSettings.require(Xp::Flakes);
auto flakeRef = parseFlakeRef(value.substr(6), {}, true, false);
debug("fetching flake search path element '%s''", value);
diff --git a/src/libexpr/flake/config.cc b/src/libexpr/flake/config.cc
index e89014862..b9613462a 100644
--- a/src/libexpr/flake/config.cc
+++ b/src/libexpr/flake/config.cc
@@ -35,7 +35,7 @@ void ConfigFile::apply()
for (auto & [name, value] : settings) {
- auto baseName = hasPrefix(name, "extra-") ? std::string(name, 6) : name;
+ auto baseName = name.starts_with("extra-") ? std::string(name, 6) : name;
// FIXME: Move into libutil/config.cc.
std::string valueS;
diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc
index e1bce90bc..1c90bfc43 100644
--- a/src/libexpr/flake/flakeref.cc
+++ b/src/libexpr/flake/flakeref.cc
@@ -186,7 +186,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
}
} else {
- if (!hasPrefix(path, "/"))
+ if (!path.starts_with("/"))
throw BadURL("flake reference '%s' is not an absolute path", url);
auto query = decodeQuery(match[2]);
path = canonPath(path + "/" + getOr(query, "dir", ""));
diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc
index 1689155b3..48e1bd6e3 100644
--- a/src/libfetchers/git.cc
+++ b/src/libfetchers/git.cc
@@ -223,7 +223,7 @@ std::pair<StorePath, Input> fetchFromWorkdir(ref<Store> store, Input & input, co
Path actualPath(absPath(workdir));
PathFilter filter = [&](const Path & p) -> bool {
- assert(hasPrefix(p, actualPath));
+ assert(p.starts_with(actualPath));
std::string file(p, actualPath.size() + 1);
auto st = lstat(p);
@@ -231,7 +231,7 @@ std::pair<StorePath, Input> fetchFromWorkdir(ref<Store> store, Input & input, co
if (S_ISDIR(st.st_mode)) {
auto prefix = file + "/";
auto i = files.lower_bound(prefix);
- return i != files.end() && hasPrefix(*i, prefix);
+ return i != files.end() && (*i).starts_with(prefix);
}
return files.count(file);
@@ -267,7 +267,7 @@ struct GitInputScheme : InputScheme
url.scheme != "git+file") return {};
auto url2(url);
- if (hasPrefix(url2.scheme, "git+")) url2.scheme = std::string(url2.scheme, 4);
+ if (url2.scheme.starts_with("git+")) url2.scheme = std::string(url2.scheme, 4);
url2.query.clear();
Attrs attrs;
diff --git a/src/libfetchers/mercurial.cc b/src/libfetchers/mercurial.cc
index 51fd1ed42..a70403660 100644
--- a/src/libfetchers/mercurial.cc
+++ b/src/libfetchers/mercurial.cc
@@ -181,7 +181,7 @@ struct MercurialInputScheme : InputScheme
Path actualPath(absPath(actualUrl));
PathFilter filter = [&](const Path & p) -> bool {
- assert(hasPrefix(p, actualPath));
+ assert(p.starts_with(actualPath));
std::string file(p, actualPath.size() + 1);
auto st = lstat(p);
@@ -189,7 +189,7 @@ struct MercurialInputScheme : InputScheme
if (S_ISDIR(st.st_mode)) {
auto prefix = file + "/";
auto i = files.lower_bound(prefix);
- return i != files.end() && hasPrefix(*i, prefix);
+ return i != files.end() && (*i).starts_with(prefix);
}
return files.count(file);
diff --git a/src/libfetchers/registry.cc b/src/libfetchers/registry.cc
index 43c03beec..da92273d6 100644
--- a/src/libfetchers/registry.cc
+++ b/src/libfetchers/registry.cc
@@ -157,7 +157,7 @@ static std::shared_ptr<Registry> getGlobalRegistry(ref<Store> store)
return std::make_shared<Registry>(Registry::Global); // empty registry
}
- if (!hasPrefix(path, "/")) {
+ if (!path.starts_with("/")) {
auto storePath = downloadFile(store, path, "flake-registry.json", false).storePath;
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
store2->addPermRoot(storePath, getCacheDir() + "/nix/flake-registry.json");
diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc
index e3a41e75e..68cb0ca40 100644
--- a/src/libfetchers/tarball.cc
+++ b/src/libfetchers/tarball.cc
@@ -188,10 +188,10 @@ struct CurlInputScheme : InputScheme
const bool hasTarballExtension(std::string_view path) const
{
- return hasSuffix(path, ".zip") || hasSuffix(path, ".tar")
- || hasSuffix(path, ".tgz") || hasSuffix(path, ".tar.gz")
- || hasSuffix(path, ".tar.xz") || hasSuffix(path, ".tar.bz2")
- || hasSuffix(path, ".tar.zst");
+ return path.ends_with(".zip") || path.ends_with(".tar")
+ || path.ends_with(".tgz") || path.ends_with(".tar.gz")
+ || path.ends_with(".tar.xz") || path.ends_with(".tar.bz2")
+ || path.ends_with(".tar.zst");
}
virtual bool isValidURL(const ParsedURL & url, bool requireTree) const = 0;
diff --git a/src/libmain/common-args.cc b/src/libmain/common-args.cc
index f92920d18..75feccbed 100644
--- a/src/libmain/common-args.cc
+++ b/src/libmain/common-args.cc
@@ -47,7 +47,7 @@ MixCommonArgs::MixCommonArgs(const std::string & programName)
std::map<std::string, Config::SettingInfo> settings;
globalConfig.getSettings(settings);
for (auto & s : settings)
- if (hasPrefix(s.first, prefix))
+ if (s.first.starts_with(prefix))
completions->add(s.first, fmt("Set the `%s` setting.", s.first));
}
}
diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc
index 45b1fdfd1..5c648ccf7 100644
--- a/src/libmain/progress-bar.cc
+++ b/src/libmain/progress-bar.cc
@@ -188,7 +188,7 @@ public:
if (type == actBuild) {
std::string name(storePathToName(getS(fields, 0)));
- if (hasSuffix(name, ".drv"))
+ if (name.ends_with(".drv"))
name = name.substr(0, name.size() - 4);
i->s = fmt("building " ANSI_BOLD "%s" ANSI_NORMAL, name);
auto machineName = getS(fields, 1);
@@ -207,7 +207,7 @@ public:
auto name = storePathToName(getS(fields, 0));
auto sub = getS(fields, 1);
i->s = fmt(
- hasPrefix(sub, "local")
+ sub.starts_with("local")
? "copying " ANSI_BOLD "%s" ANSI_NORMAL " from %s"
: "fetching " ANSI_BOLD "%s" ANSI_NORMAL " from %s",
name, sub);
@@ -215,7 +215,7 @@ public:
if (type == actPostBuildHook) {
auto name = storePathToName(getS(fields, 0));
- if (hasSuffix(name, ".drv"))
+ if (name.ends_with(".drv"))
name = name.substr(0, name.size() - 4);
i->s = fmt("post-build " ANSI_BOLD "%s" ANSI_NORMAL, name);
i->name = DrvName(name).name;
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index c4fae0eaa..9dcde7f4a 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -596,7 +596,7 @@ void LocalDerivationGoal::startBuilder()
else
pathsInChroot[i.substr(0, p)] = {i.substr(p + 1), optional};
}
- if (hasPrefix(worker.store.storeDir, tmpDirInSandbox))
+ if (worker.store.storeDir.starts_with(tmpDirInSandbox))
{
throw Error("`sandbox-build-dir` must not contain the storeDir");
}
diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc
index c8911d153..eb68d5a33 100644
--- a/src/libstore/builtins/buildenv.cc
+++ b/src/libstore/builtins/buildenv.cc
@@ -53,13 +53,13 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
* Python package brings its own
* `$out/lib/pythonX.Y/site-packages/easy-install.pth'.)
*/
- if (hasSuffix(srcFile, "/propagated-build-inputs") ||
- hasSuffix(srcFile, "/nix-support") ||
- hasSuffix(srcFile, "/perllocal.pod") ||
- hasSuffix(srcFile, "/info/dir") ||
- hasSuffix(srcFile, "/log") ||
- hasSuffix(srcFile, "/manifest.nix") ||
- hasSuffix(srcFile, "/manifest.json"))
+ if (srcFile.ends_with("/propagated-build-inputs") ||
+ srcFile.ends_with("/nix-support") ||
+ srcFile.ends_with("/perllocal.pod") ||
+ srcFile.ends_with("/info/dir") ||
+ srcFile.ends_with("/log") ||
+ srcFile.ends_with("/manifest.nix") ||
+ srcFile.ends_with("/manifest.json"))
continue;
else if (S_ISDIR(srcSt.st_mode)) {
diff --git a/src/libstore/builtins/fetchurl.cc b/src/libstore/builtins/fetchurl.cc
index 7d7924d77..3d87bdc21 100644
--- a/src/libstore/builtins/fetchurl.cc
+++ b/src/libstore/builtins/fetchurl.cc
@@ -41,7 +41,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
request.decompress = false;
auto decompressor = makeDecompressionSink(
- unpack && hasSuffix(mainUrl, ".xz") ? "xz" : "none", sink);
+ unpack && mainUrl.ends_with(".xz") ? "xz" : "none", sink);
fileTransfer->download(std::move(request), *decompressor);
decompressor->finish();
});
@@ -62,7 +62,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
if (getAttr("outputHashMode") == "flat")
for (auto hashedMirror : settings.hashedMirrors.get())
try {
- if (!hasSuffix(hashedMirror, "/")) hashedMirror += '/';
+ if (!hashedMirror.ends_with("/")) hashedMirror += '/';
std::optional<HashType> ht = parseHashTypeOpt(getAttr("outputHashAlgo"));
Hash h = newHashAllowEmpty(getAttr("outputHash"), ht);
fetch(hashedMirror + printHashType(h.type) + "/" + h.to_string(Base16, false));
diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc
index 170d1fb35..993ade7dc 100644
--- a/src/libstore/daemon.cc
+++ b/src/libstore/daemon.cc
@@ -221,7 +221,7 @@ struct ClientSettings
for (auto & s : ss)
if (trusted.count(s))
subs.push_back(s);
- else if (!hasSuffix(s, "/") && trusted.count(s + "/"))
+ else if (!s.ends_with("/") && trusted.count(s + "/"))
subs.push_back(s + "/");
else
warn("ignoring untrusted substituter '%s', you are not a trusted user.\n"
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index efba17c4b..ab84255d3 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -658,7 +658,7 @@ std::string Derivation::unparse(const Store & store, bool maskOutputs,
// FIXME: remove
bool isDerivation(std::string_view fileName)
{
- return hasSuffix(fileName, drvExtension);
+ return fileName.ends_with(drvExtension);
}
@@ -927,7 +927,7 @@ std::string_view BasicDerivation::nameFromPath(const StorePath & drvPath)
{
auto nameWithSuffix = drvPath.name();
constexpr std::string_view extension = ".drv";
- assert(hasSuffix(nameWithSuffix, extension));
+ assert(nameWithSuffix.ends_with(extension));
nameWithSuffix.remove_suffix(extension.size());
return nameWithSuffix;
}
diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc
index 5664579e7..46cda62a1 100644
--- a/src/libstore/filetransfer.cc
+++ b/src/libstore/filetransfer.cc
@@ -670,8 +670,8 @@ struct curlFileTransfer : public FileTransfer
void enqueueItem(std::shared_ptr<TransferItem> item)
{
if (item->request.data
- && !hasPrefix(item->request.uri, "http://")
- && !hasPrefix(item->request.uri, "https://"))
+ && !item->request.uri.starts_with("http://")
+ && !item->request.uri.starts_with("https://"))
throw nix::Error("uploading to '%s' is not supported", item->request.uri);
{
@@ -703,7 +703,7 @@ struct curlFileTransfer : public FileTransfer
Callback<FileTransferResult> callback) override
{
/* Ugly hack to support s3:// URIs. */
- if (hasPrefix(request.uri, "s3://")) {
+ if (request.uri.starts_with("s3://")) {
// FIXME: do this on a worker thread
try {
#if ENABLE_S3
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 2929bd6e6..14437e2f0 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -241,7 +241,7 @@ bool Settings::isWSL1()
uname(&utsbuf);
// WSL1 uses -Microsoft suffix
// WSL2 uses -microsoft-standard suffix
- return hasSuffix(utsbuf.release, "-Microsoft");
+ return std::string_view(utsbuf.release).ends_with("-Microsoft");
}
Path Settings::getDefaultSSLCertFile()
@@ -415,7 +415,7 @@ void initLibStore() {
sshd). This breaks build users because they don't have access
to the TMPDIR, in particular in ‘nix-store --serve’. */
#if __APPLE__
- if (hasPrefix(getEnv("TMPDIR").value_or("/tmp"), "/var/folders/"))
+ if (getEnv("TMPDIR").value_or("/tmp").starts_with("/var/folders/"))
unsetenv("TMPDIR");
#endif
diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc
index 85c5eed4c..9b980d81f 100644
--- a/src/libstore/http-binary-cache-store.cc
+++ b/src/libstore/http-binary-cache-store.cc
@@ -145,7 +145,7 @@ protected:
FileTransferRequest makeRequest(const std::string & path)
{
return FileTransferRequest(
- hasPrefix(path, "https://") || hasPrefix(path, "http://") || hasPrefix(path, "file://")
+ path.starts_with("https://") || path.starts_with("http://") || path.starts_with("file://")
? path
: cacheUri + "/" + path);
diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc
index 5481dd762..5684dcd80 100644
--- a/src/libstore/local-binary-cache-store.cc
+++ b/src/libstore/local-binary-cache-store.cc
@@ -85,7 +85,7 @@ protected:
for (auto & entry : readDirectory(binaryCacheDir)) {
if (entry.name.size() != 40 ||
- !hasSuffix(entry.name, ".narinfo"))
+ !entry.name.ends_with(".narinfo"))
continue;
paths.insert(parseStorePath(
storeDir + "/" + entry.name.substr(0, entry.name.size() - 8)
diff --git a/src/libstore/machines.cc b/src/libstore/machines.cc
index f808b8592..ecae3054e 100644
--- a/src/libstore/machines.cc
+++ b/src/libstore/machines.cc
@@ -24,10 +24,10 @@ Machine::Machine(decltype(storeUri) storeUri,
|| storeUri == "auto"
|| storeUri == "daemon"
|| storeUri == "local"
- || hasPrefix(storeUri, "auto?")
- || hasPrefix(storeUri, "daemon?")
- || hasPrefix(storeUri, "local?")
- || hasPrefix(storeUri, "?")
+ || storeUri.starts_with("auto?")
+ || storeUri.starts_with("daemon?")
+ || storeUri.starts_with("local?")
+ || storeUri.starts_with("?")
? storeUri
: "ssh://" + storeUri),
systemTypes(systemTypes),
@@ -67,12 +67,12 @@ bool Machine::mandatoryMet(const std::set<std::string> & features) const
ref<Store> Machine::openStore() const
{
Store::Params storeParams;
- if (hasPrefix(storeUri, "ssh://")) {
+ if (storeUri.starts_with("ssh://")) {
storeParams["max-connections"] = "1";
storeParams["log-fd"] = "4";
}
- if (hasPrefix(storeUri, "ssh://") || hasPrefix(storeUri, "ssh-ng://")) {
+ if (storeUri.starts_with("ssh://") || storeUri.starts_with("ssh-ng://")) {
if (sshKey != "")
storeParams["ssh-key"] = sshKey;
if (sshPublicHostKey != "")
diff --git a/src/libstore/path.cc b/src/libstore/path.cc
index 3c6b9fc10..c896ff927 100644
--- a/src/libstore/path.cc
+++ b/src/libstore/path.cc
@@ -42,7 +42,7 @@ StorePath::StorePath(const Hash & hash, std::string_view _name)
bool StorePath::isDerivation() const
{
- return hasSuffix(name(), drvExtension);
+ return name().ends_with(drvExtension);
}
StorePath StorePath::dummy("ffffffffffffffffffffffffffffffff-x");
diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc
index 1a62d92d4..cf5f125d4 100644
--- a/src/libstore/s3-binary-cache-store.cc
+++ b/src/libstore/s3-binary-cache-store.cc
@@ -213,7 +213,7 @@ struct S3BinaryCacheStoreConfig : virtual BinaryCacheStoreConfig
support it.
> **Note**
- >
+ >
> HTTPS should be used if the cache might contain sensitive
> information.
)"};
@@ -224,7 +224,7 @@ struct S3BinaryCacheStoreConfig : virtual BinaryCacheStoreConfig
Do not specify this setting if you're using Amazon S3.
> **Note**
- >
+ >
> This endpoint must support HTTPS and will use path-based
> addressing instead of virtual host based addressing.
)"};
@@ -448,11 +448,11 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual
return std::make_shared<std::stringstream>(std::move(compressed));
};
- if (narinfoCompression != "" && hasSuffix(path, ".narinfo"))
+ if (narinfoCompression != "" && path.ends_with(".narinfo"))
uploadFile(path, compress(narinfoCompression), mimeType, narinfoCompression);
- else if (lsCompression != "" && hasSuffix(path, ".ls"))
+ else if (lsCompression != "" && path.ends_with(".ls"))
uploadFile(path, compress(lsCompression), mimeType, lsCompression);
- else if (logCompression != "" && hasPrefix(path, "log/"))
+ else if (logCompression != "" && path.starts_with("log/"))
uploadFile(path, compress(logCompression), mimeType, logCompression);
else
uploadFile(path, istream, mimeType, "");
@@ -499,7 +499,7 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual
for (auto object : contents) {
auto & key = object.GetKey();
- if (key.size() != 40 || !hasSuffix(key, ".narinfo")) continue;
+ if (key.size() != 40 || !key.ends_with(".narinfo")) continue;
paths.insert(parseStorePath(storeDir + "/" + key.substr(0, key.size() - 8) + "-" + MissingName));
}
diff --git a/src/libstore/ssh.cc b/src/libstore/ssh.cc
index fdae083ba..ea9cba578 100644
--- a/src/libstore/ssh.cc
+++ b/src/libstore/ssh.cc
@@ -12,7 +12,7 @@ SSHMaster::SSHMaster(const std::string & host, const std::string & keyFile, cons
, compress(compress)
, logFD(logFD)
{
- if (host == "" || hasPrefix(host, "-"))
+ if (host == "" || host.starts_with("-"))
throw Error("invalid SSH host name '%s'", host);
auto state(state_.lock());
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index 8db293762..02d559540 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -162,7 +162,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
if (auto prefix = needsCompletion(*pos)) {
for (auto & [name, flag] : longFlags) {
if (!hiddenCategories.count(flag->category)
- && hasPrefix(name, std::string(*prefix, 2)))
+ && name.starts_with(std::string(*prefix, 2)))
{
if (auto & f = flag->experimentalFeature)
flagExperimentalFeatures.insert(*f);
@@ -274,7 +274,7 @@ nlohmann::json Args::toJSON()
static void hashTypeCompleter(size_t index, std::string_view prefix)
{
for (auto & type : hashTypes)
- if (hasPrefix(type, prefix))
+ if (type.starts_with(prefix))
completions->add(type);
}
@@ -370,7 +370,7 @@ MultiCommand::MultiCommand(const Commands & commands_)
}},
.completer = {[&](size_t, std::string_view prefix) {
for (auto & [name, command] : commands)
- if (hasPrefix(name, prefix))
+ if (name.starts_with(prefix))
completions->add(name);
}}
});
diff --git a/src/libutil/cgroup.cc b/src/libutil/cgroup.cc
index a008481ca..9320d2371 100644
--- a/src/libutil/cgroup.cc
+++ b/src/libutil/cgroup.cc
@@ -41,7 +41,7 @@ std::map<std::string, std::string> getCgroups(const Path & cgroupFile)
if (!std::regex_match(line, match, regex))
throw Error("invalid line '%s' in '%s'", line, cgroupFile);
- std::string name = hasPrefix(std::string(match[2]), "name=") ? std::string(match[2], 5) : match[2];
+ std::string name = std::string(match[2]).starts_with("name=") ? std::string(match[2], 5) : match[2];
cgroups.insert_or_assign(name, match[3]);
}
@@ -117,13 +117,13 @@ static CgroupStats destroyCgroup(const Path & cgroup, bool returnStats)
if (pathExists(cpustatPath)) {
for (auto & line : tokenizeString<std::vector<std::string>>(readFile(cpustatPath), "\n")) {
std::string_view userPrefix = "user_usec ";
- if (hasPrefix(line, userPrefix)) {
+ if (line.starts_with(userPrefix)) {
auto n = string2Int<uint64_t>(line.substr(userPrefix.size()));
if (n) stats.cpuUser = std::chrono::microseconds(*n);
}
std::string_view systemPrefix = "system_usec ";
- if (hasPrefix(line, systemPrefix)) {
+ if (line.starts_with(systemPrefix)) {
auto n = string2Int<uint64_t>(line.substr(systemPrefix.size()));
if (n) stats.cpuSystem = std::chrono::microseconds(*n);
}
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index 2535b410f..8e76d6d66 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -18,7 +18,7 @@ bool Config::set(const std::string & name, const std::string & value)
bool append = false;
auto i = _settings.find(name);
if (i == _settings.end()) {
- if (hasPrefix(name, "extra-")) {
+ if (name.starts_with("extra-")) {
i = _settings.find(std::string(name, 6));
if (i == _settings.end() || !i->second.setting->isAppendable())
return false;
diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc
index 7d61c0611..691b77e95 100644
--- a/src/libutil/logging.cc
+++ b/src/libutil/logging.cc
@@ -266,7 +266,7 @@ static Logger::Fields getFields(nlohmann::json & json)
std::optional<nlohmann::json> parseJSONMessage(const std::string & msg)
{
- if (!hasPrefix(msg, "@nix ")) return std::nullopt;
+ if (!msg.starts_with("@nix ")) return std::nullopt;
try {
return nlohmann::json::parse(std::string(msg, 5));
} catch (std::exception & e) {
diff --git a/src/libutil/source-path.cc b/src/libutil/source-path.cc
index 3ccbca06b..e6721f808 100644
--- a/src/libutil/source-path.cc
+++ b/src/libutil/source-path.cc
@@ -83,7 +83,7 @@ SourcePath SourcePath::resolveSymlinks(SymlinkResolution mode) const
throw Error("infinite symlink recursion in path '%s'", path);
auto target = res.readLink();
res.path.pop();
- if (hasPrefix(target, "/"))
+ if (target.starts_with("/"))
res.path = CanonPath::root;
todo.splice(todo.begin(), tokenizeString<std::list<std::string>>(target, "/"));
}
diff --git a/src/libutil/split.hh b/src/libutil/split.hh
index 3b9b2b83b..4ff940eef 100644
--- a/src/libutil/split.hh
+++ b/src/libutil/split.hh
@@ -27,7 +27,7 @@ static inline std::optional<std::string_view> splitPrefixTo(std::string_view & s
}
static inline bool splitPrefix(std::string_view & string, std::string_view prefix) {
- bool res = hasPrefix(string, prefix);
+ bool res = string.starts_with(prefix);
if (res)
string.remove_prefix(prefix.length());
return res;
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 9bb769fc2..3fe96acd2 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -1449,19 +1449,6 @@ bool statusOk(int status)
}
-bool hasPrefix(std::string_view s, std::string_view prefix)
-{
- return s.compare(0, prefix.size(), prefix) == 0;
-}
-
-
-bool hasSuffix(std::string_view s, std::string_view suffix)
-{
- return s.size() >= suffix.size()
- && s.substr(s.size() - suffix.size()) == suffix;
-}
-
-
std::string toLower(const std::string & s)
{
std::string r(s);
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index ed4c8705a..f0f9e922b 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -665,19 +665,6 @@ T readLittleEndian(unsigned char * p)
return x;
}
-
-/**
- * @return true iff `s` starts with `prefix`.
- */
-bool hasPrefix(std::string_view s, std::string_view prefix);
-
-
-/**
- * @return true iff `s` ends in `suffix`.
- */
-bool hasSuffix(std::string_view s, std::string_view suffix);
-
-
/**
* Convert a string to lower case.
*/
diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc
index cf07e60a1..3928e39a9 100644
--- a/src/nix-build/nix-build.cc
+++ b/src/nix-build/nix-build.cc
@@ -305,7 +305,7 @@ static void main_nix_build(int argc, char * * argv)
absolute = canonPath(absPath(i), true);
} catch (Error & e) {};
auto [path, outputNames] = parsePathWithOutputs(absolute);
- if (evalStore->isStorePath(path) && hasSuffix(path, ".drv"))
+ if (evalStore->isStorePath(path) && path.ends_with(".drv"))
drvs.push_back(DrvInfo(*state, evalStore, absolute));
else
/* If we're in a #! script, interpret filenames
diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc
index 898d7b05d..a12fa8e64 100644
--- a/src/nix-channel/nix-channel.cc
+++ b/src/nix-channel/nix-channel.cc
@@ -200,7 +200,7 @@ static int main_nix_channel(int argc, char ** argv)
} else if (*arg == "--rollback") {
cmd = cRollback;
} else {
- if (hasPrefix(*arg, "-"))
+ if ((*arg).starts_with("-"))
throw UsageError("unsupported argument '%s'", *arg);
args.push_back(std::move(*arg));
}
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index be5db6b5c..ad255a1e1 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -125,13 +125,13 @@ static void getAllExprs(EvalState & state,
continue; // ignore dangling symlinks in ~/.nix-defexpr
}
- if (isNixExpr(path2, st) && (st.type != InputAccessor::tRegular || hasSuffix(path2.baseName(), ".nix"))) {
+ if (isNixExpr(path2, st) && (st.type != InputAccessor::tRegular || path2.baseName().ends_with(".nix"))) {
/* Strip off the `.nix' filename suffix (if applicable),
otherwise the attribute cannot be selected with the
`-A' option. Useful if you want to stick a Nix
expression directly in ~/.nix-defexpr. */
std::string attrName = i;
- if (hasSuffix(attrName, ".nix"))
+ if (attrName.ends_with(".nix"))
attrName = std::string(attrName, 0, attrName.size() - 4);
if (!seen.insert(attrName).second) {
std::string suggestionMessage = "";
@@ -241,7 +241,7 @@ std::set<std::string> searchByPrefix(const DrvInfos & allElems, std::string_view
std::set<std::string> result;
for (const auto & drvInfo : allElems) {
const auto drvName = DrvName { drvInfo.queryName() };
- if (hasPrefix(drvName.name, prefix)) {
+ if (drvName.name.starts_with(prefix)) {
result.emplace(drvName.name);
if (result.size() >= maxResults) {
diff --git a/src/nix/develop.cc b/src/nix/develop.cc
index 9ecfdef5d..b5543447e 100644
--- a/src/nix/develop.cc
+++ b/src/nix/develop.cc
@@ -448,7 +448,7 @@ struct Common : InstallableCommand, MixProfile
StorePath getShellOutPath(ref<Store> store, ref<Installable> installable)
{
auto path = installable->getStorePath();
- if (path && hasSuffix(path->to_string(), "-env"))
+ if (path && path->to_string().ends_with("-env"))
return *path;
else {
auto drvs = Installable::toDerivations(store, {installable});
diff --git a/src/nix/doctor.cc b/src/nix/doctor.cc
index 1aa6831d3..531f0ad86 100644
--- a/src/nix/doctor.cc
+++ b/src/nix/doctor.cc
@@ -101,7 +101,7 @@ struct CmdDoctor : StoreCommand
try {
Path userEnv = canonPath(profileDir, true);
- if (store->isStorePath(userEnv) && hasSuffix(userEnv, "user-environment")) {
+ if (store->isStorePath(userEnv) && userEnv.ends_with("user-environment")) {
while (profileDir.find("/profiles/") == std::string::npos && isLink(profileDir))
profileDir = absPath(readLink(profileDir), dirOf(profileDir));
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index bbefff87a..6b3012558 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -334,7 +334,7 @@ struct CmdFlakeCheck : FlakeCommand
return
name == expected
|| name == "_"
- || (hasPrefix(name, "_") && name.substr(1) == expected);
+ || (name.starts_with("_") && name.substr(1) == expected);
};
auto checkSystemName = [&](const std::string & system, const PosIdx pos) {
diff --git a/src/nix/prefetch.cc b/src/nix/prefetch.cc
index 9f2d6cc57..0104635fb 100644
--- a/src/nix/prefetch.cc
+++ b/src/nix/prefetch.cc
@@ -42,7 +42,7 @@ std::string resolveMirrorUrl(EvalState & state, const std::string & url)
throw Error("mirror URL '%s' did not expand to anything", url);
std::string mirror(state.forceString(*mirrorList->value->listElems()[0], noPos, "while evaluating the first available mirror"));
- return mirror + (hasSuffix(mirror, "/") ? "" : "/") + s.substr(p + 1);
+ return mirror + (mirror.ends_with("/") ? "" : "/") + s.substr(p + 1);
}
std::tuple<StorePath, Hash> prefetchFile(
diff --git a/src/nix/upgrade-nix.cc b/src/nix/upgrade-nix.cc
index d238456db..af219c1b9 100644
--- a/src/nix/upgrade-nix.cc
+++ b/src/nix/upgrade-nix.cc
@@ -115,7 +115,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand
printInfo("found Nix in '%s'", where);
- if (hasPrefix(where, "/run/current-system"))
+ if (where.starts_with("/run/current-system"))
throw Error("Nix on NixOS must be upgraded via 'nixos-rebuild'");
Path profileDir = dirOf(where);
@@ -129,7 +129,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand
Path userEnv = canonPath(profileDir, true);
if (baseNameOf(where) != "bin" ||
- !hasSuffix(userEnv, "user-environment"))
+ !userEnv.ends_with("user-environment"))
throw Error("directory '%s' does not appear to be part of a Nix profile", where);
if (!store->isValidPath(store->parseStorePath(userEnv)))
diff --git a/src/resolve-system-dependencies/resolve-system-dependencies.cc b/src/resolve-system-dependencies/resolve-system-dependencies.cc
index 4ea268d24..424c789d8 100644
--- a/src/resolve-system-dependencies/resolve-system-dependencies.cc
+++ b/src/resolve-system-dependencies/resolve-system-dependencies.cc
@@ -105,7 +105,7 @@ bool isSymlink(const Path & path)
Path resolveSymlink(const Path & path)
{
auto target = readLink(path);
- return hasPrefix(target, "/")
+ return target.starts_with("/")
? target
: concatStrings(dirOf(path), "/", target);
}
@@ -125,7 +125,7 @@ std::set<std::string> resolveTree(const Path & path, PathSet & deps)
std::set<std::string> getPath(const Path & path)
{
- if (hasPrefix(path, "/dev")) return {};
+ if (path.starts_with("/dev")) return {};
Path cacheFile = resolveCacheFile(path);
if (pathExists(cacheFile))
diff --git a/tests/unit/libutil/tests.cc b/tests/unit/libutil/tests.cc
index f3c1e8248..f55c56548 100644
--- a/tests/unit/libutil/tests.cc
+++ b/tests/unit/libutil/tests.cc
@@ -235,36 +235,6 @@ namespace nix {
}
/* ----------------------------------------------------------------------------
- * hasPrefix
- * --------------------------------------------------------------------------*/
-
- TEST(hasPrefix, emptyStringHasNoPrefix) {
- ASSERT_FALSE(hasPrefix("", "foo"));
- }
-
- TEST(hasPrefix, emptyStringIsAlwaysPrefix) {
- ASSERT_TRUE(hasPrefix("foo", ""));
- ASSERT_TRUE(hasPrefix("jshjkfhsadf", ""));
- }
-
- TEST(hasPrefix, trivialCase) {
- ASSERT_TRUE(hasPrefix("foobar", "foo"));
- }
-
- /* ----------------------------------------------------------------------------
- * hasSuffix
- * --------------------------------------------------------------------------*/
-
- TEST(hasSuffix, emptyStringHasNoSuffix) {
- ASSERT_FALSE(hasSuffix("", "foo"));
- }
-
- TEST(hasSuffix, trivialCase) {
- ASSERT_TRUE(hasSuffix("foo", "foo"));
- ASSERT_TRUE(hasSuffix("foobar", "bar"));
- }
-
- /* ----------------------------------------------------------------------------
* base64Encode
* --------------------------------------------------------------------------*/