Commits

camlspotter committed 5287834

-lines

Comments (0)

Files changed (2)

 open Parser
 
 type 'a t = 
-  | Cons of 'a * 'a t lazy_t
+  | Cons of 'a * 'a t lazy_t * in_channel
   | Null
 
 type 'a info = {
       
       Cons ({ space = space_between; token; region; substr },
             lazy (match token with
-            | EOF -> close_in ic; Null
-            | _ -> loop region))
+            | EOF -> Null
+            | _ -> loop region),
+            ic)
     in
     loop Region.zero
   with
-  | e -> 
-      close_in ic;
-      raise e
+  | e -> raise e
+
+let close = function
+  | lazy Null -> ()
+  | lazy (Cons (_, _, ic)) -> close_in ic
 
 let destr = function
   | lazy Null -> None
-  | lazy (Cons (car, cdr)) -> Some (car, cdr)
+  | lazy (Cons (car, cdr, _ic)) -> Some (car, cdr)
         f bases0
         
     | TYPE when state.last_token = Some MODULE -> (* module type *)
+        (* we might change the kind to KModuleType, but ... let's keep it simpler *)
         bases0, bases0 
           
     | TYPE ->
   { state with bases = pre_bases },
   { state with bases = post_bases }
 
-let update_state state new_line str orig_region t = 
+let update_state state new_line fix_indent str orig_region t = 
 
   (* if it is a new line, compute the line's indentation *)
   let state' =
 let parse_args () = 
   let rev_paths = ref [] in
   let debug = ref false in
+  let lines = ref None in
   Arg.parse [
-    ("-debug", Arg.Set debug, "debugging")
+    ("-debug", Arg.Set debug, "debugging");
+    ("-lines", Arg.String (fun s ->
+      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
+        if start <= 0 || end_ <= 0 || start > end_ then
+          failwith (Printf.sprintf "Wrong -lines specification: %s" s);
+        lines := Some (start, end_)
+      with
+      | _ -> 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
+  List.rev !rev_paths, !debug, !lines
 
-let paths, debug = parse_args ()
+let paths, debug, lines = parse_args ()
 
 let _ = 
   List.iter (fun path ->
     let str = lazy (Filter.streamer path) in
 
     let rec loop last_orig_region state str = match Filter.destr str with
-      | None ->
-          ()
+      | None -> ()
+
       | Some (({Filter.token = EOF} as i), _) ->
           let space_between = i.Filter.space in
           print_string space_between
-          
+            
       | Some (i, str) ->
           let t = i.Filter.token in
           let orig_region = i.Filter.region in
           let space_between = i.Filter.space in
           let substr = i.Filter.substr in
 
-(*
-          Format.eprintf "<%s %d>@."
+          (*
+            Format.eprintf "<%s %d>@."
             (Sexplib.Sexp.to_string_mach (Parser.sexp_of_token t))
             (Region.columns orig_region);
-*)
+          *)
 
           let new_line = Region.lnum last_orig_region <>  Region.lnum orig_region in
 
             if new_line then { state with orig_indent = Region.columns orig_region } else state
           in
           
-          let pre, post = update_state state new_line str orig_region t in
+          let fix_indent = 
+            match lines with
+            | Some (start, _) -> start <= Region.lnum orig_region
+            | _ -> true
+          in
 
+          let pre, post = update_state state new_line fix_indent str orig_region t in
+          
           (* 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 *)
+            | _ -> () (* the line 1 has no previous new line char *)
             end;
-
+            
             let indent_string = String.make (State.indent pre) ' ' in
             if debug then begin
               print_string indent_string;
                   (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
           end else begin
             print_string space_between;
             print_string substr;
           end;
-
-          (* Now move to the next token *)
-
+          
+              (* Now move to the next token *)
+          
           let post = 
             if new_line then 
               { post with 
-                  last_token = (if t <> COMMENT then Some t else state.last_token)
+                last_token = (if t <> COMMENT then Some t else state.last_token)
                 ; last_indent = State.indent pre 
               }
             else 
               { post with 
-                  last_token = (if t <> COMMENT then Some t else state.last_token)
+                last_token = (if t <> COMMENT then Some t else state.last_token)
               }
-
+                
           in
           
           loop orig_region post str
     in
-
-    loop Region.zero State.init str
+    try
+      loop Region.zero State.init str;
+      raise Exit
+    with
+    | Exit -> Filter.close str
   ) paths