2 * Copyright 2013 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "vbsregexp55.h"
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
27 #define REGEXP_TID_LIST \
30 XDIID(MatchCollection2), \
34 #define XDIID(iface) iface ## _tid
40 static REFIID tid_ids[] = {
41 #define XDIID(iface) &IID_I ## iface
46 static ITypeLib *typelib;
47 static ITypeInfo *typeinfos[REGEXP_LAST_tid];
49 static HRESULT init_regexp_typeinfo(regexp_tid_t tid)
54 static const WCHAR vbscript_dll3W[] = {'v','b','s','c','r','i','p','t','.','d','l','l','\\','3',0};
57 hres = LoadTypeLib(vbscript_dll3W, &tl);
59 ERR("LoadRegTypeLib failed: %08x\n", hres);
63 if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
70 hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
72 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
76 if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
77 ITypeInfo_Release(ti);
84 ISubMatches ISubMatches_iface;
89 match_state_t *result;
92 typedef struct Match2 {
93 IMatch2 IMatch2_iface;
99 SubMatches *sub_matches;
102 typedef struct MatchCollectionEnum {
103 IEnumVARIANT IEnumVARIANT_iface;
107 IMatchCollection2 *mc;
110 } MatchCollectionEnum;
112 typedef struct MatchCollection2 {
113 IMatchCollection2 IMatchCollection2_iface;
114 IMatchCollection IMatchCollection_iface;
123 typedef struct RegExp2 {
124 IRegExp2 IRegExp2_iface;
125 IRegExp IRegExp_iface;
135 static inline SubMatches* impl_from_ISubMatches(ISubMatches *iface)
137 return CONTAINING_RECORD(iface, SubMatches, ISubMatches_iface);
140 static HRESULT WINAPI SubMatches_QueryInterface(
141 ISubMatches *iface, REFIID riid, void **ppv)
143 SubMatches *This = impl_from_ISubMatches(iface);
145 if(IsEqualGUID(riid, &IID_IUnknown)) {
146 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
147 *ppv = &This->ISubMatches_iface;
148 }else if(IsEqualGUID(riid, &IID_IDispatch)) {
149 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
150 *ppv = &This->ISubMatches_iface;
151 }else if(IsEqualGUID(riid, &IID_ISubMatches)) {
152 TRACE("(%p)->(IID_ISubMatches %p)\n", This, ppv);
153 *ppv = &This->ISubMatches_iface;
154 }else if(IsEqualGUID(riid, &IID_IDispatchEx)) {
155 TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
157 return E_NOINTERFACE;
159 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
161 return E_NOINTERFACE;
164 IUnknown_AddRef((IUnknown*)*ppv);
168 static ULONG WINAPI SubMatches_AddRef(ISubMatches *iface)
170 SubMatches *This = impl_from_ISubMatches(iface);
171 LONG ref = InterlockedIncrement(&This->ref);
173 TRACE("(%p) ref=%d\n", This, ref);
178 static ULONG WINAPI SubMatches_Release(ISubMatches *iface)
180 SubMatches *This = impl_from_ISubMatches(iface);
181 LONG ref = InterlockedDecrement(&This->ref);
183 TRACE("(%p) ref=%d\n", This, ref);
186 heap_free(This->match);
187 heap_free(This->result);
194 static HRESULT WINAPI SubMatches_GetTypeInfoCount(ISubMatches *iface, UINT *pctinfo)
196 SubMatches *This = impl_from_ISubMatches(iface);
198 TRACE("(%p)->(%p)\n", This, pctinfo);
204 static HRESULT WINAPI SubMatches_GetTypeInfo(ISubMatches *iface,
205 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
207 SubMatches *This = impl_from_ISubMatches(iface);
208 FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
212 static HRESULT WINAPI SubMatches_GetIDsOfNames(ISubMatches *iface,
213 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
215 SubMatches *This = impl_from_ISubMatches(iface);
217 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid),
218 rgszNames, cNames, lcid, rgDispId);
220 return ITypeInfo_GetIDsOfNames(typeinfos[SubMatches_tid], rgszNames, cNames, rgDispId);
223 static HRESULT WINAPI SubMatches_Invoke(ISubMatches *iface, DISPID dispIdMember,
224 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
225 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
227 SubMatches *This = impl_from_ISubMatches(iface);
229 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
230 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
232 return ITypeInfo_Invoke(typeinfos[SubMatches_tid], iface, dispIdMember, wFlags,
233 pDispParams, pVarResult, pExcepInfo, puArgErr);
236 static HRESULT WINAPI SubMatches_get_Item(ISubMatches *iface,
237 LONG index, VARIANT *pSubMatch)
239 SubMatches *This = impl_from_ISubMatches(iface);
241 TRACE("(%p)->(%d %p)\n", This, index, pSubMatch);
246 if(!This->result || index<0 || index>=This->result->paren_count)
249 if(This->result->parens[index].index == -1) {
250 V_VT(pSubMatch) = VT_EMPTY;
252 V_VT(pSubMatch) = VT_BSTR;
253 V_BSTR(pSubMatch) = SysAllocStringLen(
254 This->match+This->result->parens[index].index,
255 This->result->parens[index].length);
257 if(!V_BSTR(pSubMatch))
258 return E_OUTOFMEMORY;
264 static HRESULT WINAPI SubMatches_get_Count(ISubMatches *iface, LONG *pCount)
266 SubMatches *This = impl_from_ISubMatches(iface);
268 TRACE("(%p)->(%p)\n", This, pCount);
276 *pCount = This->result->paren_count;
280 static HRESULT WINAPI SubMatches_get__NewEnum(ISubMatches *iface, IUnknown **ppEnum)
282 SubMatches *This = impl_from_ISubMatches(iface);
283 FIXME("(%p)->(%p)\n", This, ppEnum);
287 static const ISubMatchesVtbl SubMatchesVtbl = {
288 SubMatches_QueryInterface,
291 SubMatches_GetTypeInfoCount,
292 SubMatches_GetTypeInfo,
293 SubMatches_GetIDsOfNames,
296 SubMatches_get_Count,
297 SubMatches_get__NewEnum
300 static HRESULT create_sub_matches(DWORD pos, match_state_t *result, SubMatches **sub_matches)
306 hres = init_regexp_typeinfo(SubMatches_tid);
310 ret = heap_alloc_zero(sizeof(*ret));
312 return E_OUTOFMEMORY;
314 ret->ISubMatches_iface.lpVtbl = &SubMatchesVtbl;
316 ret->result = result;
318 ret->match = heap_alloc((result->match_len+1) * sizeof(WCHAR));
321 return E_OUTOFMEMORY;
323 memcpy(ret->match, result->cp-result->match_len, result->match_len*sizeof(WCHAR));
324 ret->match[result->match_len] = 0;
327 for(i=0; i<result->paren_count; i++)
328 if(result->parens[i].index != -1)
329 result->parens[i].index -= pos;
339 static inline Match2* impl_from_IMatch2(IMatch2 *iface)
341 return CONTAINING_RECORD(iface, Match2, IMatch2_iface);
344 static HRESULT WINAPI Match2_QueryInterface(
345 IMatch2 *iface, REFIID riid, void **ppv)
347 Match2 *This = impl_from_IMatch2(iface);
349 if(IsEqualGUID(riid, &IID_IUnknown)) {
350 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
351 *ppv = &This->IMatch2_iface;
352 }else if(IsEqualGUID(riid, &IID_IDispatch)) {
353 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
354 *ppv = &This->IMatch2_iface;
355 }else if(IsEqualGUID(riid, &IID_IMatch2)) {
356 TRACE("(%p)->(IID_IMatch2 %p)\n", This, ppv);
357 *ppv = &This->IMatch2_iface;
358 }else if(IsEqualGUID(riid, &IID_IMatch)) {
359 TRACE("(%p)->(IID_IMatch %p)\n", This, ppv);
360 *ppv = &This->IMatch_iface;
361 }else if(IsEqualGUID(riid, &IID_IDispatchEx)) {
362 TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
364 return E_NOINTERFACE;
366 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
368 return E_NOINTERFACE;
371 IUnknown_AddRef((IUnknown*)*ppv);
375 static ULONG WINAPI Match2_AddRef(IMatch2 *iface)
377 Match2 *This = impl_from_IMatch2(iface);
378 LONG ref = InterlockedIncrement(&This->ref);
380 TRACE("(%p) ref=%d\n", This, ref);
385 static ULONG WINAPI Match2_Release(IMatch2 *iface)
387 Match2 *This = impl_from_IMatch2(iface);
388 LONG ref = InterlockedDecrement(&This->ref);
390 TRACE("(%p) ref=%d\n", This, ref);
393 ISubMatches_Release(&This->sub_matches->ISubMatches_iface);
400 static HRESULT WINAPI Match2_GetTypeInfoCount(IMatch2 *iface, UINT *pctinfo)
402 Match2 *This = impl_from_IMatch2(iface);
404 TRACE("(%p)->(%p)\n", This, pctinfo);
410 static HRESULT WINAPI Match2_GetTypeInfo(IMatch2 *iface,
411 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
413 Match2 *This = impl_from_IMatch2(iface);
414 FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
418 static HRESULT WINAPI Match2_GetIDsOfNames(IMatch2 *iface,
419 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
421 Match2 *This = impl_from_IMatch2(iface);
423 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid),
424 rgszNames, cNames, lcid, rgDispId);
426 return ITypeInfo_GetIDsOfNames(typeinfos[Match2_tid], rgszNames, cNames, rgDispId);
429 static HRESULT WINAPI Match2_Invoke(IMatch2 *iface, DISPID dispIdMember,
430 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
431 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
433 Match2 *This = impl_from_IMatch2(iface);
435 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
436 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
438 return ITypeInfo_Invoke(typeinfos[Match2_tid], iface, dispIdMember, wFlags,
439 pDispParams, pVarResult, pExcepInfo, puArgErr);
442 static HRESULT WINAPI Match2_get_Value(IMatch2 *iface, BSTR *pValue)
444 Match2 *This = impl_from_IMatch2(iface);
446 TRACE("(%p)->(%p)\n", This, pValue);
451 if(!This->sub_matches->match) {
456 *pValue = SysAllocString(This->sub_matches->match);
457 return *pValue ? S_OK : E_OUTOFMEMORY;
460 static HRESULT WINAPI Match2_get_FirstIndex(IMatch2 *iface, LONG *pFirstIndex)
462 Match2 *This = impl_from_IMatch2(iface);
464 TRACE("(%p)->(%p)\n", This, pFirstIndex);
469 *pFirstIndex = This->index;
473 static HRESULT WINAPI Match2_get_Length(IMatch2 *iface, LONG *pLength)
475 Match2 *This = impl_from_IMatch2(iface);
477 TRACE("(%p)->(%p)\n", This, pLength);
482 if(This->sub_matches->result)
483 *pLength = This->sub_matches->result->match_len;
489 static HRESULT WINAPI Match2_get_SubMatches(IMatch2 *iface, IDispatch **ppSubMatches)
491 Match2 *This = impl_from_IMatch2(iface);
493 TRACE("(%p)->(%p)\n", This, ppSubMatches);
498 *ppSubMatches = (IDispatch*)&This->sub_matches->ISubMatches_iface;
499 ISubMatches_AddRef(&This->sub_matches->ISubMatches_iface);
503 static const IMatch2Vtbl Match2Vtbl = {
504 Match2_QueryInterface,
507 Match2_GetTypeInfoCount,
509 Match2_GetIDsOfNames,
512 Match2_get_FirstIndex,
514 Match2_get_SubMatches
517 static inline Match2 *impl_from_IMatch(IMatch *iface)
519 return CONTAINING_RECORD(iface, Match2, IMatch_iface);
522 static HRESULT WINAPI Match_QueryInterface(IMatch *iface, REFIID riid, void **ppv)
524 Match2 *This = impl_from_IMatch(iface);
525 return IMatch2_QueryInterface(&This->IMatch2_iface, riid, ppv);
528 static ULONG WINAPI Match_AddRef(IMatch *iface)
530 Match2 *This = impl_from_IMatch(iface);
531 return IMatch2_AddRef(&This->IMatch2_iface);
534 static ULONG WINAPI Match_Release(IMatch *iface)
536 Match2 *This = impl_from_IMatch(iface);
537 return IMatch2_Release(&This->IMatch2_iface);
540 static HRESULT WINAPI Match_GetTypeInfoCount(IMatch *iface, UINT *pctinfo)
542 Match2 *This = impl_from_IMatch(iface);
543 return IMatch2_GetTypeInfoCount(&This->IMatch2_iface, pctinfo);
546 static HRESULT WINAPI Match_GetTypeInfo(IMatch *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
548 Match2 *This = impl_from_IMatch(iface);
549 return IMatch2_GetTypeInfo(&This->IMatch2_iface, iTInfo, lcid, ppTInfo);
552 static HRESULT WINAPI Match_GetIDsOfNames(IMatch *iface, REFIID riid,
553 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
555 Match2 *This = impl_from_IMatch(iface);
556 return IMatch2_GetIDsOfNames(&This->IMatch2_iface, riid, rgszNames, cNames, lcid, rgDispId);
559 static HRESULT WINAPI Match_Invoke(IMatch *iface, DISPID dispIdMember,
560 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
561 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
563 Match2 *This = impl_from_IMatch(iface);
564 return IMatch2_Invoke(&This->IMatch2_iface, dispIdMember, riid, lcid,
565 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
568 static HRESULT WINAPI Match_get_Value(IMatch *iface, BSTR *pValue)
570 Match2 *This = impl_from_IMatch(iface);
571 return IMatch2_get_Value(&This->IMatch2_iface, pValue);
574 static HRESULT WINAPI Match_get_FirstIndex(IMatch *iface, LONG *pFirstIndex)
576 Match2 *This = impl_from_IMatch(iface);
577 return IMatch2_get_FirstIndex(&This->IMatch2_iface, pFirstIndex);
580 static HRESULT WINAPI Match_get_Length(IMatch *iface, LONG *pLength)
582 Match2 *This = impl_from_IMatch(iface);
583 return IMatch2_get_Length(&This->IMatch2_iface, pLength);
586 static IMatchVtbl MatchVtbl = {
587 Match_QueryInterface,
590 Match_GetTypeInfoCount,
595 Match_get_FirstIndex,
599 static HRESULT create_match2(DWORD pos, match_state_t **result, IMatch2 **match)
604 hres = init_regexp_typeinfo(Match2_tid);
608 ret = heap_alloc_zero(sizeof(*ret));
610 return E_OUTOFMEMORY;
613 hres = create_sub_matches(pos, result ? *result : NULL, &ret->sub_matches);
621 ret->IMatch2_iface.lpVtbl = &Match2Vtbl;
622 ret->IMatch_iface.lpVtbl = &MatchVtbl;
625 *match = &ret->IMatch2_iface;
629 static inline MatchCollectionEnum* impl_from_IMatchCollectionEnum(IEnumVARIANT *iface)
631 return CONTAINING_RECORD(iface, MatchCollectionEnum, IEnumVARIANT_iface);
634 static HRESULT WINAPI MatchCollectionEnum_QueryInterface(
635 IEnumVARIANT *iface, REFIID riid, void **ppv)
637 MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
639 if(IsEqualGUID(riid, &IID_IUnknown)) {
640 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
641 *ppv = &This->IEnumVARIANT_iface;
642 }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) {
643 TRACE("(%p)->(IID_IEnumVARIANT %p)\n", This, ppv);
644 *ppv = &This->IEnumVARIANT_iface;
646 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
648 return E_NOINTERFACE;
651 IUnknown_AddRef((IUnknown*)*ppv);
655 static ULONG WINAPI MatchCollectionEnum_AddRef(IEnumVARIANT *iface)
657 MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
658 LONG ref = InterlockedIncrement(&This->ref);
660 TRACE("(%p) ref=%d\n", This, ref);
665 static ULONG WINAPI MatchCollectionEnum_Release(IEnumVARIANT *iface)
667 MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
668 LONG ref = InterlockedDecrement(&This->ref);
670 TRACE("(%p) ref=%d\n", This, ref);
673 IMatchCollection2_Release(This->mc);
680 static HRESULT WINAPI MatchCollectionEnum_Next(IEnumVARIANT *iface,
681 ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
683 MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
687 TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
689 if(This->pos>=This->count) {
695 for(i=0; i<celt && This->pos+i<This->count; i++) {
696 V_VT(rgVar+i) = VT_DISPATCH;
697 hres = IMatchCollection2_get_Item(This->mc, This->pos+i, &V_DISPATCH(rgVar+i));
703 VariantClear(rgVar+i);
713 static HRESULT WINAPI MatchCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt)
715 MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
717 TRACE("(%p)->(%u)\n", This, celt);
719 if(This->pos+celt <= This->count)
722 This->pos = This->count;
726 static HRESULT WINAPI MatchCollectionEnum_Reset(IEnumVARIANT *iface)
728 MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
730 TRACE("(%p)\n", This);
736 static HRESULT WINAPI MatchCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
738 MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
739 FIXME("(%p)->(%p)\n", This, ppEnum);
743 static const IEnumVARIANTVtbl MatchCollectionEnum_Vtbl = {
744 MatchCollectionEnum_QueryInterface,
745 MatchCollectionEnum_AddRef,
746 MatchCollectionEnum_Release,
747 MatchCollectionEnum_Next,
748 MatchCollectionEnum_Skip,
749 MatchCollectionEnum_Reset,
750 MatchCollectionEnum_Clone
753 static HRESULT create_enum_variant_mc2(IMatchCollection2 *mc, ULONG pos, IEnumVARIANT **enum_variant)
755 MatchCollectionEnum *ret;
757 ret = heap_alloc_zero(sizeof(*ret));
759 return E_OUTOFMEMORY;
761 ret->IEnumVARIANT_iface.lpVtbl = &MatchCollectionEnum_Vtbl;
764 IMatchCollection2_get_Count(mc, &ret->count);
766 IMatchCollection2_AddRef(mc);
768 *enum_variant = &ret->IEnumVARIANT_iface;
772 static inline MatchCollection2* impl_from_IMatchCollection2(IMatchCollection2 *iface)
774 return CONTAINING_RECORD(iface, MatchCollection2, IMatchCollection2_iface);
777 static HRESULT WINAPI MatchCollection2_QueryInterface(
778 IMatchCollection2 *iface, REFIID riid, void **ppv)
780 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
782 if(IsEqualGUID(riid, &IID_IUnknown)) {
783 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
784 *ppv = &This->IMatchCollection2_iface;
785 }else if(IsEqualGUID(riid, &IID_IDispatch)) {
786 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
787 *ppv = &This->IMatchCollection2_iface;
788 }else if(IsEqualGUID(riid, &IID_IMatchCollection2)) {
789 TRACE("(%p)->(IID_IMatchCollection2 %p)\n", This, ppv);
790 *ppv = &This->IMatchCollection2_iface;
791 }else if(IsEqualGUID(riid, &IID_IMatchCollection)) {
792 TRACE("(%p)->(IID_IMatchCollection %p)\n", This, ppv);
793 *ppv = &This->IMatchCollection_iface;
794 }else if(IsEqualGUID(riid, &IID_IDispatchEx)) {
795 TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
797 return E_NOINTERFACE;
799 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
801 return E_NOINTERFACE;
804 IUnknown_AddRef((IUnknown*)*ppv);
808 static ULONG WINAPI MatchCollection2_AddRef(IMatchCollection2 *iface)
810 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
811 LONG ref = InterlockedIncrement(&This->ref);
813 TRACE("(%p) ref=%d\n", This, ref);
818 static ULONG WINAPI MatchCollection2_Release(IMatchCollection2 *iface)
820 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
821 LONG ref = InterlockedDecrement(&This->ref);
823 TRACE("(%p) ref=%d\n", This, ref);
828 for(i=0; i<This->count; i++)
829 IMatch2_Release(This->matches[i]);
830 heap_free(This->matches);
838 static HRESULT WINAPI MatchCollection2_GetTypeInfoCount(IMatchCollection2 *iface, UINT *pctinfo)
840 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
842 TRACE("(%p)->(%p)\n", This, pctinfo);
848 static HRESULT WINAPI MatchCollection2_GetTypeInfo(IMatchCollection2 *iface,
849 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
851 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
852 FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
856 static HRESULT WINAPI MatchCollection2_GetIDsOfNames(IMatchCollection2 *iface,
857 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
859 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
861 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid),
862 rgszNames, cNames, lcid, rgDispId);
864 return ITypeInfo_GetIDsOfNames(typeinfos[MatchCollection2_tid], rgszNames, cNames, rgDispId);
867 static HRESULT WINAPI MatchCollection2_Invoke(IMatchCollection2 *iface, DISPID dispIdMember,
868 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
869 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
871 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
873 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
874 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
876 return ITypeInfo_Invoke(typeinfos[MatchCollection2_tid], iface, dispIdMember, wFlags,
877 pDispParams, pVarResult, pExcepInfo, puArgErr);
880 static HRESULT WINAPI MatchCollection2_get_Item(IMatchCollection2 *iface,
881 LONG index, IDispatch **ppMatch)
883 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
885 TRACE("(%p)->()\n", This);
890 if(index<0 || index>=This->count)
893 *ppMatch = (IDispatch*)This->matches[index];
894 IMatch2_AddRef(This->matches[index]);
898 static HRESULT WINAPI MatchCollection2_get_Count(IMatchCollection2 *iface, LONG *pCount)
900 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
902 TRACE("(%p)->()\n", This);
907 *pCount = This->count;
911 static HRESULT WINAPI MatchCollection2_get__NewEnum(IMatchCollection2 *iface, IUnknown **ppEnum)
913 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
915 TRACE("(%p)->(%p)\n", This, ppEnum);
920 return create_enum_variant_mc2(&This->IMatchCollection2_iface, 0, (IEnumVARIANT**)ppEnum);
923 static const IMatchCollection2Vtbl MatchCollection2Vtbl = {
924 MatchCollection2_QueryInterface,
925 MatchCollection2_AddRef,
926 MatchCollection2_Release,
927 MatchCollection2_GetTypeInfoCount,
928 MatchCollection2_GetTypeInfo,
929 MatchCollection2_GetIDsOfNames,
930 MatchCollection2_Invoke,
931 MatchCollection2_get_Item,
932 MatchCollection2_get_Count,
933 MatchCollection2_get__NewEnum
936 static inline MatchCollection2 *impl_from_IMatchCollection(IMatchCollection *iface)
938 return CONTAINING_RECORD(iface, MatchCollection2, IMatchCollection_iface);
941 static HRESULT WINAPI MatchCollection_QueryInterface(IMatchCollection *iface, REFIID riid, void **ppv)
943 MatchCollection2 *This = impl_from_IMatchCollection(iface);
944 return IMatchCollection2_QueryInterface(&This->IMatchCollection2_iface, riid, ppv);
947 static ULONG WINAPI MatchCollection_AddRef(IMatchCollection *iface)
949 MatchCollection2 *This = impl_from_IMatchCollection(iface);
950 return IMatchCollection2_AddRef(&This->IMatchCollection2_iface);
953 static ULONG WINAPI MatchCollection_Release(IMatchCollection *iface)
955 MatchCollection2 *This = impl_from_IMatchCollection(iface);
956 return IMatchCollection2_Release(&This->IMatchCollection2_iface);
959 static HRESULT WINAPI MatchCollection_GetTypeInfoCount(IMatchCollection *iface, UINT *pctinfo)
961 MatchCollection2 *This = impl_from_IMatchCollection(iface);
962 return IMatchCollection2_GetTypeInfoCount(&This->IMatchCollection2_iface, pctinfo);
965 static HRESULT WINAPI MatchCollection_GetTypeInfo(IMatchCollection *iface,
966 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
968 MatchCollection2 *This = impl_from_IMatchCollection(iface);
969 return IMatchCollection2_GetTypeInfo(&This->IMatchCollection2_iface, iTInfo, lcid, ppTInfo);
972 static HRESULT WINAPI MatchCollection_GetIDsOfNames(IMatchCollection *iface, REFIID riid,
973 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
975 MatchCollection2 *This = impl_from_IMatchCollection(iface);
976 return IMatchCollection2_GetIDsOfNames(&This->IMatchCollection2_iface,
977 riid, rgszNames, cNames, lcid, rgDispId);
980 static HRESULT WINAPI MatchCollection_Invoke(IMatchCollection *iface, DISPID dispIdMember,
981 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
982 EXCEPINFO *pExcepInfo, UINT *puArgErr)
984 MatchCollection2 *This = impl_from_IMatchCollection(iface);
985 return IMatchCollection2_Invoke(&This->IMatchCollection2_iface, dispIdMember,
986 riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
989 static HRESULT WINAPI MatchCollection_get_Item(IMatchCollection *iface, LONG index, IDispatch **ppMatch)
991 MatchCollection2 *This = impl_from_IMatchCollection(iface);
992 return IMatchCollection2_get_Item(&This->IMatchCollection2_iface, index, ppMatch);
995 static HRESULT WINAPI MatchCollection_get_Count(IMatchCollection *iface, LONG *pCount)
997 MatchCollection2 *This = impl_from_IMatchCollection(iface);
998 return IMatchCollection2_get_Count(&This->IMatchCollection2_iface, pCount);
1001 static HRESULT WINAPI MatchCollection_get__NewEnum(IMatchCollection *iface, IUnknown **ppEnum)
1003 MatchCollection2 *This = impl_from_IMatchCollection(iface);
1004 return IMatchCollection2_get__NewEnum(&This->IMatchCollection2_iface, ppEnum);
1007 static const IMatchCollectionVtbl MatchCollectionVtbl = {
1008 MatchCollection_QueryInterface,
1009 MatchCollection_AddRef,
1010 MatchCollection_Release,
1011 MatchCollection_GetTypeInfoCount,
1012 MatchCollection_GetTypeInfo,
1013 MatchCollection_GetIDsOfNames,
1014 MatchCollection_Invoke,
1015 MatchCollection_get_Item,
1016 MatchCollection_get_Count,
1017 MatchCollection_get__NewEnum
1020 static HRESULT add_match(IMatchCollection2 *iface, IMatch2 *add)
1022 MatchCollection2 *This = impl_from_IMatchCollection2(iface);
1024 TRACE("(%p)->(%p)\n", This, add);
1027 This->matches = heap_alloc(8*sizeof(IMatch*));
1029 return E_OUTOFMEMORY;
1031 }else if(This->size == This->count) {
1032 IMatch2 **new_matches = heap_realloc(This->matches, 2*This->size*sizeof(IMatch*));
1034 return E_OUTOFMEMORY;
1036 This->matches = new_matches;
1040 This->matches[This->count++] = add;
1041 IMatch2_AddRef(add);
1045 static HRESULT create_match_collection2(IMatchCollection2 **match_collection)
1047 MatchCollection2 *ret;
1050 hres = init_regexp_typeinfo(MatchCollection2_tid);
1054 ret = heap_alloc_zero(sizeof(*ret));
1056 return E_OUTOFMEMORY;
1058 ret->IMatchCollection2_iface.lpVtbl = &MatchCollection2Vtbl;
1059 ret->IMatchCollection_iface.lpVtbl = &MatchCollectionVtbl;
1062 *match_collection = &ret->IMatchCollection2_iface;
1066 static inline RegExp2 *impl_from_IRegExp2(IRegExp2 *iface)
1068 return CONTAINING_RECORD(iface, RegExp2, IRegExp2_iface);
1071 static HRESULT WINAPI RegExp2_QueryInterface(IRegExp2 *iface, REFIID riid, void **ppv)
1073 RegExp2 *This = impl_from_IRegExp2(iface);
1075 if(IsEqualGUID(riid, &IID_IUnknown)) {
1076 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1077 *ppv = &This->IRegExp2_iface;
1078 }else if(IsEqualGUID(riid, &IID_IDispatch)) {
1079 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1080 *ppv = &This->IRegExp2_iface;
1081 }else if(IsEqualGUID(riid, &IID_IRegExp2)) {
1082 TRACE("(%p)->(IID_IRegExp2 %p)\n", This, ppv);
1083 *ppv = &This->IRegExp2_iface;
1084 }else if(IsEqualGUID(riid, &IID_IRegExp)) {
1085 TRACE("(%p)->(IID_IRegExp %p)\n", This, ppv);
1086 *ppv = &This->IRegExp_iface;
1087 }else if(IsEqualGUID(riid, &IID_IDispatchEx)) {
1088 TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
1090 return E_NOINTERFACE;
1092 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1094 return E_NOINTERFACE;
1097 IUnknown_AddRef((IUnknown*)*ppv);
1101 static ULONG WINAPI RegExp2_AddRef(IRegExp2 *iface)
1103 RegExp2 *This = impl_from_IRegExp2(iface);
1104 LONG ref = InterlockedIncrement(&This->ref);
1106 TRACE("(%p) ref=%d\n", This, ref);
1111 static ULONG WINAPI RegExp2_Release(IRegExp2 *iface)
1113 RegExp2 *This = impl_from_IRegExp2(iface);
1114 LONG ref = InterlockedDecrement(&This->ref);
1116 TRACE("(%p) ref=%d\n", This, ref);
1119 heap_free(This->pattern);
1121 regexp_destroy(This->regexp);
1122 heap_pool_free(&This->pool);
1129 static HRESULT WINAPI RegExp2_GetTypeInfoCount(IRegExp2 *iface, UINT *pctinfo)
1131 RegExp2 *This = impl_from_IRegExp2(iface);
1133 TRACE("(%p)->(%p)\n", This, pctinfo);
1139 static HRESULT WINAPI RegExp2_GetTypeInfo(IRegExp2 *iface,
1140 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1142 RegExp2 *This = impl_from_IRegExp2(iface);
1143 FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1147 static HRESULT WINAPI RegExp2_GetIDsOfNames(IRegExp2 *iface, REFIID riid,
1148 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1150 RegExp2 *This = impl_from_IRegExp2(iface);
1152 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid),
1153 rgszNames, cNames, lcid, rgDispId);
1155 return ITypeInfo_GetIDsOfNames(typeinfos[RegExp2_tid], rgszNames, cNames, rgDispId);
1158 static HRESULT WINAPI RegExp2_Invoke(IRegExp2 *iface, DISPID dispIdMember,
1159 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1160 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1162 RegExp2 *This = impl_from_IRegExp2(iface);
1164 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1165 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1167 return ITypeInfo_Invoke(typeinfos[RegExp2_tid], iface, dispIdMember, wFlags,
1168 pDispParams, pVarResult, pExcepInfo, puArgErr);
1171 static HRESULT WINAPI RegExp2_get_Pattern(IRegExp2 *iface, BSTR *pPattern)
1173 RegExp2 *This = impl_from_IRegExp2(iface);
1175 TRACE("(%p)->(%p)\n", This, pPattern);
1180 if(!This->pattern) {
1185 *pPattern = SysAllocString(This->pattern);
1186 return *pPattern ? S_OK : E_OUTOFMEMORY;
1189 static HRESULT WINAPI RegExp2_put_Pattern(IRegExp2 *iface, BSTR pattern)
1191 RegExp2 *This = impl_from_IRegExp2(iface);
1195 TRACE("(%p)->(%s)\n", This, wine_dbgstr_w(pattern));
1198 heap_free(This->pattern);
1200 regexp_destroy(This->regexp);
1201 This->regexp = NULL;
1203 This->pattern = NULL;
1207 size = (SysStringLen(pattern)+1) * sizeof(WCHAR);
1208 p = heap_alloc(size);
1210 return E_OUTOFMEMORY;
1212 heap_free(This->pattern);
1214 memcpy(p, pattern, size);
1216 regexp_destroy(This->regexp);
1217 This->regexp = NULL;
1222 static HRESULT WINAPI RegExp2_get_IgnoreCase(IRegExp2 *iface, VARIANT_BOOL *pIgnoreCase)
1224 RegExp2 *This = impl_from_IRegExp2(iface);
1226 TRACE("(%p)->(%p)\n", This, pIgnoreCase);
1231 *pIgnoreCase = This->flags & REG_FOLD ? VARIANT_TRUE : VARIANT_FALSE;
1235 static HRESULT WINAPI RegExp2_put_IgnoreCase(IRegExp2 *iface, VARIANT_BOOL ignoreCase)
1237 RegExp2 *This = impl_from_IRegExp2(iface);
1239 TRACE("(%p)->(%s)\n", This, ignoreCase ? "true" : "false");
1242 This->flags |= REG_FOLD;
1244 This->flags &= ~REG_FOLD;
1248 static HRESULT WINAPI RegExp2_get_Global(IRegExp2 *iface, VARIANT_BOOL *pGlobal)
1250 RegExp2 *This = impl_from_IRegExp2(iface);
1252 TRACE("(%p)->(%p)\n", This, pGlobal);
1257 *pGlobal = This->flags & REG_GLOB ? VARIANT_TRUE : VARIANT_FALSE;
1261 static HRESULT WINAPI RegExp2_put_Global(IRegExp2 *iface, VARIANT_BOOL global)
1263 RegExp2 *This = impl_from_IRegExp2(iface);
1265 TRACE("(%p)->(%s)\n", This, global ? "true" : "false");
1268 This->flags |= REG_GLOB;
1270 This->flags &= ~REG_GLOB;
1274 static HRESULT WINAPI RegExp2_get_Multiline(IRegExp2 *iface, VARIANT_BOOL *pMultiline)
1276 RegExp2 *This = impl_from_IRegExp2(iface);
1278 TRACE("(%p)->(%p)\n", This, pMultiline);
1283 *pMultiline = This->flags & REG_MULTILINE ? VARIANT_TRUE : VARIANT_FALSE;
1287 static HRESULT WINAPI RegExp2_put_Multiline(IRegExp2 *iface, VARIANT_BOOL multiline)
1289 RegExp2 *This = impl_from_IRegExp2(iface);
1291 TRACE("(%p)->(%s)\n", This, multiline ? "true" : "false");
1294 This->flags |= REG_MULTILINE;
1296 This->flags &= ~REG_MULTILINE;
1300 static HRESULT WINAPI RegExp2_Execute(IRegExp2 *iface,
1301 BSTR sourceString, IDispatch **ppMatches)
1303 RegExp2 *This = impl_from_IRegExp2(iface);
1304 match_state_t *result;
1306 IMatchCollection2 *match_collection;
1307 IMatch2 *add = NULL;
1310 TRACE("(%p)->(%s %p)\n", This, debugstr_w(sourceString), ppMatches);
1312 if(!This->pattern) {
1313 DWORD i, len = SysStringLen(sourceString);
1315 hres = create_match_collection2(&match_collection);
1319 for(i=0; i<=len; i++) {
1320 hres = create_match2(i, NULL, &add);
1324 hres = add_match(match_collection, add);
1327 IMatch2_Release(add);
1329 if(!(This->flags & REG_GLOB))
1334 IMatchCollection2_Release(match_collection);
1338 *ppMatches = (IDispatch*)match_collection;
1343 This->regexp = regexp_new(NULL, &This->pool, This->pattern,
1344 strlenW(This->pattern), This->flags, FALSE);
1348 hres = regexp_set_flags(&This->regexp, NULL, &This->pool, This->flags);
1353 hres = create_match_collection2(&match_collection);
1359 result = alloc_match_state(This->regexp, NULL, pos);
1361 hres = E_OUTOFMEMORY;
1365 hres = regexp_execute(This->regexp, NULL, &This->pool,
1366 sourceString, SysStringLen(sourceString), result);
1373 hres = create_match2(result->cp-result->match_len-sourceString, &result, &add);
1377 hres = add_match(match_collection, add);
1378 IMatch2_Release(add);
1382 if(!(This->flags & REG_GLOB))
1387 IMatchCollection2_Release(match_collection);
1391 *ppMatches = (IDispatch*)match_collection;
1395 static HRESULT WINAPI RegExp2_Test(IRegExp2 *iface, BSTR sourceString, VARIANT_BOOL *pMatch)
1397 RegExp2 *This = impl_from_IRegExp2(iface);
1398 match_state_t *result;
1402 TRACE("(%p)->(%s %p)\n", This, debugstr_w(sourceString), pMatch);
1404 if(!This->pattern) {
1405 *pMatch = VARIANT_TRUE;
1410 This->regexp = regexp_new(NULL, &This->pool, This->pattern,
1411 strlenW(This->pattern), This->flags, FALSE);
1415 hres = regexp_set_flags(&This->regexp, NULL, &This->pool, This->flags);
1420 mark = heap_pool_mark(&This->pool);
1421 result = alloc_match_state(This->regexp, &This->pool, sourceString);
1423 heap_pool_clear(mark);
1424 return E_OUTOFMEMORY;
1427 hres = regexp_execute(This->regexp, NULL, &This->pool,
1428 sourceString, SysStringLen(sourceString), result);
1430 heap_pool_clear(mark);
1433 *pMatch = VARIANT_TRUE;
1434 }else if(hres == S_FALSE) {
1435 *pMatch = VARIANT_FALSE;
1441 static HRESULT WINAPI RegExp2_Replace(IRegExp2 *iface, BSTR sourceString,
1442 VARIANT replaceVar, BSTR *pDestString)
1444 RegExp2 *This = impl_from_IRegExp2(iface);
1445 FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(sourceString),
1446 debugstr_variant(&replaceVar), pDestString);
1450 static const IRegExp2Vtbl RegExp2Vtbl = {
1451 RegExp2_QueryInterface,
1454 RegExp2_GetTypeInfoCount,
1455 RegExp2_GetTypeInfo,
1456 RegExp2_GetIDsOfNames,
1458 RegExp2_get_Pattern,
1459 RegExp2_put_Pattern,
1460 RegExp2_get_IgnoreCase,
1461 RegExp2_put_IgnoreCase,
1464 RegExp2_get_Multiline,
1465 RegExp2_put_Multiline,
1471 static inline RegExp2 *impl_from_IRegExp(IRegExp *iface)
1473 return CONTAINING_RECORD(iface, RegExp2, IRegExp_iface);
1476 static HRESULT WINAPI RegExp_QueryInterface(IRegExp *iface, REFIID riid, void **ppv)
1478 RegExp2 *This = impl_from_IRegExp(iface);
1479 return IRegExp2_QueryInterface(&This->IRegExp2_iface, riid, ppv);
1482 static ULONG WINAPI RegExp_AddRef(IRegExp *iface)
1484 RegExp2 *This = impl_from_IRegExp(iface);
1485 return IRegExp2_AddRef(&This->IRegExp2_iface);
1488 static ULONG WINAPI RegExp_Release(IRegExp *iface)
1490 RegExp2 *This = impl_from_IRegExp(iface);
1491 return IRegExp2_Release(&This->IRegExp2_iface);
1494 static HRESULT WINAPI RegExp_GetTypeInfoCount(IRegExp *iface, UINT *pctinfo)
1496 RegExp2 *This = impl_from_IRegExp(iface);
1497 return IRegExp2_GetTypeInfoCount(&This->IRegExp2_iface, pctinfo);
1500 static HRESULT WINAPI RegExp_GetTypeInfo(IRegExp *iface,
1501 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1503 RegExp2 *This = impl_from_IRegExp(iface);
1504 return IRegExp2_GetTypeInfo(&This->IRegExp2_iface, iTInfo, lcid, ppTInfo);
1507 static HRESULT WINAPI RegExp_GetIDsOfNames(IRegExp *iface, REFIID riid,
1508 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1510 RegExp2 *This = impl_from_IRegExp(iface);
1511 return IRegExp2_GetIDsOfNames(&This->IRegExp2_iface, riid, rgszNames, cNames, lcid, rgDispId);
1514 static HRESULT WINAPI RegExp_Invoke(IRegExp *iface, DISPID dispIdMember,
1515 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1516 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1518 RegExp2 *This = impl_from_IRegExp(iface);
1519 return IRegExp2_Invoke(&This->IRegExp2_iface, dispIdMember, riid, lcid,
1520 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1523 static HRESULT WINAPI RegExp_get_Pattern(IRegExp *iface, BSTR *pPattern)
1525 RegExp2 *This = impl_from_IRegExp(iface);
1526 return IRegExp2_get_Pattern(&This->IRegExp2_iface, pPattern);
1529 static HRESULT WINAPI RegExp_put_Pattern(IRegExp *iface, BSTR pPattern)
1531 RegExp2 *This = impl_from_IRegExp(iface);
1532 return IRegExp2_put_Pattern(&This->IRegExp2_iface, pPattern);
1535 static HRESULT WINAPI RegExp_get_IgnoreCase(IRegExp *iface, VARIANT_BOOL *pIgnoreCase)
1537 RegExp2 *This = impl_from_IRegExp(iface);
1538 return IRegExp2_get_IgnoreCase(&This->IRegExp2_iface, pIgnoreCase);
1541 static HRESULT WINAPI RegExp_put_IgnoreCase(IRegExp *iface, VARIANT_BOOL pIgnoreCase)
1543 RegExp2 *This = impl_from_IRegExp(iface);
1544 return IRegExp2_put_IgnoreCase(&This->IRegExp2_iface, pIgnoreCase);
1547 static HRESULT WINAPI RegExp_get_Global(IRegExp *iface, VARIANT_BOOL *pGlobal)
1549 RegExp2 *This = impl_from_IRegExp(iface);
1550 return IRegExp2_get_Global(&This->IRegExp2_iface, pGlobal);
1553 static HRESULT WINAPI RegExp_put_Global(IRegExp *iface, VARIANT_BOOL pGlobal)
1555 RegExp2 *This = impl_from_IRegExp(iface);
1556 return IRegExp2_put_Global(&This->IRegExp2_iface, pGlobal);
1559 static HRESULT WINAPI RegExp_Execute(IRegExp *iface,
1560 BSTR sourceString, IDispatch **ppMatches)
1562 RegExp2 *This = impl_from_IRegExp(iface);
1563 return IRegExp2_Execute(&This->IRegExp2_iface, sourceString, ppMatches);
1566 static HRESULT WINAPI RegExp_Test(IRegExp *iface, BSTR sourceString, VARIANT_BOOL *pMatch)
1568 RegExp2 *This = impl_from_IRegExp(iface);
1569 return IRegExp2_Test(&This->IRegExp2_iface, sourceString, pMatch);
1572 static HRESULT WINAPI RegExp_Replace(IRegExp *iface, BSTR sourceString,
1573 BSTR replaceString, BSTR *pDestString)
1575 RegExp2 *This = impl_from_IRegExp(iface);
1578 V_VT(&replace) = VT_BSTR;
1579 V_BSTR(&replace) = replaceString;
1580 return IRegExp2_Replace(&This->IRegExp2_iface, sourceString, replace, pDestString);
1583 static IRegExpVtbl RegExpVtbl = {
1584 RegExp_QueryInterface,
1587 RegExp_GetTypeInfoCount,
1589 RegExp_GetIDsOfNames,
1593 RegExp_get_IgnoreCase,
1594 RegExp_put_IgnoreCase,
1602 HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, REFIID riid, void **ppv)
1607 TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppv);
1609 hres = init_regexp_typeinfo(RegExp2_tid);
1613 ret = heap_alloc_zero(sizeof(*ret));
1615 return E_OUTOFMEMORY;
1617 ret->IRegExp2_iface.lpVtbl = &RegExp2Vtbl;
1618 ret->IRegExp_iface.lpVtbl = &RegExpVtbl;
1621 heap_pool_init(&ret->pool);
1623 hres = IRegExp2_QueryInterface(&ret->IRegExp2_iface, riid, ppv);
1624 IRegExp2_Release(&ret->IRegExp2_iface);
1628 void release_regexp_typelib(void)
1632 for(i=0; i<REGEXP_LAST_tid; i++) {
1634 ITypeInfo_Release(typeinfos[i]);
1637 ITypeLib_Release(typelib);