#include "c-bindings.hpp"
#include <cassert>
namespace re2_c_bindings {
StringWrapper::StringWrapper(StringView s)
: inner_(new std::string(s.data_, s.len_)) {}
void StringWrapper::clear() {
delete inner_;
inner_ = nullptr;
}
void StringWrapper::resize(const size_t len) {
if (len == 0) {
return clear();
}
get_mutable()->resize(len);
}
StringView StringWrapper::as_view() const {
if (!inner_) {
return StringView();
}
return StringView(inner_->data(), inner_->size());
}
StringMut StringWrapper::as_mut_view() {
if (!inner_) {
return StringMut();
}
return StringMut(inner_->data(), inner_->size());
}
void NamedCapturingGroups::deref(NamedGroup *out) const {
out->name_ = absl::string_view(it_->second);
assert(it_->first > 0);
out->index_ = it_->first;
}
void NamedCapturingGroups::advance() { ++it_; }
bool NamedCapturingGroups::completed() const noexcept {
return it_ == named_groups_.cend();
}
void RE2Wrapper::quote_meta(const StringView pattern, StringWrapper *out) {
*out->get_mutable() =
std::move(re2::RE2::QuoteMeta(pattern.into_absl_view()));
}
size_t RE2Wrapper::max_submatch(const StringView rewrite) {
int ret = re2::RE2::MaxSubmatch(rewrite.into_absl_view());
assert(ret >= 0);
return ret;
}
RE2Wrapper::RE2Wrapper(StringView pattern, const re2::RE2::Options &options)
: re_(new re2::RE2(pattern.into_absl_view(), options)) {}
void RE2Wrapper::clear() {
delete re_;
re_ = nullptr;
}
const re2::RE2::Options &RE2Wrapper::options() const noexcept {
return re_->options();
}
re2::RE2::ErrorCode RE2Wrapper::error_code() const noexcept {
return re_->error_code();
}
StringView RE2Wrapper::pattern() const noexcept {
absl::string_view sv(re_->pattern());
return StringView(sv);
}
StringView RE2Wrapper::error() const noexcept {
absl::string_view sv(re_->error());
return StringView(sv);
}
StringView RE2Wrapper::error_arg() const noexcept {
absl::string_view sv(re_->error_arg());
return StringView(sv);
}
size_t RE2Wrapper::num_captures() const noexcept {
int n = re_->NumberOfCapturingGroups();
assert(n >= 0);
return n;
}
NamedCapturingGroups RE2Wrapper::named_groups() const {
return NamedCapturingGroups(re_->CapturingGroupNames());
}
static bool parse_string_view(const char *data, size_t len, void *dest) {
StringView *dest_sv = reinterpret_cast<StringView *>(dest);
dest_sv->data_ = data;
dest_sv->len_ = len;
return true;
}
bool RE2Wrapper::full_match(const StringView text) const {
return re2::RE2::FullMatchN(text.into_absl_view(), *re_, nullptr, 0);
}
bool RE2Wrapper::full_match_n(const StringView text, StringView captures[],
const size_t n) const {
re2::RE2::Arg *argv =
reinterpret_cast<re2::RE2::Arg *>(alloca(n * sizeof(re2::RE2::Arg)));
re2::RE2::Arg **argv_ref =
reinterpret_cast<re2::RE2::Arg **>(alloca(n * sizeof(re2::RE2::Arg *)));
for (size_t i = 0; i < n; ++i) {
StringView *capture_output = &captures[i];
re2::RE2::Arg::Parser parser = parse_string_view;
argv[i] = re2::RE2::Arg(capture_output, parser);
argv_ref[i] = &argv[i];
}
return re2::RE2::FullMatchN(text.into_absl_view(), *re_, argv_ref, n);
}
bool RE2Wrapper::partial_match(const StringView text) const {
return re2::RE2::PartialMatchN(text.into_absl_view(), *re_, nullptr, 0);
}
bool RE2Wrapper::partial_match_n(const StringView text, StringView captures[],
const size_t n) const {
re2::RE2::Arg *argv =
reinterpret_cast<re2::RE2::Arg *>(alloca(n * sizeof(re2::RE2::Arg)));
re2::RE2::Arg **argv_ref =
reinterpret_cast<re2::RE2::Arg **>(alloca(n * sizeof(re2::RE2::Arg *)));
for (size_t i = 0; i < n; ++i) {
StringView *capture_output = &captures[i];
re2::RE2::Arg::Parser parser = parse_string_view;
argv[i] = re2::RE2::Arg(capture_output, parser);
argv_ref[i] = &argv[i];
}
return re2::RE2::PartialMatchN(text.into_absl_view(), *re_, argv_ref, n);
}
class MutableStringViewInternal {
public:
MutableStringViewInternal(StringView *text)
: view_(text->into_absl_view()), handle_(text) {}
absl::string_view *as_mutable() noexcept { return &view_; }
~MutableStringViewInternal() { *handle_ = StringView(view_); }
private:
absl::string_view view_;
StringView *handle_;
};
bool RE2Wrapper::consume(StringView *text) const {
MutableStringViewInternal tv(text);
return re2::RE2::ConsumeN(tv.as_mutable(), *re_, nullptr, 0);
}
bool RE2Wrapper::consume_n(StringView *text, StringView captures[],
const size_t n) const {
re2::RE2::Arg *argv =
reinterpret_cast<re2::RE2::Arg *>(alloca(n * sizeof(re2::RE2::Arg)));
re2::RE2::Arg **argv_ref =
reinterpret_cast<re2::RE2::Arg **>(alloca(n * sizeof(re2::RE2::Arg *)));
for (size_t i = 0; i < n; ++i) {
StringView *capture_output = &captures[i];
re2::RE2::Arg::Parser parser = parse_string_view;
argv[i] = re2::RE2::Arg(capture_output, parser);
argv_ref[i] = &argv[i];
}
MutableStringViewInternal tv(text);
return re2::RE2::ConsumeN(tv.as_mutable(), *re_, argv_ref, n);
}
bool RE2Wrapper::find_and_consume(StringView *text) const {
MutableStringViewInternal tv(text);
return re2::RE2::FindAndConsumeN(tv.as_mutable(), *re_, nullptr, 0);
}
bool RE2Wrapper::find_and_consume_n(StringView *text, StringView captures[],
const size_t n) const {
re2::RE2::Arg *argv =
reinterpret_cast<re2::RE2::Arg *>(alloca(n * sizeof(re2::RE2::Arg)));
re2::RE2::Arg **argv_ref =
reinterpret_cast<re2::RE2::Arg **>(alloca(n * sizeof(re2::RE2::Arg *)));
for (size_t i = 0; i < n; ++i) {
StringView *capture_output = &captures[i];
re2::RE2::Arg::Parser parser = parse_string_view;
argv[i] = re2::RE2::Arg(capture_output, parser);
argv_ref[i] = &argv[i];
}
MutableStringViewInternal tv(text);
return re2::RE2::FindAndConsumeN(tv.as_mutable(), *re_, argv_ref, n);
}
bool RE2Wrapper::replace(StringWrapper *inout, const StringView rewrite) const {
return re2::RE2::Replace(inout->get_mutable(), *re_,
rewrite.into_absl_view());
}
size_t RE2Wrapper::global_replace(StringWrapper *inout,
const StringView rewrite) const {
int ret = re2::RE2::GlobalReplace(inout->get_mutable(), *re_,
rewrite.into_absl_view());
assert(ret >= 0);
return ret;
}
bool RE2Wrapper::extract(const StringView text, const StringView rewrite,
StringWrapper *out) const {
return re2::RE2::Extract(text.into_absl_view(), *re_,
rewrite.into_absl_view(), out->get_mutable());
}
bool RE2Wrapper::match_single(const StringView text, const size_t startpos,
const size_t endpos,
const re2::RE2::Anchor re_anchor) const {
return re_->Match(text.into_absl_view(), startpos, endpos, re_anchor, nullptr,
0);
}
bool RE2Wrapper::match_routine(const StringView text, const size_t startpos,
const size_t endpos,
const re2::RE2::Anchor re_anchor,
StringView submatch_args[],
const size_t nsubmatch) const {
absl::string_view *submatches = reinterpret_cast<absl::string_view *>(
alloca(nsubmatch * sizeof(absl::string_view)));
if (!re_->Match(text.into_absl_view(), startpos, endpos, re_anchor,
submatches, nsubmatch)) {
return false;
}
for (size_t i = 0; i < nsubmatch; ++i) {
submatch_args[i] = submatches[i];
}
return true;
}
bool RE2Wrapper::check_rewrite_string(const StringView rewrite,
StringWrapper *error) const {
return re_->CheckRewriteString(rewrite.into_absl_view(),
error->get_mutable());
}
bool RE2Wrapper::vector_rewrite(StringWrapper *out, const StringView rewrite,
const StringView *vec,
const size_t veclen) const {
absl::string_view *match_components = reinterpret_cast<absl::string_view *>(
alloca(veclen * sizeof(absl::string_view)));
for (size_t i = 0; i < veclen; ++i) {
match_components[i] = vec[i].into_absl_view();
}
return re_->Rewrite(out->get_mutable(), rewrite.into_absl_view(),
match_components, veclen);
}
void MatchedSetInfo::clear() {
delete matches_;
matches_ = nullptr;
}
const int *MatchedSetInfo::data() const noexcept {
return get_mutable()->data();
}
size_t MatchedSetInfo::size() const noexcept { return get_mutable()->size(); }
size_t MatchedSetInfo::capacity() const noexcept {
return get_mutable()->capacity();
}
void MatchedSetInfo::reserve(const size_t to) { get_mutable()->reserve(to); }
void MatchedSetInfo::set_len(const size_t to) { get_mutable()->resize(to); }
SetWrapper::SetWrapper(const re2::RE2::Options &options,
re2::RE2::Anchor anchor)
: set_(new re2::RE2::Set(options, anchor)) {}
void SetWrapper::clear() {
delete set_;
set_ = nullptr;
}
int SetWrapper::add(const StringView pattern, StringWrapper *error) {
return set_->Add(pattern.into_absl_view(), error->get_mutable());
}
bool SetWrapper::compile() { return set_->Compile(); }
int SetWrapper::size() const {
return set_->Size();
}
bool SetWrapper::match_routine(const StringView text, MatchedSetInfo *v) const {
return set_->Match(text.into_absl_view(), v->get_mutable());
}
bool SetWrapper::match_routine_with_error(
const StringView text, MatchedSetInfo *v,
re2::RE2::Set::ErrorInfo *error_info) const {
return set_->Match(text.into_absl_view(), v->get_mutable(), error_info);
}
void StringSet::clear() {
delete strings_;
strings_ = nullptr;
}
const StringWrapper *StringSet::cdata() const noexcept {
return strings_->data();
}
StringWrapper *StringSet::data() noexcept { return strings_->data(); }
size_t StringSet::size() const noexcept { return strings_->size(); }
FilteredRE2Wrapper::FilteredRE2Wrapper() : inner_(new re2::FilteredRE2()) {}
FilteredRE2Wrapper::FilteredRE2Wrapper(int min_atom_len)
: inner_(new re2::FilteredRE2(min_atom_len)) {}
void FilteredRE2Wrapper::clear() {
delete inner_;
inner_ = nullptr;
}
re2::RE2::ErrorCode FilteredRE2Wrapper::add(StringView pattern,
const re2::RE2::Options &options,
int *id) {
return inner_->Add(pattern.into_absl_view(), options, id);
}
size_t FilteredRE2Wrapper::num_regexps() const noexcept {
return inner_->NumRegexps();
}
const re2::RE2 *FilteredRE2Wrapper::get_re2(const int regexpid) const {
return &inner_->GetRE2(regexpid);
}
void FilteredRE2Wrapper::compile(StringSet *strings_to_match) {
std::vector<std::string> args;
inner_->Compile(&args);
StringSet::from_result(std::move(args), strings_to_match);
}
int FilteredRE2Wrapper::slow_first_match(StringView text) const {
return inner_->SlowFirstMatch(text.into_absl_view());
}
int FilteredRE2Wrapper::first_match(StringView text,
const MatchedSetInfo &atoms) const {
return inner_->FirstMatch(text.into_absl_view(), *atoms.get_mutable());
}
bool FilteredRE2Wrapper::all_matches(StringView text,
const MatchedSetInfo &atoms,
MatchedSetInfo *matching_regexps) const {
return inner_->AllMatches(text.into_absl_view(), *atoms.get_mutable(),
matching_regexps->get_mutable());
}
void FilteredRE2Wrapper::all_potentials(
const MatchedSetInfo &atoms, MatchedSetInfo *potential_regexps) const {
inner_->AllPotentials(*atoms.get_mutable(), potential_regexps->get_mutable());
}
}