Don't include <regex> in header files
This reduces compilation time by ~15 seconds (CPU time). Issue #4045.
This commit is contained in:
parent
cbe0bb29f4
commit
e8e1d420f3
|
@ -356,6 +356,7 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
|
||||||
, sEpsilon(symbols.create(""))
|
, sEpsilon(symbols.create(""))
|
||||||
, repair(NoRepair)
|
, repair(NoRepair)
|
||||||
, store(store)
|
, store(store)
|
||||||
|
, regexCache(makeRegexCache())
|
||||||
, baseEnv(allocEnv(128))
|
, baseEnv(allocEnv(128))
|
||||||
, staticBaseEnv(false, 0)
|
, staticBaseEnv(false, 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "symbol-table.hh"
|
#include "symbol-table.hh"
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
|
|
||||||
#include <regex>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -65,6 +64,11 @@ typedef std::list<SearchPathElem> SearchPath;
|
||||||
void initGC();
|
void initGC();
|
||||||
|
|
||||||
|
|
||||||
|
struct RegexCache;
|
||||||
|
|
||||||
|
std::shared_ptr<RegexCache> makeRegexCache();
|
||||||
|
|
||||||
|
|
||||||
class EvalState
|
class EvalState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -120,7 +124,7 @@ private:
|
||||||
std::unordered_map<Path, Path> resolvedPaths;
|
std::unordered_map<Path, Path> resolvedPaths;
|
||||||
|
|
||||||
/* Cache used by prim_match(). */
|
/* Cache used by prim_match(). */
|
||||||
std::unordered_map<std::string, std::regex> regexCache;
|
std::shared_ptr<RegexCache> regexCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "flakeref.hh"
|
#include "flakeref.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "registry.hh"
|
#include "registry.hh"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "lockfile.hh"
|
#include "lockfile.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
|
|
@ -3085,17 +3085,25 @@ static RegisterPrimOp primop_hashString({
|
||||||
.fun = prim_hashString,
|
.fun = prim_hashString,
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Match a regular expression against a string and return either
|
struct RegexCache
|
||||||
‘null’ or a list containing substring matches. */
|
{
|
||||||
|
std::unordered_map<std::string, std::regex> cache;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<RegexCache> makeRegexCache()
|
||||||
|
{
|
||||||
|
return std::make_shared<RegexCache>();
|
||||||
|
}
|
||||||
|
|
||||||
void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
auto re = state.forceStringNoCtx(*args[0], pos);
|
auto re = state.forceStringNoCtx(*args[0], pos);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
auto regex = state.regexCache.find(re);
|
auto regex = state.regexCache->cache.find(re);
|
||||||
if (regex == state.regexCache.end())
|
if (regex == state.regexCache->cache.end())
|
||||||
regex = state.regexCache.emplace(re, std::regex(re, std::regex::extended)).first;
|
regex = state.regexCache->cache.emplace(re, std::regex(re, std::regex::extended)).first;
|
||||||
|
|
||||||
PathSet context;
|
PathSet context;
|
||||||
const std::string str = state.forceString(*args[1], context, pos);
|
const std::string str = state.forceString(*args[1], context, pos);
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
#include <regex>
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "tarfile.hh"
|
#include "tarfile.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
namespace nix::fetchers {
|
namespace nix::fetchers {
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "tarfile.hh"
|
#include "tarfile.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
#include "names.hh"
|
#include "names.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
struct Regex
|
||||||
|
{
|
||||||
|
std::regex regex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
DrvName::DrvName()
|
DrvName::DrvName()
|
||||||
{
|
{
|
||||||
name = "";
|
name = "";
|
||||||
|
@ -30,11 +38,18 @@ DrvName::DrvName(std::string_view s) : hits(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DrvName::~DrvName()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
bool DrvName::matches(DrvName & n)
|
bool DrvName::matches(DrvName & n)
|
||||||
{
|
{
|
||||||
if (name != "*") {
|
if (name != "*") {
|
||||||
if (!regex) regex = std::unique_ptr<std::regex>(new std::regex(name, std::regex::extended));
|
if (!regex) {
|
||||||
if (!std::regex_match(n.name, *regex)) return false;
|
regex = std::make_unique<Regex>();
|
||||||
|
regex->regex = std::regex(name, std::regex::extended);
|
||||||
|
}
|
||||||
|
if (!std::regex_match(n.name, regex->regex)) return false;
|
||||||
}
|
}
|
||||||
if (version != "" && version != n.version) return false;
|
if (version != "" && version != n.version) return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -99,7 +114,7 @@ DrvNames drvNamesFromArgs(const Strings & opArgs)
|
||||||
{
|
{
|
||||||
DrvNames result;
|
DrvNames result;
|
||||||
for (auto & i : opArgs)
|
for (auto & i : opArgs)
|
||||||
result.push_back(DrvName(i));
|
result.emplace_back(i);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include <regex>
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
struct Regex;
|
||||||
|
|
||||||
struct DrvName
|
struct DrvName
|
||||||
{
|
{
|
||||||
string fullName;
|
string fullName;
|
||||||
|
@ -16,10 +17,12 @@ struct DrvName
|
||||||
|
|
||||||
DrvName();
|
DrvName();
|
||||||
DrvName(std::string_view s);
|
DrvName(std::string_view s);
|
||||||
|
~DrvName();
|
||||||
|
|
||||||
bool matches(DrvName & n);
|
bool matches(DrvName & n);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<std::regex> regex;
|
std::unique_ptr<Regex> regex;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef list<DrvName> DrvNames;
|
typedef list<DrvName> DrvNames;
|
||||||
|
|
44
src/libutil/url-parts.hh
Normal file
44
src/libutil/url-parts.hh
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
// URI stuff.
|
||||||
|
const static std::string pctEncoded = "(?:%[0-9a-fA-F][0-9a-fA-F])";
|
||||||
|
const static std::string schemeRegex = "(?:[a-z+.-]+)";
|
||||||
|
const static std::string ipv6AddressRegex = "(?:\\[[0-9a-fA-F:]+\\])";
|
||||||
|
const static std::string unreservedRegex = "(?:[a-zA-Z0-9-._~])";
|
||||||
|
const static std::string subdelimsRegex = "(?:[!$&'\"()*+,;=])";
|
||||||
|
const static std::string hostnameRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + ")*)";
|
||||||
|
const static std::string hostRegex = "(?:" + ipv6AddressRegex + "|" + hostnameRegex + ")";
|
||||||
|
const static std::string userRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|:)*)";
|
||||||
|
const static std::string authorityRegex = "(?:" + userRegex + "@)?" + hostRegex + "(?::[0-9]+)?";
|
||||||
|
const static std::string pcharRegex = "(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|[:@])";
|
||||||
|
const static std::string queryRegex = "(?:" + pcharRegex + "|[/? \"])*";
|
||||||
|
const static std::string segmentRegex = "(?:" + pcharRegex + "+)";
|
||||||
|
const static std::string absPathRegex = "(?:(?:/" + segmentRegex + ")*/?)";
|
||||||
|
const static std::string pathRegex = "(?:" + segmentRegex + "(?:/" + segmentRegex + ")*/?)";
|
||||||
|
|
||||||
|
// A Git ref (i.e. branch or tag name).
|
||||||
|
const static std::string refRegexS = "[a-zA-Z0-9][a-zA-Z0-9_.-]*"; // FIXME: check
|
||||||
|
extern std::regex refRegex;
|
||||||
|
|
||||||
|
// Instead of defining what a good Git Ref is, we define what a bad Git Ref is
|
||||||
|
// This is because of the definition of a ref in refs.c in https://github.com/git/git
|
||||||
|
// See tests/fetchGitRefs.sh for the full definition
|
||||||
|
const static std::string badGitRefRegexS = "//|^[./]|/\\.|\\.\\.|[[:cntrl:][:space:]:?^~\[]|\\\\|\\*|\\.lock$|\\.lock/|@\\{|[/.]$|^@$|^$";
|
||||||
|
extern std::regex badGitRefRegex;
|
||||||
|
|
||||||
|
// A Git revision (a SHA-1 commit hash).
|
||||||
|
const static std::string revRegexS = "[0-9a-fA-F]{40}";
|
||||||
|
extern std::regex revRegex;
|
||||||
|
|
||||||
|
// A ref or revision, or a ref followed by a revision.
|
||||||
|
const static std::string refAndOrRevRegex = "(?:(" + revRegexS + ")|(?:(" + refRegexS + ")(?:/(" + revRegexS + "))?))";
|
||||||
|
|
||||||
|
const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*";
|
||||||
|
extern std::regex flakeIdRegex;
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
#include "error.hh"
|
#include "error.hh"
|
||||||
|
|
||||||
#include <regex>
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
struct ParsedURL
|
struct ParsedURL
|
||||||
|
@ -29,40 +27,4 @@ std::map<std::string, std::string> decodeQuery(const std::string & query);
|
||||||
|
|
||||||
ParsedURL parseURL(const std::string & url);
|
ParsedURL parseURL(const std::string & url);
|
||||||
|
|
||||||
// URI stuff.
|
|
||||||
const static std::string pctEncoded = "(?:%[0-9a-fA-F][0-9a-fA-F])";
|
|
||||||
const static std::string schemeRegex = "(?:[a-z+.-]+)";
|
|
||||||
const static std::string ipv6AddressRegex = "(?:\\[[0-9a-fA-F:]+\\])";
|
|
||||||
const static std::string unreservedRegex = "(?:[a-zA-Z0-9-._~])";
|
|
||||||
const static std::string subdelimsRegex = "(?:[!$&'\"()*+,;=])";
|
|
||||||
const static std::string hostnameRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + ")*)";
|
|
||||||
const static std::string hostRegex = "(?:" + ipv6AddressRegex + "|" + hostnameRegex + ")";
|
|
||||||
const static std::string userRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|:)*)";
|
|
||||||
const static std::string authorityRegex = "(?:" + userRegex + "@)?" + hostRegex + "(?::[0-9]+)?";
|
|
||||||
const static std::string pcharRegex = "(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|[:@])";
|
|
||||||
const static std::string queryRegex = "(?:" + pcharRegex + "|[/? \"])*";
|
|
||||||
const static std::string segmentRegex = "(?:" + pcharRegex + "+)";
|
|
||||||
const static std::string absPathRegex = "(?:(?:/" + segmentRegex + ")*/?)";
|
|
||||||
const static std::string pathRegex = "(?:" + segmentRegex + "(?:/" + segmentRegex + ")*/?)";
|
|
||||||
|
|
||||||
// A Git ref (i.e. branch or tag name).
|
|
||||||
const static std::string refRegexS = "[a-zA-Z0-9][a-zA-Z0-9_.-]*"; // FIXME: check
|
|
||||||
extern std::regex refRegex;
|
|
||||||
|
|
||||||
// Instead of defining what a good Git Ref is, we define what a bad Git Ref is
|
|
||||||
// This is because of the definition of a ref in refs.c in https://github.com/git/git
|
|
||||||
// See tests/fetchGitRefs.sh for the full definition
|
|
||||||
const static std::string badGitRefRegexS = "//|^[./]|/\\.|\\.\\.|[[:cntrl:][:space:]:?^~\[]|\\\\|\\*|\\.lock$|\\.lock/|@\\{|[/.]$|^@$|^$";
|
|
||||||
extern std::regex badGitRefRegex;
|
|
||||||
|
|
||||||
// A Git revision (a SHA-1 commit hash).
|
|
||||||
const static std::string revRegexS = "[0-9a-fA-F]{40}";
|
|
||||||
extern std::regex revRegex;
|
|
||||||
|
|
||||||
// A ref or revision, or a ref followed by a revision.
|
|
||||||
const static std::string refAndOrRevRegex = "(?:(" + revRegexS + ")|(?:(" + refRegexS + ")(?:/(" + revRegexS + "))?))";
|
|
||||||
|
|
||||||
const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*";
|
|
||||||
extern std::regex flakeIdRegex;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,7 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
|
||||||
{
|
{
|
||||||
DrvNames selectors = drvNamesFromArgs(args);
|
DrvNames selectors = drvNamesFromArgs(args);
|
||||||
if (selectors.empty())
|
if (selectors.empty())
|
||||||
selectors.push_back(DrvName("*"));
|
selectors.emplace_back("*");
|
||||||
|
|
||||||
DrvInfos elems;
|
DrvInfos elems;
|
||||||
set<unsigned int> done;
|
set<unsigned int> done;
|
||||||
|
|
Loading…
Reference in a new issue