Advertisement
Guest User

Untitled

a guest
Aug 18th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 1.80 KB | None | 0 0
  1. (* filemerge.ml *)
  2.  
  3. type sortrecord = { line: string; f: in_channel }
  4.  
  5. let basename = let argv0 = Array.get Sys.argv 0 in
  6. let first = (String.rindex argv0 '/') + 1 in
  7. let len = (String.length argv0) - first in
  8.          String.sub argv0 first len;;
  9.  
  10. let ( |! ) a b = b a ;;
  11.  
  12. (* filemerge: merge sort the provided list of pre-sorted files and write
  13.  * the result to stdout *)
  14. (** string list -> unit **)
  15. let rec filemerge filenames =
  16.   (* recharge: Creates a new sortrecord list with the next line
  17.    * from the given channel; or an empty list, if the channel has
  18.    * closed. *)
  19.   (** in_channel -> sortrecord list **)
  20.   let recharge fd =
  21.     try
  22.       Some {
  23.         line = input_line fd;
  24.         f = fd
  25.       }
  26.     with
  27.       End_of_file ->
  28.         close_in_noerr fd;
  29.         None
  30.   in
  31.   (* work: Recursively spit out lines until all the files are gone *)
  32.   (* sortrecord list -> unit *)
  33.   let rec work units =
  34.     match
  35.       List.fold_left
  36.         (fun accum x ->
  37.           match accum with
  38.           | [] -> [x]
  39.           | winner :: rest ->
  40.               if compare x.line winner.line < 0
  41.               then x :: winner :: rest
  42.               else winner :: x :: rest
  43.         )
  44.         []
  45.         units
  46.     with
  47.     | [] -> ()
  48.     | hd :: tl ->
  49.         print_endline hd.line;
  50.         (match recharge hd.f with
  51.          | Some x -> work (x :: tl)
  52.          | None -> work tl
  53.         )
  54.   in
  55.   work (
  56.     List.map open_in filenames
  57.     |! List.map recharge
  58.     |! List.filter (function Some _ -> true | None -> false)
  59.     |! List.map (function Some x -> x | None -> failwith "bug")
  60.   )
  61. ;;
  62.  
  63. let () =
  64.   match Array.to_list Sys.argv with
  65.   | [] -> failwith "no arg0 wtf"
  66.   | _ :: [] -> Printf.printf "Usage: %s [file1 .. fileN]\n" basename
  67.   | _ :: files -> filemerge files
  68. ;;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement