RE2Regex(const std::string& rx) : Regex(rx), regexcl(rx, RE2::Quiet) { if (!regexcl.ok()) { throw RegexException(rx, regexcl.error()); } }
JNIEXPORT jlong JNICALL Java_com_logentries_re2_RE2_compileImpl (JNIEnv *env, jclass cls, jstring j_str, jobject j_options) { Options options(env, j_options); const char *str = env->GetStringUTFChars(j_str, 0); RE2 *pointer = new RE2(str, options); if (pointer->ok()) { env->ReleaseStringUTFChars(j_str, str); jlong j_pointer = reinterpret_cast<jlong>(pointer); assert(reinterpret_cast<RE2*>(j_pointer) == pointer); return j_pointer; } else { throw_RegExprException(env, pointer->error().c_str()); delete pointer; return 0; } }
/* returns (cre2__obj_t * int * (string * int) list) where * - cre2__obj_t is the ML-side name for a custom_block with a struct regex * * - int is the number of submatches, including the whole match * - (string * int) list is the Map.to_alist of the submatch (name, index) Map.t */ CAMLprim value mlre2__create_re(value v_options, value v_pattern) { value v_retval, v_compile_error; const char * c_pat = String_val(v_pattern); RE2::Options opt; RE2* compiled = NULL; opt.Copy(RE2::Quiet); while (v_options != Val_emptylist) { int val = Int_val(Field(Field(v_options, 0), 0)); switch (Tag_val(Field(v_options, 0))) { #define X(_u,FIRST,REST,_uu) case FIRST##REST : opt.set_##FIRST##REST(val); break; #define X__ENCODING(_u,FIRST,REST,_uu,SUFFIX,_uuu,TRANSLATED) \ case FIRST##REST##SUFFIX : opt.set_##FIRST##REST(val TRANSLATED); break; #define X__MAXMEM(_u,FIRST,REST,_uu) X(_u,FIRST,REST,_uu) #include "enum_x_macro.h" default : caml_invalid_argument("invalid option\n"); } v_options = Field(v_options, 1); } compiled = new RE2(c_pat, opt); if (!compiled->ok()) { /* Warning from this point on it's no longer safe to access v_options or v_pattern as the GC might be invoked from caml_copy_string and move those values (as we haven't registered the paramters they wouldn't get updated). This is fine because we don't access them before we call caml_raise_with_arg. */ v_compile_error = caml_copy_string(compiled->error().c_str()); delete compiled; compiled = NULL; caml_raise_with_arg(*caml_named_value("mlre2__Regex_compile_failed"), v_compile_error); } v_retval = caml_alloc_custom(&mlre2__custom_regex_ops, sizeof(compiled), 1024*1024, /* RE2 object uses ~1MB of memory outside the OCaml heap */ 500*1024*1024); /* I'm okay with 500MB of RAM being wasted */ Regex_val(v_retval) = compiled; return v_retval; }