diff options
| author | Brian Anderson <andersrb@gmail.com> | 2012-02-14 11:22:31 -0800 |
|---|---|---|
| committer | Brian Anderson <andersrb@gmail.com> | 2012-02-14 11:22:31 -0800 |
| commit | acabd821d2c3503c087b2ce2bd784c14f48cb407 (patch) | |
| tree | 37a4cc745eb6d2e1da75a5174f1c02c993ee2344 | |
| parent | 0cae213801d0c42c999ed9bb122e61db553b4d5e (diff) | |
| parent | 69834646d2efd2170236b1f8db3a71c77e378c5b (diff) | |
Merge pull request #1831 from killerswan/str_fixes
(core::str) changes to find / find_bytes
| -rw-r--r-- | src/comp/back/link.rs | 3 | ||||
| -rw-r--r-- | src/comp/driver/driver.rs | 24 | ||||
| -rw-r--r-- | src/compiletest/errors.rs | 8 | ||||
| -rw-r--r-- | src/compiletest/header.rs | 21 | ||||
| -rw-r--r-- | src/compiletest/runtest.rs | 2 | ||||
| -rw-r--r-- | src/fuzzer/fuzzer.rs | 2 | ||||
| -rw-r--r-- | src/libcore/str.rs | 140 | ||||
| -rw-r--r-- | src/libstd/test.rs | 2 | ||||
| -rw-r--r-- | src/rustdoc/markdown_pass.rs | 10 |
9 files changed, 129 insertions, 83 deletions
diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs index adb9f31f13e..3d345c1a250 100644 --- a/src/comp/back/link.rs +++ b/src/comp/back/link.rs @@ -568,10 +568,11 @@ fn link_binary(sess: session, // Converts a library file name into a cc -l argument fn unlib(config: @session::config, filename: str) -> str unsafe { let rmlib = fn@(filename: str) -> str { + let found = str::find_bytes(filename, "lib"); if config.os == session::os_macos || (config.os == session::os_linux || config.os == session::os_freebsd) && - str::find(filename, "lib") == 0 { + option::is_some(found) && option::get(found) == 0u { ret str::unsafe::slice_bytes(filename, 3u, str::len_bytes(filename)); } else { ret filename; } diff --git a/src/comp/driver/driver.rs b/src/comp/driver/driver.rs index 52f38afc69a..62cffd97099 100644 --- a/src/comp/driver/driver.rs +++ b/src/comp/driver/driver.rs @@ -269,28 +269,28 @@ fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str, } fn get_os(triple: str) -> option<session::os> { - ret if str::find(triple, "win32") >= 0 || - str::find(triple, "mingw32") >= 0 { + ret if str::contains(triple, "win32") || + str::contains(triple, "mingw32") { some(session::os_win32) - } else if str::find(triple, "darwin") >= 0 { + } else if str::contains(triple, "darwin") { some(session::os_macos) - } else if str::find(triple, "linux") >= 0 { + } else if str::contains(triple, "linux") { some(session::os_linux) - } else if str::find(triple, "freebsd") >= 0 { + } else if str::contains(triple, "freebsd") { some(session::os_freebsd) } else { none }; } fn get_arch(triple: str) -> option<session::arch> { - ret if str::find(triple, "i386") >= 0 || str::find(triple, "i486") >= 0 || - str::find(triple, "i586") >= 0 || - str::find(triple, "i686") >= 0 || - str::find(triple, "i786") >= 0 { + ret if str::contains(triple, "i386") || str::contains(triple, "i486") || + str::contains(triple, "i586") || + str::contains(triple, "i686") || + str::contains(triple, "i786") { some(session::arch_x86) - } else if str::find(triple, "x86_64") >= 0 { + } else if str::contains(triple, "x86_64") { some(session::arch_x86_64) - } else if str::find(triple, "arm") >= 0 || - str::find(triple, "xscale") >= 0 { + } else if str::contains(triple, "arm") || + str::contains(triple, "xscale") { some(session::arch_arm) } else { none }; } diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 9d81b6f00e2..f6b32e2fd31 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -24,9 +24,11 @@ fn load_errors(testfile: str) -> [expected_error] { fn parse_expected(line_num: uint, line: str) -> [expected_error] unsafe { let error_tag = "//!"; - let idx0 = str::find(line, error_tag); - if idx0 < 0 { ret []; } - let idx = (idx0 as uint) + str::len_bytes(error_tag); + let idx; + alt str::find_bytes(line, error_tag) { + option::none { ret []; } + option::some(nn) { idx = (nn as uint) + str::len_bytes(error_tag); } + } // "//!^^^ kind msg" denotes a message expected // three lines above current line: diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index f9c7a7a66e0..a976c5fb98c 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -100,18 +100,21 @@ fn parse_pp_exact(line: str, testfile: str) -> option<str> { } fn parse_name_directive(line: str, directive: str) -> bool { - str::find(line, directive) >= 0 + str::contains(line, directive) } fn parse_name_value_directive(line: str, directive: str) -> option<str> unsafe { let keycolon = directive + ":"; - if str::find(line, keycolon) >= 0 { - let colon = str::find(line, keycolon) as uint; - let value = - str::unsafe::slice_bytes(line, colon + str::len_bytes(keycolon), - str::len_bytes(line)); - #debug("%s: %s", directive, value); - option::some(value) - } else { option::none } + alt str::find_bytes(line, keycolon) { + option::some(colon) { + let value = + str::unsafe::slice_bytes(line, + colon + str::len_bytes(keycolon), + str::len_bytes(line)); + #debug("%s: %s", directive, value); + option::some(value) + } + option::none { option::none } + } } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index cf5a57c60de..5fb0bca25fa 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -199,7 +199,7 @@ fn check_error_patterns(props: test_props, let next_err_idx = 0u; let next_err_pat = props.error_patterns[next_err_idx]; for line: str in str::split_byte(procres.stderr, '\n' as u8) { - if str::find(line, next_err_pat) > 0 { + if str::contains(line, next_err_pat) { #debug("found error pattern %s", next_err_pat); next_err_idx += 1u; if next_err_idx == vec::len(props.error_patterns) { diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index f6d5f72c367..40d21864021 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -16,7 +16,7 @@ fn write_file(filename: str, content: str) { } fn contains(haystack: str, needle: str) -> bool { - str::find(haystack, needle) != -1 + str::contains(haystack, needle) } fn find_rust_files(&files: [str], path: str) { diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 5b4cc1f77e8..ed2b52cd9d0 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -70,6 +70,7 @@ export index, rindex, find, + find_bytes, contains, starts_with, ends_with, @@ -661,9 +662,10 @@ fn replace(s: str, from: str, to: str) : is_not_empty(from) -> str unsafe { unsafe::slice_bytes(s, len_bytes(from), len_bytes(s)), from, to); } else { - let idx = find(s, from); - if idx == -1 { - ret s; + let idx; + alt find_bytes(s, from) { + option::some(x) { idx = x; } + option::none { ret s; } } let before = unsafe::slice_bytes(s, 0u, idx as uint); let after = unsafe::slice_bytes(s, idx as uint + len_bytes(from), @@ -872,38 +874,62 @@ fn rindex(ss: str, cc: char) -> option<uint> { ret option::none; } -/* -Function: find +//Function: find_bytes +// +// Find the char position of the first instance of one string +// within another, or return option::none +// +// FIXME: Boyer-Moore should be significantly faster +fn find_bytes(haystack: str, needle: str) -> option<uint> { + let haystack_len = len_bytes(haystack); + let needle_len = len_bytes(needle); -Finds the index of the first matching substring. -Returns -1 if `haystack` does not contain `needle`. + if needle_len == 0u { ret option::some(0u); } + if needle_len > haystack_len { ret option::none; } -Parameters: + fn match_at(haystack: str, needle: str, ii: uint) -> bool { + let jj = ii; + for c: u8 in needle { if haystack[jj] != c { ret false; } jj += 1u; } + ret true; + } -haystack - The string to look in -needle - The string to look for + let ii = 0u; + while ii <= haystack_len - needle_len { + if match_at(haystack, needle, ii) { ret option::some(ii); } + ii += 1u; + } -Returns: + ret option::none; +} -The index of the first occurance of `needle`, or -1 if not found. +// Function: find +// +// Find the char position of the first instance of one string +// within another, or return option::none +fn find(haystack: str, needle: str) -> option<uint> { + alt find_bytes(haystack, needle) { + option::none { ret option::none; } + option::some(nn) { ret option::some(b2c_pos(haystack, nn)); } + } +} -FIXME: return an option<char position uint> instead -*/ -fn find(haystack: str, needle: str) -> int { - let haystack_len: int = len_bytes(haystack) as int; - let needle_len: int = len_bytes(needle) as int; - if needle_len == 0 { ret 0; } - fn match_at(haystack: str, needle: str, i: int) -> bool { - let j: int = i; - for c: u8 in needle { if haystack[j] != c { ret false; } j += 1; } - ret true; - } - let i: int = 0; - while i <= haystack_len - needle_len { - if match_at(haystack, needle, i) { ret i; } - i += 1; - } - ret -1; +// Function: b2c_pos +// +// Convert a byte position into a char position +// within a given string +fn b2c_pos(ss: str, bpos: uint) -> uint { + assert bpos == 0u || bpos < len_bytes(ss); + + let ii = 0u; + let cpos = 0u; + + while ii < bpos { + let sz = utf8_char_width(ss[ii]); + ii += sz; + cpos += 1u; + } + + ret cpos; } /* @@ -917,7 +943,7 @@ haystack - The string to look in needle - The string to look for */ fn contains(haystack: str, needle: str) -> bool { - 0 <= find(haystack, needle) + option::is_some(find_bytes(haystack, needle)) } /* @@ -930,12 +956,12 @@ Parameters: haystack - The string to look in needle - The string to look for */ -fn starts_with(haystack: str, needle: str) -> bool { - let haystack_len: uint = len(haystack); - let needle_len: uint = len(needle); +fn starts_with(haystack: str, needle: str) -> bool unsafe { + let haystack_len: uint = len_bytes(haystack); + let needle_len: uint = len_bytes(needle); if needle_len == 0u { ret true; } if needle_len > haystack_len { ret false; } - ret eq(substr(haystack, 0u, needle_len), needle); + ret eq(unsafe::slice_bytes(haystack, 0u, needle_len), needle); } /* @@ -1695,25 +1721,39 @@ mod tests { } #[test] + fn test_find_bytes() { + // byte positions + assert (find_bytes("banana", "apple pie") == option::none); + assert (find_bytes("", "") == option::some(0u)); + + let data = "ประเทศไทย中华Việt Nam"; + assert (find_bytes(data, "") == option::some(0u)); + assert (find_bytes(data, "ประเ") == option::some( 0u)); + assert (find_bytes(data, "ะเ") == option::some( 6u)); + assert (find_bytes(data, "中华") == option::some(27u)); + assert (find_bytes(data, "ไท华") == option::none); + } + + #[test] fn test_find() { - fn t(haystack: str, needle: str, i: int) { - let j: int = find(haystack, needle); - log(debug, "searched for " + needle); - log(debug, j); - assert (i == j); - } - t("this is a simple", "is a", 5); - t("this is a simple", "is z", -1); - t("this is a simple", "", 0); - t("this is a simple", "simple", 10); - t("this", "simple", -1); + // char positions + assert (find("banana", "apple pie") == option::none); + assert (find("", "") == option::some(0u)); - // FIXME: return option<char> position instead let data = "ประเทศไทย中华Việt Nam"; - assert (find(data, "ประเ") == 0); - assert (find(data, "ะเ") == 6); // byte position - assert (find(data, "中华") == 27); // byte position - assert (find(data, "ไท华") == -1); + assert (find(data, "") == option::some(0u)); + assert (find(data, "ประเ") == option::some(0u)); + assert (find(data, "ะเ") == option::some(2u)); + assert (find(data, "中华") == option::some(9u)); + assert (find(data, "ไท华") == option::none); + } + + #[test] + fn test_b2c_pos() { + let data = "ประเทศไทย中华Việt Nam"; + assert 0u == b2c_pos(data, 0u); + assert 2u == b2c_pos(data, 6u); + assert 9u == b2c_pos(data, 27u); } #[test] diff --git a/src/libstd/test.rs b/src/libstd/test.rs index 8d5ecda2c48..5fd4d59f74d 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -258,7 +258,7 @@ fn filter_tests(opts: test_opts, fn filter_fn(test: test_desc, filter_str: str) -> option<test_desc> { - if str::find(test.name, filter_str) >= 0 { + if str::contains(test.name, filter_str) { ret option::some(test); } else { ret option::none; } } diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs index c15d6adc7ba..21a7e68cd20 100644 --- a/src/rustdoc/markdown_pass.rs +++ b/src/rustdoc/markdown_pass.rs @@ -56,10 +56,10 @@ fn should_write_modules_last() { fn d() { }" ); - let idx_a = str::find(markdown, "# Module `a`"); - let idx_b = str::find(markdown, "## Function `b`"); - let idx_c = str::find(markdown, "# Module `c`"); - let idx_d = str::find(markdown, "## Function `d`"); + let idx_a = option::get(str::find_bytes(markdown, "# Module `a`")); + let idx_b = option::get(str::find_bytes(markdown, "## Function `b`")); + let idx_c = option::get(str::find_bytes(markdown, "# Module `c`")); + let idx_d = option::get(str::find_bytes(markdown, "## Function `d`")); assert idx_b < idx_d; assert idx_d < idx_a; @@ -854,4 +854,4 @@ mod test { let markdown = render("mod morp { }"); assert str::contains(markdown, "Module `morp`\n\n"); } -} \ No newline at end of file +} |
