Skip to content

(core::str) changes to find / find_bytes #1831

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 14, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/comp/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
24 changes: 12 additions & 12 deletions src/comp/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
}
Expand Down
8 changes: 5 additions & 3 deletions src/compiletest/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
21 changes: 12 additions & 9 deletions src/compiletest/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
}
2 changes: 1 addition & 1 deletion src/compiletest/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion src/fuzzer/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
140 changes: 90 additions & 50 deletions src/libcore/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export
index,
rindex,
find,
find_bytes,
contains,
starts_with,
ends_with,
Expand Down Expand Up @@ -663,9 +664,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),
Expand Down Expand Up @@ -874,38 +876,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;
}

/*
Expand All @@ -919,7 +945,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))
}

/*
Expand All @@ -932,12 +958,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);
}

/*
Expand Down Expand Up @@ -1696,26 +1722,40 @@ mod tests {
assert [] == words("");
}

#[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]
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
}
Expand Down
10 changes: 5 additions & 5 deletions src/rustdoc/markdown_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -854,4 +854,4 @@ mod test {
let markdown = render("mod morp { }");
assert str::contains(markdown, "Module `morp`\n\n");
}
}
}