Update the output of the reference implementation to the new format.
[tatoo.git] / tools / xml_diff.ml
index b6b9695..3c9ed7c 100644 (file)
@@ -43,7 +43,7 @@ and do_text parser_ ctx =
     Buffer.clear  ctx.text_buffer;
     Queue.add (Text s, get_position parser_) ctx.events
 
-let character_data_handler parser_ ctx text =
+let character_data_handler _ ctx text =
   Buffer.add_string ctx.text_buffer text
 
 let create_parser () =
@@ -57,6 +57,14 @@ let create_parser () =
 
 exception Diff of position
 
+let common_prefix ctx1 ctx2 len =
+  for i = 1 to len do
+    let e1,p1 = Queue.pop ctx1.events in
+    let e2,_ = Queue.pop ctx2.events in
+    if not (eq_event e1 e2) then raise (Diff p1)
+  done
+
+
 let diffs fd1 fd2 =
   let buffer1 = String.create 4096 in
   let buffer2 = String.create 4096 in
@@ -65,36 +73,40 @@ let diffs fd1 fd2 =
   let rec loop () =
     let read1 = input fd1 buffer1 0 4096 in
     let read2 = input fd2 buffer2 0 4096 in
-    if read1 == 0 && read2 == 0 then () else
+    if read1 == 0 && read2 == 0 then begin
+      let l1 = Queue.length ctx1.events in
+      let l2 = Queue.length ctx2.events in
+      if l1 > l2 then let _, p1 = Queue.pop ctx1.events in raise (Diff p1)
+      else if l2 > l1 then let _, p2 = Queue.pop ctx2.events in raise (Diff p2)
+      else common_prefix ctx1 ctx2 l1
+    end else begin
       let () = Expat.parse_sub parser1 buffer1 0 read1 in
       let () = Expat.parse_sub parser2 buffer2 0 read2 in
-      for i = 1 to min (Queue.length ctx1.events) (Queue.length ctx2.events) do
-        let e1,p1 = Queue.pop ctx1.events in
-        let e2,_ = Queue.pop ctx2.events in
-        if not (eq_event e1 e2) then
-          raise (Diff p1)
-      done;
+      common_prefix ctx1 ctx2 (min (Queue.length ctx1.events) (Queue.length ctx2.events));
       loop ()
+    end
   in
   loop ()
 
 let main () =
-  if Array.length Sys.argv != 3 then
-    Printf.eprintf "usage: %s file1.xml file2.xml\n%!" Sys.argv.(0)
-  else
+  if Array.length Sys.argv != 3 then begin
+    Printf.eprintf "usage: %s file1.xml file2.xml\n%!" Sys.argv.(0);
+    exit 2
+  end else
     let fn1 = Sys.argv.(1) in
     let fn2 = Sys.argv.(2) in
     try
       let fd1 = open_in fn1 in
       let fd2 = open_in fn2 in
-      let () =
-      try
-        diffs fd1 fd2
-      with
-        Diff p -> Printf.printf "File %s and %s differ at line %i, column %i\n%!"
-          fn1 fn2 p.line_num p.column_num
-      in close_in fd1; close_in fd2
+      let code =
+        try
+          diffs fd1 fd2; 0
+        with
+          Diff p -> Printf.eprintf "File %s and %s differ at line %i, column %i\n%!"
+            fn1 fn2 p.line_num p.column_num;1
+      in close_in fd1; close_in fd2; exit code
     with
-      _ -> Printf.eprintf "Error\n%!"
+      e -> Printf.eprintf "Error %s\n%!" (Printexc.to_string e); exit 3
+
 let () = main ()