vbscript: Added RegExp2::Test implementation.
This commit is contained in:
parent
820c7635ab
commit
4b0f475344
|
@ -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
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_free(heap_pool_t *heap)
|
||||
void *heap_pool_grow(heap_pool_t *heap, void *mem, DWORD size, DWORD inc)
|
||||
{
|
||||
struct list *iter;
|
||||
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;
|
||||
|
||||
while((iter = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
|
||||
list_remove(iter);
|
||||
heap_free(iter);
|
||||
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)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue