mirror of https://github.com/svaarala/duktape.git
Sami Vaarala
11 years ago
2 changed files with 158 additions and 0 deletions
@ -0,0 +1,124 @@ |
|||||
|
/*===
|
||||
|
*** test_1 |
||||
|
blen=5, clen=3, str="o\xe1\x88\xb4a" |
||||
|
blen=6, clen=4, str="o\xe1\x88\xb4ar" |
||||
|
blen=0, clen=0, str="" |
||||
|
blen=0, clen=0, str="" |
||||
|
final top: 1 |
||||
|
rc=0, result=undefined |
||||
|
*** test_2 |
||||
|
rc=1, result=TypeError: incorrect type, expected tag 5 |
||||
|
*** test_3 |
||||
|
rc=1, result=Error: invalid index: -2 |
||||
|
*** test_4 |
||||
|
rc=1, result=Error: invalid index: -2147483648 |
||||
|
===*/ |
||||
|
|
||||
|
void dump_string(duk_context *ctx) { |
||||
|
const char *buf; |
||||
|
size_t i, len; |
||||
|
|
||||
|
buf = duk_get_lstring(ctx, -1, &len); |
||||
|
printf("blen=%d, clen=%d, str=\"", (int) len, (int) duk_get_length(ctx, -1)); |
||||
|
for (i = 0; i < len; i++) { |
||||
|
char c = buf[i]; |
||||
|
if (c >= 0x20 && c <= 0x7e) { |
||||
|
printf("%c", c); |
||||
|
} else { |
||||
|
printf("\\x%02x", ((int) c) & 0xff); |
||||
|
} |
||||
|
} |
||||
|
printf("\"\n"); |
||||
|
|
||||
|
duk_pop(ctx); |
||||
|
} |
||||
|
|
||||
|
int test_1(duk_context *ctx) { |
||||
|
/*
|
||||
|
* Test with a string containing non-ASCII to ensure indices are |
||||
|
* treated correctly as char indices. |
||||
|
* |
||||
|
* >>> u'foo\u1234ar'.encode('utf-8').encode('hex') |
||||
|
* '666f6fe188b46172' |
||||
|
*/ |
||||
|
const char *teststr = "666f6fe188b46172"; |
||||
|
|
||||
|
duk_set_top(ctx, 0); |
||||
|
|
||||
|
duk_push_string(ctx, (const char *) teststr); |
||||
|
duk_hex_decode(ctx, -1); |
||||
|
duk_to_string(ctx, -1); |
||||
|
|
||||
|
/* basic case */ |
||||
|
duk_dup_top(ctx); |
||||
|
duk_substring(ctx, -1, 2, 5); |
||||
|
dump_string(ctx); |
||||
|
|
||||
|
/* end is clamped */ |
||||
|
duk_dup_top(ctx); |
||||
|
duk_substring(ctx, -1, 2, 8); |
||||
|
dump_string(ctx); |
||||
|
|
||||
|
/* start and end are clamped */ |
||||
|
duk_dup_top(ctx); |
||||
|
duk_substring(ctx, -1, 10, 20); |
||||
|
dump_string(ctx); |
||||
|
|
||||
|
/* start > end */ |
||||
|
duk_dup_top(ctx); |
||||
|
duk_substring(ctx, -1, 4, 2); |
||||
|
dump_string(ctx); |
||||
|
|
||||
|
printf("final top: %d\n", duk_get_top(ctx)); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/* non-string -> error */ |
||||
|
int test_2(duk_context *ctx) { |
||||
|
duk_set_top(ctx, 0); |
||||
|
|
||||
|
duk_push_int(ctx, 123456); |
||||
|
duk_substring(ctx, -1, 2, 4); |
||||
|
|
||||
|
printf("final top: %d\n", duk_get_top(ctx)); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/* invalid index */ |
||||
|
int test_3(duk_context *ctx) { |
||||
|
duk_set_top(ctx, 0); |
||||
|
|
||||
|
duk_push_string(ctx, "foobar"); |
||||
|
duk_substring(ctx, -2, 2, 4); |
||||
|
|
||||
|
printf("final top: %d\n", duk_get_top(ctx)); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/* invalid index */ |
||||
|
int test_4(duk_context *ctx) { |
||||
|
duk_set_top(ctx, 0); |
||||
|
|
||||
|
duk_push_string(ctx, "foobar"); |
||||
|
duk_substring(ctx, DUK_INVALID_INDEX, 2, 4); |
||||
|
|
||||
|
printf("final top: %d\n", duk_get_top(ctx)); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
#define TEST(func) do { \ |
||||
|
printf("*** %s\n", #func); \ |
||||
|
rc = duk_safe_call(ctx, (func), 0, 1, DUK_INVALID_INDEX); \ |
||||
|
printf("rc=%d, result=%s\n", rc, duk_to_string(ctx, -1)); \ |
||||
|
duk_pop(ctx); \ |
||||
|
} while (0) |
||||
|
|
||||
|
void test(duk_context *ctx) { |
||||
|
int rc; |
||||
|
|
||||
|
TEST(test_1); |
||||
|
TEST(test_2); |
||||
|
TEST(test_3); |
||||
|
TEST(test_4); /* FIXME: exposes value of DUK_INVALID_INDEX */ |
||||
|
} |
||||
|
|
@ -0,0 +1,34 @@ |
|||||
|
=proto |
||||
|
void duk_substring(duk_context *ctx, int index, size_t start_offset, size_t end_offset); |
||||
|
|
||||
|
=stack |
||||
|
[ ... str! ... ] -> [ ... substr! ... ] |
||||
|
|
||||
|
=summary |
||||
|
<p>Replace a string at <tt>index</tt> with a substring [<tt>start_offset</tt>, |
||||
|
<tt>end_offset</tt>[ of the string itself. If the value at <tt>index</tt> is |
||||
|
not a string or the index is invalid, throws an error.</p> |
||||
|
|
||||
|
<p>The substring operation works with characters, not bytes, and the offsets |
||||
|
are character offsets. The semantics of this call are similar to |
||||
|
<a href="http://www.ecma-international.org/ecma-262/5.1/#sec-15.5.4.15">String.prototype.substring (start, end)</a>. |
||||
|
Offset values are clamped to string length (there is no need to clamp negative |
||||
|
values because <tt>size_t</tt> is unsigned) and if start offset is larger than |
||||
|
end offset, the result is an empty string.</p> |
||||
|
|
||||
|
<div class="note"> |
||||
|
To get a byte-oriented substring, use |
||||
|
<tt><a href="#duk_get_lstring">duk_get_lstring()</a></tt> to get a string data |
||||
|
pointer and length, and |
||||
|
<tt><a href="#duk_push_lstring">duk_push_lstring()</a></tt> to push a slice of |
||||
|
bytes. |
||||
|
</div> |
||||
|
|
||||
|
=example |
||||
|
/* String at index -3 is 'foobar'. Substring [2,5[ is "oba". */ |
||||
|
|
||||
|
duk_substring(ctx, -3, 2, 5); |
||||
|
printf("substring: %s\n", duk_get_string(ctx, -3)); |
||||
|
|
||||
|
=fixme |
||||
|
Return const char *? |
Loading…
Reference in new issue