Jacek Caban : jscript: Added String. split implementation for non-regexp arguments.

Alexandre Julliard julliard at winehq.org
Wed Oct 8 08:32:42 CDT 2008


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Oct  7 12:03:02 2008 -0500

jscript: Added String.split implementation for non-regexp arguments.

---

 dlls/jscript/string.c        |   65 +++++++++++++++++++++++++++++++----------
 dlls/jscript/tests/api.js    |   30 +++++++++++++++++++
 dlls/jscript/tests/regexp.js |   17 +++++++++++
 3 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c
index ba4c82d..c6d789e 100644
--- a/dlls/jscript/string.c
+++ b/dlls/jscript/string.c
@@ -846,12 +846,13 @@ static HRESULT String_small(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
 static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
+    match_result_t *match_result = NULL;
+    DWORD match_cnt, i, match_len = 0;
     StringInstance *string;
-    match_result_t *match_result;
-    DWORD match_cnt, i, len;
-    const WCHAR *ptr;
+    const WCHAR *ptr, *ptr2;
     VARIANT *arg, var;
     DispatchEx *array;
+    BSTR match_str = NULL;
     HRESULT hres;
 
     TRACE("\n");
@@ -886,18 +887,38 @@ static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
         }
     }
     default:
-        FIXME("unsupported vt %d\n", V_VT(arg));
-        return E_NOTIMPL;
+        hres = to_string(dispex->ctx, arg, ei, &match_str);
+        if(FAILED(hres))
+            return hres;
+
+        match_len = SysStringLen(match_str);
+        if(!match_len) {
+            SysFreeString(match_str);
+            match_str = NULL;
+        }
     }
 
-    hres = create_array(dispex->ctx, match_cnt+1, &array);
+    hres = create_array(dispex->ctx, 0, &array);
 
     if(SUCCEEDED(hres)) {
         ptr = string->str;
-        for(i=0; i < match_cnt; i++) {
-            len = match_result[i].str-ptr;
+        for(i=0;; i++) {
+            if(match_result) {
+                if(i == match_cnt)
+                    break;
+                ptr2 = match_result[i].str;
+            }else if(match_str) {
+                ptr2 = strstrW(ptr, match_str);
+                if(!ptr2)
+                    break;
+            }else {
+                if(!*ptr)
+                    break;
+                ptr2 = ptr+1;
+            }
+
             V_VT(&var) = VT_BSTR;
-            V_BSTR(&var) = SysAllocStringLen(ptr, len);
+            V_BSTR(&var) = SysAllocStringLen(ptr, ptr2-ptr);
             if(!V_BSTR(&var)) {
                 hres = E_OUTOFMEMORY;
                 break;
@@ -908,20 +929,32 @@ static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
             if(FAILED(hres))
                 break;
 
-            ptr = match_result[i].str + match_result[i].len;
+            if(match_result)
+                ptr = match_result[i].str + match_result[i].len;
+            else if(match_str)
+                ptr = ptr2 + match_len;
+            else
+                ptr++;
         }
     }
 
-    if(SUCCEEDED(hres)) {
-        len = (string->str+string->length) - ptr;
+    if(SUCCEEDED(hres) && (match_str || match_result)) {
+        DWORD len = (string->str+string->length) - ptr;
 
-        V_VT(&var) = VT_BSTR;
-        V_BSTR(&var) = SysAllocStringLen(ptr, len);
+        if(len || match_str) {
+            V_VT(&var) = VT_BSTR;
+            V_BSTR(&var) = SysAllocStringLen(ptr, len);
 
-        hres = jsdisp_propput_idx(array, i, lcid, &var, ei, sp);
-        SysFreeString(V_BSTR(&var));
+            if(V_BSTR(&var)) {
+                hres = jsdisp_propput_idx(array, i, lcid, &var, ei, sp);
+                SysFreeString(V_BSTR(&var));
+            }else {
+                hres = E_OUTOFMEMORY;
+            }
+        }
     }
 
+    SysFreeString(match_str);
     heap_free(match_result);
 
     if(SUCCEEDED(hres) && retv) {
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index 3543357..58847fa 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -200,6 +200,36 @@ ok(r === "-ret-", "r = " + r + " expected '-ret-'");
 r = "-[test]-".replace("[test]", replaceFunc3, "test");
 ok(r === "-ret-", "r = " + r + " expected '-ret-'");
 
+r = "1,2,3".split(",");
+ok(typeof(r) === "object", "typeof(r) = " + typeof(r));
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+
+r = "1,2,3".split(",*");
+ok(r.length === 1, "r.length = " + r.length);
+ok(r[0] === "1,2,3", "r[0] = " + r[0]);
+
+r = "123".split("");
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+r = "123".split(2);
+ok(r.length === 2, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "3", "r[1] = " + r[1]);
+
+r = "1,2,".split(",");
+ok(typeof(r) === "object", "typeof(r) = " + typeof(r));
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "", "r[2] = " + r[2]);
+
 tmp = "abcd".indexOf("bc",0);
 ok(tmp === 1, "indexOf = " + tmp);
 tmp = "abcd".indexOf("bc",1);
diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js
index e797723..6809101 100644
--- a/dlls/jscript/tests/regexp.js
+++ b/dlls/jscript/tests/regexp.js
@@ -150,4 +150,21 @@ function replaceFunc2(m, subm, off, str) {
 r = "[test1] [test2]".replace(/\[([^\[]+)\]/g, replaceFunc2);
 ok(r === "r0 r1", "r = '" + r + "' expected 'r0 r1'");
 
+r = "1,,2,3".split(/,+/g);
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+r = "1,,2,3".split(/,+/);
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+r = "1,,2,".split(/,+/);
+ok(r.length === 2, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+
 reportSuccess();




More information about the wine-cvs mailing list