From 3edf1ba22faf722051861c8d27d41a19bb40804c Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Wed, 5 Aug 2009 23:27:52 +0200 Subject: [PATCH] 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 7d59e19c9f8..ff3510fd83b 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -20,6 +20,7 @@ #include "wine/port.h" #include +#include #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 66fea756c33..15b4b574939 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);