Skip to content

Commit acabd82

Browse files
committed
Merge pull request #1831 from killerswan/str_fixes
(core::str) changes to find / find_bytes
2 parents 0cae213 + 6983464 commit acabd82

File tree

9 files changed

+129
-83
lines changed

9 files changed

+129
-83
lines changed

src/comp/back/link.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,10 +568,11 @@ fn link_binary(sess: session,
568568
// Converts a library file name into a cc -l argument
569569
fn unlib(config: @session::config, filename: str) -> str unsafe {
570570
let rmlib = fn@(filename: str) -> str {
571+
let found = str::find_bytes(filename, "lib");
571572
if config.os == session::os_macos ||
572573
(config.os == session::os_linux ||
573574
config.os == session::os_freebsd) &&
574-
str::find(filename, "lib") == 0 {
575+
option::is_some(found) && option::get(found) == 0u {
575576
ret str::unsafe::slice_bytes(filename, 3u,
576577
str::len_bytes(filename));
577578
} else { ret filename; }

src/comp/driver/driver.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -269,28 +269,28 @@ fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str,
269269
}
270270

271271
fn get_os(triple: str) -> option<session::os> {
272-
ret if str::find(triple, "win32") >= 0 ||
273-
str::find(triple, "mingw32") >= 0 {
272+
ret if str::contains(triple, "win32") ||
273+
str::contains(triple, "mingw32") {
274274
some(session::os_win32)
275-
} else if str::find(triple, "darwin") >= 0 {
275+
} else if str::contains(triple, "darwin") {
276276
some(session::os_macos)
277-
} else if str::find(triple, "linux") >= 0 {
277+
} else if str::contains(triple, "linux") {
278278
some(session::os_linux)
279-
} else if str::find(triple, "freebsd") >= 0 {
279+
} else if str::contains(triple, "freebsd") {
280280
some(session::os_freebsd)
281281
} else { none };
282282
}
283283

284284
fn get_arch(triple: str) -> option<session::arch> {
285-
ret if str::find(triple, "i386") >= 0 || str::find(triple, "i486") >= 0 ||
286-
str::find(triple, "i586") >= 0 ||
287-
str::find(triple, "i686") >= 0 ||
288-
str::find(triple, "i786") >= 0 {
285+
ret if str::contains(triple, "i386") || str::contains(triple, "i486") ||
286+
str::contains(triple, "i586") ||
287+
str::contains(triple, "i686") ||
288+
str::contains(triple, "i786") {
289289
some(session::arch_x86)
290-
} else if str::find(triple, "x86_64") >= 0 {
290+
} else if str::contains(triple, "x86_64") {
291291
some(session::arch_x86_64)
292-
} else if str::find(triple, "arm") >= 0 ||
293-
str::find(triple, "xscale") >= 0 {
292+
} else if str::contains(triple, "arm") ||
293+
str::contains(triple, "xscale") {
294294
some(session::arch_arm)
295295
} else { none };
296296
}

src/compiletest/errors.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ fn load_errors(testfile: str) -> [expected_error] {
2424

2525
fn parse_expected(line_num: uint, line: str) -> [expected_error] unsafe {
2626
let error_tag = "//!";
27-
let idx0 = str::find(line, error_tag);
28-
if idx0 < 0 { ret []; }
29-
let idx = (idx0 as uint) + str::len_bytes(error_tag);
27+
let idx;
28+
alt str::find_bytes(line, error_tag) {
29+
option::none { ret []; }
30+
option::some(nn) { idx = (nn as uint) + str::len_bytes(error_tag); }
31+
}
3032

3133
// "//!^^^ kind msg" denotes a message expected
3234
// three lines above current line:

src/compiletest/header.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,21 @@ fn parse_pp_exact(line: str, testfile: str) -> option<str> {
100100
}
101101

102102
fn parse_name_directive(line: str, directive: str) -> bool {
103-
str::find(line, directive) >= 0
103+
str::contains(line, directive)
104104
}
105105

106106
fn parse_name_value_directive(line: str,
107107
directive: str) -> option<str> unsafe {
108108
let keycolon = directive + ":";
109-
if str::find(line, keycolon) >= 0 {
110-
let colon = str::find(line, keycolon) as uint;
111-
let value =
112-
str::unsafe::slice_bytes(line, colon + str::len_bytes(keycolon),
113-
str::len_bytes(line));
114-
#debug("%s: %s", directive, value);
115-
option::some(value)
116-
} else { option::none }
109+
alt str::find_bytes(line, keycolon) {
110+
option::some(colon) {
111+
let value =
112+
str::unsafe::slice_bytes(line,
113+
colon + str::len_bytes(keycolon),
114+
str::len_bytes(line));
115+
#debug("%s: %s", directive, value);
116+
option::some(value)
117+
}
118+
option::none { option::none }
119+
}
117120
}

src/compiletest/runtest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ fn check_error_patterns(props: test_props,
199199
let next_err_idx = 0u;
200200
let next_err_pat = props.error_patterns[next_err_idx];
201201
for line: str in str::split_byte(procres.stderr, '\n' as u8) {
202-
if str::find(line, next_err_pat) > 0 {
202+
if str::contains(line, next_err_pat) {
203203
#debug("found error pattern %s", next_err_pat);
204204
next_err_idx += 1u;
205205
if next_err_idx == vec::len(props.error_patterns) {

src/fuzzer/fuzzer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn write_file(filename: str, content: str) {
1616
}
1717

1818
fn contains(haystack: str, needle: str) -> bool {
19-
str::find(haystack, needle) != -1
19+
str::contains(haystack, needle)
2020
}
2121

2222
fn find_rust_files(&files: [str], path: str) {

src/libcore/str.rs

Lines changed: 90 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export
7070
index,
7171
rindex,
7272
find,
73+
find_bytes,
7374
contains,
7475
starts_with,
7576
ends_with,
@@ -661,9 +662,10 @@ fn replace(s: str, from: str, to: str) : is_not_empty(from) -> str unsafe {
661662
unsafe::slice_bytes(s, len_bytes(from), len_bytes(s)),
662663
from, to);
663664
} else {
664-
let idx = find(s, from);
665-
if idx == -1 {
666-
ret s;
665+
let idx;
666+
alt find_bytes(s, from) {
667+
option::some(x) { idx = x; }
668+
option::none { ret s; }
667669
}
668670
let before = unsafe::slice_bytes(s, 0u, idx as uint);
669671
let after = unsafe::slice_bytes(s, idx as uint + len_bytes(from),
@@ -872,38 +874,62 @@ fn rindex(ss: str, cc: char) -> option<uint> {
872874
ret option::none;
873875
}
874876

875-
/*
876-
Function: find
877+
//Function: find_bytes
878+
//
879+
// Find the char position of the first instance of one string
880+
// within another, or return option::none
881+
//
882+
// FIXME: Boyer-Moore should be significantly faster
883+
fn find_bytes(haystack: str, needle: str) -> option<uint> {
884+
let haystack_len = len_bytes(haystack);
885+
let needle_len = len_bytes(needle);
877886

878-
Finds the index of the first matching substring.
879-
Returns -1 if `haystack` does not contain `needle`.
887+
if needle_len == 0u { ret option::some(0u); }
888+
if needle_len > haystack_len { ret option::none; }
880889

881-
Parameters:
890+
fn match_at(haystack: str, needle: str, ii: uint) -> bool {
891+
let jj = ii;
892+
for c: u8 in needle { if haystack[jj] != c { ret false; } jj += 1u; }
893+
ret true;
894+
}
882895

883-
haystack - The string to look in
884-
needle - The string to look for
896+
let ii = 0u;
897+
while ii <= haystack_len - needle_len {
898+
if match_at(haystack, needle, ii) { ret option::some(ii); }
899+
ii += 1u;
900+
}
885901

886-
Returns:
902+
ret option::none;
903+
}
887904

888-
The index of the first occurance of `needle`, or -1 if not found.
905+
// Function: find
906+
//
907+
// Find the char position of the first instance of one string
908+
// within another, or return option::none
909+
fn find(haystack: str, needle: str) -> option<uint> {
910+
alt find_bytes(haystack, needle) {
911+
option::none { ret option::none; }
912+
option::some(nn) { ret option::some(b2c_pos(haystack, nn)); }
913+
}
914+
}
889915

890-
FIXME: return an option<char position uint> instead
891-
*/
892-
fn find(haystack: str, needle: str) -> int {
893-
let haystack_len: int = len_bytes(haystack) as int;
894-
let needle_len: int = len_bytes(needle) as int;
895-
if needle_len == 0 { ret 0; }
896-
fn match_at(haystack: str, needle: str, i: int) -> bool {
897-
let j: int = i;
898-
for c: u8 in needle { if haystack[j] != c { ret false; } j += 1; }
899-
ret true;
900-
}
901-
let i: int = 0;
902-
while i <= haystack_len - needle_len {
903-
if match_at(haystack, needle, i) { ret i; }
904-
i += 1;
905-
}
906-
ret -1;
916+
// Function: b2c_pos
917+
//
918+
// Convert a byte position into a char position
919+
// within a given string
920+
fn b2c_pos(ss: str, bpos: uint) -> uint {
921+
assert bpos == 0u || bpos < len_bytes(ss);
922+
923+
let ii = 0u;
924+
let cpos = 0u;
925+
926+
while ii < bpos {
927+
let sz = utf8_char_width(ss[ii]);
928+
ii += sz;
929+
cpos += 1u;
930+
}
931+
932+
ret cpos;
907933
}
908934

909935
/*
@@ -917,7 +943,7 @@ haystack - The string to look in
917943
needle - The string to look for
918944
*/
919945
fn contains(haystack: str, needle: str) -> bool {
920-
0 <= find(haystack, needle)
946+
option::is_some(find_bytes(haystack, needle))
921947
}
922948

923949
/*
@@ -930,12 +956,12 @@ Parameters:
930956
haystack - The string to look in
931957
needle - The string to look for
932958
*/
933-
fn starts_with(haystack: str, needle: str) -> bool {
934-
let haystack_len: uint = len(haystack);
935-
let needle_len: uint = len(needle);
959+
fn starts_with(haystack: str, needle: str) -> bool unsafe {
960+
let haystack_len: uint = len_bytes(haystack);
961+
let needle_len: uint = len_bytes(needle);
936962
if needle_len == 0u { ret true; }
937963
if needle_len > haystack_len { ret false; }
938-
ret eq(substr(haystack, 0u, needle_len), needle);
964+
ret eq(unsafe::slice_bytes(haystack, 0u, needle_len), needle);
939965
}
940966

941967
/*
@@ -1694,26 +1720,40 @@ mod tests {
16941720
assert [] == words("");
16951721
}
16961722

1723+
#[test]
1724+
fn test_find_bytes() {
1725+
// byte positions
1726+
assert (find_bytes("banana", "apple pie") == option::none);
1727+
assert (find_bytes("", "") == option::some(0u));
1728+
1729+
let data = "ประเทศไทย中华Việt Nam";
1730+
assert (find_bytes(data, "") == option::some(0u));
1731+
assert (find_bytes(data, "ประเ") == option::some( 0u));
1732+
assert (find_bytes(data, "ะเ") == option::some( 6u));
1733+
assert (find_bytes(data, "中华") == option::some(27u));
1734+
assert (find_bytes(data, "ไท华") == option::none);
1735+
}
1736+
16971737
#[test]
16981738
fn test_find() {
1699-
fn t(haystack: str, needle: str, i: int) {
1700-
let j: int = find(haystack, needle);
1701-
log(debug, "searched for " + needle);
1702-
log(debug, j);
1703-
assert (i == j);
1704-
}
1705-
t("this is a simple", "is a", 5);
1706-
t("this is a simple", "is z", -1);
1707-
t("this is a simple", "", 0);
1708-
t("this is a simple", "simple", 10);
1709-
t("this", "simple", -1);
1739+
// char positions
1740+
assert (find("banana", "apple pie") == option::none);
1741+
assert (find("", "") == option::some(0u));
17101742

1711-
// FIXME: return option<char> position instead
17121743
let data = "ประเทศไทย中华Việt Nam";
1713-
assert (find(data, "ประเ") == 0);
1714-
assert (find(data, "ะเ") == 6); // byte position
1715-
assert (find(data, "中华") == 27); // byte position
1716-
assert (find(data, "ไท华") == -1);
1744+
assert (find(data, "") == option::some(0u));
1745+
assert (find(data, "ประเ") == option::some(0u));
1746+
assert (find(data, "ะเ") == option::some(2u));
1747+
assert (find(data, "中华") == option::some(9u));
1748+
assert (find(data, "ไท华") == option::none);
1749+
}
1750+
1751+
#[test]
1752+
fn test_b2c_pos() {
1753+
let data = "ประเทศไทย中华Việt Nam";
1754+
assert 0u == b2c_pos(data, 0u);
1755+
assert 2u == b2c_pos(data, 6u);
1756+
assert 9u == b2c_pos(data, 27u);
17171757
}
17181758

17191759
#[test]

src/libstd/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ fn filter_tests(opts: test_opts,
258258

259259
fn filter_fn(test: test_desc, filter_str: str) ->
260260
option<test_desc> {
261-
if str::find(test.name, filter_str) >= 0 {
261+
if str::contains(test.name, filter_str) {
262262
ret option::some(test);
263263
} else { ret option::none; }
264264
}

src/rustdoc/markdown_pass.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ fn should_write_modules_last() {
5656
fn d() { }"
5757
);
5858

59-
let idx_a = str::find(markdown, "# Module `a`");
60-
let idx_b = str::find(markdown, "## Function `b`");
61-
let idx_c = str::find(markdown, "# Module `c`");
62-
let idx_d = str::find(markdown, "## Function `d`");
59+
let idx_a = option::get(str::find_bytes(markdown, "# Module `a`"));
60+
let idx_b = option::get(str::find_bytes(markdown, "## Function `b`"));
61+
let idx_c = option::get(str::find_bytes(markdown, "# Module `c`"));
62+
let idx_d = option::get(str::find_bytes(markdown, "## Function `d`"));
6363

6464
assert idx_b < idx_d;
6565
assert idx_d < idx_a;
@@ -854,4 +854,4 @@ mod test {
854854
let markdown = render("mod morp { }");
855855
assert str::contains(markdown, "Module `morp`\n\n");
856856
}
857-
}
857+
}

0 commit comments

Comments
 (0)