diff --git a/src/fold/fold.rs b/src/fold/fold.rs index f411d2a7c..ca761173f 100644 --- a/src/fold/fold.rs +++ b/src/fold/fold.rs @@ -94,6 +94,7 @@ fn handle_obsolete(args: &[String]) -> (Vec, Option) { (args, None) } +#[inline] fn fold(filenames: Vec, bytes: bool, spaces: bool, width: uint) { for filename in filenames.iter() { let filename: &str = filename.as_slice(); @@ -112,27 +113,20 @@ fn fold(filenames: Vec, bytes: bool, spaces: bool, width: uint) { } } +#[inline] fn fold_file(file: BufferedReader, bytes: bool, spaces: bool, width: uint) { let mut file = file; for line in file.lines() { let line_string = safe_unwrap!(line); let mut line = line_string.as_slice(); - let len = line.len(); - if line.char_at(len - 1) == '\n' { - if len == 1 { - println!(""); - continue; - } else { - line = line.slice_to(len - 1); - } - } if bytes { + let len = line.len(); let mut i = 0; - while i < line.len() { - let width = if line.len() - i >= width { width } else { line.len() - i }; + while i < len { + let width = if len - i >= width { width } else { len - i }; let slice = { let slice = line.slice(i, i + width); - if spaces && i + width < line.len() { + if spaces && i + width < len { match slice.rfind(|ch: char| ch.is_whitespace()) { Some(m) => slice.slice_to(m + 1), None => slice @@ -141,10 +135,24 @@ fn fold_file(file: BufferedReader, bytes: bool, spaces: bool, slice } }; - println!("{}", slice); + print!("{}", slice); i += slice.len(); } } else { + let mut len = line.char_len(); + let newline = + if len == 0 { + continue; + } else if len == 1 && line.char_at(len - 1) == '\n' { + println!(""); + continue; + } else if line.char_at(len - 1) == '\n' { + line = line.slice_to(line.len() - 1); + len -= 1; + true + } else { + false + }; let mut output = String::new(); let mut count = 0; for (i, ch) in line.chars().enumerate() { @@ -152,11 +160,11 @@ fn fold_file(file: BufferedReader, bytes: bool, spaces: bool, let (val, ncount) = { let slice = output.as_slice(); let (out, val, ncount) = - if spaces && i + 1 < line.len() { - match slice.rfind(|ch: char| ch.is_whitespace()) { + if spaces && i + 1 < len { + match rfind_whitespace(slice) { Some(m) => { - let routput = slice.slice_from(m + 1).to_string(); - let ncount = routput.as_slice().chars().fold(0u, |out, ch: char| { + let routput = slice.slice_chars(m + 1, slice.char_len()); + let ncount = routput.chars().fold(0u, |out, ch: char| { out + match ch { '\t' => 8, '\x08' => if out > 0 { -1 } else { 0 }, @@ -164,17 +172,17 @@ fn fold_file(file: BufferedReader, bytes: bool, spaces: bool, _ => 1 } }); - (slice.slice_to(m + 1), routput, ncount) + (slice.slice_chars(0, m + 1), routput, ncount) }, - None => (slice, "".to_string(), 0) + None => (slice, "", 0) } } else { - (slice, "".to_string(), 0) + (slice, "", 0) }; println!("{}", out); - (val, ncount) + (val.into_string(), ncount) }; - output = val.into_string(); + output = val; count = ncount; } match ch { @@ -204,8 +212,22 @@ fn fold_file(file: BufferedReader, bytes: bool, spaces: bool, output.push(ch); } if count > 0 { - print!("{}", output); + if newline { + println!("{}", output); + } else { + print!("{}", output); + } } } } } + +#[inline] +fn rfind_whitespace(slice: &str) -> Option { + for (i, ch) in slice.chars().rev().enumerate() { + if ch.is_whitespace() { + return Some(slice.char_len() - (i + 1)); + } + } + None +}