Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46318 Signed-off-by: Brendan McGrath brendan@redmandi.com --- The added keywords are based on the documentation found at: https://rosettacode.org/wiki/BNF_Grammar#VBScript
There appears to be special code for the 'rem' keyword, so I couldn't get that to work (there's a TODO test in the next patch if it's wanted).
That page also listed the following keywords (which we don't have): - Erase - Preserve - Redim - With
But did not mention these (which we do have): - Stop - Me
I'm not sure how accurate that site is so I've added a test for every keyword I added to make sure they work on Windows.
dlls/vbscript/parser.y | 86 +++++++++++++++++---- dlls/vbscript/tests/lang.vbs | 55 +++++++++++++ dlls/vbscript/tests/run.c | 144 ++++++++++++++++++++++++++++++++--- 3 files changed, 258 insertions(+), 27 deletions(-)
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index b81d7919662..52c98fca596 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -102,20 +102,21 @@ static statement_t *link_statements(statement_t*,statement_t*); double dbl; }
-%token tEOF tNL tREM tEMPTYBRACKETS -%token tTRUE tFALSE -%token tNOT tAND tOR tXOR tEQV tIMP tNEQ -%token tIS tLTEQ tGTEQ tMOD -%token tCALL tDIM tSUB tFUNCTION tGET tLET tCONST -%token tIF tELSE tELSEIF tEND tTHEN tEXIT -%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN -%token tSELECT tCASE -%token tBYREF tBYVAL -%token tOPTION -%token tSTOP -%token tNOTHING tEMPTY tNULL -%token tCLASS tSET tNEW tPUBLIC tPRIVATE tME -%token tNEXT tON tRESUME tGOTO +%token tEOF tNL tEMPTYBRACKETS +%token tLTEQ tGTEQ tNEQ +%token tSTOP tME tREM +%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> tIF tELSE tELSEIF tEND tTHEN tEXIT +%token <string> tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN +%token <string> tSELECT tCASE +%token <string> tBYREF tBYVAL +%token <string> tOPTION +%token <string> tNOTHING tEMPTY tNULL +%token <string> tCLASS tSET tNEW tPUBLIC tPRIVATE +%token <string> tNEXT tON tRESUME tGOTO %token <string> tIdentifier tString %token <string> tDEFAULT tERROR tEXPLICIT tPROPERTY tSTEP %token <lng> tLong tShort @@ -137,7 +138,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %type <dim_decl> DimDeclList DimDecl %type <dim_list> DimList %type <const_decl> ConstDecl ConstDeclList -%type <string> Identifier +%type <string> Identifier DotIdentifier %type <case_clausule> CaseClausules
%% @@ -209,7 +210,7 @@ SimpleStatement
MemberExpression : Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; } - | CallExpression '.' Identifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; } + | CallExpression '.' DotIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
DimDeclList : DimDecl { $$ = $1; } @@ -451,6 +452,59 @@ Identifier | tPROPERTY { $$ = $1; } | tSTEP { $$ = $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; } + /* Most statements accept both new line and ':' as separators */ StSep : tNL diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 15ad84a23ac..098506402bc 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -1365,4 +1365,59 @@ sub test_identifiers end sub call test_identifiers()
+sub test_dotIdentifiers + ' test keywords that can also be an indentifier after a dot + ' Call ok(testObj.rem = 10, "testObj.rem = " & testObj.rem & " expected 10") + Call ok(testObj.true = 10, "testObj.true = " & testObj.true & " expected 10") + Call ok(testObj.false = 10, "testObj.false = " & testObj.false & " expected 10") + Call ok(testObj.not = 10, "testObj.not = " & testObj.not & " expected 10") + Call ok(testObj.and = 10, "testObj.and = " & testObj.and & " expected 10") + Call ok(testObj.or = 10, "testObj.or = " & testObj.or & " expected 10") + Call ok(testObj.xor = 10, "testObj.xor = " & testObj.xor & " expected 10") + Call ok(testObj.eqv = 10, "testObj.eqv = " & testObj.eqv & " expected 10") + Call ok(testObj.imp = 10, "testObj.imp = " & testObj.imp & " expected 10") + Call ok(testObj.is = 10, "testObj.is = " & testObj.is & " expected 10") + Call ok(testObj.mod = 10, "testObj.mod = " & testObj.mod & " expected 10") + Call ok(testObj.call = 10, "testObj.call = " & testObj.call & " expected 10") + Call ok(testObj.dim = 10, "testObj.dim = " & testObj.dim & " expected 10") + Call ok(testObj.sub = 10, "testObj.sub = " & testObj.sub & " expected 10") + Call ok(testObj.function = 10, "testObj.function = " & testObj.function & " expected 10") + Call ok(testObj.get = 10, "testObj.get = " & testObj.get & " expected 10") + Call ok(testObj.let = 10, "testObj.let = " & testObj.let & " expected 10") + Call ok(testObj.const = 10, "testObj.const = " & testObj.const & " expected 10") + Call ok(testObj.if = 10, "testObj.if = " & testObj.if & " expected 10") + Call ok(testObj.else = 10, "testObj.else = " & testObj.else & " expected 10") + Call ok(testObj.elseif = 10, "testObj.elseif = " & testObj.elseif & " expected 10") + Call ok(testObj.end = 10, "testObj.end = " & testObj.end & " expected 10") + Call ok(testObj.then = 10, "testObj.then = " & testObj.then & " expected 10") + Call ok(testObj.exit = 10, "testObj.exit = " & testObj.exit & " expected 10") + Call ok(testObj.while = 10, "testObj.while = " & testObj.while & " expected 10") + Call ok(testObj.wend = 10, "testObj.wend = " & testObj.wend & " expected 10") + Call ok(testObj.do = 10, "testObj.do = " & testObj.do & " expected 10") + Call ok(testObj.loop = 10, "testObj.loop = " & testObj.loop & " expected 10") + Call ok(testObj.until = 10, "testObj.until = " & testObj.until & " expected 10") + Call ok(testObj.for = 10, "testObj.for = " & testObj.for & " expected 10") + Call ok(testObj.to = 10, "testObj.to = " & testObj.to & " expected 10") + Call ok(testObj.each = 10, "testObj.each = " & testObj.each & " expected 10") + Call ok(testObj.in = 10, "testObj.in = " & testObj.in & " expected 10") + Call ok(testObj.select = 10, "testObj.select = " & testObj.select & " expected 10") + Call ok(testObj.case = 10, "testObj.case = " & testObj.case & " expected 10") + Call ok(testObj.byref = 10, "testObj.byref = " & testObj.byref & " expected 10") + Call ok(testObj.byval = 10, "testObj.byval = " & testObj.byval & " expected 10") + Call ok(testObj.option = 10, "testObj.option = " & testObj.option & " expected 10") + Call ok(testObj.nothing = 10, "testObj.nothing = " & testObj.nothing & " expected 10") + Call ok(testObj.empty = 10, "testObj.empty = " & testObj.empty & " expected 10") + Call ok(testObj.null = 10, "testObj.null = " & testObj.null & " expected 10") + Call ok(testObj.class = 10, "testObj.class = " & testObj.class & " expected 10") + Call ok(testObj.set = 10, "testObj.set = " & testObj.set & " expected 10") + Call ok(testObj.new = 10, "testObj.new = " & testObj.new & " expected 10") + Call ok(testObj.public = 10, "testObj.public = " & testObj.public & " expected 10") + Call ok(testObj.private = 10, "testObj.private = " & testObj.private & " expected 10") + Call ok(testObj.next = 10, "testObj.next = " & testObj.next & " expected 10") + Call ok(testObj.on = 10, "testObj.on = " & testObj.on & " expected 10") + Call ok(testObj.resume = 10, "testObj.resume = " & testObj.resume & " expected 10") + Call ok(testObj.goto = 10, "testObj.goto = " & testObj.goto & " expected 10") +end sub +'call test_dotIdentifiers + reportSuccess() diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 191f5a79a0d..a28cf74196b 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -58,6 +58,9 @@ extern const CLSID CLSID_VBScriptRegExp; #define SET_EXPECT(func) \ expect_ ## func = TRUE
+#define REF_EXPECT(func) \ + (&expect_ ## func), (&called_ ## func) + #define CHECK_EXPECT2(func) \ do { \ ok(expect_ ##func, "unexpected call " #func "\n"); \ @@ -127,6 +130,56 @@ DEFINE_EXPECT(OnScriptError);
#define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPPUT 2001 +#define DISPID_TESTOBJ_REM 2002 +#define DISPID_TESTOBJ_TRUE 2003 +#define DISPID_TESTOBJ_FALSE 2004 +#define DISPID_TESTOBJ_NOT 2005 +#define DISPID_TESTOBJ_AND 2006 +#define DISPID_TESTOBJ_OR 2007 +#define DISPID_TESTOBJ_XOR 2008 +#define DISPID_TESTOBJ_EQV 2009 +#define DISPID_TESTOBJ_IMP 2010 +#define DISPID_TESTOBJ_IS 2011 +#define DISPID_TESTOBJ_MOD 2012 +#define DISPID_TESTOBJ_CALL 2013 +#define DISPID_TESTOBJ_DIM 2014 +#define DISPID_TESTOBJ_SUB 2015 +#define DISPID_TESTOBJ_FUNCTION 2016 +#define DISPID_TESTOBJ_GET 2017 +#define DISPID_TESTOBJ_LET 2018 +#define DISPID_TESTOBJ_CONST 2019 +#define DISPID_TESTOBJ_IF 2020 +#define DISPID_TESTOBJ_ELSE 2021 +#define DISPID_TESTOBJ_ELSEIF 2022 +#define DISPID_TESTOBJ_END 2023 +#define DISPID_TESTOBJ_THEN 2024 +#define DISPID_TESTOBJ_EXIT 2025 +#define DISPID_TESTOBJ_WHILE 2026 +#define DISPID_TESTOBJ_WEND 2027 +#define DISPID_TESTOBJ_DO 2028 +#define DISPID_TESTOBJ_LOOP 2029 +#define DISPID_TESTOBJ_UNTIL 2030 +#define DISPID_TESTOBJ_FOR 2031 +#define DISPID_TESTOBJ_TO 2032 +#define DISPID_TESTOBJ_EACH 2033 +#define DISPID_TESTOBJ_IN 2034 +#define DISPID_TESTOBJ_SELECT 2035 +#define DISPID_TESTOBJ_CASE 2036 +#define DISPID_TESTOBJ_BYREF 2037 +#define DISPID_TESTOBJ_BYVAL 2038 +#define DISPID_TESTOBJ_OPTION 2039 +#define DISPID_TESTOBJ_NOTHING 2040 +#define DISPID_TESTOBJ_EMPTY 2041 +#define DISPID_TESTOBJ_NULL 2042 +#define DISPID_TESTOBJ_CLASS 2043 +#define DISPID_TESTOBJ_SET 2044 +#define DISPID_TESTOBJ_NEW 2045 +#define DISPID_TESTOBJ_PUBLIC 2046 +#define DISPID_TESTOBJ_PRIVATE 2047 +#define DISPID_TESTOBJ_NEXT 2048 +#define DISPID_TESTOBJ_ON 2049 +#define DISPID_TESTOBJ_RESUME 2050 +#define DISPID_TESTOBJ_GOTO 2051
#define DISPID_COLLOBJ_RESET 3000
@@ -756,17 +809,80 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { - if(!strcmp_wa(bstrName, "propget")) { - CHECK_EXPECT(testobj_propget_d); - test_grfdex(grfdex, fdexNameCaseInsensitive); - *pid = DISPID_TESTOBJ_PROPGET; - return S_OK; - } - if(!strcmp_wa(bstrName, "propput")) { - CHECK_EXPECT(testobj_propput_d); - test_grfdex(grfdex, fdexNameCaseInsensitive); - *pid = DISPID_TESTOBJ_PROPPUT; - return S_OK; + typedef struct { + const char * const name; + DISPID pid; + BOOL *expect; + BOOL *called; + } dispid_t; + + dispid_t dispids[] = { + { "propget", DISPID_TESTOBJ_PROPGET, REF_EXPECT(testobj_propget_d) }, + { "propput", DISPID_TESTOBJ_PROPPUT, REF_EXPECT(testobj_propput_d) }, + { "rem", DISPID_TESTOBJ_REM, NULL }, + { "true", DISPID_TESTOBJ_TRUE, NULL }, + { "false", DISPID_TESTOBJ_FALSE, NULL }, + { "not", DISPID_TESTOBJ_NOT, NULL }, + { "and", DISPID_TESTOBJ_AND, NULL }, + { "or", DISPID_TESTOBJ_OR, NULL }, + { "xor", DISPID_TESTOBJ_XOR, NULL }, + { "eqv", DISPID_TESTOBJ_EQV, NULL }, + { "imp", DISPID_TESTOBJ_IMP, NULL }, + { "is", DISPID_TESTOBJ_IS, NULL }, + { "mod", DISPID_TESTOBJ_MOD, NULL }, + { "call", DISPID_TESTOBJ_CALL, NULL }, + { "dim", DISPID_TESTOBJ_DIM, NULL }, + { "sub", DISPID_TESTOBJ_SUB, NULL }, + { "function", DISPID_TESTOBJ_FUNCTION, NULL }, + { "get", DISPID_TESTOBJ_GET, NULL }, + { "let", DISPID_TESTOBJ_LET, NULL }, + { "const", DISPID_TESTOBJ_CONST, NULL }, + { "if", DISPID_TESTOBJ_IF, NULL }, + { "else", DISPID_TESTOBJ_ELSE, NULL }, + { "elseif", DISPID_TESTOBJ_ELSEIF, NULL }, + { "end", DISPID_TESTOBJ_END, NULL }, + { "then", DISPID_TESTOBJ_THEN, NULL }, + { "exit", DISPID_TESTOBJ_EXIT, NULL }, + { "while", DISPID_TESTOBJ_WHILE, NULL }, + { "wend", DISPID_TESTOBJ_WEND, NULL }, + { "do", DISPID_TESTOBJ_DO, NULL }, + { "loop", DISPID_TESTOBJ_LOOP, NULL }, + { "until", DISPID_TESTOBJ_UNTIL, NULL }, + { "for", DISPID_TESTOBJ_FOR, NULL }, + { "to", DISPID_TESTOBJ_TO, NULL }, + { "each", DISPID_TESTOBJ_EACH, NULL }, + { "in", DISPID_TESTOBJ_IN, NULL }, + { "select", DISPID_TESTOBJ_SELECT, NULL }, + { "case", DISPID_TESTOBJ_CASE, NULL }, + { "byref", DISPID_TESTOBJ_BYREF, NULL }, + { "byval", DISPID_TESTOBJ_BYVAL, NULL }, + { "option", DISPID_TESTOBJ_OPTION, NULL }, + { "nothing", DISPID_TESTOBJ_NOTHING, NULL }, + { "empty", DISPID_TESTOBJ_EMPTY, NULL }, + { "null", DISPID_TESTOBJ_NULL, NULL }, + { "class", DISPID_TESTOBJ_CLASS, NULL }, + { "set", DISPID_TESTOBJ_SET, NULL }, + { "new", DISPID_TESTOBJ_NEW, NULL }, + { "public", DISPID_TESTOBJ_PUBLIC, NULL }, + { "private", DISPID_TESTOBJ_PRIVATE, NULL }, + { "next", DISPID_TESTOBJ_NEXT, NULL }, + { "on", DISPID_TESTOBJ_ON, NULL }, + { "resume", DISPID_TESTOBJ_RESUME, NULL }, + { "goto", DISPID_TESTOBJ_GOTO, NULL }, + }; + + for (int i = 0; i < ARRAY_SIZE(dispids); i++) { + if(!strcmp_wa(bstrName, dispids[i].name)) { + dispid_t *d = &dispids[i]; + if(d->expect) { + ok(*d->expect, "unexpected call %s\n", d->name); + *d->called = TRUE; + *d->expect = FALSE; + } + test_grfdex(grfdex, fdexNameCaseInsensitive); + *pid = d->pid; + return S_OK; + } }
ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName)); @@ -833,6 +949,12 @@ static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, return S_OK; }
+ if (id >= DISPID_TESTOBJ_REM && id <= DISPID_TESTOBJ_GOTO) { + V_VT(pvarRes) = VT_I2; + V_I2(pvarRes) = 10; + return S_OK; + } + ok(0, "unexpected call %d\n", id); return E_FAIL; }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46318 Signed-off-by: Brendan McGrath brendan@redmandi.com --- I wasn't sure if you would want this test so I included it in a separate patch
dlls/vbscript/tests/run.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index a28cf74196b..bfc4b91844e 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -2377,6 +2377,10 @@ static void run_tests(void) parse_script_a("Option Explicit\nset test.setobj = testObj"); CHECK_CALLED(global_setobj_i);
+ hres = parse_script_ar("dim x\nx = testObj.rem"); + todo_wine + ok(hres == S_OK, "use of 'rem' as dot identifier failed: %x08\n", hres); + SET_EXPECT(testobj_propget_d); SET_EXPECT(testobj_propget_i); parse_script_a("dim x\nx = testObj.propget");
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46318 Signed-off-by: Brendan McGrath brendan@redmandi.com --- Changes since version 1: - uncomment call to test_dotIdentifiers
Ugh - I saw it on review of the sent email.
dlls/vbscript/parser.y | 86 +++++++++++++++++---- dlls/vbscript/tests/lang.vbs | 55 +++++++++++++ dlls/vbscript/tests/run.c | 144 ++++++++++++++++++++++++++++++++--- 3 files changed, 258 insertions(+), 27 deletions(-)
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index b81d7919662..52c98fca596 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -102,20 +102,21 @@ static statement_t *link_statements(statement_t*,statement_t*); double dbl; }
-%token tEOF tNL tREM tEMPTYBRACKETS -%token tTRUE tFALSE -%token tNOT tAND tOR tXOR tEQV tIMP tNEQ -%token tIS tLTEQ tGTEQ tMOD -%token tCALL tDIM tSUB tFUNCTION tGET tLET tCONST -%token tIF tELSE tELSEIF tEND tTHEN tEXIT -%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN -%token tSELECT tCASE -%token tBYREF tBYVAL -%token tOPTION -%token tSTOP -%token tNOTHING tEMPTY tNULL -%token tCLASS tSET tNEW tPUBLIC tPRIVATE tME -%token tNEXT tON tRESUME tGOTO +%token tEOF tNL tEMPTYBRACKETS +%token tLTEQ tGTEQ tNEQ +%token tSTOP tME tREM +%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> tIF tELSE tELSEIF tEND tTHEN tEXIT +%token <string> tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN +%token <string> tSELECT tCASE +%token <string> tBYREF tBYVAL +%token <string> tOPTION +%token <string> tNOTHING tEMPTY tNULL +%token <string> tCLASS tSET tNEW tPUBLIC tPRIVATE +%token <string> tNEXT tON tRESUME tGOTO %token <string> tIdentifier tString %token <string> tDEFAULT tERROR tEXPLICIT tPROPERTY tSTEP %token <lng> tLong tShort @@ -137,7 +138,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %type <dim_decl> DimDeclList DimDecl %type <dim_list> DimList %type <const_decl> ConstDecl ConstDeclList -%type <string> Identifier +%type <string> Identifier DotIdentifier %type <case_clausule> CaseClausules
%% @@ -209,7 +210,7 @@ SimpleStatement
MemberExpression : Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; } - | CallExpression '.' Identifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; } + | CallExpression '.' DotIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
DimDeclList : DimDecl { $$ = $1; } @@ -451,6 +452,59 @@ Identifier | tPROPERTY { $$ = $1; } | tSTEP { $$ = $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; } + /* Most statements accept both new line and ':' as separators */ StSep : tNL diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 15ad84a23ac..9f1d24c5400 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -1365,4 +1365,59 @@ sub test_identifiers end sub call test_identifiers()
+sub test_dotIdentifiers + ' test keywords that can also be an indentifier after a dot + ' Call ok(testObj.rem = 10, "testObj.rem = " & testObj.rem & " expected 10") + Call ok(testObj.true = 10, "testObj.true = " & testObj.true & " expected 10") + Call ok(testObj.false = 10, "testObj.false = " & testObj.false & " expected 10") + Call ok(testObj.not = 10, "testObj.not = " & testObj.not & " expected 10") + Call ok(testObj.and = 10, "testObj.and = " & testObj.and & " expected 10") + Call ok(testObj.or = 10, "testObj.or = " & testObj.or & " expected 10") + Call ok(testObj.xor = 10, "testObj.xor = " & testObj.xor & " expected 10") + Call ok(testObj.eqv = 10, "testObj.eqv = " & testObj.eqv & " expected 10") + Call ok(testObj.imp = 10, "testObj.imp = " & testObj.imp & " expected 10") + Call ok(testObj.is = 10, "testObj.is = " & testObj.is & " expected 10") + Call ok(testObj.mod = 10, "testObj.mod = " & testObj.mod & " expected 10") + Call ok(testObj.call = 10, "testObj.call = " & testObj.call & " expected 10") + Call ok(testObj.dim = 10, "testObj.dim = " & testObj.dim & " expected 10") + Call ok(testObj.sub = 10, "testObj.sub = " & testObj.sub & " expected 10") + Call ok(testObj.function = 10, "testObj.function = " & testObj.function & " expected 10") + Call ok(testObj.get = 10, "testObj.get = " & testObj.get & " expected 10") + Call ok(testObj.let = 10, "testObj.let = " & testObj.let & " expected 10") + Call ok(testObj.const = 10, "testObj.const = " & testObj.const & " expected 10") + Call ok(testObj.if = 10, "testObj.if = " & testObj.if & " expected 10") + Call ok(testObj.else = 10, "testObj.else = " & testObj.else & " expected 10") + Call ok(testObj.elseif = 10, "testObj.elseif = " & testObj.elseif & " expected 10") + Call ok(testObj.end = 10, "testObj.end = " & testObj.end & " expected 10") + Call ok(testObj.then = 10, "testObj.then = " & testObj.then & " expected 10") + Call ok(testObj.exit = 10, "testObj.exit = " & testObj.exit & " expected 10") + Call ok(testObj.while = 10, "testObj.while = " & testObj.while & " expected 10") + Call ok(testObj.wend = 10, "testObj.wend = " & testObj.wend & " expected 10") + Call ok(testObj.do = 10, "testObj.do = " & testObj.do & " expected 10") + Call ok(testObj.loop = 10, "testObj.loop = " & testObj.loop & " expected 10") + Call ok(testObj.until = 10, "testObj.until = " & testObj.until & " expected 10") + Call ok(testObj.for = 10, "testObj.for = " & testObj.for & " expected 10") + Call ok(testObj.to = 10, "testObj.to = " & testObj.to & " expected 10") + Call ok(testObj.each = 10, "testObj.each = " & testObj.each & " expected 10") + Call ok(testObj.in = 10, "testObj.in = " & testObj.in & " expected 10") + Call ok(testObj.select = 10, "testObj.select = " & testObj.select & " expected 10") + Call ok(testObj.case = 10, "testObj.case = " & testObj.case & " expected 10") + Call ok(testObj.byref = 10, "testObj.byref = " & testObj.byref & " expected 10") + Call ok(testObj.byval = 10, "testObj.byval = " & testObj.byval & " expected 10") + Call ok(testObj.option = 10, "testObj.option = " & testObj.option & " expected 10") + Call ok(testObj.nothing = 10, "testObj.nothing = " & testObj.nothing & " expected 10") + Call ok(testObj.empty = 10, "testObj.empty = " & testObj.empty & " expected 10") + Call ok(testObj.null = 10, "testObj.null = " & testObj.null & " expected 10") + Call ok(testObj.class = 10, "testObj.class = " & testObj.class & " expected 10") + Call ok(testObj.set = 10, "testObj.set = " & testObj.set & " expected 10") + Call ok(testObj.new = 10, "testObj.new = " & testObj.new & " expected 10") + Call ok(testObj.public = 10, "testObj.public = " & testObj.public & " expected 10") + Call ok(testObj.private = 10, "testObj.private = " & testObj.private & " expected 10") + Call ok(testObj.next = 10, "testObj.next = " & testObj.next & " expected 10") + Call ok(testObj.on = 10, "testObj.on = " & testObj.on & " expected 10") + Call ok(testObj.resume = 10, "testObj.resume = " & testObj.resume & " expected 10") + Call ok(testObj.goto = 10, "testObj.goto = " & testObj.goto & " expected 10") +end sub +call test_dotIdentifiers + reportSuccess() diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 191f5a79a0d..a28cf74196b 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -58,6 +58,9 @@ extern const CLSID CLSID_VBScriptRegExp; #define SET_EXPECT(func) \ expect_ ## func = TRUE
+#define REF_EXPECT(func) \ + (&expect_ ## func), (&called_ ## func) + #define CHECK_EXPECT2(func) \ do { \ ok(expect_ ##func, "unexpected call " #func "\n"); \ @@ -127,6 +130,56 @@ DEFINE_EXPECT(OnScriptError);
#define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPPUT 2001 +#define DISPID_TESTOBJ_REM 2002 +#define DISPID_TESTOBJ_TRUE 2003 +#define DISPID_TESTOBJ_FALSE 2004 +#define DISPID_TESTOBJ_NOT 2005 +#define DISPID_TESTOBJ_AND 2006 +#define DISPID_TESTOBJ_OR 2007 +#define DISPID_TESTOBJ_XOR 2008 +#define DISPID_TESTOBJ_EQV 2009 +#define DISPID_TESTOBJ_IMP 2010 +#define DISPID_TESTOBJ_IS 2011 +#define DISPID_TESTOBJ_MOD 2012 +#define DISPID_TESTOBJ_CALL 2013 +#define DISPID_TESTOBJ_DIM 2014 +#define DISPID_TESTOBJ_SUB 2015 +#define DISPID_TESTOBJ_FUNCTION 2016 +#define DISPID_TESTOBJ_GET 2017 +#define DISPID_TESTOBJ_LET 2018 +#define DISPID_TESTOBJ_CONST 2019 +#define DISPID_TESTOBJ_IF 2020 +#define DISPID_TESTOBJ_ELSE 2021 +#define DISPID_TESTOBJ_ELSEIF 2022 +#define DISPID_TESTOBJ_END 2023 +#define DISPID_TESTOBJ_THEN 2024 +#define DISPID_TESTOBJ_EXIT 2025 +#define DISPID_TESTOBJ_WHILE 2026 +#define DISPID_TESTOBJ_WEND 2027 +#define DISPID_TESTOBJ_DO 2028 +#define DISPID_TESTOBJ_LOOP 2029 +#define DISPID_TESTOBJ_UNTIL 2030 +#define DISPID_TESTOBJ_FOR 2031 +#define DISPID_TESTOBJ_TO 2032 +#define DISPID_TESTOBJ_EACH 2033 +#define DISPID_TESTOBJ_IN 2034 +#define DISPID_TESTOBJ_SELECT 2035 +#define DISPID_TESTOBJ_CASE 2036 +#define DISPID_TESTOBJ_BYREF 2037 +#define DISPID_TESTOBJ_BYVAL 2038 +#define DISPID_TESTOBJ_OPTION 2039 +#define DISPID_TESTOBJ_NOTHING 2040 +#define DISPID_TESTOBJ_EMPTY 2041 +#define DISPID_TESTOBJ_NULL 2042 +#define DISPID_TESTOBJ_CLASS 2043 +#define DISPID_TESTOBJ_SET 2044 +#define DISPID_TESTOBJ_NEW 2045 +#define DISPID_TESTOBJ_PUBLIC 2046 +#define DISPID_TESTOBJ_PRIVATE 2047 +#define DISPID_TESTOBJ_NEXT 2048 +#define DISPID_TESTOBJ_ON 2049 +#define DISPID_TESTOBJ_RESUME 2050 +#define DISPID_TESTOBJ_GOTO 2051
#define DISPID_COLLOBJ_RESET 3000
@@ -756,17 +809,80 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { - if(!strcmp_wa(bstrName, "propget")) { - CHECK_EXPECT(testobj_propget_d); - test_grfdex(grfdex, fdexNameCaseInsensitive); - *pid = DISPID_TESTOBJ_PROPGET; - return S_OK; - } - if(!strcmp_wa(bstrName, "propput")) { - CHECK_EXPECT(testobj_propput_d); - test_grfdex(grfdex, fdexNameCaseInsensitive); - *pid = DISPID_TESTOBJ_PROPPUT; - return S_OK; + typedef struct { + const char * const name; + DISPID pid; + BOOL *expect; + BOOL *called; + } dispid_t; + + dispid_t dispids[] = { + { "propget", DISPID_TESTOBJ_PROPGET, REF_EXPECT(testobj_propget_d) }, + { "propput", DISPID_TESTOBJ_PROPPUT, REF_EXPECT(testobj_propput_d) }, + { "rem", DISPID_TESTOBJ_REM, NULL }, + { "true", DISPID_TESTOBJ_TRUE, NULL }, + { "false", DISPID_TESTOBJ_FALSE, NULL }, + { "not", DISPID_TESTOBJ_NOT, NULL }, + { "and", DISPID_TESTOBJ_AND, NULL }, + { "or", DISPID_TESTOBJ_OR, NULL }, + { "xor", DISPID_TESTOBJ_XOR, NULL }, + { "eqv", DISPID_TESTOBJ_EQV, NULL }, + { "imp", DISPID_TESTOBJ_IMP, NULL }, + { "is", DISPID_TESTOBJ_IS, NULL }, + { "mod", DISPID_TESTOBJ_MOD, NULL }, + { "call", DISPID_TESTOBJ_CALL, NULL }, + { "dim", DISPID_TESTOBJ_DIM, NULL }, + { "sub", DISPID_TESTOBJ_SUB, NULL }, + { "function", DISPID_TESTOBJ_FUNCTION, NULL }, + { "get", DISPID_TESTOBJ_GET, NULL }, + { "let", DISPID_TESTOBJ_LET, NULL }, + { "const", DISPID_TESTOBJ_CONST, NULL }, + { "if", DISPID_TESTOBJ_IF, NULL }, + { "else", DISPID_TESTOBJ_ELSE, NULL }, + { "elseif", DISPID_TESTOBJ_ELSEIF, NULL }, + { "end", DISPID_TESTOBJ_END, NULL }, + { "then", DISPID_TESTOBJ_THEN, NULL }, + { "exit", DISPID_TESTOBJ_EXIT, NULL }, + { "while", DISPID_TESTOBJ_WHILE, NULL }, + { "wend", DISPID_TESTOBJ_WEND, NULL }, + { "do", DISPID_TESTOBJ_DO, NULL }, + { "loop", DISPID_TESTOBJ_LOOP, NULL }, + { "until", DISPID_TESTOBJ_UNTIL, NULL }, + { "for", DISPID_TESTOBJ_FOR, NULL }, + { "to", DISPID_TESTOBJ_TO, NULL }, + { "each", DISPID_TESTOBJ_EACH, NULL }, + { "in", DISPID_TESTOBJ_IN, NULL }, + { "select", DISPID_TESTOBJ_SELECT, NULL }, + { "case", DISPID_TESTOBJ_CASE, NULL }, + { "byref", DISPID_TESTOBJ_BYREF, NULL }, + { "byval", DISPID_TESTOBJ_BYVAL, NULL }, + { "option", DISPID_TESTOBJ_OPTION, NULL }, + { "nothing", DISPID_TESTOBJ_NOTHING, NULL }, + { "empty", DISPID_TESTOBJ_EMPTY, NULL }, + { "null", DISPID_TESTOBJ_NULL, NULL }, + { "class", DISPID_TESTOBJ_CLASS, NULL }, + { "set", DISPID_TESTOBJ_SET, NULL }, + { "new", DISPID_TESTOBJ_NEW, NULL }, + { "public", DISPID_TESTOBJ_PUBLIC, NULL }, + { "private", DISPID_TESTOBJ_PRIVATE, NULL }, + { "next", DISPID_TESTOBJ_NEXT, NULL }, + { "on", DISPID_TESTOBJ_ON, NULL }, + { "resume", DISPID_TESTOBJ_RESUME, NULL }, + { "goto", DISPID_TESTOBJ_GOTO, NULL }, + }; + + for (int i = 0; i < ARRAY_SIZE(dispids); i++) { + if(!strcmp_wa(bstrName, dispids[i].name)) { + dispid_t *d = &dispids[i]; + if(d->expect) { + ok(*d->expect, "unexpected call %s\n", d->name); + *d->called = TRUE; + *d->expect = FALSE; + } + test_grfdex(grfdex, fdexNameCaseInsensitive); + *pid = d->pid; + return S_OK; + } }
ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName)); @@ -833,6 +949,12 @@ static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, return S_OK; }
+ if (id >= DISPID_TESTOBJ_REM && id <= DISPID_TESTOBJ_GOTO) { + V_VT(pvarRes) = VT_I2; + V_I2(pvarRes) = 10; + return S_OK; + } + ok(0, "unexpected call %d\n", id); return E_FAIL; }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46318 Signed-off-by: Brendan McGrath brendan@redmandi.com --- dlls/vbscript/tests/run.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index a28cf74196b..bfc4b91844e 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -2377,6 +2377,10 @@ static void run_tests(void) parse_script_a("Option Explicit\nset test.setobj = testObj"); CHECK_CALLED(global_setobj_i);
+ hres = parse_script_ar("dim x\nx = testObj.rem"); + todo_wine + ok(hres == S_OK, "use of 'rem' as dot identifier failed: %x08\n", hres); + SET_EXPECT(testobj_propget_d); SET_EXPECT(testobj_propget_i); parse_script_a("dim x\nx = testObj.propget");
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=48318
Your paranoid android.
=== wxppro (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w2003std (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64_zh_CN (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64_fr (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64_he (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w2008s64 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w7u (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w7pro64 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w8 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w8adm (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w864 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w1064 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w2008s64 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w7pro64 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w864 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w1064 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=48317
Your paranoid android.
=== wxppro (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w2003std (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64_zh_CN (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64_fr (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64_he (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w2008s64 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w7u (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w7pro64 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w8 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w8adm (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w864 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w1064 (32 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== wvistau64 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w2008s64 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w7pro64 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w864 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
=== w1064 (64 bit report) ===
vbscript: run.c:888: Test failed: unexpected call L"Mod" run.c:1792: Test failed: unexpected call OnScriptError run.c:1792: Test failed: unexpected call OnScriptError run.c:2306: Test failed: expected global_success_d run.c:2307: Test failed: expected global_success_i run.c:2309: Test failed: parse_script failed: 800a01b6
Hi Brendan,
The patch looks mostly good to me. I have just one suggestion:
On 2/27/19 7:28 AM, Brendan McGrath wrote:
#define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPPUT 2001 +#define DISPID_TESTOBJ_REM 2002 +#define DISPID_TESTOBJ_TRUE 2003 +#define DISPID_TESTOBJ_FALSE 2004 +#define DISPID_TESTOBJ_NOT 2005 +#define DISPID_TESTOBJ_AND 2006 +#define DISPID_TESTOBJ_OR 2007 +#define DISPID_TESTOBJ_XOR 2008 +#define DISPID_TESTOBJ_EQV 2009 +#define DISPID_TESTOBJ_IMP 2010 +#define DISPID_TESTOBJ_IS 2011 +#define DISPID_TESTOBJ_MOD 2012 +#define DISPID_TESTOBJ_CALL 2013 +#define DISPID_TESTOBJ_DIM 2014 +#define DISPID_TESTOBJ_SUB 2015 +#define DISPID_TESTOBJ_FUNCTION 2016 +#define DISPID_TESTOBJ_GET 2017 +#define DISPID_TESTOBJ_LET 2018 +#define DISPID_TESTOBJ_CONST 2019 +#define DISPID_TESTOBJ_IF 2020 +#define DISPID_TESTOBJ_ELSE 2021 +#define DISPID_TESTOBJ_ELSEIF 2022 +#define DISPID_TESTOBJ_END 2023 +#define DISPID_TESTOBJ_THEN 2024 +#define DISPID_TESTOBJ_EXIT 2025 +#define DISPID_TESTOBJ_WHILE 2026 +#define DISPID_TESTOBJ_WEND 2027 +#define DISPID_TESTOBJ_DO 2028 +#define DISPID_TESTOBJ_LOOP 2029 +#define DISPID_TESTOBJ_UNTIL 2030 +#define DISPID_TESTOBJ_FOR 2031 +#define DISPID_TESTOBJ_TO 2032 +#define DISPID_TESTOBJ_EACH 2033 +#define DISPID_TESTOBJ_IN 2034 +#define DISPID_TESTOBJ_SELECT 2035 +#define DISPID_TESTOBJ_CASE 2036 +#define DISPID_TESTOBJ_BYREF 2037 +#define DISPID_TESTOBJ_BYVAL 2038 +#define DISPID_TESTOBJ_OPTION 2039 +#define DISPID_TESTOBJ_NOTHING 2040 +#define DISPID_TESTOBJ_EMPTY 2041 +#define DISPID_TESTOBJ_NULL 2042 +#define DISPID_TESTOBJ_CLASS 2043 +#define DISPID_TESTOBJ_SET 2044 +#define DISPID_TESTOBJ_NEW 2045 +#define DISPID_TESTOBJ_PUBLIC 2046 +#define DISPID_TESTOBJ_PRIVATE 2047 +#define DISPID_TESTOBJ_NEXT 2048 +#define DISPID_TESTOBJ_ON 2049 +#define DISPID_TESTOBJ_RESUME 2050 +#define DISPID_TESTOBJ_GOTO 2051
You could use just single DISPID (say, DISPID_TESTOBJ_KEYWORD) and return it for all keywords.
Thanks,
Jacek
Thanks Jacek - yeah I thought of that afterwards - I will make that change.
I also need to look in to how to run the test on Windows, as Windows had failures (when I actually ran the tests). So I'll make sure the tests pass on Windows too (by removing support for the keywords that don't) before submitting the next version.
On 28/2/19 5:42 am, Jacek Caban wrote:
Hi Brendan,
The patch looks mostly good to me. I have just one suggestion:
On 2/27/19 7:28 AM, Brendan McGrath wrote:
#define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPPUT 2001 +#define DISPID_TESTOBJ_REM 2002 +#define DISPID_TESTOBJ_TRUE 2003 +#define DISPID_TESTOBJ_FALSE 2004 +#define DISPID_TESTOBJ_NOT 2005 +#define DISPID_TESTOBJ_AND 2006 +#define DISPID_TESTOBJ_OR 2007 +#define DISPID_TESTOBJ_XOR 2008 +#define DISPID_TESTOBJ_EQV 2009 +#define DISPID_TESTOBJ_IMP 2010 +#define DISPID_TESTOBJ_IS 2011 +#define DISPID_TESTOBJ_MOD 2012 +#define DISPID_TESTOBJ_CALL 2013 +#define DISPID_TESTOBJ_DIM 2014 +#define DISPID_TESTOBJ_SUB 2015 +#define DISPID_TESTOBJ_FUNCTION 2016 +#define DISPID_TESTOBJ_GET 2017 +#define DISPID_TESTOBJ_LET 2018 +#define DISPID_TESTOBJ_CONST 2019 +#define DISPID_TESTOBJ_IF 2020 +#define DISPID_TESTOBJ_ELSE 2021 +#define DISPID_TESTOBJ_ELSEIF 2022 +#define DISPID_TESTOBJ_END 2023 +#define DISPID_TESTOBJ_THEN 2024 +#define DISPID_TESTOBJ_EXIT 2025 +#define DISPID_TESTOBJ_WHILE 2026 +#define DISPID_TESTOBJ_WEND 2027 +#define DISPID_TESTOBJ_DO 2028 +#define DISPID_TESTOBJ_LOOP 2029 +#define DISPID_TESTOBJ_UNTIL 2030 +#define DISPID_TESTOBJ_FOR 2031 +#define DISPID_TESTOBJ_TO 2032 +#define DISPID_TESTOBJ_EACH 2033 +#define DISPID_TESTOBJ_IN 2034 +#define DISPID_TESTOBJ_SELECT 2035 +#define DISPID_TESTOBJ_CASE 2036 +#define DISPID_TESTOBJ_BYREF 2037 +#define DISPID_TESTOBJ_BYVAL 2038 +#define DISPID_TESTOBJ_OPTION 2039 +#define DISPID_TESTOBJ_NOTHING 2040 +#define DISPID_TESTOBJ_EMPTY 2041 +#define DISPID_TESTOBJ_NULL 2042 +#define DISPID_TESTOBJ_CLASS 2043 +#define DISPID_TESTOBJ_SET 2044 +#define DISPID_TESTOBJ_NEW 2045 +#define DISPID_TESTOBJ_PUBLIC 2046 +#define DISPID_TESTOBJ_PRIVATE 2047 +#define DISPID_TESTOBJ_NEXT 2048 +#define DISPID_TESTOBJ_ON 2049 +#define DISPID_TESTOBJ_RESUME 2050 +#define DISPID_TESTOBJ_GOTO 2051
You could use just single DISPID (say, DISPID_TESTOBJ_KEYWORD) and return it for all keywords.
Thanks,
Jacek
On 2/27/19 7:45 PM, Brendan McGrath wrote:
Thanks Jacek - yeah I thought of that afterwards - I will make that change.
I also need to look in to how to run the test on Windows, as Windows had failures (when I actually ran the tests). So I'll make sure the tests pass on Windows too (by removing support for the keywords that don't) before submitting the next version.
You could register for Testbot account on testbot.winehq.org. Then you may just submit a patch there to have it tested.
Jacek
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46318 Signed-off-by: Brendan McGrath brendan@redmandi.com --- Changes since v2: - Use a single DISPID for all testObj keywords (instead of one each) - Use a case-insensitive test in testObj_GetDispID (required only for Windows)
dlls/vbscript/parser.y | 86 +++++++++++++++++++++++------ dlls/vbscript/tests/lang.vbs | 55 +++++++++++++++++++ dlls/vbscript/tests/run.c | 101 +++++++++++++++++++++++++++++++---- 3 files changed, 215 insertions(+), 27 deletions(-)
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index b81d7919662..52c98fca596 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -102,20 +102,21 @@ static statement_t *link_statements(statement_t*,statement_t*); double dbl; }
-%token tEOF tNL tREM tEMPTYBRACKETS -%token tTRUE tFALSE -%token tNOT tAND tOR tXOR tEQV tIMP tNEQ -%token tIS tLTEQ tGTEQ tMOD -%token tCALL tDIM tSUB tFUNCTION tGET tLET tCONST -%token tIF tELSE tELSEIF tEND tTHEN tEXIT -%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN -%token tSELECT tCASE -%token tBYREF tBYVAL -%token tOPTION -%token tSTOP -%token tNOTHING tEMPTY tNULL -%token tCLASS tSET tNEW tPUBLIC tPRIVATE tME -%token tNEXT tON tRESUME tGOTO +%token tEOF tNL tEMPTYBRACKETS +%token tLTEQ tGTEQ tNEQ +%token tSTOP tME tREM +%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> tIF tELSE tELSEIF tEND tTHEN tEXIT +%token <string> tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN +%token <string> tSELECT tCASE +%token <string> tBYREF tBYVAL +%token <string> tOPTION +%token <string> tNOTHING tEMPTY tNULL +%token <string> tCLASS tSET tNEW tPUBLIC tPRIVATE +%token <string> tNEXT tON tRESUME tGOTO %token <string> tIdentifier tString %token <string> tDEFAULT tERROR tEXPLICIT tPROPERTY tSTEP %token <lng> tLong tShort @@ -137,7 +138,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %type <dim_decl> DimDeclList DimDecl %type <dim_list> DimList %type <const_decl> ConstDecl ConstDeclList -%type <string> Identifier +%type <string> Identifier DotIdentifier %type <case_clausule> CaseClausules
%% @@ -209,7 +210,7 @@ SimpleStatement
MemberExpression : Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; } - | CallExpression '.' Identifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; } + | CallExpression '.' DotIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
DimDeclList : DimDecl { $$ = $1; } @@ -451,6 +452,59 @@ Identifier | tPROPERTY { $$ = $1; } | tSTEP { $$ = $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; } + /* Most statements accept both new line and ':' as separators */ StSep : tNL diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 15ad84a23ac..9f1d24c5400 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -1365,4 +1365,59 @@ sub test_identifiers end sub call test_identifiers()
+sub test_dotIdentifiers + ' test keywords that can also be an indentifier after a dot + ' Call ok(testObj.rem = 10, "testObj.rem = " & testObj.rem & " expected 10") + Call ok(testObj.true = 10, "testObj.true = " & testObj.true & " expected 10") + Call ok(testObj.false = 10, "testObj.false = " & testObj.false & " expected 10") + Call ok(testObj.not = 10, "testObj.not = " & testObj.not & " expected 10") + Call ok(testObj.and = 10, "testObj.and = " & testObj.and & " expected 10") + Call ok(testObj.or = 10, "testObj.or = " & testObj.or & " expected 10") + Call ok(testObj.xor = 10, "testObj.xor = " & testObj.xor & " expected 10") + Call ok(testObj.eqv = 10, "testObj.eqv = " & testObj.eqv & " expected 10") + Call ok(testObj.imp = 10, "testObj.imp = " & testObj.imp & " expected 10") + Call ok(testObj.is = 10, "testObj.is = " & testObj.is & " expected 10") + Call ok(testObj.mod = 10, "testObj.mod = " & testObj.mod & " expected 10") + Call ok(testObj.call = 10, "testObj.call = " & testObj.call & " expected 10") + Call ok(testObj.dim = 10, "testObj.dim = " & testObj.dim & " expected 10") + Call ok(testObj.sub = 10, "testObj.sub = " & testObj.sub & " expected 10") + Call ok(testObj.function = 10, "testObj.function = " & testObj.function & " expected 10") + Call ok(testObj.get = 10, "testObj.get = " & testObj.get & " expected 10") + Call ok(testObj.let = 10, "testObj.let = " & testObj.let & " expected 10") + Call ok(testObj.const = 10, "testObj.const = " & testObj.const & " expected 10") + Call ok(testObj.if = 10, "testObj.if = " & testObj.if & " expected 10") + Call ok(testObj.else = 10, "testObj.else = " & testObj.else & " expected 10") + Call ok(testObj.elseif = 10, "testObj.elseif = " & testObj.elseif & " expected 10") + Call ok(testObj.end = 10, "testObj.end = " & testObj.end & " expected 10") + Call ok(testObj.then = 10, "testObj.then = " & testObj.then & " expected 10") + Call ok(testObj.exit = 10, "testObj.exit = " & testObj.exit & " expected 10") + Call ok(testObj.while = 10, "testObj.while = " & testObj.while & " expected 10") + Call ok(testObj.wend = 10, "testObj.wend = " & testObj.wend & " expected 10") + Call ok(testObj.do = 10, "testObj.do = " & testObj.do & " expected 10") + Call ok(testObj.loop = 10, "testObj.loop = " & testObj.loop & " expected 10") + Call ok(testObj.until = 10, "testObj.until = " & testObj.until & " expected 10") + Call ok(testObj.for = 10, "testObj.for = " & testObj.for & " expected 10") + Call ok(testObj.to = 10, "testObj.to = " & testObj.to & " expected 10") + Call ok(testObj.each = 10, "testObj.each = " & testObj.each & " expected 10") + Call ok(testObj.in = 10, "testObj.in = " & testObj.in & " expected 10") + Call ok(testObj.select = 10, "testObj.select = " & testObj.select & " expected 10") + Call ok(testObj.case = 10, "testObj.case = " & testObj.case & " expected 10") + Call ok(testObj.byref = 10, "testObj.byref = " & testObj.byref & " expected 10") + Call ok(testObj.byval = 10, "testObj.byval = " & testObj.byval & " expected 10") + Call ok(testObj.option = 10, "testObj.option = " & testObj.option & " expected 10") + Call ok(testObj.nothing = 10, "testObj.nothing = " & testObj.nothing & " expected 10") + Call ok(testObj.empty = 10, "testObj.empty = " & testObj.empty & " expected 10") + Call ok(testObj.null = 10, "testObj.null = " & testObj.null & " expected 10") + Call ok(testObj.class = 10, "testObj.class = " & testObj.class & " expected 10") + Call ok(testObj.set = 10, "testObj.set = " & testObj.set & " expected 10") + Call ok(testObj.new = 10, "testObj.new = " & testObj.new & " expected 10") + Call ok(testObj.public = 10, "testObj.public = " & testObj.public & " expected 10") + Call ok(testObj.private = 10, "testObj.private = " & testObj.private & " expected 10") + Call ok(testObj.next = 10, "testObj.next = " & testObj.next & " expected 10") + Call ok(testObj.on = 10, "testObj.on = " & testObj.on & " expected 10") + Call ok(testObj.resume = 10, "testObj.resume = " & testObj.resume & " expected 10") + Call ok(testObj.goto = 10, "testObj.goto = " & testObj.goto & " expected 10") +end sub +call test_dotIdentifiers + reportSuccess() diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 191f5a79a0d..103082fc042 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -58,6 +58,9 @@ extern const CLSID CLSID_VBScriptRegExp; #define SET_EXPECT(func) \ expect_ ## func = TRUE
+#define REF_EXPECT(func) \ + (&expect_ ## func), (&called_ ## func) + #define CHECK_EXPECT2(func) \ do { \ ok(expect_ ##func, "unexpected call " #func "\n"); \ @@ -127,6 +130,7 @@ DEFINE_EXPECT(OnScriptError);
#define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPPUT 2001 +#define DISPID_TESTOBJ_KEYWORD 2002
#define DISPID_COLLOBJ_RESET 3000
@@ -163,6 +167,13 @@ static int strcmp_wa(LPCWSTR strw, const char *stra) return lstrcmpA(buf, stra); }
+static int stricmp_wa(LPCWSTR strw, const char *stra) +{ + CHAR buf[512]; + WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0); + return lstrcmpiA(buf, stra); +} + static const char *vt2a(VARIANT *v) { if(V_VT(v) == (VT_BYREF|VT_VARIANT)) { @@ -756,17 +767,80 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { - if(!strcmp_wa(bstrName, "propget")) { - CHECK_EXPECT(testobj_propget_d); - test_grfdex(grfdex, fdexNameCaseInsensitive); - *pid = DISPID_TESTOBJ_PROPGET; - return S_OK; - } - if(!strcmp_wa(bstrName, "propput")) { - CHECK_EXPECT(testobj_propput_d); - test_grfdex(grfdex, fdexNameCaseInsensitive); - *pid = DISPID_TESTOBJ_PROPPUT; - return S_OK; + typedef struct { + const char * const name; + DISPID pid; + BOOL *expect; + BOOL *called; + } dispid_t; + + dispid_t dispids[] = { + { "propget", DISPID_TESTOBJ_PROPGET, REF_EXPECT(testobj_propget_d) }, + { "propput", DISPID_TESTOBJ_PROPPUT, REF_EXPECT(testobj_propput_d) }, + { "rem", DISPID_TESTOBJ_KEYWORD, NULL }, + { "true", DISPID_TESTOBJ_KEYWORD, NULL }, + { "false", DISPID_TESTOBJ_KEYWORD, NULL }, + { "not", DISPID_TESTOBJ_KEYWORD, NULL }, + { "and", DISPID_TESTOBJ_KEYWORD, NULL }, + { "or", DISPID_TESTOBJ_KEYWORD, NULL }, + { "xor", DISPID_TESTOBJ_KEYWORD, NULL }, + { "eqv", DISPID_TESTOBJ_KEYWORD, NULL }, + { "imp", DISPID_TESTOBJ_KEYWORD, NULL }, + { "is", DISPID_TESTOBJ_KEYWORD, NULL }, + { "mod", DISPID_TESTOBJ_KEYWORD, NULL }, + { "call", DISPID_TESTOBJ_KEYWORD, NULL }, + { "dim", DISPID_TESTOBJ_KEYWORD, NULL }, + { "sub", DISPID_TESTOBJ_KEYWORD, NULL }, + { "function", DISPID_TESTOBJ_KEYWORD, NULL }, + { "get", DISPID_TESTOBJ_KEYWORD, NULL }, + { "let", DISPID_TESTOBJ_KEYWORD, NULL }, + { "const", DISPID_TESTOBJ_KEYWORD, NULL }, + { "if", DISPID_TESTOBJ_KEYWORD, NULL }, + { "else", DISPID_TESTOBJ_KEYWORD, NULL }, + { "elseif", DISPID_TESTOBJ_KEYWORD, NULL }, + { "end", DISPID_TESTOBJ_KEYWORD, NULL }, + { "then", DISPID_TESTOBJ_KEYWORD, NULL }, + { "exit", DISPID_TESTOBJ_KEYWORD, NULL }, + { "while", DISPID_TESTOBJ_KEYWORD, NULL }, + { "wend", DISPID_TESTOBJ_KEYWORD, NULL }, + { "do", DISPID_TESTOBJ_KEYWORD, NULL }, + { "loop", DISPID_TESTOBJ_KEYWORD, NULL }, + { "until", DISPID_TESTOBJ_KEYWORD, NULL }, + { "for", DISPID_TESTOBJ_KEYWORD, NULL }, + { "to", DISPID_TESTOBJ_KEYWORD, NULL }, + { "each", DISPID_TESTOBJ_KEYWORD, NULL }, + { "in", DISPID_TESTOBJ_KEYWORD, NULL }, + { "select", DISPID_TESTOBJ_KEYWORD, NULL }, + { "case", DISPID_TESTOBJ_KEYWORD, NULL }, + { "byref", DISPID_TESTOBJ_KEYWORD, NULL }, + { "byval", DISPID_TESTOBJ_KEYWORD, NULL }, + { "option", DISPID_TESTOBJ_KEYWORD, NULL }, + { "nothing", DISPID_TESTOBJ_KEYWORD, NULL }, + { "empty", DISPID_TESTOBJ_KEYWORD, NULL }, + { "null", DISPID_TESTOBJ_KEYWORD, NULL }, + { "class", DISPID_TESTOBJ_KEYWORD, NULL }, + { "set", DISPID_TESTOBJ_KEYWORD, NULL }, + { "new", DISPID_TESTOBJ_KEYWORD, NULL }, + { "public", DISPID_TESTOBJ_KEYWORD, NULL }, + { "private", DISPID_TESTOBJ_KEYWORD, NULL }, + { "next", DISPID_TESTOBJ_KEYWORD, NULL }, + { "on", DISPID_TESTOBJ_KEYWORD, NULL }, + { "resume", DISPID_TESTOBJ_KEYWORD, NULL }, + { "goto", DISPID_TESTOBJ_KEYWORD, NULL }, + }; + + for (int i = 0; i < ARRAY_SIZE(dispids); i++) { + if(!stricmp_wa(bstrName, dispids[i].name)) { + dispid_t *d = &dispids[i]; + if(d->expect) { + ok(*d->expect, "unexpected call %s\n", d->name); + *d->called = TRUE; + *d->expect = FALSE; + } + test_grfdex(grfdex, fdexNameCaseInsensitive); + *pid = d->pid; + return S_OK; + } }
ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName)); @@ -831,6 +905,11 @@ static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg)); ok(V_I2(pdp->rgvarg) == 1, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg)); return S_OK; + + case DISPID_TESTOBJ_KEYWORD: + V_VT(pvarRes) = VT_I2; + V_I2(pvarRes) = 10; + return S_OK; }
ok(0, "unexpected call %d\n", id);
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46318 Signed-off-by: Brendan McGrath brendan@redmandi.com --- dlls/vbscript/tests/run.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 103082fc042..49066ceb6b0 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -2334,6 +2334,10 @@ static void run_tests(void) parse_script_a("Option Explicit\nset test.setobj = testObj"); CHECK_CALLED(global_setobj_i);
+ hres = parse_script_ar("dim x\nx = testObj.rem"); + todo_wine + ok(hres == S_OK, "use of 'rem' as dot identifier failed: %x08\n", hres); + SET_EXPECT(testobj_propget_d); SET_EXPECT(testobj_propget_i); parse_script_a("dim x\nx = testObj.propget");
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com