Commits

camlspotter committed 0234955 Merge
  • Participants
  • Parent commits 64539e6, a56d9bd

Comments (0)

Files changed (1)

 
 let update_state state new_line fix_indent str orig_region t = 
 
-  (* if it is a new line, compute the line's indentation *)
+  (* If it is a new line + we need to fix the indent of the line, compute the line's indentation. 
+     Otherwise, we use the original state.
+  *)
   let state' =
-    if new_line then
+    if fix_indent && new_line then
       let pre, _ = token state str new_line orig_region t in
       { pre with last_indent = State.indent pre }
     else
       state
   in
 
+  (* Fix the indentation. It may be updated by the previous call of [token]. *)
   let fixed_region = Region.move_chars (state'.last_indent - state.orig_indent) orig_region in
-
-  (* We update the last_indent. It may be updated by the first call of token at new_line *)
   let state = { state with last_indent = state'.last_indent } in
 
+  (* Rerun [token] *)
   token state str new_line fixed_region t
 
 let parse_args () = 
       try 
         let pos = String.index s '-' in
         let (start,end_) = (int_of_string (String.sub s 0 pos),
-                            int_of_string (String.sub s (pos+1) (String.length s - pos))) in
+                            int_of_string (String.sub s (pos+1) (String.length s - pos - 1))) in
         if start <= 0 || end_ <= 0 || start > end_ then
           failwith (Printf.sprintf "Wrong -lines specification: %s" s);
         lines := Some (start, end_)
       | _ -> failwith (Printf.sprintf "Wrong -lines specification: %s" s)),
      "lines, ex. 10-12") 
   ] (fun s -> rev_paths := s :: !rev_paths) "indent paths";
-  List.rev !rev_paths, !debug, !lines
+  let paths = List.rev !rev_paths in
+  let debug = !debug in
+  let lines = !lines in
+  begin match paths, lines with
+  | ([] | [_]), _ -> ()
+  | _, Some _ -> failwith "Region can be specified with at most one file" 
+  | _ -> ()
+  end;
+  paths, debug, lines
 
 let paths, debug, lines = parse_args ()
 
+module Printer = struct
+
+  type t = (int * int) option
+      
+  let add_string t lnum s =
+    let add_line t lnum s =
+      match t with
+      | None -> print_string s
+      | Some (start, end_) ->
+          if lnum < start then ()
+          else if lnum > end_ then raise Exit
+          else print_string s
+    in
+    let get_line s =
+      try 
+        let pos = String.index s '\n' in
+        String.sub s 0 (pos + 1), 
+        Some (String.sub s (pos + 1) (String.length s - pos - 1))
+      with
+      | Not_found -> s, None
+    in
+    let rec iter lnum s = 
+      let line, rest =  get_line s in
+      add_line t lnum line;
+      match rest with
+      | Some s -> iter (lnum+1) s
+      | None -> ()
+    in
+    iter lnum s
+  ;;
+    
+end 
+
 let _ = 
+  let printer = lines in
+    
   List.iter (fun path ->
     let str = lazy (Filter.streamer path) in
 
             (Region.columns orig_region);
           *)
 
-          let new_line = Region.lnum last_orig_region <>  Region.lnum orig_region in
+          let last_line = Region.lnum last_orig_region in
+          let current_line = Region.lnum orig_region in
+          let new_line = last_line <>  current_line in
 
           let state = 
             if new_line then { state with orig_indent = Region.columns orig_region } else state
           (* printing *)
           
           if new_line then begin
-            begin try 
-              let pos = String.rindex space_between '\n' in 
-              print_endline (String.sub space_between 0 pos)
-            with
-            | _ -> () (* the line 1 has no previous new line char *)
-            end;
+            (* the line 1 has no previous new line char *)
+            let spaces = try String.sub space_between 0 (String.rindex space_between '\n' + 1) with _ -> "" in 
+            Printer.add_string printer last_line spaces;
             
             let indent_string = String.make (State.indent pre) ' ' in
             if debug then begin
-              print_string indent_string;
+              Printer.add_string printer current_line indent_string;
               if pre == post then 
-                Format.printf "-- %s@." (Sexplib.Sexp.to_string_mach (Stack.sexp_of_t pre.bases))
+                Printer.add_string printer current_line (Printf.sprintf "-- %s\n" (Sexplib.Sexp.to_string_mach (Stack.sexp_of_t pre.bases)))
               else
-                Format.printf "-- %s // %s@." 
-                  (Sexplib.Sexp.to_string_mach (Stack.sexp_of_t pre.bases))
-                  (Sexplib.Sexp.to_string_mach (Stack.sexp_of_t post.bases))
+                Printer.add_string printer current_line 
+                  (Printf.sprintf "-- %s // %s\n" 
+                     (Sexplib.Sexp.to_string_mach (Stack.sexp_of_t pre.bases))
+                     (Sexplib.Sexp.to_string_mach (Stack.sexp_of_t post.bases)))
             end;
             
-            print_string indent_string;
-            print_string substr
+            Printer.add_string printer current_line indent_string;
+            Printer.add_string printer current_line substr
           end else begin
-            print_string space_between;
-            print_string substr;
+            Printer.add_string printer current_line space_between;
+            Printer.add_string printer current_line substr;
           end;
           
-              (* Now move to the next token *)
+          (* Now move to the next token *)
           
           let post = 
             if new_line then