/* Makes compiled regular expression from compilation options, an optional value of chartables and the pattern string */ CAMLprim value pcre_compile_stub(value v_opt, value v_tables, value v_pat) { value v_rex; /* Final result -> value of type [regexp] */ const char *error = NULL; /* pointer to possible error message */ int error_ofs = 0; /* offset in the pattern at which error occurred */ /* If v_tables = [None], then pointer to tables is NULL, otherwise set it to the appropriate value */ chartables tables = (v_tables == None) ? NULL : (chartables) Field(Field(v_tables, 0), 1); /* Compiles the pattern */ pcre *regexp = pcre_compile(String_val(v_pat), Int_val(v_opt), &error, &error_ofs, tables); /* Raises appropriate exception [BadPattern] if the pattern could not be compiled */ if (regexp == NULL) raise_with_two_args(*pcre_exc_BadPattern, caml_copy_string((char *) error), Val_int(error_ofs)); /* Finalized value: GC will do a full cycle every 500 regexp allocations (one regexp consumes in average probably less than 100 bytes -> maximum of 50000 bytes unreclaimed regexps) */ v_rex = caml_alloc_final(4, pcre_dealloc_regexp, 100, 50000); /* Field[1]: compiled regular expression (Field[0] is finalizing function! See above!) */ Field(v_rex, 1) = (value) regexp; /* Field[2]: extra information about regexp when it has been studied successfully */ Field(v_rex, 2) = (value) NULL; /* Field[3]: If 0 -> regexp has not yet been studied 1 -> regexp has already been studied */ Field(v_rex, 3) = 0; return v_rex; }
static inline void range_check(int v, int max) { if (v < 0 || v >= max) raise_with_two_args(*caml_sqlite3_RangeError, Val_int(v), Val_int(max)); }
static inline void raise_io_error(value v_n_good, value v_exc) { raise_with_two_args(*bigstring_exc_IOError, v_n_good, v_exc); }