add regex feature for win32

This commit is contained in:
Kévin Szkudłapski 2012-08-01 12:17:25 +00:00 committed by wisk
parent 7e045dfcd2
commit a50075a0f3
10 changed files with 1781 additions and 1256 deletions

View File

@ -78,6 +78,7 @@
#define HAVE_RECVFROM 1
/* #undef HAVE_RECVMSG */
/* #undef HAVE_REGEX_H */
#define HAVE_REGEX_H 1
#define HAVE_REOPENFILE 1
/* #undef HAVE_SETENV */
/* #undef HAVE_SETRLIMIT */

View File

@ -109,6 +109,7 @@
<ClInclude Include="..\src\common\fuzz.h" />
<ClInclude Include="..\src\common\random.h" />
<ClInclude Include="..\src\common\ranges.h" />
<ClInclude Include="..\src\com_regexp.hpp" />
<ClInclude Include="..\src\libzzuf\debug.h" />
<ClInclude Include="..\src\libzzuf\lib-load.h" />
<ClInclude Include="..\src\libzzuf\libzzuf.h" />
@ -121,6 +122,10 @@
<ClCompile Include="..\src\common\fuzz.c" />
<ClCompile Include="..\src\common\random.c" />
<ClCompile Include="..\src\common\ranges.c" />
<ClCompile Include="..\src\com_regexp.cpp">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\src\libzzuf\debug.c" />
<ClCompile Include="..\src\libzzuf\lib-fd.c" />
<ClCompile Include="..\src\libzzuf\lib-mem.c" />

View File

@ -98,6 +98,7 @@
<ClInclude Include="..\src\common\fuzz.h" />
<ClInclude Include="..\src\common\random.h" />
<ClInclude Include="..\src\common\ranges.h" />
<ClInclude Include="..\src\com_regexp.hpp" />
<ClInclude Include="..\src\md5.h" />
<ClInclude Include="..\src\myfork.h" />
<ClInclude Include="..\src\opts.h" />
@ -109,6 +110,10 @@
<ClCompile Include="..\src\common\fuzz.c" />
<ClCompile Include="..\src\common\random.c" />
<ClCompile Include="..\src\common\ranges.c" />
<ClCompile Include="..\src\com_regexp.cpp">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\src\md5.c" />
<ClCompile Include="..\src\myfork.c" />
<ClCompile Include="..\src\opts.c" />
@ -118,4 +123,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

452
src/com_regexp.cpp Normal file
View File

@ -0,0 +1,452 @@
#include "com_regexp.hpp"
#pragma once
#pragma pack(push, 8)
#include <comdef.h>
#include <atlbase.h>
//
// Forward references and typedefs
//
struct __declspec(uuid("3f4daca7-160d-11d2-a8e9-00104b365c9f"))
/* LIBID */ __VBScript_RegExp_10;
struct __declspec(uuid("3f4daca0-160d-11d2-a8e9-00104b365c9f"))
/* dual interface */ IRegExp;
struct __declspec(uuid("3f4daca1-160d-11d2-a8e9-00104b365c9f"))
/* dual interface */ IMatch;
struct __declspec(uuid("3f4daca2-160d-11d2-a8e9-00104b365c9f"))
/* dual interface */ IMatchCollection;
struct /* coclass */ RegExp;
struct /* coclass */ Match;
struct /* coclass */ MatchCollection;
//
// Smart pointer typedef declarations
//
_COM_SMARTPTR_TYPEDEF(IRegExp, __uuidof(IRegExp));
_COM_SMARTPTR_TYPEDEF(IMatch, __uuidof(IMatch));
_COM_SMARTPTR_TYPEDEF(IMatchCollection, __uuidof(IMatchCollection));
//
// Type library items
//
struct __declspec(uuid("3f4daca0-160d-11d2-a8e9-00104b365c9f"))
IRegExp : IDispatch
{
//
// Property data
//
__declspec(property(get=GetPattern,put=PutPattern))
_bstr_t Pattern;
__declspec(property(get=GetIgnoreCase,put=PutIgnoreCase))
VARIANT_BOOL IgnoreCase;
__declspec(property(get=GetGlobal,put=PutGlobal))
VARIANT_BOOL Global;
//
// Wrapper methods for error-handling
//
_bstr_t GetPattern ( );
void PutPattern (
_bstr_t pPattern );
VARIANT_BOOL GetIgnoreCase ( );
void PutIgnoreCase (
VARIANT_BOOL pIgnoreCase );
VARIANT_BOOL GetGlobal ( );
void PutGlobal (
VARIANT_BOOL pGlobal );
IDispatchPtr Execute (
_bstr_t sourceString );
VARIANT_BOOL Test (
_bstr_t sourceString );
_bstr_t Replace (
_bstr_t sourceString,
_bstr_t replaceString );
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall get_Pattern (
/*[out,retval]*/ BSTR * pPattern ) = 0;
virtual HRESULT __stdcall put_Pattern (
/*[in]*/ BSTR pPattern ) = 0;
virtual HRESULT __stdcall get_IgnoreCase (
/*[out,retval]*/ VARIANT_BOOL * pIgnoreCase ) = 0;
virtual HRESULT __stdcall put_IgnoreCase (
/*[in]*/ VARIANT_BOOL pIgnoreCase ) = 0;
virtual HRESULT __stdcall get_Global (
/*[out,retval]*/ VARIANT_BOOL * pGlobal ) = 0;
virtual HRESULT __stdcall put_Global (
/*[in]*/ VARIANT_BOOL pGlobal ) = 0;
virtual HRESULT __stdcall raw_Execute (
/*[in]*/ BSTR sourceString,
/*[out,retval]*/ IDispatch * * ppMatches ) = 0;
virtual HRESULT __stdcall raw_Test (
/*[in]*/ BSTR sourceString,
/*[out,retval]*/ VARIANT_BOOL * pMatch ) = 0;
virtual HRESULT __stdcall raw_Replace (
/*[in]*/ BSTR sourceString,
/*[in]*/ BSTR replaceString,
/*[out,retval]*/ BSTR * pDestString ) = 0;
};
struct __declspec(uuid("3f4daca1-160d-11d2-a8e9-00104b365c9f"))
IMatch : IDispatch
{
//
// Property data
//
__declspec(property(get=GetValue))
_bstr_t Value;
__declspec(property(get=GetFirstIndex))
long FirstIndex;
__declspec(property(get=GetLength))
long Length;
//
// Wrapper methods for error-handling
//
_bstr_t GetValue ( );
long GetFirstIndex ( );
long GetLength ( );
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall get_Value (
/*[out,retval]*/ BSTR * pValue ) = 0;
virtual HRESULT __stdcall get_FirstIndex (
/*[out,retval]*/ long * pFirstIndex ) = 0;
virtual HRESULT __stdcall get_Length (
/*[out,retval]*/ long * pLength ) = 0;
};
struct __declspec(uuid("3f4daca2-160d-11d2-a8e9-00104b365c9f"))
IMatchCollection : IDispatch
{
//
// Property data
//
__declspec(property(get=GetCount))
long Count;
__declspec(property(get=GetItem))
IDispatchPtr Item[];
__declspec(property(get=Get_NewEnum))
IUnknownPtr _NewEnum;
//
// Wrapper methods for error-handling
//
IDispatchPtr GetItem (
long index );
long GetCount ( );
IUnknownPtr Get_NewEnum ( );
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall get_Item (
/*[in]*/ long index,
/*[out,retval]*/ IDispatch * * ppMatch ) = 0;
virtual HRESULT __stdcall get_Count (
/*[out,retval]*/ long * pCount ) = 0;
virtual HRESULT __stdcall get__NewEnum (
/*[out,retval]*/ IUnknown * * ppEnum ) = 0;
};
struct __declspec(uuid("3f4daca4-160d-11d2-a8e9-00104b365c9f"))
RegExp;
// [ default ] interface IRegExp
struct __declspec(uuid("3f4daca5-160d-11d2-a8e9-00104b365c9f"))
Match;
// [ default ] interface IMatch
struct __declspec(uuid("3f4daca6-160d-11d2-a8e9-00104b365c9f"))
MatchCollection;
// [ default ] interface IMatchCollection
//
// Named GUID constants initializations
//
extern "C" const GUID __declspec(selectany) LIBID_VBScript_RegExp_10 =
{0x3f4daca7,0x160d,0x11d2,{0xa8,0xe9,0x00,0x10,0x4b,0x36,0x5c,0x9f}};
extern "C" const GUID __declspec(selectany) IID_IRegExp =
{0x3f4daca0,0x160d,0x11d2,{0xa8,0xe9,0x00,0x10,0x4b,0x36,0x5c,0x9f}};
extern "C" const GUID __declspec(selectany) IID_IMatch =
{0x3f4daca1,0x160d,0x11d2,{0xa8,0xe9,0x00,0x10,0x4b,0x36,0x5c,0x9f}};
extern "C" const GUID __declspec(selectany) IID_IMatchCollection =
{0x3f4daca2,0x160d,0x11d2,{0xa8,0xe9,0x00,0x10,0x4b,0x36,0x5c,0x9f}};
extern "C" const GUID __declspec(selectany) CLSID_RegExp =
{0x3f4daca4,0x160d,0x11d2,{0xa8,0xe9,0x00,0x10,0x4b,0x36,0x5c,0x9f}};
extern "C" const GUID __declspec(selectany) CLSID_Match =
{0x3f4daca5,0x160d,0x11d2,{0xa8,0xe9,0x00,0x10,0x4b,0x36,0x5c,0x9f}};
extern "C" const GUID __declspec(selectany) CLSID_MatchCollection =
{0x3f4daca6,0x160d,0x11d2,{0xa8,0xe9,0x00,0x10,0x4b,0x36,0x5c,0x9f}};
//
// interface IRegExp wrapper method implementations
//
inline _bstr_t IRegExp::GetPattern ( ) {
BSTR _result = 0;
HRESULT _hr = get_Pattern(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _bstr_t(_result, false);
}
inline void IRegExp::PutPattern ( _bstr_t pPattern ) {
HRESULT _hr = put_Pattern(pPattern);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
}
inline VARIANT_BOOL IRegExp::GetIgnoreCase ( ) {
VARIANT_BOOL _result = 0;
HRESULT _hr = get_IgnoreCase(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}
inline void IRegExp::PutIgnoreCase ( VARIANT_BOOL pIgnoreCase ) {
HRESULT _hr = put_IgnoreCase(pIgnoreCase);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
}
inline VARIANT_BOOL IRegExp::GetGlobal ( ) {
VARIANT_BOOL _result = 0;
HRESULT _hr = get_Global(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}
inline void IRegExp::PutGlobal ( VARIANT_BOOL pGlobal ) {
HRESULT _hr = put_Global(pGlobal);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
}
inline IDispatchPtr IRegExp::Execute ( _bstr_t sourceString ) {
IDispatch * _result = 0;
HRESULT _hr = raw_Execute(sourceString, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return IDispatchPtr(_result, false);
}
inline VARIANT_BOOL IRegExp::Test ( _bstr_t sourceString ) {
VARIANT_BOOL _result = 0;
HRESULT _hr = raw_Test(sourceString, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}
inline _bstr_t IRegExp::Replace ( _bstr_t sourceString, _bstr_t replaceString ) {
BSTR _result = 0;
HRESULT _hr = raw_Replace(sourceString, replaceString, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _bstr_t(_result, false);
}
//
// interface IMatch wrapper method implementations
//
inline _bstr_t IMatch::GetValue ( ) {
BSTR _result = 0;
HRESULT _hr = get_Value(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _bstr_t(_result, false);
}
inline long IMatch::GetFirstIndex ( ) {
long _result = 0;
HRESULT _hr = get_FirstIndex(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}
inline long IMatch::GetLength ( ) {
long _result = 0;
HRESULT _hr = get_Length(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}
//
// interface IMatchCollection wrapper method implementations
//
inline IDispatchPtr IMatchCollection::GetItem ( long index ) {
IDispatch * _result = 0;
HRESULT _hr = get_Item(index, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return IDispatchPtr(_result, false);
}
inline long IMatchCollection::GetCount ( ) {
long _result = 0;
HRESULT _hr = get_Count(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}
inline IUnknownPtr IMatchCollection::Get_NewEnum ( ) {
IUnknown * _result = 0;
HRESULT _hr = get__NewEnum(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return IUnknownPtr(_result, false);
}
#pragma pack(pop)
struct cxx_regex
{
cxx_regex(int cflags = 0) : m_com_regexp(), m_cflags(cflags) {}
CComPtr<IRegExp> m_com_regexp;
int m_cflags;
};
typedef struct cxx_regmatch_s
{
void *dummy;
} cxx_regmatch_t;
int regcomp(regex_t *preg, const char *pattern, int cflags)
{
preg->cxx_regex = NULL;
static int co_init = 0;
if (co_init == 0)
{
CoInitialize(NULL);
co_init = 1;
}
cxx_regex *cr = new cxx_regex;
HRESULT hr = cr->m_com_regexp.CoCreateInstance(CLSID_RegExp);
if (FAILED(hr))
{
delete cr;
return -1;
}
try
{
cr->m_com_regexp->PutPattern(pattern);
cr->m_com_regexp->PutGlobal(VARIANT_TRUE);
preg->cxx_regex = (void *)cr;
}
catch (_com_error const&)
{
delete cr;
return -1;
}
preg->cxx_regex = (void *)cr;
return 0;
}
int regwcomp(regex_t *preg, const wchar_t *pattern, int cflags)
{
preg->cxx_regex = NULL;
static int co_init = 0;
if (co_init == 0)
{
CoInitialize(NULL);
co_init = 1;
}
cxx_regex *cr = new cxx_regex;
HRESULT hr = cr->m_com_regexp.CoCreateInstance(CLSID_RegExp);
if (FAILED(hr))
{
delete cr;
return -1;
}
try
{
cr->m_com_regexp->PutPattern(pattern);
preg->cxx_regex = (void *)cr;
}
catch (_com_error const&)
{
delete cr;
return -1;
}
preg->cxx_regex = (void *)cr;
return 0;
}
size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
{
/* Not implemented ! */
return 0;
}
int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t *pmatch, int eflags)
{
cxx_regex *cr = (cxx_regex *)preg->cxx_regex;
if (cr == NULL) return -1;
try
{
if (cr->m_com_regexp->Test(string) == VARIANT_TRUE)
return 0;
}
catch (_com_error const&)
{
return -1;
}
return REG_NOMATCH;
}
int regwexec(const regex_t *preg, const wchar_t *string, size_t nmatch, regmatch_t *pmatch, int eflags)
{
cxx_regex *cr = (cxx_regex *)preg->cxx_regex;
if (cr == NULL) return -1;
try
{
if (cr->m_com_regexp->Test(string) == VARIANT_TRUE)
return 0;
}
catch (_com_error const&)
{
return -1;
}
return REG_NOMATCH;
}
void regfree(regex_t *preg)
{
cxx_regex *cr = (cxx_regex *)preg->cxx_regex;
cr->m_com_regexp.Release();
delete cr;
preg->cxx_regex = NULL;
}

38
src/com_regexp.hpp Normal file
View File

@ -0,0 +1,38 @@
#ifndef COM_REGEXP_HPP
#define COM_REGEXP_HPP
/* ref: http://code.google.com/p/tinysegmenter-cpp */
typedef struct regex_s
{
void *cxx_regex;
} regex_t;
typedef struct regmatch_s
{
void *cxx_regmatch;
} regmatch_t;
enum regexp_result
{
REG_NOMATCH = 1,
REG_EXTENDED = 0x00000100
};
#ifdef __cplusplus
extern "C" {
#endif
int regcomp(regex_t *preg, const char *pattern, int cflags);
int regwcomp(regex_t *preg, const wchar_t *pattern, int cflags);
size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t *pmatch, int eflags);
int regwexec(const regex_t *preg, const wchar_t *string, size_t nmatch, regmatch_t *pmatch, int eflags);
void regfree(regex_t *preg);
#ifdef __cplusplus
}
#endif
#endif // !COM_REGEXP_HPP

View File

@ -24,7 +24,11 @@
#endif
#include <stdlib.h>
#if defined HAVE_REGEX_H
# include <regex.h>
# if _WIN32
# include "../com_regexp.hpp"
# else
# include <regex.h>
# endif
#endif
#include <string.h>
#include <math.h>
@ -208,6 +212,21 @@ int _zz_mustwatch(char const *file)
return 1; /* default */
}
int _zz_mustwatchw(wchar_t const *file)
{
#if defined HAVE_REGEX_H
if(has_include && regwexec(&re_include, file, 0, NULL, 0) == REG_NOMATCH)
return 0; /* not included: ignore */
if(has_exclude && regwexec(&re_exclude, file, 0, NULL, 0) != REG_NOMATCH)
return 0; /* excluded: ignore */
#else
(void)file;
#endif
return 1; /* default */
}
int _zz_iswatched(int fd)
{
if(fd < 0 || fd >= maxfd || fds[fd] == -1)

View File

@ -24,6 +24,7 @@ extern void _zz_fd_init(void);
extern void _zz_fd_fini(void);
extern int _zz_mustwatch(char const *);
extern int _zz_mustwatchw(wchar_t const *);
extern int _zz_iswatched(int);
extern void _zz_register(int);
extern void _zz_unregister(int);

View File

@ -105,7 +105,7 @@ HANDLE __stdcall NEW(CreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess,
dwFlagsAndAttributes, (int)ret);
if(!_zz_ready || _zz_islocked(-1)) return ret;
if (ret != INVALID_HANDLE_VALUE && dwCreationDisposition == OPEN_EXISTING && _zz_mustwatch(lpFileName))
if (ret != INVALID_HANDLE_VALUE && dwCreationDisposition == OPEN_EXISTING && _zz_mustwatchw(lpFileName))
{
debug("handle %#08x is registered", ret);
_zz_register(ret);

View File

@ -379,7 +379,7 @@ static int run_process(struct child *child, struct opts *opts, int pipes[][2])
/* insert your breakpoint here to have a chance to attach a debugger to libzzuf.dll */
ret = ResumeThread(pinfo.hThread);
if(ret < 0)
if(ret == -1)
{
TerminateProcess(pinfo.hProcess, -1);
return -1;

2508
src/zzuf.c

File diff suppressed because it is too large Load Diff