Piotr Caban : jscript: Added JSGlobal_parseFloat implementation.
Alexandre Julliard
julliard at winehq.org
Thu Aug 6 10:49:11 CDT 2009
Module: wine
Branch: master
Commit: 3edf1ba22faf722051861c8d27d41a19bb40804c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3edf1ba22faf722051861c8d27d41a19bb40804c
Author: Piotr Caban <piotr.caban at gmail.com>
Date: Wed Aug 5 23:27:52 2009 +0200
jscript: Added JSGlobal_parseFloat implementation.
---
dlls/jscript/global.c | 102 ++++++++++++++++++++++++++++++++++++++++++++-
dlls/jscript/tests/api.js | 10 ++++
2 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c
index 7d59e19..ff3510f 100644
--- a/dlls/jscript/global.c
+++ b/dlls/jscript/global.c
@@ -20,6 +20,7 @@
#include "wine/port.h"
#include <math.h>
+#include <limits.h>
#include "jscript.h"
#include "engine.h"
@@ -28,6 +29,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
+#define LONGLONG_MAX (((LONGLONG)0x7fffffff<<32)|0xffffffff)
+
static const WCHAR NaNW[] = {'N','a','N',0};
static const WCHAR InfinityW[] = {'I','n','f','i','n','i','t','y',0};
static const WCHAR ArrayW[] = {'A','r','r','a','y',0};
@@ -474,8 +477,103 @@ static HRESULT JSGlobal_parseInt(DispatchEx *dispex, LCID lcid, WORD flags, DISP
static HRESULT JSGlobal_parseFloat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
- FIXME("\n");
- return E_NOTIMPL;
+ LONGLONG d = 0, hlp;
+ int exp = 0, length;
+ VARIANT *arg;
+ WCHAR *str;
+ BSTR val_str = NULL;
+ BOOL ret_nan = TRUE, positive = TRUE;
+ HRESULT hres;
+
+ if(!arg_cnt(dp)) {
+ if(retv)
+ num_set_nan(retv);
+ return S_OK;
+ }
+
+ arg = get_arg(dp, 0);
+ hres = to_string(dispex->ctx, arg, ei, &val_str);
+ if(FAILED(hres))
+ return hres;
+
+ str = val_str;
+ length = SysStringLen(val_str);
+
+ while(isspaceW(*str)) str++;
+
+ if(*str == '+')
+ str++;
+ else if(*str == '-') {
+ positive = FALSE;
+ str++;
+ }
+
+ if(isdigitW(*str))
+ ret_nan = FALSE;
+
+ while(isdigitW(*str)) {
+ hlp = d*10 + *(str++) - '0';
+ if(d>LONGLONG_MAX/10 || hlp<0) {
+ exp++;
+ break;
+ }
+ else
+ d = hlp;
+ }
+ while(isdigitW(*str)) {
+ exp++;
+ str++;
+ }
+
+ if(*str == '.') str++;
+
+ if(isdigitW(*str))
+ ret_nan = FALSE;
+
+ while(isdigitW(*str)) {
+ hlp = d*10 + *(str++) - '0';
+ if(d>LONGLONG_MAX/10 || hlp<0)
+ break;
+
+ d = hlp;
+ exp--;
+ }
+ while(isdigitW(*str))
+ str++;
+
+ if(*str && !ret_nan && (*str=='e' || *str=='E')) {
+ int sign = 1, e = 0;
+
+ str++;
+ if(*str == '+')
+ str++;
+ else if(*str == '-') {
+ sign = -1;
+ str++;
+ }
+
+ while(isdigitW(*str)) {
+ if(e>INT_MAX/10 || (e = e*10 + *str++ - '0')<0)
+ e = INT_MAX;
+ }
+ e *= sign;
+
+ if(exp<0 && e<0 && exp+e>0) exp = INT_MIN;
+ else if(exp>0 && e>0 && exp+e<0) exp = INT_MAX;
+ else exp += e;
+ }
+
+ SysFreeString(val_str);
+
+ if(ret_nan) {
+ if(retv)
+ num_set_nan(retv);
+ return S_OK;
+ }
+
+ V_VT(retv) = VT_R8;
+ V_R8(retv) = (double)(positive?d:-d)*pow(10, exp);
+ return S_OK;
}
static HRESULT JSGlobal_unescape(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index 66fea75..15b4b57 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -627,6 +627,16 @@ for(i=2; i<10; i++) {
ok((0).toString(i) === "0", "(0).toString("+i+") = " + (0).toString(i));
}
+ok(parseFloat('123') === 123, "parseFloat('123') = " + parseFloat('123'));
+ok(parseFloat('-13.7') === -13.7, "parseFloat('-13.7') = " + parseFloat('-13.7'));
+ok(parseFloat('-0.01e-2') === -0.01e-2, "parseFloat('-0.01e-2') = " + parseFloat('-0.01e-2'));
+ok(parseFloat('-12e+5') === -12e+5, "parseFloat('-12e+5') = " + parseFloat('-12e+5'));
+ok(parseFloat('1E5 not parsed') === 1E5, "parseFloat('1E5 not parsed') = " + parseFloat('1E5 not parsed'));
+ok(isNaN(parseFloat('not a number')), "parseFloat('not a number') is not NaN");
+ok(parseFloat('+13.2e-3') === 13.2e-3, "parseFloat('+13.2e-3') = " + parseFloat('+13.2e-3'));
+ok(parseFloat('.12') === 0.12, "parseFloat('.12') = " + parseFloat('.12'));
+ok(parseFloat('1e') === 1, "parseFloat('1e') = " + parseFloat('1e'));
+
tmp = Math.min(1);
ok(tmp === 1, "Math.min(1) = " + tmp);
More information about the wine-cvs
mailing list