From 485413e2e9bba5dbc4bedc381c52681ac3260254 Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Sun, 5 Feb 2012 10:23:43 -0800 Subject: [PATCH 01/12] implement string iterators the simplest possible solution; it just calls str::chars_iter to do the iteration --- src/libcore/iter.rs | 19 ++++++++++++++++++- src/libcore/str.rs | 4 ++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 7aa08a6980c3c..1ba6c0e01a1a2 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -33,6 +33,12 @@ impl of iterable for option { } } +impl of iterable for str { + fn iter(blk: fn(&&char)) { + str::chars_iter(self, blk) + } +} + fn enumerate>(self: IA, blk: fn(uint, A)) { let i = 0u; self.iter {|a| @@ -168,4 +174,15 @@ fn test_repeat() { assert c == [0u, 1u, 4u, 9u, 16u]; } - +#[test] +fn test_str_char_iter() { + let i = 0u; + "፩፪፫".iter {|&&c: char| + alt i { + 0 { assert "፩" == c } + 1 { assert "፪" == c } + 2 { assert "፫" == c } + } + i += 1u; + } +} diff --git a/src/libcore/str.rs b/src/libcore/str.rs index ecb9827b85ea9..06e358ea564c9 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -768,7 +768,7 @@ Function: bytes_iter Iterate over the bytes in a string */ -fn bytes_iter(ss: str, it: fn(u8)) { +fn bytes_iter(ss: str, it: fn(&&u8)) { let pos = 0u; let len = byte_len(ss); @@ -783,7 +783,7 @@ Function: chars_iter Iterate over the characters in a string */ -fn chars_iter(s: str, it: fn(char)) { +fn chars_iter(s: str, it: fn(&&char)) { let pos = 0u, len = byte_len(s); while (pos < len) { let {ch, next} = char_range_at(s, pos); From 9d8f4b28820fa4b26e251704caa85f2bfc6562aa Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Mon, 6 Feb 2012 21:48:41 -0800 Subject: [PATCH 02/12] add iter::all and iter::any and use them in place of the few spots that used the str versions --- src/libcore/char.rs | 16 ++++---- src/libcore/core.rc | 3 +- src/libcore/iter.rs | 80 ++++++++++++++++++++++++++++++++++-- src/libcore/str.rs | 49 +++++++++++----------- src/libstd/rope.rs | 4 +- src/rustdoc/unindent_pass.rs | 4 +- 6 files changed, 117 insertions(+), 39 deletions(-) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 21028655626c5..8046c01b23535 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -48,7 +48,7 @@ import is_XID_continue = unicode::derived_property::XID_Continue; brief = "Indicates whether a character is in lower case, defined \ in terms of the Unicode General Category 'Ll'." )] -pure fn is_lowercase(c: char) -> bool { +pure fn is_lowercase(&&c: char) -> bool { ret unicode::general_category::Ll(c); } @@ -56,7 +56,7 @@ pure fn is_lowercase(c: char) -> bool { brief = "Indicates whether a character is in upper case, defined \ in terms of the Unicode General Category 'Lu'." )] -pure fn is_uppercase(c: char) -> bool { +pure fn is_uppercase(&&c: char) -> bool { ret unicode::general_category::Lu(c); } @@ -65,7 +65,7 @@ pure fn is_uppercase(c: char) -> bool { terms of the Unicode General Categories 'Zs', 'Zl', 'Zp' \ additional 'Cc'-category control codes in the range [0x09, 0x0d]" )] -pure fn is_whitespace(c: char) -> bool { +pure fn is_whitespace(&&c: char) -> bool { ret ('\x09' <= c && c <= '\x0d') || unicode::general_category::Zs(c) || unicode::general_category::Zl(c) @@ -77,7 +77,7 @@ pure fn is_whitespace(c: char) -> bool { in terms of the Unicode General Categories 'Nd', \ 'Nl', 'No' and the Derived Core Property 'Alphabetic'." )] -pure fn is_alphanumeric(c: char) -> bool { +pure fn is_alphanumeric(&&c: char) -> bool { ret unicode::derived_property::Alphabetic(c) || unicode::general_category::Nd(c) || unicode::general_category::Nl(c) || @@ -92,7 +92,7 @@ pure fn is_alphanumeric(c: char) -> bool { between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is \ 'b' or 'B', 11, etc." )] -pure fn to_digit(c: char) -> u8 unsafe { +pure fn to_digit(&&c: char) -> u8 unsafe { alt maybe_digit(c) { option::some(x) { x } option::none { fail; } @@ -103,7 +103,7 @@ pure fn to_digit(c: char) -> u8 unsafe { brief = "Convert a char to the corresponding digit. Returns none when \ character is not a valid hexadecimal digit." )] -pure fn maybe_digit(c: char) -> option { +pure fn maybe_digit(&&c: char) -> option { alt c { '0' to '9' { option::some(c as u8 - ('0' as u8)) } 'a' to 'z' { option::some(c as u8 + 10u8 - ('a' as u8)) } @@ -118,7 +118,7 @@ pure fn maybe_digit(c: char) -> option { #[doc( brief = "Convert a char to the corresponding lower case." )] -pure fn to_lower(c: char) -> char { +pure fn to_lower(&&c: char) -> char { alt c { 'A' to 'Z' { ((c as u8) + 32u8) as char } _ { c } @@ -131,7 +131,7 @@ pure fn to_lower(c: char) -> char { #[doc( brief = "Convert a char to the corresponding upper case." )] -pure fn to_upper(c: char) -> char { +pure fn to_upper(&&c: char) -> char { alt c { 'a' to 'z' { ((c as u8) - 32u8) as char } _ { c } diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 3bc5a03194937..2d377e9079373 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -36,6 +36,8 @@ export extfmt; export math; export tuple; +mod iter; + // Built-in-type support modules mod box; @@ -64,7 +66,6 @@ mod either; mod option; mod result; mod tuple; -mod iter; // Runtime and language-primitive support diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 1ba6c0e01a1a2..2fea7d2797a31 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1,3 +1,6 @@ +export iterable, enumerate, filter, map, flat_map, + foldl, to_list, repeat, all, any; + iface iterable { fn iter(blk: fn(A)); } @@ -64,6 +67,14 @@ fn map>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) { } } +//fn real_map, IB:iterable> +// (self: IA, cnv: fn@(A) -> B, blk: fn(B), new: IB) { +// self.iter {|a| +// new = new.append(blk(cnv(a))); +// } +// ret new; +//} + fn flat_map,IB:iterable>( self: IA, cnv: fn@(A) -> IB, blk: fn(B)) { self.iter {|a| @@ -91,6 +102,17 @@ fn repeat(times: uint, blk: fn()) { } } +fn all>(self: IA, prd: fn(A) -> bool) -> bool { + let r: bool = true; + self.iter {|a| + r = r && prd(a) + } + ret r; +} + +fn any>(self: IA, prd: fn(A) -> bool) -> bool { + !all(self, {|c| !prd(c) }) +} #[test] fn test_enumerate() { @@ -179,10 +201,62 @@ fn test_str_char_iter() { let i = 0u; "፩፪፫".iter {|&&c: char| alt i { - 0 { assert "፩" == c } - 1 { assert "፪" == c } - 2 { assert "፫" == c } + 0u { assert '፩' == c } + 1u { assert '፪' == c } + 2u { assert '፫' == c } } i += 1u; } } + +#[test] +fn test_str_all() { + assert true == all("፩፪፫") {|&&c| + unicode::general_category::No(c) + }; + assert false == all("፩፪፫") {|&&c| + unicode::general_category::Lu(c) + }; + assert false == all("፩፪3") {|&&c| + unicode::general_category::No(c) + }; + assert true == all("") {|&&c| + unicode::general_category::Lu(c) + }; +} + +#[test] +fn test_str_all_calls() { + let calls: uint = 0u; + assert false == all("፩2፫") {|&&c| + calls += 1u; + unicode::general_category::No(c) + }; + assert calls == 2u; +} + +#[test] +fn test_str_any() { + assert true == any("፩፪፫") {|&&c| + unicode::general_category::No(c) + }; + assert false == any("፩፪፫") {|&&c| + unicode::general_category::Lu(c) + }; + assert true == any("1፪፫") {|&&c| + unicode::general_category::No(c) + }; + assert false == any("") {|&&c| + unicode::general_category::Lu(c) + }; +} + +#[test] +fn test_str_any_calls() { + let calls: uint = 0u; + assert true == any("፩2፫") {|&&c| + calls += 1u; + unicode::general_category::Nd(c) + }; + assert calls == 2u; +} diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 06e358ea564c9..6b6bdd6a8fc78 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -58,8 +58,8 @@ export hash, // Iterating through strings - all, - any, + //all, + //any, map, bytes_iter, chars_iter, @@ -100,7 +100,7 @@ export unsafe; - +import iter::iterable; #[abi = "cdecl"] native mod rustrt { @@ -545,7 +545,7 @@ Splits a string into substrings using a function FIXME: rename to 'split' */ -fn split_func(ss: str, sepfn: fn(cc: char)->bool) -> [str] { +fn split_func(ss: str, sepfn: fn(&&cc: char)->bool) -> [str] { let vv: [str] = []; let accum: str = ""; let ends_with_sep: bool = false; @@ -688,7 +688,7 @@ Escapes special characters inside the string, making it safe for transfer. */ fn escape(s: str) -> str { let r = ""; - all(s, { |c| r += escape_char(c); true }); + iter::all(s, { |c| r += escape_char(c); true }); r } @@ -734,9 +734,9 @@ Function: all Return true if a predicate matches all characters or if the string contains no characters */ -fn all(s: str, it: fn(char) -> bool) -> bool{ - ret substr_all(s, 0u, byte_len(s), it); -} +//fn all(s: str, it: fn(&&char) -> bool) -> bool{ +// ret substr_all(s, 0u, byte_len(s), it); +//} /* Function: any @@ -744,16 +744,17 @@ Function: any Return true if a predicate matches any character (and false if it matches none or there are no characters) */ -fn any(ss: str, pred: fn(char) -> bool) -> bool { - !all(ss, {|cc| !pred(cc)}) -} +//fn any(ss: str, pred: fn(char) -> bool) -> bool { +// !all(ss, {|cc| !pred(cc)}) +//} /* Function: map Apply a function to each character */ -fn map(ss: str, ff: fn(char) -> char) -> str { +fn map(ss: str, ff: fn(&&char) -> char) -> str { +// iter::map(ss, {|c| c}, ff); let result = ""; chars_iter(ss, {|cc| @@ -988,7 +989,7 @@ Function: is_whitespace Returns true if the string contains only whitespace */ fn is_whitespace(s: str) -> bool { - ret all(s, char::is_whitespace); + ret iter::all(s, char::is_whitespace); } /* @@ -1226,7 +1227,7 @@ Safety note: represent valid positions inside `s` */ fn substr_all(s: str, byte_offset: uint, byte_len: uint, - it: fn(char) -> bool) -> bool { + it: fn(&&char) -> bool) -> bool { let i = byte_offset; let result = true; while i < byte_len { @@ -1971,20 +1972,20 @@ mod tests { #[test] fn test_all() { - assert true == all("", char::is_uppercase); - assert false == all("ymca", char::is_uppercase); - assert true == all("YMCA", char::is_uppercase); - assert false == all("yMCA", char::is_uppercase); - assert false == all("YMCy", char::is_uppercase); + assert true == iter::all("", char::is_uppercase); + assert false == iter::all("ymca", char::is_uppercase); + assert true == iter::all("YMCA", char::is_uppercase); + assert false == iter::all("yMCA", char::is_uppercase); + assert false == iter::all("YMCy", char::is_uppercase); } #[test] fn test_any() { - assert false == any("", char::is_uppercase); - assert false == any("ymca", char::is_uppercase); - assert true == any("YMCA", char::is_uppercase); - assert true == any("yMCA", char::is_uppercase); - assert true == any("Ymcy", char::is_uppercase); + assert false == iter::any("", char::is_uppercase); + assert false == iter::any("ymca", char::is_uppercase); + assert true == iter::any("YMCA", char::is_uppercase); + assert true == iter::any("yMCA", char::is_uppercase); + assert true == iter::any("Ymcy", char::is_uppercase); } #[test] diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index 28cdbfa3d4055..e6a49d710acdb 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -419,7 +419,7 @@ Returns: `true` If execution proceeded correctly, `false` if it was interrupted, that is if `it` returned `false` at any point. */ -fn loop_chars(rope: rope, it: fn(char) -> bool) -> bool { +fn loop_chars(rope: rope, it: fn(&&char) -> bool) -> bool { alt(rope) { node::empty { ret true } node::content(x) { ret node::loop_chars(x, it) } @@ -1135,7 +1135,7 @@ mod node { ret result; } - fn loop_chars(node: @node, it: fn(char) -> bool) -> bool { + fn loop_chars(node: @node, it: fn(&&char) -> bool) -> bool { ret loop_leaves(node, {|leaf| ret str::substr_all(*leaf.content, leaf.byte_offset, diff --git a/src/rustdoc/unindent_pass.rs b/src/rustdoc/unindent_pass.rs index 9c43ce4486414..b6726010be35e 100644 --- a/src/rustdoc/unindent_pass.rs +++ b/src/rustdoc/unindent_pass.rs @@ -13,6 +13,8 @@ middle of a line, and each of the following lines is indented. export mk_pass; +import iter::iterable; + fn mk_pass() -> pass { desc_pass::mk_pass(unindent) } @@ -47,7 +49,7 @@ fn unindent(s: str) -> str { } else { saw_first_line = true; let spaces = 0u; - str::all(line) {|char| + iter::all(line) {|char| // Only comparing against space because I wouldn't // know what to do with mixed whitespace chars if char == ' ' { From b068e8c547b6d3b53f84b526a5c320f93d976054 Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Sat, 18 Feb 2012 16:19:07 -0800 Subject: [PATCH 03/12] split the iterators up by type --- src/comp/syntax/ext/qquote.rs | 4 +++- src/libcore/core.rc | 10 +++++++--- src/libcore/iter.rs | 13 ++++++------- src/libcore/str.rs | 3 +-- src/libcore/str_bytes.rs | 26 ++++++++++++++++++++++++++ src/libcore/str_chars.rs | 24 ++++++++++++++++++++++++ src/libcore/str_lines.rs | 27 +++++++++++++++++++++++++++ src/libcore/str_words.rs | 29 +++++++++++++++++++++++++++++ src/rustdoc/unindent_pass.rs | 2 +- 9 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 src/libcore/str_bytes.rs create mode 100644 src/libcore/str_chars.rs create mode 100644 src/libcore/str_lines.rs create mode 100644 src/libcore/str_words.rs diff --git a/src/comp/syntax/ext/qquote.rs b/src/comp/syntax/ext/qquote.rs index f215d3741111a..bde01bcc84803 100644 --- a/src/comp/syntax/ext/qquote.rs +++ b/src/comp/syntax/ext/qquote.rs @@ -16,6 +16,8 @@ import std::io::*; import codemap::span; +import str_iter::iterable_by_chars; + type aq_ctxt = @{lo: uint, mutable gather: [{lo: uint, hi: uint, e: @ast::expr, @@ -204,7 +206,7 @@ fn expand_qquote let state = active; let i = 0u, j = 0u; let g_len = vec::len(cx.gather); - str::chars_iter(str) {|ch| + iter::each() {|ch| if (j < g_len && i == cx.gather[j].lo) { assert ch == '$'; let repl = #fmt("$%u ", j); diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 2d377e9079373..f5ee56c1d2e7c 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -28,7 +28,8 @@ This behavior can be disabled with the `no_core` crate attribute." )]; -export box, char, float, bessel, f32, f64, int, str, ptr; +export box, char, float, bessel, f32, f64, int, ptr; +export str_bytes, str_chars, str_words, str_lines, str; export uint, u8, u32, u64, vec, bool; export either, option, result, iter; export ctypes, sys, unsafe, comm, task, logging; @@ -36,8 +37,6 @@ export extfmt; export math; export tuple; -mod iter; - // Built-in-type support modules mod box; @@ -47,6 +46,10 @@ mod bessel; mod f32; mod f64; mod int; +mod str_bytes; +mod str_chars; +mod str_words; +mod str_lines; mod str; mod ptr; mod uint; @@ -66,6 +69,7 @@ mod either; mod option; mod result; mod tuple; +mod iter; // Runtime and language-primitive support diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 2fea7d2797a31..ea1fa363981ef 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1,5 +1,6 @@ +import str_chars::iterable_by_chars; export iterable, enumerate, filter, map, flat_map, - foldl, to_list, repeat, all, any; + foldl, to_list, repeat, all, any, each; iface iterable { fn iter(blk: fn(A)); @@ -36,12 +37,6 @@ impl of iterable for option { } } -impl of iterable for str { - fn iter(blk: fn(&&char)) { - str::chars_iter(self, blk) - } -} - fn enumerate>(self: IA, blk: fn(uint, A)) { let i = 0u; self.iter {|a| @@ -114,6 +109,10 @@ fn any>(self: IA, prd: fn(A) -> bool) -> bool { !all(self, {|c| !prd(c) }) } +fn each>(self: IA, blk: fn(A)) { + self.iter(blk); +} + #[test] fn test_enumerate() { enumerate(["0", "1", "2"]) {|i,j| diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 6b6bdd6a8fc78..18b3023035fd2 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -100,7 +100,7 @@ export unsafe; -import iter::iterable; +import str_chars::iterable_by_chars; #[abi = "cdecl"] native mod rustrt { @@ -754,7 +754,6 @@ Function: map Apply a function to each character */ fn map(ss: str, ff: fn(&&char) -> char) -> str { -// iter::map(ss, {|c| c}, ff); let result = ""; chars_iter(ss, {|cc| diff --git a/src/libcore/str_bytes.rs b/src/libcore/str_bytes.rs new file mode 100644 index 0000000000000..7aaeb38004130 --- /dev/null +++ b/src/libcore/str_bytes.rs @@ -0,0 +1,26 @@ +export iterable_by_bytes; +import iter::iterable; +import str::bytes_iter; + +impl iterable_by_bytes of iterable for str { + fn iter(blk: fn(&&u8)) { + str::bytes_iter(self, blk) + } +} + +#[test] +fn test_bytes_iter() { + let i = 0; + + iter::map("xyz") {|bb| + alt i { + 0 { assert bb == 'x' as u8; } + 1 { assert bb == 'y' as u8; } + 2 { assert bb == 'z' as u8; } + } + i += 1; + } + + iter::map("") {|bb| assert bb == 0u8; } +} + diff --git a/src/libcore/str_chars.rs b/src/libcore/str_chars.rs new file mode 100644 index 0000000000000..e288edbc559b8 --- /dev/null +++ b/src/libcore/str_chars.rs @@ -0,0 +1,24 @@ +import iter::iterable; +import str::chars_iter; +export iterable_by_chars; + +impl iterable_by_chars of iterable for str { + fn iter(blk: fn(&&char)) { + str::chars_iter(self, blk) + } +} + +#[test] +fn test_chars_iter() { + let i = 0; + iter::map("x\u03c0y") {|ch| + alt i { + 0 { assert ch == 'x'; } + 1 { assert ch == '\u03c0'; } + 2 { assert ch == 'y'; } + } + i += 1; + } + + iter::map("") {|_ch| fail; } // should not fail +} diff --git a/src/libcore/str_lines.rs b/src/libcore/str_lines.rs new file mode 100644 index 0000000000000..2518808aed334 --- /dev/null +++ b/src/libcore/str_lines.rs @@ -0,0 +1,27 @@ +export iterable_by_lines; +import iter::iterable; +import str::lines_iter; + +impl iterable_by_lines of iterable for str { + fn iter(blk: fn(&&str)) { + str::lines_iter(self, blk) + } +} + +#[test] +fn test_lines_iter () { + let lf = "\nMary had a little lamb\nLittle lamb\n"; + + let ii = 0; + + iter::map(lf) {|x| + alt ii { + 0 { assert "" == x; } + 1 { assert "Mary had a little lamb" == x; } + 2 { assert "Little lamb" == x; } + 3 { assert "" == x; } + _ { () } + } + ii += 1; + } +} diff --git a/src/libcore/str_words.rs b/src/libcore/str_words.rs new file mode 100644 index 0000000000000..49b3c137bb52a --- /dev/null +++ b/src/libcore/str_words.rs @@ -0,0 +1,29 @@ +export iterable_by_words; +import iter::iterable; +import str::words_iter; + +impl iterable_by_words of iterable for str { + fn iter(blk: fn(&&str)) { + str::words_iter(self, blk) + } +} + +#[test] +fn test_words_iter() { + let data = "\nMary had a little lamb\nLittle lamb\n"; + + let ii = 0; + + iter::map(data) {|ww| + alt ii { + 0 { assert "Mary" == ww; } + 1 { assert "had" == ww; } + 2 { assert "a" == ww; } + 3 { assert "little" == ww; } + _ { () } + } + ii += 1; + } + + iter::map("") {|_x| fail; } // should not fail +} diff --git a/src/rustdoc/unindent_pass.rs b/src/rustdoc/unindent_pass.rs index b6726010be35e..def1a16ac3638 100644 --- a/src/rustdoc/unindent_pass.rs +++ b/src/rustdoc/unindent_pass.rs @@ -13,7 +13,7 @@ middle of a line, and each of the following lines is indented. export mk_pass; -import iter::iterable; +import str_iter::iterable_by_chars; fn mk_pass() -> pass { desc_pass::mk_pass(unindent) From 118e21151deec84951de4ff7fc3a20e7148a9aa1 Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Sat, 18 Feb 2012 22:07:01 -0800 Subject: [PATCH 04/12] fix syntax error from the manual merge --- src/libcore/iter.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 167a40fd71402..3ff716c218e38 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -152,6 +152,7 @@ fn any>(self: IA, prd: fn(A) -> bool) -> bool { fn each>(self: IA, blk: fn(A)) { self.iter(blk); +} fn min>(self: IA) -> A { alt foldl::,IA>(self, none) {|a, b| From 5086ea9245934ac91272b9c2e54b6f2c58c3965f Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Tue, 21 Feb 2012 00:58:02 -0800 Subject: [PATCH 05/12] it'll fail if you don't have git, so mark that as required --- configure | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/configure b/configure index a910f6d9eabf5..41a65d38252e5 100755 --- a/configure +++ b/configure @@ -280,11 +280,10 @@ fi step_msg "looking for build programs" -probe_need CFG_PERL perl -probe_need CFG_PYTHON python python2.6 python2 python3 -probe_need CFG_CURL curl - -probe CFG_GIT git +probe_need CFG_PERL perl +probe_need CFG_PYTHON python python2.6 python2 python3 +probe_need CFG_CURL curl +probe_need CFG_GIT git probe CFG_CLANG clang++ probe CFG_GCC gcc probe CFG_LLVM_CONFIG llvm-config From 5b193e753b44bca82b8dca4d18f7b82d4aae1c5e Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Wed, 22 Feb 2012 09:45:29 -0800 Subject: [PATCH 06/12] some cleanup --- src/comp/syntax/ext/qquote.rs | 4 ++-- src/libcore/core.rc | 6 +++--- src/libcore/iter.rs | 6 ------ src/libcore/str.rs | 2 +- src/libcore/str_bytes.rs | 30 ++++++++++++++++-------------- src/libcore/str_chars.rs | 20 +++++++++----------- 6 files changed, 31 insertions(+), 37 deletions(-) diff --git a/src/comp/syntax/ext/qquote.rs b/src/comp/syntax/ext/qquote.rs index c8ef21d4f64a0..8fe31b23537a2 100644 --- a/src/comp/syntax/ext/qquote.rs +++ b/src/comp/syntax/ext/qquote.rs @@ -14,7 +14,7 @@ import std::io::*; import codemap::span; -import str_iter::iterable_by_chars; +import str_chars::iterable_by_chars; type aq_ctxt = @{lo: uint, mutable gather: [{lo: uint, hi: uint, @@ -197,7 +197,7 @@ fn finish let state = active; let i = 0u, j = 0u; let g_len = vec::len(cx.gather); - iter::each() {|ch| + iter::each(str) {|ch| if (j < g_len && i == cx.gather[j].lo) { assert ch == '$'; let repl = #fmt("$%u ", j); diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 9086dfa28ca18..14b8c1c21c909 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -32,7 +32,7 @@ export int, i8, i16, i32, i64; export uint, u8, u16, u32, u64; export float, f32, f64; export box, char, ptr, vec, bool; -export str_bytes, str_chars, str_words, str_lines, str; +export str, str_chars, str_bytes; export either, option, result, iter; export ctypes, sys, unsafe, comm, task, logging; export extfmt; @@ -50,8 +50,8 @@ mod f64; mod int; mod str_bytes; mod str_chars; -mod str_words; -mod str_lines; +//mod str_words; +//mod str_lines; mod i8; mod i16; mod i32; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 3ff716c218e38..750d2270efc71 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -37,12 +37,6 @@ impl of iterable for option { } } -impl of iterable for str { - fn iter(blk: fn(&&char)) { - str::chars_iter(self) { |ch| blk(ch) } - } -} - fn enumerate>(self: IA, blk: fn(uint, A)) { let i = 0u; self.iter {|a| diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 5cf1702c29d78..52c93f8acc4f4 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -783,7 +783,7 @@ Function: chars_iter Iterate over the characters in a string */ fn chars_iter(s: str, it: fn(&&char)) { - let pos = 0u, len = byte_len(s); + let pos = 0u, len = len_bytes(s); while (pos < len) { let {ch, next} = char_range_at(s, pos); pos = next; diff --git a/src/libcore/str_bytes.rs b/src/libcore/str_bytes.rs index 7aaeb38004130..e92a702b62146 100644 --- a/src/libcore/str_bytes.rs +++ b/src/libcore/str_bytes.rs @@ -1,26 +1,28 @@ -export iterable_by_bytes; import iter::iterable; -import str::bytes_iter; +export iterable_by_bytes; impl iterable_by_bytes of iterable for str { fn iter(blk: fn(&&u8)) { - str::bytes_iter(self, blk) + str::bytes_iter(self) { |b| blk(b) } } } #[test] -fn test_bytes_iter() { - let i = 0; - - iter::map("xyz") {|bb| +fn test_str_byte_iter() { + let i = 0u; + "፩፪፫".iter {|&&b: u8| alt i { - 0 { assert bb == 'x' as u8; } - 1 { assert bb == 'y' as u8; } - 2 { assert bb == 'z' as u8; } + 0u { assert 0xe1 as u8 == b } + 1u { assert 0x8d as u8 == b } + 2u { assert 0xa9 as u8 == b } + 4u { assert 0xe1 as u8 == b } + 5u { assert 0x8d as u8 == b } + 6u { assert 0xaa as u8 == b } + 7u { assert 0xe1 as u8 == b } + 8u { assert 0x8d as u8 == b } + 9u { assert 0xab as u8 == b } + _ { fail; } } - i += 1; + i += 1u; } - - iter::map("") {|bb| assert bb == 0u8; } } - diff --git a/src/libcore/str_chars.rs b/src/libcore/str_chars.rs index e288edbc559b8..491f154803164 100644 --- a/src/libcore/str_chars.rs +++ b/src/libcore/str_chars.rs @@ -1,24 +1,22 @@ import iter::iterable; -import str::chars_iter; export iterable_by_chars; impl iterable_by_chars of iterable for str { fn iter(blk: fn(&&char)) { - str::chars_iter(self, blk) + str::chars_iter(self) { |ch| blk(ch) } } } #[test] -fn test_chars_iter() { - let i = 0; - iter::map("x\u03c0y") {|ch| +fn test_str_char_iter() { + let i = 0u; + "፩፪፫".iter {|&&c: char| alt i { - 0 { assert ch == 'x'; } - 1 { assert ch == '\u03c0'; } - 2 { assert ch == 'y'; } + 0u { assert '፩' == c } + 1u { assert '፪' == c } + 2u { assert '፫' == c } + _ { fail; } } - i += 1; + i += 1u; } - - iter::map("") {|_ch| fail; } // should not fail } From ab9b2e2446995751531e1fd3abaf408171f5491a Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Wed, 29 Feb 2012 08:56:37 -0800 Subject: [PATCH 07/12] move str iterators to submodules --- src/cargo/pgp.rs | 8 +- src/comp/syntax/ext/qquote.rs | 4 +- src/libcore/char.rs | 20 +- src/libcore/core.rc | 7 +- src/libcore/iter.rs | 74 ------- src/libcore/str.rs | 370 +++++++++++++++++++--------------- src/libcore/str_bytes.rs | 28 --- src/libcore/str_chars.rs | 22 -- src/libcore/str_lines.rs | 27 --- src/libcore/str_words.rs | 29 --- src/rustdoc/unindent_pass.rs | 2 +- 11 files changed, 228 insertions(+), 363 deletions(-) delete mode 100644 src/libcore/str_bytes.rs delete mode 100644 src/libcore/str_chars.rs delete mode 100644 src/libcore/str_lines.rs delete mode 100644 src/libcore/str_words.rs diff --git a/src/cargo/pgp.rs b/src/cargo/pgp.rs index b22a225e46baf..de5107b06e07b 100644 --- a/src/cargo/pgp.rs +++ b/src/cargo/pgp.rs @@ -2,6 +2,7 @@ use std; import std::fs; import std::run; +import str::lines::iterable; fn gpg(args: [str]) -> { status: int, out: str, err: str } { ret run::program_output("gpg", args); @@ -94,10 +95,5 @@ fn verify(root: str, data: str, sig: str, keyfp: str) -> bool { let p = gpg(["--homedir", path, "--with-fingerprint", "--verify", sig, data]); let res = "Primary key fingerprint: " + keyfp; - for line in str::split_byte(p.err, '\n' as u8) { - if line == res { - ret true; - } - } - ret false; + ret iter::any(p.err) {|&&line| line == res }; } diff --git a/src/comp/syntax/ext/qquote.rs b/src/comp/syntax/ext/qquote.rs index 8fe31b23537a2..65038e2c33636 100644 --- a/src/comp/syntax/ext/qquote.rs +++ b/src/comp/syntax/ext/qquote.rs @@ -14,7 +14,7 @@ import std::io::*; import codemap::span; -import str_chars::iterable_by_chars; +import str::chars::iterable; type aq_ctxt = @{lo: uint, mutable gather: [{lo: uint, hi: uint, @@ -197,7 +197,7 @@ fn finish let state = active; let i = 0u, j = 0u; let g_len = vec::len(cx.gather); - iter::each(str) {|ch| + (*str).iter() {|ch| if (j < g_len && i == cx.gather[j].lo) { assert ch == '$'; let repl = #fmt("$%u ", j); diff --git a/src/libcore/char.rs b/src/libcore/char.rs index d45a7e31d7947..574b4895476fe 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -43,13 +43,13 @@ export is_alphabetic, import is_alphabetic = unicode::derived_property::Alphabetic; import is_XID_start = unicode::derived_property::XID_Start; import is_XID_continue = unicode::derived_property::XID_Continue; - +import str::chars::iterable; #[doc( brief = "Indicates whether a character is in lower case, defined \ in terms of the Unicode General Category 'Ll'." )] -pure fn is_lowercase(&&c: char) -> bool { +pure fn is_lowercase(c: char) -> bool { ret unicode::general_category::Ll(c); } @@ -57,7 +57,7 @@ pure fn is_lowercase(&&c: char) -> bool { brief = "Indicates whether a character is in upper case, defined \ in terms of the Unicode General Category 'Lu'." )] -pure fn is_uppercase(&&c: char) -> bool { +pure fn is_uppercase(c: char) -> bool { ret unicode::general_category::Lu(c); } @@ -66,7 +66,7 @@ pure fn is_uppercase(&&c: char) -> bool { terms of the Unicode General Categories 'Zs', 'Zl', 'Zp' \ additional 'Cc'-category control codes in the range [0x09, 0x0d]" )] -pure fn is_whitespace(&&c: char) -> bool { +pure fn is_whitespace(c: char) -> bool { ret ('\x09' <= c && c <= '\x0d') || unicode::general_category::Zs(c) || unicode::general_category::Zl(c) @@ -78,7 +78,7 @@ pure fn is_whitespace(&&c: char) -> bool { in terms of the Unicode General Categories 'Nd', \ 'Nl', 'No' and the Derived Core Property 'Alphabetic'." )] -pure fn is_alphanumeric(&&c: char) -> bool { +pure fn is_alphanumeric(c: char) -> bool { ret unicode::derived_property::Alphabetic(c) || unicode::general_category::Nd(c) || unicode::general_category::Nl(c) || @@ -115,7 +115,7 @@ pure fn to_digit(&&c: char) -> u8 unsafe { brief = "Convert a char to the corresponding digit. Returns none when \ character is not a valid hexadecimal digit." )] -pure fn maybe_digit(&&c: char) -> option { +pure fn maybe_digit(c: char) -> option { alt c { '0' to '9' { option::some(c as u8 - ('0' as u8)) } 'a' to 'z' { option::some(c as u8 + 10u8 - ('a' as u8)) } @@ -130,7 +130,7 @@ pure fn maybe_digit(&&c: char) -> option { #[doc( brief = "Convert a char to the corresponding lower case." )] -pure fn to_lower(&&c: char) -> char { +pure fn to_lower(c: char) -> char { alt c { 'A' to 'Z' { ((c as u8) + 32u8) as char } _ { c } @@ -143,7 +143,7 @@ pure fn to_lower(&&c: char) -> char { #[doc( brief = "Convert a char to the corresponding upper case." )] -pure fn to_upper(&&c: char) -> char { +pure fn to_upper(c: char) -> char { alt c { 'a' to 'z' { ((c as u8) - 32u8) as char } _ { c } @@ -236,8 +236,8 @@ fn test_to_upper() { #[test] fn test_is_ascii() unsafe { - assert str::all("banana", char::is_ascii); - assert ! str::all("ประเทศไทย中华Việt Nam", char::is_ascii); + assert iter::all("banana", {|&&ch| char::is_ascii(ch) }); + assert ! iter::all("ประเทศไทย中华Việt Nam", {|&&ch| char::is_ascii(ch) }); } #[test] diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 14b8c1c21c909..868762a090f06 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -31,8 +31,7 @@ This behavior can be disabled with the `no_core` crate attribute." export int, i8, i16, i32, i64; export uint, u8, u16, u32, u64; export float, f32, f64; -export box, char, ptr, vec, bool; -export str, str_chars, str_bytes; +export box, char, str, ptr, vec, bool; export either, option, result, iter; export ctypes, sys, unsafe, comm, task, logging; export extfmt; @@ -48,10 +47,6 @@ mod bessel; mod f32; mod f64; mod int; -mod str_bytes; -mod str_chars; -//mod str_words; -//mod str_lines; mod i8; mod i16; mod i32; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 750d2270efc71..a6d05878b6c43 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1,4 +1,3 @@ -import str_chars::iterable_by_chars; export iterable, enumerate, filter, map, flat_map, foldl, to_list, repeat, all, any, each; @@ -72,14 +71,6 @@ fn map>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) { } } -//fn real_map, IB:iterable> -// (self: IA, cnv: fn@(A) -> B, blk: fn(B), new: IB) { -// self.iter {|a| -// new = new.append(blk(cnv(a))); -// } -// ret new; -//} - fn flat_map,IB:iterable>( self: IA, cnv: fn@(A) -> IB, blk: fn(B)) { self.iter {|a| @@ -275,71 +266,6 @@ fn test_repeat() { assert c == [0u, 1u, 4u, 9u, 16u]; } -#[test] -fn test_str_char_iter() { - let i = 0u; - "፩፪፫".iter {|&&c: char| - alt i { - 0u { assert '፩' == c } - 1u { assert '፪' == c } - 2u { assert '፫' == c } - } - i += 1u; - } -} - -#[test] -fn test_str_all() { - assert true == all("፩፪፫") {|&&c| - unicode::general_category::No(c) - }; - assert false == all("፩፪፫") {|&&c| - unicode::general_category::Lu(c) - }; - assert false == all("፩፪3") {|&&c| - unicode::general_category::No(c) - }; - assert true == all("") {|&&c| - unicode::general_category::Lu(c) - }; -} - -#[test] -fn test_str_all_calls() { - let calls: uint = 0u; - assert false == all("፩2፫") {|&&c| - calls += 1u; - unicode::general_category::No(c) - }; - assert calls == 2u; -} - -#[test] -fn test_str_any() { - assert true == any("፩፪፫") {|&&c| - unicode::general_category::No(c) - }; - assert false == any("፩፪፫") {|&&c| - unicode::general_category::Lu(c) - }; - assert true == any("1፪፫") {|&&c| - unicode::general_category::No(c) - }; - assert false == any("") {|&&c| - unicode::general_category::Lu(c) - }; -} - -#[test] -fn test_str_any_calls() { - let calls: uint = 0u; - assert true == any("፩2፫") {|&&c| - calls += 1u; - unicode::general_category::Nd(c) - }; - assert calls == 2u; -} - #[test] fn test_min() { assert min([5, 4, 1, 2, 3]) == 1; diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 52c93f8acc4f4..6c33732a112b7 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -10,6 +10,8 @@ For some heavy-duty uses, we recommend trying std::rope. */ import option::{some, none}; +import iter::iterable; +import str::chars::iterable; export // Creating a string @@ -57,17 +59,6 @@ export le, hash, - // Iterating through strings - //all, - //any, - map, - bytes_iter, - chars_iter, - split_char_iter, - splitn_char_iter, - words_iter, - lines_iter, - // Searching index, byte_index, @@ -106,8 +97,6 @@ export unsafe; -import str_chars::iterable_by_chars; - #[abi = "cdecl"] native mod rustrt { fn rust_str_push(&s: str, ch: u8); @@ -424,7 +413,7 @@ fn split_byte(ss: str, sep: u8) -> [str] unsafe { let vv = []; let start = 0u, current = 0u; - str::bytes_iter(ss) {|cc| + bytes_iter(ss) {|cc| if sep == cc { vec::push(vv, str::unsafe::slice_bytes(ss, start, current)); start = current + 1u; @@ -482,7 +471,7 @@ fn split_str(ss: str, sep: str) -> [str] unsafe { let vv = []; let start = 0u, start_match = 0u, current = 0u, matching = 0u; - str::bytes_iter(ss) {|cc| + bytes_iter(ss) {|cc| if sep[matching] == cc { matching += 1u; } else { @@ -726,32 +715,12 @@ fn hash(&&s: str) -> uint { Section: Iterating through strings */ -/* -Function: all - -Return true if a predicate matches all characters or -if the string contains no characters -*/ -//fn all(s: str, it: fn(&&char) -> bool) -> bool{ -// ret substr_all(s, 0u, byte_len(s), it); -//} - -/* -Function: any - -Return true if a predicate matches any character -(and false if it matches none or there are no characters) -*/ -//fn any(ss: str, pred: fn(char) -> bool) -> bool { -// !all(ss, {|cc| !pred(cc)}) -//} - /* Function: map Apply a function to each character */ -fn map(ss: str, ff: fn(&&char) -> char) -> str { +fn map(ss: str, ff: fn(char) -> char) -> str { let result = ""; reserve(result, len_bytes(ss)); @@ -791,44 +760,6 @@ fn chars_iter(s: str, it: fn(&&char)) { } } -/* -Function: split_char_iter - -Apply a function to each substring after splitting -by character -*/ -fn split_char_iter(ss: str, cc: char, ff: fn(&&str)) { - vec::iter(split_char(ss, cc), ff) -} - -/* -Function: splitn_char_iter - -Apply a function to each substring after splitting -by character, up to `count` times -*/ -fn splitn_char_iter(ss: str, sep: char, count: uint, ff: fn(&&str)) unsafe { - vec::iter(splitn_char(ss, sep, count), ff) -} - -/* -Function: words_iter - -Apply a function to each word -*/ -fn words_iter(ss: str, ff: fn(&&str)) { - vec::iter(words(ss), ff) -} - -/* -Function: lines_iter - -Apply a function to each lines (by '\n') -*/ -fn lines_iter(ss: str, ff: fn(&&str)) { - vec::iter(lines(ss), ff) -} - /* Section: Searching */ @@ -1054,7 +985,7 @@ Function: is_whitespace Returns true if the string contains only whitespace */ fn is_whitespace(s: str) -> bool { - ret iter::all(s, char::is_whitespace); + ret iter::all(s, {|&&ch| char::is_whitespace(ch) }); } @@ -1501,6 +1432,202 @@ mod unsafe { } +mod bytes { + export iterable; + impl iterable of iterable for str { + fn iter(blk: fn(&&u8)) { + let pos = 0u; + let len = str::len_bytes(self); + + while (pos < len) { + blk(self[pos]); + pos += 1u; + } + } + } + + #[test] + fn test_str_byte_iter() { + let i = 0u; + "፩፪፫".iter {|&&b: u8| + alt i { + 0u { assert 0xe1_u8 == b } + 1u { assert 0x8d_u8 == b } + 2u { assert 0xa9_u8 == b } + 3u { assert 0xe1_u8 == b } + 4u { assert 0x8d_u8 == b } + 5u { assert 0xaa_u8 == b } + 6u { assert 0xe1_u8 == b } + 7u { assert 0x8d_u8 == b } + 8u { assert 0xab_u8 == b } + 9u { assert 0x00_u8 == b } + _ { fail; } + } + i += 1u; + } + } +} + +mod chars { + export iterable; + impl iterable of iterable for str { + fn iter(blk: fn(&&char)) { + let pos = 0u, len = str::len_bytes(self); + while (pos < len) { + let {ch, next} = str::char_range_at(self, pos); + pos = next; + blk(ch); + } + } + } + + #[test] + fn test_str_char_iter() { + let i = 0u; + "፩፪፫".iter {|&&c: char| + alt i { + 0u { assert '፩' == c } + 1u { assert '፪' == c } + 2u { assert '፫' == c } + _ { fail; } + } + i += 1u; + } + } + + #[test] + fn test_str_all() { + assert true == iter::all("፩፪፫") {|&&c| + unicode::general_category::No(c) + }; + assert false == iter::all("፩፪፫") {|&&c| + unicode::general_category::Lu(c) + }; + assert false == iter::all("፩፪3") {|&&c| + unicode::general_category::No(c) + }; + assert true == iter::all("") {|&&c| + unicode::general_category::Lu(c) + }; + } + + #[test] + fn test_str_all_calls() { + let calls: uint = 0u; + assert false == iter::all("፩2፫") {|&&c| + calls += 1u; + unicode::general_category::No(c) + }; + assert calls == 2u; + } + + #[test] + fn test_str_any() { + assert true == iter::any("፩፪፫") {|&&c| + unicode::general_category::No(c) + }; + assert false == iter::any("፩፪፫") {|&&c| + unicode::general_category::Lu(c) + }; + assert true == iter::any("1፪፫") {|&&c| + unicode::general_category::No(c) + }; + assert false == iter::any("") {|&&c| + unicode::general_category::Lu(c) + }; + } + + #[test] + fn test_str_any_calls() { + let calls: uint = 0u; + assert true == iter::any("፩2፫") {|&&c| + calls += 1u; + unicode::general_category::Nd(c) + }; + assert calls == 2u; + } +} + +mod words { + export iterable; + impl iterable of iterable for str { + fn iter(blk: fn(&&str)) { + let buf = "", buflen = 0u, pos = 0u, len = str::len_bytes(self); + while (pos < len) { + let {ch, next} = str::char_range_at(self, pos); + if (!char::is_whitespace(ch)) { + buf += str::from_char(ch); + buflen += 1u; + } else if (buflen > 0u) { + blk(buf); + buf = ""; + buflen = 0u; + } + pos = next; + } + } + } + + #[test] + fn test_words_iter() { + let data = "\nMary had a little lamb.\nLittle lamb\n"; + + let ii = 0; + + data.iter {|ww| + alt ii { + 0 { assert "Mary" == ww; } + 1 { assert "had" == ww; } + 2 { assert "a" == ww; } + 3 { assert "little" == ww; } + 4 { assert "lamb." == ww; } + _ { () } + } + ii += 1; + } + + "".iter {|_x| fail; } // should not fail + } +} + +mod lines { + export iterable; + impl iterable of iterable for str { + fn iter(blk: fn(&&str)) { + let buf = "", buflen = 0u, pos = 0u, len = str::len_bytes(self); + while (pos < len) { + let {ch, next} = str::char_range_at(self, pos); + if (ch != '\n') { + buf += str::from_char(ch); + buflen += 1u; + } else { + blk(buf); + buf = ""; + buflen = 0u; + } + pos = next; + } + } + } + + #[test] + fn test_lines_iter() { + let lf = "\nMary had a little lamb\nLittle lamb\n"; + + let ii = 0; + + lf.iter {|x| + alt ii { + 0 { assert "" == x; } + 1 { assert "Mary had a little lamb" == x; } + 2 { assert "Little lamb" == x; } + 3 { assert "" == x; } + _ { () } + } + ii += 1; + } + } +} #[cfg(test)] mod tests { @@ -2216,79 +2343,6 @@ mod tests { bytes_iter("") {|bb| assert bb == 0u8; } } - #[test] - fn test_split_char_iter() { - let data = "\nMary had a little lamb\nLittle lamb\n"; - - let ii = 0; - - split_char_iter(data, ' ') {|xx| - alt ii { - 0 { assert "\nMary" == xx; } - 1 { assert "had" == xx; } - 2 { assert "a" == xx; } - 3 { assert "little" == xx; } - _ { () } - } - ii += 1; - } - } - - #[test] - fn test_splitn_char_iter() { - let data = "\nMary had a little lamb\nLittle lamb\n"; - - let ii = 0; - - splitn_char_iter(data, ' ', 2u) {|xx| - alt ii { - 0 { assert "\nMary" == xx; } - 1 { assert "had" == xx; } - 2 { assert "a little lamb\nLittle lamb\n" == xx; } - _ { () } - } - ii += 1; - } - } - - #[test] - fn test_words_iter() { - let data = "\nMary had a little lamb\nLittle lamb\n"; - - let ii = 0; - - words_iter(data) {|ww| - alt ii { - 0 { assert "Mary" == ww; } - 1 { assert "had" == ww; } - 2 { assert "a" == ww; } - 3 { assert "little" == ww; } - _ { () } - } - ii += 1; - } - - words_iter("") {|_x| fail; } // should not fail - } - - #[test] - fn test_lines_iter () { - let lf = "\nMary had a little lamb\nLittle lamb\n"; - - let ii = 0; - - lines_iter(lf) {|x| - alt ii { - 0 { assert "" == x; } - 1 { assert "Mary had a little lamb" == x; } - 2 { assert "Little lamb" == x; } - 3 { assert "" == x; } - _ { () } - } - ii += 1; - } - } - #[test] fn test_escape() { assert(escape("abcdef") == "abcdef"); @@ -2305,20 +2359,20 @@ mod tests { #[test] fn test_all() { - assert true == iter::all("", char::is_uppercase); - assert false == iter::all("ymca", char::is_uppercase); - assert true == iter::all("YMCA", char::is_uppercase); - assert false == iter::all("yMCA", char::is_uppercase); - assert false == iter::all("YMCy", char::is_uppercase); + assert true == iter::all("", {|&&ch| char::is_uppercase(ch) }); + assert false == iter::all("ymca", {|&&ch| char::is_uppercase(ch) }); + assert true == iter::all("YMCA", {|&&ch| char::is_uppercase(ch) }); + assert false == iter::all("yMCA", {|&&ch| char::is_uppercase(ch) }); + assert false == iter::all("YMCy", {|&&ch| char::is_uppercase(ch) }); } #[test] fn test_any() { - assert false == iter::any("", char::is_uppercase); - assert false == iter::any("ymca", char::is_uppercase); - assert true == iter::any("YMCA", char::is_uppercase); - assert true == iter::any("yMCA", char::is_uppercase); - assert true == iter::any("Ymcy", char::is_uppercase); + assert false == iter::any("", {|&&ch| char::is_uppercase(ch) }); + assert false == iter::any("ymca", {|&&ch| char::is_uppercase(ch) }); + assert true == iter::any("YMCA", {|&&ch| char::is_uppercase(ch) }); + assert true == iter::any("yMCA", {|&&ch| char::is_uppercase(ch) }); + assert true == iter::any("Ymcy", {|&&ch| char::is_uppercase(ch) }); } #[test] diff --git a/src/libcore/str_bytes.rs b/src/libcore/str_bytes.rs deleted file mode 100644 index e92a702b62146..0000000000000 --- a/src/libcore/str_bytes.rs +++ /dev/null @@ -1,28 +0,0 @@ -import iter::iterable; -export iterable_by_bytes; - -impl iterable_by_bytes of iterable for str { - fn iter(blk: fn(&&u8)) { - str::bytes_iter(self) { |b| blk(b) } - } -} - -#[test] -fn test_str_byte_iter() { - let i = 0u; - "፩፪፫".iter {|&&b: u8| - alt i { - 0u { assert 0xe1 as u8 == b } - 1u { assert 0x8d as u8 == b } - 2u { assert 0xa9 as u8 == b } - 4u { assert 0xe1 as u8 == b } - 5u { assert 0x8d as u8 == b } - 6u { assert 0xaa as u8 == b } - 7u { assert 0xe1 as u8 == b } - 8u { assert 0x8d as u8 == b } - 9u { assert 0xab as u8 == b } - _ { fail; } - } - i += 1u; - } -} diff --git a/src/libcore/str_chars.rs b/src/libcore/str_chars.rs deleted file mode 100644 index 491f154803164..0000000000000 --- a/src/libcore/str_chars.rs +++ /dev/null @@ -1,22 +0,0 @@ -import iter::iterable; -export iterable_by_chars; - -impl iterable_by_chars of iterable for str { - fn iter(blk: fn(&&char)) { - str::chars_iter(self) { |ch| blk(ch) } - } -} - -#[test] -fn test_str_char_iter() { - let i = 0u; - "፩፪፫".iter {|&&c: char| - alt i { - 0u { assert '፩' == c } - 1u { assert '፪' == c } - 2u { assert '፫' == c } - _ { fail; } - } - i += 1u; - } -} diff --git a/src/libcore/str_lines.rs b/src/libcore/str_lines.rs deleted file mode 100644 index 2518808aed334..0000000000000 --- a/src/libcore/str_lines.rs +++ /dev/null @@ -1,27 +0,0 @@ -export iterable_by_lines; -import iter::iterable; -import str::lines_iter; - -impl iterable_by_lines of iterable for str { - fn iter(blk: fn(&&str)) { - str::lines_iter(self, blk) - } -} - -#[test] -fn test_lines_iter () { - let lf = "\nMary had a little lamb\nLittle lamb\n"; - - let ii = 0; - - iter::map(lf) {|x| - alt ii { - 0 { assert "" == x; } - 1 { assert "Mary had a little lamb" == x; } - 2 { assert "Little lamb" == x; } - 3 { assert "" == x; } - _ { () } - } - ii += 1; - } -} diff --git a/src/libcore/str_words.rs b/src/libcore/str_words.rs deleted file mode 100644 index 49b3c137bb52a..0000000000000 --- a/src/libcore/str_words.rs +++ /dev/null @@ -1,29 +0,0 @@ -export iterable_by_words; -import iter::iterable; -import str::words_iter; - -impl iterable_by_words of iterable for str { - fn iter(blk: fn(&&str)) { - str::words_iter(self, blk) - } -} - -#[test] -fn test_words_iter() { - let data = "\nMary had a little lamb\nLittle lamb\n"; - - let ii = 0; - - iter::map(data) {|ww| - alt ii { - 0 { assert "Mary" == ww; } - 1 { assert "had" == ww; } - 2 { assert "a" == ww; } - 3 { assert "little" == ww; } - _ { () } - } - ii += 1; - } - - iter::map("") {|_x| fail; } // should not fail -} diff --git a/src/rustdoc/unindent_pass.rs b/src/rustdoc/unindent_pass.rs index d44c07d27b45a..a165694a9342c 100644 --- a/src/rustdoc/unindent_pass.rs +++ b/src/rustdoc/unindent_pass.rs @@ -13,7 +13,7 @@ middle of a line, and each of the following lines is indented. export mk_pass; -import str_iter::iterable_by_chars; +import str::chars::iterable; fn mk_pass() -> pass { desc_pass::mk_pass(unindent) From 9ecd30bcaa8bfc43021fba4e9473a7f9d8a1c48f Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Wed, 29 Feb 2012 10:18:04 -0800 Subject: [PATCH 08/12] only require git if the source looks like it was checked out from git, otherwise don't attempt to manage the submodules --- configure | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 874512681e0d2..7ecd812ce2d84 100755 --- a/configure +++ b/configure @@ -300,7 +300,17 @@ step_msg "looking for build programs" probe_need CFG_PERL perl probe_need CFG_PYTHON python python2.6 python2 python3 probe_need CFG_CURL curl -probe_need CFG_GIT git + +# If we have no git directory then we are probably a tarball distribution +# and shouldn't attempt to load submodules +if [ ! -e ${CFG_SRC_DIR}.git ] +then + msg "git: no git directory. disabling submodules" + CFG_DISABLE_MANAGE_SUBMODULES=1 +else + probe_need CFG_GIT git +fi + probe CFG_CLANG clang++ probe CFG_GCC gcc probe CFG_LLVM_CONFIG llvm-config From adcce85df17b5f2e042eaa99eab2ada58d846947 Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Wed, 14 Mar 2012 06:45:34 -0700 Subject: [PATCH 09/12] remove iterators from the str module and make their callers use iter instead --- src/libcore/str.rs | 184 +++++++++--------------------- src/libstd/json.rs | 6 +- src/rustc/metadata/common.rs | 6 +- src/rustdoc/desc_to_brief_pass.rs | 8 +- src/rustdoc/markdown_pass.rs | 9 +- src/rustdoc/sectionalize_pass.rs | 7 +- 6 files changed, 77 insertions(+), 143 deletions(-) diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 86bd4874c920d..c475ab0883d3a 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -52,15 +52,9 @@ export hash, // Iterating through strings - all, any, all_between, any_between, - map, - bytes_iter, - chars_iter, split_char_iter, splitn_char_iter, - words_iter, - lines_iter, // Searching find, find_from, find_between, @@ -571,53 +565,14 @@ fn hash(&&s: str) -> uint { Section: Iterating through strings */ -#[doc = " -Return true if a predicate matches all characters or if the string -contains no characters -"] -fn all(s: str, it: fn(char) -> bool) -> bool { - all_between(s, 0u, len(s), it) -} - -#[doc = " -Return true if a predicate matches any character (and false if it -matches none or there are no characters) -"] -fn any(ss: str, pred: fn(char) -> bool) -> bool { - !all(ss, {|cc| !pred(cc)}) -} - #[doc = "Apply a function to each character"] fn map(ss: str, ff: fn(char) -> char) -> str { let mut result = ""; reserve(result, len(ss)); - chars_iter(ss) {|cc| str::push_char(result, ff(cc));} + iter::each(ss) {|cc| str::push_char(result, ff(cc));} result } -#[doc = "Iterate over the bytes in a string"] -fn bytes_iter(ss: str, it: fn(u8)) { - let mut pos = 0u; - let len = len(ss); - - while (pos < len) { - it(ss[pos]); - pos += 1u; - } -} - -#[doc = "Iterate over the characters in a string"] -fn chars_iter(s: str, it: fn(char)) { - let mut pos = 0u; - let len = len(s); - - while (pos < len) { - let {ch, next} = char_range_at(s, pos); - pos = next; - it(ch); - } -} - #[doc = " Apply a function to each substring after splitting by character "] @@ -633,16 +588,6 @@ fn splitn_char_iter(ss: str, sep: char, count: uint, ff: fn(&&str)) unsafe { vec::iter(splitn_char(ss, sep, count), ff) } -#[doc = "Apply a function to each word"] -fn words_iter(ss: str, ff: fn(&&str)) { - vec::iter(words(ss), ff) -} - -#[doc = "Apply a function to each lines (by '\n')"] -fn lines_iter(ss: str, ff: fn(&&str)) { - vec::iter(lines(ss), ff) -} - /* Section: Searching */ @@ -957,7 +902,7 @@ fn is_utf16(v: [const u16]) -> bool { fn to_utf16(s: str) -> [u16] { let mut u = []; - chars_iter(s) {|cch| + iter::each(s) {|&&cch: char| // Arithmetic with u32 literals is easier on the eyes than chars. let mut ch = cch as u32; @@ -1416,6 +1361,7 @@ mod chars { } i += 1u; } + assert(i == 3u); } #[test] @@ -1491,6 +1437,9 @@ mod words { } pos = next; } + if (buflen > 0u) { + blk(buf); + } } } @@ -1501,19 +1450,42 @@ mod words { let ii = 0; data.iter {|ww| +#error("%d='%s'", ii, ww); alt ii { 0 { assert "Mary" == ww; } 1 { assert "had" == ww; } 2 { assert "a" == ww; } 3 { assert "little" == ww; } - 4 { assert "lamb." == ww; } - _ { () } + 4 { assert "lamb." == ww; } + 5 { assert "Little" == ww; } + 6 { assert "lamb" == ww; } + _ { fail } } ii += 1; } + assert(ii == 7); "".iter {|_x| fail; } // should not fail } + + #[test] + fn test_words_iter2() { + let data = "\nMary had a"; + + let ii = 0; + + data.iter {|ww| +#error("%d='%s'", ii, ww); + alt ii { + 0 { assert "Mary" == ww; } + 1 { assert "had" == ww; } + 2 { assert "a" == ww; } + _ { fail } + } + ii += 1; + } + assert(ii == 3); + } } mod lines { @@ -1536,25 +1508,44 @@ mod lines { } pos = next; } + blk(buf); } } #[test] fn test_lines_iter() { - let lf = "\nMary had a little lamb\nLittle lamb\n"; + let lf = "\nMary had a little lamb\r\nLittle lamb\n"; let ii = 0; lf.iter {|x| alt ii { 0 { assert "" == x; } - 1 { assert "Mary had a little lamb" == x; } + 1 { assert "Mary had a little lamb\r" == x; } 2 { assert "Little lamb" == x; } 3 { assert "" == x; } - _ { () } + _ { fail } + } + ii += 1; + } + assert(ii == 4); + } + + #[test] + fn test_lines_iter2() { + let lf = "Mary had a little lamb\nLittle lamb"; + + let ii = 0; + + lf.iter {|x| + alt ii { + 0 { assert "Mary had a little lamb" == x; } + 1 { assert "Little lamb" == x; } + _ { fail } } ii += 1; } + assert(ii == 2); } } @@ -2228,37 +2219,6 @@ mod tests { assert !contains(data, "ไท华"); } - #[test] - fn test_chars_iter() { - let i = 0; - chars_iter("x\u03c0y") {|ch| - alt check i { - 0 { assert ch == 'x'; } - 1 { assert ch == '\u03c0'; } - 2 { assert ch == 'y'; } - } - i += 1; - } - - chars_iter("") {|_ch| fail; } // should not fail - } - - #[test] - fn test_bytes_iter() { - let i = 0; - - bytes_iter("xyz") {|bb| - alt check i { - 0 { assert bb == 'x' as u8; } - 1 { assert bb == 'y' as u8; } - 2 { assert bb == 'z' as u8; } - } - i += 1; - } - - bytes_iter("") {|bb| assert bb == 0u8; } - } - #[test] fn test_split_char_iter() { let data = "\nMary had a little lamb\nLittle lamb\n"; @@ -2294,44 +2254,6 @@ mod tests { } } - #[test] - fn test_words_iter() { - let data = "\nMary had a little lamb\nLittle lamb\n"; - - let ii = 0; - - words_iter(data) {|ww| - alt ii { - 0 { assert "Mary" == ww; } - 1 { assert "had" == ww; } - 2 { assert "a" == ww; } - 3 { assert "little" == ww; } - _ { () } - } - ii += 1; - } - - words_iter("") {|_x| fail; } // should not fail - } - - #[test] - fn test_lines_iter () { - let lf = "\nMary had a little lamb\nLittle lamb\n"; - - let ii = 0; - - lines_iter(lf) {|x| - alt ii { - 0 { assert "" == x; } - 1 { assert "Mary had a little lamb" == x; } - 2 { assert "Little lamb" == x; } - 3 { assert "" == x; } - _ { () } - } - ii += 1; - } - } - #[test] fn test_map() { assert "" == map("", char::to_upper); diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 4e197d30c9531..56e5779868b61 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -8,6 +8,8 @@ import io; import io::{reader_util, writer_util}; import map; import map::hashmap; +import iter::iterable; +import str::chars::iterable; export json; export error; @@ -47,7 +49,7 @@ fn to_writer(wr: io::writer, j: json) { string(s) { wr.write_char('"'); let escaped = ""; - str::chars_iter(s) { |c| + iter::each(s) { |c| alt c { '"' { escaped += "\\\""; } '\\' { escaped += "\\\\"; } @@ -180,7 +182,7 @@ impl parser for parser { } fn parse_ident(ident: str, value: json) -> result { - if str::all(ident, { |c| c == self.next_char() }) { + if iter::all(ident, { |c| c == self.next_char() }) { self.bump(); ok(value) } else { diff --git a/src/rustc/metadata/common.rs b/src/rustc/metadata/common.rs index 4ccb34055605a..cd2d1860de7dc 100644 --- a/src/rustc/metadata/common.rs +++ b/src/rustc/metadata/common.rs @@ -1,3 +1,6 @@ +import iter::iterable; +import str::bytes::iterable; + // EBML enum definitions and utils shared by the encoder and decoder const tag_paths: uint = 0x01u; @@ -106,7 +109,6 @@ fn hash_node_id(&&node_id: int) -> uint { ret 177573u ^ (node_id as uint); } fn hash_path(&&s: str) -> uint { let h = 5381u; - for ch: u8 in str::bytes(s) { h = (h << 5u) + h ^ (ch as uint); } + iter::each(s) {|&&ch: u8| h = (h << 5u) + h ^ (ch as uint); } ret h; } - diff --git a/src/rustdoc/desc_to_brief_pass.rs b/src/rustdoc/desc_to_brief_pass.rs index 4ff63120efb47..1fbae2ad49369 100644 --- a/src/rustdoc/desc_to_brief_pass.rs +++ b/src/rustdoc/desc_to_brief_pass.rs @@ -7,6 +7,9 @@ is interpreted as the brief description. "]; +import iter::iterable; +import str::lines::iterable; + export mk_pass; fn mk_pass() -> pass { @@ -135,10 +138,9 @@ fn sentences(s: str) -> [str] { } fn paragraphs(s: str) -> [str] { - let lines = str::lines_any(s); let whitespace_lines = 0; let accum = ""; - let paras = vec::foldl([], lines) {|paras, line| + let paras = iter::foldl(s, []) {|paras, line| let res = paras; if str::is_whitespace(line) { @@ -216,4 +218,4 @@ counties."); let brief = extract(desc); assert brief == some( "Warkworth Castle is a ruined medieval building in the town"); -} \ No newline at end of file +} diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs index ad72e55ba1054..45674db4fbdef 100644 --- a/src/rustdoc/markdown_pass.rs +++ b/src/rustdoc/markdown_pass.rs @@ -3,6 +3,8 @@ import markdown_writer::writer; import markdown_writer::writer_util; import markdown_writer::writer_factory; +import iter::iterable; +import str::lines::iterable; export mk_pass; export header_kind, header_name, header_text; @@ -489,8 +491,10 @@ fn write_sig(ctxt: ctxt, sig: option) { } fn code_block_indent(s: str) -> str { - let lines = str::lines_any(s); - let indented = par::seqmap(lines, { |line| #fmt(" %s", line) }); + let indented: [str] = []; +#error("s = '%?'", s); + iter::each(s, { |line| indented += [#fmt(" %s", line)] }); +#error("indented = '%?'", indented); str::connect(indented, "\n") } @@ -530,6 +534,7 @@ fn should_correctly_indent_fn_signature() { ] }; let markdown = test::write_markdown_str(doc); +#error("markdown = '%s'", markdown); assert str::contains(markdown, " line 1\n line 2"); } diff --git a/src/rustdoc/sectionalize_pass.rs b/src/rustdoc/sectionalize_pass.rs index fc957835822a2..45f5a97cb95b8 100644 --- a/src/rustdoc/sectionalize_pass.rs +++ b/src/rustdoc/sectionalize_pass.rs @@ -1,5 +1,8 @@ #[doc = "Breaks rustdocs into sections according to their headers"]; +import iter::iterable; +import str::lines::iterable; + export mk_pass; fn mk_pass() -> pass { @@ -88,13 +91,11 @@ fn sectionalize(desc: option) -> (option, [doc::section]) { ret (none, []); } - let lines = str::lines(option::get(desc)); - let new_desc = none; let current_section = none; let sections = []; - for line in lines { + iter::each(option::get(desc)) {|line| alt parse_header(line) { some(header) { if option::is_some(current_section) { From fcd611b19d05f140fc8f4a4f09d83fe72d584d2d Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Wed, 14 Mar 2012 07:08:55 -0700 Subject: [PATCH 10/12] remove debugging logs --- src/rustdoc/markdown_pass.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs index 45674db4fbdef..019b1b63ad9ca 100644 --- a/src/rustdoc/markdown_pass.rs +++ b/src/rustdoc/markdown_pass.rs @@ -492,9 +492,7 @@ fn write_sig(ctxt: ctxt, sig: option) { fn code_block_indent(s: str) -> str { let indented: [str] = []; -#error("s = '%?'", s); iter::each(s, { |line| indented += [#fmt(" %s", line)] }); -#error("indented = '%?'", indented); str::connect(indented, "\n") } @@ -534,7 +532,6 @@ fn should_correctly_indent_fn_signature() { ] }; let markdown = test::write_markdown_str(doc); -#error("markdown = '%s'", markdown); assert str::contains(markdown, " line 1\n line 2"); } From dfc77d79868d80498bacd175e5ca7379ed1d0e8b Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Wed, 14 Mar 2012 19:56:53 -0700 Subject: [PATCH 11/12] let the caller tag a string with a type to choose the iterator they want. solves the ugliness with importing the correct iterator --- src/cargo/pgp.rs | 4 +- src/libcore/char.rs | 8 +- src/libcore/iter.rs | 99 +++++- src/libcore/str.rs | 495 +++++++++++++++--------------- src/libstd/json.rs | 7 +- src/rustc/metadata/common.rs | 7 +- src/rustc/syntax/ext/qquote.rs | 5 +- src/rustdoc/desc_to_brief_pass.rs | 5 +- src/rustdoc/markdown_pass.rs | 7 +- src/rustdoc/sectionalize_pass.rs | 5 +- src/rustdoc/unindent_pass.rs | 34 +- 11 files changed, 391 insertions(+), 285 deletions(-) diff --git a/src/cargo/pgp.rs b/src/cargo/pgp.rs index bb8a064a1a06d..2c39cebce4cd0 100644 --- a/src/cargo/pgp.rs +++ b/src/cargo/pgp.rs @@ -1,6 +1,6 @@ use std; -import str::lines::iterable; +import str::iterable; fn gpg(args: [str]) -> { status: int, out: str, err: str } { ret run::program_output("gpg", args); @@ -93,5 +93,5 @@ fn verify(root: str, data: str, sig: str, keyfp: str) -> bool { let p = gpg(["--homedir", path, "--with-fingerprint", "--verify", sig, data]); let res = "Primary key fingerprint: " + keyfp; - ret iter::any(p.err) {|&&line| line == res }; + ret iter::any(str::by_lines(p.err)) {|&&line| line == res }; } diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 205552b0b2071..d46f4db1a702d 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -43,7 +43,7 @@ export is_alphabetic, import is_alphabetic = unicode::derived_property::Alphabetic; import is_XID_start = unicode::derived_property::XID_Start; import is_XID_continue = unicode::derived_property::XID_Continue; -import str::chars::iterable; +import str::iterable; #[doc = " Indicates whether a character is in lower case, defined @@ -222,8 +222,10 @@ fn test_to_upper() { #[test] fn test_is_ascii() unsafe { - assert iter::all("banana", {|&&ch| char::is_ascii(ch) }); - assert ! iter::all("ประเทศไทย中华Việt Nam", {|&&ch| char::is_ascii(ch) }); + assert iter::all(str::by_chars("banana"), {|&&ch| char::is_ascii(ch) }); + assert ! iter::all(str::by_chars("ประเทศไทย中华Việt Nam"), {|&&ch| + char::is_ascii(ch) + }); } #[test] diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 87a9e4fdb31e5..12cc7a5f8ad5f 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1,5 +1,6 @@ export iterable, enumerate, filter, map, flat_map, - foldl, to_list, repeat, all, any, each; + foldl, to_list, repeat, all, any, each, + take, drop, head, tail; iface iterable { fn iter(blk: fn(A)); @@ -169,6 +170,34 @@ fn max>(self: IA) -> A { } } +fn take>(self:IA, n:uint, blk:fn(A)) { + let mut i = 0u; + self.iter() {|a| + if (i < n) { + blk(a); + i += 1u; + } + } +} + +fn head>(self:IA, blk:fn(A)) { + take(self, 1u, blk) +} + +fn drop>(self:IA, n:uint, blk:fn(A)) { + let mut i:uint = 0u; + self.iter {|a| + if (i >= n) { + blk(a); + } + i += 1u; + } +} + +fn tail>(self:IA, blk:fn(A)) { + drop(self, 1u, blk) +} + #[test] fn test_enumerate() { enumerate(["0", "1", "2"]) {|i,j| @@ -308,3 +337,71 @@ fn test_foldr() { let sum = foldr([1, 2, 3, 4], 0, sub); assert sum == -2; } + +#[test] +fn test_take() { + let i = 0u; + take([5, 4, 1, 2, 3], 1u) {|h| assert h == 5; i += 1u; }; + assert i == 1u; + + i = 0u; + take([5, 4, 1, 2, 3], 2u) {|j| + alt i { + 0u { assert 5 == j } + 1u { assert 4 == j } + _ { fail; } + } + i += 1u; + } + assert i == 2u; +} + +#[test] +fn test_drop() { + let i = 0u; + drop([5, 4, 1, 2, 3], 1u) {|j| + alt i { + 0u { assert 4 == j } + 1u { assert 1 == j } + 2u { assert 2 == j } + 3u { assert 3 == j } + _ { fail; } + } + i += 1u; + } + assert i == 4u; + + i = 0u; + drop([5, 4, 1, 2, 3], 3u) {|j| + alt i { + 0u { assert 2 == j } + 1u { assert 3 == j } + _ { fail; } + } + i += 1u; + } + assert i == 2u; +} + +#[test] +fn test_head() { + let i = 0u; + head([5, 4, 1, 2, 3]) {|h| assert h == 5; i += 1u; }; + assert i == 1u; +} + +#[test] +fn test_tail() { + let i = 0u; + tail([5, 4, 1, 2, 3]) {|j| + alt i { + 0u { assert 4 == j } + 1u { assert 1 == j } + 2u { assert 2 == j } + 3u { assert 3 == j } + _ { fail; } + } + i += 1u; + } + assert i == 4u; +} diff --git a/src/libcore/str.rs b/src/libcore/str.rs index c475ab0883d3a..9033ec1624332 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -8,7 +8,6 @@ some heavy-duty uses, try std::rope. "]; import iter::iterable; -import str::chars::iterable; export // Creating a string @@ -52,6 +51,8 @@ export hash, // Iterating through strings + iterable, + by_bytes, by_chars, by_lines, by_words, all_between, any_between, split_char_iter, splitn_char_iter, @@ -569,7 +570,7 @@ Section: Iterating through strings fn map(ss: str, ff: fn(char) -> char) -> str { let mut result = ""; reserve(result, len(ss)); - iter::each(ss) {|cc| str::push_char(result, ff(cc));} + iter::each(by_chars(ss)) {|cc| str::push_char(result, ff(cc));} result } @@ -844,7 +845,7 @@ Returns true if the string contains only whitespace Whitespace characters are determined by `char::is_whitespace` "] fn is_whitespace(s: str) -> bool { - ret iter::all(s, {|&&ch| char::is_whitespace(ch) }); + ret iter::all(by_chars(s), {|&&ch| char::is_whitespace(ch) }); } #[doc = " @@ -902,7 +903,7 @@ fn is_utf16(v: [const u16]) -> bool { fn to_utf16(s: str) -> [u16] { let mut u = []; - iter::each(s) {|&&cch: char| + iter::each(by_chars(s)) {|&&cch: char| // Arithmetic with u32 literals is easier on the eyes than chars. let mut ch = cch as u32; @@ -1301,251 +1302,75 @@ mod unsafe { } } -mod bytes { - export iterable; - impl iterable of iterable for str { - fn iter(blk: fn(&&u8)) { - let mut pos = 0u; - let len = str::len(self); - while (pos < len) { - blk(self[pos]); - pos += 1u; - } - } - } - - #[test] - fn test_str_byte_iter() { - let i = 0u; - "፩፪፫".iter {|&&b: u8| - alt i { - 0u { assert 0xe1_u8 == b } - 1u { assert 0x8d_u8 == b } - 2u { assert 0xa9_u8 == b } - 3u { assert 0xe1_u8 == b } - 4u { assert 0x8d_u8 == b } - 5u { assert 0xaa_u8 == b } - 6u { assert 0xe1_u8 == b } - 7u { assert 0x8d_u8 == b } - 8u { assert 0xab_u8 == b } - 9u { assert 0x00_u8 == b } - _ { fail; } - } - i += 1u; +enum by_bytes = str; +impl of iterable for by_bytes { + fn iter(blk: fn(&&u8)) { + let mut pos = 0u; + let len = str::len(*self); + while (pos < len) { + blk(self[pos]); + pos += 1u; } } } -mod chars { - export iterable; - impl iterable of iterable for str { - fn iter(blk: fn(&&char)) { - let mut pos = 0u, len = str::len(self); - while (pos < len) { - let {ch, next} = str::char_range_at(self, pos); - pos = next; - blk(ch); - } +enum by_chars = str; +impl of iterable for by_chars { + fn iter(blk: fn(&&char)) { + let mut pos = 0u, len = str::len(*self); + while (pos < len) { + let {ch, next} = str::char_range_at(*self, pos); + pos = next; + blk(ch); } } - - #[test] - fn test_str_char_iter() { - let i = 0u; - "፩፪፫".iter {|&&c: char| - alt i { - 0u { assert '፩' == c } - 1u { assert '፪' == c } - 2u { assert '፫' == c } - _ { fail; } - } - i += 1u; - } - assert(i == 3u); - } - - #[test] - fn test_str_all() { - assert true == iter::all("፩፪፫") {|&&c| - unicode::general_category::No(c) - }; - assert false == iter::all("፩፪፫") {|&&c| - unicode::general_category::Lu(c) - }; - assert false == iter::all("፩፪3") {|&&c| - unicode::general_category::No(c) - }; - assert true == iter::all("") {|&&c| - unicode::general_category::Lu(c) - }; - } - - #[test] - fn test_str_all_calls() { - let calls: uint = 0u; - assert false == iter::all("፩2፫") {|&&c| - calls += 1u; - unicode::general_category::No(c) - }; - assert calls == 2u; - } - - #[test] - fn test_str_any() { - assert true == iter::any("፩፪፫") {|&&c| - unicode::general_category::No(c) - }; - assert false == iter::any("፩፪፫") {|&&c| - unicode::general_category::Lu(c) - }; - assert true == iter::any("1፪፫") {|&&c| - unicode::general_category::No(c) - }; - assert false == iter::any("") {|&&c| - unicode::general_category::Lu(c) - }; - } - - #[test] - fn test_str_any_calls() { - let calls: uint = 0u; - assert true == iter::any("፩2፫") {|&&c| - calls += 1u; - unicode::general_category::Nd(c) - }; - assert calls == 2u; - } } -mod words { - export iterable; - impl iterable of iterable for str { - fn iter(blk: fn(&&str)) { - let mut buf = "", - buflen = 0u, - pos = 0u, - len = str::len(self); - while (pos < len) { - let {ch, next} = str::char_range_at(self, pos); - if (!char::is_whitespace(ch)) { - buf += str::from_char(ch); - buflen += 1u; - } else if (buflen > 0u) { - blk(buf); - buf = ""; - buflen = 0u; - } - pos = next; - } - if (buflen > 0u) { +enum by_words = str; +impl of iterable for by_words { + fn iter(blk: fn(&&str)) { + let mut buf = "", + buflen = 0u, + pos = 0u, + len = str::len(*self); + while (pos < len) { + let {ch, next} = str::char_range_at(*self, pos); + if (!char::is_whitespace(ch)) { + buf += str::from_char(ch); + buflen += 1u; + } else if (buflen > 0u) { blk(buf); + buf = ""; + buflen = 0u; } + pos = next; } - } - - #[test] - fn test_words_iter() { - let data = "\nMary had a little lamb.\nLittle lamb\n"; - - let ii = 0; - - data.iter {|ww| -#error("%d='%s'", ii, ww); - alt ii { - 0 { assert "Mary" == ww; } - 1 { assert "had" == ww; } - 2 { assert "a" == ww; } - 3 { assert "little" == ww; } - 4 { assert "lamb." == ww; } - 5 { assert "Little" == ww; } - 6 { assert "lamb" == ww; } - _ { fail } - } - ii += 1; - } - assert(ii == 7); - - "".iter {|_x| fail; } // should not fail - } - - #[test] - fn test_words_iter2() { - let data = "\nMary had a"; - - let ii = 0; - - data.iter {|ww| -#error("%d='%s'", ii, ww); - alt ii { - 0 { assert "Mary" == ww; } - 1 { assert "had" == ww; } - 2 { assert "a" == ww; } - _ { fail } - } - ii += 1; - } - assert(ii == 3); - } -} - -mod lines { - export iterable; - impl iterable of iterable for str { - fn iter(blk: fn(&&str)) { - let mut buf = "", - buflen = 0u, - pos = 0u, - len = str::len(self); - while (pos < len) { - let {ch, next} = str::char_range_at(self, pos); - if (ch != '\n') { - buf += str::from_char(ch); - buflen += 1u; - } else { - blk(buf); - buf = ""; - buflen = 0u; - } - pos = next; - } + if (buflen > 0u) { blk(buf); } } +} - #[test] - fn test_lines_iter() { - let lf = "\nMary had a little lamb\r\nLittle lamb\n"; - - let ii = 0; - - lf.iter {|x| - alt ii { - 0 { assert "" == x; } - 1 { assert "Mary had a little lamb\r" == x; } - 2 { assert "Little lamb" == x; } - 3 { assert "" == x; } - _ { fail } - } - ii += 1; - } - assert(ii == 4); - } - - #[test] - fn test_lines_iter2() { - let lf = "Mary had a little lamb\nLittle lamb"; - - let ii = 0; - - lf.iter {|x| - alt ii { - 0 { assert "Mary had a little lamb" == x; } - 1 { assert "Little lamb" == x; } - _ { fail } +enum by_lines = str; +impl of iterable for by_lines { + fn iter(blk: fn(&&str)) { + let mut buf = "", + buflen = 0u, + pos = 0u, + len = str::len(*self); + while (pos < len) { + let {ch, next} = str::char_range_at(*self, pos); + if (ch != '\n') { + buf += str::from_char(ch); + buflen += 1u; + } else { + blk(buf); + buf = ""; + buflen = 0u; } - ii += 1; + pos = next; } - assert(ii == 2); + blk(buf); } } @@ -2262,20 +2087,40 @@ mod tests { #[test] fn test_all() { - assert true == iter::all("", {|&&ch| char::is_uppercase(ch) }); - assert false == iter::all("ymca", {|&&ch| char::is_uppercase(ch) }); - assert true == iter::all("YMCA", {|&&ch| char::is_uppercase(ch) }); - assert false == iter::all("yMCA", {|&&ch| char::is_uppercase(ch) }); - assert false == iter::all("YMCy", {|&&ch| char::is_uppercase(ch) }); + assert true == iter::all(by_chars(""), {|&&ch| + char::is_uppercase(ch) + }); + assert false == iter::all(by_chars("ymca"), {|&&ch| + char::is_uppercase(ch) + }); + assert true == iter::all(by_chars("YMCA"), {|&&ch| + char::is_uppercase(ch) + }); + assert false == iter::all(by_chars("yMCA"), {|&&ch| + char::is_uppercase(ch) + }); + assert false == iter::all(by_chars("YMCy"), {|&&ch| + char::is_uppercase(ch) + }); } #[test] fn test_any() { - assert false == iter::any("", {|&&ch| char::is_uppercase(ch) }); - assert false == iter::any("ymca", {|&&ch| char::is_uppercase(ch) }); - assert true == iter::any("YMCA", {|&&ch| char::is_uppercase(ch) }); - assert true == iter::any("yMCA", {|&&ch| char::is_uppercase(ch) }); - assert true == iter::any("Ymcy", {|&&ch| char::is_uppercase(ch) }); + assert false == iter::any(by_chars(""), {|&&ch| + char::is_uppercase(ch) + }); + assert false == iter::any(by_chars("ymca"), {|&&ch| + char::is_uppercase(ch) + }); + assert true == iter::any(by_chars("YMCA"), {|&&ch| + char::is_uppercase(ch) + }); + assert true == iter::any(by_chars("yMCA"), {|&&ch| + char::is_uppercase(ch) + }); + assert true == iter::any(by_chars("Ymcy"), {|&&ch| + char::is_uppercase(ch) + }); } #[test] @@ -2331,4 +2176,170 @@ mod tests { assert to_utf16(from_utf16(u)) == u; } } + + #[test] + fn test_str_byte_iter() { + let i = 0u; + by_bytes("፩፪፫").iter {|&&b: u8| + alt i { + 0u { assert 0xe1_u8 == b } + 1u { assert 0x8d_u8 == b } + 2u { assert 0xa9_u8 == b } + 3u { assert 0xe1_u8 == b } + 4u { assert 0x8d_u8 == b } + 5u { assert 0xaa_u8 == b } + 6u { assert 0xe1_u8 == b } + 7u { assert 0x8d_u8 == b } + 8u { assert 0xab_u8 == b } + _ { fail; } + } + i += 1u; + } + assert(i == 9u); + } + + #[test] + fn test_str_char_iter() { + let i = 0u; + by_chars("፩፪፫").iter {|&&c: char| + alt i { + 0u { assert '፩' == c } + 1u { assert '፪' == c } + 2u { assert '፫' == c } + _ { fail; } + } + i += 1u; + } + assert(i == 3u); + } + + #[test] + fn test_str_all() { + assert true == iter::all(by_chars("፩፪፫")) {|&&c| + unicode::general_category::No(c) + }; + assert false == iter::all(by_chars("፩፪፫")) {|&&c| + unicode::general_category::Lu(c) + }; + assert false == iter::all(by_chars("፩፪3")) {|&&c| + unicode::general_category::No(c) + }; + assert true == iter::all(by_chars("")) {|&&c| + unicode::general_category::Lu(c) + }; + } + + #[test] + fn test_str_all_calls() { + let calls: uint = 0u; + assert false == iter::all(by_chars("፩2፫")) {|&&c| + calls += 1u; + unicode::general_category::No(c) + }; + assert calls == 2u; + } + + #[test] + fn test_str_any() { + assert true == iter::any(by_chars("፩፪፫")) {|&&c| + unicode::general_category::No(c) + }; + assert false == iter::any(by_chars("፩፪፫")) {|&&c| + unicode::general_category::Lu(c) + }; + assert true == iter::any(by_chars("1፪፫")) {|&&c| + unicode::general_category::No(c) + }; + assert false == iter::any(by_chars("")) {|&&c| + unicode::general_category::Lu(c) + }; + } + + #[test] + fn test_str_any_calls() { + let calls: uint = 0u; + assert true == iter::any(by_chars("፩2፫")) {|&&c| + calls += 1u; + unicode::general_category::Nd(c) + }; + assert calls == 2u; + } + + #[test] + fn test_words_iter() { + let data = "\nMary had a little lamb.\nLittle lamb\n"; + + let ii = 0; + + by_words(data).iter {|ww| + alt ii { + 0 { assert "Mary" == ww; } + 1 { assert "had" == ww; } + 2 { assert "a" == ww; } + 3 { assert "little" == ww; } + 4 { assert "lamb." == ww; } + 5 { assert "Little" == ww; } + 6 { assert "lamb" == ww; } + _ { fail } + } + ii += 1; + } + assert(ii == 7); + + by_words("").iter {|_x| fail; } // should not fail + } + + #[test] + fn test_words_iter2() { + let data = "\nMary had a"; + + let ii = 0; + + by_words(data).iter {|ww| + alt ii { + 0 { assert "Mary" == ww; } + 1 { assert "had" == ww; } + 2 { assert "a" == ww; } + _ { fail } + } + ii += 1; + } + assert(ii == 3); + } + + #[test] + fn test_lines_iter() { + let lf = "\nMary had a little lamb\r\nLittle lamb\n"; + + let ii = 0; + + iter::each(by_lines(lf)) {|x| + alt ii { + 0 { assert "" == x; } + 1 { assert "Mary had a little lamb\r" == x; } + 2 { assert "Little lamb" == x; } + 3 { assert "" == x; } + _ { fail } + } + ii += 1; + } + assert(ii == 4); + } + + #[test] + fn test_lines_iter2() { + let lf = "Mary had a little lamb\nLittle lamb"; + + let ii = 0; + + iter::each(by_lines(lf)) {|x| + alt ii { + 0 { assert "Mary had a little lamb" == x; } + 1 { assert "Little lamb" == x; } + _ { fail } + } + ii += 1; + } + assert(ii == 2); + } } diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 56e5779868b61..881ed36e5d0aa 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -8,8 +8,7 @@ import io; import io::{reader_util, writer_util}; import map; import map::hashmap; -import iter::iterable; -import str::chars::iterable; +import str::iterable; export json; export error; @@ -49,7 +48,7 @@ fn to_writer(wr: io::writer, j: json) { string(s) { wr.write_char('"'); let escaped = ""; - iter::each(s) { |c| + iter::each(str::by_chars(s)) { |c| alt c { '"' { escaped += "\\\""; } '\\' { escaped += "\\\\"; } @@ -182,7 +181,7 @@ impl parser for parser { } fn parse_ident(ident: str, value: json) -> result { - if iter::all(ident, { |c| c == self.next_char() }) { + if iter::all(str::by_chars(ident), { |c| c == self.next_char() }) { self.bump(); ok(value) } else { diff --git a/src/rustc/metadata/common.rs b/src/rustc/metadata/common.rs index cd2d1860de7dc..218afefbb8c2a 100644 --- a/src/rustc/metadata/common.rs +++ b/src/rustc/metadata/common.rs @@ -1,5 +1,4 @@ -import iter::iterable; -import str::bytes::iterable; +import str::iterable; // EBML enum definitions and utils shared by the encoder and decoder @@ -109,6 +108,8 @@ fn hash_node_id(&&node_id: int) -> uint { ret 177573u ^ (node_id as uint); } fn hash_path(&&s: str) -> uint { let h = 5381u; - iter::each(s) {|&&ch: u8| h = (h << 5u) + h ^ (ch as uint); } + iter::each(str::by_bytes(s)) {|&&ch: u8| + h = (h << 5u) + h ^ (ch as uint); + } ret h; } diff --git a/src/rustc/syntax/ext/qquote.rs b/src/rustc/syntax/ext/qquote.rs index 7ddcd9e692626..02b462580383d 100644 --- a/src/rustc/syntax/ext/qquote.rs +++ b/src/rustc/syntax/ext/qquote.rs @@ -11,11 +11,10 @@ import syntax::parse::parser::{parser, parse_from_source_str}; import syntax::print::*; import io::*; +import str::iterable; import codemap::span; -import str::chars::iterable; - type aq_ctxt = @{lo: uint, mutable gather: [{lo: uint, hi: uint, e: @ast::expr, @@ -217,7 +216,7 @@ fn finish let state = active; let i = 0u, j = 0u; let g_len = vec::len(cx.gather); - (*str).iter() {|ch| + iter::each(str::by_chars(*str)) {|ch| if (j < g_len && i == cx.gather[j].lo) { assert ch == '$'; let repl = #fmt("$%u ", j); diff --git a/src/rustdoc/desc_to_brief_pass.rs b/src/rustdoc/desc_to_brief_pass.rs index 1fbae2ad49369..94d509dfd72ad 100644 --- a/src/rustdoc/desc_to_brief_pass.rs +++ b/src/rustdoc/desc_to_brief_pass.rs @@ -7,8 +7,7 @@ is interpreted as the brief description. "]; -import iter::iterable; -import str::lines::iterable; +import str::iterable; export mk_pass; @@ -140,7 +139,7 @@ fn sentences(s: str) -> [str] { fn paragraphs(s: str) -> [str] { let whitespace_lines = 0; let accum = ""; - let paras = iter::foldl(s, []) {|paras, line| + let paras = iter::foldl(str::by_lines(s), []) {|paras, line| let res = paras; if str::is_whitespace(line) { diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs index 019b1b63ad9ca..8d0d46eb5aef8 100644 --- a/src/rustdoc/markdown_pass.rs +++ b/src/rustdoc/markdown_pass.rs @@ -3,8 +3,7 @@ import markdown_writer::writer; import markdown_writer::writer_util; import markdown_writer::writer_factory; -import iter::iterable; -import str::lines::iterable; +import str::iterable; export mk_pass; export header_kind, header_name, header_text; @@ -492,7 +491,9 @@ fn write_sig(ctxt: ctxt, sig: option) { fn code_block_indent(s: str) -> str { let indented: [str] = []; - iter::each(s, { |line| indented += [#fmt(" %s", line)] }); + iter::each(str::by_lines(s), { + |line| indented += [#fmt(" %s", line)] + }); str::connect(indented, "\n") } diff --git a/src/rustdoc/sectionalize_pass.rs b/src/rustdoc/sectionalize_pass.rs index 45f5a97cb95b8..1ac5606e54891 100644 --- a/src/rustdoc/sectionalize_pass.rs +++ b/src/rustdoc/sectionalize_pass.rs @@ -1,7 +1,6 @@ #[doc = "Breaks rustdocs into sections according to their headers"]; -import iter::iterable; -import str::lines::iterable; +import str::iterable; export mk_pass; @@ -95,7 +94,7 @@ fn sectionalize(desc: option) -> (option, [doc::section]) { let current_section = none; let sections = []; - iter::each(option::get(desc)) {|line| + iter::each(str::by_lines(option::get(desc))) {|line| alt parse_header(line) { some(header) { if option::is_some(current_section) { diff --git a/src/rustdoc/unindent_pass.rs b/src/rustdoc/unindent_pass.rs index 552b9f357edec..50f3d19ad533a 100644 --- a/src/rustdoc/unindent_pass.rs +++ b/src/rustdoc/unindent_pass.rs @@ -13,18 +13,17 @@ middle of a line, and each of the following lines is indented. export mk_pass; -import str::chars::iterable; +import str::iterable; fn mk_pass() -> pass { text_pass::mk_pass("unindent", unindent) } fn unindent(s: str) -> str { - let lines = str::lines_any(s); let saw_first_line = false; let saw_second_line = false; - let min_indent = vec::foldl(uint::max_value, lines) {|min_indent, line| - + let min_indent = iter::foldl(str::by_lines(s), uint::max_value) + {|min_indent, line| // After we see the first non-whitespace line, look at // the line we have. If it is not whitespace, and therefore // part of the first paragraph, then ignore the indentation @@ -49,7 +48,7 @@ fn unindent(s: str) -> str { } else { saw_first_line = true; let spaces = 0u; - iter::all(line) {|char| + iter::all(str::by_chars(line)) {|char| // Only comparing against space because I wouldn't // know what to do with mixed whitespace chars if char == ' ' { @@ -63,20 +62,19 @@ fn unindent(s: str) -> str { } }; - if check vec::is_not_empty(lines) { - let unindented = [str::trim(vec::head(lines))] - + par::anymap(vec::tail(lines)) {|line| - if str::is_whitespace(line) { - line - } else { - assert str::len(line) >= min_indent; - str::slice(line, min_indent, str::len(line)) - } - }; - str::connect(unindented, "\n") - } else { - s + let unindented = []; + iter::head(str::by_lines(s)) {|line| + unindented += [str::trim(line)] } + iter::tail(str::by_lines(s)) {|line| + if str::is_whitespace(line) { + unindented += [line] + } else { + assert str::len(line) >= min_indent; + unindented += [str::slice(line, min_indent, str::len(line))]; + } + }; + str::connect(unindented, "\n") } #[test] From 25712403d28aecf4858754010cedbbef3d51d50c Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Thu, 15 Mar 2012 17:12:56 -0700 Subject: [PATCH 12/12] use more iterators --- src/compiletest/runtest.rs | 20 ++++---------------- src/libcore/str.rs | 2 +- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 19cc968ab7e27..23099b94a4c4c 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -8,6 +8,7 @@ import common::config; import header::load_props; import header::test_props; import util::logv; +import str::iterable; export run; @@ -195,7 +196,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_char(procres.stderr, '\n') { + iter::each(str::by_lines(procres.stderr)) {|line| if str::contains(line, next_err_pat) { #debug("found error pattern %s", next_err_pat); next_err_idx += 1u; @@ -243,7 +244,7 @@ fn check_expected_errors(expected_errors: [errors::expected_error], // filename:line1:col1: line2:col2: *warning:* msg // where line1:col1: is the starting point, line2:col2: // is the ending point, and * represents ANSI color codes. - for line: str in str::split_char(procres.stderr, '\n') { + iter::each(str::by_lines(procres.stderr)) {|line| let was_expected = false; vec::iteri(expected_errors) {|i, ee| if !found_flags[i] { @@ -356,21 +357,8 @@ fn make_run_args(config: config, _props: test_props, testfile: str) -> } fn split_maybe_args(argstr: option) -> [str] { - fn rm_whitespace(v: [str]) -> [str] { - fn flt(&&s: str) -> option { - if !is_whitespace(s) { option::some(s) } else { option::none } - } - - // FIXME: This should be in std - fn is_whitespace(s: str) -> bool { - for c: u8 in s { if c != ' ' as u8 { ret false; } } - ret true; - } - vec::filter_map(v, flt) - } - alt argstr { - option::some(s) { rm_whitespace(str::split_char(s, ' ')) } + option::some(s) { vec::filter(str::split_char(s, ' '), {|s| !str::is_whitespace(s) }) } option::none { [] } } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 9033ec1624332..14054f3344346 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -558,7 +558,7 @@ fn hash(&&s: str) -> uint { // djb hash. // FIXME: replace with murmur. let mut u: uint = 5381u; - for c: u8 in s { u *= 33u; u += c as uint; } + iter::each(by_bytes(s)) {|c| u *= 33u; u += c as uint; } ret u; }