method read ?obsoletes ?(no_default=false)
?(on_type_error = fun groupable_cp raw_cp output filename in_channel ->
close_in in_channel;
Printf.eprintf
"Type error while loading configuration parameter %s from file %s.\n%!"
(String.concat "." groupable_cp#get_name) filename;
output stderr;
exit 1)
filename =
match Sys.file_exists filename with false -> self#write filename | true ->
let in_channel = open_in filename in
let missing cp default = if no_default then raise (Missing_cp cp) else default in
let choose queue =
let rec iter q = Queue.iter (function
| _, Immediate cp -> raise (Found_cp cp)
| _, Subsection q -> iter q) q in
try iter queue; failwith "choose" with Found_cp cp -> cp in
let set_cp cp value =
try cp#set_raw value
with Wrong_type output -> on_type_error cp value output filename in_channel in
let rec set_and_remove raw_cps = function
| name, Immediate cp ->
(try list_assoc_remove name (fun value -> set_cp cp value; None) raw_cps
with Not_found -> missing cp raw_cps)
| name, Subsection queue ->
(try list_assoc_remove name
(function
| Raw.Section l ->
(match remainings l queue with
| [] -> None
| l -> Some (Raw.Section l))
| r -> missing (choose queue) (Some r))
raw_cps
with Not_found -> missing (choose queue) raw_cps)
and remainings raw_cps queue = Queue.fold set_and_remove raw_cps queue in
let remainings = remainings (Raw.of_channel in_channel) cps in
if remainings <> [] then match obsoletes with
| Some filename ->
let out_channel =
open_out filename in
let formatter = Format.formatter_of_out_channel out_channel in
Format.fprintf formatter "@[<v>";
Raw.save formatter (Raw.Section remainings);
Format.fprintf formatter "@]@.";
close_out out_channel
| None -> ()