Implement String.prototype.split
authorSimon Hausmann <simon.hausmann@digia.com>
Mon, 21 Jan 2013 16:21:36 +0000 (17:21 +0100)
committerLars Knoll <lars.knoll@digia.com>
Tue, 22 Jan 2013 11:20:11 +0000 (12:20 +0100)
Change-Id: I676bf6b9338ac6ce3aebadc6007858983d45f02e
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
qv4stringobject.cpp
tests/TestExpectations

index af5ac94..c2063fc 100644 (file)
@@ -510,8 +510,82 @@ Value StringPrototype::method_slice(ExecutionContext *ctx)
 
 Value StringPrototype::method_split(ExecutionContext *ctx)
 {
-    ctx->throwUnimplemented(QStringLiteral("String.prototype.splt"));
-    return Value::undefinedValue();
+    QString text;
+    if (StringObject *thisObject = ctx->thisObject.asStringObject())
+        text = thisObject->value.stringValue()->toQString();
+    else
+        text = ctx->thisObject.toString(ctx)->toQString();
+
+    Value separatorValue = ctx->argumentCount > 0 ? ctx->argument(0) : Value::undefinedValue();
+    Value limitValue = ctx->argumentCount > 1 ? ctx->argument(1) : Value::undefinedValue();
+
+    ArrayObject* array = ctx->engine->newArrayObject(ctx);
+    Value result = Value::fromObject(array);
+
+    if (separatorValue.isUndefined()) {
+        if (limitValue.isUndefined()) {
+            array->array.push_back(Value::fromString(ctx, text));
+            return result;
+        }
+        return Value::fromString(ctx, text.left(limitValue.toInteger(ctx)));
+    }
+
+    uint limit = limitValue.isUndefined() ? UINT_MAX : limitValue.toUInt32(ctx);
+
+    if (limit == 0)
+        return result;
+
+    if (RegExpObject* re = separatorValue.asRegExpObject()) {
+        if (re->value->pattern().isEmpty()) {
+            re = 0;
+            separatorValue = Value::fromString(ctx, QString());
+        }
+    }
+
+    if (RegExpObject* re = separatorValue.asRegExpObject()) {
+        uint offset = 0;
+        uint* matchOffsets = (uint*)alloca(re->value->captureCount() * 2 * sizeof(uint));
+        while (true) {
+            uint result = re->value->match(text, offset, matchOffsets);
+            if (result == JSC::Yarr::offsetNoMatch)
+                break;
+
+            array->array.push_back(Value::fromString(ctx, text.mid(offset, matchOffsets[0] - offset)));
+            offset = qMax(offset + 1, matchOffsets[1]);
+
+            if (array->array.length() >= limit)
+                break;
+
+            for (int i = 1; i < re->value->captureCount(); ++i) {
+                uint start = matchOffsets[i * 2];
+                uint end = matchOffsets[i * 2 + 1];
+                array->array.push_back(Value::fromString(ctx, text.mid(start, end - start)));
+                if (array->array.length() >= limit)
+                    break;
+            }
+        }
+        if (array->array.length() < limit)
+            array->array.push_back(Value::fromString(ctx, text.mid(offset)));
+    } else {
+        QString separator = separatorValue.toString(ctx)->toQString();
+        if (separator.isEmpty()) {
+            for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
+                array->array.push_back(Value::fromString(ctx, text.mid(i, 1)));
+            return result;
+        }
+
+        int start = 0;
+        int end;
+        while ((end = text.indexOf(separator, start)) != -1) {
+            array->array.push_back(Value::fromString(ctx, text.mid(start, end - start)));
+            start = end + separator.size();
+            if (array->array.length() >= limit)
+                break;
+        }
+        if (array->array.length() < limit && start != -1)
+            array->array.push_back(Value::fromString(ctx, text.mid(start)));
+    }
+    return result;
 }
 
 Value StringPrototype::method_substr(ExecutionContext *ctx)
index ca67cd9..7efa62f 100644 (file)
@@ -209,7 +209,6 @@ S12.10_A1.4_T4 failing
 S12.10_A1.4_T5 failing
 S12.10_A1.5_T4 failing
 S12.10_A1.5_T5 failing
-S12.6.1_A8 failing
 12.2.1-1-s failing
 12.2.1-12-s failing
 12.2.1-13-s failing
@@ -239,7 +238,6 @@ S12.6.1_A8 failing
 12.2.1-4-s failing
 12.2.1-7-s failing
 12.2.1-8-s failing
-S12.6.2_A8 failing
 13.0-10-s failing
 13.0-11-s failing
 13.0-13-s failing
@@ -567,103 +565,7 @@ S15.4.4.8_A4_T1 failing
 S15.4.4.8_A4_T2 failing
 S15.5.4.13_A2_T2 failing
 S15.5.4.13_A3_T3 failing
-S15.5.4.14_A1_T1 failing
-S15.5.4.14_A1_T10 failing
-S15.5.4.14_A1_T11 failing
-S15.5.4.14_A1_T12 failing
-S15.5.4.14_A1_T13 failing
-S15.5.4.14_A1_T14 failing
-S15.5.4.14_A1_T15 failing
-S15.5.4.14_A1_T16 failing
-S15.5.4.14_A1_T17 failing
-S15.5.4.14_A1_T18 failing
-S15.5.4.14_A1_T2 failing
-S15.5.4.14_A1_T3 failing
-S15.5.4.14_A1_T4 failing
-S15.5.4.14_A1_T5 failing
-S15.5.4.14_A1_T6 failing
-S15.5.4.14_A1_T7 failing
-S15.5.4.14_A1_T8 failing
-S15.5.4.14_A1_T9 failing
-S15.5.4.14_A2_T1 failing
-S15.5.4.14_A2_T10 failing
-S15.5.4.14_A2_T11 failing
-S15.5.4.14_A2_T12 failing
-S15.5.4.14_A2_T13 failing
-S15.5.4.14_A2_T14 failing
-S15.5.4.14_A2_T15 failing
-S15.5.4.14_A2_T16 failing
-S15.5.4.14_A2_T17 failing
-S15.5.4.14_A2_T18 failing
-S15.5.4.14_A2_T19 failing
-S15.5.4.14_A2_T2 failing
-S15.5.4.14_A2_T20 failing
-S15.5.4.14_A2_T21 failing
-S15.5.4.14_A2_T22 failing
-S15.5.4.14_A2_T23 failing
-S15.5.4.14_A2_T24 failing
-S15.5.4.14_A2_T25 failing
-S15.5.4.14_A2_T26 failing
-S15.5.4.14_A2_T27 failing
-S15.5.4.14_A2_T28 failing
-S15.5.4.14_A2_T29 failing
-S15.5.4.14_A2_T3 failing
-S15.5.4.14_A2_T30 failing
-S15.5.4.14_A2_T31 failing
-S15.5.4.14_A2_T32 failing
-S15.5.4.14_A2_T33 failing
-S15.5.4.14_A2_T34 failing
-S15.5.4.14_A2_T35 failing
-S15.5.4.14_A2_T36 failing
-S15.5.4.14_A2_T37 failing
-S15.5.4.14_A2_T38 failing
-S15.5.4.14_A2_T39 failing
-S15.5.4.14_A2_T4 failing
-S15.5.4.14_A2_T40 failing
-S15.5.4.14_A2_T41 failing
-S15.5.4.14_A2_T42 failing
-S15.5.4.14_A2_T43 failing
-S15.5.4.14_A2_T5 failing
-S15.5.4.14_A2_T6 failing
-S15.5.4.14_A2_T7 failing
-S15.5.4.14_A2_T8 failing
-S15.5.4.14_A2_T9 failing
-S15.5.4.14_A3_T1 failing
-S15.5.4.14_A3_T10 failing
-S15.5.4.14_A3_T11 failing
-S15.5.4.14_A3_T2 failing
-S15.5.4.14_A3_T3 failing
-S15.5.4.14_A3_T4 failing
-S15.5.4.14_A3_T5 failing
-S15.5.4.14_A3_T6 failing
 S15.5.4.14_A3_T7 failing
-S15.5.4.14_A3_T8 failing
-S15.5.4.14_A3_T9 failing
-S15.5.4.14_A4_T1 failing
-S15.5.4.14_A4_T10 failing
-S15.5.4.14_A4_T11 failing
-S15.5.4.14_A4_T12 failing
-S15.5.4.14_A4_T13 failing
-S15.5.4.14_A4_T14 failing
-S15.5.4.14_A4_T15 failing
-S15.5.4.14_A4_T16 failing
-S15.5.4.14_A4_T17 failing
-S15.5.4.14_A4_T18 failing
-S15.5.4.14_A4_T19 failing
-S15.5.4.14_A4_T2 failing
-S15.5.4.14_A4_T20 failing
-S15.5.4.14_A4_T21 failing
-S15.5.4.14_A4_T22 failing
-S15.5.4.14_A4_T23 failing
-S15.5.4.14_A4_T24 failing
-S15.5.4.14_A4_T25 failing
-S15.5.4.14_A4_T3 failing
-S15.5.4.14_A4_T4 failing
-S15.5.4.14_A4_T5 failing
-S15.5.4.14_A4_T6 failing
-S15.5.4.14_A4_T7 failing
-S15.5.4.14_A4_T8 failing
-S15.5.4.14_A4_T9 failing
 S15.5.4.15_A1_T2 failing
 S15.5.4.15_A1_T7 failing
 S15.5.4.15_A1_T8 failing