mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[VBSCRIPT] Sync with Wine 10.0. CORE-20606
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
|
||||
add_definitions(-D__ROS_LONG64__)
|
||||
spec2def(vbscript.dll vbscript.spec)
|
||||
|
||||
list(APPEND SOURCE
|
||||
@@ -14,23 +13,17 @@ list(APPEND SOURCE
|
||||
vbscript.c
|
||||
vbscript_main.c)
|
||||
|
||||
BISON_TARGET(parser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.tab.c COMPILE_FLAGS "-p parser_")
|
||||
BISON_TARGET(parser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.tab.c)
|
||||
|
||||
list(APPEND PCH_SKIP_SOURCE
|
||||
guid.c
|
||||
${BISON_parser_OUTPUTS})
|
||||
|
||||
list(APPEND vbscript_rc_deps
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vbscript_classes.rgs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vbsglobal.rgs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vbsregexp10.rgs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vbsregexp55.rgs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/vbsglobal.tlb
|
||||
${CMAKE_CURRENT_BINARY_DIR}/vbsregexp10.tlb
|
||||
${CMAKE_CURRENT_BINARY_DIR}/vbsregexp55.tlb)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vbscript.rgs)
|
||||
|
||||
set_source_files_properties(vbscript.rc PROPERTIES OBJECT_DEPENDS "${vbscript_rc_deps}")
|
||||
add_idl_headers(vbscript_idlheader vbscript_classes.idl vbsglobal.idl vbsregexp55.idl)
|
||||
add_typelib(vbsglobal.idl vbsregexp10.idl vbsregexp55.idl)
|
||||
|
||||
add_library(vbscript MODULE
|
||||
${SOURCE}
|
||||
@@ -43,9 +36,11 @@ if(MSVC)
|
||||
target_compile_options(vbscript PRIVATE /wd4267)
|
||||
endif()
|
||||
|
||||
add_idl_reg_scripts(vbscript registry vbscript_classes.idl)
|
||||
add_idl_reg_scripts(vbscript regtypelib vbsglobal.idl vbsregexp10.idl vbsregexp55.idl)
|
||||
set_module_type(vbscript win32dll)
|
||||
target_link_libraries(vbscript uuid wine oldnames)
|
||||
add_importlibs(vbscript oleaut32 ole32 user32 msvcrt kernel32 ntdll)
|
||||
target_link_libraries(vbscript uuid wine oldnames wine_dll_register wine_dll_canunload)
|
||||
add_importlibs(vbscript oleaut32 ole32 user32 msvcrt kernelbase kernel32_vista kernel32 ntdll)
|
||||
add_dependencies(vbscript vbscript_idlheader stdole2)
|
||||
add_pch(vbscript precomp.h "${PCH_SKIP_SOURCE}")
|
||||
add_cd_file(TARGET vbscript DESTINATION reactos/system32 FOR all)
|
||||
|
||||
+368
-221
File diff suppressed because it is too large
Load Diff
+994
-247
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <wingdi.h>
|
||||
#include <objbase.h>
|
||||
#include <initguid.h>
|
||||
#include <dispex.h>
|
||||
#include <vbscript_classes.h>
|
||||
|
||||
/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */
|
||||
+637
-266
File diff suppressed because it is too large
Load Diff
+166
-139
@@ -32,125 +32,70 @@
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
|
||||
|
||||
static const WCHAR andW[] = {'a','n','d',0};
|
||||
static const WCHAR byrefW[] = {'b','y','r','e','f',0};
|
||||
static const WCHAR byvalW[] = {'b','y','v','a','l',0};
|
||||
static const WCHAR callW[] = {'c','a','l','l',0};
|
||||
static const WCHAR caseW[] = {'c','a','s','e',0};
|
||||
static const WCHAR classW[] = {'c','l','a','s','s',0};
|
||||
static const WCHAR constW[] = {'c','o','n','s','t',0};
|
||||
static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
|
||||
static const WCHAR dimW[] = {'d','i','m',0};
|
||||
static const WCHAR doW[] = {'d','o',0};
|
||||
static const WCHAR eachW[] = {'e','a','c','h',0};
|
||||
static const WCHAR elseW[] = {'e','l','s','e',0};
|
||||
static const WCHAR elseifW[] = {'e','l','s','e','i','f',0};
|
||||
static const WCHAR emptyW[] = {'e','m','p','t','y',0};
|
||||
static const WCHAR endW[] = {'e','n','d',0};
|
||||
static const WCHAR eqvW[] = {'e','q','v',0};
|
||||
static const WCHAR errorW[] = {'e','r','r','o','r',0};
|
||||
static const WCHAR exitW[] = {'e','x','i','t',0};
|
||||
static const WCHAR explicitW[] = {'e','x','p','l','i','c','i','t',0};
|
||||
static const WCHAR falseW[] = {'f','a','l','s','e',0};
|
||||
static const WCHAR forW[] = {'f','o','r',0};
|
||||
static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
|
||||
static const WCHAR getW[] = {'g','e','t',0};
|
||||
static const WCHAR gotoW[] = {'g','o','t','o',0};
|
||||
static const WCHAR ifW[] = {'i','f',0};
|
||||
static const WCHAR impW[] = {'i','m','p',0};
|
||||
static const WCHAR inW[] = {'i','n',0};
|
||||
static const WCHAR isW[] = {'i','s',0};
|
||||
static const WCHAR letW[] = {'l','e','t',0};
|
||||
static const WCHAR loopW[] = {'l','o','o','p',0};
|
||||
static const WCHAR meW[] = {'m','e',0};
|
||||
static const WCHAR modW[] = {'m','o','d',0};
|
||||
static const WCHAR newW[] = {'n','e','w',0};
|
||||
static const WCHAR nextW[] = {'n','e','x','t',0};
|
||||
static const WCHAR notW[] = {'n','o','t',0};
|
||||
static const WCHAR nothingW[] = {'n','o','t','h','i','n','g',0};
|
||||
static const WCHAR nullW[] = {'n','u','l','l',0};
|
||||
static const WCHAR onW[] = {'o','n',0};
|
||||
static const WCHAR optionW[] = {'o','p','t','i','o','n',0};
|
||||
static const WCHAR orW[] = {'o','r',0};
|
||||
static const WCHAR privateW[] = {'p','r','i','v','a','t','e',0};
|
||||
static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
||||
static const WCHAR publicW[] = {'p','u','b','l','i','c',0};
|
||||
static const WCHAR remW[] = {'r','e','m',0};
|
||||
static const WCHAR resumeW[] = {'r','e','s','u','m','e',0};
|
||||
static const WCHAR selectW[] = {'s','e','l','e','c','t',0};
|
||||
static const WCHAR setW[] = {'s','e','t',0};
|
||||
static const WCHAR stepW[] = {'s','t','e','p',0};
|
||||
static const WCHAR stopW[] = {'s','t','o','p',0};
|
||||
static const WCHAR subW[] = {'s','u','b',0};
|
||||
static const WCHAR thenW[] = {'t','h','e','n',0};
|
||||
static const WCHAR toW[] = {'t','o',0};
|
||||
static const WCHAR trueW[] = {'t','r','u','e',0};
|
||||
static const WCHAR untilW[] = {'u','n','t','i','l',0};
|
||||
static const WCHAR wendW[] = {'w','e','n','d',0};
|
||||
static const WCHAR whileW[] = {'w','h','i','l','e',0};
|
||||
static const WCHAR xorW[] = {'x','o','r',0};
|
||||
|
||||
static const struct {
|
||||
const WCHAR *word;
|
||||
int token;
|
||||
} keywords[] = {
|
||||
{andW, tAND},
|
||||
{byrefW, tBYREF},
|
||||
{byvalW, tBYVAL},
|
||||
{callW, tCALL},
|
||||
{caseW, tCASE},
|
||||
{classW, tCLASS},
|
||||
{constW, tCONST},
|
||||
{defaultW, tDEFAULT},
|
||||
{dimW, tDIM},
|
||||
{doW, tDO},
|
||||
{eachW, tEACH},
|
||||
{elseW, tELSE},
|
||||
{elseifW, tELSEIF},
|
||||
{emptyW, tEMPTY},
|
||||
{endW, tEND},
|
||||
{eqvW, tEQV},
|
||||
{errorW, tERROR},
|
||||
{exitW, tEXIT},
|
||||
{explicitW, tEXPLICIT},
|
||||
{falseW, tFALSE},
|
||||
{forW, tFOR},
|
||||
{functionW, tFUNCTION},
|
||||
{getW, tGET},
|
||||
{gotoW, tGOTO},
|
||||
{ifW, tIF},
|
||||
{impW, tIMP},
|
||||
{inW, tIN},
|
||||
{isW, tIS},
|
||||
{letW, tLET},
|
||||
{loopW, tLOOP},
|
||||
{meW, tME},
|
||||
{modW, tMOD},
|
||||
{newW, tNEW},
|
||||
{nextW, tNEXT},
|
||||
{notW, tNOT},
|
||||
{nothingW, tNOTHING},
|
||||
{nullW, tNULL},
|
||||
{onW, tON},
|
||||
{optionW, tOPTION},
|
||||
{orW, tOR},
|
||||
{privateW, tPRIVATE},
|
||||
{propertyW, tPROPERTY},
|
||||
{publicW, tPUBLIC},
|
||||
{remW, tREM},
|
||||
{resumeW, tRESUME},
|
||||
{selectW, tSELECT},
|
||||
{setW, tSET},
|
||||
{stepW, tSTEP},
|
||||
{stopW, tSTOP},
|
||||
{subW, tSUB},
|
||||
{thenW, tTHEN},
|
||||
{toW, tTO},
|
||||
{trueW, tTRUE},
|
||||
{untilW, tUNTIL},
|
||||
{wendW, tWEND},
|
||||
{whileW, tWHILE},
|
||||
{xorW, tXOR}
|
||||
{L"and", tAND},
|
||||
{L"byref", tBYREF},
|
||||
{L"byval", tBYVAL},
|
||||
{L"call", tCALL},
|
||||
{L"case", tCASE},
|
||||
{L"class", tCLASS},
|
||||
{L"const", tCONST},
|
||||
{L"default", tDEFAULT},
|
||||
{L"dim", tDIM},
|
||||
{L"do", tDO},
|
||||
{L"each", tEACH},
|
||||
{L"else", tELSE},
|
||||
{L"elseif", tELSEIF},
|
||||
{L"empty", tEMPTY},
|
||||
{L"end", tEND},
|
||||
{L"eqv", tEQV},
|
||||
{L"error", tERROR},
|
||||
{L"exit", tEXIT},
|
||||
{L"explicit", tEXPLICIT},
|
||||
{L"false", tFALSE},
|
||||
{L"for", tFOR},
|
||||
{L"function", tFUNCTION},
|
||||
{L"get", tGET},
|
||||
{L"goto", tGOTO},
|
||||
{L"if", tIF},
|
||||
{L"imp", tIMP},
|
||||
{L"in", tIN},
|
||||
{L"is", tIS},
|
||||
{L"let", tLET},
|
||||
{L"loop", tLOOP},
|
||||
{L"me", tME},
|
||||
{L"mod", tMOD},
|
||||
{L"new", tNEW},
|
||||
{L"next", tNEXT},
|
||||
{L"not", tNOT},
|
||||
{L"nothing", tNOTHING},
|
||||
{L"null", tNULL},
|
||||
{L"on", tON},
|
||||
{L"option", tOPTION},
|
||||
{L"or", tOR},
|
||||
{L"preserve", tPRESERVE},
|
||||
{L"private", tPRIVATE},
|
||||
{L"property", tPROPERTY},
|
||||
{L"public", tPUBLIC},
|
||||
{L"redim", tREDIM},
|
||||
{L"rem", tREM},
|
||||
{L"resume", tRESUME},
|
||||
{L"select", tSELECT},
|
||||
{L"set", tSET},
|
||||
{L"step", tSTEP},
|
||||
{L"stop", tSTOP},
|
||||
{L"sub", tSUB},
|
||||
{L"then", tTHEN},
|
||||
{L"to", tTO},
|
||||
{L"true", tTRUE},
|
||||
{L"until", tUNTIL},
|
||||
{L"wend", tWEND},
|
||||
{L"while", tWHILE},
|
||||
{L"with", tWITH},
|
||||
{L"xor", tXOR}
|
||||
};
|
||||
|
||||
static inline BOOL is_identifier_char(WCHAR c)
|
||||
@@ -263,6 +208,48 @@ static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret)
|
||||
return tString;
|
||||
}
|
||||
|
||||
static int parse_date_literal(parser_ctx_t *ctx, DATE *ret)
|
||||
{
|
||||
const WCHAR *ptr = ++ctx->ptr;
|
||||
WCHAR *rptr;
|
||||
int len = 0;
|
||||
HRESULT res;
|
||||
|
||||
while(ctx->ptr < ctx->end) {
|
||||
if(*ctx->ptr == '\n' || *ctx->ptr == '\r') {
|
||||
FIXME("newline inside date literal\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(*ctx->ptr == '#')
|
||||
break;
|
||||
ctx->ptr++;
|
||||
}
|
||||
|
||||
if(ctx->ptr == ctx->end) {
|
||||
FIXME("unterminated date literal\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
len += ctx->ptr-ptr;
|
||||
|
||||
rptr = malloc((len+1)*sizeof(WCHAR));
|
||||
if(!rptr)
|
||||
return 0;
|
||||
|
||||
memcpy( rptr, ptr, len * sizeof(WCHAR));
|
||||
rptr[len] = 0;
|
||||
res = VarDateFromStr(rptr, ctx->lcid, 0, ret);
|
||||
free(rptr);
|
||||
if (FAILED(res)) {
|
||||
FIXME("Invalid date literal\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->ptr++;
|
||||
return tDate;
|
||||
}
|
||||
|
||||
static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
||||
{
|
||||
BOOL use_int = TRUE;
|
||||
@@ -273,7 +260,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
||||
if(*ctx->ptr == '0' && !('0' <= ctx->ptr[1] && ctx->ptr[1] <= '9') && ctx->ptr[1] != '.')
|
||||
return *ctx->ptr++;
|
||||
|
||||
while(ctx->ptr < ctx->end && iswdigit(*ctx->ptr)) {
|
||||
while(ctx->ptr < ctx->end && is_digit(*ctx->ptr)) {
|
||||
hlp = d*10 + *(ctx->ptr++) - '0';
|
||||
if(d>MAXLONGLONG/10 || hlp<0) {
|
||||
exp++;
|
||||
@@ -282,7 +269,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
||||
else
|
||||
d = hlp;
|
||||
}
|
||||
while(ctx->ptr < ctx->end && iswdigit(*ctx->ptr)) {
|
||||
while(ctx->ptr < ctx->end && is_digit(*ctx->ptr)) {
|
||||
exp++;
|
||||
ctx->ptr++;
|
||||
}
|
||||
@@ -291,7 +278,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
||||
use_int = FALSE;
|
||||
ctx->ptr++;
|
||||
|
||||
while(ctx->ptr < ctx->end && iswdigit(*ctx->ptr)) {
|
||||
while(ctx->ptr < ctx->end && is_digit(*ctx->ptr)) {
|
||||
hlp = d*10 + *(ctx->ptr++) - '0';
|
||||
if(d>MAXLONGLONG/10 || hlp<0)
|
||||
break;
|
||||
@@ -299,7 +286,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
||||
d = hlp;
|
||||
exp--;
|
||||
}
|
||||
while(ctx->ptr < ctx->end && iswdigit(*ctx->ptr))
|
||||
while(ctx->ptr < ctx->end && is_digit(*ctx->ptr))
|
||||
ctx->ptr++;
|
||||
}
|
||||
|
||||
@@ -314,7 +301,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
||||
ctx->ptr++;
|
||||
}
|
||||
|
||||
if(!iswdigit(*ctx->ptr)) {
|
||||
if(!is_digit(*ctx->ptr)) {
|
||||
FIXME("Invalid numeric literal\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -325,7 +312,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
||||
e = e*10 + *(ctx->ptr++) - '0';
|
||||
if(sign == -1 && -e+exp < -(INT_MAX/100)) {
|
||||
/* The literal will be rounded to 0 anyway. */
|
||||
while(iswdigit(*ctx->ptr))
|
||||
while(is_digit(*ctx->ptr))
|
||||
ctx->ptr++;
|
||||
*(double*)ret = 0;
|
||||
return tDouble;
|
||||
@@ -335,7 +322,7 @@ static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
|
||||
FIXME("Invalid numeric literal\n");
|
||||
return 0;
|
||||
}
|
||||
} while(iswdigit(*ctx->ptr));
|
||||
} while(is_digit(*ctx->ptr));
|
||||
|
||||
exp += sign*e;
|
||||
}
|
||||
@@ -369,20 +356,22 @@ static int hex_to_int(WCHAR c)
|
||||
static int parse_hex_literal(parser_ctx_t *ctx, LONG *ret)
|
||||
{
|
||||
const WCHAR *begin = ctx->ptr;
|
||||
LONG l = 0, d;
|
||||
unsigned l = 0, d;
|
||||
|
||||
while((d = hex_to_int(*++ctx->ptr)) != -1)
|
||||
l = l*16 + d;
|
||||
|
||||
if(begin + 9 /* max digits+1 */ < ctx->ptr || (*ctx->ptr != '&' && is_identifier_char(*ctx->ptr))) {
|
||||
if(begin + 9 /* max digits+1 */ < ctx->ptr) {
|
||||
FIXME("invalid literal\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(*ctx->ptr == '&')
|
||||
if(*ctx->ptr == '&') {
|
||||
ctx->ptr++;
|
||||
|
||||
*ret = l;
|
||||
*ret = l;
|
||||
}else {
|
||||
*ret = l == (UINT16)l ? (INT16)l : l;
|
||||
}
|
||||
return tInt;
|
||||
}
|
||||
|
||||
@@ -394,8 +383,7 @@ static void skip_spaces(parser_ctx_t *ctx)
|
||||
|
||||
static int comment_line(parser_ctx_t *ctx)
|
||||
{
|
||||
static const WCHAR newlineW[] = {'\n','\r',0};
|
||||
ctx->ptr = wcspbrk(ctx->ptr, newlineW);
|
||||
ctx->ptr = wcspbrk(ctx->ptr, L"\n\r");
|
||||
if(ctx->ptr)
|
||||
ctx->ptr++;
|
||||
else
|
||||
@@ -403,13 +391,14 @@ static int comment_line(parser_ctx_t *ctx)
|
||||
return tNL;
|
||||
}
|
||||
|
||||
static int parse_next_token(void *lval, parser_ctx_t *ctx)
|
||||
static int parse_next_token(void *lval, unsigned *loc, parser_ctx_t *ctx)
|
||||
{
|
||||
WCHAR c;
|
||||
|
||||
skip_spaces(ctx);
|
||||
*loc = ctx->ptr - ctx->code;
|
||||
if(ctx->ptr == ctx->end)
|
||||
return ctx->last_token == tNL ? tEOF : tNL;
|
||||
return ctx->last_token == tNL ? 0 : tNL;
|
||||
|
||||
c = *ctx->ptr;
|
||||
|
||||
@@ -417,7 +406,9 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
|
||||
return parse_numeric_literal(ctx, lval);
|
||||
|
||||
if(iswalpha(c)) {
|
||||
int ret = check_keywords(ctx, lval);
|
||||
int ret = 0;
|
||||
if(ctx->last_token != '.' && ctx->last_token != tDOT)
|
||||
ret = check_keywords(ctx, lval);
|
||||
if(!ret)
|
||||
return parse_identifier(ctx, lval);
|
||||
if(ret != tREM)
|
||||
@@ -435,15 +426,29 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
|
||||
case ':':
|
||||
case ')':
|
||||
case ',':
|
||||
case '=':
|
||||
case '+':
|
||||
case '*':
|
||||
case '/':
|
||||
case '^':
|
||||
case '\\':
|
||||
case '.':
|
||||
case '_':
|
||||
return *ctx->ptr++;
|
||||
case '.':
|
||||
/*
|
||||
* We need to distinguish between '.' used as part of a member expression and
|
||||
* a beginning of a dot expression (a member expression accessing with statement
|
||||
* expression) and a floating point number like ".2" .
|
||||
*/
|
||||
c = ctx->ptr > ctx->code ? ctx->ptr[-1] : '\n';
|
||||
if (is_identifier_char(c) || c == ')') {
|
||||
ctx->ptr++;
|
||||
return '.';
|
||||
}
|
||||
c = ctx->ptr[1];
|
||||
if('0' <= c && c <= '9')
|
||||
return parse_numeric_literal(ctx, lval);
|
||||
ctx->ptr++;
|
||||
return tDOT;
|
||||
case '-':
|
||||
if(ctx->is_html && ctx->ptr[1] == '-' && ctx->ptr[2] == '>')
|
||||
return comment_line(ctx);
|
||||
@@ -460,13 +465,31 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
|
||||
ctx->ptr++;
|
||||
return tEMPTYBRACKETS;
|
||||
}
|
||||
return '(';
|
||||
/*
|
||||
* Parser can't predict if bracket is part of argument expression or an argument
|
||||
* in call expression. We predict it here instead.
|
||||
*/
|
||||
if(ctx->last_token == tIdentifier || ctx->last_token == ')')
|
||||
return '(';
|
||||
return tEXPRLBRACKET;
|
||||
case '"':
|
||||
return parse_string_literal(ctx, lval);
|
||||
case '#':
|
||||
return parse_date_literal(ctx, lval);
|
||||
case '&':
|
||||
if(*++ctx->ptr == 'h' || *ctx->ptr == 'H')
|
||||
if((*++ctx->ptr == 'h' || *ctx->ptr == 'H') && hex_to_int(ctx->ptr[1]) != -1)
|
||||
return parse_hex_literal(ctx, lval);
|
||||
return '&';
|
||||
case '=':
|
||||
switch(*++ctx->ptr) {
|
||||
case '<':
|
||||
ctx->ptr++;
|
||||
return tLTEQ;
|
||||
case '>':
|
||||
ctx->ptr++;
|
||||
return tGTEQ;
|
||||
}
|
||||
return '=';
|
||||
case '<':
|
||||
switch(*++ctx->ptr) {
|
||||
case '>':
|
||||
@@ -481,9 +504,13 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
|
||||
}
|
||||
return '<';
|
||||
case '>':
|
||||
if(*++ctx->ptr == '=') {
|
||||
switch(*++ctx->ptr) {
|
||||
case '=':
|
||||
ctx->ptr++;
|
||||
return tGTEQ;
|
||||
case '<':
|
||||
ctx->ptr++;
|
||||
return tNEQ;
|
||||
}
|
||||
return '>';
|
||||
default:
|
||||
@@ -493,7 +520,7 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parser_lex(void *lval, parser_ctx_t *ctx)
|
||||
int parser_lex(void *lval, unsigned *loc, parser_ctx_t *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -504,7 +531,7 @@ int parser_lex(void *lval, parser_ctx_t *ctx)
|
||||
}
|
||||
|
||||
while(1) {
|
||||
ret = parse_next_token(lval, ctx);
|
||||
ret = parse_next_token(lval, loc, ctx);
|
||||
if(ret == '_') {
|
||||
skip_spaces(ctx);
|
||||
if(*ctx->ptr != '\n' && *ctx->ptr != '\r') {
|
||||
|
||||
@@ -23,8 +23,11 @@ typedef enum {
|
||||
EXPR_AND,
|
||||
EXPR_BOOL,
|
||||
EXPR_BRACKETS,
|
||||
EXPR_CALL,
|
||||
EXPR_CONCAT,
|
||||
EXPR_DATE,
|
||||
EXPR_DIV,
|
||||
EXPR_DOT,
|
||||
EXPR_DOUBLE,
|
||||
EXPR_EMPTY,
|
||||
EXPR_EQUAL,
|
||||
@@ -70,6 +73,11 @@ typedef struct {
|
||||
LONG value;
|
||||
} int_expression_t;
|
||||
|
||||
typedef struct {
|
||||
expression_t expr;
|
||||
DATE value;
|
||||
} date_expression_t;
|
||||
|
||||
typedef struct {
|
||||
expression_t expr;
|
||||
double value;
|
||||
@@ -95,9 +103,14 @@ typedef struct {
|
||||
expression_t expr;
|
||||
expression_t *obj_expr;
|
||||
const WCHAR *identifier;
|
||||
expression_t *args;
|
||||
} member_expression_t;
|
||||
|
||||
typedef struct {
|
||||
expression_t expr;
|
||||
expression_t *call_expr;
|
||||
expression_t *args;
|
||||
} call_expression_t;
|
||||
|
||||
typedef enum {
|
||||
STAT_ASSIGN,
|
||||
STAT_CALL,
|
||||
@@ -115,29 +128,31 @@ typedef enum {
|
||||
STAT_FUNC,
|
||||
STAT_IF,
|
||||
STAT_ONERROR,
|
||||
STAT_REDIM,
|
||||
STAT_SELECT,
|
||||
STAT_SET,
|
||||
STAT_STOP,
|
||||
STAT_UNTIL,
|
||||
STAT_WHILE,
|
||||
STAT_WHILELOOP,
|
||||
STAT_WITH,
|
||||
STAT_RETVAL
|
||||
} statement_type_t;
|
||||
|
||||
typedef struct _statement_t {
|
||||
statement_type_t type;
|
||||
unsigned loc;
|
||||
struct _statement_t *next;
|
||||
} statement_t;
|
||||
|
||||
typedef struct {
|
||||
statement_t stat;
|
||||
member_expression_t *expr;
|
||||
BOOL is_strict;
|
||||
call_expression_t *expr;
|
||||
} call_statement_t;
|
||||
|
||||
typedef struct {
|
||||
statement_t stat;
|
||||
member_expression_t *member_expr;
|
||||
expression_t *left_expr;
|
||||
expression_t *value_expr;
|
||||
} assign_statement_t;
|
||||
|
||||
@@ -159,6 +174,18 @@ typedef struct _dim_statement_t {
|
||||
dim_decl_t *dim_decls;
|
||||
} dim_statement_t;
|
||||
|
||||
typedef struct _redim_decl_t {
|
||||
const WCHAR *identifier;
|
||||
expression_t *dims;
|
||||
struct _redim_decl_t *next;
|
||||
} redim_decl_t;
|
||||
|
||||
typedef struct {
|
||||
statement_t stat;
|
||||
BOOL preserve;
|
||||
redim_decl_t *redim_decls;
|
||||
} redim_statement_t;
|
||||
|
||||
typedef struct _arg_decl_t {
|
||||
const WCHAR *name;
|
||||
BOOL by_ref;
|
||||
@@ -169,6 +196,7 @@ typedef struct _function_decl_t {
|
||||
const WCHAR *name;
|
||||
function_type_t type;
|
||||
BOOL is_public;
|
||||
BOOL is_default;
|
||||
arg_decl_t *args;
|
||||
statement_t *body;
|
||||
struct _function_decl_t *next;
|
||||
@@ -190,6 +218,7 @@ typedef struct _class_decl_t {
|
||||
typedef struct _elseif_decl_t {
|
||||
expression_t *expr;
|
||||
statement_t *stat;
|
||||
unsigned loc;
|
||||
struct _elseif_decl_t *next;
|
||||
} elseif_decl_t;
|
||||
|
||||
@@ -251,6 +280,12 @@ typedef struct {
|
||||
case_clausule_t *case_clausules;
|
||||
} select_statement_t;
|
||||
|
||||
typedef struct {
|
||||
statement_t stat;
|
||||
expression_t *expr;
|
||||
statement_t *body;
|
||||
} with_statement_t;
|
||||
|
||||
typedef struct {
|
||||
statement_t stat;
|
||||
expression_t *expr;
|
||||
@@ -262,9 +297,10 @@ typedef struct {
|
||||
const WCHAR *end;
|
||||
|
||||
BOOL option_explicit;
|
||||
BOOL parse_complete;
|
||||
BOOL is_html;
|
||||
HRESULT hres;
|
||||
int error_loc;
|
||||
LCID lcid;
|
||||
|
||||
int last_token;
|
||||
unsigned last_nl;
|
||||
@@ -276,7 +312,7 @@ typedef struct {
|
||||
heap_pool_t heap;
|
||||
} parser_ctx_t;
|
||||
|
||||
HRESULT parse_script(parser_ctx_t*,const WCHAR*,const WCHAR*,DWORD) DECLSPEC_HIDDEN;
|
||||
void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN;
|
||||
int parser_lex(void*,parser_ctx_t*) DECLSPEC_HIDDEN;
|
||||
void *parser_alloc(parser_ctx_t*,size_t) DECLSPEC_HIDDEN;
|
||||
HRESULT parse_script(parser_ctx_t*,const WCHAR*,const WCHAR*,DWORD);
|
||||
void parser_release(parser_ctx_t*);
|
||||
int parser_lex(void*,unsigned*,parser_ctx_t*);
|
||||
void *parser_alloc(parser_ctx_t*,size_t);
|
||||
|
||||
+326
-196
@@ -25,9 +25,8 @@
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
|
||||
|
||||
static int parser_error(parser_ctx_t *,const char*);
|
||||
static int parser_error(unsigned*,parser_ctx_t*,const char*);
|
||||
|
||||
static void parse_complete(parser_ctx_t*,BOOL);
|
||||
static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr);
|
||||
|
||||
static void source_add_statement(parser_ctx_t*,statement_t*);
|
||||
@@ -35,6 +34,7 @@ static void source_add_class(parser_ctx_t*,class_decl_t*);
|
||||
|
||||
static void *new_expression(parser_ctx_t*,expression_type_t,size_t);
|
||||
static expression_t *new_bool_expression(parser_ctx_t*,VARIANT_BOOL);
|
||||
static expression_t *new_date_expression(parser_ctx_t*,DATE);
|
||||
static expression_t *new_string_expression(parser_ctx_t*,const WCHAR*);
|
||||
static expression_t *new_long_expression(parser_ctx_t*,expression_type_t,LONG);
|
||||
static expression_t *new_double_expression(parser_ctx_t*,double);
|
||||
@@ -43,24 +43,29 @@ static expression_t *new_binary_expression(parser_ctx_t*,expression_type_t,expre
|
||||
static expression_t *new_new_expression(parser_ctx_t*,const WCHAR*);
|
||||
|
||||
static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);
|
||||
static call_expression_t *new_call_expression(parser_ctx_t*,expression_t*,expression_t*);
|
||||
static call_expression_t *make_call_expression(parser_ctx_t*,expression_t*,expression_t*);
|
||||
|
||||
static void *new_statement(parser_ctx_t*,statement_type_t,size_t);
|
||||
static statement_t *new_call_statement(parser_ctx_t*,BOOL,member_expression_t*);
|
||||
static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expression_t*);
|
||||
static statement_t *new_set_statement(parser_ctx_t*,member_expression_t*,expression_t*);
|
||||
static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*);
|
||||
static statement_t *new_while_statement(parser_ctx_t*,statement_type_t,expression_t*,statement_t*);
|
||||
static statement_t *new_forto_statement(parser_ctx_t*,const WCHAR*,expression_t*,expression_t*,expression_t*,statement_t*);
|
||||
static statement_t *new_foreach_statement(parser_ctx_t*,const WCHAR*,expression_t*,statement_t*);
|
||||
static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
|
||||
static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
|
||||
static statement_t *new_onerror_statement(parser_ctx_t*,BOOL);
|
||||
static statement_t *new_const_statement(parser_ctx_t*,const_decl_t*);
|
||||
static statement_t *new_select_statement(parser_ctx_t*,expression_t*,case_clausule_t*);
|
||||
static void *new_statement(parser_ctx_t*,statement_type_t,size_t,unsigned);
|
||||
static statement_t *new_call_statement(parser_ctx_t*,unsigned,expression_t*);
|
||||
static statement_t *new_assign_statement(parser_ctx_t*,unsigned,expression_t*,expression_t*);
|
||||
static statement_t *new_set_statement(parser_ctx_t*,unsigned,expression_t*,expression_t*);
|
||||
static statement_t *new_dim_statement(parser_ctx_t*,unsigned,dim_decl_t*);
|
||||
static statement_t *new_redim_statement(parser_ctx_t*,unsigned,BOOL,redim_decl_t*);
|
||||
static statement_t *new_while_statement(parser_ctx_t*,unsigned,statement_type_t,expression_t*,statement_t*);
|
||||
static statement_t *new_forto_statement(parser_ctx_t*,unsigned,const WCHAR*,expression_t*,expression_t*,expression_t*,statement_t*);
|
||||
static statement_t *new_foreach_statement(parser_ctx_t*,unsigned,const WCHAR*,expression_t*,statement_t*);
|
||||
static statement_t *new_if_statement(parser_ctx_t*,unsigned,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
|
||||
static statement_t *new_function_statement(parser_ctx_t*,unsigned,function_decl_t*);
|
||||
static statement_t *new_onerror_statement(parser_ctx_t*,unsigned,BOOL);
|
||||
static statement_t *new_const_statement(parser_ctx_t*,unsigned,const_decl_t*);
|
||||
static statement_t *new_select_statement(parser_ctx_t*,unsigned,expression_t*,case_clausule_t*);
|
||||
static statement_t *new_with_statement(parser_ctx_t*,unsigned,expression_t*,statement_t*);
|
||||
|
||||
static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,BOOL,dim_list_t*);
|
||||
static dim_list_t *new_dim(parser_ctx_t*,unsigned,dim_list_t*);
|
||||
static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
|
||||
static redim_decl_t *new_redim_decl(parser_ctx_t*,const WCHAR*,expression_t*);
|
||||
static elseif_decl_t *new_elseif_decl(parser_ctx_t*,unsigned,expression_t*,statement_t*);
|
||||
static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,arg_decl_t*,statement_t*);
|
||||
static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
|
||||
static const_decl_t *new_const_decl(parser_ctx_t*,const WCHAR*,expression_t*);
|
||||
@@ -77,11 +82,15 @@ static statement_t *link_statements(statement_t*,statement_t*);
|
||||
|
||||
#define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
|
||||
|
||||
#define PARSER_LTYPE unsigned
|
||||
#define YYLLOC_DEFAULT(Cur, Rhs, N) Cur = YYRHSLOC((Rhs), (N) ? 1 : 0)
|
||||
|
||||
%}
|
||||
|
||||
%lex-param { parser_ctx_t *ctx }
|
||||
%parse-param { parser_ctx_t *ctx }
|
||||
%pure-parser
|
||||
%define api.prefix {parser_}
|
||||
%define api.pure
|
||||
%start Program
|
||||
|
||||
%union {
|
||||
@@ -92,6 +101,7 @@ static statement_t *link_statements(statement_t*,statement_t*);
|
||||
elseif_decl_t *elseif;
|
||||
dim_decl_t *dim_decl;
|
||||
dim_list_t *dim_list;
|
||||
redim_decl_t *redim_decl;
|
||||
function_decl_t *func_decl;
|
||||
arg_decl_t *arg_decl;
|
||||
class_decl_t *class_decl;
|
||||
@@ -101,18 +111,20 @@ static statement_t *link_statements(statement_t*,statement_t*);
|
||||
LONG integer;
|
||||
BOOL boolean;
|
||||
double dbl;
|
||||
DATE date;
|
||||
}
|
||||
|
||||
%token tEXPRESSION tEOF tNL tEMPTYBRACKETS
|
||||
%token tEXPRESSION tNL tEMPTYBRACKETS tEXPRLBRACKET
|
||||
%token tLTEQ tGTEQ tNEQ
|
||||
%token tSTOP tME tREM
|
||||
%token tSTOP tME tREM tDOT
|
||||
%token <string> tTRUE tFALSE
|
||||
%token <string> tNOT tAND tOR tXOR tEQV tIMP
|
||||
%token <string> tIS tMOD
|
||||
%token <string> tCALL tDIM tSUB tFUNCTION tGET tLET tCONST
|
||||
%token <string> tCALL tSUB tFUNCTION tGET tLET tCONST
|
||||
%token <string> tDIM tREDIM tPRESERVE
|
||||
%token <string> tIF tELSE tELSEIF tEND tTHEN tEXIT
|
||||
%token <string> tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN
|
||||
%token <string> tSELECT tCASE
|
||||
%token <string> tSELECT tCASE tWITH
|
||||
%token <string> tBYREF tBYVAL
|
||||
%token <string> tOPTION
|
||||
%token <string> tNOTHING tEMPTY tNULL
|
||||
@@ -122,41 +134,54 @@ static statement_t *link_statements(statement_t*,statement_t*);
|
||||
%token <string> tDEFAULT tERROR tEXPLICIT tPROPERTY tSTEP
|
||||
%token <integer> tInt
|
||||
%token <dbl> tDouble
|
||||
%token <date> tDate
|
||||
|
||||
%type <statement> Statement SimpleStatement StatementNl StatementsNl StatementsNl_opt BodyStatements IfStatement Else_opt
|
||||
%type <statement> GlobalDimDeclaration
|
||||
%type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression ExpressionNl_opt
|
||||
%type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
|
||||
%type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
|
||||
%type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression SignExpression
|
||||
%type <expression> ConstExpression NumericLiteralExpression
|
||||
%type <member> MemberExpression
|
||||
%type <expression> Arguments_opt ArgumentList ArgumentList_opt Step_opt ExpressionList
|
||||
%type <boolean> OptionExplicit_opt DoType
|
||||
%type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
|
||||
%type <expression> Arguments ArgumentList ArgumentList_opt Step_opt ExpressionList
|
||||
%type <boolean> DoType Preserve_opt
|
||||
%type <arg_decl> ArgumentsDecl ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
|
||||
%type <func_decl> FunctionDecl PropertyDecl
|
||||
%type <elseif> ElseIfs_opt ElseIfs ElseIf
|
||||
%type <class_decl> ClassDeclaration ClassBody
|
||||
%type <uint> Storage Storage_opt IntegerValue
|
||||
%type <dim_decl> DimDeclList DimDecl
|
||||
%type <dim_list> DimList
|
||||
%type <redim_decl> ReDimDeclList ReDimDecl
|
||||
%type <const_decl> ConstDecl ConstDeclList
|
||||
%type <string> Identifier DotIdentifier
|
||||
%type <string> Identifier
|
||||
%type <case_clausule> CaseClausules
|
||||
|
||||
%%
|
||||
|
||||
Program
|
||||
: OptionExplicit_opt SourceElements tEOF { parse_complete(ctx, $1); }
|
||||
| tEXPRESSION ExpressionNl_opt tEOF { handle_isexpression_script(ctx, $2); }
|
||||
: OptionExplicit_opt SourceElements
|
||||
| tEXPRESSION ExpressionNl_opt { handle_isexpression_script(ctx, $2); }
|
||||
|
||||
OptionExplicit_opt
|
||||
: /* empty */ { $$ = FALSE; }
|
||||
| tOPTION tEXPLICIT StSep { $$ = TRUE; }
|
||||
: /* empty */
|
||||
| tOPTION tEXPLICIT StSep { ctx->option_explicit = TRUE; }
|
||||
|
||||
SourceElements
|
||||
: /* empty */
|
||||
| SourceElements GlobalDimDeclaration StSep
|
||||
{ source_add_statement(ctx, $2); }
|
||||
| SourceElements StatementNl { source_add_statement(ctx, $2); }
|
||||
| SourceElements ClassDeclaration { source_add_class(ctx, $2); }
|
||||
|
||||
GlobalDimDeclaration
|
||||
: tPRIVATE tCONST ConstDeclList { $$ = new_const_statement(ctx, @$, $3); CHECK_ERROR; }
|
||||
| tPUBLIC tCONST ConstDeclList { $$ = new_const_statement(ctx, @$, $3); CHECK_ERROR; }
|
||||
| tPRIVATE DimDeclList { $$ = new_dim_statement(ctx, @$, $2); CHECK_ERROR; }
|
||||
| tPUBLIC DimDeclList { $$ = new_dim_statement(ctx, @$, $2);
|
||||
(void)parser_nerrs; /* avoid unused variable warning */
|
||||
CHECK_ERROR; }
|
||||
|
||||
ExpressionNl_opt
|
||||
: /* empty */ { $$ = NULL; }
|
||||
| Expression tNL { $$ = $1; }
|
||||
@@ -171,8 +196,8 @@ StatementsNl_opt
|
||||
| StatementsNl { $$ = $1; }
|
||||
|
||||
StatementsNl
|
||||
: StatementNl { $$ = $1; }
|
||||
| StatementNl StatementsNl { $$ = link_statements($1, $2); }
|
||||
: SimpleStatement StSep { $$ = $1; }
|
||||
| SimpleStatement StSep StatementsNl { $$ = link_statements($1, $3); }
|
||||
|
||||
StatementNl
|
||||
: Statement tNL { $$ = $1; }
|
||||
@@ -185,43 +210,59 @@ Statement
|
||||
| SimpleStatement ':' { $$ = $1; }
|
||||
|
||||
SimpleStatement
|
||||
: MemberExpression ArgumentList_opt { $1->args = $2; $$ = new_call_statement(ctx, FALSE, $1); CHECK_ERROR; }
|
||||
| tCALL MemberExpression Arguments_opt { $2->args = $3; $$ = new_call_statement(ctx, TRUE, $2); CHECK_ERROR; }
|
||||
| MemberExpression Arguments_opt '=' Expression
|
||||
{ $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
|
||||
| tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
|
||||
: CallExpression ArgumentList_opt { call_expression_t *call_expr = make_call_expression(ctx, $1, $2); CHECK_ERROR;
|
||||
$$ = new_call_statement(ctx, @$, &call_expr->expr); CHECK_ERROR; }
|
||||
| tCALL UnaryExpression { $$ = new_call_statement(ctx, @$, $2); CHECK_ERROR; }
|
||||
| CallExpression '=' Expression
|
||||
{ $$ = new_assign_statement(ctx, @$, $1, $3); CHECK_ERROR; }
|
||||
| tDIM DimDeclList { $$ = new_dim_statement(ctx, @$, $2); CHECK_ERROR; }
|
||||
| tREDIM Preserve_opt ReDimDeclList { $$ = new_redim_statement(ctx, @$, $2, $3); CHECK_ERROR; }
|
||||
| IfStatement { $$ = $1; }
|
||||
| tWHILE Expression StSep StatementsNl_opt tWEND
|
||||
{ $$ = new_while_statement(ctx, STAT_WHILE, $2, $4); CHECK_ERROR; }
|
||||
{ $$ = new_while_statement(ctx, @$, STAT_WHILE, $2, $4); CHECK_ERROR; }
|
||||
| tDO DoType Expression StSep StatementsNl_opt tLOOP
|
||||
{ $$ = new_while_statement(ctx, $2 ? STAT_WHILELOOP : STAT_UNTIL, $3, $5);
|
||||
{ $$ = new_while_statement(ctx, @$, $2 ? STAT_WHILELOOP : STAT_UNTIL, $3, $5);
|
||||
CHECK_ERROR; }
|
||||
| tDO StSep StatementsNl_opt tLOOP DoType Expression
|
||||
{ $$ = new_while_statement(ctx, $5 ? STAT_DOWHILE : STAT_DOUNTIL, $6, $3);
|
||||
{ $$ = new_while_statement(ctx, @4, $5 ? STAT_DOWHILE : STAT_DOUNTIL, $6, $3);
|
||||
CHECK_ERROR; }
|
||||
| tDO StSep StatementsNl_opt tLOOP { $$ = new_while_statement(ctx, STAT_DOWHILE, NULL, $3); CHECK_ERROR; }
|
||||
| FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
|
||||
| tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 0); CHECK_ERROR; }
|
||||
| tEXIT tFOR { $$ = new_statement(ctx, STAT_EXITFOR, 0); CHECK_ERROR; }
|
||||
| tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; }
|
||||
| tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 0); CHECK_ERROR; }
|
||||
| tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; }
|
||||
| tSET MemberExpression Arguments_opt '=' Expression
|
||||
{ $2->args = $3; $$ = new_set_statement(ctx, $2, $5); CHECK_ERROR; }
|
||||
| tSTOP { $$ = new_statement(ctx, STAT_STOP, 0); CHECK_ERROR; }
|
||||
| tON tERROR tRESUME tNEXT { $$ = new_onerror_statement(ctx, TRUE); CHECK_ERROR; }
|
||||
| tON tERROR tGOTO '0' { $$ = new_onerror_statement(ctx, FALSE); CHECK_ERROR; }
|
||||
| tCONST ConstDeclList { $$ = new_const_statement(ctx, $2); CHECK_ERROR; }
|
||||
| tDO StSep StatementsNl_opt tLOOP { $$ = new_while_statement(ctx, @$, STAT_DOWHILE, NULL, $3); CHECK_ERROR; }
|
||||
| FunctionDecl { $$ = new_function_statement(ctx, @$, $1); CHECK_ERROR; }
|
||||
| tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 0, @$); CHECK_ERROR; }
|
||||
| tEXIT tFOR { $$ = new_statement(ctx, STAT_EXITFOR, 0, @$); CHECK_ERROR; }
|
||||
| tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0, @$); CHECK_ERROR; }
|
||||
| tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 0, @$); CHECK_ERROR; }
|
||||
| tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0, @$); CHECK_ERROR; }
|
||||
| tSET CallExpression '=' Expression { $$ = new_set_statement(ctx, @$, $2, $4); CHECK_ERROR; }
|
||||
| tSTOP { $$ = new_statement(ctx, STAT_STOP, 0, @$); CHECK_ERROR; }
|
||||
| tON tERROR tRESUME tNEXT { $$ = new_onerror_statement(ctx, @$, TRUE); CHECK_ERROR; }
|
||||
| tON tERROR tGOTO '0' { $$ = new_onerror_statement(ctx, @$, FALSE); CHECK_ERROR; }
|
||||
| tCONST ConstDeclList { $$ = new_const_statement(ctx, @$, $2); CHECK_ERROR; }
|
||||
| tFOR Identifier '=' Expression tTO Expression Step_opt StSep StatementsNl_opt tNEXT
|
||||
{ $$ = new_forto_statement(ctx, $2, $4, $6, $7, $9); CHECK_ERROR; }
|
||||
{ $$ = new_forto_statement(ctx, @$, $2, $4, $6, $7, $9); CHECK_ERROR; }
|
||||
| tFOR tEACH Identifier tIN Expression StSep StatementsNl_opt tNEXT
|
||||
{ $$ = new_foreach_statement(ctx, $3, $5, $7); }
|
||||
{ $$ = new_foreach_statement(ctx, @$, $3, $5, $7); }
|
||||
| tSELECT tCASE Expression StSep CaseClausules tEND tSELECT
|
||||
{ $$ = new_select_statement(ctx, $3, $5); }
|
||||
{ $$ = new_select_statement(ctx, @$, $3, $5); }
|
||||
| tWITH Expression StSep StatementsNl_opt tEND tWITH
|
||||
{ $$ = new_with_statement(ctx, @$, $2, $4); }
|
||||
|
||||
MemberExpression
|
||||
: Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
|
||||
| CallExpression '.' DotIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
|
||||
| CallExpression '.' tIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
|
||||
| tDOT tIdentifier { expression_t *dot_expr = new_expression(ctx, EXPR_DOT, sizeof(*dot_expr)); CHECK_ERROR;
|
||||
$$ = new_member_expression(ctx, dot_expr, $2); CHECK_ERROR; }
|
||||
|
||||
Preserve_opt
|
||||
: /* empty */ { $$ = FALSE; }
|
||||
| tPRESERVE { $$ = TRUE; }
|
||||
|
||||
ReDimDecl
|
||||
: tIdentifier '(' ArgumentList ')' { $$ = new_redim_decl(ctx, $1, $3); CHECK_ERROR; }
|
||||
|
||||
ReDimDeclList
|
||||
: ReDimDecl { $$ = $1; }
|
||||
| ReDimDecl ',' ReDimDeclList { $1->next = $3; $$ = $1; }
|
||||
|
||||
DimDeclList
|
||||
: DimDecl { $$ = $1; }
|
||||
@@ -257,10 +298,10 @@ Step_opt
|
||||
|
||||
IfStatement
|
||||
: tIF Expression tTHEN tNL StatementsNl_opt ElseIfs_opt Else_opt tEND tIF
|
||||
{ $$ = new_if_statement(ctx, $2, $5, $6, $7); CHECK_ERROR; }
|
||||
| tIF Expression tTHEN Statement EndIf_opt { $$ = new_if_statement(ctx, $2, $4, NULL, NULL); CHECK_ERROR; }
|
||||
{ $$ = new_if_statement(ctx, @$, $2, $5, $6, $7); CHECK_ERROR; }
|
||||
| tIF Expression tTHEN Statement EndIf_opt { $$ = new_if_statement(ctx, @$, $2, $4, NULL, NULL); CHECK_ERROR; }
|
||||
| tIF Expression tTHEN Statement tELSE Statement EndIf_opt
|
||||
{ $$ = new_if_statement(ctx, $2, $4, NULL, $6); CHECK_ERROR; }
|
||||
{ $$ = new_if_statement(ctx, @$, $2, $4, NULL, $6); CHECK_ERROR; }
|
||||
|
||||
EndIf_opt
|
||||
: /* empty */
|
||||
@@ -275,25 +316,24 @@ ElseIfs
|
||||
| ElseIf ElseIfs { $1->next = $2; $$ = $1; }
|
||||
|
||||
ElseIf
|
||||
: tELSEIF Expression tTHEN tNL StatementsNl_opt
|
||||
{ $$ = new_elseif_decl(ctx, $2, $5); }
|
||||
: tELSEIF Expression tTHEN StSep_opt StatementsNl_opt
|
||||
{ $$ = new_elseif_decl(ctx, @$, $2, $5); }
|
||||
|
||||
Else_opt
|
||||
: /* empty */ { $$ = NULL; }
|
||||
| tELSE tNL StatementsNl_opt { $$ = $3; }
|
||||
| tELSE StSep_opt StatementsNl_opt { $$ = $3; }
|
||||
|
||||
CaseClausules
|
||||
: /* empty */ { $$ = NULL; }
|
||||
| tCASE tELSE StSep StatementsNl { $$ = new_case_clausule(ctx, NULL, $4, NULL); }
|
||||
| tCASE ExpressionList StSep StatementsNl_opt CaseClausules
|
||||
{ $$ = new_case_clausule(ctx, $2, $4, $5); }
|
||||
: /* empty */ { $$ = NULL; }
|
||||
| tCASE tELSE StSep_opt StatementsNl_opt { $$ = new_case_clausule(ctx, NULL, $4, NULL); }
|
||||
| tCASE ExpressionList StSep_opt StatementsNl_opt CaseClausules { $$ = new_case_clausule(ctx, $2, $4, $5); }
|
||||
|
||||
Arguments_opt
|
||||
: EmptyBrackets_opt { $$ = NULL; }
|
||||
Arguments
|
||||
: tEMPTYBRACKETS { $$ = NULL; }
|
||||
| '(' ArgumentList ')' { $$ = $2; }
|
||||
|
||||
ArgumentList_opt
|
||||
: EmptyBrackets_opt { $$ = NULL; }
|
||||
: /* empty */ { $$ = NULL; }
|
||||
| ArgumentList { $$ = $1; }
|
||||
|
||||
ArgumentList
|
||||
@@ -369,24 +409,30 @@ MultiplicativeExpression
|
||||
{ $$ = new_binary_expression(ctx, EXPR_DIV, $1, $3); CHECK_ERROR; }
|
||||
|
||||
ExpExpression
|
||||
: UnaryExpression { $$ = $1; }
|
||||
| ExpExpression '^' UnaryExpression { $$ = new_binary_expression(ctx, EXPR_EXP, $1, $3); CHECK_ERROR; }
|
||||
: SignExpression { $$ = $1; }
|
||||
| ExpExpression '^' SignExpression { $$ = new_binary_expression(ctx, EXPR_EXP, $1, $3); CHECK_ERROR; }
|
||||
|
||||
SignExpression
|
||||
: UnaryExpression { $$ = $1; }
|
||||
| '-' SignExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
|
||||
| '+' SignExpression { $$ = $2; }
|
||||
|
||||
UnaryExpression
|
||||
: LiteralExpression { $$ = $1; }
|
||||
| CallExpression { $$ = $1; }
|
||||
| tNEW Identifier { $$ = new_new_expression(ctx, $2); CHECK_ERROR; }
|
||||
| '-' UnaryExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
|
||||
| '+' UnaryExpression { $$ = $2; }
|
||||
|
||||
CallExpression
|
||||
: PrimaryExpression { $$ = $1; }
|
||||
| MemberExpression Arguments_opt { $1->args = $2; $$ = &$1->expr; }
|
||||
: PrimaryExpression { $$ = $1; }
|
||||
| MemberExpression { $$ = &$1->expr; }
|
||||
| CallExpression Arguments { call_expression_t *expr = new_call_expression(ctx, $1, $2); CHECK_ERROR;
|
||||
$$ = &expr->expr; }
|
||||
|
||||
LiteralExpression
|
||||
: tTRUE { $$ = new_bool_expression(ctx, VARIANT_TRUE); CHECK_ERROR; }
|
||||
| tFALSE { $$ = new_bool_expression(ctx, VARIANT_FALSE); CHECK_ERROR; }
|
||||
| tString { $$ = new_string_expression(ctx, $1); CHECK_ERROR; }
|
||||
| tDate { $$ = new_date_expression(ctx, $1); CHECK_ERROR; }
|
||||
| NumericLiteralExpression { $$ = $1; }
|
||||
| tEMPTY { $$ = new_expression(ctx, EXPR_EMPTY, 0); CHECK_ERROR; }
|
||||
| tNULL { $$ = new_expression(ctx, EXPR_NULL, 0); CHECK_ERROR; }
|
||||
@@ -402,7 +448,7 @@ IntegerValue
|
||||
| tInt { $$ = $1; }
|
||||
|
||||
PrimaryExpression
|
||||
: '(' Expression ')' { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
|
||||
: tEXPRLBRACKET Expression ')' { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
|
||||
| tME { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; }
|
||||
|
||||
ClassDeclaration
|
||||
@@ -423,17 +469,21 @@ ClassBody
|
||||
| PropertyDecl StSep ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
|
||||
|
||||
PropertyDecl
|
||||
: Storage_opt tPROPERTY tGET tIdentifier ArgumentsDecl_opt StSep BodyStatements tEND tPROPERTY
|
||||
: Storage_opt tPROPERTY tGET Identifier ArgumentsDecl_opt StSep BodyStatements tEND tPROPERTY
|
||||
{ $$ = new_function_decl(ctx, $4, FUNC_PROPGET, $1, $5, $7); CHECK_ERROR; }
|
||||
| Storage_opt tPROPERTY tLET tIdentifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
|
||||
| Storage_opt tPROPERTY tLET Identifier '(' ArgumentDeclList ')' StSep BodyStatements tEND tPROPERTY
|
||||
{ $$ = new_function_decl(ctx, $4, FUNC_PROPLET, $1, $6, $9); CHECK_ERROR; }
|
||||
| Storage_opt tPROPERTY tSET tIdentifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
|
||||
| Storage_opt tPROPERTY tSET Identifier '(' ArgumentDeclList ')' StSep BodyStatements tEND tPROPERTY
|
||||
{ $$ = new_function_decl(ctx, $4, FUNC_PROPSET, $1, $6, $9); CHECK_ERROR; }
|
||||
|
||||
FunctionDecl
|
||||
: Storage_opt tSUB Identifier ArgumentsDecl_opt StSep BodyStatements tEND tSUB
|
||||
: Storage_opt tSUB Identifier StSep BodyStatements tEND tSUB
|
||||
{ $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, NULL, $5); CHECK_ERROR; }
|
||||
| Storage_opt tSUB Identifier ArgumentsDecl Nl_opt BodyStatements tEND tSUB
|
||||
{ $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, $4, $6); CHECK_ERROR; }
|
||||
| Storage_opt tFUNCTION Identifier ArgumentsDecl_opt StSep BodyStatements tEND tFUNCTION
|
||||
| Storage_opt tFUNCTION Identifier StSep BodyStatements tEND tFUNCTION
|
||||
{ $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, NULL, $5); CHECK_ERROR; }
|
||||
| Storage_opt tFUNCTION Identifier ArgumentsDecl Nl_opt BodyStatements tEND tFUNCTION
|
||||
{ $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, $4, $6); CHECK_ERROR; }
|
||||
|
||||
Storage_opt
|
||||
@@ -446,7 +496,11 @@ Storage
|
||||
| tPRIVATE { $$ = STORAGE_IS_PRIVATE; }
|
||||
|
||||
ArgumentsDecl_opt
|
||||
: EmptyBrackets_opt { $$ = NULL; }
|
||||
: /* empty*/ { $$ = 0; }
|
||||
| ArgumentsDecl { $$ = $1; }
|
||||
|
||||
ArgumentsDecl
|
||||
: tEMPTYBRACKETS { $$ = NULL; }
|
||||
| '(' ArgumentDeclList ')' { $$ = $2; }
|
||||
|
||||
ArgumentDeclList
|
||||
@@ -461,64 +515,19 @@ ArgumentDecl
|
||||
/* these keywords may also be an identifier, depending on context */
|
||||
Identifier
|
||||
: tIdentifier { $$ = $1; }
|
||||
| tDEFAULT { $$ = $1; }
|
||||
| tERROR { $$ = $1; }
|
||||
| tEXPLICIT { $$ = $1; }
|
||||
| tPROPERTY { $$ = $1; }
|
||||
| tSTEP { $$ = $1; }
|
||||
| tDEFAULT { ctx->last_token = tIdentifier; $$ = $1; }
|
||||
| tERROR { ctx->last_token = tIdentifier; $$ = $1; }
|
||||
| tEXPLICIT { ctx->last_token = tIdentifier; $$ = $1; }
|
||||
| tPROPERTY { ctx->last_token = tIdentifier; $$ = $1; }
|
||||
| tSTEP { ctx->last_token = tIdentifier; $$ = $1; }
|
||||
|
||||
/* most keywords can be an identifier after a dot */
|
||||
DotIdentifier
|
||||
: Identifier { $$ = $1; }
|
||||
| tTRUE { $$ = $1; }
|
||||
| tFALSE { $$ = $1; }
|
||||
| tNOT { $$ = $1; }
|
||||
| tAND { $$ = $1; }
|
||||
| tOR { $$ = $1; }
|
||||
| tXOR { $$ = $1; }
|
||||
| tEQV { $$ = $1; }
|
||||
| tIMP { $$ = $1; }
|
||||
| tIS { $$ = $1; }
|
||||
| tMOD { $$ = $1; }
|
||||
| tCALL { $$ = $1; }
|
||||
| tDIM { $$ = $1; }
|
||||
| tSUB { $$ = $1; }
|
||||
| tFUNCTION { $$ = $1; }
|
||||
| tGET { $$ = $1; }
|
||||
| tLET { $$ = $1; }
|
||||
| tCONST { $$ = $1; }
|
||||
| tIF { $$ = $1; }
|
||||
| tELSE { $$ = $1; }
|
||||
| tELSEIF { $$ = $1; }
|
||||
| tEND { $$ = $1; }
|
||||
| tTHEN { $$ = $1; }
|
||||
| tEXIT { $$ = $1; }
|
||||
| tWHILE { $$ = $1; }
|
||||
| tWEND { $$ = $1; }
|
||||
| tDO { $$ = $1; }
|
||||
| tLOOP { $$ = $1; }
|
||||
| tUNTIL { $$ = $1; }
|
||||
| tFOR { $$ = $1; }
|
||||
| tTO { $$ = $1; }
|
||||
| tEACH { $$ = $1; }
|
||||
| tIN { $$ = $1; }
|
||||
| tSELECT { $$ = $1; }
|
||||
| tCASE { $$ = $1; }
|
||||
| tBYREF { $$ = $1; }
|
||||
| tBYVAL { $$ = $1; }
|
||||
| tOPTION { $$ = $1; }
|
||||
| tNOTHING { $$ = $1; }
|
||||
| tEMPTY { $$ = $1; }
|
||||
| tNULL { $$ = $1; }
|
||||
| tCLASS { $$ = $1; }
|
||||
| tSET { $$ = $1; }
|
||||
| tNEW { $$ = $1; }
|
||||
| tPUBLIC { $$ = $1; }
|
||||
| tPRIVATE { $$ = $1; }
|
||||
| tNEXT { $$ = $1; }
|
||||
| tON { $$ = $1; }
|
||||
| tRESUME { $$ = $1; }
|
||||
| tGOTO { $$ = $1; }
|
||||
StSep_opt
|
||||
: /* empty */
|
||||
| StSep
|
||||
|
||||
Nl_opt
|
||||
: /* empty */
|
||||
| tNL Nl_opt
|
||||
|
||||
/* Most statements accept both new line and ':' as separators */
|
||||
StSep
|
||||
@@ -529,8 +538,16 @@ StSep
|
||||
|
||||
%%
|
||||
|
||||
static int parser_error(parser_ctx_t *ctx, const char *str)
|
||||
static int parser_error(unsigned *loc, parser_ctx_t *ctx, const char *str)
|
||||
{
|
||||
if(ctx->error_loc == -1)
|
||||
ctx->error_loc = *loc;
|
||||
if(ctx->hres == S_OK) {
|
||||
FIXME("%s: %s\n", debugstr_w(ctx->code + *loc), debugstr_a(str));
|
||||
ctx->hres = E_FAIL;
|
||||
}else {
|
||||
WARN("%s: %08lx\n", debugstr_w(ctx->code + *loc), ctx->hres);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -539,12 +556,17 @@ static void source_add_statement(parser_ctx_t *ctx, statement_t *stat)
|
||||
if(!stat)
|
||||
return;
|
||||
|
||||
/* concatenate both linked lists */
|
||||
if(ctx->stats) {
|
||||
ctx->stats_tail->next = stat;
|
||||
ctx->stats_tail = stat;
|
||||
}else {
|
||||
ctx->stats = ctx->stats_tail = stat;
|
||||
}
|
||||
/* find new tail */
|
||||
while(ctx->stats_tail->next) {
|
||||
ctx->stats_tail=ctx->stats_tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void source_add_class(parser_ctx_t *ctx, class_decl_t *class_decl)
|
||||
@@ -553,21 +575,14 @@ static void source_add_class(parser_ctx_t *ctx, class_decl_t *class_decl)
|
||||
ctx->class_decls = class_decl;
|
||||
}
|
||||
|
||||
static void parse_complete(parser_ctx_t *ctx, BOOL option_explicit)
|
||||
{
|
||||
ctx->parse_complete = TRUE;
|
||||
ctx->option_explicit = option_explicit;
|
||||
}
|
||||
|
||||
static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr)
|
||||
{
|
||||
retval_statement_t *stat;
|
||||
|
||||
ctx->parse_complete = TRUE;
|
||||
if(!expr)
|
||||
return;
|
||||
|
||||
stat = new_statement(ctx, STAT_RETVAL, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_RETVAL, sizeof(*stat), 0);
|
||||
if(!stat)
|
||||
return;
|
||||
|
||||
@@ -612,6 +627,18 @@ static expression_t *new_string_expression(parser_ctx_t *ctx, const WCHAR *value
|
||||
return &expr->expr;
|
||||
}
|
||||
|
||||
static expression_t *new_date_expression(parser_ctx_t *ctx, DATE value)
|
||||
{
|
||||
date_expression_t *expr;
|
||||
|
||||
expr = new_expression(ctx, EXPR_DATE, sizeof(*expr));
|
||||
if(!expr)
|
||||
return NULL;
|
||||
|
||||
expr->value = value;
|
||||
return &expr->expr;
|
||||
}
|
||||
|
||||
static expression_t *new_long_expression(parser_ctx_t *ctx, expression_type_t type, LONG value)
|
||||
{
|
||||
int_expression_t *expr;
|
||||
@@ -671,10 +698,61 @@ static member_expression_t *new_member_expression(parser_ctx_t *ctx, expression_
|
||||
|
||||
expr->obj_expr = obj_expr;
|
||||
expr->identifier = identifier;
|
||||
expr->args = NULL;
|
||||
return expr;
|
||||
}
|
||||
|
||||
static call_expression_t *new_call_expression(parser_ctx_t *ctx, expression_t *expr, expression_t *arguments)
|
||||
{
|
||||
call_expression_t *call_expr;
|
||||
|
||||
call_expr = new_expression(ctx, EXPR_CALL, sizeof(*call_expr));
|
||||
if(!call_expr)
|
||||
return NULL;
|
||||
|
||||
call_expr->call_expr = expr;
|
||||
call_expr->args = arguments;
|
||||
return call_expr;
|
||||
}
|
||||
|
||||
static call_expression_t *make_call_expression(parser_ctx_t *ctx, expression_t *callee_expr, expression_t *arguments)
|
||||
{
|
||||
call_expression_t *call_expr;
|
||||
|
||||
if(callee_expr->type == EXPR_MEMBER)
|
||||
return new_call_expression(ctx, callee_expr, arguments);
|
||||
if(callee_expr->type != EXPR_CALL) {
|
||||
FIXME("Unhandled for expr type %u\n", callee_expr->type);
|
||||
ctx->hres = E_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
call_expr = (call_expression_t*)callee_expr;
|
||||
if(!call_expr->args) {
|
||||
call_expr->args = arguments;
|
||||
return call_expr;
|
||||
}
|
||||
|
||||
if(call_expr->args->next) {
|
||||
FIXME("Invalid syntax: invalid use of parentheses for arguments\n");
|
||||
ctx->hres = E_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
call_expr->args = new_unary_expression(ctx, EXPR_BRACKETS, call_expr->args);
|
||||
if(!call_expr->args)
|
||||
return NULL;
|
||||
if(!arguments)
|
||||
return call_expr;
|
||||
|
||||
if(arguments->type != EXPR_NOARG) {
|
||||
FIXME("Invalid syntax: missing comma\n");
|
||||
ctx->hres = E_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
call_expr->args->next = arguments->next;
|
||||
return call_expr;
|
||||
}
|
||||
|
||||
static expression_t *new_new_expression(parser_ctx_t *ctx, const WCHAR *identifier)
|
||||
{
|
||||
string_expression_t *expr;
|
||||
@@ -687,55 +765,72 @@ static expression_t *new_new_expression(parser_ctx_t *ctx, const WCHAR *identifi
|
||||
return &expr->expr;
|
||||
}
|
||||
|
||||
static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size)
|
||||
static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size, unsigned loc)
|
||||
{
|
||||
statement_t *stat;
|
||||
|
||||
stat = parser_alloc(ctx, size ? size : sizeof(*stat));
|
||||
if(stat) {
|
||||
stat->type = type;
|
||||
stat->loc = loc;
|
||||
stat->next = NULL;
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
static statement_t *new_call_statement(parser_ctx_t *ctx, BOOL is_strict, member_expression_t *expr)
|
||||
static statement_t *new_call_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr)
|
||||
{
|
||||
call_expression_t *call_expr = NULL;
|
||||
call_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_CALL, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_CALL, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
stat->expr = expr;
|
||||
stat->is_strict = is_strict;
|
||||
switch(expr->type) {
|
||||
case EXPR_MEMBER:
|
||||
call_expr = new_call_expression(ctx, expr, NULL);
|
||||
break;
|
||||
case EXPR_CALL:
|
||||
call_expr = (call_expression_t*)expr;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported expr type %u\n", expr->type);
|
||||
ctx->hres = E_NOTIMPL;
|
||||
}
|
||||
if(!call_expr)
|
||||
return NULL;
|
||||
|
||||
stat->expr = call_expr;
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static statement_t *new_assign_statement(parser_ctx_t *ctx, member_expression_t *left, expression_t *right)
|
||||
static statement_t *new_assign_statement(parser_ctx_t *ctx, unsigned loc, expression_t *left, expression_t *right)
|
||||
{
|
||||
assign_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_ASSIGN, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_ASSIGN, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
stat->member_expr = left;
|
||||
stat->left_expr = left;
|
||||
stat->value_expr = right;
|
||||
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static statement_t *new_set_statement(parser_ctx_t *ctx, member_expression_t *left, expression_t *right)
|
||||
static statement_t *new_set_statement(parser_ctx_t *ctx, unsigned loc, expression_t *left, expression_t *right)
|
||||
{
|
||||
assign_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_SET, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_SET, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
stat->member_expr = left;
|
||||
stat->left_expr = left;
|
||||
stat->value_expr = right;
|
||||
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
@@ -767,11 +862,11 @@ static dim_list_t *new_dim(parser_ctx_t *ctx, unsigned val, dim_list_t *next)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static statement_t *new_dim_statement(parser_ctx_t *ctx, dim_decl_t *decls)
|
||||
static statement_t *new_dim_statement(parser_ctx_t *ctx, unsigned loc, dim_decl_t *decls)
|
||||
{
|
||||
dim_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_DIM, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_DIM, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
@@ -779,7 +874,34 @@ static statement_t *new_dim_statement(parser_ctx_t *ctx, dim_decl_t *decls)
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, expression_t *expr, statement_t *stat)
|
||||
static redim_decl_t *new_redim_decl(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *dims)
|
||||
{
|
||||
redim_decl_t *decl;
|
||||
|
||||
decl = parser_alloc(ctx, sizeof(*decl));
|
||||
if(!decl)
|
||||
return NULL;
|
||||
|
||||
decl->identifier = identifier;
|
||||
decl->dims = dims;
|
||||
decl->next = NULL;
|
||||
return decl;
|
||||
}
|
||||
|
||||
static statement_t *new_redim_statement(parser_ctx_t *ctx, unsigned loc, BOOL preserve, redim_decl_t *decls)
|
||||
{
|
||||
redim_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_REDIM, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
stat->preserve = preserve;
|
||||
stat->redim_decls = decls;
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_t *stat)
|
||||
{
|
||||
elseif_decl_t *decl;
|
||||
|
||||
@@ -789,15 +911,16 @@ static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, expression_t *expr, sta
|
||||
|
||||
decl->expr = expr;
|
||||
decl->stat = stat;
|
||||
decl->loc = loc;
|
||||
decl->next = NULL;
|
||||
return decl;
|
||||
}
|
||||
|
||||
static statement_t *new_while_statement(parser_ctx_t *ctx, statement_type_t type, expression_t *expr, statement_t *body)
|
||||
static statement_t *new_while_statement(parser_ctx_t *ctx, unsigned loc, statement_type_t type, expression_t *expr, statement_t *body)
|
||||
{
|
||||
while_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, type, sizeof(*stat));
|
||||
stat = new_statement(ctx, type, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
@@ -806,12 +929,12 @@ static statement_t *new_while_statement(parser_ctx_t *ctx, statement_type_t type
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static statement_t *new_forto_statement(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *from_expr,
|
||||
static statement_t *new_forto_statement(parser_ctx_t *ctx, unsigned loc, const WCHAR *identifier, expression_t *from_expr,
|
||||
expression_t *to_expr, expression_t *step_expr, statement_t *body)
|
||||
{
|
||||
forto_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_FORTO, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_FORTO, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
@@ -823,12 +946,12 @@ static statement_t *new_forto_statement(parser_ctx_t *ctx, const WCHAR *identifi
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static statement_t *new_foreach_statement(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *group_expr,
|
||||
static statement_t *new_foreach_statement(parser_ctx_t *ctx, unsigned loc, const WCHAR *identifier, expression_t *group_expr,
|
||||
statement_t *body)
|
||||
{
|
||||
foreach_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_FOREACH, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_FOREACH, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
@@ -838,12 +961,12 @@ static statement_t *new_foreach_statement(parser_ctx_t *ctx, const WCHAR *identi
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
|
||||
static statement_t *new_if_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
|
||||
statement_t *else_stat)
|
||||
{
|
||||
if_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_IF, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_IF, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
@@ -854,11 +977,11 @@ static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, stat
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static statement_t *new_select_statement(parser_ctx_t *ctx, expression_t *expr, case_clausule_t *case_clausules)
|
||||
static statement_t *new_select_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr, case_clausule_t *case_clausules)
|
||||
{
|
||||
select_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_SELECT, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_SELECT, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
@@ -867,6 +990,19 @@ static statement_t *new_select_statement(parser_ctx_t *ctx, expression_t *expr,
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static statement_t *new_with_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_t *body)
|
||||
{
|
||||
with_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_WITH, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
stat->expr = expr;
|
||||
stat->body = body;
|
||||
return &stat->stat;
|
||||
}
|
||||
|
||||
static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr, statement_t *stat, case_clausule_t *next)
|
||||
{
|
||||
case_clausule_t *ret;
|
||||
@@ -881,11 +1017,11 @@ static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static statement_t *new_onerror_statement(parser_ctx_t *ctx, BOOL resume_next)
|
||||
static statement_t *new_onerror_statement(parser_ctx_t *ctx, unsigned loc, BOOL resume_next)
|
||||
{
|
||||
onerror_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_ONERROR, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_ONERROR, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
@@ -911,10 +1047,11 @@ static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name,
|
||||
unsigned storage_flags, arg_decl_t *arg_decl, statement_t *body)
|
||||
{
|
||||
function_decl_t *decl;
|
||||
BOOL is_default = FALSE;
|
||||
|
||||
if(storage_flags & STORAGE_IS_DEFAULT) {
|
||||
if(type == FUNC_PROPGET) {
|
||||
type = FUNC_DEFGET;
|
||||
if(type == FUNC_PROPGET || type == FUNC_FUNCTION || type == FUNC_SUB) {
|
||||
is_default = TRUE;
|
||||
}else {
|
||||
FIXME("Invalid default property\n");
|
||||
ctx->hres = E_FAIL;
|
||||
@@ -929,6 +1066,7 @@ static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name,
|
||||
decl->name = name;
|
||||
decl->type = type;
|
||||
decl->is_public = !(storage_flags & STORAGE_IS_PRIVATE);
|
||||
decl->is_default = is_default;
|
||||
decl->args = arg_decl;
|
||||
decl->body = body;
|
||||
decl->next = NULL;
|
||||
@@ -936,11 +1074,11 @@ static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name,
|
||||
return decl;
|
||||
}
|
||||
|
||||
static statement_t *new_function_statement(parser_ctx_t *ctx, function_decl_t *decl)
|
||||
static statement_t *new_function_statement(parser_ctx_t *ctx, unsigned loc, function_decl_t *decl)
|
||||
{
|
||||
function_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_FUNC, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_FUNC, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
@@ -998,7 +1136,7 @@ static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_d
|
||||
static class_decl_t *add_dim_prop(parser_ctx_t *ctx, class_decl_t *class_decl, dim_decl_t *dim_decl, unsigned storage_flags)
|
||||
{
|
||||
if(storage_flags & STORAGE_IS_DEFAULT) {
|
||||
FIXME("variant prop van't be default value\n");
|
||||
FIXME("variant prop can't be default value\n");
|
||||
ctx->hres = E_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1023,11 +1161,11 @@ static const_decl_t *new_const_decl(parser_ctx_t *ctx, const WCHAR *name, expres
|
||||
return decl;
|
||||
}
|
||||
|
||||
static statement_t *new_const_statement(parser_ctx_t *ctx, const_decl_t *decls)
|
||||
static statement_t *new_const_statement(parser_ctx_t *ctx, unsigned loc, const_decl_t *decls)
|
||||
{
|
||||
const_statement_t *stat;
|
||||
|
||||
stat = new_statement(ctx, STAT_CONST, sizeof(*stat));
|
||||
stat = new_statement(ctx, STAT_CONST, sizeof(*stat), loc);
|
||||
if(!stat)
|
||||
return NULL;
|
||||
|
||||
@@ -1039,6 +1177,8 @@ static statement_t *link_statements(statement_t *head, statement_t *tail)
|
||||
{
|
||||
statement_t *iter;
|
||||
|
||||
if (!head) return tail;
|
||||
|
||||
for(iter = head; iter->next; iter = iter->next);
|
||||
iter->next = tail;
|
||||
|
||||
@@ -1057,36 +1197,26 @@ void *parser_alloc(parser_ctx_t *ctx, size_t size)
|
||||
|
||||
HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, DWORD flags)
|
||||
{
|
||||
static const WCHAR html_delimiterW[] = {'<','/','s','c','r','i','p','t','>',0};
|
||||
|
||||
ctx->code = ctx->ptr = code;
|
||||
ctx->end = ctx->code + lstrlenW(ctx->code);
|
||||
|
||||
heap_pool_init(&ctx->heap);
|
||||
|
||||
ctx->parse_complete = FALSE;
|
||||
ctx->hres = S_OK;
|
||||
|
||||
ctx->error_loc = -1;
|
||||
ctx->last_token = tNL;
|
||||
ctx->last_nl = 0;
|
||||
ctx->stats = ctx->stats_tail = NULL;
|
||||
ctx->class_decls = NULL;
|
||||
ctx->option_explicit = FALSE;
|
||||
ctx->is_html = delimiter && !wcsicmp(delimiter, html_delimiterW);
|
||||
ctx->is_html = delimiter && !wcsicmp(delimiter, L"</script>");
|
||||
|
||||
if(flags & SCRIPTTEXT_ISEXPRESSION)
|
||||
ctx->last_token = tEXPRESSION;
|
||||
|
||||
parser_parse(ctx);
|
||||
|
||||
if(FAILED(ctx->hres))
|
||||
return ctx->hres;
|
||||
if(!ctx->parse_complete) {
|
||||
FIXME("parser failed around %s\n", debugstr_w(ctx->code+20 > ctx->ptr ? ctx->code : ctx->ptr-20));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
return ctx->hres;
|
||||
}
|
||||
|
||||
void parser_release(parser_ctx_t *ctx)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "vbscript.h"
|
||||
|
||||
#include <winnls.h>
|
||||
#include <objsafe.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
|
||||
+18
-18
@@ -482,7 +482,7 @@ EmitREBytecode(CompilerState *state, regexp_t *re, size_t treeDepth,
|
||||
if (treeDepth == 0) {
|
||||
emitStateStack = NULL;
|
||||
} else {
|
||||
emitStateStack = heap_alloc(sizeof(EmitStateStackEntry) * treeDepth);
|
||||
emitStateStack = malloc(sizeof(EmitStateStackEntry) * treeDepth);
|
||||
if (!emitStateStack)
|
||||
return NULL;
|
||||
}
|
||||
@@ -788,7 +788,7 @@ EmitREBytecode(CompilerState *state, regexp_t *re, size_t treeDepth,
|
||||
}
|
||||
|
||||
cleanup:
|
||||
heap_free(emitStateStack);
|
||||
free(emitStateStack);
|
||||
return pc;
|
||||
|
||||
jump_too_big:
|
||||
@@ -1667,11 +1667,11 @@ ParseRegExp(CompilerState *state)
|
||||
return (state->result != NULL);
|
||||
}
|
||||
|
||||
operatorStack = heap_alloc(sizeof(REOpData) * operatorStackSize);
|
||||
operatorStack = malloc(sizeof(REOpData) * operatorStackSize);
|
||||
if (!operatorStack)
|
||||
return FALSE;
|
||||
|
||||
operandStack = heap_alloc(sizeof(RENode *) * operandStackSize);
|
||||
operandStack = malloc(sizeof(RENode *) * operandStackSize);
|
||||
if (!operandStack)
|
||||
goto out;
|
||||
|
||||
@@ -1762,7 +1762,7 @@ pushOperand:
|
||||
if (operandSP == operandStackSize) {
|
||||
RENode **tmp;
|
||||
operandStackSize += operandStackSize;
|
||||
tmp = heap_realloc(operandStack, sizeof(RENode *) * operandStackSize);
|
||||
tmp = realloc(operandStack, sizeof(RENode *) * operandStackSize);
|
||||
if (!tmp)
|
||||
goto out;
|
||||
operandStack = tmp;
|
||||
@@ -1895,7 +1895,7 @@ pushOperator:
|
||||
if (operatorSP == operatorStackSize) {
|
||||
REOpData *tmp;
|
||||
operatorStackSize += operatorStackSize;
|
||||
tmp = heap_realloc(operatorStack, sizeof(REOpData) * operatorStackSize);
|
||||
tmp = realloc(operatorStack, sizeof(REOpData) * operatorStackSize);
|
||||
if (!tmp)
|
||||
goto out;
|
||||
operatorStack = tmp;
|
||||
@@ -1907,8 +1907,8 @@ pushOperator:
|
||||
}
|
||||
}
|
||||
out:
|
||||
heap_free(operatorStack);
|
||||
heap_free(operandStack);
|
||||
free(operatorStack);
|
||||
free(operandStack);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1935,7 +1935,7 @@ PushBackTrackState(REGlobalData *gData, REOp op,
|
||||
ptrdiff_t btincr = ((char *)result + sz) -
|
||||
((char *)gData->backTrackStack + btsize);
|
||||
|
||||
TRACE("\tBT_Push: %lu,%lu\n", (ULONG_PTR)parenIndex, (ULONG_PTR)parenCount);
|
||||
TRACE("\tBT_Push: %Iu,%Iu\n", (ULONG_PTR)parenIndex, (ULONG_PTR)parenCount);
|
||||
|
||||
JS_COUNT_OPERATION(gData->cx, JSOW_JUMP * (1 + parenCount));
|
||||
if (btincr > 0) {
|
||||
@@ -2111,7 +2111,7 @@ ProcessCharSet(REGlobalData *gData, RECharSet *charSet)
|
||||
assert(src[-1] == '[' && end[0] == ']');
|
||||
|
||||
byteLength = (charSet->length >> 3) + 1;
|
||||
charSet->u.bits = heap_alloc(byteLength);
|
||||
charSet->u.bits = malloc(byteLength);
|
||||
if (!charSet->u.bits) {
|
||||
JS_ReportOutOfMemory(gData->cx);
|
||||
gData->ok = FALSE;
|
||||
@@ -2684,7 +2684,7 @@ ExecuteREBytecode(REGlobalData *gData, match_state_t *x)
|
||||
|
||||
case REOP_LPAREN:
|
||||
pc = ReadCompactIndex(pc, &parenIndex);
|
||||
TRACE("[ %lu ]\n", (ULONG_PTR)parenIndex);
|
||||
TRACE("[ %Iu ]\n", (ULONG_PTR)parenIndex);
|
||||
assert(parenIndex < gData->regexp->parenCount);
|
||||
if (parenIndex + 1 > parenSoFar)
|
||||
parenSoFar = parenIndex + 1;
|
||||
@@ -3047,7 +3047,7 @@ ExecuteREBytecode(REGlobalData *gData, match_state_t *x)
|
||||
parenSoFar = curState->parenSoFar;
|
||||
}
|
||||
|
||||
TRACE("\tBT_Pop: %ld,%ld\n",
|
||||
TRACE("\tBT_Pop: %Id,%Id\n",
|
||||
(ULONG_PTR)backTrackData->parenIndex,
|
||||
(ULONG_PTR)backTrackData->parenCount);
|
||||
continue;
|
||||
@@ -3184,12 +3184,12 @@ void regexp_destroy(regexp_t *re)
|
||||
UINT i;
|
||||
for (i = 0; i < re->classCount; i++) {
|
||||
if (re->classList[i].converted)
|
||||
heap_free(re->classList[i].u.bits);
|
||||
free(re->classList[i].u.bits);
|
||||
re->classList[i].u.bits = NULL;
|
||||
}
|
||||
heap_free(re->classList);
|
||||
free(re->classList);
|
||||
}
|
||||
heap_free(re);
|
||||
free(re);
|
||||
}
|
||||
|
||||
regexp_t* regexp_new(void *cx, heap_pool_t *pool, const WCHAR *str,
|
||||
@@ -3238,14 +3238,14 @@ regexp_t* regexp_new(void *cx, heap_pool_t *pool, const WCHAR *str,
|
||||
goto out;
|
||||
}
|
||||
resize = offsetof(regexp_t, program) + state.progLength + 1;
|
||||
re = heap_alloc(resize);
|
||||
re = malloc(resize);
|
||||
if (!re)
|
||||
goto out;
|
||||
|
||||
assert(state.classBitmapsMem <= CLASS_BITMAPS_MEM_LIMIT);
|
||||
re->classCount = state.classCount;
|
||||
if (re->classCount) {
|
||||
re->classList = heap_alloc(re->classCount * sizeof(RECharSet));
|
||||
re->classList = malloc(re->classCount * sizeof(RECharSet));
|
||||
if (!re->classList) {
|
||||
regexp_destroy(re);
|
||||
re = NULL;
|
||||
@@ -3272,7 +3272,7 @@ regexp_t* regexp_new(void *cx, heap_pool_t *pool, const WCHAR *str,
|
||||
regexp_t *tmp;
|
||||
assert((size_t)(endPC - re->program) < state.progLength + 1);
|
||||
resize = offsetof(regexp_t, program) + (endPC - re->program);
|
||||
tmp = heap_realloc(re, resize);
|
||||
tmp = realloc(re, resize);
|
||||
if (tmp)
|
||||
re = tmp;
|
||||
}
|
||||
|
||||
@@ -63,11 +63,11 @@ typedef struct regexp_t {
|
||||
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;
|
||||
regexp_t* regexp_new(void*, heap_pool_t*, const WCHAR*, DWORD, WORD, BOOL);
|
||||
void regexp_destroy(regexp_t*);
|
||||
HRESULT regexp_execute(regexp_t*, void*, heap_pool_t*, const WCHAR*,
|
||||
DWORD, match_state_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT regexp_set_flags(regexp_t**, void*, heap_pool_t*, WORD) DECLSPEC_HIDDEN;
|
||||
DWORD, match_state_t*);
|
||||
HRESULT regexp_set_flags(regexp_t**, void*, heap_pool_t*, WORD);
|
||||
|
||||
static inline match_state_t* alloc_match_state(regexp_t *regexp,
|
||||
heap_pool_t *pool, const WCHAR *pos)
|
||||
@@ -75,7 +75,7 @@ static inline match_state_t* alloc_match_state(regexp_t *regexp,
|
||||
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);
|
||||
ret = pool ? heap_pool_alloc(pool, size) : malloc(size);
|
||||
if(!ret)
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ typedef struct {
|
||||
LONG ref;
|
||||
|
||||
SAFEARRAY *sa;
|
||||
BOOL owned;
|
||||
ULONG i, size;
|
||||
} safearray_iter;
|
||||
|
||||
@@ -62,7 +63,7 @@ static ULONG WINAPI safearray_iter_IEnumVARIANT_AddRef(IEnumVARIANT *iface)
|
||||
safearray_iter *This = impl_from_IEnumVARIANT(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -72,12 +73,15 @@ static ULONG WINAPI safearray_iter_IEnumVARIANT_Release(IEnumVARIANT *iface)
|
||||
safearray_iter *This = impl_from_IEnumVARIANT(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", iface, ref);
|
||||
TRACE("(%p) ref=%ld\n", iface, ref);
|
||||
|
||||
if(!ref) {
|
||||
if(This->sa)
|
||||
if(This->sa) {
|
||||
SafeArrayUnlock(This->sa);
|
||||
heap_free(This);
|
||||
if(This->owned)
|
||||
SafeArrayDestroy(This->sa);
|
||||
}
|
||||
free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
@@ -90,7 +94,7 @@ static HRESULT WINAPI safearray_iter_IEnumVARIANT_Next(IEnumVARIANT *iface,
|
||||
HRESULT hres;
|
||||
VARIANT *v;
|
||||
|
||||
TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
|
||||
TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
|
||||
|
||||
if(celt != 1) {
|
||||
FIXME("celt != 1\n");
|
||||
@@ -160,7 +164,7 @@ static ULONG get_safearray_size(SAFEARRAY *sa)
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT create_safearray_iter(SAFEARRAY *sa, IEnumVARIANT **ev)
|
||||
HRESULT create_safearray_iter(SAFEARRAY *sa, BOOL owned, IEnumVARIANT **ev)
|
||||
{
|
||||
safearray_iter *iter;
|
||||
HRESULT hres;
|
||||
@@ -170,14 +174,14 @@ HRESULT create_safearray_iter(SAFEARRAY *sa, IEnumVARIANT **ev)
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
iter = heap_alloc(sizeof(*iter));
|
||||
iter = malloc(sizeof(*iter));
|
||||
if(!iter)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if(sa) {
|
||||
hres = SafeArrayLock(sa);
|
||||
if(FAILED(hres)) {
|
||||
heap_free(iter);
|
||||
free(iter);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
@@ -185,6 +189,7 @@ HRESULT create_safearray_iter(SAFEARRAY *sa, IEnumVARIANT **ev)
|
||||
iter->IEnumVARIANT_iface.lpVtbl = &safearray_iter_EnumVARIANTVtbl;
|
||||
iter->ref = 1;
|
||||
iter->sa = sa;
|
||||
iter->owned = owned;
|
||||
iter->i = 0;
|
||||
iter->size = get_safearray_size(sa);
|
||||
|
||||
|
||||
+941
-193
File diff suppressed because it is too large
Load Diff
+274
-59
@@ -19,6 +19,7 @@
|
||||
#include "vbscript.h"
|
||||
#include "regexp.h"
|
||||
#include "vbsregexp55.h"
|
||||
#include "wchar.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
@@ -51,12 +52,11 @@ static HRESULT init_regexp_typeinfo(regexp_tid_t tid)
|
||||
HRESULT hres;
|
||||
|
||||
if(!typelib) {
|
||||
static const WCHAR vbscript_dll3W[] = {'v','b','s','c','r','i','p','t','.','d','l','l','\\','3',0};
|
||||
ITypeLib *tl;
|
||||
|
||||
hres = LoadTypeLib(vbscript_dll3W, &tl);
|
||||
hres = LoadTypeLib(L"vbscript.dll\\3", &tl);
|
||||
if(FAILED(hres)) {
|
||||
ERR("LoadRegTypeLib failed: %08x\n", hres);
|
||||
ERR("LoadRegTypeLib failed: %08lx\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ static HRESULT init_regexp_typeinfo(regexp_tid_t tid)
|
||||
|
||||
hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
|
||||
if(FAILED(hres)) {
|
||||
ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
|
||||
ERR("GetTypeInfoOfGuid(%s) failed: %08lx\n", debugstr_guid(tid_ids[tid]), hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ static ULONG WINAPI SubMatches_AddRef(ISubMatches *iface)
|
||||
SubMatches *This = impl_from_ISubMatches(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -180,12 +180,12 @@ static ULONG WINAPI SubMatches_Release(ISubMatches *iface)
|
||||
SubMatches *This = impl_from_ISubMatches(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
heap_free(This->match);
|
||||
heap_free(This->result);
|
||||
heap_free(This);
|
||||
free(This->match);
|
||||
free(This->result);
|
||||
free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
@@ -205,7 +205,7 @@ static HRESULT WINAPI SubMatches_GetTypeInfo(ISubMatches *iface,
|
||||
UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
|
||||
{
|
||||
SubMatches *This = impl_from_ISubMatches(iface);
|
||||
FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
|
||||
FIXME("(%p)->(%u %lu %p)\n", This, iTInfo, lcid, ppTInfo);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ static HRESULT WINAPI SubMatches_GetIDsOfNames(ISubMatches *iface,
|
||||
{
|
||||
SubMatches *This = impl_from_ISubMatches(iface);
|
||||
|
||||
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid),
|
||||
TRACE("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid),
|
||||
rgszNames, cNames, lcid, rgDispId);
|
||||
|
||||
return ITypeInfo_GetIDsOfNames(typeinfos[SubMatches_tid], rgszNames, cNames, rgDispId);
|
||||
@@ -226,7 +226,7 @@ static HRESULT WINAPI SubMatches_Invoke(ISubMatches *iface, DISPID dispIdMember,
|
||||
{
|
||||
SubMatches *This = impl_from_ISubMatches(iface);
|
||||
|
||||
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
||||
TRACE("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
||||
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
||||
|
||||
return ITypeInfo_Invoke(typeinfos[SubMatches_tid], iface, dispIdMember, wFlags,
|
||||
@@ -238,7 +238,7 @@ static HRESULT WINAPI SubMatches_get_Item(ISubMatches *iface,
|
||||
{
|
||||
SubMatches *This = impl_from_ISubMatches(iface);
|
||||
|
||||
TRACE("(%p)->(%d %p)\n", This, index, pSubMatch);
|
||||
TRACE("(%p)->(%ld %p)\n", This, index, pSubMatch);
|
||||
|
||||
if(!pSubMatch)
|
||||
return E_POINTER;
|
||||
@@ -307,7 +307,7 @@ static HRESULT create_sub_matches(DWORD pos, match_state_t *result, SubMatches *
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
ret = heap_alloc_zero(sizeof(*ret));
|
||||
ret = calloc(1, sizeof(*ret));
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
@@ -315,9 +315,9 @@ static HRESULT create_sub_matches(DWORD pos, match_state_t *result, SubMatches *
|
||||
|
||||
ret->result = result;
|
||||
if(result) {
|
||||
ret->match = heap_alloc((result->match_len+1) * sizeof(WCHAR));
|
||||
ret->match = malloc((result->match_len+1) * sizeof(WCHAR));
|
||||
if(!ret->match) {
|
||||
heap_free(ret);
|
||||
free(ret);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(ret->match, result->cp-result->match_len, result->match_len*sizeof(WCHAR));
|
||||
@@ -377,7 +377,7 @@ static ULONG WINAPI Match2_AddRef(IMatch2 *iface)
|
||||
Match2 *This = impl_from_IMatch2(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -387,11 +387,11 @@ static ULONG WINAPI Match2_Release(IMatch2 *iface)
|
||||
Match2 *This = impl_from_IMatch2(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
ISubMatches_Release(&This->sub_matches->ISubMatches_iface);
|
||||
heap_free(This);
|
||||
free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
@@ -411,7 +411,7 @@ static HRESULT WINAPI Match2_GetTypeInfo(IMatch2 *iface,
|
||||
UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
|
||||
{
|
||||
Match2 *This = impl_from_IMatch2(iface);
|
||||
FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
|
||||
FIXME("(%p)->(%u %lu %p)\n", This, iTInfo, lcid, ppTInfo);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ static HRESULT WINAPI Match2_GetIDsOfNames(IMatch2 *iface,
|
||||
{
|
||||
Match2 *This = impl_from_IMatch2(iface);
|
||||
|
||||
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid),
|
||||
TRACE("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid),
|
||||
rgszNames, cNames, lcid, rgDispId);
|
||||
|
||||
return ITypeInfo_GetIDsOfNames(typeinfos[Match2_tid], rgszNames, cNames, rgDispId);
|
||||
@@ -432,7 +432,7 @@ static HRESULT WINAPI Match2_Invoke(IMatch2 *iface, DISPID dispIdMember,
|
||||
{
|
||||
Match2 *This = impl_from_IMatch2(iface);
|
||||
|
||||
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
||||
TRACE("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
||||
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
||||
|
||||
return ITypeInfo_Invoke(typeinfos[Match2_tid], iface, dispIdMember, wFlags,
|
||||
@@ -605,14 +605,14 @@ static HRESULT create_match2(DWORD pos, match_state_t **result, IMatch2 **match)
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
ret = heap_alloc_zero(sizeof(*ret));
|
||||
ret = calloc(1, sizeof(*ret));
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ret->index = pos;
|
||||
hres = create_sub_matches(pos, result ? *result : NULL, &ret->sub_matches);
|
||||
if(FAILED(hres)) {
|
||||
heap_free(ret);
|
||||
free(ret);
|
||||
return hres;
|
||||
}
|
||||
if(result)
|
||||
@@ -657,7 +657,7 @@ static ULONG WINAPI MatchCollectionEnum_AddRef(IEnumVARIANT *iface)
|
||||
MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -667,11 +667,11 @@ static ULONG WINAPI MatchCollectionEnum_Release(IEnumVARIANT *iface)
|
||||
MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
IMatchCollection2_Release(This->mc);
|
||||
heap_free(This);
|
||||
free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
@@ -684,7 +684,7 @@ static HRESULT WINAPI MatchCollectionEnum_Next(IEnumVARIANT *iface,
|
||||
DWORD i;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
|
||||
TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
|
||||
|
||||
if(This->pos>=This->count) {
|
||||
if(pCeltFetched)
|
||||
@@ -714,7 +714,7 @@ static HRESULT WINAPI MatchCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt)
|
||||
{
|
||||
MatchCollectionEnum *This = impl_from_IMatchCollectionEnum(iface);
|
||||
|
||||
TRACE("(%p)->(%u)\n", This, celt);
|
||||
TRACE("(%p)->(%lu)\n", This, celt);
|
||||
|
||||
if(This->pos+celt <= This->count)
|
||||
This->pos += celt;
|
||||
@@ -754,7 +754,7 @@ static HRESULT create_enum_variant_mc2(IMatchCollection2 *mc, ULONG pos, IEnumVA
|
||||
{
|
||||
MatchCollectionEnum *ret;
|
||||
|
||||
ret = heap_alloc_zero(sizeof(*ret));
|
||||
ret = calloc(1, sizeof(*ret));
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
@@ -810,7 +810,7 @@ static ULONG WINAPI MatchCollection2_AddRef(IMatchCollection2 *iface)
|
||||
MatchCollection2 *This = impl_from_IMatchCollection2(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -820,16 +820,16 @@ static ULONG WINAPI MatchCollection2_Release(IMatchCollection2 *iface)
|
||||
MatchCollection2 *This = impl_from_IMatchCollection2(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
DWORD i;
|
||||
|
||||
for(i=0; i<This->count; i++)
|
||||
IMatch2_Release(This->matches[i]);
|
||||
heap_free(This->matches);
|
||||
free(This->matches);
|
||||
|
||||
heap_free(This);
|
||||
free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
@@ -849,7 +849,7 @@ static HRESULT WINAPI MatchCollection2_GetTypeInfo(IMatchCollection2 *iface,
|
||||
UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
|
||||
{
|
||||
MatchCollection2 *This = impl_from_IMatchCollection2(iface);
|
||||
FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
|
||||
FIXME("(%p)->(%u %lu %p)\n", This, iTInfo, lcid, ppTInfo);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -858,7 +858,7 @@ static HRESULT WINAPI MatchCollection2_GetIDsOfNames(IMatchCollection2 *iface,
|
||||
{
|
||||
MatchCollection2 *This = impl_from_IMatchCollection2(iface);
|
||||
|
||||
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid),
|
||||
TRACE("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid),
|
||||
rgszNames, cNames, lcid, rgDispId);
|
||||
|
||||
return ITypeInfo_GetIDsOfNames(typeinfos[MatchCollection2_tid], rgszNames, cNames, rgDispId);
|
||||
@@ -870,7 +870,7 @@ static HRESULT WINAPI MatchCollection2_Invoke(IMatchCollection2 *iface, DISPID d
|
||||
{
|
||||
MatchCollection2 *This = impl_from_IMatchCollection2(iface);
|
||||
|
||||
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
||||
TRACE("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
||||
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
||||
|
||||
return ITypeInfo_Invoke(typeinfos[MatchCollection2_tid], iface, dispIdMember, wFlags,
|
||||
@@ -1024,12 +1024,12 @@ static HRESULT add_match(IMatchCollection2 *iface, IMatch2 *add)
|
||||
TRACE("(%p)->(%p)\n", This, add);
|
||||
|
||||
if(!This->size) {
|
||||
This->matches = heap_alloc(8*sizeof(IMatch*));
|
||||
This->matches = malloc(8 * sizeof(*This->matches));
|
||||
if(!This->matches)
|
||||
return E_OUTOFMEMORY;
|
||||
This->size = 8;
|
||||
}else if(This->size == This->count) {
|
||||
IMatch2 **new_matches = heap_realloc(This->matches, 2*This->size*sizeof(IMatch*));
|
||||
IMatch2 **new_matches = realloc(This->matches, 2 * This->size * sizeof(*This->matches));
|
||||
if(!new_matches)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
@@ -1051,7 +1051,7 @@ static HRESULT create_match_collection2(IMatchCollection2 **match_collection)
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
ret = heap_alloc_zero(sizeof(*ret));
|
||||
ret = calloc(1, sizeof(*ret));
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
@@ -1103,7 +1103,7 @@ static ULONG WINAPI RegExp2_AddRef(IRegExp2 *iface)
|
||||
RegExp2 *This = impl_from_IRegExp2(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -1113,14 +1113,14 @@ static ULONG WINAPI RegExp2_Release(IRegExp2 *iface)
|
||||
RegExp2 *This = impl_from_IRegExp2(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
heap_free(This->pattern);
|
||||
free(This->pattern);
|
||||
if(This->regexp)
|
||||
regexp_destroy(This->regexp);
|
||||
heap_pool_free(&This->pool);
|
||||
heap_free(This);
|
||||
free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
@@ -1140,8 +1140,12 @@ static HRESULT WINAPI RegExp2_GetTypeInfo(IRegExp2 *iface,
|
||||
UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
|
||||
{
|
||||
RegExp2 *This = impl_from_IRegExp2(iface);
|
||||
FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p)->(%u %lu %p)\n", This, iTInfo, lcid, ppTInfo);
|
||||
|
||||
*ppTInfo = typeinfos[RegExp2_tid];
|
||||
ITypeInfo_AddRef(*ppTInfo);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RegExp2_GetIDsOfNames(IRegExp2 *iface, REFIID riid,
|
||||
@@ -1149,7 +1153,7 @@ static HRESULT WINAPI RegExp2_GetIDsOfNames(IRegExp2 *iface, REFIID riid,
|
||||
{
|
||||
RegExp2 *This = impl_from_IRegExp2(iface);
|
||||
|
||||
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid),
|
||||
TRACE("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid),
|
||||
rgszNames, cNames, lcid, rgDispId);
|
||||
|
||||
return ITypeInfo_GetIDsOfNames(typeinfos[RegExp2_tid], rgszNames, cNames, rgDispId);
|
||||
@@ -1161,7 +1165,7 @@ static HRESULT WINAPI RegExp2_Invoke(IRegExp2 *iface, DISPID dispIdMember,
|
||||
{
|
||||
RegExp2 *This = impl_from_IRegExp2(iface);
|
||||
|
||||
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
||||
TRACE("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
||||
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
||||
|
||||
return ITypeInfo_Invoke(typeinfos[RegExp2_tid], iface, dispIdMember, wFlags,
|
||||
@@ -1195,7 +1199,7 @@ static HRESULT WINAPI RegExp2_put_Pattern(IRegExp2 *iface, BSTR pattern)
|
||||
|
||||
if(pattern && *pattern) {
|
||||
SIZE_T size = (SysStringLen(pattern)+1) * sizeof(WCHAR);
|
||||
new_pattern = heap_alloc(size);
|
||||
new_pattern = malloc(size);
|
||||
if(!new_pattern)
|
||||
return E_OUTOFMEMORY;
|
||||
memcpy(new_pattern, pattern, size);
|
||||
@@ -1203,7 +1207,7 @@ static HRESULT WINAPI RegExp2_put_Pattern(IRegExp2 *iface, BSTR pattern)
|
||||
new_pattern = NULL;
|
||||
}
|
||||
|
||||
heap_free(This->pattern);
|
||||
free(This->pattern);
|
||||
This->pattern = new_pattern;
|
||||
|
||||
if(This->regexp) {
|
||||
@@ -1316,9 +1320,9 @@ static HRESULT WINAPI RegExp2_Execute(IRegExp2 *iface,
|
||||
break;
|
||||
|
||||
hres = add_match(match_collection, add);
|
||||
IMatch2_Release(add);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
IMatch2_Release(add);
|
||||
|
||||
if(!(This->flags & REG_GLOB))
|
||||
break;
|
||||
@@ -1359,13 +1363,13 @@ static HRESULT WINAPI RegExp2_Execute(IRegExp2 *iface,
|
||||
hres = regexp_execute(This->regexp, NULL, &This->pool,
|
||||
sourceString, SysStringLen(sourceString), result);
|
||||
if(hres != S_OK) {
|
||||
heap_free(result);
|
||||
free(result);
|
||||
break;
|
||||
}
|
||||
pos = result->cp;
|
||||
|
||||
hres = create_match2(result->cp-result->match_len-sourceString, &result, &add);
|
||||
heap_free(result);
|
||||
free(result);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
hres = add_match(match_collection, add);
|
||||
@@ -1432,13 +1436,179 @@ static HRESULT WINAPI RegExp2_Test(IRegExp2 *iface, BSTR sourceString, VARIANT_B
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RegExp2_Replace(IRegExp2 *iface, BSTR sourceString,
|
||||
VARIANT replaceVar, BSTR *pDestString)
|
||||
typedef struct {
|
||||
WCHAR *buf;
|
||||
DWORD size;
|
||||
DWORD len;
|
||||
} strbuf_t;
|
||||
|
||||
static BOOL strbuf_ensure_size(strbuf_t *buf, unsigned len)
|
||||
{
|
||||
WCHAR *new_buf;
|
||||
DWORD new_size;
|
||||
|
||||
if(len <= buf->size)
|
||||
return TRUE;
|
||||
|
||||
new_size = buf->size ? buf->size<<1 : 16;
|
||||
if(new_size < len)
|
||||
new_size = len;
|
||||
if(buf->buf)
|
||||
new_buf = realloc(buf->buf, new_size*sizeof(WCHAR));
|
||||
else
|
||||
new_buf = malloc(new_size*sizeof(WCHAR));
|
||||
if(!new_buf)
|
||||
return FALSE;
|
||||
|
||||
buf->buf = new_buf;
|
||||
buf->size = new_size;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static HRESULT strbuf_append(strbuf_t *buf, const WCHAR *str, DWORD len)
|
||||
{
|
||||
if(!len)
|
||||
return S_OK;
|
||||
|
||||
if(!strbuf_ensure_size(buf, buf->len+len))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
memcpy(buf->buf+buf->len, str, len*sizeof(WCHAR));
|
||||
buf->len += len;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RegExp2_Replace(IRegExp2 *iface, BSTR source, VARIANT replaceVar, BSTR *ret)
|
||||
{
|
||||
RegExp2 *This = impl_from_IRegExp2(iface);
|
||||
FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(sourceString),
|
||||
debugstr_variant(&replaceVar), pDestString);
|
||||
return E_NOTIMPL;
|
||||
const WCHAR *cp, *prev_cp = NULL, *ptr, *prev_ptr;
|
||||
size_t match_len = 0, source_len, replace_len;
|
||||
strbuf_t buf = { NULL, 0, 0 };
|
||||
match_state_t *state = NULL;
|
||||
heap_pool_t *mark;
|
||||
VARIANT strv;
|
||||
BSTR replace;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(source), debugstr_variant(&replaceVar), ret);
|
||||
|
||||
if(This->pattern) {
|
||||
if(!This->regexp) {
|
||||
This->regexp = regexp_new(NULL, &This->pool, This->pattern,
|
||||
lstrlenW(This->pattern), This->flags, FALSE);
|
||||
if(!This->regexp)
|
||||
return E_OUTOFMEMORY;
|
||||
}else {
|
||||
hres = regexp_set_flags(&This->regexp, NULL, &This->pool, This->flags);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
V_VT(&strv) = VT_EMPTY;
|
||||
hres = VariantChangeType(&strv, &replaceVar, 0, VT_BSTR);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
replace = V_BSTR(&strv);
|
||||
replace_len = SysStringLen(replace);
|
||||
source_len = SysStringLen(source);
|
||||
|
||||
mark = heap_pool_mark(&This->pool);
|
||||
cp = source;
|
||||
if(This->regexp && !(state = alloc_match_state(This->regexp, &This->pool, cp)))
|
||||
hres = E_OUTOFMEMORY;
|
||||
|
||||
while(SUCCEEDED(hres)) {
|
||||
if(This->regexp) {
|
||||
prev_cp = cp;
|
||||
hres = regexp_execute(This->regexp, NULL, &This->pool, source, source_len, state);
|
||||
if(hres != S_OK) break;
|
||||
cp = state->cp;
|
||||
match_len = state->match_len;
|
||||
}else if(prev_cp) {
|
||||
if(cp == source + source_len)
|
||||
break;
|
||||
prev_cp = cp++;
|
||||
}else {
|
||||
prev_cp = cp;
|
||||
}
|
||||
|
||||
hres = strbuf_append(&buf, prev_cp, cp - prev_cp - match_len);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
prev_ptr = replace;
|
||||
while((ptr = wmemchr(prev_ptr, '$', replace + replace_len - prev_ptr))) {
|
||||
hres = strbuf_append(&buf, prev_ptr, ptr - prev_ptr);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
switch(ptr[1]) {
|
||||
case '$':
|
||||
hres = strbuf_append(&buf, ptr, 1);
|
||||
prev_ptr = ptr + 2;
|
||||
break;
|
||||
case '&':
|
||||
hres = strbuf_append(&buf, cp - match_len, match_len);
|
||||
prev_ptr = ptr + 2;
|
||||
break;
|
||||
case '`':
|
||||
hres = strbuf_append(&buf, source, cp - source - match_len);
|
||||
prev_ptr = ptr + 2;
|
||||
break;
|
||||
case '\'':
|
||||
hres = strbuf_append(&buf, cp, source + source_len - cp);
|
||||
prev_ptr = ptr + 2;
|
||||
break;
|
||||
default: {
|
||||
DWORD idx;
|
||||
|
||||
if(!is_digit(ptr[1])) {
|
||||
hres = strbuf_append(&buf, ptr, 1);
|
||||
prev_ptr = ptr + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
idx = ptr[1] - '0';
|
||||
if(is_digit(ptr[2]) && idx * 10 + (ptr[2] - '0') <= state->paren_count) {
|
||||
idx = idx * 10 + (ptr[2] - '0');
|
||||
prev_ptr = ptr + 3;
|
||||
}else if(idx && idx <= state->paren_count) {
|
||||
prev_ptr = ptr + 2;
|
||||
}else {
|
||||
hres = strbuf_append(&buf, ptr, 1);
|
||||
prev_ptr = ptr + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(state->parens[idx - 1].index != -1)
|
||||
hres = strbuf_append(&buf, source + state->parens[idx - 1].index,
|
||||
state->parens[idx - 1].length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
}
|
||||
if(SUCCEEDED(hres))
|
||||
hres = strbuf_append(&buf, prev_ptr, replace + replace_len - prev_ptr);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
if(!(This->flags & REG_GLOB))
|
||||
break;
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = strbuf_append(&buf, cp, source + source_len - cp);
|
||||
if(SUCCEEDED(hres) && !(*ret = SysAllocStringLen(buf.buf, buf.len)))
|
||||
hres = E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
heap_pool_clear(mark);
|
||||
free(buf.buf);
|
||||
SysFreeString(replace);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static const IRegExp2Vtbl RegExp2Vtbl = {
|
||||
@@ -1462,6 +1632,51 @@ static const IRegExp2Vtbl RegExp2Vtbl = {
|
||||
RegExp2_Replace
|
||||
};
|
||||
|
||||
BSTR string_replace(BSTR string, BSTR find, BSTR replace, int from, int cnt, int mode)
|
||||
{
|
||||
const WCHAR *ptr, *string_end;
|
||||
strbuf_t buf = { NULL, 0, 0 };
|
||||
size_t replace_len, find_len;
|
||||
BSTR ret = NULL;
|
||||
HRESULT hres = S_OK;
|
||||
int pos;
|
||||
|
||||
string_end = string + SysStringLen(string);
|
||||
ptr = from > SysStringLen(string) ? string_end : string + from;
|
||||
|
||||
find_len = SysStringLen(find);
|
||||
replace_len = SysStringLen(replace);
|
||||
|
||||
while(string_end - ptr >= find_len && cnt && find_len) {
|
||||
pos = FindStringOrdinal(FIND_FROMSTART, ptr, string_end - ptr,
|
||||
find, find_len, mode);
|
||||
|
||||
if(pos == -1)
|
||||
break;
|
||||
else {
|
||||
hres = strbuf_append(&buf, ptr, pos);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
hres = strbuf_append(&buf, replace, replace_len);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
ptr = ptr + pos + find_len;
|
||||
if(cnt != -1)
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = strbuf_append(&buf, ptr, string_end - ptr);
|
||||
if(SUCCEEDED(hres))
|
||||
ret = SysAllocStringLen(buf.buf, buf.len);
|
||||
}
|
||||
|
||||
free(buf.buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline RegExp2 *impl_from_IRegExp(IRegExp *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, RegExp2, IRegExp_iface);
|
||||
@@ -1602,7 +1817,7 @@ HRESULT create_regexp(IDispatch **ret)
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
regexp = heap_alloc_zero(sizeof(*regexp));
|
||||
regexp = calloc(1, sizeof(*regexp));
|
||||
if(!regexp)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
||||
+398
-119
@@ -61,8 +61,19 @@ typedef struct {
|
||||
IActiveScriptError IActiveScriptError_iface;
|
||||
LONG ref;
|
||||
EXCEPINFO ei;
|
||||
DWORD_PTR cookie;
|
||||
unsigned line;
|
||||
unsigned character;
|
||||
} VBScriptError;
|
||||
|
||||
static inline WCHAR *heap_pool_strdup(heap_pool_t *heap, const WCHAR *str)
|
||||
{
|
||||
size_t size = (lstrlenW(str) + 1) * sizeof(WCHAR);
|
||||
WCHAR *ret = heap_pool_alloc(heap, size);
|
||||
if (ret) memcpy(ret, str, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void change_state(VBScript *This, SCRIPTSTATE state)
|
||||
{
|
||||
if(This->state == state)
|
||||
@@ -82,8 +93,105 @@ static inline BOOL is_started(VBScript *This)
|
||||
|
||||
static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res)
|
||||
{
|
||||
ScriptDisp *obj = ctx->script_obj;
|
||||
function_t *func_iter, **new_funcs;
|
||||
dynamic_var_t *var, **new_vars;
|
||||
IServiceProvider *prev_caller;
|
||||
size_t cnt, i;
|
||||
HRESULT hres;
|
||||
|
||||
if(code->named_item) {
|
||||
if(!code->named_item->script_obj) {
|
||||
hres = create_script_disp(ctx, &code->named_item->script_obj);
|
||||
if(FAILED(hres)) return hres;
|
||||
}
|
||||
obj = code->named_item->script_obj;
|
||||
}
|
||||
|
||||
cnt = obj->global_vars_cnt + code->main_code.var_cnt;
|
||||
if (cnt > obj->global_vars_size)
|
||||
{
|
||||
if (obj->global_vars)
|
||||
new_vars = realloc(obj->global_vars, cnt * sizeof(*new_vars));
|
||||
else
|
||||
new_vars = malloc(cnt * sizeof(*new_vars));
|
||||
if (!new_vars)
|
||||
return E_OUTOFMEMORY;
|
||||
obj->global_vars = new_vars;
|
||||
obj->global_vars_size = cnt;
|
||||
}
|
||||
|
||||
cnt = obj->global_funcs_cnt;
|
||||
for (func_iter = code->funcs; func_iter; func_iter = func_iter->next)
|
||||
cnt++;
|
||||
if (cnt > obj->global_funcs_size)
|
||||
{
|
||||
if (obj->global_funcs)
|
||||
new_funcs = realloc(obj->global_funcs, cnt * sizeof(*new_funcs));
|
||||
else
|
||||
new_funcs = malloc(cnt * sizeof(*new_funcs));
|
||||
if (!new_funcs)
|
||||
return E_OUTOFMEMORY;
|
||||
obj->global_funcs = new_funcs;
|
||||
obj->global_funcs_size = cnt;
|
||||
}
|
||||
|
||||
for (i = 0; i < code->main_code.var_cnt; i++)
|
||||
{
|
||||
if (!(var = heap_pool_alloc(&obj->heap, sizeof(*var))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
var->name = heap_pool_strdup(&obj->heap, code->main_code.vars[i].name);
|
||||
if (!var->name)
|
||||
return E_OUTOFMEMORY;
|
||||
V_VT(&var->v) = VT_EMPTY;
|
||||
var->is_const = FALSE;
|
||||
var->array = NULL;
|
||||
|
||||
obj->global_vars[obj->global_vars_cnt + i] = var;
|
||||
}
|
||||
|
||||
obj->global_vars_cnt += code->main_code.var_cnt;
|
||||
|
||||
for (func_iter = code->funcs; func_iter; func_iter = func_iter->next)
|
||||
{
|
||||
for (i = 0; i < obj->global_funcs_cnt; i++)
|
||||
{
|
||||
if (!wcsicmp(obj->global_funcs[i]->name, func_iter->name))
|
||||
{
|
||||
/* global function already exists, replace it */
|
||||
obj->global_funcs[i] = func_iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == obj->global_funcs_cnt)
|
||||
obj->global_funcs[obj->global_funcs_cnt++] = func_iter;
|
||||
}
|
||||
|
||||
if (code->classes)
|
||||
{
|
||||
class_desc_t *class = code->classes;
|
||||
|
||||
while (1)
|
||||
{
|
||||
class->ctx = ctx;
|
||||
if (!class->next)
|
||||
break;
|
||||
class = class->next;
|
||||
}
|
||||
|
||||
class->next = obj->classes;
|
||||
obj->classes = code->classes;
|
||||
code->last_class = class;
|
||||
}
|
||||
|
||||
code->pending_exec = FALSE;
|
||||
return exec_script(ctx, TRUE, &code->main_code, NULL, NULL, res);
|
||||
|
||||
prev_caller = ctx->vbcaller->caller;
|
||||
ctx->vbcaller->caller = SP_CALLER_UNINITIALIZED;
|
||||
hres = exec_script(ctx, TRUE, &code->main_code, NULL, NULL, res);
|
||||
ctx->vbcaller->caller = prev_caller;
|
||||
return hres;
|
||||
}
|
||||
|
||||
static void exec_queued_code(script_ctx_t *ctx)
|
||||
@@ -96,68 +204,104 @@ static void exec_queued_code(script_ctx_t *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
IDispatch *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flags)
|
||||
static HRESULT retrieve_named_item_disp(IActiveScriptSite *site, named_item_t *item)
|
||||
{
|
||||
IUnknown *unk;
|
||||
HRESULT hres;
|
||||
|
||||
hres = IActiveScriptSite_GetItemInfo(site, item->name, SCRIPTINFO_IUNKNOWN, &unk, NULL);
|
||||
if(FAILED(hres)) {
|
||||
WARN("GetItemInfo failed: %08lx\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp);
|
||||
IUnknown_Release(unk);
|
||||
if(FAILED(hres)) {
|
||||
WARN("object does not implement IDispatch\n");
|
||||
return hres;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
named_item_t *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flags)
|
||||
{
|
||||
named_item_t *item;
|
||||
HRESULT hres;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) {
|
||||
if((item->flags & flags) == flags && !wcsicmp(item->name, name)) {
|
||||
if(!item->disp) {
|
||||
IUnknown *unk;
|
||||
|
||||
hres = IActiveScriptSite_GetItemInfo(ctx->site, item->name,
|
||||
SCRIPTINFO_IUNKNOWN, &unk, NULL);
|
||||
if(FAILED(hres)) {
|
||||
WARN("GetItemInfo failed: %08x\n", hres);
|
||||
continue;
|
||||
}
|
||||
|
||||
hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp);
|
||||
IUnknown_Release(unk);
|
||||
if(FAILED(hres)) {
|
||||
WARN("object does not implement IDispatch\n");
|
||||
continue;
|
||||
}
|
||||
if(!item->script_obj && !(item->flags & SCRIPTITEM_GLOBALMEMBERS)) {
|
||||
hres = create_script_disp(ctx, &item->script_obj);
|
||||
if(FAILED(hres)) return NULL;
|
||||
}
|
||||
|
||||
return item->disp;
|
||||
if(!item->disp && (flags || !(item->flags & SCRIPTITEM_CODEONLY))) {
|
||||
hres = retrieve_named_item_disp(ctx->site, item);
|
||||
if(FAILED(hres)) continue;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void release_named_item_script_obj(named_item_t *item)
|
||||
{
|
||||
if(!item->script_obj) return;
|
||||
|
||||
item->script_obj->ctx = NULL;
|
||||
IDispatchEx_Release(&item->script_obj->IDispatchEx_iface);
|
||||
item->script_obj = NULL;
|
||||
}
|
||||
|
||||
void release_named_item(named_item_t *item)
|
||||
{
|
||||
if(--item->ref) return;
|
||||
|
||||
free(item->name);
|
||||
free(item);
|
||||
}
|
||||
|
||||
static void release_script(script_ctx_t *ctx)
|
||||
{
|
||||
class_desc_t *class_desc;
|
||||
named_item_t *item, *item_next;
|
||||
vbscode_t *code, *code_next;
|
||||
|
||||
collect_objects(ctx);
|
||||
clear_ei(&ctx->ei);
|
||||
|
||||
release_dynamic_vars(ctx->global_vars);
|
||||
ctx->global_vars = NULL;
|
||||
|
||||
while(!list_empty(&ctx->named_items)) {
|
||||
named_item_t *iter = LIST_ENTRY(list_head(&ctx->named_items), named_item_t, entry);
|
||||
|
||||
list_remove(&iter->entry);
|
||||
if(iter->disp)
|
||||
IDispatch_Release(iter->disp);
|
||||
heap_free(iter->name);
|
||||
heap_free(iter);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(code, code_next, &ctx->code_list, vbscode_t, entry)
|
||||
{
|
||||
if(code->is_persistent)
|
||||
{
|
||||
code->pending_exec = TRUE;
|
||||
if(code->last_class) code->last_class->next = NULL;
|
||||
if(code->named_item) release_named_item_script_obj(code->named_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
list_remove(&code->entry);
|
||||
release_vbscode(code);
|
||||
}
|
||||
}
|
||||
|
||||
while(ctx->procs) {
|
||||
class_desc = ctx->procs;
|
||||
ctx->procs = class_desc->next;
|
||||
|
||||
heap_free(class_desc);
|
||||
}
|
||||
|
||||
if(ctx->host_global) {
|
||||
IDispatch_Release(ctx->host_global);
|
||||
ctx->host_global = NULL;
|
||||
LIST_FOR_EACH_ENTRY_SAFE(item, item_next, &ctx->named_items, named_item_t, entry)
|
||||
{
|
||||
if(item->disp)
|
||||
{
|
||||
IDispatch_Release(item->disp);
|
||||
item->disp = NULL;
|
||||
}
|
||||
release_named_item_script_obj(item);
|
||||
if(!(item->flags & SCRIPTITEM_ISPERSISTENT))
|
||||
{
|
||||
list_remove(&item->entry);
|
||||
release_named_item(item);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->secmgr) {
|
||||
@@ -177,19 +321,25 @@ static void release_script(script_ctx_t *ctx)
|
||||
script_obj->ctx = NULL;
|
||||
IDispatchEx_Release(&script_obj->IDispatchEx_iface);
|
||||
}
|
||||
|
||||
detach_global_objects(ctx);
|
||||
heap_pool_free(&ctx->heap);
|
||||
heap_pool_init(&ctx->heap);
|
||||
}
|
||||
|
||||
static void destroy_script(script_ctx_t *ctx)
|
||||
static void release_code_list(script_ctx_t *ctx)
|
||||
{
|
||||
while(!list_empty(&ctx->code_list))
|
||||
release_vbscode(LIST_ENTRY(list_head(&ctx->code_list), vbscode_t, entry));
|
||||
while(!list_empty(&ctx->code_list)) {
|
||||
vbscode_t *iter = LIST_ENTRY(list_head(&ctx->code_list), vbscode_t, entry);
|
||||
|
||||
release_script(ctx);
|
||||
heap_free(ctx);
|
||||
list_remove(&iter->entry);
|
||||
release_vbscode(iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void release_named_item_list(script_ctx_t *ctx)
|
||||
{
|
||||
while(!list_empty(&ctx->named_items)) {
|
||||
named_item_t *iter = LIST_ENTRY(list_head(&ctx->named_items), named_item_t, entry);
|
||||
list_remove(&iter->entry);
|
||||
release_named_item(iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void decrease_state(VBScript *This, SCRIPTSTATE state)
|
||||
@@ -202,16 +352,19 @@ static void decrease_state(VBScript *This, SCRIPTSTATE state)
|
||||
/* FALLTHROUGH */
|
||||
case SCRIPTSTATE_STARTED:
|
||||
case SCRIPTSTATE_DISCONNECTED:
|
||||
if(This->state == SCRIPTSTATE_DISCONNECTED)
|
||||
change_state(This, SCRIPTSTATE_INITIALIZED);
|
||||
if(state == SCRIPTSTATE_INITIALIZED)
|
||||
break;
|
||||
change_state(This, SCRIPTSTATE_INITIALIZED);
|
||||
/* FALLTHROUGH */
|
||||
case SCRIPTSTATE_INITIALIZED:
|
||||
case SCRIPTSTATE_UNINITIALIZED:
|
||||
change_state(This, state);
|
||||
if(state == SCRIPTSTATE_INITIALIZED)
|
||||
break;
|
||||
release_script(This->ctx);
|
||||
This->thread_id = 0;
|
||||
if(state == SCRIPTSTATE_CLOSED) {
|
||||
release_code_list(This->ctx);
|
||||
release_named_item_list(This->ctx);
|
||||
}
|
||||
break;
|
||||
case SCRIPTSTATE_CLOSED:
|
||||
break;
|
||||
@@ -219,6 +372,97 @@ static void decrease_state(VBScript *This, SCRIPTSTATE state)
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct vbcaller *vbcaller_from_IServiceProvider(IServiceProvider *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct vbcaller, IServiceProvider_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI vbcaller_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
struct vbcaller *This = vbcaller_from_IServiceProvider(iface);
|
||||
|
||||
if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IServiceProvider, riid)) {
|
||||
*ppv = &This->IServiceProvider_iface;
|
||||
}else {
|
||||
WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI vbcaller_AddRef(IServiceProvider *iface)
|
||||
{
|
||||
struct vbcaller *This = vbcaller_from_IServiceProvider(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI vbcaller_Release(IServiceProvider *iface)
|
||||
{
|
||||
struct vbcaller *This = vbcaller_from_IServiceProvider(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
if(!ref)
|
||||
free(This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI vbcaller_QueryService(IServiceProvider *iface, REFGUID guidService,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
struct vbcaller *This = vbcaller_from_IServiceProvider(iface);
|
||||
|
||||
if(IsEqualGUID(guidService, &IID_IActiveScriptSite)) {
|
||||
TRACE("(%p)->(IID_IActiveScriptSite)\n", This);
|
||||
if(This->ctx->site)
|
||||
return IActiveScriptSite_QueryInterface(This->ctx->site, riid, ppv);
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if(IsEqualGUID(guidService, &SID_GetCaller)) {
|
||||
TRACE("(%p)->(SID_GetCaller)\n", This);
|
||||
*ppv = NULL;
|
||||
if(!This->caller)
|
||||
return S_OK;
|
||||
return (This->caller == SP_CALLER_UNINITIALIZED) ? E_NOINTERFACE : IServiceProvider_QueryInterface(This->caller, riid, ppv);
|
||||
}
|
||||
|
||||
FIXME("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
|
||||
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static const IServiceProviderVtbl ServiceProviderVtbl = {
|
||||
vbcaller_QueryInterface,
|
||||
vbcaller_AddRef,
|
||||
vbcaller_Release,
|
||||
vbcaller_QueryService
|
||||
};
|
||||
|
||||
static struct vbcaller *create_vbcaller(void)
|
||||
{
|
||||
struct vbcaller *ret;
|
||||
|
||||
ret = malloc(sizeof(*ret));
|
||||
if(ret) {
|
||||
ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
|
||||
ret->ref = 1;
|
||||
ret->caller = SP_CALLER_UNINITIALIZED;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline VBScriptError *impl_from_IActiveScriptError(IActiveScriptError *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, VBScriptError, IActiveScriptError_iface);
|
||||
@@ -249,7 +493,7 @@ static ULONG WINAPI VBScriptError_AddRef(IActiveScriptError *iface)
|
||||
VBScriptError *This = impl_from_IActiveScriptError(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -259,11 +503,10 @@ static ULONG WINAPI VBScriptError_Release(IActiveScriptError *iface)
|
||||
VBScriptError *This = impl_from_IActiveScriptError(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
heap_free(This);
|
||||
}
|
||||
if(!ref)
|
||||
free(This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -285,14 +528,14 @@ static HRESULT WINAPI VBScriptError_GetSourcePosition(IActiveScriptError *iface,
|
||||
{
|
||||
VBScriptError *This = impl_from_IActiveScriptError(iface);
|
||||
|
||||
FIXME("(%p)->(%p %p %p)\n", This, source_context, line, character);
|
||||
TRACE("(%p)->(%p %p %p)\n", This, source_context, line, character);
|
||||
|
||||
if(source_context)
|
||||
*source_context = 0;
|
||||
*source_context = This->cookie;
|
||||
if(line)
|
||||
*line = 0;
|
||||
*line = This->line;
|
||||
if(character)
|
||||
*character = 0;
|
||||
*character = This->character;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -312,12 +555,13 @@ static const IActiveScriptErrorVtbl VBScriptErrorVtbl = {
|
||||
VBScriptError_GetSourceLineText
|
||||
};
|
||||
|
||||
HRESULT report_script_error(script_ctx_t *ctx)
|
||||
HRESULT report_script_error(script_ctx_t *ctx, const vbscode_t *code, unsigned loc)
|
||||
{
|
||||
VBScriptError *error;
|
||||
const WCHAR *p, *nl;
|
||||
HRESULT hres, result;
|
||||
|
||||
if(!(error = heap_alloc(sizeof(*error))))
|
||||
if(!(error = malloc(sizeof(*error))))
|
||||
return E_OUTOFMEMORY;
|
||||
error->IActiveScriptError_iface.lpVtbl = &VBScriptErrorVtbl;
|
||||
|
||||
@@ -326,6 +570,16 @@ HRESULT report_script_error(script_ctx_t *ctx)
|
||||
memset(&ctx->ei, 0, sizeof(ctx->ei));
|
||||
result = error->ei.scode;
|
||||
|
||||
p = code->source;
|
||||
error->cookie = code->cookie;
|
||||
error->line = code->start_line;
|
||||
for(nl = p = code->source; p < code->source + loc; p++) {
|
||||
if(*p != '\n') continue;
|
||||
error->line++;
|
||||
nl = p + 1;
|
||||
}
|
||||
error->character = code->source + loc - nl;
|
||||
|
||||
hres = IActiveScriptSite_OnScriptError(ctx->site, &error->IActiveScriptError_iface);
|
||||
IActiveScriptError_Release(&error->IActiveScriptError_iface);
|
||||
return hres == S_OK ? SCRIPT_E_REPORTED : result;
|
||||
@@ -359,7 +613,7 @@ static HRESULT WINAPI VBScript_QueryInterface(IActiveScript *iface, REFIID riid,
|
||||
TRACE("(%p)->(IID_IObjectSafety %p)\n", This, ppv);
|
||||
*ppv = &This->IObjectSafety_iface;
|
||||
}else {
|
||||
FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
||||
WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
@@ -373,7 +627,7 @@ static ULONG WINAPI VBScript_AddRef(IActiveScript *iface)
|
||||
VBScript *This = impl_from_IActiveScript(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -383,12 +637,14 @@ static ULONG WINAPI VBScript_Release(IActiveScript *iface)
|
||||
VBScript *This = impl_from_IActiveScript(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", iface, ref);
|
||||
TRACE("(%p) ref=%ld\n", iface, ref);
|
||||
|
||||
if(!ref) {
|
||||
decrease_state(This, SCRIPTSTATE_CLOSED);
|
||||
destroy_script(This->ctx);
|
||||
heap_free(This);
|
||||
detach_global_objects(This->ctx);
|
||||
IServiceProvider_Release(&This->ctx->vbcaller->IServiceProvider_iface);
|
||||
free(This->ctx);
|
||||
free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
@@ -397,7 +653,8 @@ static ULONG WINAPI VBScript_Release(IActiveScript *iface)
|
||||
static HRESULT WINAPI VBScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScript(iface);
|
||||
LCID lcid;
|
||||
LCID lcid = LOCALE_USER_DEFAULT;
|
||||
named_item_t *item;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, pass);
|
||||
@@ -411,6 +668,19 @@ static HRESULT WINAPI VBScript_SetScriptSite(IActiveScript *iface, IActiveScript
|
||||
if(InterlockedCompareExchange(&This->thread_id, GetCurrentThreadId(), 0))
|
||||
return E_UNEXPECTED;
|
||||
|
||||
/* Retrieve new dispatches for persistent named items */
|
||||
LIST_FOR_EACH_ENTRY(item, &This->ctx->named_items, named_item_t, entry)
|
||||
{
|
||||
if(!item->disp)
|
||||
{
|
||||
hres = retrieve_named_item_disp(pass, item);
|
||||
if(FAILED(hres)) return hres;
|
||||
}
|
||||
|
||||
/* For some reason, CODEONLY flag is lost in re-initialized scripts */
|
||||
item->flags &= ~SCRIPTITEM_CODEONLY;
|
||||
}
|
||||
|
||||
hres = create_script_disp(This->ctx, &This->ctx->script_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
@@ -418,9 +688,12 @@ static HRESULT WINAPI VBScript_SetScriptSite(IActiveScript *iface, IActiveScript
|
||||
This->ctx->site = pass;
|
||||
IActiveScriptSite_AddRef(This->ctx->site);
|
||||
|
||||
hres = IActiveScriptSite_GetLCID(This->ctx->site, &lcid);
|
||||
if(hres == S_OK)
|
||||
This->ctx->lcid = lcid;
|
||||
IActiveScriptSite_GetLCID(This->ctx->site, &lcid);
|
||||
This->ctx->lcid = IsValidLocale(lcid, 0) ? lcid : GetUserDefaultLCID();
|
||||
GetLocaleInfoW(lcid, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, (WCHAR *)&This->ctx->codepage,
|
||||
sizeof(This->ctx->codepage)/sizeof(WCHAR));
|
||||
if (!This->ctx->codepage)
|
||||
This->ctx->codepage = CP_UTF8;
|
||||
|
||||
if(This->is_initialized)
|
||||
change_state(This, SCRIPTSTATE_INITIALIZED);
|
||||
@@ -452,7 +725,7 @@ static HRESULT WINAPI VBScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if(!This->is_initialized)
|
||||
if(!This->is_initialized || (!This->ctx->site && ss != SCRIPTSTATE_CLOSED))
|
||||
return E_UNEXPECTED;
|
||||
|
||||
switch(ss) {
|
||||
@@ -464,7 +737,10 @@ static HRESULT WINAPI VBScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE
|
||||
exec_queued_code(This->ctx);
|
||||
break;
|
||||
case SCRIPTSTATE_INITIALIZED:
|
||||
FIXME("unimplemented SCRIPTSTATE_INITIALIZED\n");
|
||||
decrease_state(This, SCRIPTSTATE_INITIALIZED);
|
||||
return S_OK;
|
||||
case SCRIPTSTATE_CLOSED:
|
||||
decrease_state(This, SCRIPTSTATE_CLOSED);
|
||||
return S_OK;
|
||||
case SCRIPTSTATE_DISCONNECTED:
|
||||
FIXME("unimplemented SCRIPTSTATE_DISCONNECTED\n");
|
||||
@@ -514,7 +790,7 @@ static HRESULT WINAPI VBScript_AddNamedItem(IActiveScript *iface, LPCOLESTR pstr
|
||||
IDispatch *disp = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
|
||||
TRACE("(%p)->(%s %lx)\n", This, debugstr_w(pstrName), dwFlags);
|
||||
|
||||
if(This->thread_id != GetCurrentThreadId() || !This->ctx->site)
|
||||
return E_UNEXPECTED;
|
||||
@@ -524,7 +800,7 @@ static HRESULT WINAPI VBScript_AddNamedItem(IActiveScript *iface, LPCOLESTR pstr
|
||||
|
||||
hres = IActiveScriptSite_GetItemInfo(This->ctx->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL);
|
||||
if(FAILED(hres)) {
|
||||
WARN("GetItemInfo failed: %08x\n", hres);
|
||||
WARN("GetItemInfo failed: %08lx\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
@@ -534,27 +810,24 @@ static HRESULT WINAPI VBScript_AddNamedItem(IActiveScript *iface, LPCOLESTR pstr
|
||||
WARN("object does not implement IDispatch\n");
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(This->ctx->host_global)
|
||||
IDispatch_Release(This->ctx->host_global);
|
||||
IDispatch_AddRef(disp);
|
||||
This->ctx->host_global = disp;
|
||||
}
|
||||
|
||||
item = heap_alloc(sizeof(*item));
|
||||
item = malloc(sizeof(*item));
|
||||
if(!item) {
|
||||
if(disp)
|
||||
IDispatch_Release(disp);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
item->ref = 1;
|
||||
item->disp = disp;
|
||||
item->flags = dwFlags;
|
||||
item->name = heap_strdupW(pstrName);
|
||||
item->script_obj = NULL;
|
||||
item->name = wcsdup(pstrName);
|
||||
if(!item->name) {
|
||||
if(disp)
|
||||
IDispatch_Release(disp);
|
||||
heap_free(item);
|
||||
free(item);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
@@ -566,15 +839,16 @@ static HRESULT WINAPI VBScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTyp
|
||||
DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScript(iface);
|
||||
FIXME("(%p)->()\n", This);
|
||||
FIXME("(%p)->(%s %ld %ld %ld)\n", This, debugstr_guid(rguidTypeLib), dwMajor, dwMinor, dwFlags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI VBScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName, IDispatch **ppdisp)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScript(iface);
|
||||
ScriptDisp *script_obj;
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, ppdisp);
|
||||
TRACE("(%p)->(%s %p)\n", This, debugstr_w(pstrItemName), ppdisp);
|
||||
|
||||
if(!ppdisp)
|
||||
return E_POINTER;
|
||||
@@ -584,7 +858,14 @@ static HRESULT WINAPI VBScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
*ppdisp = (IDispatch*)&This->ctx->script_obj->IDispatchEx_iface;
|
||||
script_obj = This->ctx->script_obj;
|
||||
if(pstrItemName) {
|
||||
named_item_t *item = lookup_named_item(This->ctx, pstrItemName, 0);
|
||||
if(!item) return E_INVALIDARG;
|
||||
if(item->script_obj) script_obj = item->script_obj;
|
||||
}
|
||||
|
||||
*ppdisp = (IDispatch*)&script_obj->IDispatchEx_iface;
|
||||
IDispatch_AddRef(*ppdisp);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -674,7 +955,7 @@ static HRESULT WINAPI VBScriptDebug_GetScriptTextAttributes(IActiveScriptDebug *
|
||||
LPCOLESTR code, ULONG len, LPCOLESTR delimiter, DWORD flags, SOURCE_TEXT_ATTR *attr)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScriptDebug(iface);
|
||||
FIXME("(%p)->(%s %u %s %#x %p)\n", This, debugstr_w(code), len,
|
||||
FIXME("(%p)->(%s %lu %s %#lx %p)\n", This, debugstr_w(code), len,
|
||||
debugstr_w(delimiter), flags, attr);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -683,7 +964,7 @@ static HRESULT WINAPI VBScriptDebug_GetScriptletTextAttributes(IActiveScriptDebu
|
||||
LPCOLESTR code, ULONG len, LPCOLESTR delimiter, DWORD flags, SOURCE_TEXT_ATTR *attr)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScriptDebug(iface);
|
||||
FIXME("(%p)->(%s %u %s %#x %p)\n", This, debugstr_w(code), len,
|
||||
FIXME("(%p)->(%s %lu %s %#lx %p)\n", This, debugstr_w(code), len,
|
||||
debugstr_w(delimiter), flags, attr);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -692,7 +973,7 @@ static HRESULT WINAPI VBScriptDebug_EnumCodeContextsOfPosition(IActiveScriptDebu
|
||||
CTXARG_T source, ULONG offset, ULONG len, IEnumDebugCodeContexts **ret)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScriptDebug(iface);
|
||||
FIXME("(%p)->(%s %u %u %p)\n", This, wine_dbgstr_longlong(source), offset, len, ret);
|
||||
FIXME("(%p)->(%s %lu %lu %p)\n", This, wine_dbgstr_longlong(source), offset, len, ret);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -750,7 +1031,7 @@ static HRESULT WINAPI VBScriptParse_AddScriptlet(IActiveScriptParse *iface,
|
||||
BSTR *pbstrName, EXCEPINFO *pexcepinfo)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScriptParse(iface);
|
||||
FIXME("(%p)->(%s %s %s %s %s %s %s %u %x %p %p)\n", This, debugstr_w(pstrDefaultName),
|
||||
FIXME("(%p)->(%s %s %s %s %s %s %s %lu %lx %p %p)\n", This, debugstr_w(pstrDefaultName),
|
||||
debugstr_w(pstrCode), debugstr_w(pstrItemName), debugstr_w(pstrSubItemName),
|
||||
debugstr_w(pstrEventName), debugstr_w(pstrDelimiter), wine_dbgstr_longlong(dwSourceContextCookie),
|
||||
ulStartingLineNumber, dwFlags, pbstrName, pexcepinfo);
|
||||
@@ -763,32 +1044,21 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface,
|
||||
DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
|
||||
{
|
||||
VBScript *This = impl_from_IActiveScriptParse(iface);
|
||||
IDispatch *context = NULL;
|
||||
vbscode_t *code;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %s %p %s %s %u %x %p %p)\n", This, debugstr_w(pstrCode),
|
||||
TRACE("(%p)->(%s %s %p %s %s %lu %lx %p %p)\n", This, debugstr_w(pstrCode),
|
||||
debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
|
||||
wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLine, dwFlags, pvarResult, pexcepinfo);
|
||||
|
||||
if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if(pstrItemName) {
|
||||
context = lookup_named_item(This->ctx, pstrItemName, 0);
|
||||
if(!context) {
|
||||
WARN("Inknown context %s\n", debugstr_w(pstrItemName));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
hres = compile_script(This->ctx, pstrCode, pstrDelimiter, dwFlags, &code);
|
||||
hres = compile_script(This->ctx, pstrCode, pstrItemName, pstrDelimiter, dwSourceContextCookie,
|
||||
ulStartingLine, dwFlags, &code);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(context)
|
||||
IDispatch_AddRef(code->context = context);
|
||||
|
||||
if(!(dwFlags & SCRIPTTEXT_ISEXPRESSION) && !is_started(This)) {
|
||||
code->pending_exec = TRUE;
|
||||
return S_OK;
|
||||
@@ -839,14 +1109,15 @@ static HRESULT WINAPI VBScriptParseProcedure_ParseProcedureText(IActiveScriptPar
|
||||
vbdisp_t *vbdisp;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %s %s %s %p %s %s %u %x %p)\n", This, debugstr_w(pstrCode), debugstr_w(pstrFormalParams),
|
||||
TRACE("(%p)->(%s %s %s %s %p %s %s %lu %lx %p)\n", This, debugstr_w(pstrCode), debugstr_w(pstrFormalParams),
|
||||
debugstr_w(pstrProcedureName), debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
|
||||
wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLineNumber, dwFlags, ppdisp);
|
||||
|
||||
if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hres = compile_procedure(This->ctx, pstrCode, pstrDelimiter, dwFlags, &desc);
|
||||
hres = compile_procedure(This->ctx, pstrCode, pstrItemName, pstrDelimiter, dwSourceContextCookie,
|
||||
ulStartingLineNumber, dwFlags, &desc);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
@@ -910,7 +1181,7 @@ static HRESULT WINAPI VBScriptSafety_SetInterfaceSafetyOptions(IObjectSafety *if
|
||||
{
|
||||
VBScript *This = impl_from_IObjectSafety(iface);
|
||||
|
||||
TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
|
||||
TRACE("(%p)->(%s %lx %lx)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
|
||||
|
||||
if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
|
||||
return E_FAIL;
|
||||
@@ -929,16 +1200,22 @@ static const IObjectSafetyVtbl VBScriptSafetyVtbl = {
|
||||
|
||||
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, REFIID riid, void **ppv)
|
||||
{
|
||||
struct vbcaller *vbcaller;
|
||||
script_ctx_t *ctx;
|
||||
VBScript *ret;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppv);
|
||||
|
||||
ret = heap_alloc_zero(sizeof(*ret));
|
||||
ret = calloc(1, sizeof(*ret));
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if(!(vbcaller = create_vbcaller())) {
|
||||
free(ret);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
ret->IActiveScript_iface.lpVtbl = &VBScriptVtbl;
|
||||
ret->IActiveScriptDebug_iface.lpVtbl = &VBScriptDebugVtbl;
|
||||
ret->IActiveScriptParse_iface.lpVtbl = &VBScriptParseVtbl;
|
||||
@@ -948,14 +1225,16 @@ HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pU
|
||||
ret->ref = 1;
|
||||
ret->state = SCRIPTSTATE_UNINITIALIZED;
|
||||
|
||||
ctx = ret->ctx = heap_alloc_zero(sizeof(*ctx));
|
||||
ctx = ret->ctx = calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
heap_free(ret);
|
||||
IServiceProvider_Release(&vbcaller->IServiceProvider_iface);
|
||||
free(ret);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
vbcaller->ctx = ctx;
|
||||
ctx->vbcaller = vbcaller;
|
||||
ctx->safeopt = INTERFACE_USES_DISPEX;
|
||||
heap_pool_init(&ctx->heap);
|
||||
list_init(&ctx->objects);
|
||||
list_init(&ctx->code_list);
|
||||
list_init(&ctx->named_items);
|
||||
@@ -1009,7 +1288,7 @@ static ULONG WINAPI AXSite_AddRef(IServiceProvider *iface)
|
||||
AXSite *This = impl_from_IServiceProvider(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -1019,10 +1298,10 @@ static ULONG WINAPI AXSite_Release(IServiceProvider *iface)
|
||||
AXSite *This = impl_from_IServiceProvider(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
if(!ref)
|
||||
heap_free(This);
|
||||
free(This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -1052,11 +1331,11 @@ IUnknown *create_ax_site(script_ctx_t *ctx)
|
||||
|
||||
hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
|
||||
if(FAILED(hres)) {
|
||||
ERR("Could not get IServiceProvider iface: %08x\n", hres);
|
||||
ERR("Could not get IServiceProvider iface: %08lx\n", hres);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = heap_alloc(sizeof(*ret));
|
||||
ret = malloc(sizeof(*ret));
|
||||
if(!ret) {
|
||||
IServiceProvider_Release(sp);
|
||||
return NULL;
|
||||
|
||||
+116
-87
@@ -30,13 +30,9 @@
|
||||
#include "activscp.h"
|
||||
#include "activdbg.h"
|
||||
|
||||
#ifdef __REACTOS__
|
||||
#include <initguid.h>
|
||||
#endif
|
||||
#include "vbscript_classes.h"
|
||||
#include "vbscript_defs.h"
|
||||
|
||||
#include "wine/heap.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
typedef struct {
|
||||
@@ -48,26 +44,18 @@ typedef struct {
|
||||
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;
|
||||
void heap_pool_init(heap_pool_t*);
|
||||
void *heap_pool_alloc(heap_pool_t*,size_t) __WINE_ALLOC_SIZE(2);
|
||||
void *heap_pool_grow(heap_pool_t*,void*,DWORD,DWORD);
|
||||
void heap_pool_clear(heap_pool_t*);
|
||||
void heap_pool_free(heap_pool_t*);
|
||||
heap_pool_t *heap_pool_mark(heap_pool_t*);
|
||||
|
||||
typedef struct _function_t function_t;
|
||||
typedef struct _vbscode_t vbscode_t;
|
||||
typedef struct _script_ctx_t script_ctx_t;
|
||||
typedef struct _vbdisp_t vbdisp_t;
|
||||
|
||||
typedef struct named_item_t {
|
||||
IDispatch *disp;
|
||||
DWORD flags;
|
||||
LPWSTR name;
|
||||
|
||||
struct list entry;
|
||||
} named_item_t;
|
||||
|
||||
typedef enum {
|
||||
VBDISP_CALLGET,
|
||||
VBDISP_LET,
|
||||
@@ -125,17 +113,32 @@ struct _vbdisp_t {
|
||||
VARIANT props[1];
|
||||
};
|
||||
|
||||
typedef struct _ident_map_t ident_map_t;
|
||||
typedef struct _dynamic_var_t {
|
||||
struct _dynamic_var_t *next;
|
||||
VARIANT v;
|
||||
const WCHAR *name;
|
||||
BOOL is_const;
|
||||
SAFEARRAY *array;
|
||||
} dynamic_var_t;
|
||||
|
||||
typedef struct {
|
||||
IDispatchEx IDispatchEx_iface;
|
||||
LONG ref;
|
||||
|
||||
ident_map_t *ident_map;
|
||||
unsigned ident_map_cnt;
|
||||
unsigned ident_map_size;
|
||||
dynamic_var_t **global_vars;
|
||||
size_t global_vars_cnt;
|
||||
size_t global_vars_size;
|
||||
|
||||
function_t **global_funcs;
|
||||
size_t global_funcs_cnt;
|
||||
size_t global_funcs_size;
|
||||
|
||||
class_desc_t *classes;
|
||||
|
||||
script_ctx_t *ctx;
|
||||
heap_pool_t heap;
|
||||
|
||||
unsigned int rnd;
|
||||
} ScriptDisp;
|
||||
|
||||
typedef struct _builtin_prop_t builtin_prop_t;
|
||||
@@ -148,16 +151,26 @@ typedef struct {
|
||||
script_ctx_t *ctx;
|
||||
} BuiltinDisp;
|
||||
|
||||
HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
|
||||
HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
|
||||
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
|
||||
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,WORD,DISPPARAMS*) DECLSPEC_HIDDEN;
|
||||
HRESULT get_disp_value(script_ctx_t*,IDispatch*,VARIANT*) DECLSPEC_HIDDEN;
|
||||
void collect_objects(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT create_script_disp(script_ctx_t*,ScriptDisp**) DECLSPEC_HIDDEN;
|
||||
typedef struct named_item_t {
|
||||
ScriptDisp *script_obj;
|
||||
IDispatch *disp;
|
||||
unsigned ref;
|
||||
DWORD flags;
|
||||
LPWSTR name;
|
||||
|
||||
HRESULT to_int(VARIANT*,int*) DECLSPEC_HIDDEN;
|
||||
struct list entry;
|
||||
} named_item_t;
|
||||
|
||||
HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**);
|
||||
HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*);
|
||||
HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*);
|
||||
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*);
|
||||
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,WORD,DISPPARAMS*);
|
||||
HRESULT get_disp_value(script_ctx_t*,IDispatch*,VARIANT*);
|
||||
void collect_objects(script_ctx_t*);
|
||||
HRESULT create_script_disp(script_ctx_t*,ScriptDisp**);
|
||||
|
||||
HRESULT to_int(VARIANT*,int*);
|
||||
|
||||
static inline unsigned arg_cnt(const DISPPARAMS *dp)
|
||||
{
|
||||
@@ -169,45 +182,44 @@ static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
|
||||
return dp->rgvarg + dp->cArgs-i-1;
|
||||
}
|
||||
|
||||
typedef struct _dynamic_var_t {
|
||||
struct _dynamic_var_t *next;
|
||||
VARIANT v;
|
||||
const WCHAR *name;
|
||||
BOOL is_const;
|
||||
} dynamic_var_t;
|
||||
#define SP_CALLER_UNINITIALIZED ((IServiceProvider*)IntToPtr(-1))
|
||||
|
||||
struct vbcaller {
|
||||
IServiceProvider IServiceProvider_iface;
|
||||
|
||||
LONG ref;
|
||||
|
||||
script_ctx_t *ctx;
|
||||
IServiceProvider *caller;
|
||||
};
|
||||
|
||||
struct _script_ctx_t {
|
||||
IActiveScriptSite *site;
|
||||
LCID lcid;
|
||||
UINT codepage;
|
||||
|
||||
IInternetHostSecurityManager *secmgr;
|
||||
struct vbcaller *vbcaller;
|
||||
DWORD safeopt;
|
||||
|
||||
IDispatch *host_global;
|
||||
|
||||
ScriptDisp *script_obj;
|
||||
|
||||
BuiltinDisp *global_obj;
|
||||
BuiltinDisp *err_obj;
|
||||
|
||||
EXCEPINFO ei;
|
||||
|
||||
dynamic_var_t *global_vars;
|
||||
function_t *global_funcs;
|
||||
class_desc_t *classes;
|
||||
class_desc_t *procs;
|
||||
|
||||
heap_pool_t heap;
|
||||
vbscode_t *error_loc_code;
|
||||
unsigned error_loc_offset;
|
||||
|
||||
struct list objects;
|
||||
struct list code_list;
|
||||
struct list named_items;
|
||||
};
|
||||
|
||||
HRESULT init_global(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT init_err(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT init_global(script_ctx_t*);
|
||||
HRESULT init_err(script_ctx_t*);
|
||||
|
||||
IUnknown *create_ax_site(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||
IUnknown *create_ax_site(script_ctx_t*);
|
||||
|
||||
typedef enum {
|
||||
ARG_NONE = 0,
|
||||
@@ -216,7 +228,8 @@ typedef enum {
|
||||
ARG_INT,
|
||||
ARG_UINT,
|
||||
ARG_ADDR,
|
||||
ARG_DOUBLE
|
||||
ARG_DOUBLE,
|
||||
ARG_DATE
|
||||
} instr_arg_type_t;
|
||||
|
||||
#define OP_LIST \
|
||||
@@ -225,10 +238,12 @@ typedef enum {
|
||||
X(assign_ident, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(assign_member, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(bool, 1, ARG_INT, 0) \
|
||||
X(catch, 1, ARG_ADDR, ARG_UINT) \
|
||||
X(catch, 1, ARG_ADDR, ARG_UINT) \
|
||||
X(case, 0, ARG_ADDR, 0) \
|
||||
X(concat, 1, 0, 0) \
|
||||
X(const, 1, ARG_BSTR, 0) \
|
||||
X(date, 1, ARG_DATE, 0) \
|
||||
X(deref, 1, 0, 0) \
|
||||
X(dim, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(div, 1, 0, 0) \
|
||||
X(double, 1, ARG_DOUBLE, 0) \
|
||||
@@ -243,6 +258,7 @@ typedef enum {
|
||||
X(gteq, 1, 0, 0) \
|
||||
X(icall, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(icallv, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(ident, 1, ARG_BSTR, 0) \
|
||||
X(idiv, 1, 0, 0) \
|
||||
X(imp, 1, 0, 0) \
|
||||
X(incc, 1, ARG_BSTR, 0) \
|
||||
@@ -265,17 +281,23 @@ typedef enum {
|
||||
X(not, 1, 0, 0) \
|
||||
X(nothing, 1, 0, 0) \
|
||||
X(null, 1, 0, 0) \
|
||||
X(numval, 1, 0, 0) \
|
||||
X(or, 1, 0, 0) \
|
||||
X(pop, 1, ARG_UINT, 0) \
|
||||
X(redim, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(redim_preserve, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(ret, 0, 0, 0) \
|
||||
X(retval, 1, 0, 0) \
|
||||
X(set_ident, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(set_member, 1, ARG_BSTR, ARG_UINT) \
|
||||
X(stack, 1, ARG_UINT, 0) \
|
||||
X(step, 0, ARG_ADDR, ARG_BSTR) \
|
||||
X(stop, 1, 0, 0) \
|
||||
X(string, 1, ARG_STR, 0) \
|
||||
X(sub, 1, 0, 0) \
|
||||
X(val, 1, 0, 0) \
|
||||
X(vcall, 1, ARG_UINT, 0) \
|
||||
X(vcallv, 1, ARG_UINT, 0) \
|
||||
X(xor, 1, 0, 0)
|
||||
|
||||
typedef enum {
|
||||
@@ -291,10 +313,12 @@ typedef union {
|
||||
unsigned uint;
|
||||
LONG lng;
|
||||
double *dbl;
|
||||
DATE *date;
|
||||
} instr_arg_t;
|
||||
|
||||
typedef struct {
|
||||
vbsop_t op;
|
||||
unsigned loc;
|
||||
instr_arg_t arg1;
|
||||
instr_arg_t arg2;
|
||||
} instr_t;
|
||||
@@ -311,7 +335,6 @@ typedef enum {
|
||||
FUNC_PROPGET,
|
||||
FUNC_PROPLET,
|
||||
FUNC_PROPSET,
|
||||
FUNC_DEFGET
|
||||
} function_type_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -335,70 +358,76 @@ struct _function_t {
|
||||
|
||||
struct _vbscode_t {
|
||||
instr_t *instrs;
|
||||
unsigned ref;
|
||||
|
||||
WCHAR *source;
|
||||
DWORD_PTR cookie;
|
||||
unsigned start_line;
|
||||
|
||||
BOOL option_explicit;
|
||||
|
||||
BOOL pending_exec;
|
||||
BOOL is_persistent;
|
||||
function_t main_code;
|
||||
IDispatch *context;
|
||||
named_item_t *named_item;
|
||||
|
||||
BSTR *bstr_pool;
|
||||
unsigned bstr_pool_size;
|
||||
unsigned bstr_cnt;
|
||||
heap_pool_t heap;
|
||||
|
||||
function_t *funcs;
|
||||
class_desc_t *classes;
|
||||
class_desc_t *last_class;
|
||||
|
||||
struct list entry;
|
||||
};
|
||||
|
||||
void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,DWORD,vbscode_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT compile_procedure(script_ctx_t*,const WCHAR*,const WCHAR*,DWORD,class_desc_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT exec_script(script_ctx_t*,BOOL,function_t*,vbdisp_t*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
|
||||
void release_dynamic_vars(dynamic_var_t*) DECLSPEC_HIDDEN;
|
||||
IDispatch *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned) DECLSPEC_HIDDEN;
|
||||
void clear_ei(EXCEPINFO*) DECLSPEC_HIDDEN;
|
||||
HRESULT report_script_error(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||
void detach_global_objects(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT get_builtin_id(BuiltinDisp*,const WCHAR*,DISPID*) DECLSPEC_HIDDEN;
|
||||
static inline void grab_vbscode(vbscode_t *code)
|
||||
{
|
||||
code->ref++;
|
||||
}
|
||||
|
||||
void release_regexp_typelib(void) DECLSPEC_HIDDEN;
|
||||
void release_vbscode(vbscode_t*);
|
||||
HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,const WCHAR*,DWORD_PTR,unsigned,DWORD,vbscode_t**);
|
||||
HRESULT compile_procedure(script_ctx_t*,const WCHAR*,const WCHAR*,const WCHAR*,DWORD_PTR,unsigned,DWORD,class_desc_t**);
|
||||
HRESULT exec_script(script_ctx_t*,BOOL,function_t*,vbdisp_t*,DISPPARAMS*,VARIANT*);
|
||||
void release_dynamic_var(dynamic_var_t*);
|
||||
named_item_t *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned);
|
||||
void release_named_item(named_item_t*);
|
||||
void clear_ei(EXCEPINFO*);
|
||||
HRESULT report_script_error(script_ctx_t*,const vbscode_t*,unsigned);
|
||||
void detach_global_objects(script_ctx_t*);
|
||||
HRESULT get_builtin_id(BuiltinDisp*,const WCHAR*,DISPID*);
|
||||
HRESULT array_access(SAFEARRAY *array, DISPPARAMS *dp, VARIANT **ret);
|
||||
|
||||
void release_regexp_typelib(void);
|
||||
HRESULT get_dispatch_typeinfo(ITypeInfo**);
|
||||
|
||||
static inline BOOL is_int32(double d)
|
||||
{
|
||||
return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d;
|
||||
}
|
||||
|
||||
HRESULT create_regexp(IDispatch**) DECLSPEC_HIDDEN;
|
||||
static inline BOOL is_digit(WCHAR c)
|
||||
{
|
||||
return '0' <= c && c <= '9';
|
||||
}
|
||||
|
||||
HRESULT map_hres(HRESULT) DECLSPEC_HIDDEN;
|
||||
HRESULT create_regexp(IDispatch**);
|
||||
BSTR string_replace(BSTR,BSTR,BSTR,int,int,int);
|
||||
|
||||
HRESULT create_safearray_iter(SAFEARRAY *sa, IEnumVARIANT **ev) DECLSPEC_HIDDEN;
|
||||
void map_vbs_exception(EXCEPINFO *);
|
||||
|
||||
HRESULT create_safearray_iter(SAFEARRAY *sa, BOOL owned, IEnumVARIANT **ev);
|
||||
|
||||
#define FACILITY_VBS 0xa
|
||||
#define MAKE_VBSERROR(code) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_VBS, code)
|
||||
|
||||
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
|
||||
HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
|
||||
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
|
||||
HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
|
||||
|
||||
BSTR get_vbscript_string(int) DECLSPEC_HIDDEN;
|
||||
BSTR get_vbscript_error_string(HRESULT) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline LPWSTR heap_strdupW(LPCWSTR str)
|
||||
{
|
||||
LPWSTR ret = NULL;
|
||||
|
||||
if(str) {
|
||||
DWORD size;
|
||||
|
||||
size = (lstrlenW(str)+1)*sizeof(WCHAR);
|
||||
ret = heap_alloc(size);
|
||||
if(ret)
|
||||
memcpy(ret, str, size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
BSTR get_vbscript_string(int);
|
||||
|
||||
#define VBSCRIPT_BUILD_VERSION 16978
|
||||
#define VBSCRIPT_MAJOR_VERSION 5
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <windef.h>
|
||||
#include "vbscript_defs.h"
|
||||
|
||||
#pragma makedep po
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE
|
||||
@@ -54,6 +56,7 @@ STRINGTABLE
|
||||
VBSE_INVALID_DLL_FUNCTION_NAME "Specified DLL function not found"
|
||||
VBSE_INVALID_TYPELIB_VARIABLE "Variable uses an Automation type not supported in VBScript"
|
||||
VBSE_SERVER_NOT_FOUND "The remote server machine does not exist or is unavailable"
|
||||
VBSE_UNQUALIFIED_REFERENCE "Invalid or unqualified reference"
|
||||
|
||||
VBS_COMPILE_ERROR "Microsoft VBScript compilation error"
|
||||
VBS_RUNTIME_ERROR "Microsoft VBScript runtime error"
|
||||
@@ -65,15 +68,6 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
/* @makedep: vbscript.rgs */
|
||||
2 WINE_REGISTRY vbscript.rgs
|
||||
|
||||
3 WINE_REGISTRY "vbsglobal.rgs"
|
||||
4 WINE_REGISTRY "vbsregexp10.rgs"
|
||||
5 WINE_REGISTRY "vbsregexp55.rgs"
|
||||
6 WINE_REGISTRY "vbscript_classes.rgs"
|
||||
|
||||
1 TYPELIB "vbsglobal.tlb"
|
||||
2 TYPELIB "vbsregexp10.tlb"
|
||||
3 TYPELIB "vbsregexp55.tlb"
|
||||
|
||||
#define WINE_FILEDESCRIPTION_STR "Wine VBScript"
|
||||
#define WINE_FILENAME_STR "vbscript.dll"
|
||||
#define WINE_FILEVERSION 5,8,7601,16978
|
||||
|
||||
@@ -63,19 +63,19 @@ HKCR
|
||||
{
|
||||
Edit
|
||||
{
|
||||
Command = s '"%%SystemRoot%%\system32\notepad.exe" %%1'
|
||||
Command = s '"%SystemRoot%\system32\notepad.exe" %%1'
|
||||
}
|
||||
Open
|
||||
{
|
||||
Command = s '"%%SystemRoot%%\system32\wscript.exe" "%%1" %%*'
|
||||
Command = s '"%SystemRoot%\system32\wscript.exe" "%%1" %%*'
|
||||
}
|
||||
Open2
|
||||
{
|
||||
Command = s '"%%SystemRoot%%\system32\cscript.exe" "%%1" %%*'
|
||||
Command = s '"%SystemRoot%\system32\cscript.exe" "%%1" %%*'
|
||||
}
|
||||
Print
|
||||
{
|
||||
Command = s '"%%SystemRoot%%\system32\notepad.exe" /p %%1'
|
||||
Command = s '"%SystemRoot%\system32\notepad.exe" /p %%1'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove Interface
|
||||
{
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
'{3F4DACA4-160D-11D2-A8E9-00104B365C9F}' = s 'VBScript Regular Expression'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
|
||||
ProgId = s 'VBScript.RegExp'
|
||||
Version = s '5.5'
|
||||
}
|
||||
'{B54F3741-5B07-11CF-A4B0-00AA004A55E8}' = s 'VB Script Language'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
|
||||
ProgId = s 'VBScript'
|
||||
}
|
||||
'{B54F3742-5B07-11CF-A4B0-00AA004A55E8}' = s 'VB Script Language Authoring'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
|
||||
ProgId = s 'VBScript Author'
|
||||
}
|
||||
'{B54F3743-5B07-11CF-A4B0-00AA004A55E8}' = s 'VB Script Language Encoding'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
|
||||
ProgId = s 'VBScript.Encode'
|
||||
}
|
||||
}
|
||||
'VBScript.RegExp' = s 'VBScript Regular Expression'
|
||||
{
|
||||
CLSID = s '{3F4DACA4-160D-11D2-A8E9-00104B365C9F}'
|
||||
}
|
||||
'VBScript' = s 'VB Script Language'
|
||||
{
|
||||
CLSID = s '{B54F3741-5B07-11CF-A4B0-00AA004A55E8}'
|
||||
}
|
||||
'VBScript Author' = s 'VB Script Language Authoring'
|
||||
{
|
||||
CLSID = s '{B54F3742-5B07-11CF-A4B0-00AA004A55E8}'
|
||||
}
|
||||
'VBScript.Encode' = s 'VB Script Language Encoding'
|
||||
{
|
||||
CLSID = s '{B54F3743-5B07-11CF-A4B0-00AA004A55E8}'
|
||||
}
|
||||
}
|
||||
@@ -267,6 +267,7 @@
|
||||
#define VBSE_INVALID_DLL_FUNCTION_NAME 453
|
||||
#define VBSE_INVALID_TYPELIB_VARIABLE 458
|
||||
#define VBSE_SERVER_NOT_FOUND 462
|
||||
#define VBSE_UNQUALIFIED_REFERENCE 505
|
||||
|
||||
#define VBS_COMPILE_ERROR 4096
|
||||
#define VBS_RUNTIME_ERROR 4097
|
||||
|
||||
@@ -34,6 +34,7 @@ WINE_DECLARE_DEBUG_CHANNEL(heap);
|
||||
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
|
||||
|
||||
static HINSTANCE vbscript_hinstance;
|
||||
static ITypeInfo *dispatch_typeinfo;
|
||||
|
||||
BSTR get_vbscript_string(int id)
|
||||
{
|
||||
@@ -42,14 +43,6 @@ BSTR get_vbscript_string(int id)
|
||||
return SysAllocString(buf);
|
||||
}
|
||||
|
||||
BSTR get_vbscript_error_string(HRESULT error)
|
||||
{
|
||||
BSTR ret;
|
||||
if(HRESULT_FACILITY(error) != FACILITY_VBS || !(ret = get_vbscript_string(HRESULT_CODE(error))))
|
||||
ret = get_vbscript_string(VBS_UNKNOWN_RUNTIME_ERROR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MIN_BLOCK_SIZE 128
|
||||
#define ARENA_FREE_FILLER 0xaa
|
||||
|
||||
@@ -73,12 +66,12 @@ void *heap_pool_alloc(heap_pool_t *heap, size_t size)
|
||||
|
||||
if(!heap->block_cnt) {
|
||||
if(!heap->blocks) {
|
||||
heap->blocks = heap_alloc(sizeof(void*));
|
||||
heap->blocks = malloc(sizeof(void*));
|
||||
if(!heap->blocks)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp = heap_alloc(block_size(0));
|
||||
tmp = malloc(block_size(0));
|
||||
if(!tmp)
|
||||
return NULL;
|
||||
|
||||
@@ -94,12 +87,12 @@ void *heap_pool_alloc(heap_pool_t *heap, size_t size)
|
||||
|
||||
if(size <= block_size(heap->last_block+1)) {
|
||||
if(heap->last_block+1 == heap->block_cnt) {
|
||||
tmp = heap_realloc(heap->blocks, (heap->block_cnt+1)*sizeof(void*));
|
||||
tmp = realloc(heap->blocks, (heap->block_cnt+1)*sizeof(void*));
|
||||
if(!tmp)
|
||||
return NULL;
|
||||
|
||||
heap->blocks = tmp;
|
||||
heap->blocks[heap->block_cnt] = heap_alloc(block_size(heap->block_cnt));
|
||||
heap->blocks[heap->block_cnt] = malloc(block_size(heap->block_cnt));
|
||||
if(!heap->blocks[heap->block_cnt])
|
||||
return NULL;
|
||||
|
||||
@@ -111,7 +104,7 @@ void *heap_pool_alloc(heap_pool_t *heap, size_t size)
|
||||
return heap->blocks[heap->last_block];
|
||||
}
|
||||
|
||||
list = heap_alloc(size + sizeof(struct list));
|
||||
list = malloc(size + sizeof(struct list));
|
||||
if(!list)
|
||||
return NULL;
|
||||
|
||||
@@ -144,7 +137,7 @@ void heap_pool_clear(heap_pool_t *heap)
|
||||
|
||||
while((tmp = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
|
||||
list_remove(tmp);
|
||||
heap_free(tmp);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
if(WARN_ON(heap)) {
|
||||
@@ -165,8 +158,8 @@ void heap_pool_free(heap_pool_t *heap)
|
||||
heap_pool_clear(heap);
|
||||
|
||||
for(i=0; i < heap->block_cnt; i++)
|
||||
heap_free(heap->blocks[i]);
|
||||
heap_free(heap->blocks);
|
||||
free(heap->blocks[i]);
|
||||
free(heap->blocks);
|
||||
|
||||
heap_pool_init(heap);
|
||||
}
|
||||
@@ -180,6 +173,29 @@ heap_pool_t *heap_pool_mark(heap_pool_t *heap)
|
||||
return heap;
|
||||
}
|
||||
|
||||
HRESULT get_dispatch_typeinfo(ITypeInfo **out)
|
||||
{
|
||||
ITypeInfo *typeinfo;
|
||||
ITypeLib *typelib;
|
||||
HRESULT hr;
|
||||
|
||||
if (!dispatch_typeinfo)
|
||||
{
|
||||
hr = LoadRegTypeLib(&IID_StdOle, STDOLE_MAJORVERNUM, STDOLE_MINORVERNUM, STDOLE_LCID, &typelib);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IDispatch, &typeinfo);
|
||||
ITypeLib_Release(typelib);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
if (InterlockedCompareExchangePointer((void**)&dispatch_typeinfo, typeinfo, NULL))
|
||||
ITypeInfo_Release(typeinfo);
|
||||
}
|
||||
|
||||
*out = dispatch_typeinfo;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
@@ -244,20 +260,17 @@ static IClassFactory VBScriptRegExpFactory = { &VBScriptRegExpFactoryVtbl };
|
||||
*/
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||
{
|
||||
TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpv);
|
||||
TRACE("(%p %ld %p)\n", hInstDLL, fdwReason, lpv);
|
||||
|
||||
switch(fdwReason)
|
||||
{
|
||||
#ifndef __REACTOS__
|
||||
case DLL_WINE_PREATTACH:
|
||||
return FALSE; /* prefer native version */
|
||||
#endif
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hInstDLL);
|
||||
vbscript_hinstance = hInstDLL;
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (lpv) break;
|
||||
if (dispatch_typeinfo) ITypeInfo_Release(dispatch_typeinfo);
|
||||
release_regexp_typelib();
|
||||
}
|
||||
|
||||
@@ -280,29 +293,3 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||
FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllCanUnloadNow (vbscript.@)
|
||||
*/
|
||||
HRESULT WINAPI DllCanUnloadNow(void)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllRegisterServer (vbscript.@)
|
||||
*/
|
||||
HRESULT WINAPI DllRegisterServer(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
return __wine_register_resources(vbscript_hinstance);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllUnregisterServer (vbscript.@)
|
||||
*/
|
||||
HRESULT WINAPI DllUnregisterServer(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
return __wine_unregister_resources(vbscript_hinstance);
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove Typelib
|
||||
{
|
||||
NoRemove '{3EEF9758-35FC-11D1-8CE4-00C04FC2B185}'
|
||||
{
|
||||
'1.0' = s 'Microsoft VBScript Globals'
|
||||
{
|
||||
'0' { win32 = s '%MODULE%' }
|
||||
FLAGS = s '0'
|
||||
}
|
||||
}
|
||||
}
|
||||
NoRemove Interface
|
||||
{
|
||||
'{3EEF9758-35FC-11D1-8CE4-00C04FC2B186}' = s 'GlobalObj'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3EEF9758-35FC-11D1-8CE4-00C04FC2B185}' { val Version = s '1.0' }
|
||||
}
|
||||
'{3EEF9758-35FC-11D1-8CE4-00C04FC2B187}' = s 'ErrObj'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3EEF9758-35FC-11D1-8CE4-00C04FC2B185}' { val Version = s '1.0' }
|
||||
}
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import "oaidl.idl";
|
||||
|
||||
[
|
||||
helpstring("Microsoft VBScript Regular Expressions 1.0"),
|
||||
id(2),
|
||||
uuid(3f4daca7-160d-11d2-a8e9-00104b365c9f),
|
||||
version(1.0)
|
||||
]
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove Typelib
|
||||
{
|
||||
NoRemove '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}'
|
||||
{
|
||||
'1.0' = s 'Microsoft VBScript Regular Expressions 1.0'
|
||||
{
|
||||
'0' { win32 = s '%MODULE%' }
|
||||
FLAGS = s '0'
|
||||
}
|
||||
}
|
||||
}
|
||||
NoRemove Interface
|
||||
{
|
||||
'{3F4DACA0-160D-11D2-A8E9-00104B365C9F}' = s 'IRegExp'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '1.0' }
|
||||
}
|
||||
'{3F4DACA1-160D-11D2-A8E9-00104B365C9F}' = s 'IMatch'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '1.0' }
|
||||
}
|
||||
'{3F4DACA2-160D-11D2-A8E9-00104B365C9F}' = s 'IMatchCollection'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '1.0' }
|
||||
}
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import "oaidl.idl";
|
||||
|
||||
[
|
||||
helpstring("Microsoft VBScript Regular Expressions 5.5"),
|
||||
id(3),
|
||||
uuid(3f4daca7-160d-11d2-a8e9-00104b365c9f),
|
||||
version(5.5)
|
||||
]
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove Typelib
|
||||
{
|
||||
NoRemove '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}'
|
||||
{
|
||||
'5.5' = s 'Microsoft VBScript Regular Expressions 5.5'
|
||||
{
|
||||
'0' { win32 = s '%MODULE%' }
|
||||
FLAGS = s '0'
|
||||
}
|
||||
}
|
||||
}
|
||||
NoRemove Interface
|
||||
{
|
||||
'{3F4DACA0-160D-11D2-A8E9-00104B365C9F}' = s 'IRegExp'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
|
||||
}
|
||||
'{3F4DACB0-160D-11D2-A8E9-00104B365C9F}' = s 'IRegExp2'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
|
||||
}
|
||||
'{3F4DACA1-160D-11D2-A8E9-00104B365C9F}' = s 'IMatch'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
|
||||
}
|
||||
'{3F4DACB1-160D-11D2-A8E9-00104B365C9F}' = s 'IMatch2'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
|
||||
}
|
||||
'{3F4DACA2-160D-11D2-A8E9-00104B365C9F}' = s 'IMatchCollection'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
|
||||
}
|
||||
'{3F4DACB2-160D-11D2-A8E9-00104B365C9F}' = s 'IMatchCollection2'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
|
||||
}
|
||||
'{3F4DACB3-160D-11D2-A8E9-00104B365C9F}' = s 'ISubMatches'
|
||||
{
|
||||
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
|
||||
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
|
||||
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
|
||||
}
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -207,7 +207,7 @@ dll/win32/url # Synced to WineStaging-3.3
|
||||
dll/win32/urlmon # Synced to WineStaging-4.18
|
||||
dll/win32/usp10 # Synced to WineStaging-4.18
|
||||
dll/win32/uxtheme # Forked
|
||||
dll/win32/vbscript # Synced to WineStaging-4.18
|
||||
dll/win32/vbscript # Synced to Wine-10.0
|
||||
dll/win32/version # Synced to WineStaging-4.18
|
||||
dll/win32/vssapi # Synced to WineStaging-4.18
|
||||
dll/win32/wbemdisp # Synced to WineStaging-4.18
|
||||
|
||||
Reference in New Issue
Block a user