-
Notifications
You must be signed in to change notification settings - Fork 1
/
persist.ml
73 lines (63 loc) · 2.55 KB
/
persist.ml
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
(* vim:sw=4 ts=4 sts=4 expandtab spell spelllang=en
*)
(* Copyright 2012, Cedric Cellier
*
* This file is part of RobiNet.
*
* RobiNet is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RobiNet is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with RobiNet. If not, see <http://www.gnu.org/licenses/>.
*)
(**
Simple serialization module
Helps to keep an object state in a file in a friendly format (for instance
javascript or csv)
*)
open Batteries
let debug = false
let rootdir = "persist"
let mkdir_all ?(is_file=false) dir =
let dir_exist d =
try Unix.is_directory d
with Unix.Unix_error _ -> false in
let dir = if is_file then Filename.dirname dir else dir in
let rec ensure_exist d =
if debug then Printf.printf "Persist: Ensure dir '%s' exists\n%!" d ;
if String.length d > 0 && not (dir_exist d) then (
ensure_exist (Filename.dirname d) ;
if debug then Printf.printf "Persist: Creating directory '%s'\n%!" d ;
try Unix.mkdir d 0o755
with Unix.Unix_error (Unix.EEXIST, "mkdir", _) ->
(* Happen when we have "somepath//someother" (dirname should handle this IMHO *)
()
) in
ensure_exist dir
let make_abs family fname =
let fname = Filename.(concat (concat rootdir family) fname) in
mkdir_all ~is_file:true fname ;
fname
let with_input_file family fname default func =
try File.with_file_in (make_abs family fname) func
with Sys_error _ -> (* we suppose all sys_errors are no_such_file :-/ *)
func (BatIO.input_string default)
let with_output_file family fname func = File.with_file_out (make_abs family fname) func
(* All names of a category must be unique *)
let genname =
let seqfile = ".genname" in
let seq = ref (with_input_file "system" seqfile "0\n" (fun ic ->
Scanf.bscanf (Scanf.Scanning.from_input ic) "%d" identity)) in
let save_seq () = with_output_file "system" seqfile (fun oc ->
Printf.fprintf oc "%d\n" !seq) in
at_exit save_seq ;
fun pref ->
incr seq ;
pref ^ (string_of_int !seq)