forked from ermine/sulci
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lang.ml
133 lines (116 loc) · 3.98 KB
/
lang.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
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
(*
* (c) 2004-2012 Anastasia Gornostaeva
*)
open Common
let ext = ".htbl"
module LangMap = Map.Make(String)
type langtime_t = {
expand_time: string -> int -> int -> int -> int -> int -> int -> string;
float_seconds: string -> float -> string
}
module LangTime = Map.Make(String)
let langmsgs : (string, string) Hashtbl.t LangMap.t ref = ref LangMap.empty
let langtime : langtime_t LangTime.t ref = ref LangTime.empty
let langdir = ref ""
let deflang = ref "ru"
let load_htbl cfg lang =
let htbl = Marshal.from_channel
(open_in_bin (Filename.concat !langdir (lang ^ ext))) in
langmsgs := LangMap.add lang htbl !langmsgs
let find_htbl lang =
try
LangMap.find lang !langmsgs
with Not_found ->
try
let htbl = Marshal.from_channel
(open_in_bin (Filename.concat !langdir (lang ^ ext))) in
langmsgs := LangMap.add lang htbl !langmsgs;
htbl
with _ ->
LangMap.find !deflang !langmsgs
let process str args =
let rec aux_subst acc part = function
| [] -> List.rev (part :: acc)
| arges ->
try
let mark = String.index part '%' in
if mark+1 < String.length part then
match part.[mark+1] with
| '1'..'9' as d -> (
let n = Char.code d - Char.code '0' -1 in
if mark+2 < String.length part then
match part.[mark+2] with
| 's' ->
aux_subst (List.nth args n ::
String.sub part 0 mark :: acc)
(string_after part (mark+3)) arges
| _ ->
aux_subst (String.sub part 0 (mark+3) :: acc)
(string_after part (mark+3)) arges
else
List.rev (part :: acc)
)
| 's' ->
aux_subst (List.hd arges :: String.sub part 0 mark :: acc)
(string_after part (mark+2)) (List.tl arges)
| _ ->
aux_subst (String.sub part 0 (mark+2) :: acc)
(string_after part (mark+2)) arges
else
List.rev (part :: acc)
with Not_found ->
List.rev (part :: acc)
in
let res = aux_subst [] str args in
String.concat "" res
let get_msg lang msgid args =
try
let htbl = find_htbl lang in
let str =
try Hashtbl.find htbl msgid with _ ->
let hashtbl = LangMap.find !deflang !langmsgs in
Hashtbl.find hashtbl msgid
in
process str args
with Not_found ->
(*
log#error "lang not found: [%s]\n" msgid;
*)
"[not found in lang pack: " ^ msgid ^ "]"
let update lang =
try
let htbl = Marshal.from_channel
(open_in_bin (Filename.concat !langdir (lang ^ ext))) in
langmsgs := LangMap.add lang htbl !langmsgs;
"Updated"
with exn ->
Printexc.to_string exn
let expand_time ~lang cause seconds =
let year, month, day, hour, min, sec = Strftime.seconds_to_string seconds in
let f =
try
(LangTime.find lang !langtime).expand_time
with Not_found ->
(LangTime.find !deflang !langtime).expand_time
in
f cause year month day hour min sec
let float_seconds lang cause seconds =
let f =
try
(LangTime.find lang !langtime).float_seconds
with Not_found ->
(LangTime.find !deflang !langtime).float_seconds
in
f cause seconds
let update_msgid (lang:string) (msgid:string) (str:string option) =
let htbl = LangMap.find lang !langmsgs in
(match str with
| None -> Hashtbl.remove htbl msgid
| Some data ->
if Hashtbl.mem htbl msgid then
Hashtbl.replace htbl msgid data
else
Hashtbl.add htbl msgid data;
);
let mout = open_out_bin (Filename.concat !langdir (lang ^ ext)) in
Marshal.to_channel mout htbl []