ext/re2/re2.cc in re2-0.0.2 vs ext/re2/re2.cc in re2-0.0.3
- old
+ new
@@ -17,20 +17,20 @@
#if !defined(RSTRING_LEN)
# define RSTRING_LEN(x) (RSTRING(x)->len)
#endif
- typedef struct _re2p {
+ struct re2_pattern {
RE2 *pattern;
- } re2_pattern;
+ };
VALUE re2_cRE2;
/* Symbols used in RE2 options. */
static ID id_utf8, id_posix_syntax, id_longest_match, id_log_errors,
- id_max_mem, id_literal, id_never_nl, id_case_sensitive,
- id_perl_classes, id_word_boundary, id_one_line;
+ id_max_mem, id_literal, id_never_nl, id_case_sensitive,
+ id_perl_classes, id_word_boundary, id_one_line;
void
re2_free(re2_pattern* self)
{
if (self->pattern) {
@@ -40,13 +40,12 @@
}
static VALUE
re2_allocate(VALUE klass)
{
- re2_pattern *p = (re2_pattern*)malloc(sizeof(re2_pattern));
- p->pattern = NULL;
- return Data_Wrap_Struct(klass, 0, re2_free, p);
+ re2_pattern *p;
+ return Data_Make_Struct(klass, re2_pattern, 0, re2_free, p);
}
/*
* call-seq:
* RE2(pattern) -> re2
@@ -122,12 +121,16 @@
if (RTEST(options)) {
if (TYPE(options) != T_HASH) {
rb_raise(rb_eArgError, "options should be a hash");
}
- re2_options = new RE2::Options();
+ re2_options = new (std::nothrow) RE2::Options();
+ if (re2_options == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate RE2::Options");
+ }
+
utf8 = rb_hash_aref(options, ID2SYM(id_utf8));
if (!NIL_P(utf8)) {
re2_options->set_utf8(RTEST(utf8));
}
@@ -179,15 +182,19 @@
one_line = rb_hash_aref(options, ID2SYM(id_one_line));
if (!NIL_P(one_line)) {
re2_options->set_one_line(RTEST(one_line));
}
- p->pattern = new RE2(StringValuePtr(pattern), *re2_options);
+ p->pattern = new (std::nothrow) RE2(StringValuePtr(pattern), *re2_options);
} else {
- p->pattern = new RE2(StringValuePtr(pattern));
+ p->pattern = new (std::nothrow) RE2(StringValuePtr(pattern));
}
+ if (p->pattern == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate RE2 object");
+ }
+
return self;
}
/*
* call-seq:
@@ -200,11 +207,11 @@
* re2.inspect #=> "/woo?/"
*/
static VALUE
re2_inspect(VALUE self)
{
- VALUE result = rb_str_buf_new(0);
+ VALUE result = rb_str_buf_new(2);
re2_pattern *p;
rb_str_buf_cat2(result, "/");
Data_Get_Struct(self, re2_pattern, p);
rb_str_buf_cat2(result, p->pattern->pattern().c_str());
@@ -622,23 +629,38 @@
n = NUM2INT(number_of_matches);
} else {
n = p->pattern->NumberOfCapturingGroups();
}
- text_as_string_piece = new re2::StringPiece(StringValuePtr(text));
+ text_as_string_piece = new (std::nothrow) re2::StringPiece(StringValuePtr(text));
+ if (text_as_string_piece == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate StringPiece for text");
+ }
+
if (n == 0) {
- return BOOL2RUBY(p->pattern->Match(*text_as_string_piece, 0, RE2::UNANCHORED, 0, 0));
+ matched = p->pattern->Match(*text_as_string_piece, 0, RE2::UNANCHORED, 0, 0);
+
+ delete text_as_string_piece;
+
+ return BOOL2RUBY(matched);
+
} else {
/* Because match returns the whole match as well. */
n += 1;
- string_matches = new re2::StringPiece[n];
+ string_matches = new (std::nothrow) re2::StringPiece[n];
+ if (string_matches == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate array of StringPieces for matches");
+ }
+
matched = p->pattern->Match(*text_as_string_piece, 0, RE2::UNANCHORED, string_matches, n);
+ delete text_as_string_piece;
+
if (matched) {
matches = rb_ary_new();
for (int i = 0; i < n; i++) {
if (!string_matches[i].empty()) {
@@ -646,12 +668,17 @@
} else {
rb_ary_push(matches, Qnil);
}
}
+ delete[] string_matches;
+
return matches;
} else {
+
+ delete[] string_matches;
+
return Qnil;
}
}
}
@@ -727,38 +754,63 @@
static VALUE
re2_FullMatchN(VALUE self, VALUE text, VALUE re)
{
UNUSED(self);
int n;
- bool matched;
+ bool matched, re2_given;
re2_pattern *p;
VALUE matches;
RE2 *compiled_pattern;
RE2::Arg *argv;
const RE2::Arg **args;
std::string *string_matches;
- if (rb_obj_is_kind_of(re, re2_cRE2)) {
+ re2_given = rb_obj_is_kind_of(re, re2_cRE2);
+
+ if (re2_given) {
Data_Get_Struct(re, re2_pattern, p);
compiled_pattern = p->pattern;
} else {
- compiled_pattern = new RE2(StringValuePtr(re));
+ compiled_pattern = new (std::nothrow) RE2(StringValuePtr(re));
+
+ if (compiled_pattern == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate RE2 object for pattern");
+ }
}
n = compiled_pattern->NumberOfCapturingGroups();
- argv = new RE2::Arg[n];
- args = new const RE2::Arg*[n];
- string_matches = new std::string[n];
+ argv = new (std::nothrow) RE2::Arg[n];
+ args = new (std::nothrow) const RE2::Arg*[n];
+ string_matches = new (std::nothrow) std::string[n];
+ if (argv == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate array of RE2::Args");
+ }
+
+ if (args == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate array of pointers to RE2::Args");
+ }
+
+ if (string_matches == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate array of strings for matches");
+ }
+
for (int i = 0; i < n; i++) {
args[i] = &argv[i];
argv[i] = &string_matches[i];
}
matched = RE2::FullMatchN(StringValuePtr(text), *compiled_pattern, args, n);
+ if (!re2_given) {
+ delete compiled_pattern;
+ }
+
+ delete[] argv;
+ delete[] args;
+
if (matched) {
matches = rb_ary_new();
for (int i = 0; i < n; i++) {
if (!string_matches[i].empty()) {
@@ -766,12 +818,15 @@
} else {
rb_ary_push(matches, Qnil);
}
}
+ delete[] string_matches;
+
return matches;
} else {
+ delete[] string_matches;
return Qnil;
}
}
/*
@@ -786,38 +841,63 @@
static VALUE
re2_PartialMatchN(VALUE self, VALUE text, VALUE re)
{
UNUSED(self);
int n;
- bool matched;
+ bool matched, re2_given;
re2_pattern *p;
VALUE matches;
RE2 *compiled_pattern;
RE2::Arg *argv;
const RE2::Arg **args;
std::string *string_matches;
- if (rb_obj_is_kind_of(re, re2_cRE2)) {
+ re2_given = rb_obj_is_kind_of(re, re2_cRE2);
+
+ if (re2_given) {
Data_Get_Struct(re, re2_pattern, p);
compiled_pattern = p->pattern;
} else {
- compiled_pattern = new RE2(StringValuePtr(re));
+ compiled_pattern = new (std::nothrow) RE2(StringValuePtr(re));
+
+ if (compiled_pattern == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate RE2 object for pattern");
+ }
}
n = compiled_pattern->NumberOfCapturingGroups();
- argv = new RE2::Arg[n];
- args = new const RE2::Arg*[n];
- string_matches = new std::string[n];
+ argv = new (std::nothrow) RE2::Arg[n];
+ args = new (std::nothrow) const RE2::Arg*[n];
+ string_matches = new (std::nothrow) std::string[n];
+ if (argv == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate array of RE2::Args");
+ }
+
+ if (args == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate array of pointers to RE2::Args");
+ }
+
+ if (string_matches == 0) {
+ rb_raise(rb_eNoMemError, "not enough memory to allocate array of strings for matches");
+ }
+
for (int i = 0; i < n; i++) {
args[i] = &argv[i];
argv[i] = &string_matches[i];
}
matched = RE2::PartialMatchN(StringValuePtr(text), *compiled_pattern, args, n);
+ if (!re2_given) {
+ delete compiled_pattern;
+ }
+
+ delete[] argv;
+ delete[] args;
+
if (matched) {
matches = rb_ary_new();
for (int i = 0; i < n; i++) {
if (!string_matches[i].empty()) {
@@ -825,11 +905,14 @@
} else {
rb_ary_push(matches, Qnil);
}
}
+ delete[] string_matches;
+
return matches;
} else {
+ delete[] string_matches;
return Qnil;
}
}
/*