diff options
| author | Brian Anderson <andersrb@gmail.com> | 2012-02-11 17:42:45 -0800 |
|---|---|---|
| committer | Brian Anderson <andersrb@gmail.com> | 2012-02-11 17:42:45 -0800 |
| commit | 737db5b49a47593529395d2d9225ca2eaa684634 (patch) | |
| tree | f7c0923b454f2f856d79c9deec181f1fb200e6ba /src/libcore | |
| parent | c82a0d7c3c0c0fda158102af7bc5af2823df2f06 (diff) | |
| parent | 207bb3d2df92f896145b3f2ef8aa5ca5cea00104 (diff) | |
| download | rust-737db5b49a47593529395d2d9225ca2eaa684634.tar.gz rust-737db5b49a47593529395d2d9225ca2eaa684634.zip | |
Merge pull request #1812 from killerswan/indexing2
(core::str) Fixing index and rindex
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/str.rs | 129 |
1 files changed, 96 insertions, 33 deletions
diff --git a/src/libcore/str.rs b/src/libcore/str.rs index b98d96bb901..ca7bb819443 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -253,15 +253,12 @@ Function: pop_char Remove the final character from a string and return it. Failure: - If the string does not contain any characters. */ fn pop_char(&s: str) -> char unsafe { let end = byte_len(s); - while end > 0u && s[end - 1u] & 192u8 == tag_cont_u8 { end -= 1u; } - assert (end > 0u); - let ch = char_at(s, end - 1u); - s = unsafe::slice_bytes(s, 0u, end - 1u); + let {ch:ch, prev:end} = char_range_at_reverse(s, end); + s = unsafe::slice_bytes(s, 0u, end); ret ch; } @@ -868,32 +865,50 @@ fn lines_iter(ss: str, ff: fn(&&str)) { Section: Searching */ -/* -Function: index +// Function: index +// +// Returns the index of the first matching char +// (as option some/none) +fn index(ss: str, cc: char) -> option<uint> { + let bii = 0u; + let cii = 0u; + let len = byte_len(ss); + while bii < len { + let {ch, next} = char_range_at(ss, bii); -Returns the index of the first matching byte. Returns -1 if -no match is found. + // found here? + if ch == cc { + ret option::some(cii); + } -FIXME: UTF-8 -*/ -fn index(s: str, c: u8) -> int { - let i: int = 0; - for k: u8 in s { if k == c { ret i; } i += 1; } - ret -1; -} + cii += 1u; + bii = next; + } -/* -Function: rindex + // wasn't found + ret option::none; +} -Returns the index of the last matching byte. Returns -1 -if no match is found. +// Function: rindex +// +// Returns the index of the first matching char +// (as option some/none) +fn rindex(ss: str, cc: char) -> option<uint> { + let bii = byte_len(ss); + let cii = char_len(ss); + while bii > 0u { + let {ch, prev} = char_range_at_reverse(ss, bii); + cii -= 1u; + bii = prev; + + // found here? + if ch == cc { + ret option::some(cii); + } + } -FIXME: UTF-8 -*/ -fn rindex(s: str, c: u8) -> int { - let n: int = byte_len(s) as int; - while n >= 0 { if s[n] == c { ret n; } n -= 1; } - ret n; + // wasn't found + ret option::none; } /* @@ -1233,6 +1248,25 @@ Pluck a character out of a string */ fn char_at(s: str, i: uint) -> char { ret char_range_at(s, i).ch; } +// Function: char_range_at_reverse +// +// Given a byte position and a str, return the previous char and its position +// This function can be used to iterate over a unicode string in reverse. +fn char_range_at_reverse(ss: str, start: uint) -> {ch: char, prev: uint} { + let prev = start; + + // while there is a previous byte == 10...... + while prev > 0u && ss[prev - 1u] & 192u8 == tag_cont_u8 { + prev -= 1u; + } + + // now refer to the initial byte of previous char + prev -= 1u; + + let ch = char_at(ss, prev); + ret {ch:ch, prev:prev}; +} + /* Function: substr_all @@ -1442,13 +1476,42 @@ mod tests { } #[test] - fn test_index_and_rindex() { - assert (index("hello", 'e' as u8) == 1); - assert (index("hello", 'o' as u8) == 4); - assert (index("hello", 'z' as u8) == -1); - assert (rindex("hello", 'l' as u8) == 3); - assert (rindex("hello", 'h' as u8) == 0); - assert (rindex("hello", 'z' as u8) == -1); + fn test_index() { + assert ( index("hello", 'h') == option::some(0u)); + assert ( index("hello", 'e') == option::some(1u)); + assert ( index("hello", 'o') == option::some(4u)); + assert ( index("hello", 'z') == option::none); + } + + #[test] + fn test_rindex() { + assert (rindex("hello", 'l') == option::some(3u)); + assert (rindex("hello", 'o') == option::some(4u)); + assert (rindex("hello", 'h') == option::some(0u)); + assert (rindex("hello", 'z') == option::none); + } + + #[test] + fn test_pop_char() { + let data = "ประเทศไทย中华"; + let cc = pop_char(data); + assert "ประเทศไทย中" == data; + assert '华' == cc; + } + + #[test] + fn test_pop_char_2() { + let data2 = "华"; + let cc2 = pop_char(data2); + assert "" == data2; + assert '华' == cc2; + } + + #[test] + #[should_fail] + fn test_pop_char_fail() { + let data = ""; + let _cc3 = pop_char(data); } #[test] |
