about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-06-15 20:40:14 -0700
committerbors <bors@rust-lang.org>2013-06-15 20:40:14 -0700
commitb9119edc55287bb1a9b5609bdef84001c3341e22 (patch)
tree77af5c825954526dfb8cddf081e37c27fcdc0e93 /src/libsyntax
parentc989b79127c5062df0a64d8c383de93c82a3d9b7 (diff)
parent876f6deb4af73d3a6a9845c8ca0a9edff0e25989 (diff)
downloadrust-b9119edc55287bb1a9b5609bdef84001c3341e22.tar.gz
rust-b9119edc55287bb1a9b5609bdef84001c3341e22.zip
auto merge of #7114 : pnkfelix/rust/issue3961-fix-whitespace-detection, r=brson
r?  (yes, the review request is back, now that I got it building against incom... I mean master!)

(Attempting to port from orphaned pull-request #6764 )

Fix for #3961. Also includes a test case to illustrate the issues. (All of the entries that say "should align" should align with each other, and the four lines near the end that say "compare _" for _ in {A,B,C,D} should line up with each other.)

Before applying this change set:
-- the "(should align)"'s are all over the place, and the form/line feeding spaces are not cut out as one might or might not expect.
-- compare B and D do not match A and C.

(To be honest, its hard to really say what the right behavior is here, and people who are expecting a particular behavior out of a pretty printer in these cases may well get burned.)

Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/parse/comments.rs37
1 files changed, 23 insertions, 14 deletions
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 68473f11537..b7bb1b3bc53 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -197,26 +197,35 @@ fn read_line_comments(rdr: @mut StringReader, code_to_the_left: bool,
     }
 }
 
-// FIXME #3961: This is not the right way to convert string byte
-// offsets to characters.
-fn all_whitespace(s: &str, begin: uint, end: uint) -> bool {
-    let mut i: uint = begin;
-    while i != end {
-        if !is_whitespace(s[i] as char) { return false; } i += 1u;
+// Returns None if the first col chars of s contain a non-whitespace char.
+// Otherwise returns Some(k) where k is first char offset after that leading
+// whitespace.  Note k may be outside bounds of s.
+fn all_whitespace(s: &str, col: CharPos) -> Option<uint> {
+    let len = s.len();
+    let mut col = col.to_uint();
+    let mut cursor: uint = 0;
+    while col > 0 && cursor < len {
+        let r: str::CharRange = s.char_range_at(cursor);
+        if !r.ch.is_whitespace() {
+            return None;
+        }
+        cursor = r.next;
+        col -= 1;
     }
-    return true;
+    return Some(cursor);
 }
 
 fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
                                         s: ~str, col: CharPos) {
     let len = s.len();
-    // FIXME #3961: Doing bytewise comparison and slicing with CharPos
-    let col = col.to_uint();
-    let s1 = if all_whitespace(s, 0, uint::min(len, col)) {
-        if col < len {
-            s.slice(col, len).to_owned()
-        } else {  ~"" }
-    } else { s };
+    let s1 = match all_whitespace(s, col) {
+        Some(col) => {
+            if col < len {
+                s.slice(col, len).to_owned()
+            } else {  ~"" }
+        }
+        None => s,
+    };
     debug!("pushing line: %s", s1);
     lines.push(s1);
 }