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 if nb_files > 0 then begin for i = 1 to nb_files do count_file Sys.argv.(i) done; if nb_files > 1 then output_results "total" wc_count_total; end else begin count_channel stdin; output_results "" wc_count; end; exit 0;; main();;