Module: wine Branch: master Commit: 8988156255a4173b328c3a956b2857011fd390a4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8988156255a4173b328c3a956b...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Sep 1 13:27:08 2009 +0200
jscript: Added String.lastIndexOf implementation.
---
dlls/jscript/string.c | 84 +++++++++++++++++++++++++++++++++++++++++++- dlls/jscript/tests/api.js | 20 +++++++++++ 2 files changed, 102 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c index 3b0ad59..4311aee 100644 --- a/dlls/jscript/string.c +++ b/dlls/jscript/string.c @@ -562,11 +562,91 @@ static HRESULT String_italics(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR return do_attributeless_tag_format(dispex, lcid, flags, dp, retv, ei, sp, italicstagW); }
+/* ECMA-262 3rd Edition 15.5.4.8 */ static HRESULT String_lastIndexOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + BSTR search_str, val_str = NULL; + DWORD length, pos, search_len; + const WCHAR *str; + INT ret = -1; + HRESULT hres; + + TRACE("\n"); + + if(is_class(dispex, JSCLASS_STRING)) { + StringInstance *this = (StringInstance*)dispex; + + str = this->str; + length = this->length; + }else { + VARIANT this; + + V_VT(&this) = VT_DISPATCH; + V_DISPATCH(&this) = (IDispatch*)_IDispatchEx_(dispex); + + hres = to_string(dispex->ctx, &this, ei, &val_str); + if(FAILED(hres)) + return hres; + + str = val_str; + length = SysStringLen(val_str); + } + + if(!arg_cnt(dp)) { + if(retv) { + V_VT(retv) = VT_I4; + V_I4(retv) = -1; + } + SysFreeString(val_str); + return S_OK; + } + + hres = to_string(dispex->ctx, get_arg(dp,0), ei, &search_str); + if(FAILED(hres)) { + SysFreeString(val_str); + return hres; + } + + search_len = SysStringLen(search_str); + + if(arg_cnt(dp) >= 2) { + VARIANT ival; + + hres = to_integer(dispex->ctx, get_arg(dp,1), ei, &ival); + if(SUCCEEDED(hres)) { + if(V_VT(&ival) == VT_I4) + pos = V_VT(&ival) > 0 ? V_I4(&ival) : 0; + else + pos = V_R8(&ival) > 0.0 ? length : 0; + if(pos > length) + pos = length; + } + }else { + pos = length; + } + + if(SUCCEEDED(hres) && length >= search_len) { + const WCHAR *ptr; + + for(ptr = str+min(pos, length-search_len); ptr >= str; ptr--) { + if(!memcmp(ptr, search_str, search_len*sizeof(WCHAR))) { + ret = ptr-str; + break; + } + } + } + + SysFreeString(search_str); + SysFreeString(val_str); + if(FAILED(hres)) + return hres; + + if(retv) { + V_VT(retv) = VT_I4; + V_I4(retv) = ret; + } + return S_OK; }
static HRESULT String_link(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index d5d7fb3..cff7114 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -114,6 +114,7 @@ ok(str.toString() === "test", "str.toString() = " + str.toString()); var strObj = new Object(); strObj.toString = function() { return "abcd" }; strObj.substr = String.prototype.substr; +strObj.lastIndexOf = String.prototype.lastIndexOf;
tmp = "value " + str; ok(tmp === "value test", "'value ' + str = " + tmp); @@ -294,6 +295,25 @@ ok(tmp === 1, "indexOf = " + tmp); tmp = "abcd".indexOf(); ok(tmp == -1, "indexOf = " + tmp);
+tmp = "abcd".lastIndexOf("bc",1); +ok(tmp === 1, "lastIndexOf = " + tmp); +tmp = "abcd".lastIndexOf("bc",2); +ok(tmp === 1, "lastIndexOf = " + tmp); +tmp = "abcd".lastIndexOf("bc"); +ok(tmp === 1, "lastIndexOf = " + tmp); +tmp = "abcd".lastIndexOf("ac"); +ok(tmp === -1, "lastIndexOf = " + tmp); +tmp = "abcd".lastIndexOf("d",10); +ok(tmp === 3, "lastIndexOf = " + tmp); +tmp = "abcd".lastIndexOf("bc",0,"test"); +ok(tmp === -1, "lastIndexOf = " + tmp); +tmp = "abcd".lastIndexOf(); +ok(tmp === -1, "lastIndexOf = " + tmp); +tmp = "aaaa".lastIndexOf("a",2); +ok(tmp == 2, "lastIndexOf = " + tmp); +tmp = strObj.lastIndexOf("b"); +ok(tmp === 1, "lastIndexOf = " + tmp); + tmp = "".toLowerCase(); ok(tmp === "", "''.toLowerCase() = " + tmp); tmp = "test".toLowerCase();