[GB.PCRE]

* BUG: Fix two cases of memory leaks with CREGEXP->code: (re)compilation of
  a (new) pattern and object destruction.
* NEW: Introduce the static RegExp.Check() method which works like the
  constructor but immediately returns a boolean whether the pattern could
  be applied to the subject - handy for one-line string validation.



git-svn-id: svn://localhost/gambas/trunk@5727 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Tobias Boege 2013-07-11 14:50:13 +00:00
parent aaf6e45351
commit b6718e1361

View file

@ -47,6 +47,9 @@ static void compile(void *_object)
return;
}
if (THIS->code)
free(THIS->code);
THIS->code = pcre_compile(THIS->pattern, THIS->copts, &errstr, &errptr, NULL);
if (!THIS->code)
@ -180,6 +183,7 @@ BEGIN_METHOD(RegExp_new, GB_STRING subject; GB_STRING pattern; GB_INTEGER coptio
THIS->copts = VARGOPT(coptions, 0);
THIS->pattern = GB.NewString(STRING(pattern), LENGTH(pattern));
THIS->code = NULL;
compile(THIS);
if (!THIS->code) // we didn't get a compiled pattern back.
@ -198,6 +202,8 @@ END_METHOD
BEGIN_METHOD_VOID(RegExp_free)
if (THIS->code)
free(THIS->code);
GB.FreeString(&THIS->subject);
GB.FreeString(&THIS->pattern);
GB.Free(POINTER(&THIS->ovector));
@ -205,6 +211,41 @@ BEGIN_METHOD_VOID(RegExp_free)
END_METHOD
BEGIN_METHOD(RegExp_Check, GB_STRING subject; GB_STRING pattern; GB_INTEGER coptions; GB_INTEGER eoptions)
/*
* The gb.pcre internal routines don't require the GB_BASE to be
* initialised by Gambas!
*/
CREGEXP tmp;
bzero(&tmp, sizeof(tmp));
tmp.ovecsize = OVECSIZE_INC;
GB.Alloc(POINTER(&tmp.ovector), sizeof(int) * tmp.ovecsize);
tmp.copts = VARGOPT(coptions, 0);
tmp.pattern = GB.NewString(STRING(pattern), LENGTH(pattern));
compile(&tmp);
if (!tmp.code) {
GB.Free(POINTER(&tmp.ovector));
GB.FreeString(&tmp.pattern);
return;
}
tmp.eopts = VARGOPT(eoptions, 0);
tmp.subject = GB.NewString(STRING(subject), LENGTH(subject));
exec(&tmp);
GB.ReturnBoolean(tmp.ovector[0] != -1);
free(tmp.code);
GB.FreeString(&tmp.subject);
GB.FreeString(&tmp.pattern);
GB.Free(POINTER(&tmp.ovector));
END_METHOD
BEGIN_PROPERTY(RegExp_Pattern)
GB.ReturnString(THIS->pattern);
@ -290,6 +331,8 @@ GB_DESC CRegexpDesc[] =
GB_METHOD("Compile", NULL, RegExp_Compile, "(Pattern)s[(CompileOptions)i]"),
GB_METHOD("Exec", NULL, RegExp_Exec, "(Subject)s[(ExecOptions)i]"),
GB_STATIC_METHOD("Check", "b", RegExp_Check, "(Subject)s(Pattern)s[(CompileOptions)i(ExecOptions)i]"),
GB_CONSTANT("Caseless", "i", PCRE_CASELESS),
GB_CONSTANT("MultiLine", "i", PCRE_MULTILINE),
GB_CONSTANT("DotAll", "i", PCRE_DOTALL),