forked from lix-project/lix
Switch from std::regex to boost::regex
This commit is contained in:
parent
dda0e34ecf
commit
d2f5e263e3
24
flake.nix
24
flake.nix
|
@ -154,7 +154,7 @@
|
||||||
|
|
||||||
configureFlags =
|
configureFlags =
|
||||||
lib.optionals stdenv.isLinux [
|
lib.optionals stdenv.isLinux [
|
||||||
"--with-boost=${boost}/lib"
|
"--with-boost=${boost-nix}/lib"
|
||||||
"--with-sandbox-shell=${sh}/bin/busybox"
|
"--with-sandbox-shell=${sh}/bin/busybox"
|
||||||
]
|
]
|
||||||
++ lib.optionals (stdenv.isLinux && !(isStatic && stdenv.system == "aarch64-linux")) [
|
++ lib.optionals (stdenv.isLinux && !(isStatic && stdenv.system == "aarch64-linux")) [
|
||||||
|
@ -202,7 +202,7 @@
|
||||||
version = libgit2.lastModifiedDate;
|
version = libgit2.lastModifiedDate;
|
||||||
cmakeFlags = (attrs.cmakeFlags or []) ++ ["-DUSE_SSH=exec"];
|
cmakeFlags = (attrs.cmakeFlags or []) ++ ["-DUSE_SSH=exec"];
|
||||||
}))
|
}))
|
||||||
boost
|
boost-nix
|
||||||
lowdown-nix
|
lowdown-nix
|
||||||
libsodium
|
libsodium
|
||||||
]
|
]
|
||||||
|
@ -423,14 +423,14 @@
|
||||||
|
|
||||||
propagatedBuildInputs = propagatedDeps;
|
propagatedBuildInputs = propagatedDeps;
|
||||||
|
|
||||||
disallowedReferences = [ boost ];
|
disallowedReferences = [ boost-nix ];
|
||||||
|
|
||||||
preConfigure = lib.optionalString (! currentStdenv.hostPlatform.isStatic)
|
preConfigure = lib.optionalString (! currentStdenv.hostPlatform.isStatic)
|
||||||
''
|
''
|
||||||
# Copy libboost_context so we don't get all of Boost in our closure.
|
# Copy libboost_context so we don't get all of Boost in our closure.
|
||||||
# https://github.com/NixOS/nixpkgs/issues/45462
|
# https://github.com/NixOS/nixpkgs/issues/45462
|
||||||
mkdir -p $out/lib
|
mkdir -p $out/lib
|
||||||
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
|
cp -pd ${boost-nix}/lib/{libboost_context*,libboost_thread*,libboost_system*,libboost_regex*} $out/lib
|
||||||
rm -f $out/lib/*.a
|
rm -f $out/lib/*.a
|
||||||
${lib.optionalString currentStdenv.hostPlatform.isLinux ''
|
${lib.optionalString currentStdenv.hostPlatform.isLinux ''
|
||||||
chmod u+w $out/lib/*.so.*
|
chmod u+w $out/lib/*.so.*
|
||||||
|
@ -440,9 +440,9 @@
|
||||||
for LIB in $out/lib/*.dylib; do
|
for LIB in $out/lib/*.dylib; do
|
||||||
chmod u+w $LIB
|
chmod u+w $LIB
|
||||||
install_name_tool -id $LIB $LIB
|
install_name_tool -id $LIB $LIB
|
||||||
install_name_tool -delete_rpath ${boost}/lib/ $LIB || true
|
install_name_tool -delete_rpath ${boost-nix}/lib/ $LIB || true
|
||||||
done
|
done
|
||||||
install_name_tool -change ${boost}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib
|
install_name_tool -change ${boost-nix}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
@ -470,9 +470,13 @@
|
||||||
''}
|
''}
|
||||||
${lib.optionalString currentStdenv.isDarwin ''
|
${lib.optionalString currentStdenv.isDarwin ''
|
||||||
install_name_tool \
|
install_name_tool \
|
||||||
-change ${boost}/lib/libboost_context.dylib \
|
-change ${boost-nix}/lib/libboost_context.dylib \
|
||||||
$out/lib/libboost_context.dylib \
|
$out/lib/libboost_context.dylib \
|
||||||
$out/lib/libnixutil.dylib
|
$out/lib/libnixutil.dylib
|
||||||
|
install_name_tool \
|
||||||
|
-change ${boost-nix}/lib/libboost_regex.dylib \
|
||||||
|
$out/lib/libboost_regex.dylib \
|
||||||
|
$out/lib/libnixexpr.dylib
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
@ -495,6 +499,12 @@
|
||||||
meta.mainProgram = "nix";
|
meta.mainProgram = "nix";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
boost-nix = final.boost.override {
|
||||||
|
# enableIcu arg is not yet supported
|
||||||
|
# but will be with next nixpkgs update
|
||||||
|
enableIcu = false;
|
||||||
|
};
|
||||||
|
|
||||||
lowdown-nix = with final; currentStdenv.mkDerivation rec {
|
lowdown-nix = with final; currentStdenv.mkDerivation rec {
|
||||||
name = "lowdown-0.9.0";
|
name = "lowdown-0.9.0";
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ libexpr_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/lib
|
||||||
|
|
||||||
libexpr_LIBS = libutil libstore libfetchers
|
libexpr_LIBS = libutil libstore libfetchers
|
||||||
|
|
||||||
libexpr_LDFLAGS += -lboost_context -pthread
|
libexpr_LDFLAGS += -lboost_context -lboost_regex -pthread
|
||||||
ifdef HOST_LINUX
|
ifdef HOST_LINUX
|
||||||
libexpr_LDFLAGS += -ldl
|
libexpr_LDFLAGS += -ldl
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "primops.hh"
|
#include "primops.hh"
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
#include <boost/regex.hpp>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -24,7 +25,6 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <regex>
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -3885,19 +3885,30 @@ static RegisterPrimOp primop_convertHash({
|
||||||
.fun = prim_convertHash,
|
.fun = prim_convertHash,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// regex aliases, switch between boost and std
|
||||||
|
using regex = boost::regex;
|
||||||
|
using regex_error = boost::regex_error;
|
||||||
|
using cmatch = boost::cmatch;
|
||||||
|
using cregex_iterator = boost::cregex_iterator;
|
||||||
|
namespace regex_constants = boost::regex_constants;
|
||||||
|
// overloaded function alias
|
||||||
|
constexpr auto regex_match = [] (auto &&...args) {
|
||||||
|
return boost::regex_match(std::forward<decltype(args)>(args)...);
|
||||||
|
};
|
||||||
|
|
||||||
struct RegexCache
|
struct RegexCache
|
||||||
{
|
{
|
||||||
// TODO use C++20 transparent comparison when available
|
// TODO use C++20 transparent comparison when available
|
||||||
std::unordered_map<std::string_view, std::regex> cache;
|
std::unordered_map<std::string_view, regex> cache;
|
||||||
std::list<std::string> keys;
|
std::list<std::string> keys;
|
||||||
|
|
||||||
std::regex get(std::string_view re)
|
regex get(std::string_view re)
|
||||||
{
|
{
|
||||||
auto it = cache.find(re);
|
auto it = cache.find(re);
|
||||||
if (it != cache.end())
|
if (it != cache.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
keys.emplace_back(re);
|
keys.emplace_back(re);
|
||||||
return cache.emplace(keys.back(), std::regex(keys.back(), std::regex::extended)).first->second;
|
return cache.emplace(keys.back(), regex(keys.back(), regex::extended)).first->second;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3917,8 +3928,8 @@ void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.match");
|
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.match");
|
||||||
|
|
||||||
std::cmatch match;
|
cmatch match;
|
||||||
if (!std::regex_match(str.begin(), str.end(), match, regex)) {
|
if (!regex_match(str.begin(), str.end(), match, regex)) {
|
||||||
v.mkNull();
|
v.mkNull();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3933,8 +3944,8 @@ void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
(v.listElems()[i] = state.allocValue())->mkString(match[i + 1].str());
|
(v.listElems()[i] = state.allocValue())->mkString(match[i + 1].str());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (std::regex_error & e) {
|
} catch (regex_error & e) {
|
||||||
if (e.code() == std::regex_constants::error_space) {
|
if (e.code() == regex_constants::error_space) {
|
||||||
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
||||||
state.debugThrowLastTrace(EvalError({
|
state.debugThrowLastTrace(EvalError({
|
||||||
.msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
|
.msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
|
||||||
|
@ -3997,8 +4008,8 @@ void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.split");
|
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.split");
|
||||||
|
|
||||||
auto begin = std::cregex_iterator(str.begin(), str.end(), regex);
|
auto begin = cregex_iterator(str.begin(), str.end(), regex);
|
||||||
auto end = std::cregex_iterator();
|
auto end = cregex_iterator();
|
||||||
|
|
||||||
// Any matches results are surrounded by non-matching results.
|
// Any matches results are surrounded by non-matching results.
|
||||||
const size_t len = std::distance(begin, end);
|
const size_t len = std::distance(begin, end);
|
||||||
|
@ -4037,8 +4048,8 @@ void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
|
|
||||||
assert(idx == 2 * len + 1);
|
assert(idx == 2 * len + 1);
|
||||||
|
|
||||||
} catch (std::regex_error & e) {
|
} catch (regex_error & e) {
|
||||||
if (e.code() == std::regex_constants::error_space) {
|
if (e.code() == regex_constants::error_space) {
|
||||||
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
||||||
state.debugThrowLastTrace(EvalError({
|
state.debugThrowLastTrace(EvalError({
|
||||||
.msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
|
.msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
|
||||||
|
|
Loading…
Reference in a new issue