From 1655583b02578150d2ef08e16bda0c8bfe8194aa Mon Sep 17 00:00:00 2001 From: Oliver Schneider <git1984941651981@oli-obk.de> Date: Thu, 30 Apr 2015 13:13:20 +0200 Subject: [PATCH] handle windows newlines --- src/changes.rs | 44 +++++++++++++++++++++++++++++++++++++------- src/lib.rs | 7 +++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/changes.rs b/src/changes.rs index 8884b05d77e..f0aebe7c94f 100644 --- a/src/changes.rs +++ b/src/changes.rs @@ -18,8 +18,10 @@ use std::collections::HashMap; use syntax::codemap::{CodeMap, Span, BytePos}; use std::fmt; use std::fs::File; -use std::io::Write; +use std::io::{Write, stdout}; use WriteMode; +use NEWLINE_STYLE; +use NewlineStyle; // This is basically a wrapper around a bunch of Ropes which makes it convenient // to work with libsyntax. It is badly named. @@ -148,6 +150,28 @@ impl<'a> ChangeSet<'a> { -> Result<Option<String>, ::std::io::Error> { let text = &self.file_map[filename]; + // prints all newlines either as `\n` or as `\r\n` + fn write_system_newlines<T>( + mut writer: T, + text: &StringBuffer) + -> Result<(), ::std::io::Error> + where T: Write, + { + match NEWLINE_STYLE { + NewlineStyle::Unix => write!(writer, "{}", text), + NewlineStyle::Windows => { + for (c, _) in text.chars() { + match c { + '\n' => try!(write!(writer, "\r\n")), + '\r' => continue, + c => try!(write!(writer, "{}", c)), + } + } + Ok(()) + }, + } + } + match mode { WriteMode::Overwrite => { // Do a little dance to make writing safer - write to a temp file @@ -157,8 +181,8 @@ impl<'a> ChangeSet<'a> { let bk_name = filename.to_owned() + ".bk"; { // Write text to temp file - let mut tmp_file = try!(File::create(&tmp_name)); - try!(write!(tmp_file, "{}", text)); + let tmp_file = try!(File::create(&tmp_name)); + try!(write_system_newlines(tmp_file, text)); } try!(::std::fs::rename(filename, bk_name)); @@ -166,15 +190,21 @@ impl<'a> ChangeSet<'a> { } WriteMode::NewFile(extn) => { let filename = filename.to_owned() + "." + extn; - let mut file = try!(File::create(&filename)); - try!(write!(file, "{}", text)); + let file = try!(File::create(&filename)); + try!(write_system_newlines(file, text)); } WriteMode::Display => { println!("{}:\n", filename); - println!("{}", text); + let stdout = stdout(); + let stdout_lock = stdout.lock(); + try!(write_system_newlines(stdout_lock, text)); } WriteMode::Return(_) => { - return Ok(Some(text.to_string())); + // io::Write is not implemented for String, working around with Vec<u8> + let mut v = Vec::new(); + try!(write_system_newlines(&mut v, text)); + // won't panic, we are writing correct utf8 + return Ok(Some(String::from_utf8(v).unwrap())); } } diff --git a/src/lib.rs b/src/lib.rs index e22a0861390..cf191f04f95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,6 +59,7 @@ const LEEWAY: usize = 5; const MAX_WIDTH: usize = 100; const MIN_STRING: usize = 10; const TAB_SPACES: usize = 4; +const NEWLINE_STYLE: NewlineStyle = NewlineStyle::Unix; const FN_BRACE_STYLE: BraceStyle = BraceStyle::SameLineWhere; const FN_RETURN_INDENT: ReturnIndent = ReturnIndent::WithArgs; // When we get scoped annotations, we should have rustfmt::skip. @@ -75,6 +76,12 @@ pub enum WriteMode { Return(&'static Fn(HashMap<String, String>)), } +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +enum NewlineStyle { + Windows, // \r\n + Unix, // \n +} + #[derive(Copy, Clone, Eq, PartialEq, Debug)] enum BraceStyle { AlwaysNextLine,