agrep.ml
(* On parse les arguments sur la ligne de commande en utilisant le module Arg *) let split_string = ref "$";; let set_split s = split_string := s;; let pattern_string = ref None let interactive = ref true let files = ref [] let add_pattern_or_file s = match !pattern_string with None -> pattern_string := Some s | _ -> files := s :: !files;; let options = [ "-d", Arg.String set_split, "Set delimiter pattern"; ] let usage = "Usage: grep [-d DELIMITER_STRING ] REGEXP file1 .. filen";; let () = Arg.parse options add_pattern_or_file usage;; let delim = Str.regexp !split_string let pattern = match !pattern_string with | None -> print_endline usage; exit 1 | Some s -> Str.regexp s let matches regexp line = try let _ = Str.search_forward regexp line 0 in true with Not_found -> false;; (* le traitement d'une region *) let process_region lines = if List.exists (matches pattern) lines then begin List.iter print_endline (List.rev lines); flush stdout end;; (* On accumule les lignes jusqu'a une ligne separatrice *) let rec iter_region chan r = try let line = input_line chan in if matches delim line then (process_region r; iter_region chan [ line ]) else iter_region chan (line :: r) with End_of_file -> process_region r;; let process_chan chan = iter_region chan [] (* main *) let () = match !files with [] -> process_chan stdin | l -> let process file = Printf.printf "<<%d>>\n" (match !pattern_string with Some s -> Char.code s.[2] | _ -> 0); let c = open_in file in process_chan c; close_in c in List.iter process l;;