vbscript: Allow omitting optional function parameters in call expressions.
This commit is contained in:
parent
679ddf24d4
commit
3873c93891
|
@ -522,6 +522,8 @@ static HRESULT compile_expression(compile_ctx_t *ctx, expression_t *expr)
|
||||||
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_nequal);
|
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_nequal);
|
||||||
case EXPR_NEW:
|
case EXPR_NEW:
|
||||||
return push_instr_str(ctx, OP_new, ((string_expression_t*)expr)->value);
|
return push_instr_str(ctx, OP_new, ((string_expression_t*)expr)->value);
|
||||||
|
case EXPR_NOARG:
|
||||||
|
return push_instr_int(ctx, OP_hres, DISP_E_PARAMNOTFOUND);
|
||||||
case EXPR_NOT:
|
case EXPR_NOT:
|
||||||
return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_not);
|
return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_not);
|
||||||
case EXPR_NOTHING:
|
case EXPR_NOTHING:
|
||||||
|
|
|
@ -1366,6 +1366,18 @@ static HRESULT interp_nothing(exec_ctx_t *ctx)
|
||||||
return stack_push(ctx, &v);
|
return stack_push(ctx, &v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT interp_hres(exec_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
const unsigned arg = ctx->instr->arg1.uint;
|
||||||
|
VARIANT v;
|
||||||
|
|
||||||
|
TRACE("%d\n", arg);
|
||||||
|
|
||||||
|
V_VT(&v) = VT_ERROR;
|
||||||
|
V_ERROR(&v) = arg;
|
||||||
|
return stack_push(ctx, &v);
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT interp_not(exec_ctx_t *ctx)
|
static HRESULT interp_not(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
variant_val_t val;
|
variant_val_t val;
|
||||||
|
|
|
@ -42,6 +42,7 @@ typedef enum {
|
||||||
EXPR_NEG,
|
EXPR_NEG,
|
||||||
EXPR_NEQUAL,
|
EXPR_NEQUAL,
|
||||||
EXPR_NEW,
|
EXPR_NEW,
|
||||||
|
EXPR_NOARG, /* not a real expression */
|
||||||
EXPR_NOT,
|
EXPR_NOT,
|
||||||
EXPR_NOTHING,
|
EXPR_NOTHING,
|
||||||
EXPR_NULL,
|
EXPR_NULL,
|
||||||
|
|
|
@ -128,7 +128,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
|
||||||
%type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
|
%type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
|
||||||
%type <expression> ConstExpression NumericLiteralExpression
|
%type <expression> ConstExpression NumericLiteralExpression
|
||||||
%type <member> MemberExpression
|
%type <member> MemberExpression
|
||||||
%type <expression> Arguments_opt ArgumentList_opt Step_opt ExpressionList
|
%type <expression> Arguments_opt ArgumentList ArgumentList_opt Step_opt ExpressionList
|
||||||
%type <boolean> OptionExplicit_opt DoType
|
%type <boolean> OptionExplicit_opt DoType
|
||||||
%type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
|
%type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
|
||||||
%type <func_decl> FunctionDecl PropertyDecl
|
%type <func_decl> FunctionDecl PropertyDecl
|
||||||
|
@ -279,11 +279,16 @@ CaseClausules
|
||||||
|
|
||||||
Arguments_opt
|
Arguments_opt
|
||||||
: EmptyBrackets_opt { $$ = NULL; }
|
: EmptyBrackets_opt { $$ = NULL; }
|
||||||
| '(' ExpressionList ')' { $$ = $2; }
|
| '(' ArgumentList ')' { $$ = $2; }
|
||||||
|
|
||||||
ArgumentList_opt
|
ArgumentList_opt
|
||||||
: EmptyBrackets_opt { $$ = NULL; }
|
: EmptyBrackets_opt { $$ = NULL; }
|
||||||
| ExpressionList { $$ = $1; }
|
| ArgumentList { $$ = $1; }
|
||||||
|
|
||||||
|
ArgumentList
|
||||||
|
: Expression { $$ = $1; }
|
||||||
|
| Expression ',' ArgumentList { $1->next = $3; $$ = $1; }
|
||||||
|
| ',' ArgumentList { $$ = new_expression(ctx, EXPR_NOARG, 0); CHECK_ERROR; $$->next = $2; }
|
||||||
|
|
||||||
EmptyBrackets_opt
|
EmptyBrackets_opt
|
||||||
: /* empty */
|
: /* empty */
|
||||||
|
|
|
@ -92,6 +92,7 @@ DEFINE_EXPECT(global_propargput_d);
|
||||||
DEFINE_EXPECT(global_propargput_i);
|
DEFINE_EXPECT(global_propargput_i);
|
||||||
DEFINE_EXPECT(global_propargput1_d);
|
DEFINE_EXPECT(global_propargput1_d);
|
||||||
DEFINE_EXPECT(global_propargput1_i);
|
DEFINE_EXPECT(global_propargput1_i);
|
||||||
|
DEFINE_EXPECT(global_testoptionalarg_i);
|
||||||
DEFINE_EXPECT(collectionobj_newenum_i);
|
DEFINE_EXPECT(collectionobj_newenum_i);
|
||||||
DEFINE_EXPECT(Next);
|
DEFINE_EXPECT(Next);
|
||||||
DEFINE_EXPECT(GetWindow);
|
DEFINE_EXPECT(GetWindow);
|
||||||
|
@ -115,6 +116,7 @@ DEFINE_EXPECT(EnableModeless);
|
||||||
#define DISPID_GLOBAL_DOUBLEASSTRING 1014
|
#define DISPID_GLOBAL_DOUBLEASSTRING 1014
|
||||||
#define DISPID_GLOBAL_TESTARRAY 1015
|
#define DISPID_GLOBAL_TESTARRAY 1015
|
||||||
#define DISPID_GLOBAL_THROWINT 1016
|
#define DISPID_GLOBAL_THROWINT 1016
|
||||||
|
#define DISPID_GLOBAL_TESTOPTIONALARG 1017
|
||||||
|
|
||||||
#define DISPID_TESTOBJ_PROPGET 2000
|
#define DISPID_TESTOBJ_PROPGET 2000
|
||||||
#define DISPID_TESTOBJ_PROPPUT 2001
|
#define DISPID_TESTOBJ_PROPPUT 2001
|
||||||
|
@ -1007,6 +1009,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
|
||||||
*pid = DISPID_GLOBAL_THROWINT;
|
*pid = DISPID_GLOBAL_THROWINT;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
if(!strcmp_wa(bstrName, "testOptionalArg")) {
|
||||||
|
test_grfdex(grfdex, fdexNameCaseInsensitive);
|
||||||
|
*pid = DISPID_GLOBAL_TESTOPTIONALARG;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if(strict_dispid_check && strcmp_wa(bstrName, "x"))
|
if(strict_dispid_check && strcmp_wa(bstrName, "x"))
|
||||||
ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
|
ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
|
||||||
|
@ -1044,7 +1051,7 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DISPID_GLOBAL_TRACE:
|
case DISPID_GLOBAL_TRACE:
|
||||||
ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
|
ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
|
||||||
ok(pdp != NULL, "pdp == NULL\n");
|
ok(pdp != NULL, "pdp == NULL\n");
|
||||||
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||||
|
@ -1320,6 +1327,30 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
|
||||||
|
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DISPID_GLOBAL_TESTOPTIONALARG: {
|
||||||
|
VARIANT *v;
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
CHECK_EXPECT(global_testoptionalarg_i);
|
||||||
|
|
||||||
|
ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
|
||||||
|
ok(pdp != NULL, "pdp == NULL\n");
|
||||||
|
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||||
|
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||||
|
ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
|
||||||
|
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||||
|
ok(!pvarRes, "pvarRes != NULL\n");
|
||||||
|
ok(pei != NULL, "pei == NULL\n");
|
||||||
|
|
||||||
|
ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
|
||||||
|
opt = V_I2(pdp->rgvarg);
|
||||||
|
ok(opt == 1 || opt == 2, "opt = %d\n", opt);
|
||||||
|
v = pdp->rgvarg+pdp->cArgs-opt;
|
||||||
|
ok(V_VT(v) == VT_ERROR, "V_VT(v) = %d\n", V_VT(v));
|
||||||
|
ok(V_ERROR(v) == DISP_E_PARAMNOTFOUND, "V_ERROR(v) = %08x\n", V_ERROR(v));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ok(0, "unexpected call %d\n", id);
|
ok(0, "unexpected call %d\n", id);
|
||||||
|
@ -2075,6 +2106,18 @@ static void run_tests(void)
|
||||||
hres = parse_script_ar("throwInt(&h80004001&)");
|
hres = parse_script_ar("throwInt(&h80004001&)");
|
||||||
ok(hres == MAKE_VBSERROR(445), "hres = %08x\n", hres);
|
ok(hres == MAKE_VBSERROR(445), "hres = %08x\n", hres);
|
||||||
|
|
||||||
|
SET_EXPECT(global_testoptionalarg_i);
|
||||||
|
parse_script_a("call testOptionalArg(1,,2)");
|
||||||
|
CHECK_CALLED(global_testoptionalarg_i);
|
||||||
|
|
||||||
|
SET_EXPECT(global_testoptionalarg_i);
|
||||||
|
parse_script_a("call testOptionalArg(,1,1)");
|
||||||
|
CHECK_CALLED(global_testoptionalarg_i);
|
||||||
|
|
||||||
|
SET_EXPECT(global_testoptionalarg_i);
|
||||||
|
parse_script_a("testOptionalArg 1,,2");
|
||||||
|
CHECK_CALLED(global_testoptionalarg_i);
|
||||||
|
|
||||||
strict_dispid_check = FALSE;
|
strict_dispid_check = FALSE;
|
||||||
|
|
||||||
SET_EXPECT(testobj_value_i);
|
SET_EXPECT(testobj_value_i);
|
||||||
|
|
|
@ -234,6 +234,7 @@ typedef enum {
|
||||||
X(empty, 1, 0, 0) \
|
X(empty, 1, 0, 0) \
|
||||||
X(enumnext, 0, ARG_ADDR, ARG_BSTR) \
|
X(enumnext, 0, ARG_ADDR, ARG_BSTR) \
|
||||||
X(equal, 1, 0, 0) \
|
X(equal, 1, 0, 0) \
|
||||||
|
X(hres, 1, ARG_UINT, 0) \
|
||||||
X(errmode, 1, ARG_INT, 0) \
|
X(errmode, 1, ARG_INT, 0) \
|
||||||
X(eqv, 1, 0, 0) \
|
X(eqv, 1, 0, 0) \
|
||||||
X(exp, 1, 0, 0) \
|
X(exp, 1, 0, 0) \
|
||||||
|
|
Loading…
Reference in New Issue