[vala/0.10-parallel: 22/32] CodeWriter: Do not replace .vapi if unchanged



commit a6d9b01fdd8820da465c7d47dd4fb66a45bd5340
Author: Ryan Lortie <desrt desrt ca>
Date:   Sat Aug 28 16:30:05 2010 +0200

    CodeWriter: Do not replace .vapi if unchanged
    
    Steal some logic from the CCodeWriter to avoid replacing .vapi output if
    nothing has changed.

 vala/valacodewriter.vala |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)
---
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index 056f20d..cc8ad04 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -65,9 +65,16 @@ public class Vala.CodeWriter : CodeVisitor {
 	 * @param filename a relative or absolute filename
 	 */
 	public void write_file (CodeContext context, string filename) {
+		var file_exists = FileUtils.test (filename, FileTest.EXISTS);
+		var temp_filename = filename + ".valatmp";
 		this.context = context;
-	
-		stream = FileStream.open (filename, "w");
+
+		if (file_exists) {
+			stream = FileStream.open (temp_filename, "w");
+		} else {
+			stream = FileStream.open (filename, "w");
+		}
+
 		if (stream == null) {
 			Report.error (null, "unable to open `%s' for writing".printf (filename));
 			return;
@@ -87,6 +94,32 @@ public class Vala.CodeWriter : CodeVisitor {
 		current_scope = null;
 
 		stream = null;
+
+		if (file_exists) {
+			var changed = true;
+
+			try {
+				var old_file = new MappedFile (filename, false);
+				var new_file = new MappedFile (temp_filename, false);
+				var len = old_file.get_length ();
+				if (len == new_file.get_length ()) {
+					if (Memory.cmp (old_file.get_contents (), new_file.get_contents (), len) == 0) {
+						changed = false;
+					}
+				}
+				old_file = null;
+				new_file = null;
+			} catch (FileError e) {
+				// assume changed if mmap comparison doesn't work
+			}
+
+			if (changed) {
+				FileUtils.rename (temp_filename, filename);
+			} else {
+				FileUtils.unlink (temp_filename);
+			}
+		}
+
 	}
 
 	public override void visit_using_directive (UsingDirective ns) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]