Jacek Caban : jscript: Added support for conditional compilation @if/@elif /@else/@end.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Oct 1 14:34:31 CDT 2014


Module: wine
Branch: master
Commit: afba44d3244f93effbd48ecc93358f897ec713ec
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=afba44d3244f93effbd48ecc93358f897ec713ec

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Oct  1 10:45:12 2014 +0200

jscript: Added support for conditional compilation @if/@elif/@else/@end.

---

 dlls/jscript/lex.c    | 93 ++++++++++++++++++++++++++++++++++++++++++++-------
 dlls/jscript/parser.h |  1 +
 2 files changed, 81 insertions(+), 13 deletions(-)

diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c
index 357b905..3daaf47 100644
--- a/dlls/jscript/lex.c
+++ b/dlls/jscript/lex.c
@@ -63,6 +63,9 @@ static const WCHAR voidW[] = {'v','o','i','d',0};
 static const WCHAR whileW[] = {'w','h','i','l','e',0};
 static const WCHAR withW[] = {'w','i','t','h',0};
 
+static const WCHAR elifW[] = {'e','l','i','f',0};
+static const WCHAR endW[] = {'e','n','d',0};
+
 static const struct {
     const WCHAR *word;
     int token;
@@ -942,6 +945,61 @@ int try_parse_ccval(parser_ctx_t *ctx, ccval_t *r)
     return 0;
 }
 
+static int skip_code(parser_ctx_t *ctx, BOOL exec_else)
+{
+    int if_depth = 1;
+    const WCHAR *ptr;
+
+    while(1) {
+        ptr = strchrW(ctx->ptr, '@');
+        if(!ptr) {
+            WARN("No @end\n");
+            return lex_error(ctx, JS_E_EXPECTED_CCEND);
+        }
+        ctx->ptr = ptr+1;
+
+        if(!check_keyword(ctx, endW, NULL)) {
+            if(--if_depth)
+                continue;
+            return 0;
+        }
+
+        if(exec_else && !check_keyword(ctx, elifW, NULL)) {
+            if(if_depth > 1)
+                continue;
+
+            if(!skip_spaces(ctx) || *ctx->ptr != '(')
+                return lex_error(ctx, JS_E_MISSING_LBRACKET);
+
+            if(!parse_cc_expr(ctx))
+                return -1;
+
+            if(!get_ccbool(ctx->ccval))
+                continue; /* skip block of code */
+
+            /* continue parsing */
+            ctx->cc_if_depth++;
+            return 0;
+        }
+
+        if(exec_else && !check_keyword(ctx, elseW, NULL)) {
+            if(if_depth > 1)
+                continue;
+
+            /* parse else block */
+            ctx->cc_if_depth++;
+            return 0;
+        }
+
+        if(!check_keyword(ctx, ifW, NULL)) {
+            if_depth++;
+            continue;
+        }
+
+        ctx->ptr++;
+    }
+}
+
 static int cc_token(parser_ctx_t *ctx, void *lval)
 {
     unsigned id_len = 0;
@@ -949,8 +1007,6 @@ static int cc_token(parser_ctx_t *ctx, void *lval)
 
     static const WCHAR cc_onW[] = {'c','c','_','o','n',0};
     static const WCHAR setW[] = {'s','e','t',0};
-    static const WCHAR elifW[] = {'e','l','i','f',0};
-    static const WCHAR endW[] = {'e','n','d',0};
 
     ctx->ptr++;
 
@@ -989,23 +1045,34 @@ static int cc_token(parser_ctx_t *ctx, void *lval)
     }
 
     if(!check_keyword(ctx, ifW, NULL)) {
-        FIXME("@if not implemented\n");
-        return lex_error(ctx, E_NOTIMPL);
-    }
+        if(!skip_spaces(ctx) || *ctx->ptr != '(')
+            return lex_error(ctx, JS_E_MISSING_LBRACKET);
 
-    if(!check_keyword(ctx, elifW, NULL)) {
-        FIXME("@elif not implemented\n");
-        return lex_error(ctx, E_NOTIMPL);
+        if(!parse_cc_expr(ctx))
+            return -1;
+
+        if(get_ccbool(ctx->ccval)) {
+            /* continue parsing block inside if */
+            ctx->cc_if_depth++;
+            return 0;
+        }
+
+        return skip_code(ctx, TRUE);
     }
 
-    if(!check_keyword(ctx, elseW, NULL)) {
-        FIXME("@else not implemented\n");
-        return lex_error(ctx, E_NOTIMPL);
+    if(!check_keyword(ctx, elifW, NULL) || !check_keyword(ctx, elseW, NULL)) {
+        if(!ctx->cc_if_depth)
+            return lex_error(ctx, JS_E_SYNTAX);
+
+        return skip_code(ctx, FALSE);
     }
 
     if(!check_keyword(ctx, endW, NULL)) {
-        FIXME("@end not implemented\n");
-        return lex_error(ctx, E_NOTIMPL);
+        if(!ctx->cc_if_depth)
+            return lex_error(ctx, JS_E_SYNTAX);
+
+        ctx->cc_if_depth--;
+        return 0;
     }
 
     if(!ctx->script->cc)
diff --git a/dlls/jscript/parser.h b/dlls/jscript/parser.h
index cb4e9c4..ab5744a 100644
--- a/dlls/jscript/parser.h
+++ b/dlls/jscript/parser.h
@@ -42,6 +42,7 @@ typedef struct _parser_ctx_t {
     HRESULT hres;
 
     ccval_t ccval;
+    unsigned cc_if_depth;
 
     heap_pool_t heap;
 } parser_ctx_t;




More information about the wine-cvs mailing list