[PATCH 0/1] MR10486: vbscript: Fix error character positions for Exit and Dim statements.
For invalid Exit statements (e.g. Exit Do outside a Do loop), point the error position at the keyword after Exit (Do/For/Function/Property/Sub) instead of at Exit itself, matching Windows. For duplicate Dim declarations, store the identifier location in dim_decl_t and use it as the error position, so the error points at the duplicate name instead of the Dim keyword. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10486
From: Francis De Brabandere <francisdb@gmail.com> For invalid Exit statements (e.g. Exit Do outside a Do loop), point the error position at the keyword after Exit (Do/For/Function/Property/Sub) instead of at Exit itself, matching Windows. For duplicate Dim declarations, store the identifier location in dim_decl_t and use it as the error position, so the error points at the duplicate name instead of the Dim keyword. --- dlls/vbscript/compile.c | 1 + dlls/vbscript/parse.h | 1 + dlls/vbscript/parser.y | 27 ++++++++++++++------------- dlls/vbscript/tests/run.c | 4 ++-- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 8c82d849a1b..be833d7022a 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1141,6 +1141,7 @@ static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat) while(1) { if(lookup_dim_decls(ctx, dim_decl->name) || lookup_args_name(ctx, dim_decl->name) || lookup_const_decls(ctx, dim_decl->name, FALSE)) { + ctx->loc = dim_decl->loc; return MAKE_VBSERROR(VBSE_NAME_REDEFINED); } diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index 71fc713ea9c..cacdd4b38f1 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -161,6 +161,7 @@ typedef struct _dim_list_t { typedef struct _dim_decl_t { const WCHAR *name; + unsigned loc; BOOL is_array; BOOL is_public; /* Used only for class members. */ dim_list_t *dims; diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index c1a5b944268..ef4d71c1e42 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -62,7 +62,7 @@ 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_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,unsigned,BOOL,dim_list_t*); static dim_list_t *new_dim(parser_ctx_t*,unsigned,dim_list_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*); @@ -231,11 +231,11 @@ SimpleStatement 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; } + | tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 0, @2); CHECK_ERROR; } + | tEXIT tFOR { $$ = new_statement(ctx, STAT_EXITFOR, 0, @2); CHECK_ERROR; } + | tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0, @2); CHECK_ERROR; } + | tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 0, @2); CHECK_ERROR; } + | tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0, @2); 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; } @@ -265,9 +265,9 @@ MemberDeclList | MemberDecl ',' MemberDeclList { $1->next = $3; $$ = $1; } MemberDecl - : MemberIdentifier { $$ = new_dim_decl(ctx, $1, FALSE, NULL); CHECK_ERROR; } - | MemberIdentifier '(' DimList ')' { $$ = new_dim_decl(ctx, $1, TRUE, $3); CHECK_ERROR; } - | MemberIdentifier tEMPTYBRACKETS { $$ = new_dim_decl(ctx, $1, TRUE, NULL); CHECK_ERROR; } + : MemberIdentifier { $$ = new_dim_decl(ctx, $1, @1, FALSE, NULL); CHECK_ERROR; } + | MemberIdentifier '(' DimList ')' { $$ = new_dim_decl(ctx, $1, @1, TRUE, $3); CHECK_ERROR; } + | MemberIdentifier tEMPTYBRACKETS { $$ = new_dim_decl(ctx, $1, @1, TRUE, NULL); CHECK_ERROR; } ReDimDecl : tIdentifier '(' ArgumentList ')' { $$ = new_redim_decl(ctx, $1, $3); CHECK_ERROR; } @@ -281,9 +281,9 @@ DimDeclList | DimDecl ',' DimDeclList { $1->next = $3; $$ = $1; } DimDecl - : Identifier { $$ = new_dim_decl(ctx, $1, FALSE, NULL); CHECK_ERROR; } - | Identifier '(' DimList ')' { $$ = new_dim_decl(ctx, $1, TRUE, $3); CHECK_ERROR; } - | Identifier tEMPTYBRACKETS { $$ = new_dim_decl(ctx, $1, TRUE, NULL); CHECK_ERROR; } + : Identifier { $$ = new_dim_decl(ctx, $1, @1, FALSE, NULL); CHECK_ERROR; } + | Identifier '(' DimList ')' { $$ = new_dim_decl(ctx, $1, @1, TRUE, $3); CHECK_ERROR; } + | Identifier tEMPTYBRACKETS { $$ = new_dim_decl(ctx, $1, @1, TRUE, NULL); CHECK_ERROR; } DimList : IntegerValue { $$ = new_dim(ctx, $1, NULL); } @@ -863,7 +863,7 @@ static statement_t *new_set_statement(parser_ctx_t *ctx, unsigned loc, expressio return &stat->stat; } -static dim_decl_t *new_dim_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL is_array, dim_list_t *dims) +static dim_decl_t *new_dim_decl(parser_ctx_t *ctx, const WCHAR *name, unsigned loc, BOOL is_array, dim_list_t *dims) { dim_decl_t *decl; @@ -872,6 +872,7 @@ static dim_decl_t *new_dim_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL is_ar return NULL; decl->name = name; + decl->loc = loc; decl->is_array = is_array; decl->dims = dims; decl->next = NULL; diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index d3aebff098a..c9bf089a3c4 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -2890,7 +2890,7 @@ static void test_parse_errors(void) { /* Name redefined - error 1041 */ L"Dim a\nDim a\n", - 1, -4, + 1, 4, NULL, S_OK, 1041 }, { @@ -2980,7 +2980,7 @@ static void test_parse_errors(void) { /* Invalid 'exit' statement - error 1039 */ L"Exit Do\n", - 0, -5, + 0, 5, NULL, S_OK, 1039 }, { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10486
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)