Piotr Caban : vbscript: Parse doubles with bigger precision in parse_numeric_literal.

Alexandre Julliard julliard at winehq.org
Mon May 19 15:09:59 CDT 2014


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Fri May 16 17:22:37 2014 +0200

vbscript: Parse doubles with bigger precision in parse_numeric_literal.

---

 dlls/vbscript/lex.c          |   43 ++++++++++++++++++++++++++++++++----------
 dlls/vbscript/tests/lang.vbs |    1 +
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index 65d2334..dc5a9fe 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -16,6 +16,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include <assert.h>
 
 #include "vbscript.h"
@@ -258,28 +261,48 @@ static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret)
 
 static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
 {
-    double n = 0;
+    LONGLONG d = 0, hlp;
+    int exp = 0;
 
     if(*ctx->ptr == '0' && !('0' <= ctx->ptr[1] && ctx->ptr[1] <= '9') && ctx->ptr[1] != '.')
         return *ctx->ptr++;
 
-    do {
-        n = n*10 + *ctx->ptr++ - '0';
-    }while('0' <= *ctx->ptr && *ctx->ptr <= '9');
+    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+        hlp = d*10 + *(ctx->ptr++) - '0';
+        if(d>MAXLONGLONG/10 || hlp<0) {
+            exp++;
+            break;
+        }
+        else
+            d = hlp;
+    }
+    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+        exp++;
+        ctx->ptr++;
+    }
 
     if(*ctx->ptr != '.') {
-        if((LONG)n == n) {
-            LONG l = n;
+        if(!exp && (LONG)d == d) {
+            LONG l = d;
             *(LONG*)ret = l;
             return (short)l == l ? tShort : tLong;
         }
     }else {
-        double e = 1.0;
-        while('0' <= *++ctx->ptr && *ctx->ptr <= '9')
-            n += (e /= 10.0)*(*ctx->ptr-'0');
+        ctx->ptr++;
+
+        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
+            hlp = d*10 + *(ctx->ptr++) - '0';
+            if(d>MAXLONGLONG/10 || hlp<0)
+                break;
+
+            d = hlp;
+            exp--;
+        }
+        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
+            ctx->ptr++;
     }
 
-    *(double*)ret = n;
+    *(double*)ret = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp);
     return tDouble;
 }
 
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index c24ffa6..530c5dd 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -187,6 +187,7 @@ Call ok(2*3 = 6, "2*3 = " & (2*3))
 Call ok(3/2 = 1.5, "3/2 = " & (3/2))
 Call ok(5\4/2 = 2, "5\4/2 = " & (5\2/1))
 Call ok(12/3\2 = 2, "12/3\2 = " & (12/3\2))
+Call ok(5/1000000 = 0.000005, "5/1000000 = " & (5/1000000))
 
 Call ok(2^3 = 8, "2^3 = " & (2^3))
 Call ok(2^3^2 = 64, "2^3^2 = " & (2^3^2))




More information about the wine-cvs mailing list