From 61e21b25576f7f3491f6a837bf59d8b44c6897a0 Mon Sep 17 00:00:00 2001 From: Jade Lovelace Date: Sun, 17 Mar 2024 19:14:18 -0700 Subject: [PATCH] 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 --- src/libcmd/common-eval-args.cc | 2 +- src/libcmd/installables.cc | 12 ++++---- src/libcmd/repl.cc | 2 +- src/libexpr/eval-settings.cc | 4 +-- src/libexpr/eval.cc | 16 +++++----- src/libexpr/flake/config.cc | 2 +- src/libexpr/flake/flakeref.cc | 2 +- src/libfetchers/git.cc | 6 ++-- src/libfetchers/mercurial.cc | 4 +-- src/libfetchers/registry.cc | 2 +- src/libfetchers/tarball.cc | 8 ++--- src/libmain/common-args.cc | 2 +- src/libmain/progress-bar.cc | 6 ++-- src/libstore/build/local-derivation-goal.cc | 2 +- src/libstore/builtins/buildenv.cc | 14 ++++----- src/libstore/builtins/fetchurl.cc | 4 +-- src/libstore/daemon.cc | 2 +- src/libstore/derivations.cc | 4 +-- src/libstore/filetransfer.cc | 6 ++-- src/libstore/globals.cc | 4 +-- src/libstore/http-binary-cache-store.cc | 2 +- src/libstore/local-binary-cache-store.cc | 2 +- src/libstore/machines.cc | 12 ++++---- src/libstore/path.cc | 2 +- src/libstore/s3-binary-cache-store.cc | 12 ++++---- src/libstore/ssh.cc | 2 +- src/libutil/args.cc | 6 ++-- src/libutil/cgroup.cc | 6 ++-- src/libutil/config.cc | 2 +- src/libutil/logging.cc | 2 +- src/libutil/source-path.cc | 2 +- src/libutil/split.hh | 2 +- src/libutil/util.cc | 13 -------- src/libutil/util.hh | 13 -------- src/nix-build/nix-build.cc | 2 +- src/nix-channel/nix-channel.cc | 2 +- src/nix-env/nix-env.cc | 6 ++-- src/nix/develop.cc | 2 +- src/nix/doctor.cc | 2 +- src/nix/flake.cc | 2 +- src/nix/prefetch.cc | 2 +- src/nix/upgrade-nix.cc | 4 +-- .../resolve-system-dependencies.cc | 4 +-- tests/unit/libutil/tests.cc | 30 ------------------- 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, 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( @@ -2823,7 +2823,7 @@ std::optional 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 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 fetchFromWorkdir(ref 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 fetchFromWorkdir(ref 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 getGlobalRegistry(ref store) return std::make_shared(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()) 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 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 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 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 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 & features) const ref 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::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 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>(readFile(cpustatPath), "\n")) { std::string_view userPrefix = "user_usec "; - if (hasPrefix(line, userPrefix)) { + if (line.starts_with(userPrefix)) { auto n = string2Int(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(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 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>(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 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 searchByPrefix(const DrvInfos & allElems, std::string_view std::set 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, ref 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 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 resolveTree(const Path & path, PathSet & deps) std::set 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 @@ -234,36 +234,6 @@ namespace nix { ASSERT_EQ(concatStringsSep(",", strings), "this"); } - /* ---------------------------------------------------------------------------- - * 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 * --------------------------------------------------------------------------*/