let replace_file ?(justcreatenewfile = false) path_orig func =
let dir_orig = Filename.dirname path_orig
and fn_orig = Filename.basename path_orig in
let (processing_res, path_tmp) =
(*
подумать, как ловить ошибку в with -- ибо тут явно она,
Sys_error при вызове replace_file.
0. ловить ли исключения в with-обёртке в try open_.. и try close_.. так,
чтобы сообщать о них особым образом, типа failwith "Filew.with_..:
open_in_bin failed"?
1. использовать ли Res в Filew?
2. придумать ли шнягу для оборачивания ошибок, возникающих
только в with-обёртке? (видимо заменой пользовательской функции
на что-то, следящее за исключениями?
"with1_catch thehandler with_file_in_bin path_orig & fun ..."
)
*)
with_file_in_bin path_orig
(fun in_ch ->
with_temp_file_opened_bin ~cleanup: false ~temp_dir: dir_orig
(fn_orig ^ ".") ".new"
(fun path_tmp out_ch ->
let res =
try
match func in_ch out_ch with
| None -> `Ok
| Some e -> `Error e
with | e -> `Exn e
in (res, path_tmp)))
in
match processing_res with
| `Exn e -> (remove_file path_tmp; raise e)
| `Error e -> (remove_file path_tmp; Some e)
| `Ok ->
(if justcreatenewfile
then ()
else
(let path_bak = rename_to_tmp path_orig (fn_orig ^ ".") ".bak" in
let new_to_orig = rename_opt path_tmp path_orig
in
match new_to_orig with
| None -> remove_file path_bak
| Some e -> (rename path_bak path_orig; raise e));
None)