Didn't build here, did you forget to add dependency on ole32?

ccache gcc -c -I. -I. -I../../include -I../../include  -D__WINESRC__
-D_REENTRANT -fPIC -Wall -pipe -fno-strict-aliasing
-Wdeclaration-after-statement -Wempty-body -Wstrict-prototypes
-Wtype-limits -Wwrite-strings -Wpointer-arith -Wlogical-op  -g -O0
-Werror -Wno-unused-but-set-variable -Wno-unused-but-set-parameter  -o
vwin32.o vwin32.c
global.o: In function `create_object':
/home/bob/wineslave.dir/sandbox/slave/runtests-default/build/dlls/vbscript/global.c:74:
undefined reference to `CLSIDFromProgID'
/home/bob/wineslave.dir/sandbox/slave/runtests-default/build/dlls/vbscript/global.c:92:
undefined reference to `CoGetClassObject'
/home/bob/wineslave.dir/sandbox/slave/runtests-default/build/dlls/vbscript/global.c:114:
undefined reference to `CoTaskMemFree'
collect2: ld returned 1 exit status
winegcc: ccache failed
make[1]: *** [vbscript.dll.so] Error 2


---------- Forwarded message ----------
From:  <[email protected]>
Date: Thu, Sep 22, 2011 at 8:01 AM
Subject: Re: 79194: [PATCH 10/13] vbscript: Added CreateObject implementation
To: [email protected]


This is an experimental automated build and test service.
Please feel free to ignore this email while we work the kinks out.

For more info about this message, see http://wiki.winehq.org/BuildBot

The Buildbot has detected a failed build on builder runtests-default
while building Wine.
Full details are available at:
http://buildbot.kegel.com/builders/runtests-default/builds/26 (though
maybe not for long, as I'm still reinstalling the buildbot
periodically while experimenting)
BUILD FAILED: failed shell_2

Errors:
make: *** [dlls/vbscript] Error 2
From: Jacek Caban <[email protected]>
Subject: [PATCH 01/13] vbscript: Added for..to statement parser implementation
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:22:40 +0200

---
  dlls/vbscript/lex.c    |    6 ++++++
  dlls/vbscript/parse.h  |   10 ++++++++++
  dlls/vbscript/parser.y |   28 ++++++++++++++++++++++++++--
  3 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index f42d2fd..ac3d65e 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -44,6 +44,7 @@ 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};
@@ -68,9 +69,11 @@ 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 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};
@@ -99,6 +102,7 @@ static const struct {
     {exitW,      tEXIT},
     {explicitW,  tEXPLICIT},
     {falseW,     tFALSE},
+    {forW,       tFOR},
     {functionW,  tFUNCTION},
     {getW,       tGET},
     {gotoW,      tGOTO},
@@ -123,9 +127,11 @@ static const struct {
     {remW,       tREM},
     {resumeW,    tRESUME},
     {setW,       tSET},
+    {stepW,      tSTEP},
     {stopW,      tSTOP},
     {subW,       tSUB},
     {thenW,      tTHEN},
+    {toW,        tTO},
     {trueW,      tTRUE},
     {untilW,     tUNTIL},
     {wendW,      tWEND},
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 8e4be57..a5bd505 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -106,6 +106,7 @@ typedef enum {
     STAT_EXITFUNC,
     STAT_EXITPROP,
     STAT_EXITSUB,
+    STAT_FORTO,
     STAT_FUNC,
     STAT_IF,
     STAT_ONERROR,
@@ -198,6 +199,15 @@ typedef struct {
 
 typedef struct {
     statement_t stat;
+    const WCHAR *identifier;
+    expression_t *from_expr;
+    expression_t *to_expr;
+    expression_t *step_expr;
+    statement_t *body;
+} forto_statement_t;
+
+typedef struct {
+    statement_t stat;
     BOOL resume_next;
 } onerror_statement_t;
 
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 8435e92..3b30051 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -52,6 +52,7 @@ static statement_t 
*new_assign_statement(parser_ctx_t*,member_expression_t*,expr
 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_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);
@@ -102,7 +103,7 @@ static statement_t 
*link_statements(statement_t*,statement_t*);
 %token tIS tLTEQ tGTEQ tMOD
 %token tCALL tDIM tSUB tFUNCTION tPROPERTY tGET tLET tCONST
 %token tIF tELSE tELSEIF tEND tTHEN tEXIT
-%token tWHILE tWEND tDO tLOOP tUNTIL
+%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tSTEP
 %token tBYREF tBYVAL
 %token tOPTION tEXPLICIT
 %token tSTOP
@@ -118,7 +119,7 @@ static statement_t 
*link_statements(statement_t*,statement_t*);
 %type <expression> ConcatExpression AdditiveExpression ModExpression 
IntdivExpression MultiplicativeExpression ExpExpression
 %type <expression> NotExpression UnaryExpression AndExpression OrExpression 
XorExpression EqvExpression
 %type <member> MemberExpression
-%type <expression> Arguments_opt ArgumentList_opt ArgumentList
+%type <expression> Arguments_opt ArgumentList_opt ArgumentList Step_opt
 %type <bool> OptionExplicit_opt DoType
 %type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
 %type <func_decl> FunctionDecl PropertyDecl
@@ -186,6 +187,8 @@ SimpleStatement
     | 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 tIdentifier '=' Expression tTO Expression Step_opt tNL 
StatementsNl_opt tNEXT
+                                            { $$ = new_forto_statement(ctx, 
$2, $4, $6, $7, $9); CHECK_ERROR; }
 
 MemberExpression
     : tIdentifier                           { $$ = new_member_expression(ctx, 
NULL, $1); CHECK_ERROR; }
@@ -206,6 +209,10 @@ DoType
     : tWHILE        { $$ = TRUE; }
     | tUNTIL        { $$ = FALSE; }
 
+Step_opt
+    : /* empty */                           { $$ = NULL;}
+    | tSTEP Expression                      { $$ = $2; }
+
 IfStatement
     : tIF Expression tTHEN tNL StatementsNl ElseIfs_opt Else_opt tEND tIF
                                             { $$ = new_if_statement(ctx, $2, 
$5, $6, $7); CHECK_ERROR; }
@@ -626,6 +633,23 @@ 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,
+        expression_t *to_expr, expression_t *step_expr, statement_t *body)
+{
+    forto_statement_t *stat;
+
+    stat = new_statement(ctx, STAT_FORTO, sizeof(*stat));
+    if(!stat)
+        return NULL;
+
+    stat->identifier = identifier;
+    stat->from_expr = from_expr;
+    stat->to_expr = to_expr;
+    stat->step_expr = step_expr;
+    stat->body = body;
+    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,
         statement_t *else_stat)
 {

From: Jacek Caban <[email protected]>
Subject: [PATCH 02/13] vbscript: Added for..to statement compiler implementation
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:23:10 +0200

---
  dlls/vbscript/compile.c  |   77 
++++++++++++++++++++++++++++++++++++++++++++++
  dlls/vbscript/interp.c   |   30 ++++++++++++++++++
  dlls/vbscript/vbscript.h |    4 ++
  3 files changed, 111 insertions(+), 0 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 9cfe45b..1f1f041 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -169,6 +169,18 @@ static HRESULT push_instr_int(compile_ctx_t *ctx, vbsop_t 
op, LONG arg)
     return S_OK;
 }
 
+static HRESULT push_instr_uint(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
+{
+    unsigned ret;
+
+    ret = push_instr(ctx, op);
+    if(ret == -1)
+        return E_OUTOFMEMORY;
+
+    instr_ptr(ctx, ret)->arg1.uint = arg;
+    return S_OK;
+}
+
 static HRESULT push_instr_addr(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
 {
     unsigned ret;
@@ -603,6 +615,68 @@ static HRESULT compile_dowhile_statement(compile_ctx_t 
*ctx, while_statement_t *
     return S_OK;
 }
 
+static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t 
*stat)
+{
+    unsigned step_instr, instr;
+    BSTR identifier;
+    HRESULT hres;
+
+    identifier = alloc_bstr_arg(ctx, stat->identifier);
+    if(!identifier)
+        return E_OUTOFMEMORY;
+
+    hres = compile_expression(ctx, stat->from_expr);
+    if(FAILED(hres))
+        return hres;
+
+    instr = push_instr(ctx, OP_assign_ident);
+    if(instr == -1)
+        return E_OUTOFMEMORY;
+    instr_ptr(ctx, instr)->arg1.bstr = identifier;
+
+    hres = compile_expression(ctx, stat->to_expr);
+    if(FAILED(hres))
+        return hres;
+
+    if(push_instr(ctx, OP_val) == -1)
+        return E_OUTOFMEMORY;
+
+    if(stat->step_expr) {
+        hres = compile_expression(ctx, stat->step_expr);
+        if(FAILED(hres))
+            return hres;
+
+        if(push_instr(ctx, OP_val) == -1)
+            return E_OUTOFMEMORY;
+    }else {
+        hres = push_instr_int(ctx, OP_short, 1);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    step_instr = push_instr(ctx, OP_step);
+    if(step_instr == -1)
+        return E_OUTOFMEMORY;
+    instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
+
+    hres = compile_statement(ctx, stat->body);
+    if(FAILED(hres))
+        return hres;
+
+    instr = push_instr(ctx, OP_incc);
+    if(instr == -1)
+        return E_OUTOFMEMORY;
+    instr_ptr(ctx, instr)->arg1.bstr = identifier;
+
+    hres = push_instr_addr(ctx, OP_jmp, step_instr);
+    if(FAILED(hres))
+        return hres;
+
+    instr_ptr(ctx, step_instr)->arg1.uint = ctx->instr_cnt;
+
+    return push_instr_uint(ctx, OP_pop, 2);
+}
+
 static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t 
*stat, BOOL is_set)
 {
     HRESULT hres;
@@ -799,6 +873,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, 
statement_t *stat)
         case STAT_EXITSUB:
             hres = compile_exitsub_statement(ctx);
             break;
+        case STAT_FORTO:
+            hres = compile_forto_statement(ctx, (forto_statement_t*)stat);
+            break;
         case STAT_FUNC:
             hres = compile_function_statement(ctx, 
(function_statement_t*)stat);
             break;
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index c2ffd98..1327c17 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -682,6 +682,22 @@ static HRESULT interp_const(exec_ctx_t *ctx)
     return add_dynamic_var(ctx, arg, TRUE, val.v, val.owned);
 }
 
+static HRESULT interp_val(exec_ctx_t *ctx)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT interp_pop(exec_ctx_t *ctx)
+{
+    const unsigned n = ctx->instr->arg1.uint;
+
+    TRACE("%u\n", n);
+
+    stack_popn(ctx, n);
+    return S_OK;
+}
+
 static HRESULT interp_new(exec_ctx_t *ctx)
 {
     const WCHAR *arg = ctx->instr->arg1.bstr;
@@ -710,6 +726,13 @@ static HRESULT interp_new(exec_ctx_t *ctx)
     return stack_push(ctx, &v);
 }
 
+static HRESULT interp_step(exec_ctx_t *ctx)
+{
+    const BSTR ident = ctx->instr->arg2.bstr;
+    FIXME("%s\n", debugstr_w(ident));
+    return E_NOTIMPL;
+}
+
 static HRESULT interp_jmp(exec_ctx_t *ctx)
 {
     const unsigned arg = ctx->instr->arg1.uint;
@@ -1439,6 +1462,13 @@ static HRESULT interp_neg(exec_ctx_t *ctx)
     return stack_push(ctx, &v);
 }
 
+static HRESULT interp_incc(exec_ctx_t *ctx)
+{
+    const BSTR ident = ctx->instr->arg1.bstr;
+    FIXME("%s\n", debugstr_w(ident));
+    return E_NOTIMPL;
+}
+
 static const instr_func_t op_funcs[] = {
 #define X(x,n,a,b) interp_ ## x,
 OP_LIST
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index bd55719..4b0a569 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -199,6 +199,7 @@ typedef enum {
     X(icallv,         1, ARG_BSTR,    ARG_UINT)   \
     X(idiv,           1, 0,           0)          \
     X(imp,            1, 0,           0)          \
+    X(incc,           1, ARG_BSTR,    0)          \
     X(is,             1, 0,           0)          \
     X(jmp,            0, ARG_ADDR,    0)          \
     X(jmp_false,      0, ARG_ADDR,    0)          \
@@ -218,13 +219,16 @@ typedef enum {
     X(nothing,        1, 0,           0)          \
     X(null,           1, 0,           0)          \
     X(or,             1, 0,           0)          \
+    X(pop,            1, ARG_UINT,    0)          \
     X(ret,            0, 0,           0)          \
     X(set_ident,      1, ARG_BSTR,    0)          \
     X(set_member,     1, ARG_BSTR,    0)          \
     X(short,          1, ARG_INT,     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(xor,            1, 0,           0)
 
 typedef enum {

From: Jacek Caban <[email protected]>
Subject: [PATCH 03/13] vbscript: Added interp_val implementation
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:23:25 +0200

---
  dlls/vbscript/interp.c |   20 ++++++++++++++++++--
  1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 1327c17..5e41845 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -684,8 +684,24 @@ static HRESULT interp_const(exec_ctx_t *ctx)
 
 static HRESULT interp_val(exec_ctx_t *ctx)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    variant_val_t val;
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    hres = stack_pop_val(ctx, &val);
+    if(FAILED(hres))
+        return hres;
+
+    if(!val.owned) {
+        V_VT(&v) = VT_EMPTY;
+        hres = VariantCopy(&v, val.v);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    return stack_push(ctx, val.owned ? val.v : &v);
 }
 
 static HRESULT interp_pop(exec_ctx_t *ctx)

From: Jacek Caban <[email protected]>
Subject: [PATCH 04/13] vbscript: Added interp_step implementation
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:23:51 +0200

---
  dlls/vbscript/interp.c |   41 +++++++++++++++++++++++++++++++++++++++--
  1 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 5e41845..c95183d 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -245,6 +245,12 @@ static inline VARIANT *stack_pop(exec_ctx_t *ctx)
     return ctx->stack + --ctx->top;
 }
 
+static inline VARIANT *stack_top(exec_ctx_t *ctx, unsigned n)
+{
+    assert(ctx->top >= n);
+    return ctx->stack + (ctx->top-n-1);
+}
+
 static HRESULT stack_push(exec_ctx_t *ctx, VARIANT *v)
 {
     if(ctx->stack_size == ctx->top) {
@@ -745,8 +751,39 @@ static HRESULT interp_new(exec_ctx_t *ctx)
 static HRESULT interp_step(exec_ctx_t *ctx)
 {
     const BSTR ident = ctx->instr->arg2.bstr;
-    FIXME("%s\n", debugstr_w(ident));
-    return E_NOTIMPL;
+    BOOL gteq_zero;
+    VARIANT zero;
+    ref_t ref;
+    HRESULT hres;
+
+    TRACE("%s\n", debugstr_w(ident));
+
+    V_VT(&zero) = VT_I2;
+    V_I2(&zero) = 0;
+    hres = VarCmp(stack_top(ctx, 0), &zero, ctx->script->lcid, 0);
+    if(FAILED(hres))
+        return hres;
+
+    gteq_zero = hres == VARCMP_GT || hres == VARCMP_EQ;
+
+    hres = lookup_identifier(ctx, ident, VBDISP_ANY, &ref);
+    if(FAILED(hres))
+        return hres;
+
+    if(ref.type != REF_VAR) {
+        FIXME("%s is not REF_VAR\n", debugstr_w(ident));
+        return E_FAIL;
+    }
+
+    hres = VarCmp(ref.u.v, stack_top(ctx, 1), ctx->script->lcid, 0);
+    if(FAILED(hres))
+        return hres;
+
+    if(hres == VARCMP_EQ || hres == (gteq_zero ? VARCMP_LT : VARCMP_GT))
+        ctx->instr++;
+    else
+        instr_jmp(ctx, ctx->instr->arg1.uint);
+    return S_OK;
 }
 
 static HRESULT interp_jmp(exec_ctx_t *ctx)

From: Jacek Caban <[email protected]>
Subject: [PATCH 05/13] vbscript: Added interp_incc implementation
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:24:05 +0200

---
  dlls/vbscript/interp.c |   24 ++++++++++++++++++++++--
  1 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index c95183d..08ea83e 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -1518,8 +1518,28 @@ static HRESULT interp_neg(exec_ctx_t *ctx)
 static HRESULT interp_incc(exec_ctx_t *ctx)
 {
     const BSTR ident = ctx->instr->arg1.bstr;
-    FIXME("%s\n", debugstr_w(ident));
-    return E_NOTIMPL;
+    VARIANT v;
+    ref_t ref;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    hres = lookup_identifier(ctx, ident, VBDISP_LET, &ref);
+    if(FAILED(hres))
+        return hres;
+
+    if(ref.type != REF_VAR) {
+        FIXME("ref.type is not REF_VAR\n");
+        return E_FAIL;
+    }
+
+    hres = VarAdd(stack_top(ctx, 0), ref.u.v, &v);
+    if(FAILED(hres))
+        return hres;
+
+    VariantClear(ref.u.v);
+    *ref.u.v = v;
+    return S_OK;
 }
 
 static const instr_func_t op_funcs[] = {

From: Jacek Caban <[email protected]>
Subject: [PATCH 06/13] vbscript: Added for..in statement tests
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:24:20 +0200

---
  dlls/vbscript/tests/lang.vbs |   56 
+++++++++++++++++++++++++++++++++++++++++-
  1 files changed, 55 insertions(+), 1 deletions(-)

diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 2d712f5..3b3ad50 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -18,7 +18,7 @@
 
 Option Explicit
 
-dim x, y
+dim x, y, z
 
 call ok(true, "true is not true?")
 ok true, "true is not true?"
@@ -333,6 +333,60 @@ do
     ok false, "exit do didn't work"
 loop while true
 
+y = "for1:"
+for x = 5 to 8
+    y = y & " " & x
+next
+Call ok(y = "for1: 5 6 7 8", "y = " & y)
+
+y = "for2:"
+for x = 5 to 8 step 2
+    y = y & " " & x
+next
+Call ok(y = "for2: 5 7", "y = " & y)
+
+y = "for3:"
+x = 2
+for x = x+3 to 8
+    y = y & " " & x
+next
+Call ok(y = "for3: 5 6 7 8", "y = " & y)
+
+y = "for4:"
+for x = 5 to 4
+    y = y & " " & x
+next
+Call ok(y = "for4:", "y = " & y)
+
+y = "for5:"
+for x = 5 to 3 step true
+    y = y & " " & x
+next
+Call ok(y = "for5: 5 4 3", "y = " & y)
+
+y = "for6:"
+z = 4
+for x = 5 to z step 3-4
+    y = y & " " & x
+    z = 0
+next
+Call ok(y = "for6: 5 4", "y = " & y)
+
+y = "for7:"
+z = 1
+for x = 5 to 8 step z
+    y = y & " " & x
+    z = 2
+next
+Call ok(y = "for7: 5 6 7 8", "y = " & y)
+
+y = "for8:"
+for x = 5 to 8
+    y = y & " " & x
+    x = x+1
+next
+Call ok(y = "for8: 5 7", "y = " & y)
+
 if false then
 Sub testsub
     x = true

From: Jacek Caban <[email protected]>
Subject: [PATCH 07/13] vbscript: Added exit for statement support
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:24:44 +0200

---
  dlls/vbscript/compile.c      |   27 +++++++++++++++++++++++++--
  dlls/vbscript/parse.h        |    1 +
  dlls/vbscript/parser.y       |    1 +
  dlls/vbscript/tests/lang.vbs |    9 +++++++++
  4 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 1f1f041..153e9b0 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -39,6 +39,7 @@ typedef struct {
     unsigned labels_cnt;
 
     unsigned while_end_label;
+    unsigned for_end_label;
     unsigned sub_end_label;
     unsigned func_end_label;
     unsigned prop_end_label;
@@ -617,7 +618,7 @@ static HRESULT compile_dowhile_statement(compile_ctx_t 
*ctx, while_statement_t *
 
 static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t 
*stat)
 {
-    unsigned step_instr, instr;
+    unsigned step_instr, instr, prev_label;
     BSTR identifier;
     HRESULT hres;
 
@@ -654,10 +655,16 @@ static HRESULT compile_forto_statement(compile_ctx_t 
*ctx, forto_statement_t *st
             return hres;
     }
 
+    prev_label = ctx->for_end_label;
+    ctx->for_end_label = alloc_label(ctx);
+    if(ctx->for_end_label == -1)
+        return E_OUTOFMEMORY;
+
     step_instr = push_instr(ctx, OP_step);
     if(step_instr == -1)
         return E_OUTOFMEMORY;
     instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
+    instr_ptr(ctx, step_instr)->arg1.uint = ctx->for_end_label;
 
     hres = compile_statement(ctx, stat->body);
     if(FAILED(hres))
@@ -672,7 +679,8 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, 
forto_statement_t *st
     if(FAILED(hres))
         return hres;
 
-    instr_ptr(ctx, step_instr)->arg1.uint = ctx->instr_cnt;
+    label_set_addr(ctx, ctx->for_end_label);
+    ctx->for_end_label = prev_label;
 
     return push_instr_uint(ctx, OP_pop, 2);
 }
@@ -804,6 +812,16 @@ static HRESULT compile_exitdo_statement(compile_ctx_t *ctx)
     return push_instr_addr(ctx, OP_jmp, ctx->while_end_label);
 }
 
+static HRESULT compile_exitfor_statement(compile_ctx_t *ctx)
+{
+    if(ctx->for_end_label == -1) {
+        FIXME("Exit For outside For Loop\n");
+        return E_FAIL;
+    }
+
+    return push_instr_addr(ctx, OP_jmp, ctx->for_end_label);
+}
+
 static HRESULT compile_exitsub_statement(compile_ctx_t *ctx)
 {
     if(ctx->sub_end_label == -1) {
@@ -864,6 +882,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, 
statement_t *stat)
         case STAT_EXITDO:
             hres = compile_exitdo_statement(ctx);
             break;
+        case STAT_EXITFOR:
+            hres = compile_exitfor_statement(ctx);
+            break;
         case STAT_EXITFUNC:
             hres = compile_exitfunc_statement(ctx);
             break;
@@ -931,6 +952,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t 
*stat, function_t *f
     func->code_off = ctx->instr_cnt;
 
     ctx->while_end_label = -1;
+    ctx->for_end_label = -1;
     ctx->sub_end_label = -1;
     ctx->func_end_label = -1;
     ctx->prop_end_label = -1;
@@ -967,6 +989,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t 
*stat, function_t *f
         return hres;
 
     assert(ctx->while_end_label == -1);
+    assert(ctx->for_end_label == -1);
 
     if(ctx->sub_end_label != -1)
         label_set_addr(ctx, ctx->sub_end_label);
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index a5bd505..e58e7f3 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -103,6 +103,7 @@ typedef enum {
     STAT_DOUNTIL,
     STAT_DOWHILE,
     STAT_EXITDO,
+    STAT_EXITFOR,
     STAT_EXITFUNC,
     STAT_EXITPROP,
     STAT_EXITSUB,
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 3b30051..d6bda55 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -178,6 +178,7 @@ SimpleStatement
                                               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; }
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 3b3ad50..46a0330 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -387,6 +387,15 @@ for x = 5 to 8
 next
 Call ok(y = "for8: 5 7", "y = " & y)
 
+for x = 1.5 to 1
+    Call ok(false, "for..to called when unexpected")
+next
+
+for x = 1 to 100
+    exit for
+    Call ok(false, "exit for not escaped the loop?")
+next
+
 if false then
 Sub testsub
     x = true

From: Jacek Caban <[email protected]>
Subject: [PATCH 08/13] vbscript: Added support for DISPATCH_METHOD flags in 
invoke_builtin
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:25:06 +0200

---
  dlls/vbscript/vbdisp.c |   18 +++++++++++++-----
  1 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 96df71a..d083d74 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -139,14 +139,15 @@ static HRESULT invoke_builtin(vbdisp_t *This, const 
builtin_prop_t *prop, WORD f
             FIXME("property does not support DISPATCH_PROPERTYGET\n");
             return E_FAIL;
         }
-        /* FALLTHROUGH */
+        break;
     case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
-        if(arg_cnt(dp) < prop->min_args || arg_cnt(dp) > (prop->max_args ? 
prop->max_args : prop->min_args)) {
-            FIXME("invalid number of arguments\n");
+        break;
+    case DISPATCH_METHOD:
+        if(prop->flags & (BP_GET|BP_GETPUT)) {
+            FIXME("Call on property\n");
             return E_FAIL;
         }
-
-        return prop->proc(This, dp->rgvarg, dp->cArgs, res);
+        break;
     case DISPATCH_PROPERTYPUT:
         if(!(prop->flags & (BP_GET|BP_GETPUT))) {
             FIXME("property does not support DISPATCH_PROPERTYPUT\n");
@@ -159,6 +160,13 @@ static HRESULT invoke_builtin(vbdisp_t *This, const 
builtin_prop_t *prop, WORD f
         FIXME("unsupported flags %x\n", flags);
         return E_NOTIMPL;
     }
+
+    if(arg_cnt(dp) < prop->min_args || arg_cnt(dp) > (prop->max_args ? 
prop->max_args : prop->min_args)) {
+        FIXME("invalid number of arguments\n");
+        return E_FAIL;
+    }
+
+    return prop->proc(This, dp->rgvarg, dp->cArgs, res);
 }
 
 static BOOL run_terminator(vbdisp_t *This)

From: Jacek Caban <[email protected]>
Subject: [PATCH 09/13] vbscript: Lookup global object before host-provided 
objects
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:25:15 +0200

---
  dlls/vbscript/interp.c |   44 +++++++++++++++++++++++---------------------
  1 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 08ea83e..678b51a 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -126,12 +126,14 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR 
name, vbdisp_invoke_type_
     if(lookup_dynamic_vars(ctx->func->type == FUNC_GLOBAL ? 
ctx->script->global_vars : ctx->dynamic_vars, name, ref))
         return S_OK;
 
-    hres = disp_get_id(ctx->this_obj, name, invoke_type, TRUE, &id);
-    if(SUCCEEDED(hres)) {
-        ref->type = REF_DISP;
-        ref->u.d.disp = ctx->this_obj;
-        ref->u.d.id = id;
-        return S_OK;
+    if(ctx->func->type != FUNC_GLOBAL) {
+        hres = disp_get_id(ctx->this_obj, name, invoke_type, TRUE, &id);
+        if(SUCCEEDED(hres)) {
+            ref->type = REF_DISP;
+            ref->u.d.disp = ctx->this_obj;
+            ref->u.d.id = id;
+            return S_OK;
+        }
     }
 
     if(ctx->func->type != FUNC_GLOBAL && 
lookup_dynamic_vars(ctx->script->global_vars, name, ref))
@@ -145,8 +147,22 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR 
name, vbdisp_invoke_type_
         }
     }
 
+    if(!strcmpiW(name, errW)) {
+        ref->type = REF_OBJ;
+        ref->u.obj = (IDispatch*)&ctx->script->err_obj->IDispatchEx_iface;
+        return S_OK;
+    }
+
+    hres = vbdisp_get_id(ctx->script->global_obj, name, invoke_type, TRUE, 
&id);
+    if(SUCCEEDED(hres)) {
+        ref->type = REF_DISP;
+        ref->u.d.disp = 
(IDispatch*)&ctx->script->global_obj->IDispatchEx_iface;
+        ref->u.d.id = id;
+        return S_OK;
+    }
+
     LIST_FOR_EACH_ENTRY(item, &ctx->script->named_items, named_item_t, entry) {
-        if((item->flags & SCRIPTITEM_GLOBALMEMBERS) && item->disp != 
ctx->this_obj) {
+        if((item->flags & SCRIPTITEM_GLOBALMEMBERS)) {
             hres = disp_get_id(item->disp, name, invoke_type, FALSE, &id);
             if(SUCCEEDED(hres)) {
                 ref->type = REF_DISP;
@@ -180,20 +196,6 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR 
name, vbdisp_invoke_type_
         }
     }
 
-    if(!strcmpiW(name, errW)) {
-        ref->type = REF_OBJ;
-        ref->u.obj = (IDispatch*)&ctx->script->err_obj->IDispatchEx_iface;
-        return S_OK;
-    }
-
-    hres = vbdisp_get_id(ctx->script->global_obj, name, invoke_type, TRUE, 
&id);
-    if(SUCCEEDED(hres)) {
-        ref->type = REF_DISP;
-        ref->u.d.disp = 
(IDispatch*)&ctx->script->global_obj->IDispatchEx_iface;
-        ref->u.d.id = id;
-        return S_OK;
-    }
-
     ref->type = REF_NONE;
     return S_OK;
 }

From: Jacek Caban <[email protected]>
Subject: [PATCH 10/13] vbscript: Added CreateObject implementation
Message-Id: <[email protected]>
Date: Thu, 22 Sep 2011 14:25:27 +0200

---
  dlls/vbscript/global.c        |  134 
++++++++++++++++++++++++++++++++++++++++-
  dlls/vbscript/vbscript.c      |    3 +
  dlls/vbscript/vbscript.h      |    3 +
  dlls/vbscript/vbscript_main.c |    1 +
  4 files changed, 139 insertions(+), 2 deletions(-)

diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c
index 3d58ea7..5af7e16 100644
--- a/dlls/vbscript/global.c
+++ b/dlls/vbscript/global.c
@@ -19,10 +19,118 @@
 #include "vbscript.h"
 #include "vbscript_defs.h"
 
+#include "mshtmhst.h"
+#include "objsafe.h"
+
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
 
+#define VB_E_CANNOT_CREATE_OBJ 0x800a01ad
+
+/* Defined as extern in urlmon.idl, but not exported by uuid.lib */
+const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
+    {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
+
+static IInternetHostSecurityManager *get_sec_mgr(script_ctx_t *ctx)
+{
+    IInternetHostSecurityManager *secmgr;
+    IServiceProvider *sp;
+    HRESULT hres;
+
+    if(!ctx->site)
+        return NULL;
+
+    if(ctx->secmgr)
+        return ctx->secmgr;
+
+    hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, 
(void**)&sp);
+    if(FAILED(hres))
+        return NULL;
+
+    hres = IServiceProvider_QueryService(sp, 
&SID_SInternetHostSecurityManager, &IID_IInternetHostSecurityManager,
+            (void**)&secmgr);
+    IServiceProvider_Release(sp);
+    if(FAILED(hres))
+        return NULL;
+
+    return ctx->secmgr = secmgr;
+}
+
+static IUnknown *create_object(script_ctx_t *ctx, const WCHAR *progid)
+{
+    IInternetHostSecurityManager *secmgr = NULL;
+    IObjectWithSite *obj_site;
+    struct CONFIRMSAFETY cs;
+    IClassFactoryEx *cfex;
+    IClassFactory *cf;
+    DWORD policy_size;
+    BYTE *bpolicy;
+    IUnknown *obj;
+    DWORD policy;
+    GUID guid;
+    HRESULT hres;
+
+    hres = CLSIDFromProgID(progid, &guid);
+    if(FAILED(hres))
+        return NULL;
+
+    TRACE("GUID %s\n", debugstr_guid(&guid));
+
+    if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) {
+        secmgr = get_sec_mgr(ctx);
+        if(!secmgr)
+            return NULL;
+
+        policy = 0;
+        hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, 
URLACTION_ACTIVEX_RUN,
+                (BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 
0);
+        if(FAILED(hres) || policy != URLPOLICY_ALLOW)
+            return NULL;
+    }
+
+    hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, 
NULL, &IID_IClassFactory, (void**)&cf);
+    if(FAILED(hres))
+        return NULL;
+
+    hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, 
(void**)&cfex);
+    if(SUCCEEDED(hres)) {
+        FIXME("Use IClassFactoryEx\n");
+        IClassFactoryEx_Release(cfex);
+    }
+
+    hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
+    if(FAILED(hres))
+        return NULL;
+
+    if(secmgr) {
+        cs.clsid = guid;
+        cs.pUnk = obj;
+        cs.dwFlags = 0;
+        hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, 
&GUID_CUSTOM_CONFIRMOBJECTSAFETY,
+                &bpolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
+        if(SUCCEEDED(hres)) {
+            policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : 
URLPOLICY_DISALLOW;
+            CoTaskMemFree(bpolicy);
+        }
+
+        if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
+            IUnknown_Release(obj);
+            return NULL;
+        }
+    }
+
+    hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, 
(void**)&obj_site);
+    if(SUCCEEDED(hres)) {
+        FIXME("ObjectWithSite\n");
+        IObjectWithSite_Release(obj_site);
+        IUnknown_Release(obj);
+        return NULL;
+    }
+
+    return obj;
+}
+
 static HRESULT Global_CCur(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, 
VARIANT *res)
 {
     FIXME("\n");
@@ -483,8 +591,30 @@ static HRESULT Global_MsgBox(vbdisp_t *This, VARIANT *arg, 
unsigned args_cnt, VA
 
 static HRESULT Global_CreateObject(vbdisp_t *This, VARIANT *arg, unsigned 
args_cnt, VARIANT *res)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    IUnknown *obj;
+    HRESULT hres;
+
+    TRACE("(%s)\n", debugstr_variant(arg));
+
+    if(V_VT(arg) != VT_BSTR) {
+        FIXME("non-bstr arg\n");
+        return E_INVALIDARG;
+    }
+
+    obj = create_object(This->desc->ctx, V_BSTR(arg));
+    if(!obj)
+        return VB_E_CANNOT_CREATE_OBJ;
+
+    if(res) {
+        hres = IUnknown_QueryInterface(obj, &IID_IDispatch, 
(void**)&V_DISPATCH(res));
+        if(FAILED(hres))
+            return hres;
+
+        V_VT(res) = VT_DISPATCH;
+    }
+
+    IUnknown_Release(obj);
+    return S_OK;
 }
 
 static HRESULT Global_GetObject(vbdisp_t *This, VARIANT *arg, unsigned 
args_cnt, VARIANT *res)
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index 3ac9560..d4e8cca 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -129,6 +129,8 @@ static void destroy_script(script_ctx_t *ctx)
 
     if(ctx->host_global)
         IDispatch_Release(ctx->host_global);
+    if(ctx->secmgr)
+        IInternetHostSecurityManager_Release(ctx->secmgr);
     if(ctx->site)
         IActiveScriptSite_Release(ctx->site);
     if(ctx->err_obj)
@@ -516,6 +518,7 @@ static HRESULT WINAPI 
VBScriptParse_InitNew(IActiveScriptParse *iface)
     if(!ctx)
         return E_OUTOFMEMORY;
 
+    ctx->safeopt = This->safeopt;
     vbsheap_init(&ctx->heap);
     list_init(&ctx->objects);
     list_init(&ctx->code_list);
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 4b0a569..d8134fa 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -143,6 +143,9 @@ struct _script_ctx_t {
     IActiveScriptSite *site;
     LCID lcid;
 
+    IInternetHostSecurityManager *secmgr;
+    DWORD safeopt;
+
     IDispatch *host_global;
 
     class_desc_t script_desc;
diff --git a/dlls/vbscript/vbscript_main.c b/dlls/vbscript/vbscript_main.c
index 4054d35..c47227f 100644
--- a/dlls/vbscript/vbscript_main.c
+++ b/dlls/vbscript/vbscript_main.c
@@ -20,6 +20,7 @@
 
 #include "vbscript.h"
 #include "objsafe.h"
+#include "mshtmhst.h"
 #include "rpcproxy.h"
 #include "vbscript_classes.h"
 #include "vbsglobal.h"



Reply via email to