vbscript: Added RegExp2::Test implementation.

oldstable
Piotr Caban 2013-02-19 12:39:47 +01:00 committed by Alexandre Julliard
parent 820c7635ab
commit 4b0f475344
6 changed files with 3480 additions and 7 deletions

View File

@ -7,6 +7,7 @@ C_SRCS = \
global.c \
interp.c \
lex.c \
regexp.c \
vbdisp.c \
vbregexp.c \
vbscript.c \

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
/*
* Copyright 2008 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* Code in this file is based on files:
* js/src/jsregexp.h
* js/src/jsregexp.c
* from Mozilla project, released under LGPL 2.1 or later.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*/
#define REG_FOLD 0x01 /* fold uppercase to lowercase */
#define REG_GLOB 0x02 /* global exec, creates array of matches */
#define REG_MULTILINE 0x04 /* treat ^ and $ as begin and end of line */
#define REG_STICKY 0x08 /* only match starting at lastIndex */
typedef struct RECapture {
ptrdiff_t index; /* start of contents, -1 for empty */
size_t length; /* length of capture */
} RECapture;
typedef struct match_state_t {
const WCHAR *cp;
DWORD match_len;
DWORD paren_count;
RECapture parens[1];
} match_state_t;
typedef BYTE jsbytecode;
typedef struct regexp_t {
WORD flags; /* flags, see jsapi.h's REG_* defines */
size_t parenCount; /* number of parenthesized submatches */
size_t classCount; /* count [...] bitmaps */
struct RECharSet *classList; /* list of [...] bitmaps */
const WCHAR *source; /* locked source string, sans // */
DWORD source_len;
jsbytecode program[1]; /* regular expression bytecode */
} regexp_t;
regexp_t* regexp_new(void*, heap_pool_t*, const WCHAR*, DWORD, WORD, BOOL) DECLSPEC_HIDDEN;
void regexp_destroy(regexp_t*) DECLSPEC_HIDDEN;
HRESULT regexp_execute(regexp_t*, void*, heap_pool_t*, const WCHAR*,
DWORD, match_state_t*) DECLSPEC_HIDDEN;
static inline match_state_t* alloc_match_state(regexp_t *regexp,
heap_pool_t *pool, const WCHAR *pos)
{
size_t size = offsetof(match_state_t, parens) + regexp->parenCount*sizeof(RECapture);
match_state_t *ret;
ret = pool ? heap_pool_alloc(pool, size) : heap_alloc(size);
if(!ret)
return NULL;
ret->cp = pos;
return ret;
}

View File

@ -17,6 +17,7 @@
*/
#include "vbscript.h"
#include "regexp.h"
#include "vbsregexp55.h"
#include "wine/debug.h"
@ -86,6 +87,9 @@ typedef struct {
LONG ref;
WCHAR *pattern;
regexp_t *regexp;
heap_pool_t pool;
WORD flags;
} RegExp2;
static inline RegExp2 *impl_from_IRegExp2(IRegExp2 *iface)
@ -138,6 +142,9 @@ static ULONG WINAPI RegExp2_Release(IRegExp2 *iface)
if(!ref) {
heap_free(This->pattern);
if(This->regexp)
regexp_destroy(This->regexp);
heap_pool_free(&This->pool);
heap_free(This);
}
@ -214,6 +221,10 @@ static HRESULT WINAPI RegExp2_put_Pattern(IRegExp2 *iface, BSTR pattern)
if(!pattern) {
heap_free(This->pattern);
if(This->regexp) {
regexp_destroy(This->regexp);
This->regexp = NULL;
}
This->pattern = NULL;
return S_OK;
}
@ -226,6 +237,10 @@ static HRESULT WINAPI RegExp2_put_Pattern(IRegExp2 *iface, BSTR pattern)
heap_free(This->pattern);
This->pattern = p;
memcpy(p, pattern, size);
if(This->regexp) {
regexp_destroy(This->regexp);
This->regexp = NULL;
}
return S_OK;
}
@ -282,8 +297,43 @@ static HRESULT WINAPI RegExp2_Execute(IRegExp2 *iface,
static HRESULT WINAPI RegExp2_Test(IRegExp2 *iface, BSTR sourceString, VARIANT_BOOL *pMatch)
{
RegExp2 *This = impl_from_IRegExp2(iface);
FIXME("(%p)->(%s %p)\n", This, debugstr_w(sourceString), pMatch);
return E_NOTIMPL;
match_state_t *result;
heap_pool_t *mark;
HRESULT hres;
TRACE("(%p)->(%s %p)\n", This, debugstr_w(sourceString), pMatch);
if(!This->pattern) {
*pMatch = VARIANT_TRUE;
return S_OK;
}
if(!This->regexp) {
This->regexp = regexp_new(NULL, &This->pool, This->pattern,
strlenW(This->pattern), This->flags, FALSE);
if(!This->regexp)
return E_FAIL;
}
mark = heap_pool_mark(&This->pool);
result = alloc_match_state(This->regexp, &This->pool, sourceString);
if(!result) {
heap_pool_clear(mark);
return E_OUTOFMEMORY;
}
hres = regexp_execute(This->regexp, NULL, &This->pool,
sourceString, SysStringLen(sourceString), result);
heap_pool_clear(mark);
if(hres == S_OK) {
*pMatch = VARIANT_TRUE;
}else if(hres == S_FALSE) {
*pMatch = VARIANT_FALSE;
hres = S_OK;
}
return hres;
}
static HRESULT WINAPI RegExp2_Replace(IRegExp2 *iface, BSTR sourceString,
@ -466,6 +516,7 @@ HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory *iface, IUnkno
ret->IRegExp_iface.lpVtbl = &RegExpVtbl;
ret->ref = 1;
heap_pool_init(&ret->pool);
hres = IRegExp2_QueryInterface(&ret->IRegExp2_iface, riid, ppv);
IRegExp2_Release(&ret->IRegExp2_iface);

View File

@ -36,12 +36,16 @@ typedef struct {
DWORD block_cnt;
DWORD last_block;
DWORD offset;
BOOL mark;
struct list custom_blocks;
} heap_pool_t;
void heap_pool_init(heap_pool_t*) DECLSPEC_HIDDEN;
void *heap_pool_alloc(heap_pool_t*,size_t) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN;
void *heap_pool_grow(heap_pool_t*,void*,DWORD,DWORD) DECLSPEC_HIDDEN;
void heap_pool_clear(heap_pool_t*) DECLSPEC_HIDDEN;
void heap_pool_free(heap_pool_t*) DECLSPEC_HIDDEN;
heap_pool_t *heap_pool_mark(heap_pool_t*) DECLSPEC_HIDDEN;
typedef struct _function_t function_t;
typedef struct _vbscode_t vbscode_t;

View File

@ -29,6 +29,7 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
WINE_DECLARE_DEBUG_CHANNEL(heap);
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
@ -127,6 +128,7 @@ const char *debugstr_variant(const VARIANT *v)
}
#define MIN_BLOCK_SIZE 128
#define ARENA_FREE_FILLER 0xaa
static inline DWORD block_size(DWORD block)
{
@ -194,19 +196,65 @@ void *heap_pool_alloc(heap_pool_t *heap, size_t size)
return list+1;
}
void *heap_pool_grow(heap_pool_t *heap, void *mem, DWORD size, DWORD inc)
{
void *ret;
if(mem == (BYTE*)heap->blocks[heap->last_block] + heap->offset-size
&& heap->offset+inc < block_size(heap->last_block)) {
heap->offset += inc;
return mem;
}
ret = heap_pool_alloc(heap, size+inc);
if(ret) /* FIXME: avoid copying for custom blocks */
memcpy(ret, mem, size);
return ret;
}
void heap_pool_clear(heap_pool_t *heap)
{
struct list *tmp;
if(!heap)
return;
while((tmp = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
list_remove(tmp);
heap_free(tmp);
}
if(WARN_ON(heap)) {
DWORD i;
for(i=0; i < heap->block_cnt; i++)
memset(heap->blocks[i], ARENA_FREE_FILLER, block_size(i));
}
heap->last_block = heap->offset = 0;
heap->mark = FALSE;
}
void heap_pool_free(heap_pool_t *heap)
{
struct list *iter;
DWORD i;
while((iter = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
list_remove(iter);
heap_free(iter);
}
heap_pool_clear(heap);
for(i=0; i < heap->block_cnt; i++)
heap_free(heap->blocks[i]);
heap_free(heap->blocks);
heap_pool_init(heap);
}
heap_pool_t *heap_pool_mark(heap_pool_t *heap)
{
if(heap->mark)
return NULL;
heap->mark = TRUE;
return heap;
}
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)