dbghelp: Use new regular expression matcher for files.

This commit is contained in:
Eric Pouech 2012-01-22 12:58:04 +01:00 committed by Alexandre Julliard
parent 026ec7f690
commit f3107df576
1 changed files with 56 additions and 94 deletions

View File

@ -30,9 +30,6 @@
#include <limits.h>
#include <sys/types.h>
#include <assert.h>
#ifdef HAVE_REGEX_H
# include <regex.h>
#endif
#include "wine/debug.h"
#include "dbghelp_private.h"
@ -138,101 +135,54 @@ static void symt_add_module_ht(struct module* module, struct symt_ht* ht)
}
}
#ifdef HAVE_REGEX_H
static BOOL compile_file_regex(regex_t* re, const char* srcfile)
static WCHAR* file_regex(const char* srcfile)
{
char *mask, *p;
BOOL ret;
WCHAR* mask;
WCHAR* p;
if (!srcfile || !*srcfile) return regcomp(re, ".*", REG_NOSUB);
p = mask = HeapAlloc(GetProcessHeap(), 0, 5 * strlen(srcfile) + 4);
*p++ = '^';
while (*srcfile)
if (!srcfile || !*srcfile)
{
switch (*srcfile)
if (!(p = mask = HeapAlloc(GetProcessHeap(), 0, 3 * sizeof(WCHAR)))) return NULL;
*p++ = '?';
*p++ = '#';
}
else
{
DWORD sz = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
WCHAR* srcfileW;
/* FIXME: we use here the largest conversion for every char... could be optimized */
p = mask = HeapAlloc(GetProcessHeap(), 0, (5 * strlen(srcfile) + 1 + sz) * sizeof(WCHAR));
if (!mask) return NULL;
srcfileW = mask + 5 * strlen(srcfile) + 1;
MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, sz);
while (*srcfileW)
{
case '\\':
case '/':
*p++ = '[';
*p++ = '\\';
*p++ = '\\';
*p++ = '/';
*p++ = ']';
break;
case '.':
*p++ = '\\';
*p++ = '.';
break;
case '*':
*p++ = '.';
*p++ = '*';
break;
default:
*p++ = *srcfile;
break;
switch (*srcfileW)
{
case '\\':
case '/':
*p++ = '[';
*p++ = '\\';
*p++ = '\\';
*p++ = '/';
*p++ = ']';
break;
case '.':
*p++ = '?';
break;
default:
*p++ = *srcfileW;
break;
}
srcfileW++;
}
srcfile++;
}
*p++ = '$';
*p = 0;
ret = !regcomp(re, mask, REG_NOSUB);
HeapFree(GetProcessHeap(), 0, mask);
if (!ret)
{
FIXME("Couldn't compile %s\n", mask);
SetLastError(ERROR_INVALID_PARAMETER);
}
return ret;
return mask;
}
static int match_regexp( const regex_t *re, const char *str )
{
return !regexec( re, str, 0, NULL, 0 );
}
#else /* HAVE_REGEX_H */
/* if we don't have regexp support, fall back to a simple string comparison */
typedef struct
{
char *str;
BOOL icase;
} regex_t;
static void compile_regex(const char* str, int numchar, regex_t* re, BOOL _case)
{
if (numchar == -1) numchar = strlen( str );
re->str = HeapAlloc( GetProcessHeap(), 0, numchar + 1 );
memcpy( re->str, str, numchar );
re->str[numchar] = 0;
re->icase = _case;
}
static BOOL compile_file_regex(regex_t* re, const char* srcfile)
{
if (!srcfile || !*srcfile) re->str = NULL;
else compile_regex( srcfile, -1, re, FALSE );
return TRUE;
}
static int match_regexp( const regex_t *re, const char *str )
{
if (!re->str) return 1;
if (re->icase) return !lstrcmpiA( re->str, str );
return !strcmp( re->str, str );
}
static void regfree( regex_t *re )
{
HeapFree( GetProcessHeap(), 0, re->str );
}
#endif /* HAVE_REGEX_H */
struct symt_compiland* symt_new_compiland(struct module* module,
unsigned long address, unsigned src_idx)
{
@ -2136,7 +2086,7 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland,
struct module_pair pair;
struct hash_table_iter hti;
struct symt_ht* sym;
regex_t re;
WCHAR* srcmask;
struct line_info* dli;
void* ptr;
SRCCODEINFO sci;
@ -2150,7 +2100,7 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland,
if (compiland) FIXME("Unsupported yet (filtering on compiland %s)\n", compiland);
pair.requested = module_find_by_addr(pair.pcs, base, DMT_UNKNOWN);
if (!module_get_debug(&pair)) return FALSE;
if (!compile_file_regex(&re, srcfile)) return FALSE;
if (!(srcmask = file_regex(srcfile))) return FALSE;
sci.SizeOfStruct = sizeof(sci);
sci.ModBase = base;
@ -2170,8 +2120,20 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland,
if (dli->is_source_file)
{
file = source_get(pair.effective, dli->u.source_file);
if (!match_regexp(&re, file)) sci.FileName[0] = '\0';
else strcpy(sci.FileName, file);
if (!file) sci.FileName[0] = '\0';
else
{
DWORD sz = MultiByteToWideChar(CP_ACP, 0, file, -1, NULL, 0);
WCHAR* fileW;
if ((fileW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, sz);
if (SymMatchStringW(fileW, srcmask, FALSE))
strcpy(sci.FileName, file);
else
sci.FileName[0] = '\0';
HeapFree(GetProcessHeap(), 0, fileW);
}
}
else if (sci.FileName[0])
{
@ -2183,7 +2145,7 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland,
}
}
}
regfree(&re);
HeapFree(GetProcessHeap(), 0, srcmask);
return TRUE;
}