about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMarvin Löbel <loebel.marvin@gmail.com>2013-03-23 17:25:16 +0100
committerMarvin Löbel <loebel.marvin@gmail.com>2013-03-26 14:59:17 +0100
commitd74606ead60d524eb72afad2cd8b45facd6c5d40 (patch)
tree55c4d07b5e67f9576fb496a0e24b67600504324e /src
parent624a685283f66afcb40ee3c235624aedebc2f08f (diff)
downloadrust-d74606ead60d524eb72afad2cd8b45facd6c5d40.tar.gz
rust-d74606ead60d524eb72afad2cd8b45facd6c5d40.zip
pre-rebase commit
Diffstat (limited to 'src')
-rw-r--r--src/libcore/str.rs201
-rw-r--r--src/libstd/getopts.rs19
2 files changed, 119 insertions, 101 deletions
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index e91120e7790..28f76125746 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -56,15 +56,15 @@ pub fn from_slice(s: &str) -> ~str {
 
 impl ToStr for ~str {
     #[inline(always)]
-    fn to_str(&self) -> ~str { copy *self }
+    fn to_str(&self) -> ~str { from_slice(*self) }
 }
 impl ToStr for &'self str {
     #[inline(always)]
-    fn to_str(&self) -> ~str { ::str::from_slice(*self) }
+    fn to_str(&self) -> ~str { from_slice(*self) }
 }
 impl ToStr for @str {
     #[inline(always)]
-    fn to_str(&self) -> ~str { ::str::from_slice(*self) }
+    fn to_str(&self) -> ~str { from_slice(*self) }
 }
 
 /**
@@ -383,7 +383,7 @@ Section: Transforming strings
 */
 
 /**
- * Converts a string to a vector of bytes
+ * Converts a string to a unique vector of bytes
  *
  * The result vector is not null-terminated.
  */
@@ -403,14 +403,11 @@ pub fn byte_slice<T>(s: &str, f: &fn(v: &[u8]) -> T) -> T {
     }
 }
 
-/// Convert a string to a vector of characters
-pub fn chars(s: &str) -> ~[char] {
-    let mut buf = ~[], i = 0;
-    let len = len(s);
-    while i < len {
-        let CharRange {ch, next} = char_range_at(s, i);
-        unsafe { buf.push(ch); }
-        i = next;
+/// Convert a string to a unique vector of characters
+pub fn to_chars(s: &str) -> ~[char] {
+    let mut buf = ~[];
+    for each_char(s) |c| {
+        buf.push(c);
     }
     buf
 }
@@ -418,7 +415,7 @@ pub fn chars(s: &str) -> ~[char] {
 /**
  * Take a substring of another.
  *
- * Returns a string containing `n` characters starting at byte offset
+ * Returns a slice pointing at `n` characters starting from byte offset
  * `begin`.
  */
 pub fn substr(s: &'a str, begin: uint, n: uint) -> &'a str {
@@ -437,10 +434,17 @@ pub fn slice(s: &'a str, begin: uint, end: uint) -> &'a str {
     unsafe { raw::slice_bytes(s, begin, end) }
 }
 
-/// Splits a string into substrings at each occurrence of a given
-/// character.
-pub fn split_char(s: &str, sep: char) -> ~[~str] {
-    split_char_inner(s, sep, len(s), true, true)
+/// Splits a string into substrings at each occurrence of a given character
+pub fn each_split_char(s: &str, sep: char, it: &fn(&str) -> bool) {
+    each_split_char_inner(s, sep, len(s), true, true, it)
+}
+
+/**
+ * Like `split_char`, but a trailing empty string is omitted
+ * (e.g. `split_char_no_trailing("A B ",' ') == ~[~"A",~"B"]`)
+ */
+pub fn each_split_char_no_trailing(s: &str, sep: char, it: &fn(&str) -> bool) {
+    each_split_char_inner(s, sep, len(s), true, false, it)
 }
 
 /**
@@ -449,35 +453,25 @@ pub fn split_char(s: &str, sep: char) -> ~[~str] {
  *
  * The byte must be a valid UTF-8/ASCII byte
  */
-pub fn splitn_char(s: &str, sep: char, count: uint) -> ~[~str] {
-    split_char_inner(s, sep, count, true, true)
+pub fn each_splitn_char(s: &str, sep: char, count: uint, it: &fn(&str) -> bool) {
+    each_split_char_inner(s, sep, count, true, true, it)
 }
 
 /// Like `split_char`, but omits empty strings from the returned vector
-pub fn split_char_nonempty(s: &str, sep: char) -> ~[~str] {
-    split_char_inner(s, sep, len(s), false, false)
-}
-
-/**
- * Like `split_char`, but a trailing empty string is omitted
- * (e.g. `split_char_no_trailing("A B ",' ') == ~[~"A",~"B"]`)
- */
-pub fn split_char_no_trailing(s: &str, sep: char) -> ~[~str] {
-    split_char_inner(s, sep, len(s), true, false)
+pub fn each_split_char_nonempty(s: &str, sep: char, it: &fn(&str) -> bool) {
+    each_split_char_inner(s, sep, len(s), false, false, it)
 }
 
-fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool,
-                    allow_trailing_empty: bool) -> ~[~str] {
+fn each_split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool,
+                         allow_trailing_empty: bool), it: &fn(&str) -> bool) {
     if sep < 128u as char {
         let b = sep as u8, l = len(s);
-        let mut result = ~[], done = 0u;
+        let mut done = 0u;
         let mut i = 0u, start = 0u;
         while i < l && done < count {
             if s[i] == b {
                 if allow_empty || start < i {
-                    unsafe {
-                        result.push(raw::slice_bytes_unique(s, start, i));
-                    }
+                    if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { return; }
                 }
                 start = i + 1u;
                 done += 1u;
@@ -486,56 +480,48 @@ fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool,
         }
         // only push a non-empty trailing substring
         if allow_trailing_empty || start < l {
-            unsafe { result.push(raw::slice_bytes_unique(s, start, l) ) };
+            if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return; }
         }
-        result
     } else {
-        split_inner(s, |cur| cur == sep, count, allow_empty, allow_trailing_empty)
+        each_split_inner(s, |cur| cur == sep, count, allow_empty, allow_trailing_empty, it)
     }
 }
 
-
 /// Splits a string into substrings using a character function
-pub fn split(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] {
-    split_inner(s, sepfn, len(s), true, true)
+pub fn each_split(s: &str, sepfn: &fn(char) -> bool, it: &fn(&str) -> bool) {
+    each_split_inner(s, sepfn, len(s), true, true, it)
+}
+
+/**
+ * Like `split`, but a trailing empty string is omitted
+ * (e.g. `split_no_trailing("A B ",' ') == ~[~"A",~"B"]`)
+ */
+pub fn each_split_no_trailing(s: &str, sepfn: &fn(char) -> bool, it: &fn(&str) -> bool) {
+    each_split_inner(s, sepfn, len(s), true, false, it)
 }
 
 /**
  * Splits a string into substrings using a character function, cutting at
  * most `count` times.
  */
-pub fn splitn(s: &str,
-                   sepfn: &fn(char) -> bool,
-                   count: uint)
-                -> ~[~str] {
-    split_inner(s, sepfn, count, true, true)
+pub fn each_splitn(s: &str, sepfn: &fn(char) -> bool, count: uint, it: &fn(&str) -> bool) {
+    each_split_inner(s, sepfn, count, true, true, it)
 }
 
 /// Like `split`, but omits empty strings from the returned vector
-pub fn split_nonempty(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] {
-    split_inner(s, sepfn, len(s), false, false)
-}
-
-
-/**
- * Like `split`, but a trailing empty string is omitted
- * (e.g. `split_no_trailing("A B ",' ') == ~[~"A",~"B"]`)
- */
-pub fn split_no_trailing(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] {
-    split_inner(s, sepfn, len(s), true, false)
+pub fn each_split_nonempty(s: &str, sepfn: &fn(char) -> bool, it: &fn(&str) -> bool) {
+    each_split_inner(s, sepfn, len(s), false, false, it)
 }
 
-fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint,
-               allow_empty: bool, allow_trailing_empty: bool) -> ~[~str] {
+pure fn each_split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint,
+               allow_empty: bool, allow_trailing_empty: bool), it: &fn(&str) -> bool) {
     let l = len(s);
-    let mut result = ~[], i = 0u, start = 0u, done = 0u;
+    let mut i = 0u, start = 0u, done = 0u;
     while i < l && done < count {
         let CharRange {ch, next} = char_range_at(s, i);
         if sepfn(ch) {
             if allow_empty || start < i {
-                unsafe {
-                    result.push(raw::slice_bytes_unique(s, start, i));
-                }
+                if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { return; }
             }
             start = next;
             done += 1u;
@@ -543,11 +529,8 @@ fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint,
         i = next;
     }
     if allow_trailing_empty || start < l {
-        unsafe {
-            result.push(raw::slice_bytes_unique(s, start, l));
-        }
+        if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return;  }
     }
-    result
 }
 
 // See Issue #1932 for why this is a naive search
@@ -596,22 +579,18 @@ fn iter_between_matches(s: &'a str, sep: &'b str, f: &fn(uint, uint)) {
  * fail_unless!(["", "XXX", "YYY", ""] == split_str(".XXX.YYY.", "."))
  * ~~~
  */
-pub fn split_str(s: &'a str, sep: &'b str) -> ~[~str] {
-    let mut result = ~[];
+pub fn each_split_str(s: &'a str, sep: &'b str, it: &fn(&str) -> bool) {
     do iter_between_matches(s, sep) |from, to| {
-        unsafe { result.push(raw::slice_bytes_unique(s, from, to)); }
+        if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return; }
     }
-    result
 }
 
-pub fn split_str_nonempty(s: &'a str, sep: &'b str) -> ~[~str] {
-    let mut result = ~[];
+pub fn each_split_str_nonempty(s: &'a str, sep: &'b str, it: &fn(&str) -> bool) {
     do iter_between_matches(s, sep) |from, to| {
         if to > from {
-            unsafe { result.push(raw::slice_bytes_unique(s, from, to)); }
+            if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return; }
         }
     }
-    result
 }
 
 /// Levenshtein Distance between two strings
@@ -651,34 +630,32 @@ pub fn levdistance(s: &str, t: &str) -> uint {
 /**
  * Splits a string into a vector of the substrings separated by LF ('\n').
  */
-pub fn lines(s: &str) -> ~[~str] {
-    split_char_no_trailing(s, '\n')
-}
+pub fn each_line(s: &str, it: &fn(&str) -> bool) { each_split_char(s, '\n', it) }
 
 /**
  * Splits a string into a vector of the substrings separated by LF ('\n')
  * and/or CR LF ("\r\n")
  */
-pub fn lines_any(s: &str) -> ~[~str] {
-    vec::map(lines(s), |s| {
-        let l = len(*s);
-        let mut cp = copy *s;
+pub fn each_line_any(s: &str, it: &fn(&str) -> bool) {
+    for each_line(s) |s| {
+        let l = s.len();
         if l > 0u && s[l - 1u] == '\r' as u8 {
-            unsafe { raw::set_len(&mut cp, l - 1u); }
+            if !it( unsafe { raw::slice_bytes(s, 0, l - 1) } ) { return; }
+        } else {
+            if !it( s ) { return; }
         }
-        cp
-    })
+    }
 }
 
 /// Splits a string into a vector of the substrings separated by whitespace
-pub fn words(s: &str) -> ~[~str] {
-    split_nonempty(s, char::is_whitespace)
+pub fn each_word(s: &str, it: &fn(&str) -> bool) {
+    each_split_nonempty(s, |c| char::is_whitespace(c), it)
 }
 
 /** Split a string into a vector of substrings,
- *  each of which is less than a limit
+ *  each of which is less bytes long than a limit
  */
-pub fn split_within(ss: &str, lim: uint) -> ~[~str] {
+pub fn each_split_within(ss: &str, lim: uint, it: &fn(&str) -> bool) {
     let words = str::words(ss);
 
     // empty?
@@ -705,6 +682,22 @@ pub fn split_within(ss: &str, lim: uint) -> ~[~str] {
     if row != ~"" { rows.push(row); }
 
     rows
+    // NOTE: Finish change here
+
+    let mut last_slice_i = 0, last_word_i = 0, word_start = true;
+    for each_chari(s) |i, c| {
+        if (i - last_slice_i) <= lim {
+            if char::is_whitespace(c) {
+
+            } else {
+
+            }
+        } else {
+
+        }
+
+
+    }
 }
 
 
@@ -997,10 +990,17 @@ pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) {
     }
 }
 
-/// Iterates over the chars in a string
+
+/// Iterate over each char of a string, without allocating
 #[inline(always)]
 pub fn each_char(s: &str, it: &fn(char) -> bool) {
-    each_chari(s, |_i, c| it(c))
+    let mut i = 0;
+    let len = len(s);
+    while i < len {
+        let CharRange {ch, next} = char_range_at(s, i);
+        if !it(ch) { return; }
+        i = next;
+    }
 }
 
 /// Iterates over the chars in a string, with indices
@@ -1038,31 +1038,34 @@ pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) {
     }
 }
 
-/// Apply a function to each substring after splitting by character
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// NOTE: Remove afterwards
+/* /// Apply a function to each substring after splitting by character
 pub fn split_char_each(ss: &str, cc: char, ff: &fn(v: &str) -> bool) {
     vec::each(split_char(ss, cc), |s| ff(*s))
 }
 
-/**
+**
  * Apply a function to each substring after splitting by character, up to
  * `count` times
- */
+ *
 pub fn splitn_char_each(ss: &str, sep: char, count: uint,
                          ff: &fn(v: &str) -> bool) {
     vec::each(splitn_char(ss, sep, count), |s| ff(*s))
 }
 
-/// Apply a function to each word
+/ Apply a function to each word
 pub fn words_each(ss: &str, ff: &fn(v: &str) -> bool) {
     vec::each(words(ss), |s| ff(*s))
 }
 
-/**
+**
  * Apply a function to each line (by '\n')
- */
+ *
 pub fn lines_each(ss: &str, ff: &fn(v: &str) -> bool) {
     vec::each(lines(ss), |s| ff(*s))
-}
+} */
+/////////////////////////////////////////////////////////////////////////////////////////////////
 
 /*
 Section: Searching
@@ -2511,7 +2514,7 @@ impl OwnedStr for ~str {
 impl Clone for ~str {
     #[inline(always)]
     fn clone(&self) -> ~str {
-        self.to_str()  // hilarious
+        from_slice(*self)
     }
 }
 
diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs
index de8a8f34381..f837f776b96 100644
--- a/src/libstd/getopts.rs
+++ b/src/libstd/getopts.rs
@@ -601,7 +601,7 @@ pub mod groups {
             row += match short_name.len() {
                 0 => ~"",
                 1 => ~"-" + short_name + " ",
-                _ => fail!(~"the short name should only be 1 char long"),
+                _ => fail!(~"the short name should only be 1 ascii char long"),
             };
 
             // long option
@@ -617,6 +617,7 @@ pub mod groups {
                 Maybe => ~"[" + hint + ~"]",
             };
 
+            // FIXME: #5516
             // here we just need to indent the start of the description
             let rowlen = row.len();
             row += if rowlen < 24 {
@@ -625,8 +626,22 @@ pub mod groups {
                 desc_sep
             };
 
+            // Normalize desc to contain words seperated by one space character
+            let mut desc_normalized_whitespace = ~str
+            for desc.each_word |word| {
+                desc_normalized_whitespace.push_str(word);
+                desc_normalized_whitespace.push_char(' ');
+            }
+
+            // FIXME: #5516
+            let mut desc_rows: ~[~str] = ~[];
+            for desc_normalized_whitespace.each_split_within(54) |substr| {
+                desc_rows.push(~substr);
+            }
+
+            // FIXME: #5516
             // wrapped description
-            row += str::connect(str::split_within(desc, 54), desc_sep);
+            row += str::connect(desc_rows, desc_sep);
 
             row
         });