1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
(***********************************************************************)
(* *)
(* Objective Caml *)
(* *)
(* Pierre Weis, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 2001 Institut National de Recherche en Informatique et *)
(* en Automatique. All rights reserved. This file is distributed *)
(* only by permission. *)
(* *)
(***********************************************************************)
open Printf;;
type entry = {
ident : string;
first_name : string;
last_name : string;
address : string;
tel : string;
url : string;
};;
type address_book = {
file : string;
entries : (string, entry) Hashtbl.t
};;
let print_entry e =
printf "First name : %s\n" e.first_name;
printf "Last name : %s\n" e.last_name;
printf "Addr : %s\n" e.address;
printf "Tel : %s\n" e.tel;
printf "URL : %s\n" e.url;;
let print_address_book ab =
print_string "Adresse book from ";
print_string ab.file;
print_newline ();
Hashtbl.iter (fun k e -> print_entry e; print_newline ()) ab.entries;;
let read_address_book_ic ic =
(input_value ic : address_book);;
let save_address_book_oc oc ab =
(output_value oc (ab : address_book));;
let read_address_book ab =
let ic = open_in_bin ab in
read_address_book_ic ic;
close_in ic;;
let save_address_book ab =
let oc = open_out_bin ab.file in
save_address_book_oc oc ab;
close_out oc;;
let make_entry id fn ln a t u = {
ident = id;
first_name = fn;
last_name = ln;
address = a;
tel = t;
url = u
};;
let dummy_entry = make_entry "" "" "" "" "" "";;
let dummy_file = "book";;
let the_book =
ref {file = dummy_file; entries = Hashtbl.create 100};;
let init_address_book ab =
if ab <> "" then read_address_book ab else read_address_book dummy_file;;
let verify_absent ab e =
let es = ab.entries in
if Hashtbl.mem es e.last_name &&
List.mem e (Hashtbl.find_all es e.last_name) then
failwith
(sprintf "Entry %s is already stored in adress book %s" e.last_name ab.file);;
let verify_present ab e =
let es = ab.entries in
let n = e.name in
if not (Hashtbl.mem es n) || not (List.mem e (Hashtbl.find_all es n)) then
failwith
(sprintf "Entry %s is not stored in adress book %s" n ab.file);;
let add_entry ab n e =
verify_absent ab e;
let es = ab.entries in
Hashtbl.add es n e;;
let rec list_remove x = function
| [] -> []
| y :: l -> if y = x then l else y :: list_remove x l;;
let remove_entry ab e =
let es = ab.entries in
let eqs = Hashtbl.find_all es e.name in
let but_e = list_remove e eqs in
List.iter (fun e -> Hashtbl.remove es e.name) eqs;
List.iter (fun e -> Hashtbl.add es e.name e) but_e;;
let modify_entry ab e new_e =
verify_present ab e;
verify_absent ab new_e;
remove_entry ab e;
add_entry ab e.name new_e;;
let delete_entry ab e =
verify_present ab e;
remove_entry ab e;;
let search_named_entry ab n =
Hashtbl.find_all ab.entries n;;
let search ab p =
let res = ref [] in
Hashtbl.iter (fun k v -> if p k v then res := v :: !res) ab.entries;
!res;;
let search_regexp_entry foldp ab pat =
let re = if foldp then Str.regexp_case_fold pat else Str.regexp pat in
search ab (fun k v -> Str.string_match re k 0);;
let full_text_regexp_search foldp ab pat =
let re = if foldp then Str.regexp_case_fold pat else Str.regexp pat in
search ab
(fun k v ->
Str.string_match re v.name 0 ||
Str.string_match re v.address 0 ||
Str.string_match re v.tel 0 ||
Str.string_match re v.url 0);;
type search_entry_predicate = {
name_pred : string -> bool;
address_pred : string -> bool;
tel_pred : string -> bool;
url_pred : string -> bool;
};;
type search_entry_pattern = {
name_pat : string;
address_pat : string;
tel_pat : string;
url_pat : string;
};;
let full_search ab se =
search ab
(fun k v ->
se.name_pred v.name ||
se.address_pred v.address ||
se.tel_pred v.tel ||
se.url_pred v.url);;
let full_text_regexp_search foldp ab pat =
let regexp = if foldp then Str.regexp_case_fold else Str.regexp in
let str_match p s = Str.string_match (regexp p) s 0 in
let se = {
name_pred = str_match pat.name_pat;
address_pred = str_match pat.address_pat;
tel_pred = str_match pat.tel_pat;
url_pred = str_match pat.url_pat;
} in
full_search ab se;;
let make_name_entry_pattern pat = {
name_pat = pat;
address_pat = "";
tel_pat = "";
url_pat = "";
};;
let make_full_text_entry_pattern pat = {
name_pat = pat;
address_pat = pat;
tel_pat = pat;
url_pat = pat;
};;
let full_search ab pat =
full_text_regexp_search true ab (make_full_text_entry_pattern pat);;
let enter_new_entry n a t u = add_entry !the_book n (make_entry n a t u);;
enter_new_entry
"Weis"
"Domaine de Voluceau"
"5738"
"http://pauillac.inria.fr/~weis/";;
print_address_book !the_book;;
|