wc.ml
type counts = {
 mutable chars : int;
 mutable lines : int;
 mutable words : int;
};;

let wc_count = {chars = 0; lines = 0; words = 0};;
let wc_count_total = {chars = 0; lines = 0; words = 0};;

let reset_count () =
 wc_count.chars <- 0;
 wc_count.lines <- 0;
 wc_count.words <- 0;;

let cumulate () =
 wc_count_total.chars <- wc_count_total.chars + wc_count.chars;
 wc_count_total.lines <- wc_count_total.lines + wc_count.lines;
 wc_count_total.words <- wc_count_total.words + wc_count.words;;

let rec counter ic iw =
 let c = input_char ic in
 wc_count.chars <- wc_count.chars + 1;
 match c with
 | ' ' | '\t' ->
    if iw then wc_count.words <- wc_count.words + 1 else ();
    counter ic false
 | '\n' ->
    wc_count.lines <- wc_count.lines + 1;
    if iw then wc_count.words <- wc_count.words + 1 else ();
    counter ic false
 | c ->
    counter ic true;;

let count_channel ic =
 reset_count ();
 try counter ic false with
 | End_of_file -> cumulate (); close_in ic;;

let output_results s wc =
  Printf.printf "%7d%8d%9d %s\n" wc.lines  wc.words wc.chars  s
;;


let count_file file_name =
 try
  let ic = open_in file_name in
  count_channel ic;
  output_results file_name wc_count;
 with Sys_error s -> print_string s; print_newline(); exit 2
;;

let main () =
 let nb_files = Array.length Sys.argv - 1 in
 for i = 1 to nb_files do
  count_file Sys.argv.(i)
 done;
 if nb_files > 1 then output_results "total" wc_count_total;
 exit 0;;

main();;