1
2(* Counts characters, lines and words in one or several files. *)
3
4let chars = ref 0
5and words = ref 0
6and lines = ref 0
7
8type state = Inside_word | Outside_word
9
10let count_channel in_channel =
11  let rec count status =
12    let c = input_char in_channel in
13    incr chars;
14    match c with
15      '\n' ->
16        incr lines; count Outside_word
17    | ' ' | '\t' ->
18        count Outside_word
19    | _ ->
20        if status = Outside_word then begin incr words; () end;
21        count Inside_word
22  in
23    try
24      count Outside_word
25    with End_of_file ->
26      ()
27
28let count_file name =
29  let ic = open_in name in
30  count_channel ic;
31  close_in ic
32
33let print_result () =
34  print_int !chars; print_string " characters, ";
35  print_int !words; print_string " words, ";
36  print_int !lines; print_string " lines";
37  print_newline()
38
39let count name =
40  count_file name;
41  print_result ()
42
43let _ =
44try
45  if Array.length Sys.argv <= 1 then
46    count_channel stdin                (* No command-line arguments *)
47  else
48    for i = 1 to Array.length Sys.argv - 1 do
49      count_file  Sys.argv.(i)
50    done;
51  print_result ()
52with Sys_error s ->
53  print_string "I/O error: ";
54  print_string s;
55  print_newline()
56