Codebase list ocaml-extunix / 75b6e39
Updated version 0.1.5 from 'upstream/0.1.5' with Debian dir af834583b1cc145669a23f61ef6fee416f78b1b1 Stephane Glondu 6 years ago
21 changed file(s) with 4952 addition(s) and 3838 deletion(s). Raw diff Collapse all Expand all
0 language: c
1 sudo: required
2 install: wget https://raw.githubusercontent.com/ocaml/ocaml-ci-scripts/master/.travis-opam.sh
3 script: bash -ex .travis-opam.sh
4 env:
5 - OCAML_VERSION=4.00
6 - OCAML_VERSION=4.01
7 - OCAML_VERSION=4.02
8 - OCAML_VERSION=4.03
9 - OCAML_VERSION=4.04
10 os:
11 - linux
12 - osx
0 0.1.5 - 28 Jun 2017
1 * build with -safe-string
2
3 0.1.4 - 11 Nov 2016
4 + SO_REUSEPORT
5 * fix sendmsg bug
6 * fix build on mingw
7
08 0.1.3 - 24 Nov 2015
19 * New bindings :
210 * fchmodat
00
11 ExtUnix OCaml library
22 =====================
3
4 [![Build Status](https://travis-ci.org/ygrek/extunix.svg?branch=master)](https://travis-ci.org/ygrek/extunix)
5 [![Build status](https://ci.appveyor.com/api/projects/status/66fpgc2qol5fu30g?svg=true)](https://ci.appveyor.com/project/ygrek/extunix/branch/master)
36
47 A collection of thin bindings to various low-level system API.
58
6972 * Be MT friendly by default - i.e. release runtime lock for blocking
7073 operations, (FIXME) optionally provide ST variants
7174
72 Portability:
75 Portability:
7376 * No shell scripting for build and install (think windows :) )
7477 * Write portable C code (use compiler options to catch compatibility issues),
7578 NB: msvc doesn't support C99.
126129 ---------------------
127130
128131 * Review `git log` and update CHANGES.txt
129 * Update version in _oasis and `oasis setup`
132 * Update version in _oasis and do `oasis setup`
130133 * Commit
131134 * `make release`
132 * Upload (forge and oasis-db) and update download links on web page
133 * Commit
135 * Upload tarball and update download links on web page
136 * Update opam
134137
135138 Development
136139 -----------
138141 Many people contribute to extunix. Please submit your patches and/or feature requests
139142 to project bugtracker at
140143
141 https://forge.ocamlcore.org/tracker/?group_id=175
144 https://github.com/ygrek/extunix/issues
142145
143146 Current maintainer is reachable at :
144147
00 OASISFormat: 0.4
11 Name: extunix
2 Version: 0.1.3
2 Version: 0.1.5
33 License: LGPL-2.1 with OCaml linking exception
44 Authors: ygrek, Sylvain Le Gall, Stéphane Glondu, Kaustuv Chaudhuri, Joshua Smith, Niki Yoshiuchi, Gerd Stolpmann, Goswin von Brederlow, Andre Nathan, Zhenya Lykhovyd, Mehdi Dogguy, Roman Vorobets, Pierre Chambart, Dmitry Grebeniuk, François Bobot
55 Copyrights:
4242 Path: src/
4343 Modules: ExtUnix, ExtUnixAll, ExtUnixSpecific, ExtUnixConfig
4444 if flag(strict) && ccomp_type(cc)
45 CCOpt: -std=c89 -pedantic -Wno-long-long -Wextra
45 CCOpt: -pedantic -Wno-long-long -Wextra
4646 CSources: config.h,
4747 eventfd.c, dirfd.c, fsync.c, statvfs.c, atfile.c,
4848 ioctl_siocgifconf.c, uname.c, fadvise.c, fallocate.c,
4949 tty_ioctl.c, unistd.c, stdlib.c, signalfd.c, ptrace.c,
5050 resource.c, mman.c, time.c, pts.c, execinfo.c, malloc.c,
51 endian.c, read_cred.c, fexecve.c, sendmsg.c,
51 endian.c, read_cred.c, fexecve.c, sendmsg.c, mktemp.c,
5252 memalign.c, endianba.c, pread_pwrite_ba.c, bigarray.c,
5353 splice.c, sysconf.c, common.c, common.h, sockopt.c, poll.c,
5454 sysinfo.c, mount.c, unshare.c
55 BuildDepends: unix, bigarray
55 BuildDepends: unix, bigarray, bytes
5656
5757 Executable test
5858 Path: test/
7979 Custom: true
8080 CompiledObject: best
8181 MainIs: test_user_namespace.ml
82 BuildDepends: bytes, str, extunix, oUnit (>= 1.0.3)
82 BuildDepends: str, extunix, oUnit (>= 1.0.3)
8383
8484 Test main
8585 Command: $test && $testba
00 # OASIS_START
1 # DO NOT EDIT (digest: 957cfd9ae0923eb98d90af8c7e21f978)
1 # DO NOT EDIT (digest: 853ac0fe9d8ae2341b7b84ec2bc2ffed)
22 # Ignore VCS directories, you can use the same kind of rule outside
33 # OASIS_START/STOP if you want to exclude directories that contains
44 # useless stuff for the build process
4040 "src/read_cred.c": oasis_library_extunix_ccopt
4141 "src/fexecve.c": oasis_library_extunix_ccopt
4242 "src/sendmsg.c": oasis_library_extunix_ccopt
43 "src/mktemp.c": oasis_library_extunix_ccopt
4344 "src/memalign.c": oasis_library_extunix_ccopt
4445 "src/endianba.c": oasis_library_extunix_ccopt
4546 "src/pread_pwrite_ba.c": oasis_library_extunix_ccopt
5455 "src/unshare.c": oasis_library_extunix_ccopt
5556 <src/extunix.{cma,cmxa}>: use_libextunix_stubs
5657 <src/*.ml{,i,y}>: pkg_bigarray
58 <src/*.ml{,i,y}>: pkg_bytes
5759 <src/*.ml{,i,y}>: pkg_unix
5860 "src/eventfd.c": pkg_bigarray
61 "src/eventfd.c": pkg_bytes
5962 "src/eventfd.c": pkg_unix
6063 "src/dirfd.c": pkg_bigarray
64 "src/dirfd.c": pkg_bytes
6165 "src/dirfd.c": pkg_unix
6266 "src/fsync.c": pkg_bigarray
67 "src/fsync.c": pkg_bytes
6368 "src/fsync.c": pkg_unix
6469 "src/statvfs.c": pkg_bigarray
70 "src/statvfs.c": pkg_bytes
6571 "src/statvfs.c": pkg_unix
6672 "src/atfile.c": pkg_bigarray
73 "src/atfile.c": pkg_bytes
6774 "src/atfile.c": pkg_unix
6875 "src/ioctl_siocgifconf.c": pkg_bigarray
76 "src/ioctl_siocgifconf.c": pkg_bytes
6977 "src/ioctl_siocgifconf.c": pkg_unix
7078 "src/uname.c": pkg_bigarray
79 "src/uname.c": pkg_bytes
7180 "src/uname.c": pkg_unix
7281 "src/fadvise.c": pkg_bigarray
82 "src/fadvise.c": pkg_bytes
7383 "src/fadvise.c": pkg_unix
7484 "src/fallocate.c": pkg_bigarray
85 "src/fallocate.c": pkg_bytes
7586 "src/fallocate.c": pkg_unix
7687 "src/tty_ioctl.c": pkg_bigarray
88 "src/tty_ioctl.c": pkg_bytes
7789 "src/tty_ioctl.c": pkg_unix
7890 "src/unistd.c": pkg_bigarray
91 "src/unistd.c": pkg_bytes
7992 "src/unistd.c": pkg_unix
8093 "src/stdlib.c": pkg_bigarray
94 "src/stdlib.c": pkg_bytes
8195 "src/stdlib.c": pkg_unix
8296 "src/signalfd.c": pkg_bigarray
97 "src/signalfd.c": pkg_bytes
8398 "src/signalfd.c": pkg_unix
8499 "src/ptrace.c": pkg_bigarray
100 "src/ptrace.c": pkg_bytes
85101 "src/ptrace.c": pkg_unix
86102 "src/resource.c": pkg_bigarray
103 "src/resource.c": pkg_bytes
87104 "src/resource.c": pkg_unix
88105 "src/mman.c": pkg_bigarray
106 "src/mman.c": pkg_bytes
89107 "src/mman.c": pkg_unix
90108 "src/time.c": pkg_bigarray
109 "src/time.c": pkg_bytes
91110 "src/time.c": pkg_unix
92111 "src/pts.c": pkg_bigarray
112 "src/pts.c": pkg_bytes
93113 "src/pts.c": pkg_unix
94114 "src/execinfo.c": pkg_bigarray
115 "src/execinfo.c": pkg_bytes
95116 "src/execinfo.c": pkg_unix
96117 "src/malloc.c": pkg_bigarray
118 "src/malloc.c": pkg_bytes
97119 "src/malloc.c": pkg_unix
98120 "src/endian.c": pkg_bigarray
121 "src/endian.c": pkg_bytes
99122 "src/endian.c": pkg_unix
100123 "src/read_cred.c": pkg_bigarray
124 "src/read_cred.c": pkg_bytes
101125 "src/read_cred.c": pkg_unix
102126 "src/fexecve.c": pkg_bigarray
127 "src/fexecve.c": pkg_bytes
103128 "src/fexecve.c": pkg_unix
104129 "src/sendmsg.c": pkg_bigarray
130 "src/sendmsg.c": pkg_bytes
105131 "src/sendmsg.c": pkg_unix
132 "src/mktemp.c": pkg_bigarray
133 "src/mktemp.c": pkg_bytes
134 "src/mktemp.c": pkg_unix
106135 "src/memalign.c": pkg_bigarray
136 "src/memalign.c": pkg_bytes
107137 "src/memalign.c": pkg_unix
108138 "src/endianba.c": pkg_bigarray
139 "src/endianba.c": pkg_bytes
109140 "src/endianba.c": pkg_unix
110141 "src/pread_pwrite_ba.c": pkg_bigarray
142 "src/pread_pwrite_ba.c": pkg_bytes
111143 "src/pread_pwrite_ba.c": pkg_unix
112144 "src/bigarray.c": pkg_bigarray
145 "src/bigarray.c": pkg_bytes
113146 "src/bigarray.c": pkg_unix
114147 "src/splice.c": pkg_bigarray
148 "src/splice.c": pkg_bytes
115149 "src/splice.c": pkg_unix
116150 "src/sysconf.c": pkg_bigarray
151 "src/sysconf.c": pkg_bytes
117152 "src/sysconf.c": pkg_unix
118153 "src/common.c": pkg_bigarray
154 "src/common.c": pkg_bytes
119155 "src/common.c": pkg_unix
120156 "src/sockopt.c": pkg_bigarray
157 "src/sockopt.c": pkg_bytes
121158 "src/sockopt.c": pkg_unix
122159 "src/poll.c": pkg_bigarray
160 "src/poll.c": pkg_bytes
123161 "src/poll.c": pkg_unix
124162 "src/sysinfo.c": pkg_bigarray
163 "src/sysinfo.c": pkg_bytes
125164 "src/sysinfo.c": pkg_unix
126165 "src/mount.c": pkg_bigarray
166 "src/mount.c": pkg_bytes
127167 "src/mount.c": pkg_unix
128168 "src/unshare.c": pkg_bigarray
169 "src/unshare.c": pkg_bytes
129170 "src/unshare.c": pkg_unix
130171 # Executable test
131172 <test/test.{native,byte}>: pkg_bigarray
173 <test/test.{native,byte}>: pkg_bytes
132174 <test/test.{native,byte}>: pkg_oUnit
133175 <test/test.{native,byte}>: pkg_unix
134176 <test/test.{native,byte}>: use_extunix
135177 <test/test.{native,byte}>: custom
136178 # Executable testba
137179 <test/testba.{native,byte}>: pkg_bigarray
180 <test/testba.{native,byte}>: pkg_bytes
138181 <test/testba.{native,byte}>: pkg_oUnit
139182 <test/testba.{native,byte}>: pkg_unix
140183 <test/testba.{native,byte}>: use_extunix
154197 <test/*.ml{,i,y}>: use_extunix
155198 <test/test_user_namespace.{native,byte}>: custom
156199 # OASIS_STOP
157 true: my_warnings
200 true: my_warnings, safe_string
158201 "test/test.ml": warn_d
159202 "src/pa_have.ml": pkg_camlp4.quotations.r, pkg_camlp4.extend, syntax_camlp4o
160203 <**/rootfs*>: -traverse
0 platform:
1 - x86
2
3 environment:
4 FORK_USER: ocaml
5 FORK_BRANCH: master
6 CYG_ROOT: C:\cygwin64
7
8 install:
9 - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/$env:FORK_USER/ocaml-ci-scripts/$env:FORK_BRANCH/appveyor-install.ps1"))
10
11 build_script:
12 - call %CYG_ROOT%\bin\bash.exe -l %APPVEYOR_BUILD_FOLDER%\appveyor-opam.sh
00 (* OASIS_START *)
1 (* DO NOT EDIT (digest: f0e05c6a2cb9b0a3d7737c452238402f) *)
1 (* DO NOT EDIT (digest: ef46e449a0bca58674187dad7f0b1323) *)
22 module OASISGettext = struct
33 (* # 22 "src/oasis/OASISGettext.ml" *)
44
55
6 let ns_ str =
7 str
8
9
10 let s_ str =
11 str
12
13
14 let f_ (str: ('a, 'b, 'c, 'd) format4) =
15 str
6 let ns_ str = str
7 let s_ str = str
8 let f_ (str: ('a, 'b, 'c, 'd) format4) = str
169
1710
1811 let fn_ fmt1 fmt2 n =
2215 fmt2^^""
2316
2417
25 let init =
26 []
18 let init = []
19 end
20
21 module OASISString = struct
22 (* # 22 "src/oasis/OASISString.ml" *)
23
24
25 (** Various string utilities.
26
27 Mostly inspired by extlib and batteries ExtString and BatString libraries.
28
29 @author Sylvain Le Gall
30 *)
31
32
33 let nsplitf str f =
34 if str = "" then
35 []
36 else
37 let buf = Buffer.create 13 in
38 let lst = ref [] in
39 let push () =
40 lst := Buffer.contents buf :: !lst;
41 Buffer.clear buf
42 in
43 let str_len = String.length str in
44 for i = 0 to str_len - 1 do
45 if f str.[i] then
46 push ()
47 else
48 Buffer.add_char buf str.[i]
49 done;
50 push ();
51 List.rev !lst
52
53
54 (** [nsplit c s] Split the string [s] at char [c]. It doesn't include the
55 separator.
56 *)
57 let nsplit str c =
58 nsplitf str ((=) c)
59
60
61 let find ~what ?(offset=0) str =
62 let what_idx = ref 0 in
63 let str_idx = ref offset in
64 while !str_idx < String.length str &&
65 !what_idx < String.length what do
66 if str.[!str_idx] = what.[!what_idx] then
67 incr what_idx
68 else
69 what_idx := 0;
70 incr str_idx
71 done;
72 if !what_idx <> String.length what then
73 raise Not_found
74 else
75 !str_idx - !what_idx
76
77
78 let sub_start str len =
79 let str_len = String.length str in
80 if len >= str_len then
81 ""
82 else
83 String.sub str len (str_len - len)
84
85
86 let sub_end ?(offset=0) str len =
87 let str_len = String.length str in
88 if len >= str_len then
89 ""
90 else
91 String.sub str 0 (str_len - len)
92
93
94 let starts_with ~what ?(offset=0) str =
95 let what_idx = ref 0 in
96 let str_idx = ref offset in
97 let ok = ref true in
98 while !ok &&
99 !str_idx < String.length str &&
100 !what_idx < String.length what do
101 if str.[!str_idx] = what.[!what_idx] then
102 incr what_idx
103 else
104 ok := false;
105 incr str_idx
106 done;
107 if !what_idx = String.length what then
108 true
109 else
110 false
111
112
113 let strip_starts_with ~what str =
114 if starts_with ~what str then
115 sub_start str (String.length what)
116 else
117 raise Not_found
118
119
120 let ends_with ~what ?(offset=0) str =
121 let what_idx = ref ((String.length what) - 1) in
122 let str_idx = ref ((String.length str) - 1) in
123 let ok = ref true in
124 while !ok &&
125 offset <= !str_idx &&
126 0 <= !what_idx do
127 if str.[!str_idx] = what.[!what_idx] then
128 decr what_idx
129 else
130 ok := false;
131 decr str_idx
132 done;
133 if !what_idx = -1 then
134 true
135 else
136 false
137
138
139 let strip_ends_with ~what str =
140 if ends_with ~what str then
141 sub_end str (String.length what)
142 else
143 raise Not_found
144
145
146 let replace_chars f s =
147 let buf = Buffer.create (String.length s) in
148 String.iter (fun c -> Buffer.add_char buf (f c)) s;
149 Buffer.contents buf
150
151 let lowercase_ascii =
152 replace_chars
153 (fun c ->
154 if (c >= 'A' && c <= 'Z') then
155 Char.chr (Char.code c + 32)
156 else
157 c)
158
159 let uncapitalize_ascii s =
160 if s <> "" then
161 (lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
162 else
163 s
164
165 let uppercase_ascii =
166 replace_chars
167 (fun c ->
168 if (c >= 'a' && c <= 'z') then
169 Char.chr (Char.code c - 32)
170 else
171 c)
172
173 let capitalize_ascii s =
174 if s <> "" then
175 (uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
176 else
177 s
178
179 end
180
181 module OASISUtils = struct
182 (* # 22 "src/oasis/OASISUtils.ml" *)
183
184
185 open OASISGettext
186
187
188 module MapExt =
189 struct
190 module type S =
191 sig
192 include Map.S
193 val add_list: 'a t -> (key * 'a) list -> 'a t
194 val of_list: (key * 'a) list -> 'a t
195 val to_list: 'a t -> (key * 'a) list
196 end
197
198 module Make (Ord: Map.OrderedType) =
199 struct
200 include Map.Make(Ord)
201
202 let rec add_list t =
203 function
204 | (k, v) :: tl -> add_list (add k v t) tl
205 | [] -> t
206
207 let of_list lst = add_list empty lst
208
209 let to_list t = fold (fun k v acc -> (k, v) :: acc) t []
210 end
211 end
212
213
214 module MapString = MapExt.Make(String)
215
216
217 module SetExt =
218 struct
219 module type S =
220 sig
221 include Set.S
222 val add_list: t -> elt list -> t
223 val of_list: elt list -> t
224 val to_list: t -> elt list
225 end
226
227 module Make (Ord: Set.OrderedType) =
228 struct
229 include Set.Make(Ord)
230
231 let rec add_list t =
232 function
233 | e :: tl -> add_list (add e t) tl
234 | [] -> t
235
236 let of_list lst = add_list empty lst
237
238 let to_list = elements
239 end
240 end
241
242
243 module SetString = SetExt.Make(String)
244
245
246 let compare_csl s1 s2 =
247 String.compare (OASISString.lowercase_ascii s1) (OASISString.lowercase_ascii s2)
248
249
250 module HashStringCsl =
251 Hashtbl.Make
252 (struct
253 type t = string
254 let equal s1 s2 = (compare_csl s1 s2) = 0
255 let hash s = Hashtbl.hash (OASISString.lowercase_ascii s)
256 end)
257
258 module SetStringCsl =
259 SetExt.Make
260 (struct
261 type t = string
262 let compare = compare_csl
263 end)
264
265
266 let varname_of_string ?(hyphen='_') s =
267 if String.length s = 0 then
268 begin
269 invalid_arg "varname_of_string"
270 end
271 else
272 begin
273 let buf =
274 OASISString.replace_chars
275 (fun c ->
276 if ('a' <= c && c <= 'z')
277 ||
278 ('A' <= c && c <= 'Z')
279 ||
280 ('0' <= c && c <= '9') then
281 c
282 else
283 hyphen)
284 s;
285 in
286 let buf =
287 (* Start with a _ if digit *)
288 if '0' <= s.[0] && s.[0] <= '9' then
289 "_"^buf
290 else
291 buf
292 in
293 OASISString.lowercase_ascii buf
294 end
295
296
297 let varname_concat ?(hyphen='_') p s =
298 let what = String.make 1 hyphen in
299 let p =
300 try
301 OASISString.strip_ends_with ~what p
302 with Not_found ->
303 p
304 in
305 let s =
306 try
307 OASISString.strip_starts_with ~what s
308 with Not_found ->
309 s
310 in
311 p^what^s
312
313
314 let is_varname str =
315 str = varname_of_string str
316
317
318 let failwithf fmt = Printf.ksprintf failwith fmt
319
320
321 let rec file_location ?pos1 ?pos2 ?lexbuf () =
322 match pos1, pos2, lexbuf with
323 | Some p, None, _ | None, Some p, _ ->
324 file_location ~pos1:p ~pos2:p ?lexbuf ()
325 | Some p1, Some p2, _ ->
326 let open Lexing in
327 let fn, lineno = p1.pos_fname, p1.pos_lnum in
328 let c1 = p1.pos_cnum - p1.pos_bol in
329 let c2 = c1 + (p2.pos_cnum - p1.pos_cnum) in
330 Printf.sprintf (f_ "file %S, line %d, characters %d-%d") fn lineno c1 c2
331 | _, _, Some lexbuf ->
332 file_location
333 ~pos1:(Lexing.lexeme_start_p lexbuf)
334 ~pos2:(Lexing.lexeme_end_p lexbuf)
335 ()
336 | None, None, None ->
337 s_ "<position undefined>"
338
339
340 let failwithpf ?pos1 ?pos2 ?lexbuf fmt =
341 let loc = file_location ?pos1 ?pos2 ?lexbuf () in
342 Printf.ksprintf (fun s -> failwith (Printf.sprintf "%s: %s" loc s)) fmt
27343
28344
29345 end
32348 (* # 22 "src/oasis/OASISExpr.ml" *)
33349
34350
35
36
37
38351 open OASISGettext
352 open OASISUtils
39353
40354
41355 type test = string
42
43
44356 type flag = string
45357
46358
51363 | EOr of t * t
52364 | EFlag of flag
53365 | ETest of test * string
54
55366
56367
57368 type 'a choices = (t * 'a) list
128439 end
129440
130441
131 # 132 "myocamlbuild.ml"
442 # 443 "myocamlbuild.ml"
132443 module BaseEnvLight = struct
133444 (* # 22 "src/base/BaseEnvLight.ml" *)
134445
139450 type t = string MapString.t
140451
141452
142 let default_filename =
143 Filename.concat
144 (Sys.getcwd ())
145 "setup.data"
146
147
148 let load ?(allow_empty=false) ?(filename=default_filename) () =
149 if Sys.file_exists filename then
150 begin
151 let chn =
152 open_in_bin filename
153 in
154 let st =
155 Stream.of_channel chn
156 in
157 let line =
158 ref 1
159 in
160 let st_line =
161 Stream.from
162 (fun _ ->
163 try
164 match Stream.next st with
165 | '\n' -> incr line; Some '\n'
166 | c -> Some c
167 with Stream.Failure -> None)
168 in
169 let lexer =
170 Genlex.make_lexer ["="] st_line
171 in
172 let rec read_file mp =
173 match Stream.npeek 3 lexer with
174 | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
175 Stream.junk lexer;
176 Stream.junk lexer;
177 Stream.junk lexer;
178 read_file (MapString.add nm value mp)
179 | [] ->
180 mp
181 | _ ->
182 failwith
183 (Printf.sprintf
184 "Malformed data file '%s' line %d"
185 filename !line)
186 in
187 let mp =
188 read_file MapString.empty
189 in
190 close_in chn;
191 mp
192 end
193 else if allow_empty then
194 begin
453 let default_filename = Filename.concat (Sys.getcwd ()) "setup.data"
454
455
456 let load ?(allow_empty=false) ?(filename=default_filename) ?stream () =
457 let line = ref 1 in
458 let lexer st =
459 let st_line =
460 Stream.from
461 (fun _ ->
462 try
463 match Stream.next st with
464 | '\n' -> incr line; Some '\n'
465 | c -> Some c
466 with Stream.Failure -> None)
467 in
468 Genlex.make_lexer ["="] st_line
469 in
470 let rec read_file lxr mp =
471 match Stream.npeek 3 lxr with
472 | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
473 Stream.junk lxr; Stream.junk lxr; Stream.junk lxr;
474 read_file lxr (MapString.add nm value mp)
475 | [] -> mp
476 | _ ->
477 failwith
478 (Printf.sprintf "Malformed data file '%s' line %d" filename !line)
479 in
480 match stream with
481 | Some st -> read_file (lexer st) MapString.empty
482 | None ->
483 if Sys.file_exists filename then begin
484 let chn = open_in_bin filename in
485 let st = Stream.of_channel chn in
486 try
487 let mp = read_file (lexer st) MapString.empty in
488 close_in chn; mp
489 with e ->
490 close_in chn; raise e
491 end else if allow_empty then begin
195492 MapString.empty
196 end
197 else
198 begin
493 end else begin
199494 failwith
200495 (Printf.sprintf
201496 "Unable to load environment, the file '%s' doesn't exist."
202497 filename)
203498 end
204499
205
206500 let rec var_expand str env =
207 let buff =
208 Buffer.create ((String.length str) * 2)
209 in
210 Buffer.add_substitute
211 buff
212 (fun var ->
213 try
214 var_expand (MapString.find var env) env
215 with Not_found ->
216 failwith
217 (Printf.sprintf
218 "No variable %s defined when trying to expand %S."
219 var
220 str))
221 str;
222 Buffer.contents buff
223
224
225 let var_get name env =
226 var_expand (MapString.find name env) env
227
228
229 let var_choose lst env =
230 OASISExpr.choose
231 (fun nm -> var_get nm env)
232 lst
501 let buff = Buffer.create ((String.length str) * 2) in
502 Buffer.add_substitute
503 buff
504 (fun var ->
505 try
506 var_expand (MapString.find var env) env
507 with Not_found ->
508 failwith
509 (Printf.sprintf
510 "No variable %s defined when trying to expand %S."
511 var
512 str))
513 str;
514 Buffer.contents buff
515
516
517 let var_get name env = var_expand (MapString.find name env) env
518 let var_choose lst env = OASISExpr.choose (fun nm -> var_get nm env) lst
233519 end
234520
235521
236 # 237 "myocamlbuild.ml"
522 # 523 "myocamlbuild.ml"
237523 module MyOCamlbuildFindlib = struct
238524 (* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
239525
240526
241527 (** OCamlbuild extension, copied from
242 * http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild
528 * https://ocaml.org/learn/tutorials/ocamlbuild/Using_ocamlfind_with_ocamlbuild.html
243529 * by N. Pouillard and others
244530 *
245 * Updated on 2009/02/28
531 * Updated on 2016-06-02
246532 *
247533 * Modified by Sylvain Le Gall
248 *)
534 *)
249535 open Ocamlbuild_plugin
250536
251 type conf =
252 { no_automatic_syntax: bool;
253 }
254
255 (* these functions are not really officially exported *)
256 let run_and_read =
257 Ocamlbuild_pack.My_unix.run_and_read
258
259
260 let blank_sep_strings =
261 Ocamlbuild_pack.Lexers.blank_sep_strings
537
538 type conf = {no_automatic_syntax: bool}
539
540
541 let run_and_read = Ocamlbuild_pack.My_unix.run_and_read
542
543
544 let blank_sep_strings = Ocamlbuild_pack.Lexers.blank_sep_strings
262545
263546
264547 let exec_from_conf exec =
265548 let exec =
266 let env_filename = Pathname.basename BaseEnvLight.default_filename in
267 let env = BaseEnvLight.load ~filename:env_filename ~allow_empty:true () in
549 let env = BaseEnvLight.load ~allow_empty:true () in
268550 try
269551 BaseEnvLight.var_get exec env
270552 with Not_found ->
275557 if Sys.os_type = "Win32" then begin
276558 let buff = Buffer.create (String.length str) in
277559 (* Adapt for windowsi, ocamlbuild + win32 has a hard time to handle '\\'.
278 *)
560 *)
279561 String.iter
280562 (fun c -> Buffer.add_char buff (if c = '\\' then '/' else c))
281563 str;
284566 str
285567 end
286568 in
287 fix_win32 exec
569 fix_win32 exec
570
288571
289572 let split s ch =
290573 let buf = Buffer.create 13 in
293576 x := (Buffer.contents buf) :: !x;
294577 Buffer.clear buf
295578 in
296 String.iter
297 (fun c ->
298 if c = ch then
299 flush ()
300 else
301 Buffer.add_char buf c)
302 s;
303 flush ();
304 List.rev !x
579 String.iter
580 (fun c ->
581 if c = ch then
582 flush ()
583 else
584 Buffer.add_char buf c)
585 s;
586 flush ();
587 List.rev !x
305588
306589
307590 let split_nl s = split s '\n'
343626 let dispatch conf =
344627 function
345628 | After_options ->
346 (* By using Before_options one let command line options have an higher
347 * priority on the contrary using After_options will guarantee to have
348 * the higher priority override default commands by ocamlfind ones *)
349 Options.ocamlc := ocamlfind & A"ocamlc";
350 Options.ocamlopt := ocamlfind & A"ocamlopt";
351 Options.ocamldep := ocamlfind & A"ocamldep";
352 Options.ocamldoc := ocamlfind & A"ocamldoc";
353 Options.ocamlmktop := ocamlfind & A"ocamlmktop";
354 Options.ocamlmklib := ocamlfind & A"ocamlmklib"
629 (* By using Before_options one let command line options have an higher
630 * priority on the contrary using After_options will guarantee to have
631 * the higher priority override default commands by ocamlfind ones *)
632 Options.ocamlc := ocamlfind & A"ocamlc";
633 Options.ocamlopt := ocamlfind & A"ocamlopt";
634 Options.ocamldep := ocamlfind & A"ocamldep";
635 Options.ocamldoc := ocamlfind & A"ocamldoc";
636 Options.ocamlmktop := ocamlfind & A"ocamlmktop";
637 Options.ocamlmklib := ocamlfind & A"ocamlmklib"
355638
356639 | After_rules ->
357640
358 (* When one link an OCaml library/binary/package, one should use
359 * -linkpkg *)
360 flag ["ocaml"; "link"; "program"] & A"-linkpkg";
361
362 if not (conf.no_automatic_syntax) then begin
363 (* For each ocamlfind package one inject the -package option when
364 * compiling, computing dependencies, generating documentation and
365 * linking. *)
366 List.iter
367 begin fun pkg ->
368 let base_args = [A"-package"; A pkg] in
369 (* TODO: consider how to really choose camlp4o or camlp4r. *)
370 let syn_args = [A"-syntax"; A "camlp4o"] in
371 let (args, pargs) =
372 (* Heuristic to identify syntax extensions: whether they end in
373 ".syntax"; some might not.
374 *)
375 if Filename.check_suffix pkg "syntax" ||
376 List.mem pkg well_known_syntax then
377 (syn_args @ base_args, syn_args)
378 else
379 (base_args, [])
380 in
381 flag ["ocaml"; "compile"; "pkg_"^pkg] & S args;
382 flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S args;
383 flag ["ocaml"; "doc"; "pkg_"^pkg] & S args;
384 flag ["ocaml"; "link"; "pkg_"^pkg] & S base_args;
385 flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S args;
386
387 (* TODO: Check if this is allowed for OCaml < 3.12.1 *)
388 flag ["ocaml"; "compile"; "package("^pkg^")"] & S pargs;
389 flag ["ocaml"; "ocamldep"; "package("^pkg^")"] & S pargs;
390 flag ["ocaml"; "doc"; "package("^pkg^")"] & S pargs;
391 flag ["ocaml"; "infer_interface"; "package("^pkg^")"] & S pargs;
392 end
393 (find_packages ());
394 end;
395
396 (* Like -package but for extensions syntax. Morover -syntax is useless
397 * when linking. *)
398 List.iter begin fun syntax ->
641 (* Avoid warnings for unused tag *)
642 flag ["tests"] N;
643
644 (* When one link an OCaml library/binary/package, one should use
645 * -linkpkg *)
646 flag ["ocaml"; "link"; "program"] & A"-linkpkg";
647
648 (* For each ocamlfind package one inject the -package option when
649 * compiling, computing dependencies, generating documentation and
650 * linking. *)
651 List.iter
652 begin fun pkg ->
653 let base_args = [A"-package"; A pkg] in
654 (* TODO: consider how to really choose camlp4o or camlp4r. *)
655 let syn_args = [A"-syntax"; A "camlp4o"] in
656 let (args, pargs) =
657 (* Heuristic to identify syntax extensions: whether they end in
658 ".syntax"; some might not.
659 *)
660 if not (conf.no_automatic_syntax) &&
661 (Filename.check_suffix pkg "syntax" ||
662 List.mem pkg well_known_syntax) then
663 (syn_args @ base_args, syn_args)
664 else
665 (base_args, [])
666 in
667 flag ["ocaml"; "compile"; "pkg_"^pkg] & S args;
668 flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S args;
669 flag ["ocaml"; "doc"; "pkg_"^pkg] & S args;
670 flag ["ocaml"; "link"; "pkg_"^pkg] & S base_args;
671 flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S args;
672
673 (* TODO: Check if this is allowed for OCaml < 3.12.1 *)
674 flag ["ocaml"; "compile"; "package("^pkg^")"] & S pargs;
675 flag ["ocaml"; "ocamldep"; "package("^pkg^")"] & S pargs;
676 flag ["ocaml"; "doc"; "package("^pkg^")"] & S pargs;
677 flag ["ocaml"; "infer_interface"; "package("^pkg^")"] & S pargs;
678 end
679 (find_packages ());
680
681 (* Like -package but for extensions syntax. Morover -syntax is useless
682 * when linking. *)
683 List.iter begin fun syntax ->
399684 flag ["ocaml"; "compile"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
400685 flag ["ocaml"; "ocamldep"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
401686 flag ["ocaml"; "doc"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
402687 flag ["ocaml"; "infer_interface"; "syntax_"^syntax] &
403 S[A"-syntax"; A syntax];
404 end (find_syntaxes ());
405
406 (* The default "thread" tag is not compatible with ocamlfind.
407 * Indeed, the default rules add the "threads.cma" or "threads.cmxa"
408 * options when using this tag. When using the "-linkpkg" option with
409 * ocamlfind, this module will then be added twice on the command line.
410 *
411 * To solve this, one approach is to add the "-thread" option when using
412 * the "threads" package using the previous plugin.
413 *)
414 flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]);
415 flag ["ocaml"; "pkg_threads"; "doc"] (S[A "-I"; A "+threads"]);
416 flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
417 flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"]);
418 flag ["ocaml"; "package(threads)"; "compile"] (S[A "-thread"]);
419 flag ["ocaml"; "package(threads)"; "doc"] (S[A "-I"; A "+threads"]);
420 flag ["ocaml"; "package(threads)"; "link"] (S[A "-thread"]);
421 flag ["ocaml"; "package(threads)"; "infer_interface"] (S[A "-thread"]);
688 S[A"-syntax"; A syntax];
689 end (find_syntaxes ());
690
691 (* The default "thread" tag is not compatible with ocamlfind.
692 * Indeed, the default rules add the "threads.cma" or "threads.cmxa"
693 * options when using this tag. When using the "-linkpkg" option with
694 * ocamlfind, this module will then be added twice on the command line.
695 *
696 * To solve this, one approach is to add the "-thread" option when using
697 * the "threads" package using the previous plugin.
698 *)
699 flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]);
700 flag ["ocaml"; "pkg_threads"; "doc"] (S[A "-I"; A "+threads"]);
701 flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
702 flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"]);
703 flag ["c"; "pkg_threads"; "compile"] (S[A "-thread"]);
704 flag ["ocaml"; "package(threads)"; "compile"] (S[A "-thread"]);
705 flag ["ocaml"; "package(threads)"; "doc"] (S[A "-I"; A "+threads"]);
706 flag ["ocaml"; "package(threads)"; "link"] (S[A "-thread"]);
707 flag ["ocaml"; "package(threads)"; "infer_interface"] (S[A "-thread"]);
708 flag ["c"; "package(threads)"; "compile"] (S[A "-thread"]);
422709
423710 | _ ->
424 ()
711 ()
425712 end
426713
427714 module MyOCamlbuildBase = struct
431718 (** Base functions for writing myocamlbuild.ml
432719 @author Sylvain Le Gall
433720 *)
434
435
436
437721
438722
439723 open Ocamlbuild_plugin
444728 type file = string
445729 type name = string
446730 type tag = string
447
448
449 (* # 62 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
450731
451732
452733 type t =
461742 }
462743
463744
464 let env_filename =
465 Pathname.basename
466 BaseEnvLight.default_filename
745 (* # 110 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
746
747
748 let env_filename = Pathname.basename BaseEnvLight.default_filename
467749
468750
469751 let dispatch_combine lst =
482764
483765
484766 let dispatch t e =
485 let env =
486 BaseEnvLight.load
487 ~filename:env_filename
488 ~allow_empty:true
489 ()
490 in
767 let env = BaseEnvLight.load ~allow_empty:true () in
491768 match e with
492769 | Before_options ->
493770 let no_trailing_dot s =
515792 | nm, [], intf_modules ->
516793 ocaml_lib nm;
517794 let cmis =
518 List.map (fun m -> (String.uncapitalize m) ^ ".cmi")
795 List.map (fun m -> (OASISString.uncapitalize_ascii m) ^ ".cmi")
519796 intf_modules in
520797 dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis
521798 | nm, dir :: tl, intf_modules ->
528805 ["compile"; "infer_interface"; "doc"])
529806 tl;
530807 let cmis =
531 List.map (fun m -> dir^"/"^(String.uncapitalize m)^".cmi")
808 List.map (fun m -> dir^"/"^(OASISString.uncapitalize_ascii m)^".cmi")
532809 intf_modules in
533810 dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"]
534811 cmis)
551828 flag ["link"; "library"; "ocaml"; "native"; tag_libstubs lib]
552829 (S[A"-cclib"; A("-l"^(nm_libstubs lib))]);
553830
554 flag ["link"; "program"; "ocaml"; "byte"; tag_libstubs lib]
555 (S[A"-dllib"; A("dll"^(nm_libstubs lib))]);
831 if bool_of_string (BaseEnvLight.var_get "native_dynlink" env) then
832 flag ["link"; "program"; "ocaml"; "byte"; tag_libstubs lib]
833 (S[A"-dllib"; A("dll"^(nm_libstubs lib))]);
556834
557835 (* When ocaml link something that use the C library, then one
558836 need that file to be up to date.
559837 This holds both for programs and for libraries.
560838 *)
561 dep ["link"; "ocaml"; tag_libstubs lib]
562 [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
563
564 dep ["compile"; "ocaml"; tag_libstubs lib]
565 [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
839 dep ["link"; "ocaml"; tag_libstubs lib]
840 [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
841
842 dep ["compile"; "ocaml"; tag_libstubs lib]
843 [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
566844
567845 (* TODO: be more specific about what depends on headers *)
568846 (* Depends on .h files *)
602880 end
603881
604882
605 # 606 "myocamlbuild.ml"
883 # 884 "myocamlbuild.ml"
606884 open Ocamlbuild_plugin;;
607885 let package_default =
608886 {
619897 S
620898 [
621899 A "-ccopt";
622 A "-std=c89";
623 A "-ccopt";
624900 A "-pedantic";
625901 A "-ccopt";
626902 A "-Wno-long-long";
637913
638914 let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
639915
640 # 642 "myocamlbuild.ml"
916 # 918 "myocamlbuild.ml"
641917 (* OASIS_STOP *)
642918
643919 let gen gen_all prod =
657933 gen true "src/extUnixAll.ml";;
658934 gen false "src/extUnixSpecific.ml";;
659935
660 flag ["compile"; "ocaml"; "my_warnings"] (S[A "-w"; A"+A-e-3-44-48"]);;
936 flag ["compile"; "ocaml"; "my_warnings"] (S[A "-w"; A"+A-e-3-44-48-50"]);;
661937
662938 Ocamlbuild_plugin.dispatch dispatch_default;;
0 opam-version: "1.2"
1 maintainer: "ygrek@autistici.org"
2 homepage: "http://extunix.forge.ocamlcore.org/"
3 dev-repo: "git://github.com/ygrek/extunix.git"
4 bug-reports: "https://github.com/ygrek/extunix/issues"
5 doc: "http://extunix.forge.ocamlcore.org/api/index.html"
6 license: "LGPL-2.1 with OCaml linking exception"
7 authors: [ "ygrek"
8 "Sylvain Le Gall"
9 "Stéphane Glondu"
10 "Kaustuv Chaudhuri"
11 "Joshua Smith"
12 "Niki Yoshiuchi"
13 "Gerd Stolpmann"
14 "Goswin von Brederlow"
15 "Andre Nathan"
16 "Zhenya Lykhovyd"
17 "Mehdi Dogguy"
18 "Roman Vorobets"
19 "Pierre Chambart"
20 "Dmitry Grebeniuk"
21 "François Bobot" ]
22 build: [
23 ["ocaml" "setup.ml" "-configure" "--%{ounit:enable}%-tests" "--prefix" prefix] {ocaml-version >= "4.02.0"}
24 ["ocaml" "setup.ml" "-configure" "--prefix" prefix] {ocaml-version < "4.02.0"}
25 ["ocaml" "setup.ml" "-build"]
26 ]
27 install: [
28 ["ocaml" "setup.ml" "-install"]
29 ]
30 build-doc: [
31 ["ocaml" "setup.ml" "-doc"]
32 ]
33 build-test: [
34 ["ocaml" "setup.ml" "-test"]
35 ]
36 remove: [
37 ["ocamlfind" "remove" "extunix"]
38 ]
39 depends: [
40 "ocamlfind" {build}
41 "camlp4" {build}
42 "ounit" {test & >= "1.0.3"}
43 "base-bigarray"
44 "base-unix"
45 "ocamlbuild" {build}
46 ]
+3946
-3321
setup.ml less more
00 (* setup.ml generated for the first time by OASIS v0.2.0~alpha1 *)
11
22 (* OASIS_START *)
3 (* DO NOT EDIT (digest: fb964b88aabc914f4cd05f402ca6329c) *)
3 (* DO NOT EDIT (digest: d236ca499e7ecbb7e73f451438eb26c4) *)
44 (*
5 Regenerated by OASIS v0.4.5
5 Regenerated by OASIS v0.4.8
66 Visit http://oasis.forge.ocamlcore.org for more information and
77 documentation about functions used in this file.
88 *)
1010 (* # 22 "src/oasis/OASISGettext.ml" *)
1111
1212
13 let ns_ str =
14 str
15
16
17 let s_ str =
18 str
19
20
21 let f_ (str: ('a, 'b, 'c, 'd) format4) =
22 str
13 let ns_ str = str
14 let s_ str = str
15 let f_ (str: ('a, 'b, 'c, 'd) format4) = str
2316
2417
2518 let fn_ fmt1 fmt2 n =
2922 fmt2^^""
3023
3124
32 let init =
33 []
34
35
36 end
37
38 module OASISContext = struct
39 (* # 22 "src/oasis/OASISContext.ml" *)
40
41
42 open OASISGettext
43
44
45 type level =
46 [ `Debug
47 | `Info
48 | `Warning
49 | `Error]
50
51
52 type t =
53 {
54 (* TODO: replace this by a proplist. *)
55 quiet: bool;
56 info: bool;
57 debug: bool;
58 ignore_plugins: bool;
59 ignore_unknown_fields: bool;
60 printf: level -> string -> unit;
61 }
62
63
64 let printf lvl str =
65 let beg =
66 match lvl with
67 | `Error -> s_ "E: "
68 | `Warning -> s_ "W: "
69 | `Info -> s_ "I: "
70 | `Debug -> s_ "D: "
71 in
72 prerr_endline (beg^str)
73
74
75 let default =
76 ref
77 {
78 quiet = false;
79 info = false;
80 debug = false;
81 ignore_plugins = false;
82 ignore_unknown_fields = false;
83 printf = printf;
84 }
85
86
87 let quiet =
88 {!default with quiet = true}
89
90
91 let fspecs () =
92 (* TODO: don't act on default. *)
93 let ignore_plugins = ref false in
94 ["-quiet",
95 Arg.Unit (fun () -> default := {!default with quiet = true}),
96 s_ " Run quietly";
97
98 "-info",
99 Arg.Unit (fun () -> default := {!default with info = true}),
100 s_ " Display information message";
101
102
103 "-debug",
104 Arg.Unit (fun () -> default := {!default with debug = true}),
105 s_ " Output debug message";
106
107 "-ignore-plugins",
108 Arg.Set ignore_plugins,
109 s_ " Ignore plugin's field.";
110
111 "-C",
112 (* TODO: remove this chdir. *)
113 Arg.String (fun str -> Sys.chdir str),
114 s_ "dir Change directory before running."],
115 fun () -> {!default with ignore_plugins = !ignore_plugins}
25 let init = []
11626 end
11727
11828 module OASISString = struct
12434 Mostly inspired by extlib and batteries ExtString and BatString libraries.
12535
12636 @author Sylvain Le Gall
127 *)
37 *)
12838
12939
13040 let nsplitf str f =
13848 Buffer.clear buf
13949 in
14050 let str_len = String.length str in
141 for i = 0 to str_len - 1 do
142 if f str.[i] then
143 push ()
144 else
145 Buffer.add_char buf str.[i]
146 done;
147 push ();
148 List.rev !lst
51 for i = 0 to str_len - 1 do
52 if f str.[i] then
53 push ()
54 else
55 Buffer.add_char buf str.[i]
56 done;
57 push ();
58 List.rev !lst
14959
15060
15161 (** [nsplit c s] Split the string [s] at char [c]. It doesn't include the
15262 separator.
153 *)
63 *)
15464 let nsplit str c =
15565 nsplitf str ((=) c)
15666
15868 let find ~what ?(offset=0) str =
15969 let what_idx = ref 0 in
16070 let str_idx = ref offset in
161 while !str_idx < String.length str &&
162 !what_idx < String.length what do
163 if str.[!str_idx] = what.[!what_idx] then
164 incr what_idx
165 else
166 what_idx := 0;
167 incr str_idx
168 done;
169 if !what_idx <> String.length what then
170 raise Not_found
71 while !str_idx < String.length str &&
72 !what_idx < String.length what do
73 if str.[!str_idx] = what.[!what_idx] then
74 incr what_idx
17175 else
172 !str_idx - !what_idx
76 what_idx := 0;
77 incr str_idx
78 done;
79 if !what_idx <> String.length what then
80 raise Not_found
81 else
82 !str_idx - !what_idx
17383
17484
17585 let sub_start str len =
192102 let what_idx = ref 0 in
193103 let str_idx = ref offset in
194104 let ok = ref true in
195 while !ok &&
196 !str_idx < String.length str &&
197 !what_idx < String.length what do
198 if str.[!str_idx] = what.[!what_idx] then
199 incr what_idx
200 else
201 ok := false;
202 incr str_idx
203 done;
204 if !what_idx = String.length what then
205 true
105 while !ok &&
106 !str_idx < String.length str &&
107 !what_idx < String.length what do
108 if str.[!str_idx] = what.[!what_idx] then
109 incr what_idx
206110 else
207 false
111 ok := false;
112 incr str_idx
113 done;
114 if !what_idx = String.length what then
115 true
116 else
117 false
208118
209119
210120 let strip_starts_with ~what str =
218128 let what_idx = ref ((String.length what) - 1) in
219129 let str_idx = ref ((String.length str) - 1) in
220130 let ok = ref true in
221 while !ok &&
222 offset <= !str_idx &&
223 0 <= !what_idx do
224 if str.[!str_idx] = what.[!what_idx] then
225 decr what_idx
226 else
227 ok := false;
228 decr str_idx
229 done;
230 if !what_idx = -1 then
231 true
131 while !ok &&
132 offset <= !str_idx &&
133 0 <= !what_idx do
134 if str.[!str_idx] = what.[!what_idx] then
135 decr what_idx
232136 else
233 false
137 ok := false;
138 decr str_idx
139 done;
140 if !what_idx = -1 then
141 true
142 else
143 false
234144
235145
236146 let strip_ends_with ~what str =
245155 String.iter (fun c -> Buffer.add_char buf (f c)) s;
246156 Buffer.contents buf
247157
158 let lowercase_ascii =
159 replace_chars
160 (fun c ->
161 if (c >= 'A' && c <= 'Z') then
162 Char.chr (Char.code c + 32)
163 else
164 c)
165
166 let uncapitalize_ascii s =
167 if s <> "" then
168 (lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
169 else
170 s
171
172 let uppercase_ascii =
173 replace_chars
174 (fun c ->
175 if (c >= 'a' && c <= 'z') then
176 Char.chr (Char.code c - 32)
177 else
178 c)
179
180 let capitalize_ascii s =
181 if s <> "" then
182 (uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
183 else
184 s
248185
249186 end
250187
314251
315252
316253 let compare_csl s1 s2 =
317 String.compare (String.lowercase s1) (String.lowercase s2)
254 String.compare (OASISString.lowercase_ascii s1) (OASISString.lowercase_ascii s2)
318255
319256
320257 module HashStringCsl =
321258 Hashtbl.Make
322259 (struct
323260 type t = string
324
325 let equal s1 s2 =
326 (String.lowercase s1) = (String.lowercase s2)
327
328 let hash s =
329 Hashtbl.hash (String.lowercase s)
261 let equal s1 s2 = (compare_csl s1 s2) = 0
262 let hash s = Hashtbl.hash (OASISString.lowercase_ascii s)
330263 end)
331264
332265 module SetStringCsl =
364297 else
365298 buf
366299 in
367 String.lowercase buf
300 OASISString.lowercase_ascii buf
368301 end
369302
370303
392325 let failwithf fmt = Printf.ksprintf failwith fmt
393326
394327
328 let rec file_location ?pos1 ?pos2 ?lexbuf () =
329 match pos1, pos2, lexbuf with
330 | Some p, None, _ | None, Some p, _ ->
331 file_location ~pos1:p ~pos2:p ?lexbuf ()
332 | Some p1, Some p2, _ ->
333 let open Lexing in
334 let fn, lineno = p1.pos_fname, p1.pos_lnum in
335 let c1 = p1.pos_cnum - p1.pos_bol in
336 let c2 = c1 + (p2.pos_cnum - p1.pos_cnum) in
337 Printf.sprintf (f_ "file %S, line %d, characters %d-%d") fn lineno c1 c2
338 | _, _, Some lexbuf ->
339 file_location
340 ~pos1:(Lexing.lexeme_start_p lexbuf)
341 ~pos2:(Lexing.lexeme_end_p lexbuf)
342 ()
343 | None, None, None ->
344 s_ "<position undefined>"
345
346
347 let failwithpf ?pos1 ?pos2 ?lexbuf fmt =
348 let loc = file_location ?pos1 ?pos2 ?lexbuf () in
349 Printf.ksprintf (fun s -> failwith (Printf.sprintf "%s: %s" loc s)) fmt
350
351
352 end
353
354 module OASISUnixPath = struct
355 (* # 22 "src/oasis/OASISUnixPath.ml" *)
356
357
358 type unix_filename = string
359 type unix_dirname = string
360
361
362 type host_filename = string
363 type host_dirname = string
364
365
366 let current_dir_name = "."
367
368
369 let parent_dir_name = ".."
370
371
372 let is_current_dir fn =
373 fn = current_dir_name || fn = ""
374
375
376 let concat f1 f2 =
377 if is_current_dir f1 then
378 f2
379 else
380 let f1' =
381 try OASISString.strip_ends_with ~what:"/" f1 with Not_found -> f1
382 in
383 f1'^"/"^f2
384
385
386 let make =
387 function
388 | hd :: tl ->
389 List.fold_left
390 (fun f p -> concat f p)
391 hd
392 tl
393 | [] ->
394 invalid_arg "OASISUnixPath.make"
395
396
397 let dirname f =
398 try
399 String.sub f 0 (String.rindex f '/')
400 with Not_found ->
401 current_dir_name
402
403
404 let basename f =
405 try
406 let pos_start =
407 (String.rindex f '/') + 1
408 in
409 String.sub f pos_start ((String.length f) - pos_start)
410 with Not_found ->
411 f
412
413
414 let chop_extension f =
415 try
416 let last_dot =
417 String.rindex f '.'
418 in
419 let sub =
420 String.sub f 0 last_dot
421 in
422 try
423 let last_slash =
424 String.rindex f '/'
425 in
426 if last_slash < last_dot then
427 sub
428 else
429 f
430 with Not_found ->
431 sub
432
433 with Not_found ->
434 f
435
436
437 let capitalize_file f =
438 let dir = dirname f in
439 let base = basename f in
440 concat dir (OASISString.capitalize_ascii base)
441
442
443 let uncapitalize_file f =
444 let dir = dirname f in
445 let base = basename f in
446 concat dir (OASISString.uncapitalize_ascii base)
447
448
449 end
450
451 module OASISHostPath = struct
452 (* # 22 "src/oasis/OASISHostPath.ml" *)
453
454
455 open Filename
456 open OASISGettext
457
458
459 module Unix = OASISUnixPath
460
461
462 let make =
463 function
464 | [] ->
465 invalid_arg "OASISHostPath.make"
466 | hd :: tl ->
467 List.fold_left Filename.concat hd tl
468
469
470 let of_unix ufn =
471 match Sys.os_type with
472 | "Unix" | "Cygwin" -> ufn
473 | "Win32" ->
474 make
475 (List.map
476 (fun p ->
477 if p = Unix.current_dir_name then
478 current_dir_name
479 else if p = Unix.parent_dir_name then
480 parent_dir_name
481 else
482 p)
483 (OASISString.nsplit ufn '/'))
484 | os_type ->
485 OASISUtils.failwithf
486 (f_ "Don't know the path format of os_type %S when translating unix \
487 filename. %S")
488 os_type ufn
489
490
491 end
492
493 module OASISFileSystem = struct
494 (* # 22 "src/oasis/OASISFileSystem.ml" *)
495
496 (** File System functions
497
498 @author Sylvain Le Gall
499 *)
500
501 type 'a filename = string
502
503 class type closer =
504 object
505 method close: unit
506 end
507
508 class type reader =
509 object
510 inherit closer
511 method input: Buffer.t -> int -> unit
512 end
513
514 class type writer =
515 object
516 inherit closer
517 method output: Buffer.t -> unit
518 end
519
520 class type ['a] fs =
521 object
522 method string_of_filename: 'a filename -> string
523 method open_out: ?mode:(open_flag list) -> ?perm:int -> 'a filename -> writer
524 method open_in: ?mode:(open_flag list) -> ?perm:int -> 'a filename -> reader
525 method file_exists: 'a filename -> bool
526 method remove: 'a filename -> unit
527 end
528
529
530 module Mode =
531 struct
532 let default_in = [Open_rdonly]
533 let default_out = [Open_wronly; Open_creat; Open_trunc]
534
535 let text_in = Open_text :: default_in
536 let text_out = Open_text :: default_out
537
538 let binary_in = Open_binary :: default_in
539 let binary_out = Open_binary :: default_out
540 end
541
542 let std_length = 4096 (* Standard buffer/read length. *)
543 let binary_out = Mode.binary_out
544 let binary_in = Mode.binary_in
545
546 let of_unix_filename ufn = (ufn: 'a filename)
547 let to_unix_filename fn = (fn: string)
548
549
550 let defer_close o f =
551 try
552 let r = f o in o#close; r
553 with e ->
554 o#close; raise e
555
556
557 let stream_of_reader rdr =
558 let buf = Buffer.create std_length in
559 let pos = ref 0 in
560 let eof = ref false in
561 let rec next idx =
562 let bpos = idx - !pos in
563 if !eof then begin
564 None
565 end else if bpos < Buffer.length buf then begin
566 Some (Buffer.nth buf bpos)
567 end else begin
568 pos := !pos + Buffer.length buf;
569 Buffer.clear buf;
570 begin
571 try
572 rdr#input buf std_length;
573 with End_of_file ->
574 if Buffer.length buf = 0 then
575 eof := true
576 end;
577 next idx
578 end
579 in
580 Stream.from next
581
582
583 let read_all buf rdr =
584 try
585 while true do
586 rdr#input buf std_length
587 done
588 with End_of_file ->
589 ()
590
591 class ['a] host_fs rootdir : ['a] fs =
592 object (self)
593 method private host_filename fn = Filename.concat rootdir fn
594 method string_of_filename = self#host_filename
595
596 method open_out ?(mode=Mode.text_out) ?(perm=0o666) fn =
597 let chn = open_out_gen mode perm (self#host_filename fn) in
598 object
599 method close = close_out chn
600 method output buf = Buffer.output_buffer chn buf
601 end
602
603 method open_in ?(mode=Mode.text_in) ?(perm=0o666) fn =
604 (* TODO: use Buffer.add_channel when minimal version of OCaml will
605 * be >= 4.03.0 (previous version was discarding last chars).
606 *)
607 let chn = open_in_gen mode perm (self#host_filename fn) in
608 let strm = Stream.of_channel chn in
609 object
610 method close = close_in chn
611 method input buf len =
612 let read = ref 0 in
613 try
614 for _i = 0 to len do
615 Buffer.add_char buf (Stream.next strm);
616 incr read
617 done
618 with Stream.Failure ->
619 if !read = 0 then
620 raise End_of_file
621 end
622
623 method file_exists fn = Sys.file_exists (self#host_filename fn)
624 method remove fn = Sys.remove (self#host_filename fn)
625 end
626
627 end
628
629 module OASISContext = struct
630 (* # 22 "src/oasis/OASISContext.ml" *)
631
632
633 open OASISGettext
634
635
636 type level =
637 [ `Debug
638 | `Info
639 | `Warning
640 | `Error]
641
642
643 type source
644 type source_filename = source OASISFileSystem.filename
645
646
647 let in_srcdir ufn = OASISFileSystem.of_unix_filename ufn
648
649
650 type t =
651 {
652 (* TODO: replace this by a proplist. *)
653 quiet: bool;
654 info: bool;
655 debug: bool;
656 ignore_plugins: bool;
657 ignore_unknown_fields: bool;
658 printf: level -> string -> unit;
659 srcfs: source OASISFileSystem.fs;
660 load_oasis_plugin: string -> bool;
661 }
662
663
664 let printf lvl str =
665 let beg =
666 match lvl with
667 | `Error -> s_ "E: "
668 | `Warning -> s_ "W: "
669 | `Info -> s_ "I: "
670 | `Debug -> s_ "D: "
671 in
672 prerr_endline (beg^str)
673
674
675 let default =
676 ref
677 {
678 quiet = false;
679 info = false;
680 debug = false;
681 ignore_plugins = false;
682 ignore_unknown_fields = false;
683 printf = printf;
684 srcfs = new OASISFileSystem.host_fs(Sys.getcwd ());
685 load_oasis_plugin = (fun _ -> false);
686 }
687
688
689 let quiet =
690 {!default with quiet = true}
691
692
693 let fspecs () =
694 (* TODO: don't act on default. *)
695 let ignore_plugins = ref false in
696 ["-quiet",
697 Arg.Unit (fun () -> default := {!default with quiet = true}),
698 s_ " Run quietly";
699
700 "-info",
701 Arg.Unit (fun () -> default := {!default with info = true}),
702 s_ " Display information message";
703
704
705 "-debug",
706 Arg.Unit (fun () -> default := {!default with debug = true}),
707 s_ " Output debug message";
708
709 "-ignore-plugins",
710 Arg.Set ignore_plugins,
711 s_ " Ignore plugin's field.";
712
713 "-C",
714 Arg.String
715 (fun str ->
716 Sys.chdir str;
717 default := {!default with srcfs = new OASISFileSystem.host_fs str}),
718 s_ "dir Change directory before running (affects setup.{data,log})."],
719 fun () -> {!default with ignore_plugins = !ignore_plugins}
395720 end
396721
397722 module PropList = struct
412737 let () =
413738 Printexc.register_printer
414739 (function
415 | Not_set (nm, Some rsn) ->
416 Some
417 (Printf.sprintf (f_ "Field '%s' is not set: %s") nm rsn)
418 | Not_set (nm, None) ->
419 Some
420 (Printf.sprintf (f_ "Field '%s' is not set") nm)
421 | No_printer nm ->
422 Some
423 (Printf.sprintf (f_ "No default printer for value %s") nm)
424 | Unknown_field (nm, schm) ->
425 Some
426 (Printf.sprintf
427 (f_ "Field %s is not defined in schema %s") nm schm)
428 | _ ->
429 None)
740 | Not_set (nm, Some rsn) ->
741 Some
742 (Printf.sprintf (f_ "Field '%s' is not set: %s") nm rsn)
743 | Not_set (nm, None) ->
744 Some
745 (Printf.sprintf (f_ "Field '%s' is not set") nm)
746 | No_printer nm ->
747 Some
748 (Printf.sprintf (f_ "No default printer for value %s") nm)
749 | Unknown_field (nm, schm) ->
750 Some
751 (Printf.sprintf
752 (f_ "Field %s is not defined in schema %s") nm schm)
753 | _ ->
754 None)
430755
431756
432757 module Data =
433758 struct
434759 type t =
435 (name, unit -> unit) Hashtbl.t
760 (name, unit -> unit) Hashtbl.t
436761
437762 let create () =
438763 Hashtbl.create 13
441766 Hashtbl.clear t
442767
443768
444 (* # 78 "src/oasis/PropList.ml" *)
769 (* # 77 "src/oasis/PropList.ml" *)
445770 end
446771
447772
448773 module Schema =
449774 struct
450775 type ('ctxt, 'extra) value =
451 {
452 get: Data.t -> string;
453 set: Data.t -> ?context:'ctxt -> string -> unit;
454 help: (unit -> string) option;
455 extra: 'extra;
456 }
776 {
777 get: Data.t -> string;
778 set: Data.t -> ?context:'ctxt -> string -> unit;
779 help: (unit -> string) option;
780 extra: 'extra;
781 }
457782
458783 type ('ctxt, 'extra) t =
459 {
460 name: name;
461 fields: (name, ('ctxt, 'extra) value) Hashtbl.t;
462 order: name Queue.t;
463 name_norm: string -> string;
464 }
784 {
785 name: name;
786 fields: (name, ('ctxt, 'extra) value) Hashtbl.t;
787 order: name Queue.t;
788 name_norm: string -> string;
789 }
465790
466791 let create ?(case_insensitive=false) nm =
467792 {
470795 order = Queue.create ();
471796 name_norm =
472797 (if case_insensitive then
473 String.lowercase
798 OASISString.lowercase_ascii
474799 else
475800 fun s -> s);
476801 }
480805 t.name_norm nm
481806 in
482807
483 if Hashtbl.mem t.fields key then
484 failwith
485 (Printf.sprintf
486 (f_ "Field '%s' is already defined in schema '%s'")
487 nm t.name);
488 Hashtbl.add
489 t.fields
490 key
491 {
492 set = set;
493 get = get;
494 help = help;
495 extra = extra;
496 };
497 Queue.add nm t.order
808 if Hashtbl.mem t.fields key then
809 failwith
810 (Printf.sprintf
811 (f_ "Field '%s' is already defined in schema '%s'")
812 nm t.name);
813 Hashtbl.add
814 t.fields
815 key
816 {
817 set = set;
818 get = get;
819 help = help;
820 extra = extra;
821 };
822 Queue.add nm t.order
498823
499824 let mem t nm =
500825 Hashtbl.mem t.fields nm
520845 let v =
521846 find t k
522847 in
523 f acc k v.extra v.help)
848 f acc k v.extra v.help)
524849 acc
525850 t.order
526851
538863 module Field =
539864 struct
540865 type ('ctxt, 'value, 'extra) t =
541 {
542 set: Data.t -> ?context:'ctxt -> 'value -> unit;
543 get: Data.t -> 'value;
544 sets: Data.t -> ?context:'ctxt -> string -> unit;
545 gets: Data.t -> string;
546 help: (unit -> string) option;
547 extra: 'extra;
548 }
866 {
867 set: Data.t -> ?context:'ctxt -> 'value -> unit;
868 get: Data.t -> 'value;
869 sets: Data.t -> ?context:'ctxt -> string -> unit;
870 gets: Data.t -> string;
871 help: (unit -> string) option;
872 extra: 'extra;
873 }
549874
550875 let new_id =
551876 let last_id =
552877 ref 0
553878 in
554 fun () -> incr last_id; !last_id
879 fun () -> incr last_id; !last_id
555880
556881 let create ?schema ?name ?parse ?print ?default ?update ?help extra =
557882 (* Default value container *)
590915 let x =
591916 match update with
592917 | Some f ->
593 begin
594 try
595 f ?context (get data) x
596 with Not_set _ ->
597 x
598 end
918 begin
919 try
920 f ?context (get data) x
921 with Not_set _ ->
922 x
923 end
599924 | None ->
600 x
925 x
601926 in
602 Hashtbl.replace
603 data
604 nm
605 (fun () -> v := Some x)
927 Hashtbl.replace
928 data
929 nm
930 (fun () -> v := Some x)
606931 in
607932
608933 (* Parse string value, if possible *)
609934 let parse =
610935 match parse with
611936 | Some f ->
612 f
937 f
613938 | None ->
614 fun ?context s ->
615 failwith
616 (Printf.sprintf
617 (f_ "Cannot parse field '%s' when setting value %S")
618 nm
619 s)
939 fun ?context s ->
940 failwith
941 (Printf.sprintf
942 (f_ "Cannot parse field '%s' when setting value %S")
943 nm
944 s)
620945 in
621946
622947 (* Set data, from string *)
628953 let print =
629954 match print with
630955 | Some f ->
631 f
956 f
632957 | None ->
633 fun _ -> raise (No_printer nm)
958 fun _ -> raise (No_printer nm)
634959 in
635960
636961 (* Get data, as a string *)
638963 print (get data)
639964 in
640965
641 begin
642 match schema with
643 | Some t ->
644 Schema.add t nm sets gets extra help
645 | None ->
646 ()
647 end;
648
649 {
650 set = set;
651 get = get;
652 sets = sets;
653 gets = gets;
654 help = help;
655 extra = extra;
656 }
966 begin
967 match schema with
968 | Some t ->
969 Schema.add t nm sets gets extra help
970 | None ->
971 ()
972 end;
973
974 {
975 set = set;
976 get = get;
977 sets = sets;
978 gets = gets;
979 help = help;
980 extra = extra;
981 }
657982
658983 let fset data t ?context x =
659984 t.set data ?context x
6751000 let fld =
6761001 Field.create ?schema ?name ?parse ?print ?default ?update ?help extra
6771002 in
678 fun data -> Field.fget data fld
1003 fun data -> Field.fget data fld
6791004 end
6801005 end
6811006
6971022 | `Info -> ctxt.info
6981023 | _ -> true
6991024 in
700 Printf.ksprintf
701 (fun str ->
702 if cond then
703 begin
704 ctxt.printf lvl str
705 end)
706 fmt
1025 Printf.ksprintf
1026 (fun str ->
1027 if cond then
1028 begin
1029 ctxt.printf lvl str
1030 end)
1031 fmt
7071032
7081033
7091034 let debug ~ctxt fmt =
7281053
7291054
7301055 open OASISGettext
731
732
733
734
735
736 type s = string
7371056
7381057
7391058 type t = string
7491068 | VAnd of comparator * comparator
7501069
7511070
752
7531071 (* Range of allowed characters *)
754 let is_digit c =
755 '0' <= c && c <= '9'
756
757
758 let is_alpha c =
759 ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
760
761
762 let is_special =
763 function
764 | '.' | '+' | '-' | '~' -> true
765 | _ -> false
1072 let is_digit c = '0' <= c && c <= '9'
1073 let is_alpha c = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
1074 let is_special = function | '.' | '+' | '-' | '~' -> true | _ -> false
7661075
7671076
7681077 let rec version_compare v1 v2 =
7701079 begin
7711080 (* Compare ascii string, using special meaning for version
7721081 * related char
773 *)
1082 *)
7741083 let val_ascii c =
7751084 if c = '~' then -1
7761085 else if is_digit c then 0
8051114 let compare_digit () =
8061115 let extract_int v p =
8071116 let start_p = !p in
808 while !p < String.length v && is_digit v.[!p] do
809 incr p
810 done;
811 let substr =
812 String.sub v !p ((String.length v) - !p)
813 in
814 let res =
815 match String.sub v start_p (!p - start_p) with
816 | "" -> 0
817 | s -> int_of_string s
818 in
819 res, substr
1117 while !p < String.length v && is_digit v.[!p] do
1118 incr p
1119 done;
1120 let substr =
1121 String.sub v !p ((String.length v) - !p)
1122 in
1123 let res =
1124 match String.sub v start_p (!p - start_p) with
1125 | "" -> 0
1126 | s -> int_of_string s
1127 in
1128 res, substr
8201129 in
8211130 let i1, tl1 = extract_int v1 (ref !p) in
8221131 let i2, tl2 = extract_int v2 (ref !p) in
823 i1 - i2, tl1, tl2
1132 i1 - i2, tl1, tl2
8241133 in
8251134
826 match compare_vascii () with
827 | 0 ->
828 begin
829 match compare_digit () with
830 | 0, tl1, tl2 ->
831 if tl1 <> "" && is_digit tl1.[0] then
832 1
833 else if tl2 <> "" && is_digit tl2.[0] then
834 -1
835 else
836 version_compare tl1 tl2
837 | n, _, _ ->
838 n
839 end
840 | n ->
841 n
1135 match compare_vascii () with
1136 | 0 ->
1137 begin
1138 match compare_digit () with
1139 | 0, tl1, tl2 ->
1140 if tl1 <> "" && is_digit tl1.[0] then
1141 1
1142 else if tl2 <> "" && is_digit tl2.[0] then
1143 -1
1144 else
1145 version_compare tl1 tl2
1146 | n, _, _ ->
1147 n
1148 end
1149 | n ->
1150 n
8421151 end
843 else
844 begin
845 0
846 end
1152 else begin
1153 0
1154 end
8471155
8481156
8491157 let version_of_string str = str
8501158
8511159
8521160 let string_of_version t = t
853
854
855 let version_compare_string s1 s2 =
856 version_compare (version_of_string s1) (version_of_string s2)
8571161
8581162
8591163 let chop t =
8611165 let pos =
8621166 String.rindex t '.'
8631167 in
864 String.sub t 0 pos
1168 String.sub t 0 pos
8651169 with Not_found ->
8661170 t
8671171
8691173 let rec comparator_apply v op =
8701174 match op with
8711175 | VGreater cv ->
872 (version_compare v cv) > 0
1176 (version_compare v cv) > 0
8731177 | VGreaterEqual cv ->
874 (version_compare v cv) >= 0
1178 (version_compare v cv) >= 0
8751179 | VLesser cv ->
876 (version_compare v cv) < 0
1180 (version_compare v cv) < 0
8771181 | VLesserEqual cv ->
878 (version_compare v cv) <= 0
1182 (version_compare v cv) <= 0
8791183 | VEqual cv ->
880 (version_compare v cv) = 0
1184 (version_compare v cv) = 0
8811185 | VOr (op1, op2) ->
882 (comparator_apply v op1) || (comparator_apply v op2)
1186 (comparator_apply v op1) || (comparator_apply v op2)
8831187 | VAnd (op1, op2) ->
884 (comparator_apply v op1) && (comparator_apply v op2)
1188 (comparator_apply v op1) && (comparator_apply v op2)
8851189
8861190
8871191 let rec string_of_comparator =
8921196 | VGreaterEqual v -> ">= "^(string_of_version v)
8931197 | VLesserEqual v -> "<= "^(string_of_version v)
8941198 | VOr (c1, c2) ->
895 (string_of_comparator c1)^" || "^(string_of_comparator c2)
1199 (string_of_comparator c1)^" || "^(string_of_comparator c2)
8961200 | VAnd (c1, c2) ->
897 (string_of_comparator c1)^" && "^(string_of_comparator c2)
1201 (string_of_comparator c1)^" && "^(string_of_comparator c2)
8981202
8991203
9001204 let rec varname_of_comparator =
9041208 (OASISUtils.varname_of_string
9051209 (string_of_version v))
9061210 in
907 function
908 | VGreater v -> concat "gt" v
909 | VLesser v -> concat "lt" v
910 | VEqual v -> concat "eq" v
911 | VGreaterEqual v -> concat "ge" v
912 | VLesserEqual v -> concat "le" v
913 | VOr (c1, c2) ->
914 (varname_of_comparator c1)^"_or_"^(varname_of_comparator c2)
915 | VAnd (c1, c2) ->
916 (varname_of_comparator c1)^"_and_"^(varname_of_comparator c2)
917
918
919 let rec comparator_ge v' =
920 let cmp v = version_compare v v' >= 0 in
9211211 function
922 | VEqual v
923 | VGreaterEqual v
924 | VGreater v -> cmp v
925 | VLesserEqual _
926 | VLesser _ -> false
927 | VOr (c1, c2) -> comparator_ge v' c1 || comparator_ge v' c2
928 | VAnd (c1, c2) -> comparator_ge v' c1 && comparator_ge v' c2
1212 | VGreater v -> concat "gt" v
1213 | VLesser v -> concat "lt" v
1214 | VEqual v -> concat "eq" v
1215 | VGreaterEqual v -> concat "ge" v
1216 | VLesserEqual v -> concat "le" v
1217 | VOr (c1, c2) ->
1218 (varname_of_comparator c1)^"_or_"^(varname_of_comparator c2)
1219 | VAnd (c1, c2) ->
1220 (varname_of_comparator c1)^"_and_"^(varname_of_comparator c2)
9291221
9301222
9311223 end
9361228
9371229 (** License for _oasis fields
9381230 @author Sylvain Le Gall
939 *)
940
941
942
1231 *)
9431232
9441233
9451234 type license = string
946
947
9481235 type license_exception = string
9491236
9501237
9521239 | Version of OASISVersion.t
9531240 | VersionOrLater of OASISVersion.t
9541241 | NoVersion
955
9561242
9571243
9581244 type license_dep_5_unit =
9631249 }
9641250
9651251
966
9671252 type license_dep_5 =
9681253 | DEP5Unit of license_dep_5_unit
9691254 | DEP5Or of license_dep_5 list
9751260 | OtherLicense of string (* URL *)
9761261
9771262
978
9791263 end
9801264
9811265 module OASISExpr = struct
9821266 (* # 22 "src/oasis/OASISExpr.ml" *)
9831267
9841268
985
986
987
9881269 open OASISGettext
1270 open OASISUtils
9891271
9901272
9911273 type test = string
992
993
9941274 type flag = string
9951275
9961276
10011281 | EOr of t * t
10021282 | EFlag of flag
10031283 | ETest of test * string
1004
10051284
10061285
10071286 type 'a choices = (t * 'a) list
10801359 module OASISText = struct
10811360 (* # 22 "src/oasis/OASISText.ml" *)
10821361
1083
1084
10851362 type elt =
10861363 | Para of string
10871364 | Verbatim of string
10881365 | BlankLine
10891366
1090
10911367 type t = elt list
1368
1369 end
1370
1371 module OASISSourcePatterns = struct
1372 (* # 22 "src/oasis/OASISSourcePatterns.ml" *)
1373
1374 open OASISUtils
1375 open OASISGettext
1376
1377 module Templater =
1378 struct
1379 (* TODO: use this module in BaseEnv.var_expand and BaseFileAB, at least. *)
1380 type t =
1381 {
1382 atoms: atom list;
1383 origin: string
1384 }
1385 and atom =
1386 | Text of string
1387 | Expr of expr
1388 and expr =
1389 | Ident of string
1390 | String of string
1391 | Call of string * expr
1392
1393
1394 type env =
1395 {
1396 variables: string MapString.t;
1397 functions: (string -> string) MapString.t;
1398 }
1399
1400
1401 let eval env t =
1402 let rec eval_expr env =
1403 function
1404 | String str -> str
1405 | Ident nm ->
1406 begin
1407 try
1408 MapString.find nm env.variables
1409 with Not_found ->
1410 (* TODO: add error location within the string. *)
1411 failwithf
1412 (f_ "Unable to find variable %S in source pattern %S")
1413 nm t.origin
1414 end
1415
1416 | Call (fn, expr) ->
1417 begin
1418 try
1419 (MapString.find fn env.functions) (eval_expr env expr)
1420 with Not_found ->
1421 (* TODO: add error location within the string. *)
1422 failwithf
1423 (f_ "Unable to find function %S in source pattern %S")
1424 fn t.origin
1425 end
1426 in
1427 String.concat ""
1428 (List.map
1429 (function
1430 | Text str -> str
1431 | Expr expr -> eval_expr env expr)
1432 t.atoms)
1433
1434
1435 let parse env s =
1436 let lxr = Genlex.make_lexer [] in
1437 let parse_expr s =
1438 let st = lxr (Stream.of_string s) in
1439 match Stream.npeek 3 st with
1440 | [Genlex.Ident fn; Genlex.Ident nm] -> Call(fn, Ident nm)
1441 | [Genlex.Ident fn; Genlex.String str] -> Call(fn, String str)
1442 | [Genlex.String str] -> String str
1443 | [Genlex.Ident nm] -> Ident nm
1444 (* TODO: add error location within the string. *)
1445 | _ -> failwithf (f_ "Unable to parse expression %S") s
1446 in
1447 let parse s =
1448 let lst_exprs = ref [] in
1449 let ss =
1450 let buff = Buffer.create (String.length s) in
1451 Buffer.add_substitute
1452 buff
1453 (fun s -> lst_exprs := (parse_expr s) :: !lst_exprs; "\000")
1454 s;
1455 Buffer.contents buff
1456 in
1457 let rec join =
1458 function
1459 | hd1 :: tl1, hd2 :: tl2 -> Text hd1 :: Expr hd2 :: join (tl1, tl2)
1460 | [], tl -> List.map (fun e -> Expr e) tl
1461 | tl, [] -> List.map (fun e -> Text e) tl
1462 in
1463 join (OASISString.nsplit ss '\000', List.rev (!lst_exprs))
1464 in
1465 let t = {atoms = parse s; origin = s} in
1466 (* We rely on a simple evaluation for checking variables/functions.
1467 It works because there is no if/loop statement.
1468 *)
1469 let _s : string = eval env t in
1470 t
1471
1472 (* # 144 "src/oasis/OASISSourcePatterns.ml" *)
1473 end
1474
1475
1476 type t = Templater.t
1477
1478
1479 let env ~modul () =
1480 {
1481 Templater.
1482 variables = MapString.of_list ["module", modul];
1483 functions = MapString.of_list
1484 [
1485 "capitalize_file", OASISUnixPath.capitalize_file;
1486 "uncapitalize_file", OASISUnixPath.uncapitalize_file;
1487 ];
1488 }
1489
1490 let all_possible_files lst ~path ~modul =
1491 let eval = Templater.eval (env ~modul ()) in
1492 List.fold_left
1493 (fun acc pat -> OASISUnixPath.concat path (eval pat) :: acc)
1494 [] lst
1495
1496
1497 let to_string t = t.Templater.origin
1498
10921499
10931500 end
10941501
10951502 module OASISTypes = struct
10961503 (* # 22 "src/oasis/OASISTypes.ml" *)
1097
1098
1099
11001504
11011505
11021506 type name = string
11031507 type package_name = string
11041508 type url = string
11051509 type unix_dirname = string
1106 type unix_filename = string
1107 type host_dirname = string
1108 type host_filename = string
1510 type unix_filename = string (* TODO: replace everywhere. *)
1511 type host_dirname = string (* TODO: replace everywhere. *)
1512 type host_filename = string (* TODO: replace everywhere. *)
11091513 type prog = string
11101514 type arg = string
11111515 type args = string list
11221526 | Best
11231527
11241528
1125
11261529 type dependency =
11271530 | FindlibPackage of findlib_full * OASISVersion.comparator option
11281531 | InternalLibrary of name
11291532
11301533
1131
11321534 type tool =
11331535 | ExternalTool of name
11341536 | InternalExecutable of name
1135
11361537
11371538
11381539 type vcs =
11471548 | OtherVCS of url
11481549
11491550
1150
11511551 type plugin_kind =
1152 [ `Configure
1153 | `Build
1154 | `Doc
1155 | `Test
1156 | `Install
1157 | `Extra
1158 ]
1552 [ `Configure
1553 | `Build
1554 | `Doc
1555 | `Test
1556 | `Install
1557 | `Extra
1558 ]
11591559
11601560
11611561 type plugin_data_purpose =
1162 [ `Configure
1163 | `Build
1164 | `Install
1165 | `Clean
1166 | `Distclean
1167 | `Install
1168 | `Uninstall
1169 | `Test
1170 | `Doc
1171 | `Extra
1172 | `Other of string
1173 ]
1562 [ `Configure
1563 | `Build
1564 | `Install
1565 | `Clean
1566 | `Distclean
1567 | `Install
1568 | `Uninstall
1569 | `Test
1570 | `Doc
1571 | `Extra
1572 | `Other of string
1573 ]
11741574
11751575
11761576 type 'a plugin = 'a * name * OASISVersion.t option
11821582 type plugin_data = (all_plugin * plugin_data_purpose * (unit -> unit)) list
11831583
11841584
1185 (* # 115 "src/oasis/OASISTypes.ml" *)
1186
1187
11881585 type 'a conditional = 'a OASISExpr.choices
11891586
11901587
11911588 type custom =
1192 {
1193 pre_command: (command_line option) conditional;
1194 post_command: (command_line option) conditional;
1195 }
1196
1589 {
1590 pre_command: (command_line option) conditional;
1591 post_command: (command_line option) conditional;
1592 }
11971593
11981594
11991595 type common_section =
1200 {
1201 cs_name: name;
1202 cs_data: PropList.Data.t;
1203 cs_plugin_data: plugin_data;
1204 }
1205
1596 {
1597 cs_name: name;
1598 cs_data: PropList.Data.t;
1599 cs_plugin_data: plugin_data;
1600 }
12061601
12071602
12081603 type build_section =
1209 {
1210 bs_build: bool conditional;
1211 bs_install: bool conditional;
1212 bs_path: unix_dirname;
1213 bs_compiled_object: compiled_object;
1214 bs_build_depends: dependency list;
1215 bs_build_tools: tool list;
1216 bs_c_sources: unix_filename list;
1217 bs_data_files: (unix_filename * unix_filename option) list;
1218 bs_ccopt: args conditional;
1219 bs_cclib: args conditional;
1220 bs_dlllib: args conditional;
1221 bs_dllpath: args conditional;
1222 bs_byteopt: args conditional;
1223 bs_nativeopt: args conditional;
1224 }
1225
1604 {
1605 bs_build: bool conditional;
1606 bs_install: bool conditional;
1607 bs_path: unix_dirname;
1608 bs_compiled_object: compiled_object;
1609 bs_build_depends: dependency list;
1610 bs_build_tools: tool list;
1611 bs_interface_patterns: OASISSourcePatterns.t list;
1612 bs_implementation_patterns: OASISSourcePatterns.t list;
1613 bs_c_sources: unix_filename list;
1614 bs_data_files: (unix_filename * unix_filename option) list;
1615 bs_findlib_extra_files: unix_filename list;
1616 bs_ccopt: args conditional;
1617 bs_cclib: args conditional;
1618 bs_dlllib: args conditional;
1619 bs_dllpath: args conditional;
1620 bs_byteopt: args conditional;
1621 bs_nativeopt: args conditional;
1622 }
12261623
12271624
12281625 type library =
1229 {
1230 lib_modules: string list;
1231 lib_pack: bool;
1232 lib_internal_modules: string list;
1233 lib_findlib_parent: findlib_name option;
1234 lib_findlib_name: findlib_name option;
1235 lib_findlib_containers: findlib_name list;
1236 }
1626 {
1627 lib_modules: string list;
1628 lib_pack: bool;
1629 lib_internal_modules: string list;
1630 lib_findlib_parent: findlib_name option;
1631 lib_findlib_name: findlib_name option;
1632 lib_findlib_directory: unix_dirname option;
1633 lib_findlib_containers: findlib_name list;
1634 }
12371635
12381636
12391637 type object_ =
1240 {
1241 obj_modules: string list;
1242 obj_findlib_fullname: findlib_name list option;
1243 }
1638 {
1639 obj_modules: string list;
1640 obj_findlib_fullname: findlib_name list option;
1641 obj_findlib_directory: unix_dirname option;
1642 }
12441643
12451644
12461645 type executable =
1247 {
1248 exec_custom: bool;
1249 exec_main_is: unix_filename;
1250 }
1646 {
1647 exec_custom: bool;
1648 exec_main_is: unix_filename;
1649 }
12511650
12521651
12531652 type flag =
1254 {
1255 flag_description: string option;
1256 flag_default: bool conditional;
1257 }
1653 {
1654 flag_description: string option;
1655 flag_default: bool conditional;
1656 }
12581657
12591658
12601659 type source_repository =
1261 {
1262 src_repo_type: vcs;
1263 src_repo_location: url;
1264 src_repo_browser: url option;
1265 src_repo_module: string option;
1266 src_repo_branch: string option;
1267 src_repo_tag: string option;
1268 src_repo_subdir: unix_filename option;
1269 }
1660 {
1661 src_repo_type: vcs;
1662 src_repo_location: url;
1663 src_repo_browser: url option;
1664 src_repo_module: string option;
1665 src_repo_branch: string option;
1666 src_repo_tag: string option;
1667 src_repo_subdir: unix_filename option;
1668 }
12701669
12711670
12721671 type test =
1273 {
1274 test_type: [`Test] plugin;
1275 test_command: command_line conditional;
1276 test_custom: custom;
1277 test_working_directory: unix_filename option;
1278 test_run: bool conditional;
1279 test_tools: tool list;
1280 }
1672 {
1673 test_type: [`Test] plugin;
1674 test_command: command_line conditional;
1675 test_custom: custom;
1676 test_working_directory: unix_filename option;
1677 test_run: bool conditional;
1678 test_tools: tool list;
1679 }
12811680
12821681
12831682 type doc_format =
1284 | HTML of unix_filename
1683 | HTML of unix_filename (* TODO: source filename. *)
12851684 | DocText
12861685 | PDF
12871686 | PostScript
1288 | Info of unix_filename
1687 | Info of unix_filename (* TODO: source filename. *)
12891688 | DVI
12901689 | OtherDoc
12911690
12921691
1293
12941692 type doc =
1295 {
1296 doc_type: [`Doc] plugin;
1297 doc_custom: custom;
1298 doc_build: bool conditional;
1299 doc_install: bool conditional;
1300 doc_install_dir: unix_filename;
1301 doc_title: string;
1302 doc_authors: string list;
1303 doc_abstract: string option;
1304 doc_format: doc_format;
1305 doc_data_files: (unix_filename * unix_filename option) list;
1306 doc_build_tools: tool list;
1307 }
1693 {
1694 doc_type: [`Doc] plugin;
1695 doc_custom: custom;
1696 doc_build: bool conditional;
1697 doc_install: bool conditional;
1698 doc_install_dir: unix_filename; (* TODO: dest filename ?. *)
1699 doc_title: string;
1700 doc_authors: string list;
1701 doc_abstract: string option;
1702 doc_format: doc_format;
1703 (* TODO: src filename. *)
1704 doc_data_files: (unix_filename * unix_filename option) list;
1705 doc_build_tools: tool list;
1706 }
13081707
13091708
13101709 type section =
13171716 | Doc of common_section * doc
13181717
13191718
1320
13211719 type section_kind =
1322 [ `Library | `Object | `Executable | `Flag | `SrcRepo | `Test | `Doc ]
1720 [ `Library | `Object | `Executable | `Flag | `SrcRepo | `Test | `Doc ]
13231721
13241722
13251723 type package =
1326 {
1327 oasis_version: OASISVersion.t;
1328 ocaml_version: OASISVersion.comparator option;
1329 findlib_version: OASISVersion.comparator option;
1330 alpha_features: string list;
1331 beta_features: string list;
1332 name: package_name;
1333 version: OASISVersion.t;
1334 license: OASISLicense.t;
1335 license_file: unix_filename option;
1336 copyrights: string list;
1337 maintainers: string list;
1338 authors: string list;
1339 homepage: url option;
1340 synopsis: string;
1341 description: OASISText.t option;
1342 categories: url list;
1343
1344 conf_type: [`Configure] plugin;
1345 conf_custom: custom;
1346
1347 build_type: [`Build] plugin;
1348 build_custom: custom;
1349
1350 install_type: [`Install] plugin;
1351 install_custom: custom;
1352 uninstall_custom: custom;
1353
1354 clean_custom: custom;
1355 distclean_custom: custom;
1356
1357 files_ab: unix_filename list;
1358 sections: section list;
1359 plugins: [`Extra] plugin list;
1360 disable_oasis_section: unix_filename list;
1361 schema_data: PropList.Data.t;
1362 plugin_data: plugin_data;
1363 }
1724 {
1725 oasis_version: OASISVersion.t;
1726 ocaml_version: OASISVersion.comparator option;
1727 findlib_version: OASISVersion.comparator option;
1728 alpha_features: string list;
1729 beta_features: string list;
1730 name: package_name;
1731 version: OASISVersion.t;
1732 license: OASISLicense.t;
1733 license_file: unix_filename option; (* TODO: source filename. *)
1734 copyrights: string list;
1735 maintainers: string list;
1736 authors: string list;
1737 homepage: url option;
1738 bugreports: url option;
1739 synopsis: string;
1740 description: OASISText.t option;
1741 tags: string list;
1742 categories: url list;
1743
1744 conf_type: [`Configure] plugin;
1745 conf_custom: custom;
1746
1747 build_type: [`Build] plugin;
1748 build_custom: custom;
1749
1750 install_type: [`Install] plugin;
1751 install_custom: custom;
1752 uninstall_custom: custom;
1753
1754 clean_custom: custom;
1755 distclean_custom: custom;
1756
1757 files_ab: unix_filename list; (* TODO: source filename. *)
1758 sections: section list;
1759 plugins: [`Extra] plugin list;
1760 disable_oasis_section: unix_filename list; (* TODO: source filename. *)
1761 schema_data: PropList.Data.t;
1762 plugin_data: plugin_data;
1763 }
13641764
13651765
13661766 end
13761776 module MapPlugin =
13771777 Map.Make
13781778 (struct
1379 type t = plugin_kind * name
1380 let compare = Pervasives.compare
1381 end)
1779 type t = plugin_kind * name
1780 let compare = Pervasives.compare
1781 end)
13821782
13831783 module Data =
13841784 struct
13851785 type t =
1386 {
1387 oasis_version: OASISVersion.t;
1388 plugin_versions: OASISVersion.t option MapPlugin.t;
1389 alpha_features: string list;
1390 beta_features: string list;
1391 }
1786 {
1787 oasis_version: OASISVersion.t;
1788 plugin_versions: OASISVersion.t option MapPlugin.t;
1789 alpha_features: string list;
1790 beta_features: string list;
1791 }
13921792
13931793 let create oasis_version alpha_features beta_features =
13941794 {
14061806
14071807 let add_plugin (plugin_kind, plugin_name, plugin_version) t =
14081808 {t with
1409 plugin_versions = MapPlugin.add
1410 (plugin_kind, plugin_name)
1411 plugin_version
1412 t.plugin_versions}
1809 plugin_versions = MapPlugin.add
1810 (plugin_kind, plugin_name)
1811 plugin_version
1812 t.plugin_versions}
14131813
14141814 let plugin_version plugin_kind plugin_name t =
14151815 MapPlugin.find (plugin_kind, plugin_name) t.plugin_versions
14181818 Printf.sprintf
14191819 "oasis_version: %s; alpha_features: %s; beta_features: %s; \
14201820 plugins_version: %s"
1421 (OASISVersion.string_of_version t.oasis_version)
1821 (OASISVersion.string_of_version (t:t).oasis_version)
14221822 (String.concat ", " t.alpha_features)
14231823 (String.concat ", " t.beta_features)
14241824 (String.concat ", "
14251825 (MapPlugin.fold
14261826 (fun (_, plg) ver_opt acc ->
14271827 (plg^
1428 (match ver_opt with
1429 | Some v ->
1430 " "^(OASISVersion.string_of_version v)
1431 | None -> ""))
1828 (match ver_opt with
1829 | Some v ->
1830 " "^(OASISVersion.string_of_version v)
1831 | None -> ""))
14321832 :: acc)
14331833 t.plugin_versions []))
14341834 end
14431843
14441844 let string_of_stage =
14451845 function
1446 | Alpha -> "alpha"
1447 | Beta -> "beta"
1846 | Alpha -> "alpha"
1847 | Beta -> "beta"
14481848
14491849
14501850 let field_of_stage =
14511851 function
1452 | Alpha -> "AlphaFeatures"
1453 | Beta -> "BetaFeatures"
1852 | Alpha -> "AlphaFeatures"
1853 | Beta -> "BetaFeatures"
14541854
14551855 type publication = InDev of stage | SinceVersion of OASISVersion.t
14561856
14571857 type t =
1458 {
1459 name: string;
1460 plugin: all_plugin option;
1461 publication: publication;
1462 description: unit -> string;
1463 }
1858 {
1859 name: string;
1860 plugin: all_plugin option;
1861 publication: publication;
1862 description: unit -> string;
1863 }
14641864
14651865 (* TODO: mutex protect this. *)
14661866 let all_features = Hashtbl.create 13
14741874 let to_string t =
14751875 Printf.sprintf
14761876 "feature: %s; plugin: %s; publication: %s"
1477 t.name
1877 (t:t).name
14781878 (match t.plugin with
1479 | None -> "<none>"
1480 | Some (_, nm, _) -> nm)
1879 | None -> "<none>"
1880 | Some (_, nm, _) -> nm)
14811881 (match t.publication with
1482 | InDev stage -> string_of_stage stage
1483 | SinceVersion ver -> ">= "^(OASISVersion.string_of_version ver))
1882 | InDev stage -> string_of_stage stage
1883 | SinceVersion ver -> ">= "^(OASISVersion.string_of_version ver))
14841884
14851885 let data_check t data origin =
14861886 let no_message = "no message" in
14871887
14881888 let check_feature features stage =
1489 let has_feature = List.mem t.name features in
1889 let has_feature = List.mem (t:t).name features in
14901890 if not has_feature then
1491 match origin with
1492 | Field (fld, where) ->
1493 Some
1494 (Printf.sprintf
1495 (f_ "Field %s in %s is only available when feature %s \
1496 is in field %s.")
1497 fld where t.name (field_of_stage stage))
1498 | Section sct ->
1499 Some
1500 (Printf.sprintf
1501 (f_ "Section %s is only available when features %s \
1502 is in field %s.")
1503 sct t.name (field_of_stage stage))
1504 | NoOrigin ->
1505 Some no_message
1891 match (origin:origin) with
1892 | Field (fld, where) ->
1893 Some
1894 (Printf.sprintf
1895 (f_ "Field %s in %s is only available when feature %s \
1896 is in field %s.")
1897 fld where t.name (field_of_stage stage))
1898 | Section sct ->
1899 Some
1900 (Printf.sprintf
1901 (f_ "Section %s is only available when features %s \
1902 is in field %s.")
1903 sct t.name (field_of_stage stage))
1904 | NoOrigin ->
1905 Some no_message
15061906 else
15071907 None
15081908 in
15121912 OASISVersion.comparator_apply
15131913 version (OASISVersion.VGreaterEqual min_version)
15141914 in
1515 Printf.ksprintf
1516 (fun str ->
1517 if version_is_good then
1518 None
1519 else
1520 Some str)
1521 fmt
1915 Printf.ksprintf
1916 (fun str -> if version_is_good then None else Some str)
1917 fmt
15221918 in
15231919
15241920 match origin, t.plugin, t.publication with
1525 | _, _, InDev Alpha -> check_feature data.Data.alpha_features Alpha
1526 | _, _, InDev Beta -> check_feature data.Data.beta_features Beta
1527 | Field(fld, where), None, SinceVersion min_version ->
1528 version_is_good ~min_version data.Data.oasis_version
1529 (f_ "Field %s in %s is only valid since OASIS v%s, update \
1530 OASISFormat field from '%s' to '%s' after checking \
1531 OASIS changelog.")
1532 fld where (string_of_version min_version)
1533 (string_of_version data.Data.oasis_version)
1534 (string_of_version min_version)
1535
1536 | Field(fld, where), Some(plugin_knd, plugin_name, _),
1537 SinceVersion min_version ->
1538 begin
1921 | _, _, InDev Alpha -> check_feature data.Data.alpha_features Alpha
1922 | _, _, InDev Beta -> check_feature data.Data.beta_features Beta
1923 | Field(fld, where), None, SinceVersion min_version ->
1924 version_is_good ~min_version data.Data.oasis_version
1925 (f_ "Field %s in %s is only valid since OASIS v%s, update \
1926 OASISFormat field from '%s' to '%s' after checking \
1927 OASIS changelog.")
1928 fld where (string_of_version min_version)
1929 (string_of_version data.Data.oasis_version)
1930 (string_of_version min_version)
1931
1932 | Field(fld, where), Some(plugin_knd, plugin_name, _),
1933 SinceVersion min_version ->
1934 begin
1935 try
1936 let plugin_version_current =
15391937 try
1540 let plugin_version_current =
1541 try
1542 match Data.plugin_version plugin_knd plugin_name data with
1543 | Some ver -> ver
1544 | None ->
1545 failwithf
1546 (f_ "Field %s in %s is only valid for the OASIS \
1547 plugin %s since v%s, but no plugin version is \
1548 defined in the _oasis file, change '%s' to \
1549 '%s (%s)' in your _oasis file.")
1550 fld where plugin_name (string_of_version min_version)
1551 plugin_name
1552 plugin_name (string_of_version min_version)
1553 with Not_found ->
1554 failwithf
1555 (f_ "Field %s in %s is only valid when the OASIS plugin %s \
1556 is defined.")
1557 fld where plugin_name
1558 in
1559 version_is_good ~min_version plugin_version_current
1560 (f_ "Field %s in %s is only valid for the OASIS plugin %s \
1561 since v%s, update your plugin from '%s (%s)' to \
1562 '%s (%s)' after checking the plugin's changelog.")
1563 fld where plugin_name (string_of_version min_version)
1564 plugin_name (string_of_version plugin_version_current)
1565 plugin_name (string_of_version min_version)
1566 with Failure msg ->
1567 Some msg
1568 end
1569
1570 | Section sct, None, SinceVersion min_version ->
1571 version_is_good ~min_version data.Data.oasis_version
1572 (f_ "Section %s is only valid for since OASIS v%s, update \
1573 OASISFormat field from '%s' to '%s' after checking OASIS \
1574 changelog.")
1575 sct (string_of_version min_version)
1576 (string_of_version data.Data.oasis_version)
1577 (string_of_version min_version)
1578
1579 | Section sct, Some(plugin_knd, plugin_name, _),
1580 SinceVersion min_version ->
1581 begin
1938 match Data.plugin_version plugin_knd plugin_name data with
1939 | Some ver -> ver
1940 | None ->
1941 failwithf
1942 (f_ "Field %s in %s is only valid for the OASIS \
1943 plugin %s since v%s, but no plugin version is \
1944 defined in the _oasis file, change '%s' to \
1945 '%s (%s)' in your _oasis file.")
1946 fld where plugin_name (string_of_version min_version)
1947 plugin_name
1948 plugin_name (string_of_version min_version)
1949 with Not_found ->
1950 failwithf
1951 (f_ "Field %s in %s is only valid when the OASIS plugin %s \
1952 is defined.")
1953 fld where plugin_name
1954 in
1955 version_is_good ~min_version plugin_version_current
1956 (f_ "Field %s in %s is only valid for the OASIS plugin %s \
1957 since v%s, update your plugin from '%s (%s)' to \
1958 '%s (%s)' after checking the plugin's changelog.")
1959 fld where plugin_name (string_of_version min_version)
1960 plugin_name (string_of_version plugin_version_current)
1961 plugin_name (string_of_version min_version)
1962 with Failure msg ->
1963 Some msg
1964 end
1965
1966 | Section sct, None, SinceVersion min_version ->
1967 version_is_good ~min_version data.Data.oasis_version
1968 (f_ "Section %s is only valid for since OASIS v%s, update \
1969 OASISFormat field from '%s' to '%s' after checking OASIS \
1970 changelog.")
1971 sct (string_of_version min_version)
1972 (string_of_version data.Data.oasis_version)
1973 (string_of_version min_version)
1974
1975 | Section sct, Some(plugin_knd, plugin_name, _),
1976 SinceVersion min_version ->
1977 begin
1978 try
1979 let plugin_version_current =
15821980 try
1583 let plugin_version_current =
1584 try
1585 match Data.plugin_version plugin_knd plugin_name data with
1586 | Some ver -> ver
1587 | None ->
1588 failwithf
1589 (f_ "Section %s is only valid for the OASIS \
1590 plugin %s since v%s, but no plugin version is \
1591 defined in the _oasis file, change '%s' to \
1592 '%s (%s)' in your _oasis file.")
1593 sct plugin_name (string_of_version min_version)
1594 plugin_name
1595 plugin_name (string_of_version min_version)
1596 with Not_found ->
1597 failwithf
1598 (f_ "Section %s is only valid when the OASIS plugin %s \
1599 is defined.")
1600 sct plugin_name
1601 in
1602 version_is_good ~min_version plugin_version_current
1603 (f_ "Section %s is only valid for the OASIS plugin %s \
1604 since v%s, update your plugin from '%s (%s)' to \
1605 '%s (%s)' after checking the plugin's changelog.")
1606 sct plugin_name (string_of_version min_version)
1607 plugin_name (string_of_version plugin_version_current)
1608 plugin_name (string_of_version min_version)
1609 with Failure msg ->
1610 Some msg
1611 end
1612
1613 | NoOrigin, None, SinceVersion min_version ->
1614 version_is_good ~min_version data.Data.oasis_version "%s" no_message
1615
1616 | NoOrigin, Some(plugin_knd, plugin_name, _), SinceVersion min_version ->
1617 begin
1618 try
1619 let plugin_version_current =
1620 match Data.plugin_version plugin_knd plugin_name data with
1621 | Some ver -> ver
1622 | None -> raise Not_found
1623 in
1624 version_is_good ~min_version plugin_version_current
1625 "%s" no_message
1981 match Data.plugin_version plugin_knd plugin_name data with
1982 | Some ver -> ver
1983 | None ->
1984 failwithf
1985 (f_ "Section %s is only valid for the OASIS \
1986 plugin %s since v%s, but no plugin version is \
1987 defined in the _oasis file, change '%s' to \
1988 '%s (%s)' in your _oasis file.")
1989 sct plugin_name (string_of_version min_version)
1990 plugin_name
1991 plugin_name (string_of_version min_version)
16261992 with Not_found ->
1627 Some no_message
1628 end
1993 failwithf
1994 (f_ "Section %s is only valid when the OASIS plugin %s \
1995 is defined.")
1996 sct plugin_name
1997 in
1998 version_is_good ~min_version plugin_version_current
1999 (f_ "Section %s is only valid for the OASIS plugin %s \
2000 since v%s, update your plugin from '%s (%s)' to \
2001 '%s (%s)' after checking the plugin's changelog.")
2002 sct plugin_name (string_of_version min_version)
2003 plugin_name (string_of_version plugin_version_current)
2004 plugin_name (string_of_version min_version)
2005 with Failure msg ->
2006 Some msg
2007 end
2008
2009 | NoOrigin, None, SinceVersion min_version ->
2010 version_is_good ~min_version data.Data.oasis_version "%s" no_message
2011
2012 | NoOrigin, Some(plugin_knd, plugin_name, _), SinceVersion min_version ->
2013 begin
2014 try
2015 let plugin_version_current =
2016 match Data.plugin_version plugin_knd plugin_name data with
2017 | Some ver -> ver
2018 | None -> raise Not_found
2019 in
2020 version_is_good ~min_version plugin_version_current
2021 "%s" no_message
2022 with Not_found ->
2023 Some no_message
2024 end
16292025
16302026
16312027 let data_assert t data origin =
16322028 match data_check t data origin with
1633 | None -> ()
1634 | Some str -> failwith str
2029 | None -> ()
2030 | Some str -> failwith str
16352031
16362032
16372033 let data_test t data =
16382034 match data_check t data NoOrigin with
1639 | None -> true
1640 | Some str -> false
2035 | None -> true
2036 | Some _ -> false
16412037
16422038
16432039 let package_test t pkg =
16572053 description = description;
16582054 }
16592055 in
1660 Hashtbl.add all_features name t;
1661 t
2056 Hashtbl.add all_features name t;
2057 t
16622058
16632059
16642060 let get_stage name =
16872083 create "flag_docs"
16882084 (since_version "0.3")
16892085 (fun () ->
1690 s_ "Building docs require '-docs' flag at configure.")
2086 s_ "Make building docs require '-docs' flag at configure.")
16912087
16922088
16932089 let flag_tests =
16942090 create "flag_tests"
16952091 (since_version "0.3")
16962092 (fun () ->
1697 s_ "Running tests require '-tests' flag at configure.")
2093 s_ "Make running tests require '-tests' flag at configure.")
16982094
16992095
17002096 let pack =
17192115 let compiled_setup_ml =
17202116 create "compiled_setup_ml" alpha
17212117 (fun () ->
1722 s_ "It compiles the setup.ml and speed-up actions done with it.")
2118 s_ "Compile the setup.ml and speed-up actions done with it.")
17232119
17242120 let disable_oasis_section =
17252121 create "disable_oasis_section" alpha
17262122 (fun () ->
1727 s_ "Allows the OASIS section comments and digest to be omitted in \
1728 generated files.")
2123 s_ "Allow the OASIS section comments and digests to be omitted in \
2124 generated files.")
17292125
17302126 let no_automatic_syntax =
17312127 create "no_automatic_syntax" alpha
17332129 s_ "Disable the automatic inclusion of -syntax camlp4o for packages \
17342130 that matches the internal heuristic (if a dependency ends with \
17352131 a .syntax or is a well known syntax).")
1736 end
1737
1738 module OASISUnixPath = struct
1739 (* # 22 "src/oasis/OASISUnixPath.ml" *)
1740
1741
1742 type unix_filename = string
1743 type unix_dirname = string
1744
1745
1746 type host_filename = string
1747 type host_dirname = string
1748
1749
1750 let current_dir_name = "."
1751
1752
1753 let parent_dir_name = ".."
1754
1755
1756 let is_current_dir fn =
1757 fn = current_dir_name || fn = ""
1758
1759
1760 let concat f1 f2 =
1761 if is_current_dir f1 then
1762 f2
1763 else
1764 let f1' =
1765 try OASISString.strip_ends_with ~what:"/" f1 with Not_found -> f1
1766 in
1767 f1'^"/"^f2
1768
1769
1770 let make =
1771 function
1772 | hd :: tl ->
1773 List.fold_left
1774 (fun f p -> concat f p)
1775 hd
1776 tl
1777 | [] ->
1778 invalid_arg "OASISUnixPath.make"
1779
1780
1781 let dirname f =
1782 try
1783 String.sub f 0 (String.rindex f '/')
1784 with Not_found ->
1785 current_dir_name
1786
1787
1788 let basename f =
1789 try
1790 let pos_start =
1791 (String.rindex f '/') + 1
1792 in
1793 String.sub f pos_start ((String.length f) - pos_start)
1794 with Not_found ->
1795 f
1796
1797
1798 let chop_extension f =
1799 try
1800 let last_dot =
1801 String.rindex f '.'
1802 in
1803 let sub =
1804 String.sub f 0 last_dot
1805 in
1806 try
1807 let last_slash =
1808 String.rindex f '/'
1809 in
1810 if last_slash < last_dot then
1811 sub
1812 else
1813 f
1814 with Not_found ->
1815 sub
1816
1817 with Not_found ->
1818 f
1819
1820
1821 let capitalize_file f =
1822 let dir = dirname f in
1823 let base = basename f in
1824 concat dir (String.capitalize base)
1825
1826
1827 let uncapitalize_file f =
1828 let dir = dirname f in
1829 let base = basename f in
1830 concat dir (String.uncapitalize base)
1831
1832
1833 end
1834
1835 module OASISHostPath = struct
1836 (* # 22 "src/oasis/OASISHostPath.ml" *)
1837
1838
1839 open Filename
1840
1841
1842 module Unix = OASISUnixPath
1843
1844
1845 let make =
1846 function
1847 | [] ->
1848 invalid_arg "OASISHostPath.make"
1849 | hd :: tl ->
1850 List.fold_left Filename.concat hd tl
1851
1852
1853 let of_unix ufn =
1854 if Sys.os_type = "Unix" then
1855 ufn
1856 else
1857 make
1858 (List.map
1859 (fun p ->
1860 if p = Unix.current_dir_name then
1861 current_dir_name
1862 else if p = Unix.parent_dir_name then
1863 parent_dir_name
1864 else
1865 p)
1866 (OASISString.nsplit ufn '/'))
1867
1868
2132
2133 let findlib_directory =
2134 create "findlib_directory" beta
2135 (fun () ->
2136 s_ "Allow to install findlib libraries in sub-directories of the target \
2137 findlib directory.")
2138
2139 let findlib_extra_files =
2140 create "findlib_extra_files" beta
2141 (fun () ->
2142 s_ "Allow to install extra files for findlib libraries.")
2143
2144 let source_patterns =
2145 create "source_patterns" alpha
2146 (fun () ->
2147 s_ "Customize mapping between module name and source file.")
18692148 end
18702149
18712150 module OASISSection = struct
18782157 let section_kind_common =
18792158 function
18802159 | Library (cs, _, _) ->
1881 `Library, cs
2160 `Library, cs
18822161 | Object (cs, _, _) ->
1883 `Object, cs
2162 `Object, cs
18842163 | Executable (cs, _, _) ->
1885 `Executable, cs
2164 `Executable, cs
18862165 | Flag (cs, _) ->
1887 `Flag, cs
2166 `Flag, cs
18882167 | SrcRepo (cs, _) ->
1889 `SrcRepo, cs
2168 `SrcRepo, cs
18902169 | Test (cs, _) ->
1891 `Test, cs
2170 `Test, cs
18922171 | Doc (cs, _) ->
1893 `Doc, cs
2172 `Doc, cs
18942173
18952174
18962175 let section_common sct =
19092188
19102189
19112190 (** Key used to identify section
1912 *)
2191 *)
19132192 let section_id sct =
19142193 let k, cs =
19152194 section_kind_common sct
19162195 in
1917 k, cs.cs_name
2196 k, cs.cs_name
2197
2198
2199 let string_of_section_kind =
2200 function
2201 | `Library -> "library"
2202 | `Object -> "object"
2203 | `Executable -> "executable"
2204 | `Flag -> "flag"
2205 | `SrcRepo -> "src repository"
2206 | `Test -> "test"
2207 | `Doc -> "doc"
19182208
19192209
19202210 let string_of_section sct =
1921 let k, nm =
1922 section_id sct
1923 in
1924 (match k with
1925 | `Library -> "library"
1926 | `Object -> "object"
1927 | `Executable -> "executable"
1928 | `Flag -> "flag"
1929 | `SrcRepo -> "src repository"
1930 | `Test -> "test"
1931 | `Doc -> "doc")
1932 ^" "^nm
2211 let k, nm = section_id sct in
2212 (string_of_section_kind k)^" "^nm
19332213
19342214
19352215 let section_find id scts =
19632243
19642244 module OASISBuildSection = struct
19652245 (* # 22 "src/oasis/OASISBuildSection.ml" *)
2246
2247 open OASISTypes
2248
2249 (* Look for a module file, considering capitalization or not. *)
2250 let find_module source_file_exists bs modul =
2251 let possible_lst =
2252 OASISSourcePatterns.all_possible_files
2253 (bs.bs_interface_patterns @ bs.bs_implementation_patterns)
2254 ~path:bs.bs_path
2255 ~modul
2256 in
2257 match List.filter source_file_exists possible_lst with
2258 | (fn :: _) as fn_lst -> `Sources (OASISUnixPath.chop_extension fn, fn_lst)
2259 | [] ->
2260 let open OASISUtils in
2261 let _, rev_lst =
2262 List.fold_left
2263 (fun (set, acc) fn ->
2264 let base_fn = OASISUnixPath.chop_extension fn in
2265 if SetString.mem base_fn set then
2266 set, acc
2267 else
2268 SetString.add base_fn set, base_fn :: acc)
2269 (SetString.empty, []) possible_lst
2270 in
2271 `No_sources (List.rev rev_lst)
19662272
19672273
19682274 end
19872293 | Byte -> false
19882294 in
19892295
1990 OASISUnixPath.concat
1991 dir
1992 (cs.cs_name^(suffix_program ())),
1993
1994 if not is_native_exec &&
1995 not exec.exec_custom &&
1996 bs.bs_c_sources <> [] then
1997 Some (dir^"/dll"^cs.cs_name^"_stubs"^(ext_dll ()))
1998 else
1999 None
2296 OASISUnixPath.concat
2297 dir
2298 (cs.cs_name^(suffix_program ())),
2299
2300 if not is_native_exec &&
2301 not exec.exec_custom &&
2302 bs.bs_c_sources <> [] then
2303 Some (dir^"/dll"^cs.cs_name^"_stubs"^(ext_dll ()))
2304 else
2305 None
20002306
20012307
20022308 end
20062312
20072313
20082314 open OASISTypes
2009 open OASISUtils
20102315 open OASISGettext
2011 open OASISSection
2012
2013
2014 (* Look for a module file, considering capitalization or not. *)
2015 let find_module source_file_exists bs modul =
2016 let possible_base_fn =
2017 List.map
2018 (OASISUnixPath.concat bs.bs_path)
2019 [modul;
2020 OASISUnixPath.uncapitalize_file modul;
2021 OASISUnixPath.capitalize_file modul]
2022 in
2023 (* TODO: we should be able to be able to determine the source for every
2024 * files. Hence we should introduce a Module(source: fn) for the fields
2025 * Modules and InternalModules
2026 *)
2027 List.fold_left
2028 (fun acc base_fn ->
2029 match acc with
2030 | `No_sources _ ->
2031 begin
2032 let file_found =
2033 List.fold_left
2034 (fun acc ext ->
2035 if source_file_exists (base_fn^ext) then
2036 (base_fn^ext) :: acc
2037 else
2038 acc)
2039 []
2040 [".ml"; ".mli"; ".mll"; ".mly"]
2041 in
2042 match file_found with
2043 | [] ->
2044 acc
2045 | lst ->
2046 `Sources (base_fn, lst)
2047 end
2048 | `Sources _ ->
2049 acc)
2050 (`No_sources possible_base_fn)
2051 possible_base_fn
2052
2316
2317 let find_module ~ctxt source_file_exists cs bs modul =
2318 match OASISBuildSection.find_module source_file_exists bs modul with
2319 | `Sources _ as res -> res
2320 | `No_sources _ as res ->
2321 OASISMessage.warning
2322 ~ctxt
2323 (f_ "Cannot find source file matching module '%s' in library %s.")
2324 modul cs.cs_name;
2325 OASISMessage.warning
2326 ~ctxt
2327 (f_ "Use InterfacePatterns or ImplementationPatterns to define \
2328 this file with feature %S.")
2329 (OASISFeatures.source_patterns.OASISFeatures.name);
2330 res
20532331
20542332 let source_unix_files ~ctxt (cs, bs, lib) source_file_exists =
20552333 List.fold_left
20562334 (fun acc modul ->
2057 match find_module source_file_exists bs modul with
2058 | `Sources (base_fn, lst) ->
2059 (base_fn, lst) :: acc
2060 | `No_sources _ ->
2061 OASISMessage.warning
2062 ~ctxt
2063 (f_ "Cannot find source file matching \
2064 module '%s' in library %s")
2065 modul cs.cs_name;
2066 acc)
2335 match find_module ~ctxt source_file_exists cs bs modul with
2336 | `Sources (base_fn, lst) -> (base_fn, lst) :: acc
2337 | `No_sources _ -> acc)
20672338 []
20682339 (lib.lib_modules @ lib.lib_internal_modules)
20692340
20702341
20712342 let generated_unix_files
2072 ~ctxt
2073 ~is_native
2074 ~has_native_dynlink
2075 ~ext_lib
2076 ~ext_dll
2077 ~source_file_exists
2078 (cs, bs, lib) =
2343 ~ctxt
2344 ~is_native
2345 ~has_native_dynlink
2346 ~ext_lib
2347 ~ext_dll
2348 ~source_file_exists
2349 (cs, bs, lib) =
20792350
20802351 let find_modules lst ext =
20812352 let find_module modul =
2082 match find_module source_file_exists bs modul with
2083 | `Sources (base_fn, [fn]) when ext <> "cmi"
2084 && Filename.check_suffix fn ".mli" ->
2085 None (* No implementation files for pure interface. *)
2086 | `Sources (base_fn, _) ->
2087 Some [base_fn]
2088 | `No_sources lst ->
2089 OASISMessage.warning
2090 ~ctxt
2091 (f_ "Cannot find source file matching \
2092 module '%s' in library %s")
2093 modul cs.cs_name;
2094 Some lst
2353 match find_module ~ctxt source_file_exists cs bs modul with
2354 | `Sources (_, [fn]) when ext <> "cmi"
2355 && Filename.check_suffix fn ".mli" ->
2356 None (* No implementation files for pure interface. *)
2357 | `Sources (base_fn, _) -> Some [base_fn]
2358 | `No_sources lst -> Some lst
20952359 in
20962360 List.fold_left
20972361 (fun acc nm ->
2098 match find_module nm with
2099 | None -> acc
2100 | Some base_fns ->
2101 List.map (fun base_fn -> base_fn ^"."^ext) base_fns :: acc)
2362 match find_module nm with
2363 | None -> acc
2364 | Some base_fns ->
2365 List.map (fun base_fn -> base_fn ^"."^ext) base_fns :: acc)
21022366 []
21032367 lst
21042368 in
21072371 let cmxs =
21082372 let should_be_built =
21092373 match bs.bs_compiled_object with
2110 | Native -> true
2111 | Best -> is_native
2112 | Byte -> false
2374 | Native -> true
2375 | Best -> is_native
2376 | Byte -> false
21132377 in
2114 if should_be_built then
2115 if lib.lib_pack then
2116 find_modules
2117 [cs.cs_name]
2118 "cmx"
2119 else
2120 find_modules
2121 (lib.lib_modules @ lib.lib_internal_modules)
2122 "cmx"
2378 if should_be_built then
2379 if lib.lib_pack then
2380 find_modules
2381 [cs.cs_name]
2382 "cmx"
21232383 else
2124 []
2384 find_modules
2385 (lib.lib_modules @ lib.lib_internal_modules)
2386 "cmx"
2387 else
2388 []
21252389 in
21262390
21272391 let acc_nopath =
21362400 else [".cmi"; ".cmti"; ".cmt"; ".annot"]
21372401 in
21382402 List.map
2139 begin
2140 List.fold_left
2141 begin fun accu s ->
2403 (List.fold_left
2404 (fun accu s ->
21422405 let dot = String.rindex s '.' in
21432406 let base = String.sub s 0 dot in
2144 List.map ((^) base) sufx @ accu
2145 end
2146 []
2147 end
2407 List.map ((^) base) sufx @ accu)
2408 [])
21482409 (find_modules lib.lib_modules "cmi")
21492410 in
21502411
21672428 [cs.cs_name^".cmxs"] :: acc
21682429 else acc)
21692430 in
2170 [cs.cs_name^".cmxa"] :: [cs.cs_name^ext_lib] :: acc
2431 [cs.cs_name^".cmxa"] :: [cs.cs_name^ext_lib] :: acc
21712432 in
2172 match bs.bs_compiled_object with
2173 | Native ->
2174 byte (native acc_nopath)
2175 | Best when is_native ->
2176 byte (native acc_nopath)
2177 | Byte | Best ->
2178 byte acc_nopath
2433 match bs.bs_compiled_object with
2434 | Native -> byte (native acc_nopath)
2435 | Best when is_native -> byte (native acc_nopath)
2436 | Byte | Best -> byte acc_nopath
21792437 in
21802438
21812439 (* Add C library to be built *)
21822440 let acc_nopath =
2183 if bs.bs_c_sources <> [] then
2184 begin
2185 ["lib"^cs.cs_name^"_stubs"^ext_lib]
2186 ::
2187 ["dll"^cs.cs_name^"_stubs"^ext_dll]
2188 ::
2441 if bs.bs_c_sources <> [] then begin
2442 ["lib"^cs.cs_name^"_stubs"^ext_lib]
2443 ::
2444 if has_native_dynlink then
2445 ["dll"^cs.cs_name^"_stubs"^ext_dll] :: acc_nopath
2446 else
21892447 acc_nopath
2190 end
2191 else
2448 end else begin
21922449 acc_nopath
2193 in
2194
2195 (* All the files generated *)
2196 List.rev_append
2197 (List.rev_map
2198 (List.rev_map
2199 (OASISUnixPath.concat bs.bs_path))
2200 acc_nopath)
2201 (headers @ cmxs)
2450 end
2451 in
2452
2453 (* All the files generated *)
2454 List.rev_append
2455 (List.rev_map
2456 (List.rev_map
2457 (OASISUnixPath.concat bs.bs_path))
2458 acc_nopath)
2459 (headers @ cmxs)
22022460
22032461
22042462 end
22102468 open OASISTypes
22112469 open OASISGettext
22122470
2471
2472 let find_module ~ctxt source_file_exists cs bs modul =
2473 match OASISBuildSection.find_module source_file_exists bs modul with
2474 | `Sources _ as res -> res
2475 | `No_sources _ as res ->
2476 OASISMessage.warning
2477 ~ctxt
2478 (f_ "Cannot find source file matching module '%s' in object %s.")
2479 modul cs.cs_name;
2480 OASISMessage.warning
2481 ~ctxt
2482 (f_ "Use InterfacePatterns or ImplementationPatterns to define \
2483 this file with feature %S.")
2484 (OASISFeatures.source_patterns.OASISFeatures.name);
2485 res
22132486
22142487 let source_unix_files ~ctxt (cs, bs, obj) source_file_exists =
22152488 List.fold_left
22162489 (fun acc modul ->
2217 match OASISLibrary.find_module source_file_exists bs modul with
2218 | `Sources (base_fn, lst) ->
2219 (base_fn, lst) :: acc
2220 | `No_sources _ ->
2221 OASISMessage.warning
2222 ~ctxt
2223 (f_ "Cannot find source file matching \
2224 module '%s' in object %s")
2225 modul cs.cs_name;
2226 acc)
2490 match find_module ~ctxt source_file_exists cs bs modul with
2491 | `Sources (base_fn, lst) -> (base_fn, lst) :: acc
2492 | `No_sources _ -> acc)
22272493 []
22282494 obj.obj_modules
22292495
22302496
22312497 let generated_unix_files
2232 ~ctxt
2233 ~is_native
2234 ~source_file_exists
2235 (cs, bs, obj) =
2498 ~ctxt
2499 ~is_native
2500 ~source_file_exists
2501 (cs, bs, obj) =
22362502
22372503 let find_module ext modul =
2238 match OASISLibrary.find_module source_file_exists bs modul with
2239 | `Sources (base_fn, _) -> [base_fn ^ ext]
2240 | `No_sources lst ->
2241 OASISMessage.warning
2242 ~ctxt
2243 (f_ "Cannot find source file matching \
2244 module '%s' in object %s")
2245 modul cs.cs_name ;
2246 lst
2504 match find_module ~ctxt source_file_exists cs bs modul with
2505 | `Sources (base_fn, _) -> [base_fn ^ ext]
2506 | `No_sources lst -> lst
22472507 in
22482508
22492509 let header, byte, native, c_object, f =
22502510 match obj.obj_modules with
22512511 | [ m ] -> (find_module ".cmi" m,
2252 find_module ".cmo" m,
2253 find_module ".cmx" m,
2254 find_module ".o" m,
2255 fun x -> x)
2512 find_module ".cmo" m,
2513 find_module ".cmx" m,
2514 find_module ".o" m,
2515 fun x -> x)
22562516 | _ -> ([cs.cs_name ^ ".cmi"],
2257 [cs.cs_name ^ ".cmo"],
2258 [cs.cs_name ^ ".cmx"],
2259 [cs.cs_name ^ ".o"],
2260 OASISUnixPath.concat bs.bs_path)
2261 in
2262 List.map (List.map f) (
2263 match bs.bs_compiled_object with
2264 | Native ->
2265 native :: c_object :: byte :: header :: []
2266 | Best when is_native ->
2267 native :: c_object :: byte :: header :: []
2268 | Byte | Best ->
2269 byte :: header :: [])
2517 [cs.cs_name ^ ".cmo"],
2518 [cs.cs_name ^ ".cmx"],
2519 [cs.cs_name ^ ".o"],
2520 OASISUnixPath.concat bs.bs_path)
2521 in
2522 List.map (List.map f) (
2523 match bs.bs_compiled_object with
2524 | Native ->
2525 native :: c_object :: byte :: header :: []
2526 | Best when is_native ->
2527 native :: c_object :: byte :: header :: []
2528 | Byte | Best ->
2529 byte :: header :: [])
22702530
22712531
22722532 end
22782538 open OASISTypes
22792539 open OASISUtils
22802540 open OASISGettext
2281 open OASISSection
22822541
22832542
22842543 type library_name = name
22962555 common_section *
22972556 build_section *
22982557 [`Library of library | `Object of object_] *
2558 unix_dirname option *
22992559 group_t list)
23002560
23012561
23022562 type data = common_section *
2303 build_section *
2304 [`Library of library | `Object of object_]
2563 build_section *
2564 [`Library of library | `Object of object_]
23052565 type tree =
23062566 | Node of (data option) * (tree MapString.t)
23072567 | Leaf of data
23192579 let name =
23202580 String.concat "." (lib.lib_findlib_containers @ [name])
23212581 in
2322 name
2582 name
23232583 in
2324 List.fold_left
2325 (fun mp ->
2326 function
2327 | Library (cs, _, lib) ->
2328 begin
2329 let lib_name = cs.cs_name in
2330 let fndlb_parts = fndlb_parts cs lib in
2331 if MapString.mem lib_name mp then
2332 failwithf
2333 (f_ "The library name '%s' is used more than once.")
2334 lib_name;
2335 match lib.lib_findlib_parent with
2336 | Some lib_name_parent ->
2337 MapString.add
2338 lib_name
2339 (`Unsolved (lib_name_parent, fndlb_parts))
2340 mp
2341 | None ->
2342 MapString.add
2343 lib_name
2344 (`Solved fndlb_parts)
2345 mp
2346 end
2347
2348 | Object (cs, _, obj) ->
2349 begin
2350 let obj_name = cs.cs_name in
2351 if MapString.mem obj_name mp then
2352 failwithf
2353 (f_ "The object name '%s' is used more than once.")
2354 obj_name;
2355 let findlib_full_name = match obj.obj_findlib_fullname with
2356 | Some ns -> String.concat "." ns
2357 | None -> obj_name
2358 in
2584 List.fold_left
2585 (fun mp ->
2586 function
2587 | Library (cs, _, lib) ->
2588 begin
2589 let lib_name = cs.cs_name in
2590 let fndlb_parts = fndlb_parts cs lib in
2591 if MapString.mem lib_name mp then
2592 failwithf
2593 (f_ "The library name '%s' is used more than once.")
2594 lib_name;
2595 match lib.lib_findlib_parent with
2596 | Some lib_name_parent ->
23592597 MapString.add
2360 obj_name
2361 (`Solved findlib_full_name)
2598 lib_name
2599 (`Unsolved (lib_name_parent, fndlb_parts))
23622600 mp
2363 end
2364
2365 | Executable _ | Test _ | Flag _ | SrcRepo _ | Doc _ ->
2366 mp)
2367 MapString.empty
2368 pkg.sections
2601 | None ->
2602 MapString.add
2603 lib_name
2604 (`Solved fndlb_parts)
2605 mp
2606 end
2607
2608 | Object (cs, _, obj) ->
2609 begin
2610 let obj_name = cs.cs_name in
2611 if MapString.mem obj_name mp then
2612 failwithf
2613 (f_ "The object name '%s' is used more than once.")
2614 obj_name;
2615 let findlib_full_name = match obj.obj_findlib_fullname with
2616 | Some ns -> String.concat "." ns
2617 | None -> obj_name
2618 in
2619 MapString.add
2620 obj_name
2621 (`Solved findlib_full_name)
2622 mp
2623 end
2624
2625 | Executable _ | Test _ | Flag _ | SrcRepo _ | Doc _ ->
2626 mp)
2627 MapString.empty
2628 pkg.sections
23692629 in
23702630
23712631 (* Solve the above graph to be only library name to full findlib name. *)
23772637 with regard to findlib naming.")
23782638 lib_name;
23792639 let visited = SetString.add lib_name visited in
2380 try
2381 match MapString.find lib_name mp with
2382 | `Solved fndlb_nm ->
2383 fndlb_nm, mp
2384 | `Unsolved (lib_nm_parent, post_fndlb_nm) ->
2385 let pre_fndlb_nm, mp =
2386 solve visited mp lib_nm_parent lib_name
2387 in
2388 let fndlb_nm = pre_fndlb_nm^"."^post_fndlb_nm in
2389 fndlb_nm, MapString.add lib_name (`Solved fndlb_nm) mp
2390 with Not_found ->
2391 failwithf
2392 (f_ "Library '%s', which is defined as the findlib parent of \
2393 library '%s', doesn't exist.")
2394 lib_name lib_name_child
2640 try
2641 match MapString.find lib_name mp with
2642 | `Solved fndlb_nm ->
2643 fndlb_nm, mp
2644 | `Unsolved (lib_nm_parent, post_fndlb_nm) ->
2645 let pre_fndlb_nm, mp =
2646 solve visited mp lib_nm_parent lib_name
2647 in
2648 let fndlb_nm = pre_fndlb_nm^"."^post_fndlb_nm in
2649 fndlb_nm, MapString.add lib_name (`Solved fndlb_nm) mp
2650 with Not_found ->
2651 failwithf
2652 (f_ "Library '%s', which is defined as the findlib parent of \
2653 library '%s', doesn't exist.")
2654 lib_name lib_name_child
23952655 in
23962656 let mp =
23972657 MapString.fold
23982658 (fun lib_name status mp ->
23992659 match status with
24002660 | `Solved _ ->
2401 (* Solved initialy, no need to go further *)
2402 mp
2661 (* Solved initialy, no need to go further *)
2662 mp
24032663 | `Unsolved _ ->
2404 let _, mp = solve SetString.empty mp lib_name "<none>" in
2405 mp)
2664 let _, mp = solve SetString.empty mp lib_name "<none>" in
2665 mp)
24062666 fndlb_parts_of_lib_name
24072667 fndlb_parts_of_lib_name
24082668 in
2409 MapString.map
2410 (function
2411 | `Solved fndlb_nm -> fndlb_nm
2412 | `Unsolved _ -> assert false)
2413 mp
2669 MapString.map
2670 (function
2671 | `Solved fndlb_nm -> fndlb_nm
2672 | `Unsolved _ -> assert false)
2673 mp
24142674 in
24152675
24162676 (* Convert an internal library name to a findlib name. *)
24222682 in
24232683
24242684 (* Add a library to the tree.
2425 *)
2685 *)
24262686 let add sct mp =
24272687 let fndlb_fullname =
24282688 let cs, _, _ = sct in
24292689 let lib_name = cs.cs_name in
2430 findlib_name_of_library_name lib_name
2690 findlib_name_of_library_name lib_name
24312691 in
24322692 let rec add_children nm_lst (children: tree MapString.t) =
24332693 match nm_lst with
24342694 | (hd :: tl) ->
2435 begin
2436 let node =
2437 try
2438 add_node tl (MapString.find hd children)
2439 with Not_found ->
2440 (* New node *)
2441 new_node tl
2442 in
2443 MapString.add hd node children
2444 end
2695 begin
2696 let node =
2697 try
2698 add_node tl (MapString.find hd children)
2699 with Not_found ->
2700 (* New node *)
2701 new_node tl
2702 in
2703 MapString.add hd node children
2704 end
24452705 | [] ->
2446 (* Should not have a nameless library. *)
2447 assert false
2706 (* Should not have a nameless library. *)
2707 assert false
24482708 and add_node tl node =
24492709 if tl = [] then
24502710 begin
24512711 match node with
24522712 | Node (None, children) ->
2453 Node (Some sct, children)
2713 Node (Some sct, children)
24542714 | Leaf (cs', _, _) | Node (Some (cs', _, _), _) ->
2455 (* TODO: allow to merge Package, i.e.
2456 * archive(byte) = "foo.cma foo_init.cmo"
2457 *)
2458 let cs, _, _ = sct in
2459 failwithf
2460 (f_ "Library '%s' and '%s' have the same findlib name '%s'")
2461 cs.cs_name cs'.cs_name fndlb_fullname
2715 (* TODO: allow to merge Package, i.e.
2716 * archive(byte) = "foo.cma foo_init.cmo"
2717 *)
2718 let cs, _, _ = sct in
2719 failwithf
2720 (f_ "Library '%s' and '%s' have the same findlib name '%s'")
2721 cs.cs_name cs'.cs_name fndlb_fullname
24622722 end
24632723 else
24642724 begin
24652725 match node with
24662726 | Leaf data ->
2467 Node (Some data, add_children tl MapString.empty)
2727 Node (Some data, add_children tl MapString.empty)
24682728 | Node (data_opt, children) ->
2469 Node (data_opt, add_children tl children)
2729 Node (data_opt, add_children tl children)
24702730 end
24712731 and new_node =
24722732 function
24732733 | [] ->
2474 Leaf sct
2734 Leaf sct
24752735 | hd :: tl ->
2476 Node (None, MapString.add hd (new_node tl) MapString.empty)
2736 Node (None, MapString.add hd (new_node tl) MapString.empty)
24772737 in
2478 add_children (OASISString.nsplit fndlb_fullname '.') mp
2479 in
2480
2481 let rec group_of_tree mp =
2738 add_children (OASISString.nsplit fndlb_fullname '.') mp
2739 in
2740
2741 let unix_directory dn lib =
2742 let directory =
2743 match lib with
2744 | `Library lib -> lib.lib_findlib_directory
2745 | `Object obj -> obj.obj_findlib_directory
2746 in
2747 match dn, directory with
2748 | None, None -> None
2749 | None, Some dn | Some dn, None -> Some dn
2750 | Some dn1, Some dn2 -> Some (OASISUnixPath.concat dn1 dn2)
2751 in
2752
2753 let rec group_of_tree dn mp =
24822754 MapString.fold
24832755 (fun nm node acc ->
24842756 let cur =
24852757 match node with
2486 | Node (Some (cs, bs, lib), children) ->
2487 Package (nm, cs, bs, lib, group_of_tree children)
2488 | Node (None, children) ->
2489 Container (nm, group_of_tree children)
2490 | Leaf (cs, bs, lib) ->
2491 Package (nm, cs, bs, lib, [])
2758 | Node (Some (cs, bs, lib), children) ->
2759 let current_dn = unix_directory dn lib in
2760 Package (nm, cs, bs, lib, current_dn, group_of_tree current_dn children)
2761 | Node (None, children) ->
2762 Container (nm, group_of_tree dn children)
2763 | Leaf (cs, bs, lib) ->
2764 let current_dn = unix_directory dn lib in
2765 Package (nm, cs, bs, lib, current_dn, [])
24922766 in
2493 cur :: acc)
2767 cur :: acc)
24942768 mp []
24952769 in
24962770
24992773 (fun mp ->
25002774 function
25012775 | Library (cs, bs, lib) ->
2502 add (cs, bs, `Library lib) mp
2776 add (cs, bs, `Library lib) mp
25032777 | Object (cs, bs, obj) ->
2504 add (cs, bs, `Object obj) mp
2778 add (cs, bs, `Object obj) mp
25052779 | _ ->
2506 mp)
2780 mp)
25072781 MapString.empty
25082782 pkg.sections
25092783 in
25102784
2511 let groups =
2512 group_of_tree group_mp
2513 in
2785 let groups = group_of_tree None group_mp in
25142786
25152787 let library_name_of_findlib_name =
25162788 lazy begin
25282800 raise (FindlibPackageNotFound fndlb_nm)
25292801 in
25302802
2531 groups,
2532 findlib_name_of_library_name,
2533 library_name_of_findlib_name
2803 groups,
2804 findlib_name_of_library_name,
2805 library_name_of_findlib_name
25342806
25352807
25362808 let findlib_of_group =
25372809 function
25382810 | Container (fndlb_nm, _)
2539 | Package (fndlb_nm, _, _, _, _) -> fndlb_nm
2811 | Package (fndlb_nm, _, _, _, _, _) -> fndlb_nm
25402812
25412813
25422814 let root_of_group grp =
25442816 (* We do a DFS in the group. *)
25452817 function
25462818 | Container (_, children) ->
2547 List.fold_left
2548 (fun res grp ->
2549 if res = None then
2550 root_lib_aux grp
2551 else
2552 res)
2553 None
2554 children
2555 | Package (_, cs, bs, lib, _) ->
2556 Some (cs, bs, lib)
2557 in
2558 match root_lib_aux grp with
2559 | Some res ->
2560 res
2561 | None ->
2562 failwithf
2563 (f_ "Unable to determine root library of findlib library '%s'")
2564 (findlib_of_group grp)
2819 List.fold_left
2820 (fun res grp ->
2821 if res = None then
2822 root_lib_aux grp
2823 else
2824 res)
2825 None
2826 children
2827 | Package (_, cs, bs, lib, _, _) ->
2828 Some (cs, bs, lib)
2829 in
2830 match root_lib_aux grp with
2831 | Some res ->
2832 res
2833 | None ->
2834 failwithf
2835 (f_ "Unable to determine root library of findlib library '%s'")
2836 (findlib_of_group grp)
25652837
25662838
25672839 end
26072879
26082880 (* TODO: I don't like this quote, it is there because $(rm) foo expands to
26092881 * 'rm -f' foo...
2610 *)
2882 *)
26112883 let run ~ctxt ?f_exit_code ?(quote=true) cmd args =
26122884 let cmd =
26132885 if quote then
26252897 let cmdline =
26262898 String.concat " " (cmd :: args)
26272899 in
2628 info ~ctxt (f_ "Running command '%s'") cmdline;
2629 match f_exit_code, Sys.command cmdline with
2630 | None, 0 -> ()
2631 | None, i ->
2632 failwithf
2633 (f_ "Command '%s' terminated with error code %d")
2634 cmdline i
2635 | Some f, i ->
2636 f i
2900 info ~ctxt (f_ "Running command '%s'") cmdline;
2901 match f_exit_code, Sys.command cmdline with
2902 | None, 0 -> ()
2903 | None, i ->
2904 failwithf
2905 (f_ "Command '%s' terminated with error code %d")
2906 cmdline i
2907 | Some f, i ->
2908 f i
26372909
26382910
26392911 let run_read_output ~ctxt ?f_exit_code cmd args =
26402912 let fn =
26412913 Filename.temp_file "oasis-" ".txt"
26422914 in
2643 try
2915 try
2916 begin
2917 let () =
2918 run ~ctxt ?f_exit_code cmd (args @ [">"; Filename.quote fn])
2919 in
2920 let chn =
2921 open_in fn
2922 in
2923 let routput =
2924 ref []
2925 in
26442926 begin
2645 let () =
2646 run ~ctxt ?f_exit_code cmd (args @ [">"; Filename.quote fn])
2647 in
2648 let chn =
2649 open_in fn
2650 in
2651 let routput =
2652 ref []
2653 in
2654 begin
2655 try
2656 while true do
2657 routput := (input_line chn) :: !routput
2658 done
2659 with End_of_file ->
2660 ()
2661 end;
2662 close_in chn;
2663 Sys.remove fn;
2664 List.rev !routput
2665 end
2666 with e ->
2667 (try Sys.remove fn with _ -> ());
2668 raise e
2927 try
2928 while true do
2929 routput := (input_line chn) :: !routput
2930 done
2931 with End_of_file ->
2932 ()
2933 end;
2934 close_in chn;
2935 Sys.remove fn;
2936 List.rev !routput
2937 end
2938 with e ->
2939 (try Sys.remove fn with _ -> ());
2940 raise e
26692941
26702942
26712943 let run_read_one_line ~ctxt ?f_exit_code cmd args =
26722944 match run_read_output ~ctxt ?f_exit_code cmd args with
26732945 | [fst] ->
2674 fst
2946 fst
26752947 | lst ->
2676 failwithf
2677 (f_ "Command return unexpected output %S")
2678 (String.concat "\n" lst)
2948 failwithf
2949 (f_ "Command return unexpected output %S")
2950 (String.concat "\n" lst)
26792951 end
26802952
26812953 module OASISFileUtil = struct
26882960 let file_exists_case fn =
26892961 let dirname = Filename.dirname fn in
26902962 let basename = Filename.basename fn in
2691 if Sys.file_exists dirname then
2692 if basename = Filename.current_dir_name then
2693 true
2694 else
2695 List.mem
2696 basename
2697 (Array.to_list (Sys.readdir dirname))
2963 if Sys.file_exists dirname then
2964 if basename = Filename.current_dir_name then
2965 true
26982966 else
2699 false
2967 List.mem
2968 basename
2969 (Array.to_list (Sys.readdir dirname))
2970 else
2971 false
27002972
27012973
27022974 let find_file ?(case_sensitive=true) paths exts =
27152987 let rec combined_paths lst =
27162988 match lst with
27172989 | p1 :: p2 :: tl ->
2718 let acc =
2719 (List.map
2720 (fun (a, b) -> Filename.concat a b)
2721 (p1 * p2))
2722 in
2723 combined_paths (acc :: tl)
2990 let acc =
2991 (List.map
2992 (fun (a, b) -> Filename.concat a b)
2993 (p1 * p2))
2994 in
2995 combined_paths (acc :: tl)
27242996 | [e] ->
2725 e
2997 e
27262998 | [] ->
2727 []
2999 []
27283000 in
27293001
27303002 let alternatives =
27363008 p ^ e)
27373009 ((combined_paths paths) * exts)
27383010 in
2739 List.find (fun file ->
2740 (if case_sensitive then
2741 file_exists_case file
2742 else
2743 Sys.file_exists file)
2744 && not (Sys.is_directory file)
2745 ) alternatives
3011 List.find (fun file ->
3012 (if case_sensitive then
3013 file_exists_case file
3014 else
3015 Sys.file_exists file)
3016 && not (Sys.is_directory file)
3017 ) alternatives
27463018
27473019
27483020 let which ~ctxt prg =
27493021 let path_sep =
27503022 match Sys.os_type with
27513023 | "Win32" ->
2752 ';'
3024 ';'
27533025 | _ ->
2754 ':'
3026 ':'
27553027 in
27563028 let path_lst = OASISString.nsplit (Sys.getenv "PATH") path_sep in
27573029 let exec_ext =
27583030 match Sys.os_type with
27593031 | "Win32" ->
2760 "" :: (OASISString.nsplit (Sys.getenv "PATHEXT") path_sep)
3032 "" :: (OASISString.nsplit (Sys.getenv "PATHEXT") path_sep)
27613033 | _ ->
2762 [""]
2763 in
2764 find_file ~case_sensitive:false [path_lst; [prg]] exec_ext
3034 [""]
3035 in
3036 find_file ~case_sensitive:false [path_lst; [prg]] exec_ext
27653037
27663038
27673039 (**/**)
27683040 let rec fix_dir dn =
27693041 (* Windows hack because Sys.file_exists "src\\" = false when
27703042 * Sys.file_exists "src" = true
2771 *)
3043 *)
27723044 let ln =
27733045 String.length dn
27743046 in
2775 if Sys.os_type = "Win32" && ln > 0 && dn.[ln - 1] = '\\' then
2776 fix_dir (String.sub dn 0 (ln - 1))
2777 else
2778 dn
3047 if Sys.os_type = "Win32" && ln > 0 && dn.[ln - 1] = '\\' then
3048 fix_dir (String.sub dn 0 (ln - 1))
3049 else
3050 dn
27793051
27803052
27813053 let q = Filename.quote
27863058 if recurse then
27873059 match Sys.os_type with
27883060 | "Win32" ->
2789 OASISExec.run ~ctxt
2790 "xcopy" [q src; q tgt; "/E"]
3061 OASISExec.run ~ctxt
3062 "xcopy" [q src; q tgt; "/E"]
27913063 | _ ->
2792 OASISExec.run ~ctxt
2793 "cp" ["-r"; q src; q tgt]
3064 OASISExec.run ~ctxt
3065 "cp" ["-r"; q src; q tgt]
27943066 else
27953067 OASISExec.run ~ctxt
27963068 (match Sys.os_type with
2797 | "Win32" -> "copy"
2798 | _ -> "cp")
3069 | "Win32" -> "copy"
3070 | _ -> "cp")
27993071 [q src; q tgt]
28003072
28013073
28023074 let mkdir ~ctxt tgt =
28033075 OASISExec.run ~ctxt
28043076 (match Sys.os_type with
2805 | "Win32" -> "md"
2806 | _ -> "mkdir")
3077 | "Win32" -> "md"
3078 | _ -> "mkdir")
28073079 [q tgt]
28083080
28093081
28113083 let tgt =
28123084 fix_dir tgt
28133085 in
2814 if Sys.file_exists tgt then
2815 begin
2816 if not (Sys.is_directory tgt) then
2817 OASISUtils.failwithf
2818 (f_ "Cannot create directory '%s', a file of the same name already \
2819 exists")
2820 tgt
2821 end
2822 else
2823 begin
2824 mkdir_parent ~ctxt f (Filename.dirname tgt);
2825 if not (Sys.file_exists tgt) then
2826 begin
2827 f tgt;
2828 mkdir ~ctxt tgt
2829 end
2830 end
3086 if Sys.file_exists tgt then
3087 begin
3088 if not (Sys.is_directory tgt) then
3089 OASISUtils.failwithf
3090 (f_ "Cannot create directory '%s', a file of the same name already \
3091 exists")
3092 tgt
3093 end
3094 else
3095 begin
3096 mkdir_parent ~ctxt f (Filename.dirname tgt);
3097 if not (Sys.file_exists tgt) then
3098 begin
3099 f tgt;
3100 mkdir ~ctxt tgt
3101 end
3102 end
28313103
28323104
28333105 let rmdir ~ctxt tgt =
28343106 if Sys.readdir tgt = [||] then begin
28353107 match Sys.os_type with
28363108 | "Win32" ->
2837 OASISExec.run ~ctxt "rd" [q tgt]
3109 OASISExec.run ~ctxt "rd" [q tgt]
28383110 | _ ->
2839 OASISExec.run ~ctxt "rm" ["-r"; q tgt]
3111 OASISExec.run ~ctxt "rm" ["-r"; q tgt]
28403112 end else begin
28413113 OASISMessage.error ~ctxt
28423114 (f_ "Cannot remove directory '%s': not empty.")
28453117
28463118
28473119 let glob ~ctxt fn =
2848 let basename =
2849 Filename.basename fn
2850 in
2851 if String.length basename >= 2 &&
2852 basename.[0] = '*' &&
2853 basename.[1] = '.' then
2854 begin
2855 let ext_len =
2856 (String.length basename) - 2
2857 in
2858 let ext =
2859 String.sub basename 2 ext_len
2860 in
2861 let dirname =
2862 Filename.dirname fn
2863 in
2864 Array.fold_left
2865 (fun acc fn ->
2866 try
2867 let fn_ext =
2868 String.sub
2869 fn
2870 ((String.length fn) - ext_len)
2871 ext_len
2872 in
2873 if fn_ext = ext then
2874 (Filename.concat dirname fn) :: acc
2875 else
2876 acc
2877 with Invalid_argument _ ->
2878 acc)
2879 []
2880 (Sys.readdir dirname)
2881 end
2882 else
2883 begin
2884 if file_exists_case fn then
2885 [fn]
2886 else
2887 []
2888 end
2889 end
2890
2891
2892 # 2893 "setup.ml"
2893 module BaseEnvLight = struct
2894 (* # 22 "src/base/BaseEnvLight.ml" *)
2895
2896
2897 module MapString = Map.Make(String)
2898
2899
2900 type t = string MapString.t
2901
2902
2903 let default_filename =
2904 Filename.concat
2905 (Sys.getcwd ())
2906 "setup.data"
2907
2908
2909 let load ?(allow_empty=false) ?(filename=default_filename) () =
2910 if Sys.file_exists filename then
3120 let basename =
3121 Filename.basename fn
3122 in
3123 if String.length basename >= 2 &&
3124 basename.[0] = '*' &&
3125 basename.[1] = '.' then
29113126 begin
2912 let chn =
2913 open_in_bin filename
3127 let ext_len =
3128 (String.length basename) - 2
29143129 in
2915 let st =
2916 Stream.of_channel chn
3130 let ext =
3131 String.sub basename 2 ext_len
29173132 in
2918 let line =
2919 ref 1
3133 let dirname =
3134 Filename.dirname fn
29203135 in
2921 let st_line =
2922 Stream.from
2923 (fun _ ->
2924 try
2925 match Stream.next st with
2926 | '\n' -> incr line; Some '\n'
2927 | c -> Some c
2928 with Stream.Failure -> None)
2929 in
2930 let lexer =
2931 Genlex.make_lexer ["="] st_line
2932 in
2933 let rec read_file mp =
2934 match Stream.npeek 3 lexer with
2935 | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
2936 Stream.junk lexer;
2937 Stream.junk lexer;
2938 Stream.junk lexer;
2939 read_file (MapString.add nm value mp)
2940 | [] ->
2941 mp
2942 | _ ->
2943 failwith
2944 (Printf.sprintf
2945 "Malformed data file '%s' line %d"
2946 filename !line)
2947 in
2948 let mp =
2949 read_file MapString.empty
2950 in
2951 close_in chn;
2952 mp
2953 end
2954 else if allow_empty then
2955 begin
2956 MapString.empty
3136 Array.fold_left
3137 (fun acc fn ->
3138 try
3139 let fn_ext =
3140 String.sub
3141 fn
3142 ((String.length fn) - ext_len)
3143 ext_len
3144 in
3145 if fn_ext = ext then
3146 (Filename.concat dirname fn) :: acc
3147 else
3148 acc
3149 with Invalid_argument _ ->
3150 acc)
3151 []
3152 (Sys.readdir dirname)
29573153 end
29583154 else
29593155 begin
3156 if file_exists_case fn then
3157 [fn]
3158 else
3159 []
3160 end
3161 end
3162
3163
3164 # 3165 "setup.ml"
3165 module BaseEnvLight = struct
3166 (* # 22 "src/base/BaseEnvLight.ml" *)
3167
3168
3169 module MapString = Map.Make(String)
3170
3171
3172 type t = string MapString.t
3173
3174
3175 let default_filename = Filename.concat (Sys.getcwd ()) "setup.data"
3176
3177
3178 let load ?(allow_empty=false) ?(filename=default_filename) ?stream () =
3179 let line = ref 1 in
3180 let lexer st =
3181 let st_line =
3182 Stream.from
3183 (fun _ ->
3184 try
3185 match Stream.next st with
3186 | '\n' -> incr line; Some '\n'
3187 | c -> Some c
3188 with Stream.Failure -> None)
3189 in
3190 Genlex.make_lexer ["="] st_line
3191 in
3192 let rec read_file lxr mp =
3193 match Stream.npeek 3 lxr with
3194 | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
3195 Stream.junk lxr; Stream.junk lxr; Stream.junk lxr;
3196 read_file lxr (MapString.add nm value mp)
3197 | [] -> mp
3198 | _ ->
3199 failwith
3200 (Printf.sprintf "Malformed data file '%s' line %d" filename !line)
3201 in
3202 match stream with
3203 | Some st -> read_file (lexer st) MapString.empty
3204 | None ->
3205 if Sys.file_exists filename then begin
3206 let chn = open_in_bin filename in
3207 let st = Stream.of_channel chn in
3208 try
3209 let mp = read_file (lexer st) MapString.empty in
3210 close_in chn; mp
3211 with e ->
3212 close_in chn; raise e
3213 end else if allow_empty then begin
3214 MapString.empty
3215 end else begin
29603216 failwith
29613217 (Printf.sprintf
29623218 "Unable to load environment, the file '%s' doesn't exist."
29633219 filename)
29643220 end
29653221
2966
29673222 let rec var_expand str env =
2968 let buff =
2969 Buffer.create ((String.length str) * 2)
2970 in
2971 Buffer.add_substitute
2972 buff
2973 (fun var ->
2974 try
2975 var_expand (MapString.find var env) env
2976 with Not_found ->
2977 failwith
2978 (Printf.sprintf
2979 "No variable %s defined when trying to expand %S."
2980 var
2981 str))
2982 str;
2983 Buffer.contents buff
2984
2985
2986 let var_get name env =
2987 var_expand (MapString.find name env) env
2988
2989
2990 let var_choose lst env =
2991 OASISExpr.choose
2992 (fun nm -> var_get nm env)
2993 lst
3223 let buff = Buffer.create ((String.length str) * 2) in
3224 Buffer.add_substitute
3225 buff
3226 (fun var ->
3227 try
3228 var_expand (MapString.find var env) env
3229 with Not_found ->
3230 failwith
3231 (Printf.sprintf
3232 "No variable %s defined when trying to expand %S."
3233 var
3234 str))
3235 str;
3236 Buffer.contents buff
3237
3238
3239 let var_get name env = var_expand (MapString.find name env) env
3240 let var_choose lst env = OASISExpr.choose (fun nm -> var_get nm env) lst
29943241 end
29953242
29963243
2997 # 2998 "setup.ml"
3244 # 3245 "setup.ml"
29983245 module BaseContext = struct
29993246 (* # 22 "src/base/BaseContext.ml" *)
30003247
30153262
30163263 (** Message to user, overrid for Base
30173264 @author Sylvain Le Gall
3018 *)
3265 *)
30193266 open OASISMessage
30203267 open BaseContext
30213268
30383285
30393286 open OASISGettext
30403287 open OASISUtils
3288 open OASISContext
30413289 open PropList
30423290
30433291
30603308
30613309
30623310 type definition_t =
3063 {
3064 hide: bool;
3065 dump: bool;
3066 cli: cli_handle_t;
3067 arg_help: string option;
3068 group: string option;
3069 }
3070
3071
3072 let schema =
3073 Schema.create "environment"
3311 {
3312 hide: bool;
3313 dump: bool;
3314 cli: cli_handle_t;
3315 arg_help: string option;
3316 group: string option;
3317 }
3318
3319
3320 let schema = Schema.create "environment"
30743321
30753322
30763323 (* Environment data *)
3077 let env =
3078 Data.create ()
3324 let env = Data.create ()
30793325
30803326
30813327 (* Environment data from file *)
3082 let env_from_file =
3083 ref MapString.empty
3328 let env_from_file = ref MapString.empty
30843329
30853330
30863331 (* Lexer for var *)
3087 let var_lxr =
3088 Genlex.make_lexer []
3332 let var_lxr = Genlex.make_lexer []
30893333
30903334
30913335 let rec var_expand str =
30923336 let buff =
30933337 Buffer.create ((String.length str) * 2)
30943338 in
3095 Buffer.add_substitute
3096 buff
3097 (fun var ->
3098 try
3099 (* TODO: this is a quick hack to allow calling Test.Command
3100 * without defining executable name really. I.e. if there is
3101 * an exec Executable toto, then $(toto) should be replace
3102 * by its real name. It is however useful to have this function
3103 * for other variable that depend on the host and should be
3104 * written better than that.
3105 *)
3106 let st =
3107 var_lxr (Stream.of_string var)
3108 in
3109 match Stream.npeek 3 st with
3110 | [Genlex.Ident "utoh"; Genlex.Ident nm] ->
3111 OASISHostPath.of_unix (var_get nm)
3112 | [Genlex.Ident "utoh"; Genlex.String s] ->
3113 OASISHostPath.of_unix s
3114 | [Genlex.Ident "ocaml_escaped"; Genlex.Ident nm] ->
3115 String.escaped (var_get nm)
3116 | [Genlex.Ident "ocaml_escaped"; Genlex.String s] ->
3117 String.escaped s
3118 | [Genlex.Ident nm] ->
3119 var_get nm
3120 | _ ->
3121 failwithf
3122 (f_ "Unknown expression '%s' in variable expansion of %s.")
3123 var
3124 str
3125 with
3126 | Unknown_field (_, _) ->
3127 failwithf
3128 (f_ "No variable %s defined when trying to expand %S.")
3129 var
3130 str
3131 | Stream.Error e ->
3132 failwithf
3133 (f_ "Syntax error when parsing '%s' when trying to \
3134 expand %S: %s")
3135 var
3136 str
3137 e)
3138 str;
3139 Buffer.contents buff
3339 Buffer.add_substitute
3340 buff
3341 (fun var ->
3342 try
3343 (* TODO: this is a quick hack to allow calling Test.Command
3344 * without defining executable name really. I.e. if there is
3345 * an exec Executable toto, then $(toto) should be replace
3346 * by its real name. It is however useful to have this function
3347 * for other variable that depend on the host and should be
3348 * written better than that.
3349 *)
3350 let st =
3351 var_lxr (Stream.of_string var)
3352 in
3353 match Stream.npeek 3 st with
3354 | [Genlex.Ident "utoh"; Genlex.Ident nm] ->
3355 OASISHostPath.of_unix (var_get nm)
3356 | [Genlex.Ident "utoh"; Genlex.String s] ->
3357 OASISHostPath.of_unix s
3358 | [Genlex.Ident "ocaml_escaped"; Genlex.Ident nm] ->
3359 String.escaped (var_get nm)
3360 | [Genlex.Ident "ocaml_escaped"; Genlex.String s] ->
3361 String.escaped s
3362 | [Genlex.Ident nm] ->
3363 var_get nm
3364 | _ ->
3365 failwithf
3366 (f_ "Unknown expression '%s' in variable expansion of %s.")
3367 var
3368 str
3369 with
3370 | Unknown_field (_, _) ->
3371 failwithf
3372 (f_ "No variable %s defined when trying to expand %S.")
3373 var
3374 str
3375 | Stream.Error e ->
3376 failwithf
3377 (f_ "Syntax error when parsing '%s' when trying to \
3378 expand %S: %s")
3379 var
3380 str
3381 e)
3382 str;
3383 Buffer.contents buff
31403384
31413385
31423386 and var_get name =
31513395 raise e
31523396 end
31533397 in
3154 var_expand vl
3398 var_expand vl
31553399
31563400
31573401 let var_choose ?printer ?name lst =
31663410 let buff =
31673411 Buffer.create (String.length vl)
31683412 in
3169 String.iter
3170 (function
3171 | '$' -> Buffer.add_string buff "\\$"
3172 | c -> Buffer.add_char buff c)
3173 vl;
3174 Buffer.contents buff
3413 String.iter
3414 (function
3415 | '$' -> Buffer.add_string buff "\\$"
3416 | c -> Buffer.add_char buff c)
3417 vl;
3418 Buffer.contents buff
31753419
31763420
31773421 let var_define
3178 ?(hide=false)
3179 ?(dump=true)
3180 ?short_desc
3181 ?(cli=CLINone)
3182 ?arg_help
3183 ?group
3184 name (* TODO: type constraint on the fact that name must be a valid OCaml
3185 id *)
3186 dflt =
3422 ?(hide=false)
3423 ?(dump=true)
3424 ?short_desc
3425 ?(cli=CLINone)
3426 ?arg_help
3427 ?group
3428 name (* TODO: type constraint on the fact that name must be a valid OCaml
3429 id *)
3430 dflt =
31873431
31883432 let default =
31893433 [
32043448 in
32053449
32063450 (* Try to find a value that can be defined
3207 *)
3451 *)
32083452 let var_get_low lst =
32093453 let errors, res =
32103454 List.fold_left
3211 (fun (errors, res) (o, v) ->
3455 (fun (errors, res) (_, v) ->
32123456 if res = None then
32133457 begin
32143458 try
32153459 errors, Some (v ())
32163460 with
32173461 | Not_found ->
3218 errors, res
3462 errors, res
32193463 | Failure rsn ->
3220 (rsn :: errors), res
3464 (rsn :: errors), res
32213465 | e ->
3222 (Printexc.to_string e) :: errors, res
3466 (Printexc.to_string e) :: errors, res
32233467 end
32243468 else
32253469 errors, res)
32293473 Pervasives.compare o2 o1)
32303474 lst)
32313475 in
3232 match res, errors with
3233 | Some v, _ ->
3234 v
3235 | None, [] ->
3236 raise (Not_set (name, None))
3237 | None, lst ->
3238 raise (Not_set (name, Some (String.concat (s_ ", ") lst)))
3476 match res, errors with
3477 | Some v, _ ->
3478 v
3479 | None, [] ->
3480 raise (Not_set (name, None))
3481 | None, lst ->
3482 raise (Not_set (name, Some (String.concat (s_ ", ") lst)))
32393483 in
32403484
32413485 let help =
32513495 ~parse:(fun ?(context=ODefault) s -> [context, fun () -> s])
32523496 ~print:var_get_low
32533497 ~default
3254 ~update:(fun ?context x old_x -> x @ old_x)
3498 ~update:(fun ?context:_ x old_x -> x @ old_x)
32553499 ?help
32563500 extra
32573501 in
32583502
3259 fun () ->
3260 var_expand (var_get_low (var_get_lst env))
3503 fun () ->
3504 var_expand (var_get_low (var_get_lst env))
32613505
32623506
32633507 let var_redefine
3264 ?hide
3265 ?dump
3266 ?short_desc
3267 ?cli
3268 ?arg_help
3269 ?group
3270 name
3271 dflt =
3508 ?hide
3509 ?dump
3510 ?short_desc
3511 ?cli
3512 ?arg_help
3513 ?group
3514 name
3515 dflt =
32723516 if Schema.mem schema name then
32733517 begin
32743518 (* TODO: look suspsicious, we want to memorize dflt not dflt () *)
32893533 end
32903534
32913535
3292 let var_ignore (e: unit -> string) = ()
3536 let var_ignore (_: unit -> string) = ()
32933537
32943538
32953539 let print_hidden =
33143558 schema)
33153559
33163560
3317 let default_filename =
3318 BaseEnvLight.default_filename
3319
3320
3321 let load ?allow_empty ?filename () =
3322 env_from_file := BaseEnvLight.load ?allow_empty ?filename ()
3561 let default_filename = in_srcdir "setup.data"
3562
3563
3564 let load ~ctxt ?(allow_empty=false) ?(filename=default_filename) () =
3565 let open OASISFileSystem in
3566 env_from_file :=
3567 let repr_filename = ctxt.srcfs#string_of_filename filename in
3568 if ctxt.srcfs#file_exists filename then begin
3569 let buf = Buffer.create 13 in
3570 defer_close
3571 (ctxt.srcfs#open_in ~mode:binary_in filename)
3572 (read_all buf);
3573 defer_close
3574 (ctxt.srcfs#open_in ~mode:binary_in filename)
3575 (fun rdr ->
3576 OASISMessage.info ~ctxt "Loading environment from %S." repr_filename;
3577 BaseEnvLight.load ~allow_empty
3578 ~filename:(repr_filename)
3579 ~stream:(stream_of_reader rdr)
3580 ())
3581 end else if allow_empty then begin
3582 BaseEnvLight.MapString.empty
3583 end else begin
3584 failwith
3585 (Printf.sprintf
3586 (f_ "Unable to load environment, the file '%s' doesn't exist.")
3587 repr_filename)
3588 end
33233589
33243590
33253591 let unload () =
33273593 Data.clear env
33283594
33293595
3330 let dump ?(filename=default_filename) () =
3331 let chn =
3332 open_out_bin filename
3333 in
3334 let output nm value =
3335 Printf.fprintf chn "%s=%S\n" nm value
3336 in
3337 let mp_todo =
3338 (* Dump data from schema *)
3339 Schema.fold
3340 (fun mp_todo nm def _ ->
3341 if def.dump then
3342 begin
3343 try
3344 let value =
3345 Schema.get
3346 schema
3347 env
3348 nm
3349 in
3350 output nm value
3351 with Not_set _ ->
3352 ()
3353 end;
3354 MapString.remove nm mp_todo)
3355 !env_from_file
3356 schema
3357 in
3358 (* Dump data defined outside of schema *)
3359 MapString.iter output mp_todo;
3360
3361 (* End of the dump *)
3362 close_out chn
3363
3596 let dump ~ctxt ?(filename=default_filename) () =
3597 let open OASISFileSystem in
3598 defer_close
3599 (ctxt.OASISContext.srcfs#open_out ~mode:binary_out filename)
3600 (fun wrtr ->
3601 let buf = Buffer.create 63 in
3602 let output nm value =
3603 Buffer.add_string buf (Printf.sprintf "%s=%S\n" nm value)
3604 in
3605 let mp_todo =
3606 (* Dump data from schema *)
3607 Schema.fold
3608 (fun mp_todo nm def _ ->
3609 if def.dump then begin
3610 try
3611 output nm (Schema.get schema env nm)
3612 with Not_set _ ->
3613 ()
3614 end;
3615 MapString.remove nm mp_todo)
3616 !env_from_file
3617 schema
3618 in
3619 (* Dump data defined outside of schema *)
3620 MapString.iter output mp_todo;
3621 wrtr#output buf)
33643622
33653623 let print () =
33663624 let printable_vars =
33693627 if not def.hide || bool_of_string (print_hidden ()) then
33703628 begin
33713629 try
3372 let value =
3373 Schema.get
3374 schema
3375 env
3376 nm
3377 in
3630 let value = Schema.get schema env nm in
33783631 let txt =
33793632 match short_descr_opt with
33803633 | Some s -> s ()
33813634 | None -> nm
33823635 in
3383 (txt, value) :: acc
3636 (txt, value) :: acc
33843637 with Not_set _ ->
3385 acc
3638 acc
33863639 end
33873640 else
33883641 acc)
33943647 (List.rev_map String.length
33953648 (List.rev_map fst printable_vars))
33963649 in
3397 let dot_pad str =
3398 String.make ((max_length - (String.length str)) + 3) '.'
3399 in
3400
3401 Printf.printf "\nConfiguration: \n";
3650 let dot_pad str = String.make ((max_length - (String.length str)) + 3) '.' in
3651 Printf.printf "\nConfiguration:\n";
34023652 List.iter
34033653 (fun (name, value) ->
3404 Printf.printf "%s: %s %s\n" name (dot_pad name) value)
3654 Printf.printf "%s: %s" name (dot_pad name);
3655 if value = "" then
3656 Printf.printf "\n"
3657 else
3658 Printf.printf " %s\n" value)
34053659 (List.rev printable_vars);
34063660 Printf.printf "\n%!"
34073661
34083662
34093663 let args () =
3410 let arg_concat =
3411 OASISUtils.varname_concat ~hyphen:'-'
3412 in
3413 [
3414 "--override",
3415 Arg.Tuple
3416 (
3417 let rvr = ref ""
3418 in
3419 let rvl = ref ""
3420 in
3421 [
3422 Arg.Set_string rvr;
3423 Arg.Set_string rvl;
3424 Arg.Unit
3425 (fun () ->
3426 Schema.set
3427 schema
3428 env
3429 ~context:OCommandLine
3430 !rvr
3431 !rvl)
3432 ]
3433 ),
3434 "var+val Override any configuration variable.";
3435
3436 ]
3437 @
3664 let arg_concat = OASISUtils.varname_concat ~hyphen:'-' in
3665 [
3666 "--override",
3667 Arg.Tuple
3668 (
3669 let rvr = ref ""
3670 in
3671 let rvl = ref ""
3672 in
3673 [
3674 Arg.Set_string rvr;
3675 Arg.Set_string rvl;
3676 Arg.Unit
3677 (fun () ->
3678 Schema.set
3679 schema
3680 env
3681 ~context:OCommandLine
3682 !rvr
3683 !rvl)
3684 ]
3685 ),
3686 "var+val Override any configuration variable.";
3687
3688 ]
3689 @
34383690 List.flatten
34393691 (Schema.fold
3440 (fun acc name def short_descr_opt ->
3441 let var_set s =
3442 Schema.set
3443 schema
3444 env
3445 ~context:OCommandLine
3446 name
3447 s
3448 in
3449
3450 let arg_name =
3451 OASISUtils.varname_of_string ~hyphen:'-' name
3452 in
3453
3454 let hlp =
3455 match short_descr_opt with
3456 | Some txt -> txt ()
3457 | None -> ""
3458 in
3459
3460 let arg_hlp =
3461 match def.arg_help with
3462 | Some s -> s
3463 | None -> "str"
3464 in
3465
3466 let default_value =
3467 try
3468 Printf.sprintf
3469 (f_ " [%s]")
3470 (Schema.get
3471 schema
3472 env
3473 name)
3474 with Not_set _ ->
3475 ""
3476 in
3477
3478 let args =
3479 match def.cli with
3480 | CLINone ->
3481 []
3482 | CLIAuto ->
3483 [
3484 arg_concat "--" arg_name,
3485 Arg.String var_set,
3486 Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value
3487 ]
3488 | CLIWith ->
3489 [
3490 arg_concat "--with-" arg_name,
3491 Arg.String var_set,
3492 Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value
3493 ]
3494 | CLIEnable ->
3495 let dflt =
3496 if default_value = " [true]" then
3497 s_ " [default: enabled]"
3498 else
3499 s_ " [default: disabled]"
3500 in
3501 [
3502 arg_concat "--enable-" arg_name,
3503 Arg.Unit (fun () -> var_set "true"),
3504 Printf.sprintf (f_ " %s%s") hlp dflt;
3505
3506 arg_concat "--disable-" arg_name,
3507 Arg.Unit (fun () -> var_set "false"),
3508 Printf.sprintf (f_ " %s%s") hlp dflt
3509 ]
3510 | CLIUser lst ->
3511 lst
3512 in
3513 args :: acc)
3692 (fun acc name def short_descr_opt ->
3693 let var_set s =
3694 Schema.set
3695 schema
3696 env
3697 ~context:OCommandLine
3698 name
3699 s
3700 in
3701
3702 let arg_name =
3703 OASISUtils.varname_of_string ~hyphen:'-' name
3704 in
3705
3706 let hlp =
3707 match short_descr_opt with
3708 | Some txt -> txt ()
3709 | None -> ""
3710 in
3711
3712 let arg_hlp =
3713 match def.arg_help with
3714 | Some s -> s
3715 | None -> "str"
3716 in
3717
3718 let default_value =
3719 try
3720 Printf.sprintf
3721 (f_ " [%s]")
3722 (Schema.get
3723 schema
3724 env
3725 name)
3726 with Not_set _ ->
3727 ""
3728 in
3729
3730 let args =
3731 match def.cli with
3732 | CLINone ->
3733 []
3734 | CLIAuto ->
3735 [
3736 arg_concat "--" arg_name,
3737 Arg.String var_set,
3738 Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value
3739 ]
3740 | CLIWith ->
3741 [
3742 arg_concat "--with-" arg_name,
3743 Arg.String var_set,
3744 Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value
3745 ]
3746 | CLIEnable ->
3747 let dflt =
3748 if default_value = " [true]" then
3749 s_ " [default: enabled]"
3750 else
3751 s_ " [default: disabled]"
3752 in
3753 [
3754 arg_concat "--enable-" arg_name,
3755 Arg.Unit (fun () -> var_set "true"),
3756 Printf.sprintf (f_ " %s%s") hlp dflt;
3757
3758 arg_concat "--disable-" arg_name,
3759 Arg.Unit (fun () -> var_set "false"),
3760 Printf.sprintf (f_ " %s%s") hlp dflt
3761 ]
3762 | CLIUser lst ->
3763 lst
3764 in
3765 args :: acc)
35143766 []
35153767 schema)
35163768 end
35243776
35253777
35263778 let parse argv args =
3527 (* Simulate command line for Arg *)
3528 let current =
3529 ref 0
3530 in
3531
3532 try
3533 Arg.parse_argv
3534 ~current:current
3535 (Array.concat [[|"none"|]; argv])
3536 (Arg.align args)
3537 (failwithf (f_ "Don't know what to do with arguments: '%s'"))
3538 (s_ "configure options:")
3539 with
3540 | Arg.Help txt ->
3541 print_endline txt;
3542 exit 0
3543 | Arg.Bad txt ->
3544 prerr_endline txt;
3545 exit 1
3779 (* Simulate command line for Arg *)
3780 let current =
3781 ref 0
3782 in
3783
3784 try
3785 Arg.parse_argv
3786 ~current:current
3787 (Array.concat [[|"none"|]; argv])
3788 (Arg.align args)
3789 (failwithf (f_ "Don't know what to do with arguments: '%s'"))
3790 (s_ "configure options:")
3791 with
3792 | Arg.Help txt ->
3793 print_endline txt;
3794 exit 0
3795 | Arg.Bad txt ->
3796 prerr_endline txt;
3797 exit 1
35463798 end
35473799
35483800 module BaseCheck = struct
35643816 (fun res e ->
35653817 match res with
35663818 | Some _ ->
3567 res
3819 res
35683820 | None ->
3569 try
3570 Some (OASISFileUtil.which ~ctxt:!BaseContext.default e)
3571 with Not_found ->
3572 None)
3821 try
3822 Some (OASISFileUtil.which ~ctxt:!BaseContext.default e)
3823 with Not_found ->
3824 None)
35733825 None
35743826 prg_lst
35753827 in
3576 match alternate with
3577 | Some prg -> prg
3578 | None -> raise Not_found)
3828 match alternate with
3829 | Some prg -> prg
3830 | None -> raise Not_found)
35793831
35803832
35813833 let prog prg =
35913843
35923844
35933845 let version
3594 var_prefix
3595 cmp
3596 fversion
3597 () =
3846 var_prefix
3847 cmp
3848 fversion
3849 () =
35983850 (* Really compare version provided *)
35993851 let var =
36003852 var_prefix^"_version_"^(OASISVersion.varname_of_comparator cmp)
36013853 in
3602 var_redefine
3603 ~hide:true
3604 var
3605 (fun () ->
3606 let version_str =
3607 match fversion () with
3608 | "[Distributed with OCaml]" ->
3609 begin
3610 try
3611 (var_get "ocaml_version")
3612 with Not_found ->
3613 warning
3614 (f_ "Variable ocaml_version not defined, fallback \
3615 to default");
3616 Sys.ocaml_version
3617 end
3618 | res ->
3619 res
3620 in
3621 let version =
3622 OASISVersion.version_of_string version_str
3623 in
3624 if OASISVersion.comparator_apply version cmp then
3625 version_str
3626 else
3627 failwithf
3628 (f_ "Cannot satisfy version constraint on %s: %s (version: %s)")
3629 var_prefix
3630 (OASISVersion.string_of_comparator cmp)
3631 version_str)
3632 ()
3854 var_redefine
3855 ~hide:true
3856 var
3857 (fun () ->
3858 let version_str =
3859 match fversion () with
3860 | "[Distributed with OCaml]" ->
3861 begin
3862 try
3863 (var_get "ocaml_version")
3864 with Not_found ->
3865 warning
3866 (f_ "Variable ocaml_version not defined, fallback \
3867 to default");
3868 Sys.ocaml_version
3869 end
3870 | res ->
3871 res
3872 in
3873 let version =
3874 OASISVersion.version_of_string version_str
3875 in
3876 if OASISVersion.comparator_apply version cmp then
3877 version_str
3878 else
3879 failwithf
3880 (f_ "Cannot satisfy version constraint on %s: %s (version: %s)")
3881 var_prefix
3882 (OASISVersion.string_of_comparator cmp)
3883 version_str)
3884 ()
36333885
36343886
36353887 let package_version pkg =
36503902 (ocamlfind ())
36513903 ["query"; "-format"; "%d"; pkg]
36523904 in
3653 if Sys.file_exists dir && Sys.is_directory dir then
3654 dir
3655 else
3656 failwithf
3657 (f_ "When looking for findlib package %s, \
3658 directory %s return doesn't exist")
3659 pkg dir
3905 if Sys.file_exists dir && Sys.is_directory dir then
3906 dir
3907 else
3908 failwithf
3909 (f_ "When looking for findlib package %s, \
3910 directory %s return doesn't exist")
3911 pkg dir
36603912 in
36613913 let vl =
36623914 var_redefine
36643916 (fun () -> findlib_dir pkg)
36653917 ()
36663918 in
3667 (
3668 match version_comparator with
3669 | Some ver_cmp ->
3670 ignore
3671 (version
3672 var
3673 ver_cmp
3674 (fun _ -> package_version pkg)
3675 ())
3676 | None ->
3677 ()
3678 );
3679 vl
3919 (
3920 match version_comparator with
3921 | Some ver_cmp ->
3922 ignore
3923 (version
3924 var
3925 ver_cmp
3926 (fun _ -> package_version pkg)
3927 ())
3928 | None ->
3929 ()
3930 );
3931 vl
36803932 end
36813933
36823934 module BaseOCamlcConfig = struct
36983950 let ocamlc_config_map =
36993951 (* Map name to value for ocamlc -config output
37003952 (name ^": "^value)
3701 *)
3953 *)
37023954 let rec split_field mp lst =
37033955 match lst with
37043956 | line :: tl ->
3705 let mp =
3706 try
3707 let pos_semicolon =
3708 String.index line ':'
3709 in
3710 if pos_semicolon > 1 then
3711 (
3712 let name =
3713 String.sub line 0 pos_semicolon
3714 in
3715 let linelen =
3716 String.length line
3717 in
3718 let value =
3719 if linelen > pos_semicolon + 2 then
3720 String.sub
3721 line
3722 (pos_semicolon + 2)
3723 (linelen - pos_semicolon - 2)
3724 else
3725 ""
3726 in
3727 SMap.add name value mp
3728 )
3729 else
3730 (
3731 mp
3732 )
3733 with Not_found ->
3957 let mp =
3958 try
3959 let pos_semicolon =
3960 String.index line ':'
3961 in
3962 if pos_semicolon > 1 then
3963 (
3964 let name =
3965 String.sub line 0 pos_semicolon
3966 in
3967 let linelen =
3968 String.length line
3969 in
3970 let value =
3971 if linelen > pos_semicolon + 2 then
3972 String.sub
3973 line
3974 (pos_semicolon + 2)
3975 (linelen - pos_semicolon - 2)
3976 else
3977 ""
3978 in
3979 SMap.add name value mp
3980 )
3981 else
37343982 (
37353983 mp
37363984 )
3737 in
3738 split_field mp tl
3985 with Not_found ->
3986 (
3987 mp
3988 )
3989 in
3990 split_field mp tl
37393991 | [] ->
3740 mp
3992 mp
37413993 in
37423994
37433995 let cache =
37514003 (ocamlc ()) ["-config"]))
37524004 []))
37534005 in
3754 var_redefine
3755 "ocamlc_config_map"
3756 ~hide:true
3757 ~dump:false
3758 (fun () ->
3759 (* TODO: update if ocamlc change !!! *)
3760 Lazy.force cache)
4006 var_redefine
4007 "ocamlc_config_map"
4008 ~hide:true
4009 ~dump:false
4010 (fun () ->
4011 (* TODO: update if ocamlc change !!! *)
4012 Lazy.force cache)
37614013
37624014
37634015 let var_define nm =
37724024 String.sub s 0 (String.index s '+')
37734025 with _ ->
37744026 s
3775 in
4027 in
37764028
37774029 let nm_config, value_config =
37784030 match nm with
37794031 | "ocaml_version" ->
3780 "version", chop_version_suffix
4032 "version", chop_version_suffix
37814033 | _ -> nm, (fun x -> x)
37824034 in
3783 var_redefine
3784 nm
3785 (fun () ->
3786 try
3787 let map =
3788 avlbl_config_get ()
3789 in
3790 let value =
3791 SMap.find nm_config map
3792 in
3793 value_config value
3794 with Not_found ->
3795 failwithf
3796 (f_ "Cannot find field '%s' in '%s -config' output")
3797 nm
3798 (ocamlc ()))
4035 var_redefine
4036 nm
4037 (fun () ->
4038 try
4039 let map =
4040 avlbl_config_get ()
4041 in
4042 let value =
4043 SMap.find nm_config map
4044 in
4045 value_config value
4046 with Not_found ->
4047 failwithf
4048 (f_ "Cannot find field '%s' in '%s -config' output")
4049 nm
4050 (ocamlc ()))
37994051
38004052 end
38014053
38054057
38064058 open OASISGettext
38074059 open OASISTypes
3808 open OASISExpr
38094060 open BaseCheck
38104061 open BaseEnv
38114062
38354086 let since_version =
38364087 OASISVersion.VGreaterEqual (OASISVersion.version_of_string since_version)
38374088 in
3838 var_cond :=
4089 var_cond :=
38394090 (fun ver ->
38404091 if OASISVersion.comparator_apply ver since_version then
38414092 holder := f ()) :: !var_cond;
3842 fun () -> !holder ()
4093 fun () -> !holder ()
38434094
38444095
38454096 (**/**)
39004151 OASISExec.run_read_output ~ctxt:!BaseContext.default
39014152 (flexlink ()) ["-help"]
39024153 in
3903 match lst with
3904 | line :: _ ->
3905 Scanf.sscanf line "FlexDLL version %s" (fun ver -> ver)
3906 | [] ->
3907 raise Not_found)
4154 match lst with
4155 | line :: _ ->
4156 Scanf.sscanf line "FlexDLL version %s" (fun ver -> ver)
4157 | [] ->
4158 raise Not_found)
39084159
39094160
39104161 (**/**)
39204171 let (/) a b =
39214172 if os_type () = Sys.os_type then
39224173 Filename.concat a b
3923 else if os_type () = "Unix" then
4174 else if os_type () = "Unix" || os_type () = "Cygwin" then
39244175 OASISUnixPath.concat a b
39254176 else
39264177 OASISUtils.failwithf (f_ "Cannot handle os_type %s filename concat")
39344185 (fun () ->
39354186 match os_type () with
39364187 | "Win32" ->
3937 let program_files =
3938 Sys.getenv "PROGRAMFILES"
3939 in
3940 program_files/(pkg_name ())
4188 let program_files =
4189 Sys.getenv "PROGRAMFILES"
4190 in
4191 program_files/(pkg_name ())
39414192 | _ ->
3942 "/usr/local")
4193 "/usr/local")
39434194
39444195
39454196 let exec_prefix =
40754326 let _s: string =
40764327 ocamlopt ()
40774328 in
4078 "true"
4329 "true"
40794330 with PropList.Not_set _ ->
40804331 let _s: string =
40814332 ocamlc ()
40824333 in
4083 "false")
4334 "false")
40844335
40854336
40864337 let ext_program =
41334384 (fun () ->
41344385 var_define
41354386 ~short_desc:(fun () ->
4136 s_ "Compile tests executable and library and run them")
4387 s_ "Compile tests executable and library and run them")
41374388 ~cli:CLIEnable
41384389 "tests"
41394390 (fun () -> "false"))
41724423 in
41734424 let has_native_dynlink =
41744425 let ocamlfind = ocamlfind () in
4175 try
4176 let fn =
4177 OASISExec.run_read_one_line
4178 ~ctxt:!BaseContext.default
4179 ocamlfind
4180 ["query"; "-predicates"; "native"; "dynlink";
4181 "-format"; "%d/%a"]
4182 in
4183 Sys.file_exists fn
4184 with _ ->
4185 false
4426 try
4427 let fn =
4428 OASISExec.run_read_one_line
4429 ~ctxt:!BaseContext.default
4430 ocamlfind
4431 ["query"; "-predicates"; "native"; "dynlink";
4432 "-format"; "%d/%a"]
4433 in
4434 Sys.file_exists fn
4435 with _ ->
4436 false
41864437 in
4187 if not has_native_dynlink then
4438 if not has_native_dynlink then
4439 false
4440 else if ocaml_lt_312 () then
4441 false
4442 else if (os_type () = "Win32" || os_type () = "Cygwin")
4443 && flexdll_lt_030 () then
4444 begin
4445 BaseMessage.warning
4446 (f_ ".cmxs generation disabled because FlexDLL needs to be \
4447 at least 0.30. Please upgrade FlexDLL from %s to 0.30.")
4448 (flexdll_version ());
41884449 false
4189 else if ocaml_lt_312 () then
4190 false
4191 else if (os_type () = "Win32" || os_type () = "Cygwin")
4192 && flexdll_lt_030 () then
4193 begin
4194 BaseMessage.warning
4195 (f_ ".cmxs generation disabled because FlexDLL needs to be \
4196 at least 0.30. Please upgrade FlexDLL from %s to 0.30.")
4197 (flexdll_version ());
4198 false
4199 end
4200 else
4201 true
4450 end
4451 else
4452 true
42024453 in
4203 string_of_bool res)
4454 string_of_bool res)
42044455
42054456
42064457 let init pkg =
42164467 open BaseEnv
42174468 open OASISGettext
42184469 open BaseMessage
4470 open OASISContext
42194471
42204472
42214473 let to_filename fn =
4222 let fn =
4223 OASISHostPath.of_unix fn
4224 in
4225 if not (Filename.check_suffix fn ".ab") then
4226 warning
4227 (f_ "File '%s' doesn't have '.ab' extension")
4228 fn;
4229 Filename.chop_extension fn
4230
4231
4232 let replace fn_lst =
4233 let buff =
4234 Buffer.create 13
4235 in
4236 List.iter
4237 (fun fn ->
4238 let fn =
4239 OASISHostPath.of_unix fn
4240 in
4241 let chn_in =
4242 open_in fn
4243 in
4244 let chn_out =
4245 open_out (to_filename fn)
4246 in
4247 (
4248 try
4249 while true do
4250 Buffer.add_string buff (var_expand (input_line chn_in));
4251 Buffer.add_char buff '\n'
4252 done
4253 with End_of_file ->
4254 ()
4255 );
4256 Buffer.output_buffer chn_out buff;
4257 Buffer.clear buff;
4258 close_in chn_in;
4259 close_out chn_out)
4260 fn_lst
4474 if not (Filename.check_suffix fn ".ab") then
4475 warning (f_ "File '%s' doesn't have '.ab' extension") fn;
4476 OASISFileSystem.of_unix_filename (Filename.chop_extension fn)
4477
4478
4479 let replace ~ctxt fn_lst =
4480 let open OASISFileSystem in
4481 let ibuf, obuf = Buffer.create 13, Buffer.create 13 in
4482 List.iter
4483 (fun fn ->
4484 Buffer.clear ibuf; Buffer.clear obuf;
4485 defer_close
4486 (ctxt.srcfs#open_in (of_unix_filename fn))
4487 (read_all ibuf);
4488 Buffer.add_string obuf (var_expand (Buffer.contents ibuf));
4489 defer_close
4490 (ctxt.srcfs#open_out (to_filename fn))
4491 (fun wrtr -> wrtr#output obuf))
4492 fn_lst
42614493 end
42624494
42634495 module BaseLog = struct
42654497
42664498
42674499 open OASISUtils
4268
4269
4270 let default_filename =
4271 Filename.concat
4272 (Filename.dirname BaseEnv.default_filename)
4273 "setup.log"
4274
4275
4276 module SetTupleString =
4277 Set.Make
4278 (struct
4279 type t = string * string
4280 let compare (s11, s12) (s21, s22) =
4281 match String.compare s11 s21 with
4282 | 0 -> String.compare s12 s22
4283 | n -> n
4284 end)
4285
4286
4287 let load () =
4288 if Sys.file_exists default_filename then
4289 begin
4290 let chn =
4291 open_in default_filename
4292 in
4293 let scbuf =
4294 Scanf.Scanning.from_file default_filename
4295 in
4296 let rec read_aux (st, lst) =
4297 if not (Scanf.Scanning.end_of_input scbuf) then
4298 begin
4299 let acc =
4300 try
4301 Scanf.bscanf scbuf "%S %S\n"
4302 (fun e d ->
4303 let t =
4304 e, d
4305 in
4306 if SetTupleString.mem t st then
4307 st, lst
4308 else
4309 SetTupleString.add t st,
4310 t :: lst)
4311 with Scanf.Scan_failure _ ->
4312 failwith
4313 (Scanf.bscanf scbuf
4314 "%l"
4315 (fun line ->
4316 Printf.sprintf
4317 "Malformed log file '%s' at line %d"
4318 default_filename
4319 line))
4320 in
4321 read_aux acc
4322 end
4323 else
4324 begin
4325 close_in chn;
4326 List.rev lst
4327 end
4328 in
4329 read_aux (SetTupleString.empty, [])
4330 end
4500 open OASISContext
4501 open OASISGettext
4502 open OASISFileSystem
4503
4504
4505 let default_filename = in_srcdir "setup.log"
4506
4507
4508 let load ~ctxt () =
4509 let module SetTupleString =
4510 Set.Make
4511 (struct
4512 type t = string * string
4513 let compare (s11, s12) (s21, s22) =
4514 match String.compare s11 s21 with
4515 | 0 -> String.compare s12 s22
4516 | n -> n
4517 end)
4518 in
4519 if ctxt.srcfs#file_exists default_filename then begin
4520 defer_close
4521 (ctxt.srcfs#open_in default_filename)
4522 (fun rdr ->
4523 let line = ref 1 in
4524 let lxr = Genlex.make_lexer [] (stream_of_reader rdr) in
4525 let rec read_aux (st, lst) =
4526 match Stream.npeek 2 lxr with
4527 | [Genlex.String e; Genlex.String d] ->
4528 let t = e, d in
4529 Stream.junk lxr; Stream.junk lxr;
4530 if SetTupleString.mem t st then
4531 read_aux (st, lst)
4532 else
4533 read_aux (SetTupleString.add t st, t :: lst)
4534 | [] -> List.rev lst
4535 | _ ->
4536 failwithf
4537 (f_ "Malformed log file '%s' at line %d")
4538 (ctxt.srcfs#string_of_filename default_filename)
4539 !line
4540 in
4541 read_aux (SetTupleString.empty, []))
4542 end else begin
4543 []
4544 end
4545
4546
4547 let register ~ctxt event data =
4548 defer_close
4549 (ctxt.srcfs#open_out
4550 ~mode:[Open_append; Open_creat; Open_text]
4551 ~perm:0o644
4552 default_filename)
4553 (fun wrtr ->
4554 let buf = Buffer.create 13 in
4555 Printf.bprintf buf "%S %S\n" event data;
4556 wrtr#output buf)
4557
4558
4559 let unregister ~ctxt event data =
4560 let lst = load ~ctxt () in
4561 let buf = Buffer.create 13 in
4562 List.iter
4563 (fun (e, d) ->
4564 if e <> event || d <> data then
4565 Printf.bprintf buf "%S %S\n" e d)
4566 lst;
4567 if Buffer.length buf > 0 then
4568 defer_close
4569 (ctxt.srcfs#open_out default_filename)
4570 (fun wrtr -> wrtr#output buf)
43314571 else
4332 begin
4333 []
4334 end
4335
4336
4337 let register event data =
4338 let chn_out =
4339 open_out_gen [Open_append; Open_creat; Open_text] 0o644 default_filename
4340 in
4341 Printf.fprintf chn_out "%S %S\n" event data;
4342 close_out chn_out
4343
4344
4345 let unregister event data =
4346 if Sys.file_exists default_filename then
4347 begin
4348 let lst =
4349 load ()
4350 in
4351 let chn_out =
4352 open_out default_filename
4353 in
4354 let write_something =
4355 ref false
4356 in
4357 List.iter
4358 (fun (e, d) ->
4359 if e <> event || d <> data then
4360 begin
4361 write_something := true;
4362 Printf.fprintf chn_out "%S %S\n" e d
4363 end)
4364 lst;
4365 close_out chn_out;
4366 if not !write_something then
4367 Sys.remove default_filename
4368 end
4369
4370
4371 let filter events =
4372 let st_events =
4373 List.fold_left
4374 (fun st e ->
4375 SetString.add e st)
4376 SetString.empty
4377 events
4378 in
4379 List.filter
4380 (fun (e, _) -> SetString.mem e st_events)
4381 (load ())
4382
4383
4384 let exists event data =
4572 ctxt.srcfs#remove default_filename
4573
4574
4575 let filter ~ctxt events =
4576 let st_events = SetString.of_list events in
4577 List.filter
4578 (fun (e, _) -> SetString.mem e st_events)
4579 (load ~ctxt ())
4580
4581
4582 let exists ~ctxt event data =
43854583 List.exists
43864584 (fun v -> (event, data) = v)
4387 (load ())
4585 (load ~ctxt ())
43884586 end
43894587
43904588 module BaseBuilt = struct
44074605
44084606 let to_log_event_file t nm =
44094607 "built_"^
4410 (match t with
4411 | BExec -> "exec"
4412 | BExecLib -> "exec_lib"
4413 | BLib -> "lib"
4414 | BObj -> "obj"
4415 | BDoc -> "doc")^
4416 "_"^nm
4608 (match t with
4609 | BExec -> "exec"
4610 | BExecLib -> "exec_lib"
4611 | BLib -> "lib"
4612 | BObj -> "obj"
4613 | BDoc -> "doc")^
4614 "_"^nm
44174615
44184616
44194617 let to_log_event_done t nm =
44204618 "is_"^(to_log_event_file t nm)
44214619
44224620
4423 let register t nm lst =
4424 BaseLog.register
4425 (to_log_event_done t nm)
4426 "true";
4621 let register ~ctxt t nm lst =
4622 BaseLog.register ~ctxt (to_log_event_done t nm) "true";
44274623 List.iter
44284624 (fun alt ->
44294625 let registered =
44304626 List.fold_left
44314627 (fun registered fn ->
4432 if OASISFileUtil.file_exists_case fn then
4433 begin
4434 BaseLog.register
4435 (to_log_event_file t nm)
4436 (if Filename.is_relative fn then
4437 Filename.concat (Sys.getcwd ()) fn
4438 else
4439 fn);
4440 true
4441 end
4442 else
4443 registered)
4628 if OASISFileUtil.file_exists_case fn then begin
4629 BaseLog.register ~ctxt
4630 (to_log_event_file t nm)
4631 (if Filename.is_relative fn then
4632 Filename.concat (Sys.getcwd ()) fn
4633 else
4634 fn);
4635 true
4636 end else begin
4637 registered
4638 end)
44444639 false
44454640 alt
44464641 in
4447 if not registered then
4448 warning
4449 (f_ "Cannot find an existing alternative files among: %s")
4450 (String.concat (s_ ", ") alt))
4642 if not registered then
4643 warning
4644 (f_ "Cannot find an existing alternative files among: %s")
4645 (String.concat (s_ ", ") alt))
44514646 lst
44524647
44534648
4454 let unregister t nm =
4649 let unregister ~ctxt t nm =
44554650 List.iter
4456 (fun (e, d) ->
4457 BaseLog.unregister e d)
4458 (BaseLog.filter
4459 [to_log_event_file t nm;
4460 to_log_event_done t nm])
4461
4462
4463 let fold t nm f acc =
4651 (fun (e, d) -> BaseLog.unregister ~ctxt e d)
4652 (BaseLog.filter ~ctxt [to_log_event_file t nm; to_log_event_done t nm])
4653
4654
4655 let fold ~ctxt t nm f acc =
44644656 List.fold_left
44654657 (fun acc (_, fn) ->
4466 if OASISFileUtil.file_exists_case fn then
4467 begin
4468 f acc fn
4469 end
4470 else
4471 begin
4472 warning
4473 (f_ "File '%s' has been marked as built \
4658 if OASISFileUtil.file_exists_case fn then begin
4659 f acc fn
4660 end else begin
4661 warning
4662 (f_ "File '%s' has been marked as built \
44744663 for %s but doesn't exist")
4475 fn
4476 (Printf.sprintf
4477 (match t with
4478 | BExec | BExecLib ->
4479 (f_ "executable %s")
4480 | BLib ->
4481 (f_ "library %s")
4482 | BObj ->
4483 (f_ "object %s")
4484 | BDoc ->
4485 (f_ "documentation %s"))
4486 nm);
4487 acc
4488 end)
4664 fn
4665 (Printf.sprintf
4666 (match t with
4667 | BExec | BExecLib -> (f_ "executable %s")
4668 | BLib -> (f_ "library %s")
4669 | BObj -> (f_ "object %s")
4670 | BDoc -> (f_ "documentation %s"))
4671 nm);
4672 acc
4673 end)
44894674 acc
4490 (BaseLog.filter
4491 [to_log_event_file t nm])
4492
4493
4494 let is_built t nm =
4675 (BaseLog.filter ~ctxt [to_log_event_file t nm])
4676
4677
4678 let is_built ~ctxt t nm =
44954679 List.fold_left
4496 (fun is_built (_, d) ->
4497 (try
4498 bool_of_string d
4499 with _ ->
4500 false))
4680 (fun _ (_, d) -> try bool_of_string d with _ -> false)
45014681 false
4502 (BaseLog.filter
4503 [to_log_event_done t nm])
4682 (BaseLog.filter ~ctxt [to_log_event_done t nm])
45044683
45054684
45064685 let of_executable ffn (cs, bs, exec) =
45164695 let evs =
45174696 (BExec, cs.cs_name, [[ffn unix_exec_is]])
45184697 ::
4519 (match unix_dll_opt with
4520 | Some fn ->
4521 [BExecLib, cs.cs_name, [[ffn fn]]]
4522 | None ->
4523 [])
4524 in
4525 evs,
4526 unix_exec_is,
4527 unix_dll_opt
4698 (match unix_dll_opt with
4699 | Some fn ->
4700 [BExecLib, cs.cs_name, [[ffn fn]]]
4701 | None ->
4702 [])
4703 in
4704 evs,
4705 unix_exec_is,
4706 unix_dll_opt
45284707
45294708
45304709 let of_library ffn (cs, bs, lib) =
45324711 OASISLibrary.generated_unix_files
45334712 ~ctxt:!BaseContext.default
45344713 ~source_file_exists:(fun fn ->
4535 OASISFileUtil.file_exists_case (OASISHostPath.of_unix fn))
4714 OASISFileUtil.file_exists_case (OASISHostPath.of_unix fn))
45364715 ~is_native:(bool_of_string (is_native ()))
45374716 ~has_native_dynlink:(bool_of_string (native_dynlink ()))
45384717 ~ext_lib:(ext_lib ())
45444723 cs.cs_name,
45454724 List.map (List.map ffn) unix_lst]
45464725 in
4547 evs, unix_lst
4726 evs, unix_lst
45484727
45494728
45504729 let of_object ffn (cs, bs, obj) =
45524731 OASISObject.generated_unix_files
45534732 ~ctxt:!BaseContext.default
45544733 ~source_file_exists:(fun fn ->
4555 OASISFileUtil.file_exists_case (OASISHostPath.of_unix fn))
4734 OASISFileUtil.file_exists_case (OASISHostPath.of_unix fn))
45564735 ~is_native:(bool_of_string (is_native ()))
45574736 (cs, bs, obj)
45584737 in
45614740 cs.cs_name,
45624741 List.map (List.map ffn) unix_lst]
45634742 in
4564 evs, unix_lst
4743 evs, unix_lst
45654744
45664745 end
45674746
45904769 | Some (cmd, args) -> String.concat " " (cmd :: args)
45914770 | None -> s_ "No command"
45924771 in
4593 match
4594 var_choose
4595 ~name:(s_ "Pre/Post Command")
4596 ~printer
4597 lst with
4598 | Some (cmd, args) ->
4599 begin
4600 try
4601 run cmd args [||]
4602 with e when failsafe ->
4603 warning
4604 (f_ "Command '%s' fail with error: %s")
4605 (String.concat " " (cmd :: args))
4606 (match e with
4607 | Failure msg -> msg
4608 | e -> Printexc.to_string e)
4609 end
4610 | None ->
4611 ()
4772 match
4773 var_choose
4774 ~name:(s_ "Pre/Post Command")
4775 ~printer
4776 lst with
4777 | Some (cmd, args) ->
4778 begin
4779 try
4780 run cmd args [||]
4781 with e when failsafe ->
4782 warning
4783 (f_ "Command '%s' fail with error: %s")
4784 (String.concat " " (cmd :: args))
4785 (match e with
4786 | Failure msg -> msg
4787 | e -> Printexc.to_string e)
4788 end
4789 | None ->
4790 ()
46124791 in
46134792 let res =
46144793 optional_command cstm.pre_command;
46154794 f e
46164795 in
4617 optional_command cstm.post_command;
4618 res
4796 optional_command cstm.post_command;
4797 res
46194798 end
46204799
46214800 module BaseDynVar = struct
46284807 open BaseBuilt
46294808
46304809
4631 let init pkg =
4810 let init ~ctxt pkg =
46324811 (* TODO: disambiguate exec vs other variable by adding exec_VARNAME. *)
46334812 (* TODO: provide compile option for library libary_byte_args_VARNAME... *)
46344813 List.iter
46354814 (function
4636 | Executable (cs, bs, exec) ->
4637 if var_choose bs.bs_build then
4638 var_ignore
4639 (var_redefine
4640 (* We don't save this variable *)
4641 ~dump:false
4642 ~short_desc:(fun () ->
4643 Printf.sprintf
4644 (f_ "Filename of executable '%s'")
4645 cs.cs_name)
4646 (OASISUtils.varname_of_string cs.cs_name)
4647 (fun () ->
4648 let fn_opt =
4649 fold
4650 BExec cs.cs_name
4651 (fun _ fn -> Some fn)
4652 None
4653 in
4654 match fn_opt with
4655 | Some fn -> fn
4656 | None ->
4657 raise
4658 (PropList.Not_set
4659 (cs.cs_name,
4660 Some (Printf.sprintf
4661 (f_ "Executable '%s' not yet built.")
4662 cs.cs_name)))))
4663
4664 | Library _ | Object _ | Flag _ | Test _ | SrcRepo _ | Doc _ ->
4665 ())
4815 | Executable (cs, bs, _) ->
4816 if var_choose bs.bs_build then
4817 var_ignore
4818 (var_redefine
4819 (* We don't save this variable *)
4820 ~dump:false
4821 ~short_desc:(fun () ->
4822 Printf.sprintf
4823 (f_ "Filename of executable '%s'")
4824 cs.cs_name)
4825 (OASISUtils.varname_of_string cs.cs_name)
4826 (fun () ->
4827 let fn_opt =
4828 fold ~ctxt BExec cs.cs_name (fun _ fn -> Some fn) None
4829 in
4830 match fn_opt with
4831 | Some fn -> fn
4832 | None ->
4833 raise
4834 (PropList.Not_set
4835 (cs.cs_name,
4836 Some (Printf.sprintf
4837 (f_ "Executable '%s' not yet built.")
4838 cs.cs_name)))))
4839
4840 | Library _ | Object _ | Flag _ | Test _ | SrcRepo _ | Doc _ ->
4841 ())
46664842 pkg.sections
46674843 end
46684844
46734849 open BaseEnv
46744850 open BaseMessage
46754851 open OASISTypes
4676 open OASISExpr
46774852 open OASISGettext
46784853
46794854
4680 let test lst pkg extra_args =
4855 let test ~ctxt lst pkg extra_args =
46814856
46824857 let one_test (failure, n) (test_plugin, cs, test) =
46834858 if var_choose
4684 ~name:(Printf.sprintf
4685 (f_ "test %s run")
4686 cs.cs_name)
4687 ~printer:string_of_bool
4688 test.test_run then
4859 ~name:(Printf.sprintf
4860 (f_ "test %s run")
4861 cs.cs_name)
4862 ~printer:string_of_bool
4863 test.test_run then
46894864 begin
4690 let () =
4691 info (f_ "Running test '%s'") cs.cs_name
4692 in
4865 let () = info (f_ "Running test '%s'") cs.cs_name in
46934866 let back_cwd =
46944867 match test.test_working_directory with
46954868 | Some dir ->
4696 let cwd =
4697 Sys.getcwd ()
4698 in
4699 let chdir d =
4700 info (f_ "Changing directory to '%s'") d;
4701 Sys.chdir d
4702 in
4703 chdir dir;
4704 fun () -> chdir cwd
4869 let cwd = Sys.getcwd () in
4870 let chdir d =
4871 info (f_ "Changing directory to '%s'") d;
4872 Sys.chdir d
4873 in
4874 chdir dir;
4875 fun () -> chdir cwd
47054876
47064877 | None ->
4707 fun () -> ()
4878 fun () -> ()
47084879 in
4709 try
4710 let failure_percent =
4711 BaseCustom.hook
4712 test.test_custom
4713 (test_plugin pkg (cs, test))
4714 extra_args
4715 in
4716 back_cwd ();
4717 (failure_percent +. failure, n + 1)
4718 with e ->
4719 begin
4720 back_cwd ();
4721 raise e
4722 end
4880 try
4881 let failure_percent =
4882 BaseCustom.hook
4883 test.test_custom
4884 (test_plugin ~ctxt pkg (cs, test))
4885 extra_args
4886 in
4887 back_cwd ();
4888 (failure_percent +. failure, n + 1)
4889 with e ->
4890 begin
4891 back_cwd ();
4892 raise e
4893 end
47234894 end
47244895 else
47254896 begin
47274898 (failure, n)
47284899 end
47294900 in
4730 let failed, n =
4731 List.fold_left
4732 one_test
4733 (0.0, 0)
4734 lst
4735 in
4736 let failure_percent =
4737 if n = 0 then
4738 0.0
4739 else
4740 failed /. (float_of_int n)
4741 in
4901 let failed, n = List.fold_left one_test (0.0, 0) lst in
4902 let failure_percent = if n = 0 then 0.0 else failed /. (float_of_int n) in
47424903 let msg =
47434904 Printf.sprintf
47444905 (f_ "Tests had a %.2f%% failure rate")
47454906 (100. *. failure_percent)
47464907 in
4747 if failure_percent > 0.0 then
4748 failwith msg
4749 else
4750 info "%s" msg;
4751
4752 (* Possible explanation why the tests where not run. *)
4753 if OASISFeatures.package_test OASISFeatures.flag_tests pkg &&
4754 not (bool_of_string (BaseStandardVar.tests ())) &&
4755 lst <> [] then
4756 BaseMessage.warning
4757 "Tests are turned off, consider enabling with \
4758 'ocaml setup.ml -configure --enable-tests'"
4908 if failure_percent > 0.0 then
4909 failwith msg
4910 else
4911 info "%s" msg;
4912
4913 (* Possible explanation why the tests where not run. *)
4914 if OASISFeatures.package_test OASISFeatures.flag_tests pkg &&
4915 not (bool_of_string (BaseStandardVar.tests ())) &&
4916 lst <> [] then
4917 BaseMessage.warning
4918 "Tests are turned off, consider enabling with \
4919 'ocaml setup.ml -configure --enable-tests'"
47594920 end
47604921
47614922 module BaseDoc = struct
47684929 open OASISGettext
47694930
47704931
4771 let doc lst pkg extra_args =
4932 let doc ~ctxt lst pkg extra_args =
47724933
47734934 let one_doc (doc_plugin, cs, doc) =
47744935 if var_choose
4775 ~name:(Printf.sprintf
4776 (f_ "documentation %s build")
4777 cs.cs_name)
4778 ~printer:string_of_bool
4779 doc.doc_build then
4936 ~name:(Printf.sprintf
4937 (f_ "documentation %s build")
4938 cs.cs_name)
4939 ~printer:string_of_bool
4940 doc.doc_build then
47804941 begin
47814942 info (f_ "Building documentation '%s'") cs.cs_name;
47824943 BaseCustom.hook
47834944 doc.doc_custom
4784 (doc_plugin pkg (cs, doc))
4945 (doc_plugin ~ctxt pkg (cs, doc))
47854946 extra_args
47864947 end
47874948 in
4788 List.iter one_doc lst;
4789
4790 if OASISFeatures.package_test OASISFeatures.flag_docs pkg &&
4791 not (bool_of_string (BaseStandardVar.docs ())) &&
4792 lst <> [] then
4793 BaseMessage.warning
4794 "Docs are turned off, consider enabling with \
4795 'ocaml setup.ml -configure --enable-docs'"
4949 List.iter one_doc lst;
4950
4951 if OASISFeatures.package_test OASISFeatures.flag_docs pkg &&
4952 not (bool_of_string (BaseStandardVar.docs ())) &&
4953 lst <> [] then
4954 BaseMessage.warning
4955 "Docs are turned off, consider enabling with \
4956 'ocaml setup.ml -configure --enable-docs'"
47964957 end
47974958
47984959 module BaseSetup = struct
47994960 (* # 22 "src/base/BaseSetup.ml" *)
48004961
4962 open OASISContext
48014963 open BaseEnv
48024964 open BaseMessage
48034965 open OASISTypes
4804 open OASISSection
48054966 open OASISGettext
48064967 open OASISUtils
48074968
48084969
48094970 type std_args_fun =
4810 package -> string array -> unit
4971 ctxt:OASISContext.t -> package -> string array -> unit
48114972
48124973
48134974 type ('a, 'b) section_args_fun =
4814 name * (package -> (common_section * 'a) -> string array -> 'b)
4975 name *
4976 (ctxt:OASISContext.t ->
4977 package ->
4978 (common_section * 'a) ->
4979 string array ->
4980 'b)
48154981
48164982
48174983 type t =
4818 {
4819 configure: std_args_fun;
4820 build: std_args_fun;
4821 doc: ((doc, unit) section_args_fun) list;
4822 test: ((test, float) section_args_fun) list;
4823 install: std_args_fun;
4824 uninstall: std_args_fun;
4825 clean: std_args_fun list;
4826 clean_doc: (doc, unit) section_args_fun list;
4827 clean_test: (test, unit) section_args_fun list;
4828 distclean: std_args_fun list;
4829 distclean_doc: (doc, unit) section_args_fun list;
4830 distclean_test: (test, unit) section_args_fun list;
4831 package: package;
4832 oasis_fn: string option;
4833 oasis_version: string;
4834 oasis_digest: Digest.t option;
4835 oasis_exec: string option;
4836 oasis_setup_args: string list;
4837 setup_update: bool;
4838 }
4984 {
4985 configure: std_args_fun;
4986 build: std_args_fun;
4987 doc: ((doc, unit) section_args_fun) list;
4988 test: ((test, float) section_args_fun) list;
4989 install: std_args_fun;
4990 uninstall: std_args_fun;
4991 clean: std_args_fun list;
4992 clean_doc: (doc, unit) section_args_fun list;
4993 clean_test: (test, unit) section_args_fun list;
4994 distclean: std_args_fun list;
4995 distclean_doc: (doc, unit) section_args_fun list;
4996 distclean_test: (test, unit) section_args_fun list;
4997 package: package;
4998 oasis_fn: string option;
4999 oasis_version: string;
5000 oasis_digest: Digest.t option;
5001 oasis_exec: string option;
5002 oasis_setup_args: string list;
5003 setup_update: bool;
5004 }
48395005
48405006
48415007 (* Associate a plugin function with data from package *)
48455011 (fun acc sct ->
48465012 match filter_map sct with
48475013 | Some e ->
4848 e :: acc
5014 e :: acc
48495015 | None ->
4850 acc)
5016 acc)
48515017 []
48525018 lst)
48535019
48645030 action
48655031
48665032
4867 let configure t args =
5033 let configure ~ctxt t args =
48685034 (* Run configure *)
48695035 BaseCustom.hook
48705036 t.package.conf_custom
48735039 begin
48745040 try
48755041 unload ();
4876 load ();
5042 load ~ctxt ();
48775043 with _ ->
48785044 ()
48795045 end;
48805046
48815047 (* Run plugin's configure *)
4882 t.configure t.package args;
5048 t.configure ~ctxt t.package args;
48835049
48845050 (* Dump to allow postconf to change it *)
4885 dump ())
5051 dump ~ctxt ())
48865052 ();
48875053
48885054 (* Reload environment *)
48895055 unload ();
4890 load ();
5056 load ~ctxt ();
48915057
48925058 (* Save environment *)
48935059 print ();
48945060
48955061 (* Replace data in file *)
4896 BaseFileAB.replace t.package.files_ab
4897
4898
4899 let build t args =
5062 BaseFileAB.replace ~ctxt t.package.files_ab
5063
5064
5065 let build ~ctxt t args =
49005066 BaseCustom.hook
49015067 t.package.build_custom
4902 (t.build t.package)
5068 (t.build ~ctxt t.package)
49035069 args
49045070
49055071
4906 let doc t args =
5072 let doc ~ctxt t args =
49075073 BaseDoc.doc
5074 ~ctxt
49085075 (join_plugin_sections
49095076 (function
4910 | Doc (cs, e) ->
4911 Some
4912 (lookup_plugin_section
4913 "documentation"
4914 (s_ "build")
4915 cs.cs_name
4916 t.doc,
4917 cs,
4918 e)
4919 | _ ->
4920 None)
5077 | Doc (cs, e) ->
5078 Some
5079 (lookup_plugin_section
5080 "documentation"
5081 (s_ "build")
5082 cs.cs_name
5083 t.doc,
5084 cs,
5085 e)
5086 | _ ->
5087 None)
49215088 t.package.sections)
49225089 t.package
49235090 args
49245091
49255092
4926 let test t args =
5093 let test ~ctxt t args =
49275094 BaseTest.test
5095 ~ctxt
49285096 (join_plugin_sections
49295097 (function
4930 | Test (cs, e) ->
4931 Some
4932 (lookup_plugin_section
4933 "test"
4934 (s_ "run")
4935 cs.cs_name
4936 t.test,
4937 cs,
4938 e)
4939 | _ ->
4940 None)
5098 | Test (cs, e) ->
5099 Some
5100 (lookup_plugin_section
5101 "test"
5102 (s_ "run")
5103 cs.cs_name
5104 t.test,
5105 cs,
5106 e)
5107 | _ ->
5108 None)
49415109 t.package.sections)
49425110 t.package
49435111 args
49445112
49455113
4946 let all t args =
4947 let rno_doc =
4948 ref false
4949 in
4950 let rno_test =
4951 ref false
4952 in
4953 let arg_rest =
4954 ref []
4955 in
4956 Arg.parse_argv
4957 ~current:(ref 0)
4958 (Array.of_list
4959 ((Sys.executable_name^" all") ::
5114 let all ~ctxt t args =
5115 let rno_doc = ref false in
5116 let rno_test = ref false in
5117 let arg_rest = ref [] in
5118 Arg.parse_argv
5119 ~current:(ref 0)
5120 (Array.of_list
5121 ((Sys.executable_name^" all") ::
49605122 (Array.to_list args)))
4961 [
4962 "-no-doc",
4963 Arg.Set rno_doc,
4964 s_ "Don't run doc target";
4965
4966 "-no-test",
4967 Arg.Set rno_test,
4968 s_ "Don't run test target";
4969
4970 "--",
4971 Arg.Rest (fun arg -> arg_rest := arg :: !arg_rest),
4972 s_ "All arguments for configure.";
4973 ]
4974 (failwithf (f_ "Don't know what to do with '%s'"))
4975 "";
4976
4977 info "Running configure step";
4978 configure t (Array.of_list (List.rev !arg_rest));
4979
4980 info "Running build step";
4981 build t [||];
4982
4983 (* Load setup.log dynamic variables *)
4984 BaseDynVar.init t.package;
4985
4986 if not !rno_doc then
4987 begin
4988 info "Running doc step";
4989 doc t [||];
4990 end
4991 else
4992 begin
4993 info "Skipping doc step"
4994 end;
4995
4996 if not !rno_test then
4997 begin
4998 info "Running test step";
4999 test t [||]
5000 end
5001 else
5002 begin
5003 info "Skipping test step"
5004 end
5005
5006
5007 let install t args =
5008 BaseCustom.hook
5009 t.package.install_custom
5010 (t.install t.package)
5011 args
5012
5013
5014 let uninstall t args =
5015 BaseCustom.hook
5016 t.package.uninstall_custom
5017 (t.uninstall t.package)
5018 args
5019
5020
5021 let reinstall t args =
5022 uninstall t args;
5023 install t args
5123 [
5124 "-no-doc",
5125 Arg.Set rno_doc,
5126 s_ "Don't run doc target";
5127
5128 "-no-test",
5129 Arg.Set rno_test,
5130 s_ "Don't run test target";
5131
5132 "--",
5133 Arg.Rest (fun arg -> arg_rest := arg :: !arg_rest),
5134 s_ "All arguments for configure.";
5135 ]
5136 (failwithf (f_ "Don't know what to do with '%s'"))
5137 "";
5138
5139 info "Running configure step";
5140 configure ~ctxt t (Array.of_list (List.rev !arg_rest));
5141
5142 info "Running build step";
5143 build ~ctxt t [||];
5144
5145 (* Load setup.log dynamic variables *)
5146 BaseDynVar.init ~ctxt t.package;
5147
5148 if not !rno_doc then begin
5149 info "Running doc step";
5150 doc ~ctxt t [||]
5151 end else begin
5152 info "Skipping doc step"
5153 end;
5154 if not !rno_test then begin
5155 info "Running test step";
5156 test ~ctxt t [||]
5157 end else begin
5158 info "Skipping test step"
5159 end
5160
5161
5162 let install ~ctxt t args =
5163 BaseCustom.hook t.package.install_custom (t.install ~ctxt t.package) args
5164
5165
5166 let uninstall ~ctxt t args =
5167 BaseCustom.hook t.package.uninstall_custom (t.uninstall ~ctxt t.package) args
5168
5169
5170 let reinstall ~ctxt t args =
5171 uninstall ~ctxt t args;
5172 install ~ctxt t args
50245173
50255174
50265175 let clean, distclean =
50315180 warning
50325181 (f_ "Action fail with error: %s")
50335182 (match e with
5034 | Failure msg -> msg
5035 | e -> Printexc.to_string e)
5036 in
5037
5038 let generic_clean t cstm mains docs tests args =
5183 | Failure msg -> msg
5184 | e -> Printexc.to_string e)
5185 in
5186
5187 let generic_clean ~ctxt t cstm mains docs tests args =
50395188 BaseCustom.hook
50405189 ~failsafe:true
50415190 cstm
50435192 (* Clean section *)
50445193 List.iter
50455194 (function
5046 | Test (cs, test) ->
5047 let f =
5048 try
5049 List.assoc cs.cs_name tests
5050 with Not_found ->
5051 fun _ _ _ -> ()
5052 in
5053 failsafe
5054 (f t.package (cs, test))
5055 args
5056 | Doc (cs, doc) ->
5057 let f =
5058 try
5059 List.assoc cs.cs_name docs
5060 with Not_found ->
5061 fun _ _ _ -> ()
5062 in
5063 failsafe
5064 (f t.package (cs, doc))
5065 args
5066 | Library _
5067 | Object _
5068 | Executable _
5069 | Flag _
5070 | SrcRepo _ ->
5071 ())
5195 | Test (cs, test) ->
5196 let f =
5197 try
5198 List.assoc cs.cs_name tests
5199 with Not_found ->
5200 fun ~ctxt:_ _ _ _ -> ()
5201 in
5202 failsafe (f ~ctxt t.package (cs, test)) args
5203 | Doc (cs, doc) ->
5204 let f =
5205 try
5206 List.assoc cs.cs_name docs
5207 with Not_found ->
5208 fun ~ctxt:_ _ _ _ -> ()
5209 in
5210 failsafe (f ~ctxt t.package (cs, doc)) args
5211 | Library _ | Object _ | Executable _ | Flag _ | SrcRepo _ -> ())
50725212 t.package.sections;
50735213 (* Clean whole package *)
5074 List.iter
5075 (fun f ->
5076 failsafe
5077 (f t.package)
5078 args)
5079 mains)
5214 List.iter (fun f -> failsafe (f ~ctxt t.package) args) mains)
50805215 ()
50815216 in
50825217
5083 let clean t args =
5218 let clean ~ctxt t args =
50845219 generic_clean
5220 ~ctxt
50855221 t
50865222 t.package.clean_custom
50875223 t.clean
50905226 args
50915227 in
50925228
5093 let distclean t args =
5229 let distclean ~ctxt t args =
50945230 (* Call clean *)
5095 clean t args;
5231 clean ~ctxt t args;
50965232
50975233 (* Call distclean code *)
50985234 generic_clean
5235 ~ctxt
50995236 t
51005237 t.package.distclean_custom
51015238 t.distclean
51035240 t.distclean_test
51045241 args;
51055242
5106 (* Remove generated file *)
5243 (* Remove generated source files. *)
51075244 List.iter
51085245 (fun fn ->
5109 if Sys.file_exists fn then
5110 begin
5111 info (f_ "Remove '%s'") fn;
5112 Sys.remove fn
5113 end)
5114 (BaseEnv.default_filename
5115 ::
5116 BaseLog.default_filename
5117 ::
5118 (List.rev_map BaseFileAB.to_filename t.package.files_ab))
5119 in
5120
5121 clean, distclean
5122
5123
5124 let version t _ =
5125 print_endline t.oasis_version
5246 if ctxt.srcfs#file_exists fn then begin
5247 info (f_ "Remove '%s'") (ctxt.srcfs#string_of_filename fn);
5248 ctxt.srcfs#remove fn
5249 end)
5250 ([BaseEnv.default_filename; BaseLog.default_filename]
5251 @ (List.rev_map BaseFileAB.to_filename t.package.files_ab))
5252 in
5253
5254 clean, distclean
5255
5256
5257 let version ~ctxt:_ (t: t) _ = print_endline t.oasis_version
51265258
51275259
51285260 let update_setup_ml, no_update_setup_ml_cli =
51295261 let b = ref true in
5130 b,
5131 ("-no-update-setup-ml",
5132 Arg.Clear b,
5133 s_ " Don't try to update setup.ml, even if _oasis has changed.")
5134
5135
5262 b,
5263 ("-no-update-setup-ml",
5264 Arg.Clear b,
5265 s_ " Don't try to update setup.ml, even if _oasis has changed.")
5266
5267 (* TODO: srcfs *)
51365268 let default_oasis_fn = "_oasis"
51375269
51385270
51535285 let setup_ml, args =
51545286 match Array.to_list Sys.argv with
51555287 | setup_ml :: args ->
5156 setup_ml, args
5288 setup_ml, args
51575289 | [] ->
5158 failwith
5159 (s_ "Expecting non-empty command line arguments.")
5290 failwith
5291 (s_ "Expecting non-empty command line arguments.")
51605292 in
51615293 let ocaml, setup_ml =
51625294 if Sys.executable_name = Sys.argv.(0) then
51635295 (* We are not running in standard mode, probably the script
51645296 * is precompiled.
5165 *)
5297 *)
51665298 "ocaml", "setup.ml"
51675299 else
51685300 ocaml, setup_ml
51735305 OASISExec.run_read_one_line
51745306 ~ctxt:!BaseContext.default
51755307 ~f_exit_code:
5176 (function
5177 | 0 ->
5178 ()
5179 | 1 ->
5180 failwithf
5181 (f_ "Executable '%s' is probably an old version \
5182 of oasis (< 0.3.0), please update to version \
5183 v%s.")
5184 oasis_exec t.oasis_version
5185 | 127 ->
5186 failwithf
5187 (f_ "Cannot find executable '%s', please install \
5188 oasis v%s.")
5189 oasis_exec t.oasis_version
5190 | n ->
5191 failwithf
5192 (f_ "Command '%s version' exited with code %d.")
5193 oasis_exec n)
5308 (function
5309 | 0 ->
5310 ()
5311 | 1 ->
5312 failwithf
5313 (f_ "Executable '%s' is probably an old version \
5314 of oasis (< 0.3.0), please update to version \
5315 v%s.")
5316 oasis_exec t.oasis_version
5317 | 127 ->
5318 failwithf
5319 (f_ "Cannot find executable '%s', please install \
5320 oasis v%s.")
5321 oasis_exec t.oasis_version
5322 | n ->
5323 failwithf
5324 (f_ "Command '%s version' exited with code %d.")
5325 oasis_exec n)
51945326 oasis_exec ["version"]
51955327 in
5196 if OASISVersion.comparator_apply
5197 (OASISVersion.version_of_string oasis_exec_version)
5198 (OASISVersion.VGreaterEqual
5199 (OASISVersion.version_of_string t.oasis_version)) then
5200 begin
5201 (* We have a version >= for the executable oasis, proceed with
5202 * update.
5203 *)
5204 (* TODO: delegate this check to 'oasis setup'. *)
5205 if Sys.os_type = "Win32" then
5206 failwithf
5207 (f_ "It is not possible to update the running script \
5208 setup.ml on Windows. Please update setup.ml by \
5209 running '%s'.")
5210 (String.concat " " (oasis_exec :: "setup" :: t.oasis_setup_args))
5211 else
5212 begin
5213 OASISExec.run
5214 ~ctxt:!BaseContext.default
5215 ~f_exit_code:
5216 (function
5217 | 0 ->
5218 ()
5219 | n ->
5220 failwithf
5221 (f_ "Unable to update setup.ml using '%s', \
5222 please fix the problem and retry.")
5223 oasis_exec)
5224 oasis_exec ("setup" :: t.oasis_setup_args);
5225 OASISExec.run ~ctxt:!BaseContext.default ocaml (setup_ml :: args)
5226 end
5227 end
5228 else
5229 failwithf
5230 (f_ "The version of '%s' (v%s) doesn't match the version of \
5231 oasis used to generate the %s file. Please install at \
5232 least oasis v%s.")
5233 oasis_exec oasis_exec_version setup_ml t.oasis_version
5328 if OASISVersion.comparator_apply
5329 (OASISVersion.version_of_string oasis_exec_version)
5330 (OASISVersion.VGreaterEqual
5331 (OASISVersion.version_of_string t.oasis_version)) then
5332 begin
5333 (* We have a version >= for the executable oasis, proceed with
5334 * update.
5335 *)
5336 (* TODO: delegate this check to 'oasis setup'. *)
5337 if Sys.os_type = "Win32" then
5338 failwithf
5339 (f_ "It is not possible to update the running script \
5340 setup.ml on Windows. Please update setup.ml by \
5341 running '%s'.")
5342 (String.concat " " (oasis_exec :: "setup" :: t.oasis_setup_args))
5343 else
5344 begin
5345 OASISExec.run
5346 ~ctxt:!BaseContext.default
5347 ~f_exit_code:
5348 (fun n ->
5349 if n <> 0 then
5350 failwithf
5351 (f_ "Unable to update setup.ml using '%s', \
5352 please fix the problem and retry.")
5353 oasis_exec)
5354 oasis_exec ("setup" :: t.oasis_setup_args);
5355 OASISExec.run ~ctxt:!BaseContext.default ocaml (setup_ml :: args)
5356 end
5357 end
5358 else
5359 failwithf
5360 (f_ "The version of '%s' (v%s) doesn't match the version of \
5361 oasis used to generate the %s file. Please install at \
5362 least oasis v%s.")
5363 oasis_exec oasis_exec_version setup_ml t.oasis_version
52345364 in
52355365
52365366 if !update_setup_ml then
52475377 else
52485378 false
52495379 | None ->
5250 false
5380 false
52515381 with e ->
52525382 error
52535383 (f_ "Error when updating setup.ml. If you want to avoid this error, \
52615391
52625392
52635393 let setup t =
5264 let catch_exn =
5265 ref true
5266 in
5267 try
5268 let act_ref =
5269 ref (fun _ ->
5270 failwithf
5271 (f_ "No action defined, run '%s %s -help'")
5272 Sys.executable_name
5273 Sys.argv.(0))
5274
5275 in
5276 let extra_args_ref =
5277 ref []
5278 in
5279 let allow_empty_env_ref =
5280 ref false
5281 in
5282 let arg_handle ?(allow_empty_env=false) act =
5283 Arg.Tuple
5284 [
5285 Arg.Rest (fun str -> extra_args_ref := str :: !extra_args_ref);
5286
5287 Arg.Unit
5288 (fun () ->
5289 allow_empty_env_ref := allow_empty_env;
5290 act_ref := act);
5291 ]
5292 in
5293
5294 Arg.parse
5295 (Arg.align
5296 ([
5297 "-configure",
5298 arg_handle ~allow_empty_env:true configure,
5299 s_ "[options*] Configure the whole build process.";
5300
5301 "-build",
5302 arg_handle build,
5303 s_ "[options*] Build executables and libraries.";
5304
5305 "-doc",
5306 arg_handle doc,
5307 s_ "[options*] Build documents.";
5308
5309 "-test",
5310 arg_handle test,
5311 s_ "[options*] Run tests.";
5312
5313 "-all",
5314 arg_handle ~allow_empty_env:true all,
5315 s_ "[options*] Run configure, build, doc and test targets.";
5316
5317 "-install",
5318 arg_handle install,
5319 s_ "[options*] Install libraries, data, executables \
5320 and documents.";
5321
5322 "-uninstall",
5323 arg_handle uninstall,
5324 s_ "[options*] Uninstall libraries, data, executables \
5325 and documents.";
5326
5327 "-reinstall",
5328 arg_handle reinstall,
5329 s_ "[options*] Uninstall and install libraries, data, \
5330 executables and documents.";
5331
5332 "-clean",
5333 arg_handle ~allow_empty_env:true clean,
5334 s_ "[options*] Clean files generated by a build.";
5335
5336 "-distclean",
5337 arg_handle ~allow_empty_env:true distclean,
5338 s_ "[options*] Clean files generated by a build and configure.";
5339
5340 "-version",
5341 arg_handle ~allow_empty_env:true version,
5342 s_ " Display version of OASIS used to generate this setup.ml.";
5343
5344 "-no-catch-exn",
5345 Arg.Clear catch_exn,
5346 s_ " Don't catch exception, useful for debugging.";
5347 ]
5348 @
5394 let catch_exn = ref true in
5395 let act_ref =
5396 ref (fun ~ctxt:_ _ ->
5397 failwithf
5398 (f_ "No action defined, run '%s %s -help'")
5399 Sys.executable_name
5400 Sys.argv.(0))
5401
5402 in
5403 let extra_args_ref = ref [] in
5404 let allow_empty_env_ref = ref false in
5405 let arg_handle ?(allow_empty_env=false) act =
5406 Arg.Tuple
5407 [
5408 Arg.Rest (fun str -> extra_args_ref := str :: !extra_args_ref);
5409 Arg.Unit
5410 (fun () ->
5411 allow_empty_env_ref := allow_empty_env;
5412 act_ref := act);
5413 ]
5414 in
5415 try
5416 let () =
5417 Arg.parse
5418 (Arg.align
5419 ([
5420 "-configure",
5421 arg_handle ~allow_empty_env:true configure,
5422 s_ "[options*] Configure the whole build process.";
5423
5424 "-build",
5425 arg_handle build,
5426 s_ "[options*] Build executables and libraries.";
5427
5428 "-doc",
5429 arg_handle doc,
5430 s_ "[options*] Build documents.";
5431
5432 "-test",
5433 arg_handle test,
5434 s_ "[options*] Run tests.";
5435
5436 "-all",
5437 arg_handle ~allow_empty_env:true all,
5438 s_ "[options*] Run configure, build, doc and test targets.";
5439
5440 "-install",
5441 arg_handle install,
5442 s_ "[options*] Install libraries, data, executables \
5443 and documents.";
5444
5445 "-uninstall",
5446 arg_handle uninstall,
5447 s_ "[options*] Uninstall libraries, data, executables \
5448 and documents.";
5449
5450 "-reinstall",
5451 arg_handle reinstall,
5452 s_ "[options*] Uninstall and install libraries, data, \
5453 executables and documents.";
5454
5455 "-clean",
5456 arg_handle ~allow_empty_env:true clean,
5457 s_ "[options*] Clean files generated by a build.";
5458
5459 "-distclean",
5460 arg_handle ~allow_empty_env:true distclean,
5461 s_ "[options*] Clean files generated by a build and configure.";
5462
5463 "-version",
5464 arg_handle ~allow_empty_env:true version,
5465 s_ " Display version of OASIS used to generate this setup.ml.";
5466
5467 "-no-catch-exn",
5468 Arg.Clear catch_exn,
5469 s_ " Don't catch exception, useful for debugging.";
5470 ]
5471 @
53495472 (if t.setup_update then
53505473 [no_update_setup_ml_cli]
53515474 else
53525475 [])
5353 @ (BaseContext.args ())))
5354 (failwithf (f_ "Don't know what to do with '%s'"))
5355 (s_ "Setup and run build process current package\n");
5356
5357 (* Build initial environment *)
5358 load ~allow_empty:!allow_empty_env_ref ();
5359
5360 (** Initialize flags *)
5361 List.iter
5362 (function
5363 | Flag (cs, {flag_description = hlp;
5364 flag_default = choices}) ->
5365 begin
5366 let apply ?short_desc () =
5367 var_ignore
5368 (var_define
5369 ~cli:CLIEnable
5370 ?short_desc
5371 (OASISUtils.varname_of_string cs.cs_name)
5372 (fun () ->
5373 string_of_bool
5374 (var_choose
5375 ~name:(Printf.sprintf
5376 (f_ "default value of flag %s")
5377 cs.cs_name)
5378 ~printer:string_of_bool
5379 choices)))
5380 in
5381 match hlp with
5382 | Some hlp ->
5383 apply ~short_desc:(fun () -> hlp) ()
5384 | None ->
5385 apply ()
5386 end
5387 | _ ->
5388 ())
5389 t.package.sections;
5390
5391 BaseStandardVar.init t.package;
5392
5393 BaseDynVar.init t.package;
5394
5395 if t.setup_update && update_setup_ml t then
5396 ()
5397 else
5398 !act_ref t (Array.of_list (List.rev !extra_args_ref))
5399
5400 with e when !catch_exn ->
5401 error "%s" (Printexc.to_string e);
5402 exit 1
5476 @ (BaseContext.args ())))
5477 (failwithf (f_ "Don't know what to do with '%s'"))
5478 (s_ "Setup and run build process current package\n")
5479 in
5480
5481 (* Instantiate the context. *)
5482 let ctxt = !BaseContext.default in
5483
5484 (* Build initial environment *)
5485 load ~ctxt ~allow_empty:!allow_empty_env_ref ();
5486
5487 (** Initialize flags *)
5488 List.iter
5489 (function
5490 | Flag (cs, {flag_description = hlp;
5491 flag_default = choices}) ->
5492 begin
5493 let apply ?short_desc () =
5494 var_ignore
5495 (var_define
5496 ~cli:CLIEnable
5497 ?short_desc
5498 (OASISUtils.varname_of_string cs.cs_name)
5499 (fun () ->
5500 string_of_bool
5501 (var_choose
5502 ~name:(Printf.sprintf
5503 (f_ "default value of flag %s")
5504 cs.cs_name)
5505 ~printer:string_of_bool
5506 choices)))
5507 in
5508 match hlp with
5509 | Some hlp -> apply ~short_desc:(fun () -> hlp) ()
5510 | None -> apply ()
5511 end
5512 | _ ->
5513 ())
5514 t.package.sections;
5515
5516 BaseStandardVar.init t.package;
5517
5518 BaseDynVar.init ~ctxt t.package;
5519
5520 if not (t.setup_update && update_setup_ml t) then
5521 !act_ref ~ctxt t (Array.of_list (List.rev !extra_args_ref))
5522
5523 with e when !catch_exn ->
5524 error "%s" (Printexc.to_string e);
5525 exit 1
54035526
54045527
54055528 end
54065529
5407
5408 # 5409 "setup.ml"
5530 module BaseCompat = struct
5531 (* # 22 "src/base/BaseCompat.ml" *)
5532
5533 (** Compatibility layer to provide a stable API inside setup.ml.
5534 This layer allows OASIS to change in between minor versions
5535 (e.g. 0.4.6 -> 0.4.7) but still provides a stable API inside setup.ml. This
5536 enables to write functions that manipulate setup_t inside setup.ml. See
5537 deps.ml for an example.
5538
5539 The module opened by default will depend on the version of the _oasis. E.g.
5540 if we have "OASISFormat: 0.3", the module Compat_0_3 will be opened and
5541 the function Compat_0_3 will be called. If setup.ml is generated with the
5542 -nocompat, no module will be opened.
5543
5544 @author Sylvain Le Gall
5545 *)
5546
5547 module Compat_0_4 =
5548 struct
5549 let rctxt = ref !BaseContext.default
5550
5551 module BaseSetup =
5552 struct
5553 module Original = BaseSetup
5554
5555 open OASISTypes
5556
5557 type std_args_fun = package -> string array -> unit
5558 type ('a, 'b) section_args_fun =
5559 name * (package -> (common_section * 'a) -> string array -> 'b)
5560 type t =
5561 {
5562 configure: std_args_fun;
5563 build: std_args_fun;
5564 doc: ((doc, unit) section_args_fun) list;
5565 test: ((test, float) section_args_fun) list;
5566 install: std_args_fun;
5567 uninstall: std_args_fun;
5568 clean: std_args_fun list;
5569 clean_doc: (doc, unit) section_args_fun list;
5570 clean_test: (test, unit) section_args_fun list;
5571 distclean: std_args_fun list;
5572 distclean_doc: (doc, unit) section_args_fun list;
5573 distclean_test: (test, unit) section_args_fun list;
5574 package: package;
5575 oasis_fn: string option;
5576 oasis_version: string;
5577 oasis_digest: Digest.t option;
5578 oasis_exec: string option;
5579 oasis_setup_args: string list;
5580 setup_update: bool;
5581 }
5582
5583 let setup t =
5584 let mk_std_args_fun f =
5585 fun ~ctxt pkg args -> rctxt := ctxt; f pkg args
5586 in
5587 let mk_section_args_fun l =
5588 List.map
5589 (fun (nm, f) ->
5590 nm,
5591 (fun ~ctxt pkg sct args ->
5592 rctxt := ctxt;
5593 f pkg sct args))
5594 l
5595 in
5596 let t' =
5597 {
5598 Original.
5599 configure = mk_std_args_fun t.configure;
5600 build = mk_std_args_fun t.build;
5601 doc = mk_section_args_fun t.doc;
5602 test = mk_section_args_fun t.test;
5603 install = mk_std_args_fun t.install;
5604 uninstall = mk_std_args_fun t.uninstall;
5605 clean = List.map mk_std_args_fun t.clean;
5606 clean_doc = mk_section_args_fun t.clean_doc;
5607 clean_test = mk_section_args_fun t.clean_test;
5608 distclean = List.map mk_std_args_fun t.distclean;
5609 distclean_doc = mk_section_args_fun t.distclean_doc;
5610 distclean_test = mk_section_args_fun t.distclean_test;
5611
5612 package = t.package;
5613 oasis_fn = t.oasis_fn;
5614 oasis_version = t.oasis_version;
5615 oasis_digest = t.oasis_digest;
5616 oasis_exec = t.oasis_exec;
5617 oasis_setup_args = t.oasis_setup_args;
5618 setup_update = t.setup_update;
5619 }
5620 in
5621 Original.setup t'
5622
5623 end
5624
5625 let adapt_setup_t setup_t =
5626 let module O = BaseSetup.Original in
5627 let mk_std_args_fun f = fun pkg args -> f ~ctxt:!rctxt pkg args in
5628 let mk_section_args_fun l =
5629 List.map
5630 (fun (nm, f) -> nm, (fun pkg sct args -> f ~ctxt:!rctxt pkg sct args))
5631 l
5632 in
5633 {
5634 BaseSetup.
5635 configure = mk_std_args_fun setup_t.O.configure;
5636 build = mk_std_args_fun setup_t.O.build;
5637 doc = mk_section_args_fun setup_t.O.doc;
5638 test = mk_section_args_fun setup_t.O.test;
5639 install = mk_std_args_fun setup_t.O.install;
5640 uninstall = mk_std_args_fun setup_t.O.uninstall;
5641 clean = List.map mk_std_args_fun setup_t.O.clean;
5642 clean_doc = mk_section_args_fun setup_t.O.clean_doc;
5643 clean_test = mk_section_args_fun setup_t.O.clean_test;
5644 distclean = List.map mk_std_args_fun setup_t.O.distclean;
5645 distclean_doc = mk_section_args_fun setup_t.O.distclean_doc;
5646 distclean_test = mk_section_args_fun setup_t.O.distclean_test;
5647
5648 package = setup_t.O.package;
5649 oasis_fn = setup_t.O.oasis_fn;
5650 oasis_version = setup_t.O.oasis_version;
5651 oasis_digest = setup_t.O.oasis_digest;
5652 oasis_exec = setup_t.O.oasis_exec;
5653 oasis_setup_args = setup_t.O.oasis_setup_args;
5654 setup_update = setup_t.O.setup_update;
5655 }
5656 end
5657
5658
5659 module Compat_0_3 =
5660 struct
5661 include Compat_0_4
5662 end
5663
5664 end
5665
5666
5667 # 5668 "setup.ml"
54095668 module InternalConfigurePlugin = struct
54105669 (* # 22 "src/plugins/internal/InternalConfigurePlugin.ml" *)
54115670
54125671
54135672 (** Configure using internal scheme
54145673 @author Sylvain Le Gall
5415 *)
5674 *)
54165675
54175676
54185677 open BaseEnv
54235682
54245683
54255684 (** Configure build using provided series of check to be done
5426 * and then output corresponding file.
5427 *)
5428 let configure pkg argv =
5685 and then output corresponding file.
5686 *)
5687 let configure ~ctxt:_ pkg argv =
54295688 let var_ignore_eval var = let _s: string = var () in () in
54305689 let errors = ref SetString.empty in
54315690 let buff = Buffer.create 13 in
54475706 let check_tools lst =
54485707 List.iter
54495708 (function
5450 | ExternalTool tool ->
5451 begin
5452 try
5453 var_ignore_eval (BaseCheck.prog tool)
5454 with e ->
5455 warn_exception e;
5456 add_errors (f_ "Cannot find external tool '%s'") tool
5457 end
5458 | InternalExecutable nm1 ->
5459 (* Check that matching tool is built *)
5460 List.iter
5461 (function
5462 | Executable ({cs_name = nm2},
5463 {bs_build = build},
5464 _) when nm1 = nm2 ->
5465 if not (var_choose build) then
5466 add_errors
5467 (f_ "Cannot find buildable internal executable \
5468 '%s' when checking build depends")
5469 nm1
5470 | _ ->
5471 ())
5472 pkg.sections)
5709 | ExternalTool tool ->
5710 begin
5711 try
5712 var_ignore_eval (BaseCheck.prog tool)
5713 with e ->
5714 warn_exception e;
5715 add_errors (f_ "Cannot find external tool '%s'") tool
5716 end
5717 | InternalExecutable nm1 ->
5718 (* Check that matching tool is built *)
5719 List.iter
5720 (function
5721 | Executable ({cs_name = nm2; _},
5722 {bs_build = build; _},
5723 _) when nm1 = nm2 ->
5724 if not (var_choose build) then
5725 add_errors
5726 (f_ "Cannot find buildable internal executable \
5727 '%s' when checking build depends")
5728 nm1
5729 | _ ->
5730 ())
5731 pkg.sections)
54735732 lst
54745733 in
54755734
54935752 (* Check depends *)
54945753 List.iter
54955754 (function
5496 | FindlibPackage (findlib_pkg, version_comparator) ->
5497 begin
5498 try
5499 var_ignore_eval
5500 (BaseCheck.package ?version_comparator findlib_pkg)
5501 with e ->
5502 warn_exception e;
5503 match version_comparator with
5504 | None ->
5505 add_errors
5506 (f_ "Cannot find findlib package %s")
5507 findlib_pkg
5508 | Some ver_cmp ->
5509 add_errors
5510 (f_ "Cannot find findlib package %s (%s)")
5511 findlib_pkg
5512 (OASISVersion.string_of_comparator ver_cmp)
5513 end
5514 | InternalLibrary nm1 ->
5515 (* Check that matching library is built *)
5516 List.iter
5517 (function
5518 | Library ({cs_name = nm2},
5519 {bs_build = build},
5520 _) when nm1 = nm2 ->
5521 if not (var_choose build) then
5522 add_errors
5523 (f_ "Cannot find buildable internal library \
5524 '%s' when checking build depends")
5525 nm1
5526 | _ ->
5527 ())
5528 pkg.sections)
5755 | FindlibPackage (findlib_pkg, version_comparator) ->
5756 begin
5757 try
5758 var_ignore_eval
5759 (BaseCheck.package ?version_comparator findlib_pkg)
5760 with e ->
5761 warn_exception e;
5762 match version_comparator with
5763 | None ->
5764 add_errors
5765 (f_ "Cannot find findlib package %s")
5766 findlib_pkg
5767 | Some ver_cmp ->
5768 add_errors
5769 (f_ "Cannot find findlib package %s (%s)")
5770 findlib_pkg
5771 (OASISVersion.string_of_comparator ver_cmp)
5772 end
5773 | InternalLibrary nm1 ->
5774 (* Check that matching library is built *)
5775 List.iter
5776 (function
5777 | Library ({cs_name = nm2; _},
5778 {bs_build = build; _},
5779 _) when nm1 = nm2 ->
5780 if not (var_choose build) then
5781 add_errors
5782 (f_ "Cannot find buildable internal library \
5783 '%s' when checking build depends")
5784 nm1
5785 | _ ->
5786 ())
5787 pkg.sections)
55295788 bs.bs_build_depends
55305789 end
55315790 in
55375796 begin
55385797 match pkg.ocaml_version with
55395798 | Some ver_cmp ->
5540 begin
5541 try
5542 var_ignore_eval
5543 (BaseCheck.version
5544 "ocaml"
5545 ver_cmp
5546 BaseStandardVar.ocaml_version)
5547 with e ->
5548 warn_exception e;
5549 add_errors
5550 (f_ "OCaml version %s doesn't match version constraint %s")
5551 (BaseStandardVar.ocaml_version ())
5552 (OASISVersion.string_of_comparator ver_cmp)
5553 end
5799 begin
5800 try
5801 var_ignore_eval
5802 (BaseCheck.version
5803 "ocaml"
5804 ver_cmp
5805 BaseStandardVar.ocaml_version)
5806 with e ->
5807 warn_exception e;
5808 add_errors
5809 (f_ "OCaml version %s doesn't match version constraint %s")
5810 (BaseStandardVar.ocaml_version ())
5811 (OASISVersion.string_of_comparator ver_cmp)
5812 end
55545813 | None ->
5555 ()
5814 ()
55565815 end;
55575816
55585817 (* Findlib version *)
55595818 begin
55605819 match pkg.findlib_version with
55615820 | Some ver_cmp ->
5562 begin
5563 try
5564 var_ignore_eval
5565 (BaseCheck.version
5566 "findlib"
5567 ver_cmp
5568 BaseStandardVar.findlib_version)
5569 with e ->
5570 warn_exception e;
5571 add_errors
5572 (f_ "Findlib version %s doesn't match version constraint %s")
5573 (BaseStandardVar.findlib_version ())
5574 (OASISVersion.string_of_comparator ver_cmp)
5575 end
5821 begin
5822 try
5823 var_ignore_eval
5824 (BaseCheck.version
5825 "findlib"
5826 ver_cmp
5827 BaseStandardVar.findlib_version)
5828 with e ->
5829 warn_exception e;
5830 add_errors
5831 (f_ "Findlib version %s doesn't match version constraint %s")
5832 (BaseStandardVar.findlib_version ())
5833 (OASISVersion.string_of_comparator ver_cmp)
5834 end
55765835 | None ->
5577 ()
5836 ()
55785837 end;
55795838 (* Make sure the findlib version is fine for the OCaml compiler. *)
55805839 begin
55815840 let ocaml_ge4 =
55825841 OASISVersion.version_compare
5583 (OASISVersion.version_of_string (BaseStandardVar.ocaml_version()))
5842 (OASISVersion.version_of_string (BaseStandardVar.ocaml_version ()))
55845843 (OASISVersion.version_of_string "4.0.0") >= 0 in
55855844 if ocaml_ge4 then
55865845 let findlib_lt132 =
56055864 (* Check build depends *)
56065865 List.iter
56075866 (function
5608 | Executable (_, bs, _)
5609 | Library (_, bs, _) as sct ->
5610 build_checks sct bs
5611 | Doc (_, doc) ->
5612 if var_choose doc.doc_build then
5613 check_tools doc.doc_build_tools
5614 | Test (_, test) ->
5615 if var_choose test.test_run then
5616 check_tools test.test_tools
5617 | _ ->
5618 ())
5867 | Executable (_, bs, _)
5868 | Library (_, bs, _) as sct ->
5869 build_checks sct bs
5870 | Doc (_, doc) ->
5871 if var_choose doc.doc_build then
5872 check_tools doc.doc_build_tools
5873 | Test (_, test) ->
5874 if var_choose test.test_run then
5875 check_tools test.test_tools
5876 | _ ->
5877 ())
56195878 pkg.sections;
56205879
56215880 (* Check if we need native dynlink (presence of libraries that compile to
5622 * native)
5623 *)
5881 native)
5882 *)
56245883 begin
56255884 let has_cmxa =
56265885 List.exists
56275886 (function
5628 | Library (_, bs, _) ->
5629 var_choose bs.bs_build &&
5630 (bs.bs_compiled_object = Native ||
5631 (bs.bs_compiled_object = Best &&
5632 bool_of_string (BaseStandardVar.is_native ())))
5633 | _ ->
5634 false)
5887 | Library (_, bs, _) ->
5888 var_choose bs.bs_build &&
5889 (bs.bs_compiled_object = Native ||
5890 (bs.bs_compiled_object = Best &&
5891 bool_of_string (BaseStandardVar.is_native ())))
5892 | _ ->
5893 false)
56355894 pkg.sections
56365895 in
5637 if has_cmxa then
5638 var_ignore_eval BaseStandardVar.native_dynlink
5896 if has_cmxa then
5897 var_ignore_eval BaseStandardVar.native_dynlink
56395898 end;
56405899
56415900 (* Check errors *)
56645923 *)
56655924
56665925
5926 (* TODO: rewrite this module with OASISFileSystem. *)
5927
56675928 open BaseEnv
56685929 open BaseStandardVar
56695930 open BaseMessage
56735934 open OASISUtils
56745935
56755936
5676 let exec_hook =
5677 ref (fun (cs, bs, exec) -> cs, bs, exec)
5678
5679
5680 let lib_hook =
5681 ref (fun (cs, bs, lib) -> cs, bs, lib, [])
5682
5683
5684 let obj_hook =
5685 ref (fun (cs, bs, obj) -> cs, bs, obj, [])
5686
5687
5688 let doc_hook =
5689 ref (fun (cs, doc) -> cs, doc)
5690
5691
5692 let install_file_ev =
5693 "install-file"
5694
5695
5696 let install_dir_ev =
5697 "install-dir"
5698
5699
5700 let install_findlib_ev =
5701 "install-findlib"
5702
5703
5937 let exec_hook = ref (fun (cs, bs, exec) -> cs, bs, exec)
5938 let lib_hook = ref (fun (cs, bs, dn, lib) -> cs, bs, dn, lib, [])
5939 let obj_hook = ref (fun (cs, bs, dn, obj) -> cs, bs, dn, obj, [])
5940 let doc_hook = ref (fun (cs, doc) -> cs, doc)
5941
5942 let install_file_ev = "install-file"
5943 let install_dir_ev = "install-dir"
5944 let install_findlib_ev = "install-findlib"
5945
5946
5947 (* TODO: this can be more generic and used elsewhere. *)
57045948 let win32_max_command_line_length = 8000
57055949
57065950
57696013 ["install" :: findlib_name :: meta :: files]
57706014
57716015
5772 let install pkg argv =
6016 let install =
57736017
57746018 let in_destdir =
57756019 try
57846028 fun fn -> fn
57856029 in
57866030
5787 let install_file ?tgt_fn src_file envdir =
6031 let install_file ~ctxt ?(prepend_destdir=true) ?tgt_fn src_file envdir =
57886032 let tgt_dir =
5789 in_destdir (envdir ())
6033 if prepend_destdir then in_destdir (envdir ()) else envdir ()
57906034 in
57916035 let tgt_file =
57926036 Filename.concat
57996043 in
58006044 (* Create target directory if needed *)
58016045 OASISFileUtil.mkdir_parent
5802 ~ctxt:!BaseContext.default
6046 ~ctxt
58036047 (fun dn ->
58046048 info (f_ "Creating directory '%s'") dn;
5805 BaseLog.register install_dir_ev dn)
5806 tgt_dir;
6049 BaseLog.register ~ctxt install_dir_ev dn)
6050 (Filename.dirname tgt_file);
58076051
58086052 (* Really install files *)
58096053 info (f_ "Copying file '%s' to '%s'") src_file tgt_file;
5810 OASISFileUtil.cp ~ctxt:!BaseContext.default src_file tgt_file;
5811 BaseLog.register install_file_ev tgt_file
6054 OASISFileUtil.cp ~ctxt src_file tgt_file;
6055 BaseLog.register ~ctxt install_file_ev tgt_file
6056 in
6057
6058 (* Install the files for a library. *)
6059
6060 let install_lib_files ~ctxt findlib_name files =
6061 let findlib_dir =
6062 let dn =
6063 let findlib_destdir =
6064 OASISExec.run_read_one_line ~ctxt (ocamlfind ())
6065 ["printconf" ; "destdir"]
6066 in
6067 Filename.concat findlib_destdir findlib_name
6068 in
6069 fun () -> dn
6070 in
6071 let () =
6072 if not (OASISFileUtil.file_exists_case (findlib_dir ())) then
6073 failwithf
6074 (f_ "Directory '%s' doesn't exist for findlib library %s")
6075 (findlib_dir ()) findlib_name
6076 in
6077 let f dir file =
6078 let basename = Filename.basename file in
6079 let tgt_fn = Filename.concat dir basename in
6080 (* Destdir is already include in printconf. *)
6081 install_file ~ctxt ~prepend_destdir:false ~tgt_fn file findlib_dir
6082 in
6083 List.iter (fun (dir, files) -> List.iter (f dir) files) files ;
58126084 in
58136085
58146086 (* Install data into defined directory *)
5815 let install_data srcdir lst tgtdir =
6087 let install_data ~ctxt srcdir lst tgtdir =
58166088 let tgtdir =
58176089 OASISHostPath.of_unix (var_expand tgtdir)
58186090 in
58296101 src;
58306102 List.iter
58316103 (fun fn ->
5832 install_file
6104 install_file ~ctxt
58336105 fn
58346106 (fun () ->
58356107 match tgt_opt with
58446116 let make_fnames modul sufx =
58456117 List.fold_right
58466118 begin fun sufx accu ->
5847 (String.capitalize modul ^ sufx) ::
5848 (String.uncapitalize modul ^ sufx) ::
6119 (OASISString.capitalize_ascii modul ^ sufx) ::
6120 (OASISString.uncapitalize_ascii modul ^ sufx) ::
58496121 accu
58506122 end
58516123 sufx
58536125 in
58546126
58556127 (** Install all libraries *)
5856 let install_libs pkg =
6128 let install_libs ~ctxt pkg =
6129
6130 let find_first_existing_files_in_path bs lst =
6131 let path = OASISHostPath.of_unix bs.bs_path in
6132 List.find
6133 OASISFileUtil.file_exists_case
6134 (List.map (Filename.concat path) lst)
6135 in
6136
6137 let files_of_modules new_files typ cs bs modules =
6138 List.fold_left
6139 (fun acc modul ->
6140 begin
6141 try
6142 (* Add uncompiled header from the source tree *)
6143 [find_first_existing_files_in_path
6144 bs (make_fnames modul [".mli"; ".ml"])]
6145 with Not_found ->
6146 warning
6147 (f_ "Cannot find source header for module %s \
6148 in %s %s")
6149 typ modul cs.cs_name;
6150 []
6151 end
6152 @
6153 List.fold_left
6154 (fun acc fn ->
6155 try
6156 find_first_existing_files_in_path bs [fn] :: acc
6157 with Not_found ->
6158 acc)
6159 acc (make_fnames modul [".annot";".cmti";".cmt"]))
6160 new_files
6161 modules
6162 in
6163
6164 let files_of_build_section (f_data, new_files) typ cs bs =
6165 let extra_files =
6166 List.map
6167 (fun fn ->
6168 try
6169 find_first_existing_files_in_path bs [fn]
6170 with Not_found ->
6171 failwithf
6172 (f_ "Cannot find extra findlib file %S in %s %s ")
6173 fn
6174 typ
6175 cs.cs_name)
6176 bs.bs_findlib_extra_files
6177 in
6178 let f_data () =
6179 (* Install data associated with the library *)
6180 install_data
6181 ~ctxt
6182 bs.bs_path
6183 bs.bs_data_files
6184 (Filename.concat
6185 (datarootdir ())
6186 pkg.name);
6187 f_data ()
6188 in
6189 f_data, new_files @ extra_files
6190 in
58576191
58586192 let files_of_library (f_data, acc) data_lib =
5859 let cs, bs, lib, lib_extra =
5860 !lib_hook data_lib
5861 in
5862 if var_choose bs.bs_install &&
5863 BaseBuilt.is_built BaseBuilt.BLib cs.cs_name then
5864 begin
5865 let acc =
5866 (* Start with acc + lib_extra *)
5867 List.rev_append lib_extra acc
5868 in
5869 let acc =
5870 (* Add uncompiled header from the source tree *)
5871 let path =
5872 OASISHostPath.of_unix bs.bs_path
5873 in
5874 List.fold_left
5875 begin fun acc modul ->
5876 begin
5877 try
5878 [List.find
5879 OASISFileUtil.file_exists_case
5880 (List.map
5881 (Filename.concat path)
5882 (make_fnames modul [".mli"; ".ml"]))]
5883 with Not_found ->
5884 warning
5885 (f_ "Cannot find source header for module %s \
5886 in library %s")
5887 modul cs.cs_name;
5888 []
5889 end
5890 @
5891 List.filter
5892 OASISFileUtil.file_exists_case
5893 (List.map
5894 (Filename.concat path)
5895 (make_fnames modul [".annot";".cmti";".cmt"]))
5896 @ acc
5897 end
5898 acc
5899 lib.lib_modules
5900 in
5901
5902 let acc =
5903 (* Get generated files *)
5904 BaseBuilt.fold
5905 BaseBuilt.BLib
5906 cs.cs_name
5907 (fun acc fn -> fn :: acc)
5908 acc
5909 in
5910
5911 let f_data () =
5912 (* Install data associated with the library *)
5913 install_data
5914 bs.bs_path
5915 bs.bs_data_files
5916 (Filename.concat
5917 (datarootdir ())
5918 pkg.name);
5919 f_data ()
5920 in
5921
5922 (f_data, acc)
5923 end
5924 else
5925 begin
5926 (f_data, acc)
5927 end
6193 let cs, bs, lib, dn, lib_extra = !lib_hook data_lib in
6194 if var_choose bs.bs_install &&
6195 BaseBuilt.is_built ~ctxt BaseBuilt.BLib cs.cs_name then begin
6196 (* Start with lib_extra *)
6197 let new_files = lib_extra in
6198 let new_files =
6199 files_of_modules new_files "library" cs bs lib.lib_modules
6200 in
6201 let f_data, new_files =
6202 files_of_build_section (f_data, new_files) "library" cs bs
6203 in
6204 let new_files =
6205 (* Get generated files *)
6206 BaseBuilt.fold
6207 ~ctxt
6208 BaseBuilt.BLib
6209 cs.cs_name
6210 (fun acc fn -> fn :: acc)
6211 new_files
6212 in
6213 let acc = (dn, new_files) :: acc in
6214
6215 let f_data () =
6216 (* Install data associated with the library *)
6217 install_data
6218 ~ctxt
6219 bs.bs_path
6220 bs.bs_data_files
6221 (Filename.concat
6222 (datarootdir ())
6223 pkg.name);
6224 f_data ()
6225 in
6226
6227 (f_data, acc)
6228 end else begin
6229 (f_data, acc)
6230 end
59286231 and files_of_object (f_data, acc) data_obj =
5929 let cs, bs, obj, obj_extra =
5930 !obj_hook data_obj
5931 in
5932 if var_choose bs.bs_install &&
5933 BaseBuilt.is_built BaseBuilt.BObj cs.cs_name then
5934 begin
5935 let acc =
5936 (* Start with acc + obj_extra *)
5937 List.rev_append obj_extra acc
5938 in
5939 let acc =
5940 (* Add uncompiled header from the source tree *)
5941 let path =
5942 OASISHostPath.of_unix bs.bs_path
5943 in
5944 List.fold_left
5945 begin fun acc modul ->
5946 begin
5947 try
5948 [List.find
5949 OASISFileUtil.file_exists_case
5950 (List.map
5951 (Filename.concat path)
5952 (make_fnames modul [".mli"; ".ml"]))]
5953 with Not_found ->
5954 warning
5955 (f_ "Cannot find source header for module %s \
5956 in object %s")
5957 modul cs.cs_name;
5958 []
5959 end
5960 @
5961 List.filter
5962 OASISFileUtil.file_exists_case
5963 (List.map
5964 (Filename.concat path)
5965 (make_fnames modul [".annot";".cmti";".cmt"]))
5966 @ acc
5967 end
5968 acc
5969 obj.obj_modules
5970 in
5971
5972 let acc =
5973 (* Get generated files *)
5974 BaseBuilt.fold
5975 BaseBuilt.BObj
5976 cs.cs_name
5977 (fun acc fn -> fn :: acc)
5978 acc
5979 in
5980
5981 let f_data () =
5982 (* Install data associated with the object *)
5983 install_data
5984 bs.bs_path
5985 bs.bs_data_files
5986 (Filename.concat
5987 (datarootdir ())
5988 pkg.name);
5989 f_data ()
5990 in
5991
5992 (f_data, acc)
5993 end
5994 else
5995 begin
5996 (f_data, acc)
5997 end
5998
6232 let cs, bs, obj, dn, obj_extra = !obj_hook data_obj in
6233 if var_choose bs.bs_install &&
6234 BaseBuilt.is_built ~ctxt BaseBuilt.BObj cs.cs_name then begin
6235 (* Start with obj_extra *)
6236 let new_files = obj_extra in
6237 let new_files =
6238 files_of_modules new_files "object" cs bs obj.obj_modules
6239 in
6240 let f_data, new_files =
6241 files_of_build_section (f_data, new_files) "object" cs bs
6242 in
6243
6244 let new_files =
6245 (* Get generated files *)
6246 BaseBuilt.fold
6247 ~ctxt
6248 BaseBuilt.BObj
6249 cs.cs_name
6250 (fun acc fn -> fn :: acc)
6251 new_files
6252 in
6253 let acc = (dn, new_files) :: acc in
6254
6255 let f_data () =
6256 (* Install data associated with the object *)
6257 install_data
6258 ~ctxt
6259 bs.bs_path
6260 bs.bs_data_files
6261 (Filename.concat (datarootdir ()) pkg.name);
6262 f_data ()
6263 in
6264 (f_data, acc)
6265 end else begin
6266 (f_data, acc)
6267 end
59996268 in
60006269
60016270 (* Install one group of library *)
60066275 match grp with
60076276 | Container (_, children) ->
60086277 data_and_files, children
6009 | Package (_, cs, bs, `Library lib, children) ->
6010 files_of_library data_and_files (cs, bs, lib), children
6011 | Package (_, cs, bs, `Object obj, children) ->
6012 files_of_object data_and_files (cs, bs, obj), children
6278 | Package (_, cs, bs, `Library lib, dn, children) ->
6279 files_of_library data_and_files (cs, bs, lib, dn), children
6280 | Package (_, cs, bs, `Object obj, dn, children) ->
6281 files_of_object data_and_files (cs, bs, obj, dn), children
60136282 in
60146283 List.fold_left
60156284 install_group_lib_aux
60186287 in
60196288
60206289 (* Findlib name of the root library *)
6021 let findlib_name =
6022 findlib_of_group grp
6023 in
6290 let findlib_name = findlib_of_group grp in
60246291
60256292 (* Determine root library *)
6026 let root_lib =
6027 root_of_group grp
6028 in
6293 let root_lib = root_of_group grp in
60296294
60306295 (* All files to install for this library *)
6031 let f_data, files =
6032 install_group_lib_aux (ignore, []) grp
6033 in
6296 let f_data, files = install_group_lib_aux (ignore, []) grp in
60346297
60356298 (* Really install, if there is something to install *)
6036 if files = [] then
6037 begin
6038 warning
6039 (f_ "Nothing to install for findlib library '%s'")
6040 findlib_name
6041 end
6042 else
6043 begin
6044 let meta =
6045 (* Search META file *)
6046 let _, bs, _ =
6047 root_lib
6299 if files = [] then begin
6300 warning
6301 (f_ "Nothing to install for findlib library '%s'") findlib_name
6302 end else begin
6303 let meta =
6304 (* Search META file *)
6305 let _, bs, _ = root_lib in
6306 let res = Filename.concat bs.bs_path "META" in
6307 if not (OASISFileUtil.file_exists_case res) then
6308 failwithf
6309 (f_ "Cannot find file '%s' for findlib library %s")
6310 res
6311 findlib_name;
6312 res
6313 in
6314 let files =
6315 (* Make filename shorter to avoid hitting command max line length
6316 * too early, esp. on Windows.
6317 *)
6318 (* TODO: move to OASISHostPath as make_relative. *)
6319 let remove_prefix p n =
6320 let plen = String.length p in
6321 let nlen = String.length n in
6322 if plen <= nlen && String.sub n 0 plen = p then begin
6323 let fn_sep = if Sys.os_type = "Win32" then '\\' else '/' in
6324 let cutpoint =
6325 plen +
6326 (if plen < nlen && n.[plen] = fn_sep then 1 else 0)
60486327 in
6049 let res =
6050 Filename.concat bs.bs_path "META"
6051 in
6052 if not (OASISFileUtil.file_exists_case res) then
6053 failwithf
6054 (f_ "Cannot find file '%s' for findlib library %s")
6055 res
6056 findlib_name;
6057 res
6058 in
6059 let files =
6060 (* Make filename shorter to avoid hitting command max line length
6061 * too early, esp. on Windows.
6062 *)
6063 let remove_prefix p n =
6064 let plen = String.length p in
6065 let nlen = String.length n in
6066 if plen <= nlen && String.sub n 0 plen = p then
6067 begin
6068 let fn_sep =
6069 if Sys.os_type = "Win32" then
6070 '\\'
6071 else
6072 '/'
6073 in
6074 let cutpoint = plen +
6075 (if plen < nlen && n.[plen] = fn_sep then
6076 1
6077 else
6078 0)
6079 in
6080 String.sub n cutpoint (nlen - cutpoint)
6081 end
6082 else
6083 n
6084 in
6085 List.map (remove_prefix (Sys.getcwd ())) files
6086 in
6087 info
6088 (f_ "Installing findlib library '%s'")
6089 findlib_name;
6090 let ocamlfind = ocamlfind () in
6091 let commands =
6092 split_install_command
6093 ocamlfind
6094 findlib_name
6095 meta
6096 files
6097 in
6098 List.iter
6099 (OASISExec.run ~ctxt:!BaseContext.default ocamlfind)
6100 commands;
6101 BaseLog.register install_findlib_ev findlib_name
6102 end;
6103
6104 (* Install data files *)
6105 f_data ();
6106
6328 String.sub n cutpoint (nlen - cutpoint)
6329 end else begin
6330 n
6331 end
6332 in
6333 List.map
6334 (fun (dir, fn) ->
6335 (dir, List.map (remove_prefix (Sys.getcwd ())) fn))
6336 files
6337 in
6338 let ocamlfind = ocamlfind () in
6339 let nodir_files, dir_files =
6340 List.fold_left
6341 (fun (nodir, dir) (dn, lst) ->
6342 match dn with
6343 | Some dn -> nodir, (dn, lst) :: dir
6344 | None -> lst @ nodir, dir)
6345 ([], [])
6346 (List.rev files)
6347 in
6348 info (f_ "Installing findlib library '%s'") findlib_name;
6349 List.iter
6350 (OASISExec.run ~ctxt ocamlfind)
6351 (split_install_command ocamlfind findlib_name meta nodir_files);
6352 install_lib_files ~ctxt findlib_name dir_files;
6353 BaseLog.register ~ctxt install_findlib_ev findlib_name
6354 end;
6355
6356 (* Install data files *)
6357 f_data ();
61076358 in
61086359
6109 let group_libs, _, _ =
6110 findlib_mapping pkg
6111 in
6360 let group_libs, _, _ = findlib_mapping pkg in
61126361
61136362 (* We install libraries in groups *)
61146363 List.iter install_group_lib group_libs
61156364 in
61166365
6117 let install_execs pkg =
6366 let install_execs ~ctxt pkg =
61186367 let install_exec data_exec =
6119 let cs, bs, exec =
6120 !exec_hook data_exec
6121 in
6122 if var_choose bs.bs_install &&
6123 BaseBuilt.is_built BaseBuilt.BExec cs.cs_name then
6124 begin
6125 let exec_libdir () =
6126 Filename.concat
6127 (libdir ())
6128 pkg.name
6129 in
6130 BaseBuilt.fold
6131 BaseBuilt.BExec
6132 cs.cs_name
6133 (fun () fn ->
6134 install_file
6135 ~tgt_fn:(cs.cs_name ^ ext_program ())
6136 fn
6137 bindir)
6138 ();
6139 BaseBuilt.fold
6140 BaseBuilt.BExecLib
6141 cs.cs_name
6142 (fun () fn ->
6143 install_file
6144 fn
6145 exec_libdir)
6146 ();
6147 install_data
6148 bs.bs_path
6149 bs.bs_data_files
6150 (Filename.concat
6151 (datarootdir ())
6152 pkg.name)
6153 end
6368 let cs, bs, _ = !exec_hook data_exec in
6369 if var_choose bs.bs_install &&
6370 BaseBuilt.is_built ~ctxt BaseBuilt.BExec cs.cs_name then begin
6371 let exec_libdir () = Filename.concat (libdir ()) pkg.name in
6372 BaseBuilt.fold
6373 ~ctxt
6374 BaseBuilt.BExec
6375 cs.cs_name
6376 (fun () fn ->
6377 install_file ~ctxt
6378 ~tgt_fn:(cs.cs_name ^ ext_program ())
6379 fn
6380 bindir)
6381 ();
6382 BaseBuilt.fold
6383 ~ctxt
6384 BaseBuilt.BExecLib
6385 cs.cs_name
6386 (fun () fn -> install_file ~ctxt fn exec_libdir)
6387 ();
6388 install_data ~ctxt
6389 bs.bs_path
6390 bs.bs_data_files
6391 (Filename.concat (datarootdir ()) pkg.name)
6392 end
61546393 in
6155 List.iter
6156 (function
6157 | Executable (cs, bs, exec)->
6158 install_exec (cs, bs, exec)
6159 | _ ->
6160 ())
6394 List.iter
6395 (function
6396 | Executable (cs, bs, exec)-> install_exec (cs, bs, exec)
6397 | _ -> ())
61616398 pkg.sections
61626399 in
61636400
6164 let install_docs pkg =
6401 let install_docs ~ctxt pkg =
61656402 let install_doc data =
6166 let cs, doc =
6167 !doc_hook data
6168 in
6169 if var_choose doc.doc_install &&
6170 BaseBuilt.is_built BaseBuilt.BDoc cs.cs_name then
6171 begin
6172 let tgt_dir =
6173 OASISHostPath.of_unix (var_expand doc.doc_install_dir)
6174 in
6175 BaseBuilt.fold
6176 BaseBuilt.BDoc
6177 cs.cs_name
6178 (fun () fn ->
6179 install_file
6180 fn
6181 (fun () -> tgt_dir))
6182 ();
6183 install_data
6184 Filename.current_dir_name
6185 doc.doc_data_files
6186 doc.doc_install_dir
6187 end
6403 let cs, doc = !doc_hook data in
6404 if var_choose doc.doc_install &&
6405 BaseBuilt.is_built ~ctxt BaseBuilt.BDoc cs.cs_name then begin
6406 let tgt_dir = OASISHostPath.of_unix (var_expand doc.doc_install_dir) in
6407 BaseBuilt.fold
6408 ~ctxt
6409 BaseBuilt.BDoc
6410 cs.cs_name
6411 (fun () fn -> install_file ~ctxt fn (fun () -> tgt_dir))
6412 ();
6413 install_data ~ctxt
6414 Filename.current_dir_name
6415 doc.doc_data_files
6416 doc.doc_install_dir
6417 end
61886418 in
6189 List.iter
6190 (function
6191 | Doc (cs, doc) ->
6192 install_doc (cs, doc)
6193 | _ ->
6194 ())
6195 pkg.sections
6196 in
6197
6198 install_libs pkg;
6199 install_execs pkg;
6200 install_docs pkg
6419 List.iter
6420 (function
6421 | Doc (cs, doc) -> install_doc (cs, doc)
6422 | _ -> ())
6423 pkg.sections
6424 in
6425 fun ~ctxt pkg _ ->
6426 install_libs ~ctxt pkg;
6427 install_execs ~ctxt pkg;
6428 install_docs ~ctxt pkg
62016429
62026430
62036431 (* Uninstall already installed data *)
6204 let uninstall _ argv =
6205 List.iter
6206 (fun (ev, data) ->
6207 if ev = install_file_ev then
6208 begin
6209 if OASISFileUtil.file_exists_case data then
6210 begin
6211 info
6212 (f_ "Removing file '%s'")
6213 data;
6214 Sys.remove data
6215 end
6216 else
6217 begin
6218 warning
6219 (f_ "File '%s' doesn't exist anymore")
6220 data
6221 end
6222 end
6223 else if ev = install_dir_ev then
6224 begin
6225 if Sys.file_exists data && Sys.is_directory data then
6226 begin
6227 if Sys.readdir data = [||] then
6228 begin
6229 info
6230 (f_ "Removing directory '%s'")
6231 data;
6232 OASISFileUtil.rmdir ~ctxt:!BaseContext.default data
6233 end
6234 else
6235 begin
6236 warning
6237 (f_ "Directory '%s' is not empty (%s)")
6238 data
6239 (String.concat
6240 ", "
6241 (Array.to_list
6242 (Sys.readdir data)))
6243 end
6244 end
6245 else
6246 begin
6247 warning
6248 (f_ "Directory '%s' doesn't exist anymore")
6249 data
6250 end
6251 end
6252 else if ev = install_findlib_ev then
6253 begin
6254 info (f_ "Removing findlib library '%s'") data;
6255 OASISExec.run ~ctxt:!BaseContext.default
6256 (ocamlfind ()) ["remove"; data]
6257 end
6258 else
6259 failwithf (f_ "Unknown log event '%s'") ev;
6260 BaseLog.unregister ev data)
6261 (* We process event in reverse order *)
6432 let uninstall ~ctxt _ _ =
6433 let uninstall_aux (ev, data) =
6434 if ev = install_file_ev then begin
6435 if OASISFileUtil.file_exists_case data then begin
6436 info (f_ "Removing file '%s'") data;
6437 Sys.remove data
6438 end else begin
6439 warning (f_ "File '%s' doesn't exist anymore") data
6440 end
6441 end else if ev = install_dir_ev then begin
6442 if Sys.file_exists data && Sys.is_directory data then begin
6443 if Sys.readdir data = [||] then begin
6444 info (f_ "Removing directory '%s'") data;
6445 OASISFileUtil.rmdir ~ctxt data
6446 end else begin
6447 warning
6448 (f_ "Directory '%s' is not empty (%s)")
6449 data
6450 (String.concat ", " (Array.to_list (Sys.readdir data)))
6451 end
6452 end else begin
6453 warning (f_ "Directory '%s' doesn't exist anymore") data
6454 end
6455 end else if ev = install_findlib_ev then begin
6456 info (f_ "Removing findlib library '%s'") data;
6457 OASISExec.run ~ctxt (ocamlfind ()) ["remove"; data]
6458 end else begin
6459 failwithf (f_ "Unknown log event '%s'") ev;
6460 end;
6461 BaseLog.unregister ~ctxt ev data
6462 in
6463 (* We process event in reverse order *)
6464 List.iter uninstall_aux
62626465 (List.rev
6263 (BaseLog.filter
6264 [install_file_ev;
6265 install_dir_ev;
6266 install_findlib_ev]))
6267
6466 (BaseLog.filter ~ctxt [install_file_ev; install_dir_ev]));
6467 List.iter uninstall_aux
6468 (List.rev (BaseLog.filter ~ctxt [install_findlib_ev]))
62686469
62696470 end
62706471
62716472
6272 # 6273 "setup.ml"
6473 # 6474 "setup.ml"
62736474 module OCamlbuildCommon = struct
62746475 (* # 22 "src/plugins/ocamlbuild/OCamlbuildCommon.ml" *)
62756476
62766477
62776478 (** Functions common to OCamlbuild build and doc plugin
6278 *)
6479 *)
62796480
62806481
62816482 open OASISGettext
62826483 open BaseEnv
62836484 open BaseStandardVar
62846485 open OASISTypes
6285
6286
62876486
62886487
62896488 type extra_args = string list
63086507 "-classic-display";
63096508 "-no-log";
63106509 "-no-links";
6510 ]
6511 else
6512 [];
6513
6514 if OASISVersion.comparator_apply
6515 (OASISVersion.version_of_string (ocaml_version ()))
6516 (OASISVersion.VLesser (OASISVersion.version_of_string "3.11.1")) then
6517 [
63116518 "-install-lib-dir";
63126519 (Filename.concat (standard_library ()) "ocamlbuild")
63136520 ]
63446551
63456552
63466553 (** Run 'ocamlbuild -clean' if not already done *)
6347 let run_clean extra_argv =
6554 let run_clean ~ctxt extra_argv =
63486555 let extra_cli =
63496556 String.concat " " (Array.to_list extra_argv)
63506557 in
6351 (* Run if never called with these args *)
6352 if not (BaseLog.exists ocamlbuild_clean_ev extra_cli) then
6353 begin
6354 OASISExec.run ~ctxt:!BaseContext.default
6355 (ocamlbuild ()) (fix_args ["-clean"] extra_argv);
6356 BaseLog.register ocamlbuild_clean_ev extra_cli;
6357 at_exit
6358 (fun () ->
6359 try
6360 BaseLog.unregister ocamlbuild_clean_ev extra_cli
6361 with _ ->
6362 ())
6363 end
6558 (* Run if never called with these args *)
6559 if not (BaseLog.exists ~ctxt ocamlbuild_clean_ev extra_cli) then
6560 begin
6561 OASISExec.run ~ctxt (ocamlbuild ()) (fix_args ["-clean"] extra_argv);
6562 BaseLog.register ~ctxt ocamlbuild_clean_ev extra_cli;
6563 at_exit
6564 (fun () ->
6565 try
6566 BaseLog.unregister ~ctxt ocamlbuild_clean_ev extra_cli
6567 with _ -> ())
6568 end
63646569
63656570
63666571 (** Run ocamlbuild, unregister all clean events *)
6367 let run_ocamlbuild args extra_argv =
6572 let run_ocamlbuild ~ctxt args extra_argv =
63686573 (* TODO: enforce that target in args must be UNIX encoded i.e. toto/index.html
6369 *)
6370 OASISExec.run ~ctxt:!BaseContext.default
6371 (ocamlbuild ()) (fix_args args extra_argv);
6574 *)
6575 OASISExec.run ~ctxt (ocamlbuild ()) (fix_args args extra_argv);
63726576 (* Remove any clean event, we must run it again *)
63736577 List.iter
6374 (fun (e, d) -> BaseLog.unregister e d)
6375 (BaseLog.filter [ocamlbuild_clean_ev])
6578 (fun (e, d) -> BaseLog.unregister ~ctxt e d)
6579 (BaseLog.filter ~ctxt [ocamlbuild_clean_ev])
63766580
63776581
63786582 (** Determine real build directory *)
63806584 let rec search_args dir =
63816585 function
63826586 | "-build-dir" :: dir :: tl ->
6383 search_args dir tl
6587 search_args dir tl
63846588 | _ :: tl ->
6385 search_args dir tl
6589 search_args dir tl
63866590 | [] ->
6387 dir
6388 in
6389 search_args "_build" (fix_args [] extra_argv)
6591 dir
6592 in
6593 search_args "_build" (fix_args [] extra_argv)
63906594
63916595
63926596 end
64076611 open BaseEnv
64086612 open OCamlbuildCommon
64096613 open BaseStandardVar
6410 open BaseMessage
6411
6412
6413
6414
6415
6416 let cond_targets_hook =
6417 ref (fun lst -> lst)
6418
6419
6420 let build extra_args pkg argv =
6614
6615
6616 let cond_targets_hook = ref (fun lst -> lst)
6617
6618
6619 let build ~ctxt extra_args pkg argv =
64216620 (* Return the filename in build directory *)
64226621 let in_build_dir fn =
64236622 Filename.concat
64816680 (List.map
64826681 (List.filter
64836682 (fun fn ->
6484 ends_with ".cmo" fn
6485 || ends_with ".cmx" fn))
6683 ends_with ~what:".cmo" fn
6684 || ends_with ~what:".cmx" fn))
64866685 unix_files))
64876686 in
64886687
64976696
64986697 | Executable (cs, bs, exec) when var_choose bs.bs_build ->
64996698 begin
6500 let evs, unix_exec_is, unix_dll_opt =
6501 BaseBuilt.of_executable
6502 in_build_dir_of_unix
6503 (cs, bs, exec)
6699 let evs, _, _ =
6700 BaseBuilt.of_executable in_build_dir_of_unix (cs, bs, exec)
65046701 in
65056702
65066703 let target ext =
65146711 (* Fix evs, we want to use the unix_tgt, without copying *)
65156712 List.map
65166713 (function
6517 | BaseBuilt.BExec, nm, lst when nm = cs.cs_name ->
6714 | BaseBuilt.BExec, nm, _ when nm = cs.cs_name ->
65186715 BaseBuilt.BExec, nm,
65196716 [[in_build_dir_of_unix unix_tgt]]
65206717 | ev ->
65586755 (List.length fns))
65596756 (String.concat (s_ " or ") (List.map (Printf.sprintf "'%s'") fns)))
65606757 lst;
6561 (BaseBuilt.register bt bnm lst)
6758 (BaseBuilt.register ~ctxt bt bnm lst)
65626759 in
65636760
65646761 (* Run the hook *)
65656762 let cond_targets = !cond_targets_hook cond_targets in
65666763
65676764 (* Run a list of target... *)
6568 run_ocamlbuild (List.flatten (List.map snd cond_targets) @ extra_args) argv;
6765 run_ocamlbuild
6766 ~ctxt
6767 (List.flatten (List.map snd cond_targets) @ extra_args)
6768 argv;
65696769 (* ... and register events *)
65706770 List.iter check_and_register (List.flatten (List.map fst cond_targets))
65716771
65726772
6573 let clean pkg extra_args =
6574 run_clean extra_args;
6773 let clean ~ctxt pkg extra_args =
6774 run_clean ~ctxt extra_args;
65756775 List.iter
65766776 (function
65776777 | Library (cs, _, _) ->
6578 BaseBuilt.unregister BaseBuilt.BLib cs.cs_name
6778 BaseBuilt.unregister ~ctxt BaseBuilt.BLib cs.cs_name
65796779 | Executable (cs, _, _) ->
6580 BaseBuilt.unregister BaseBuilt.BExec cs.cs_name;
6581 BaseBuilt.unregister BaseBuilt.BExecLib cs.cs_name
6780 BaseBuilt.unregister ~ctxt BaseBuilt.BExec cs.cs_name;
6781 BaseBuilt.unregister ~ctxt BaseBuilt.BExecLib cs.cs_name
65826782 | _ ->
65836783 ())
65846784 pkg.sections
65926792
65936793 (* Create documentation using ocamlbuild .odocl files
65946794 @author Sylvain Le Gall
6595 *)
6795 *)
65966796
65976797
65986798 open OASISTypes
65996799 open OASISGettext
6600 open OASISMessage
66016800 open OCamlbuildCommon
6602 open BaseStandardVar
6603
6604
66056801
66066802
66076803 type run_t =
66116807 }
66126808
66136809
6614 let doc_build run pkg (cs, doc) argv =
6810 let doc_build ~ctxt run _ (cs, _) argv =
66156811 let index_html =
66166812 OASISUnixPath.make
66176813 [
66286824 cs.cs_name^".docdir";
66296825 ]
66306826 in
6631 run_ocamlbuild (index_html :: run.extra_args) argv;
6632 List.iter
6633 (fun glb ->
6634 BaseBuilt.register
6635 BaseBuilt.BDoc
6636 cs.cs_name
6637 [OASISFileUtil.glob ~ctxt:!BaseContext.default
6638 (Filename.concat tgt_dir glb)])
6639 ["*.html"; "*.css"]
6640
6641
6642 let doc_clean run pkg (cs, doc) argv =
6643 run_clean argv;
6644 BaseBuilt.unregister BaseBuilt.BDoc cs.cs_name
6827 run_ocamlbuild ~ctxt (index_html :: run.extra_args) argv;
6828 List.iter
6829 (fun glb ->
6830 BaseBuilt.register
6831 ~ctxt
6832 BaseBuilt.BDoc
6833 cs.cs_name
6834 [OASISFileUtil.glob ~ctxt (Filename.concat tgt_dir glb)])
6835 ["*.html"; "*.css"]
6836
6837
6838 let doc_clean ~ctxt _ _ (cs, _) argv =
6839 run_clean ~ctxt argv;
6840 BaseBuilt.unregister ~ctxt BaseBuilt.BDoc cs.cs_name
66456841
66466842
66476843 end
66486844
66496845
6650 # 6651 "setup.ml"
6846 # 6847 "setup.ml"
66516847 module CustomPlugin = struct
66526848 (* # 22 "src/plugins/custom/CustomPlugin.ml" *)
66536849
66546850
66556851 (** Generate custom configure/build/doc/test/install system
66566852 @author
6657 *)
6853 *)
66586854
66596855
66606856 open BaseEnv
66616857 open OASISGettext
66626858 open OASISTypes
66636859
6664
6665
6666
6667
66686860 type t =
6669 {
6670 cmd_main: command_line conditional;
6671 cmd_clean: (command_line option) conditional;
6672 cmd_distclean: (command_line option) conditional;
6673 }
6861 {
6862 cmd_main: command_line conditional;
6863 cmd_clean: (command_line option) conditional;
6864 cmd_distclean: (command_line option) conditional;
6865 }
66746866
66756867
66766868 let run = BaseCustom.run
66776869
66786870
6679 let main t _ extra_args =
6680 let cmd, args =
6681 var_choose
6682 ~name:(s_ "main command")
6683 t.cmd_main
6684 in
6685 run cmd args extra_args
6686
6687
6688 let clean t pkg extra_args =
6871 let main ~ctxt:_ t _ extra_args =
6872 let cmd, args = var_choose ~name:(s_ "main command") t.cmd_main in
6873 run cmd args extra_args
6874
6875
6876 let clean ~ctxt:_ t _ extra_args =
66896877 match var_choose t.cmd_clean with
6690 | Some (cmd, args) ->
6691 run cmd args extra_args
6692 | _ ->
6693 ()
6694
6695
6696 let distclean t pkg extra_args =
6878 | Some (cmd, args) -> run cmd args extra_args
6879 | _ -> ()
6880
6881
6882 let distclean ~ctxt:_ t _ extra_args =
66976883 match var_choose t.cmd_distclean with
6698 | Some (cmd, args) ->
6699 run cmd args extra_args
6700 | _ ->
6701 ()
6884 | Some (cmd, args) -> run cmd args extra_args
6885 | _ -> ()
67026886
67036887
67046888 module Build =
67056889 struct
6706 let main t pkg extra_args =
6707 main t pkg extra_args;
6890 let main ~ctxt t pkg extra_args =
6891 main ~ctxt t pkg extra_args;
67086892 List.iter
67096893 (fun sct ->
67106894 let evs =
67116895 match sct with
67126896 | Library (cs, bs, lib) when var_choose bs.bs_build ->
6713 begin
6714 let evs, _ =
6715 BaseBuilt.of_library
6716 OASISHostPath.of_unix
6717 (cs, bs, lib)
6718 in
6719 evs
6720 end
6897 begin
6898 let evs, _ =
6899 BaseBuilt.of_library
6900 OASISHostPath.of_unix
6901 (cs, bs, lib)
6902 in
6903 evs
6904 end
67216905 | Executable (cs, bs, exec) when var_choose bs.bs_build ->
6722 begin
6723 let evs, _, _ =
6724 BaseBuilt.of_executable
6725 OASISHostPath.of_unix
6726 (cs, bs, exec)
6727 in
6728 evs
6729 end
6906 begin
6907 let evs, _, _ =
6908 BaseBuilt.of_executable
6909 OASISHostPath.of_unix
6910 (cs, bs, exec)
6911 in
6912 evs
6913 end
67306914 | _ ->
6731 []
6915 []
67326916 in
6733 List.iter
6734 (fun (bt, bnm, lst) -> BaseBuilt.register bt bnm lst)
6735 evs)
6917 List.iter
6918 (fun (bt, bnm, lst) -> BaseBuilt.register ~ctxt bt bnm lst)
6919 evs)
67366920 pkg.sections
67376921
6738 let clean t pkg extra_args =
6739 clean t pkg extra_args;
6922 let clean ~ctxt t pkg extra_args =
6923 clean ~ctxt t pkg extra_args;
67406924 (* TODO: this seems to be pretty generic (at least wrt to ocamlbuild
67416925 * considering moving this to BaseSetup?
67426926 *)
67436927 List.iter
67446928 (function
6745 | Library (cs, _, _) ->
6746 BaseBuilt.unregister BaseBuilt.BLib cs.cs_name
6747 | Executable (cs, _, _) ->
6748 BaseBuilt.unregister BaseBuilt.BExec cs.cs_name;
6749 BaseBuilt.unregister BaseBuilt.BExecLib cs.cs_name
6750 | _ ->
6751 ())
6929 | Library (cs, _, _) ->
6930 BaseBuilt.unregister ~ctxt BaseBuilt.BLib cs.cs_name
6931 | Executable (cs, _, _) ->
6932 BaseBuilt.unregister ~ctxt BaseBuilt.BExec cs.cs_name;
6933 BaseBuilt.unregister ~ctxt BaseBuilt.BExecLib cs.cs_name
6934 | _ ->
6935 ())
67526936 pkg.sections
67536937
6754 let distclean t pkg extra_args =
6755 distclean t pkg extra_args
6938 let distclean ~ctxt t pkg extra_args = distclean ~ctxt t pkg extra_args
67566939 end
67576940
67586941
67596942 module Test =
67606943 struct
6761 let main t pkg (cs, test) extra_args =
6944 let main ~ctxt t pkg (cs, _) extra_args =
67626945 try
6763 main t pkg extra_args;
6946 main ~ctxt t pkg extra_args;
67646947 0.0
67656948 with Failure s ->
67666949 BaseMessage.warning
67696952 s;
67706953 1.0
67716954
6772 let clean t pkg (cs, test) extra_args =
6773 clean t pkg extra_args
6774
6775 let distclean t pkg (cs, test) extra_args =
6776 distclean t pkg extra_args
6955 let clean ~ctxt t pkg _ extra_args = clean ~ctxt t pkg extra_args
6956
6957 let distclean ~ctxt t pkg _ extra_args = distclean ~ctxt t pkg extra_args
67776958 end
67786959
67796960
67806961 module Doc =
67816962 struct
6782 let main t pkg (cs, _) extra_args =
6783 main t pkg extra_args;
6784 BaseBuilt.register BaseBuilt.BDoc cs.cs_name []
6785
6786 let clean t pkg (cs, _) extra_args =
6787 clean t pkg extra_args;
6788 BaseBuilt.unregister BaseBuilt.BDoc cs.cs_name
6789
6790 let distclean t pkg (cs, _) extra_args =
6791 distclean t pkg extra_args
6963 let main ~ctxt t pkg (cs, _) extra_args =
6964 main ~ctxt t pkg extra_args;
6965 BaseBuilt.register ~ctxt BaseBuilt.BDoc cs.cs_name []
6966
6967 let clean ~ctxt t pkg (cs, _) extra_args =
6968 clean ~ctxt t pkg extra_args;
6969 BaseBuilt.unregister ~ctxt BaseBuilt.BDoc cs.cs_name
6970
6971 let distclean ~ctxt t pkg _ extra_args = distclean ~ctxt t pkg extra_args
67926972 end
67936973
67946974
67956975 end
67966976
67976977
6798 # 6799 "setup.ml"
6978 # 6979 "setup.ml"
67996979 open OASISTypes;;
68006980
68016981 let setup_t =
68567036 {
68577037 oasis_version = "0.4";
68587038 ocaml_version = None;
6859 findlib_version = None;
6860 alpha_features = [];
6861 beta_features = [];
6862 name = "extunix";
6863 version = "0.1.3";
7039 version = "0.1.4";
68647040 license =
68657041 OASISLicense.DEP5License
68667042 (OASISLicense.DEP5Unit
68697045 excption = Some "OCaml linking";
68707046 version = OASISLicense.Version "2.1"
68717047 });
7048 findlib_version = None;
7049 alpha_features = [];
7050 beta_features = [];
7051 name = "extunix";
68727052 license_file = None;
68737053 copyrights =
68747054 [
69087088 "Fran\195\167ois Bobot"
69097089 ];
69107090 homepage = Some "http://extunix.forge.ocamlcore.org/";
7091 bugreports = None;
69117092 synopsis = "Extended functions for OCaml Unix module";
69127093 description =
69137094 Some
69197100 OASISText.Verbatim
69207101 " fallocate, openat, dirfd, eventfd, signalfd, setrlimit, mlockall, etc"
69217102 ];
7103 tags = [];
69227104 categories = [];
6923 conf_type = (`Configure, "internal", Some "0.4");
6924 conf_custom =
6925 {
6926 pre_command = [(OASISExpr.EBool true, None)];
6927 post_command =
6928 [
6929 (OASISExpr.EBool true,
6930 Some
6931 (("ocaml",
6932 [
6933 "src/discover.ml";
6934 "-ocamlc";
6935 "$ocamlc";
6936 "-ext_obj";
6937 "$ext_obj"
6938 ])))
6939 ]
6940 };
6941 build_type = (`Build, "ocamlbuild", Some "0.4");
6942 build_custom =
6943 {
6944 pre_command = [(OASISExpr.EBool true, None)];
6945 post_command = [(OASISExpr.EBool true, None)]
6946 };
6947 install_type = (`Install, "internal", Some "0.4");
6948 install_custom =
6949 {
6950 pre_command = [(OASISExpr.EBool true, None)];
6951 post_command = [(OASISExpr.EBool true, None)]
6952 };
6953 uninstall_custom =
6954 {
6955 pre_command = [(OASISExpr.EBool true, None)];
6956 post_command = [(OASISExpr.EBool true, None)]
6957 };
6958 clean_custom =
6959 {
6960 pre_command = [(OASISExpr.EBool true, None)];
6961 post_command = [(OASISExpr.EBool true, None)]
6962 };
6963 distclean_custom =
6964 {
6965 pre_command =
6966 [
6967 (OASISExpr.EBool true,
6968 Some (("$rm", ["$(utoh \"src/config.h\")"])))
6969 ];
6970 post_command =
6971 [
6972 (OASISExpr.EBool true,
6973 Some (("$rm", ["$(utoh \"src/config.ml\")"])))
6974 ]
6975 };
69767105 files_ab = [];
69777106 sections =
69787107 [
70007129 bs_build_depends =
70017130 [
70027131 FindlibPackage ("unix", None);
7003 FindlibPackage ("bigarray", None)
7132 FindlibPackage ("bigarray", None);
7133 FindlibPackage ("bytes", None)
70047134 ];
70057135 bs_build_tools =
70067136 [ExternalTool "ocamlbuild"; ExternalTool "camlp4"];
7137 bs_interface_patterns =
7138 [
7139 {
7140 OASISSourcePatterns.Templater.atoms =
7141 [
7142 OASISSourcePatterns.Templater.Text "";
7143 OASISSourcePatterns.Templater.Expr
7144 (OASISSourcePatterns.Templater.Call
7145 ("capitalize_file",
7146 OASISSourcePatterns.Templater.Ident
7147 "module"));
7148 OASISSourcePatterns.Templater.Text ".mli"
7149 ];
7150 origin = "${capitalize_file module}.mli"
7151 };
7152 {
7153 OASISSourcePatterns.Templater.atoms =
7154 [
7155 OASISSourcePatterns.Templater.Text "";
7156 OASISSourcePatterns.Templater.Expr
7157 (OASISSourcePatterns.Templater.Call
7158 ("uncapitalize_file",
7159 OASISSourcePatterns.Templater.Ident
7160 "module"));
7161 OASISSourcePatterns.Templater.Text ".mli"
7162 ];
7163 origin = "${uncapitalize_file module}.mli"
7164 }
7165 ];
7166 bs_implementation_patterns =
7167 [
7168 {
7169 OASISSourcePatterns.Templater.atoms =
7170 [
7171 OASISSourcePatterns.Templater.Text "";
7172 OASISSourcePatterns.Templater.Expr
7173 (OASISSourcePatterns.Templater.Call
7174 ("capitalize_file",
7175 OASISSourcePatterns.Templater.Ident
7176 "module"));
7177 OASISSourcePatterns.Templater.Text ".ml"
7178 ];
7179 origin = "${capitalize_file module}.ml"
7180 };
7181 {
7182 OASISSourcePatterns.Templater.atoms =
7183 [
7184 OASISSourcePatterns.Templater.Text "";
7185 OASISSourcePatterns.Templater.Expr
7186 (OASISSourcePatterns.Templater.Call
7187 ("uncapitalize_file",
7188 OASISSourcePatterns.Templater.Ident
7189 "module"));
7190 OASISSourcePatterns.Templater.Text ".ml"
7191 ];
7192 origin = "${uncapitalize_file module}.ml"
7193 };
7194 {
7195 OASISSourcePatterns.Templater.atoms =
7196 [
7197 OASISSourcePatterns.Templater.Text "";
7198 OASISSourcePatterns.Templater.Expr
7199 (OASISSourcePatterns.Templater.Call
7200 ("capitalize_file",
7201 OASISSourcePatterns.Templater.Ident
7202 "module"));
7203 OASISSourcePatterns.Templater.Text ".mll"
7204 ];
7205 origin = "${capitalize_file module}.mll"
7206 };
7207 {
7208 OASISSourcePatterns.Templater.atoms =
7209 [
7210 OASISSourcePatterns.Templater.Text "";
7211 OASISSourcePatterns.Templater.Expr
7212 (OASISSourcePatterns.Templater.Call
7213 ("uncapitalize_file",
7214 OASISSourcePatterns.Templater.Ident
7215 "module"));
7216 OASISSourcePatterns.Templater.Text ".mll"
7217 ];
7218 origin = "${uncapitalize_file module}.mll"
7219 };
7220 {
7221 OASISSourcePatterns.Templater.atoms =
7222 [
7223 OASISSourcePatterns.Templater.Text "";
7224 OASISSourcePatterns.Templater.Expr
7225 (OASISSourcePatterns.Templater.Call
7226 ("capitalize_file",
7227 OASISSourcePatterns.Templater.Ident
7228 "module"));
7229 OASISSourcePatterns.Templater.Text ".mly"
7230 ];
7231 origin = "${capitalize_file module}.mly"
7232 };
7233 {
7234 OASISSourcePatterns.Templater.atoms =
7235 [
7236 OASISSourcePatterns.Templater.Text "";
7237 OASISSourcePatterns.Templater.Expr
7238 (OASISSourcePatterns.Templater.Call
7239 ("uncapitalize_file",
7240 OASISSourcePatterns.Templater.Ident
7241 "module"));
7242 OASISSourcePatterns.Templater.Text ".mly"
7243 ];
7244 origin = "${uncapitalize_file module}.mly"
7245 }
7246 ];
70077247 bs_c_sources =
70087248 [
70097249 "config.h";
70317271 "read_cred.c";
70327272 "fexecve.c";
70337273 "sendmsg.c";
7274 "mktemp.c";
70347275 "memalign.c";
70357276 "endianba.c";
70367277 "pread_pwrite_ba.c";
70467287 "unshare.c"
70477288 ];
70487289 bs_data_files = [];
7290 bs_findlib_extra_files = [];
70497291 bs_ccopt =
70507292 [
70517293 (OASISExpr.EBool true, []);
70527294 (OASISExpr.EAnd
70537295 (OASISExpr.EFlag "strict",
70547296 OASISExpr.ETest ("ccomp_type", "cc")),
7055 [
7056 "-std=c89";
7057 "-pedantic";
7058 "-Wno-long-long";
7059 "-Wextra"
7060 ])
7297 ["-pedantic"; "-Wno-long-long"; "-Wextra"])
70617298 ];
70627299 bs_cclib = [(OASISExpr.EBool true, [])];
70637300 bs_dlllib = [(OASISExpr.EBool true, [])];
70777314 lib_internal_modules = [];
70787315 lib_findlib_parent = None;
70797316 lib_findlib_name = None;
7317 lib_findlib_directory = None;
70807318 lib_findlib_containers = []
70817319 });
70827320 Executable
71037341 ];
71047342 bs_build_tools =
71057343 [ExternalTool "ocamlbuild"; ExternalTool "camlp4"];
7344 bs_interface_patterns =
7345 [
7346 {
7347 OASISSourcePatterns.Templater.atoms =
7348 [
7349 OASISSourcePatterns.Templater.Text "";
7350 OASISSourcePatterns.Templater.Expr
7351 (OASISSourcePatterns.Templater.Call
7352 ("capitalize_file",
7353 OASISSourcePatterns.Templater.Ident
7354 "module"));
7355 OASISSourcePatterns.Templater.Text ".mli"
7356 ];
7357 origin = "${capitalize_file module}.mli"
7358 };
7359 {
7360 OASISSourcePatterns.Templater.atoms =
7361 [
7362 OASISSourcePatterns.Templater.Text "";
7363 OASISSourcePatterns.Templater.Expr
7364 (OASISSourcePatterns.Templater.Call
7365 ("uncapitalize_file",
7366 OASISSourcePatterns.Templater.Ident
7367 "module"));
7368 OASISSourcePatterns.Templater.Text ".mli"
7369 ];
7370 origin = "${uncapitalize_file module}.mli"
7371 }
7372 ];
7373 bs_implementation_patterns =
7374 [
7375 {
7376 OASISSourcePatterns.Templater.atoms =
7377 [
7378 OASISSourcePatterns.Templater.Text "";
7379 OASISSourcePatterns.Templater.Expr
7380 (OASISSourcePatterns.Templater.Call
7381 ("capitalize_file",
7382 OASISSourcePatterns.Templater.Ident
7383 "module"));
7384 OASISSourcePatterns.Templater.Text ".ml"
7385 ];
7386 origin = "${capitalize_file module}.ml"
7387 };
7388 {
7389 OASISSourcePatterns.Templater.atoms =
7390 [
7391 OASISSourcePatterns.Templater.Text "";
7392 OASISSourcePatterns.Templater.Expr
7393 (OASISSourcePatterns.Templater.Call
7394 ("uncapitalize_file",
7395 OASISSourcePatterns.Templater.Ident
7396 "module"));
7397 OASISSourcePatterns.Templater.Text ".ml"
7398 ];
7399 origin = "${uncapitalize_file module}.ml"
7400 };
7401 {
7402 OASISSourcePatterns.Templater.atoms =
7403 [
7404 OASISSourcePatterns.Templater.Text "";
7405 OASISSourcePatterns.Templater.Expr
7406 (OASISSourcePatterns.Templater.Call
7407 ("capitalize_file",
7408 OASISSourcePatterns.Templater.Ident
7409 "module"));
7410 OASISSourcePatterns.Templater.Text ".mll"
7411 ];
7412 origin = "${capitalize_file module}.mll"
7413 };
7414 {
7415 OASISSourcePatterns.Templater.atoms =
7416 [
7417 OASISSourcePatterns.Templater.Text "";
7418 OASISSourcePatterns.Templater.Expr
7419 (OASISSourcePatterns.Templater.Call
7420 ("uncapitalize_file",
7421 OASISSourcePatterns.Templater.Ident
7422 "module"));
7423 OASISSourcePatterns.Templater.Text ".mll"
7424 ];
7425 origin = "${uncapitalize_file module}.mll"
7426 };
7427 {
7428 OASISSourcePatterns.Templater.atoms =
7429 [
7430 OASISSourcePatterns.Templater.Text "";
7431 OASISSourcePatterns.Templater.Expr
7432 (OASISSourcePatterns.Templater.Call
7433 ("capitalize_file",
7434 OASISSourcePatterns.Templater.Ident
7435 "module"));
7436 OASISSourcePatterns.Templater.Text ".mly"
7437 ];
7438 origin = "${capitalize_file module}.mly"
7439 };
7440 {
7441 OASISSourcePatterns.Templater.atoms =
7442 [
7443 OASISSourcePatterns.Templater.Text "";
7444 OASISSourcePatterns.Templater.Expr
7445 (OASISSourcePatterns.Templater.Call
7446 ("uncapitalize_file",
7447 OASISSourcePatterns.Templater.Ident
7448 "module"));
7449 OASISSourcePatterns.Templater.Text ".mly"
7450 ];
7451 origin = "${uncapitalize_file module}.mly"
7452 }
7453 ];
71067454 bs_c_sources = [];
71077455 bs_data_files = [];
7456 bs_findlib_extra_files = [];
71087457 bs_ccopt = [(OASISExpr.EBool true, [])];
71097458 bs_cclib = [(OASISExpr.EBool true, [])];
71107459 bs_dlllib = [(OASISExpr.EBool true, [])];
71377486 ];
71387487 bs_build_tools =
71397488 [ExternalTool "ocamlbuild"; ExternalTool "camlp4"];
7489 bs_interface_patterns =
7490 [
7491 {
7492 OASISSourcePatterns.Templater.atoms =
7493 [
7494 OASISSourcePatterns.Templater.Text "";
7495 OASISSourcePatterns.Templater.Expr
7496 (OASISSourcePatterns.Templater.Call
7497 ("capitalize_file",
7498 OASISSourcePatterns.Templater.Ident
7499 "module"));
7500 OASISSourcePatterns.Templater.Text ".mli"
7501 ];
7502 origin = "${capitalize_file module}.mli"
7503 };
7504 {
7505 OASISSourcePatterns.Templater.atoms =
7506 [
7507 OASISSourcePatterns.Templater.Text "";
7508 OASISSourcePatterns.Templater.Expr
7509 (OASISSourcePatterns.Templater.Call
7510 ("uncapitalize_file",
7511 OASISSourcePatterns.Templater.Ident
7512 "module"));
7513 OASISSourcePatterns.Templater.Text ".mli"
7514 ];
7515 origin = "${uncapitalize_file module}.mli"
7516 }
7517 ];
7518 bs_implementation_patterns =
7519 [
7520 {
7521 OASISSourcePatterns.Templater.atoms =
7522 [
7523 OASISSourcePatterns.Templater.Text "";
7524 OASISSourcePatterns.Templater.Expr
7525 (OASISSourcePatterns.Templater.Call
7526 ("capitalize_file",
7527 OASISSourcePatterns.Templater.Ident
7528 "module"));
7529 OASISSourcePatterns.Templater.Text ".ml"
7530 ];
7531 origin = "${capitalize_file module}.ml"
7532 };
7533 {
7534 OASISSourcePatterns.Templater.atoms =
7535 [
7536 OASISSourcePatterns.Templater.Text "";
7537 OASISSourcePatterns.Templater.Expr
7538 (OASISSourcePatterns.Templater.Call
7539 ("uncapitalize_file",
7540 OASISSourcePatterns.Templater.Ident
7541 "module"));
7542 OASISSourcePatterns.Templater.Text ".ml"
7543 ];
7544 origin = "${uncapitalize_file module}.ml"
7545 };
7546 {
7547 OASISSourcePatterns.Templater.atoms =
7548 [
7549 OASISSourcePatterns.Templater.Text "";
7550 OASISSourcePatterns.Templater.Expr
7551 (OASISSourcePatterns.Templater.Call
7552 ("capitalize_file",
7553 OASISSourcePatterns.Templater.Ident
7554 "module"));
7555 OASISSourcePatterns.Templater.Text ".mll"
7556 ];
7557 origin = "${capitalize_file module}.mll"
7558 };
7559 {
7560 OASISSourcePatterns.Templater.atoms =
7561 [
7562 OASISSourcePatterns.Templater.Text "";
7563 OASISSourcePatterns.Templater.Expr
7564 (OASISSourcePatterns.Templater.Call
7565 ("uncapitalize_file",
7566 OASISSourcePatterns.Templater.Ident
7567 "module"));
7568 OASISSourcePatterns.Templater.Text ".mll"
7569 ];
7570 origin = "${uncapitalize_file module}.mll"
7571 };
7572 {
7573 OASISSourcePatterns.Templater.atoms =
7574 [
7575 OASISSourcePatterns.Templater.Text "";
7576 OASISSourcePatterns.Templater.Expr
7577 (OASISSourcePatterns.Templater.Call
7578 ("capitalize_file",
7579 OASISSourcePatterns.Templater.Ident
7580 "module"));
7581 OASISSourcePatterns.Templater.Text ".mly"
7582 ];
7583 origin = "${capitalize_file module}.mly"
7584 };
7585 {
7586 OASISSourcePatterns.Templater.atoms =
7587 [
7588 OASISSourcePatterns.Templater.Text "";
7589 OASISSourcePatterns.Templater.Expr
7590 (OASISSourcePatterns.Templater.Call
7591 ("uncapitalize_file",
7592 OASISSourcePatterns.Templater.Ident
7593 "module"));
7594 OASISSourcePatterns.Templater.Text ".mly"
7595 ];
7596 origin = "${uncapitalize_file module}.mly"
7597 }
7598 ];
71407599 bs_c_sources = [];
71417600 bs_data_files = [];
7601 bs_findlib_extra_files = [];
71427602 bs_ccopt = [(OASISExpr.EBool true, [])];
71437603 bs_cclib = [(OASISExpr.EBool true, [])];
71447604 bs_dlllib = [(OASISExpr.EBool true, [])];
71647624 bs_compiled_object = Best;
71657625 bs_build_depends =
71667626 [
7167 FindlibPackage ("bytes", None);
71687627 FindlibPackage ("str", None);
71697628 InternalLibrary "extunix";
71707629 FindlibPackage
71737632 ];
71747633 bs_build_tools =
71757634 [ExternalTool "ocamlbuild"; ExternalTool "camlp4"];
7635 bs_interface_patterns =
7636 [
7637 {
7638 OASISSourcePatterns.Templater.atoms =
7639 [
7640 OASISSourcePatterns.Templater.Text "";
7641 OASISSourcePatterns.Templater.Expr
7642 (OASISSourcePatterns.Templater.Call
7643 ("capitalize_file",
7644 OASISSourcePatterns.Templater.Ident
7645 "module"));
7646 OASISSourcePatterns.Templater.Text ".mli"
7647 ];
7648 origin = "${capitalize_file module}.mli"
7649 };
7650 {
7651 OASISSourcePatterns.Templater.atoms =
7652 [
7653 OASISSourcePatterns.Templater.Text "";
7654 OASISSourcePatterns.Templater.Expr
7655 (OASISSourcePatterns.Templater.Call
7656 ("uncapitalize_file",
7657 OASISSourcePatterns.Templater.Ident
7658 "module"));
7659 OASISSourcePatterns.Templater.Text ".mli"
7660 ];
7661 origin = "${uncapitalize_file module}.mli"
7662 }
7663 ];
7664 bs_implementation_patterns =
7665 [
7666 {
7667 OASISSourcePatterns.Templater.atoms =
7668 [
7669 OASISSourcePatterns.Templater.Text "";
7670 OASISSourcePatterns.Templater.Expr
7671 (OASISSourcePatterns.Templater.Call
7672 ("capitalize_file",
7673 OASISSourcePatterns.Templater.Ident
7674 "module"));
7675 OASISSourcePatterns.Templater.Text ".ml"
7676 ];
7677 origin = "${capitalize_file module}.ml"
7678 };
7679 {
7680 OASISSourcePatterns.Templater.atoms =
7681 [
7682 OASISSourcePatterns.Templater.Text "";
7683 OASISSourcePatterns.Templater.Expr
7684 (OASISSourcePatterns.Templater.Call
7685 ("uncapitalize_file",
7686 OASISSourcePatterns.Templater.Ident
7687 "module"));
7688 OASISSourcePatterns.Templater.Text ".ml"
7689 ];
7690 origin = "${uncapitalize_file module}.ml"
7691 };
7692 {
7693 OASISSourcePatterns.Templater.atoms =
7694 [
7695 OASISSourcePatterns.Templater.Text "";
7696 OASISSourcePatterns.Templater.Expr
7697 (OASISSourcePatterns.Templater.Call
7698 ("capitalize_file",
7699 OASISSourcePatterns.Templater.Ident
7700 "module"));
7701 OASISSourcePatterns.Templater.Text ".mll"
7702 ];
7703 origin = "${capitalize_file module}.mll"
7704 };
7705 {
7706 OASISSourcePatterns.Templater.atoms =
7707 [
7708 OASISSourcePatterns.Templater.Text "";
7709 OASISSourcePatterns.Templater.Expr
7710 (OASISSourcePatterns.Templater.Call
7711 ("uncapitalize_file",
7712 OASISSourcePatterns.Templater.Ident
7713 "module"));
7714 OASISSourcePatterns.Templater.Text ".mll"
7715 ];
7716 origin = "${uncapitalize_file module}.mll"
7717 };
7718 {
7719 OASISSourcePatterns.Templater.atoms =
7720 [
7721 OASISSourcePatterns.Templater.Text "";
7722 OASISSourcePatterns.Templater.Expr
7723 (OASISSourcePatterns.Templater.Call
7724 ("capitalize_file",
7725 OASISSourcePatterns.Templater.Ident
7726 "module"));
7727 OASISSourcePatterns.Templater.Text ".mly"
7728 ];
7729 origin = "${capitalize_file module}.mly"
7730 };
7731 {
7732 OASISSourcePatterns.Templater.atoms =
7733 [
7734 OASISSourcePatterns.Templater.Text "";
7735 OASISSourcePatterns.Templater.Expr
7736 (OASISSourcePatterns.Templater.Call
7737 ("uncapitalize_file",
7738 OASISSourcePatterns.Templater.Ident
7739 "module"));
7740 OASISSourcePatterns.Templater.Text ".mly"
7741 ];
7742 origin = "${uncapitalize_file module}.mly"
7743 }
7744 ];
71767745 bs_c_sources = [];
71777746 bs_data_files = [];
7747 bs_findlib_extra_files = [];
71787748 bs_ccopt = [(OASISExpr.EBool true, [])];
71797749 bs_cclib = [(OASISExpr.EBool true, [])];
71807750 bs_dlllib = [(OASISExpr.EBool true, [])];
72667836 ]
72677837 })
72687838 ];
7839 disable_oasis_section = [];
7840 conf_type = (`Configure, "internal", Some "0.4");
7841 conf_custom =
7842 {
7843 pre_command = [(OASISExpr.EBool true, None)];
7844 post_command =
7845 [
7846 (OASISExpr.EBool true,
7847 Some
7848 (("ocaml",
7849 [
7850 "src/discover.ml";
7851 "-ocamlc";
7852 "$ocamlc";
7853 "-ext_obj";
7854 "$ext_obj"
7855 ])))
7856 ]
7857 };
7858 build_type = (`Build, "ocamlbuild", Some "0.4");
7859 build_custom =
7860 {
7861 pre_command = [(OASISExpr.EBool true, None)];
7862 post_command = [(OASISExpr.EBool true, None)]
7863 };
7864 install_type = (`Install, "internal", Some "0.4");
7865 install_custom =
7866 {
7867 pre_command = [(OASISExpr.EBool true, None)];
7868 post_command = [(OASISExpr.EBool true, None)]
7869 };
7870 uninstall_custom =
7871 {
7872 pre_command = [(OASISExpr.EBool true, None)];
7873 post_command = [(OASISExpr.EBool true, None)]
7874 };
7875 clean_custom =
7876 {
7877 pre_command = [(OASISExpr.EBool true, None)];
7878 post_command = [(OASISExpr.EBool true, None)]
7879 };
7880 distclean_custom =
7881 {
7882 pre_command =
7883 [
7884 (OASISExpr.EBool true,
7885 Some (("$rm", ["$(utoh \"src/config.h\")"])))
7886 ];
7887 post_command =
7888 [
7889 (OASISExpr.EBool true,
7890 Some (("$rm", ["$(utoh \"src/config.ml\")"])))
7891 ]
7892 };
72697893 plugins =
72707894 [(`Extra, "DevFiles", Some "0.3"); (`Extra, "META", Some "0.3")];
7271 disable_oasis_section = [];
72727895 schema_data = PropList.Data.create ();
72737896 plugin_data = []
72747897 };
72757898 oasis_fn = Some "_oasis";
7276 oasis_version = "0.4.5";
7277 oasis_digest = Some "d\224\186}\182CdEL<\156H\131*#\156";
7899 oasis_version = "0.4.8";
7900 oasis_digest = Some "S\021\189[\164\201\026*\183o[\b\236\005\194\134";
72787901 oasis_exec = None;
72797902 oasis_setup_args = [];
72807903 setup_update = false
72827905
72837906 let setup () = BaseSetup.setup setup_t;;
72847907
7285 # 7287 "setup.ml"
7908 # 7910 "setup.ml"
7909 let setup_t = BaseCompat.Compat_0_4.adapt_setup_t setup_t
7910 open BaseCompat.Compat_0_4
72867911 (* OASIS_STOP *)
72877912 let () = setup ();;
00 # OASIS_START
1 # DO NOT EDIT (digest: d2df78e63c11b2d3caeee272e1a8e0c7)
2 version = "0.1.3"
1 # DO NOT EDIT (digest: 24d1df0bb0b333dd59a32e45cd09ce09)
2 version = "0.1.4"
33 description = "Extended functions for OCaml Unix module"
4 requires = "unix bigarray"
4 requires = "unix bigarray bytes"
55 archive(byte) = "extunix.cma"
66 archive(byte, plugin) = "extunix.cma"
77 archive(native) = "extunix.cmxa"
44 /* otherlibs/unix/open.c */
55
66 #ifndef O_NONBLOCK
7 #ifdef __MINGW32__
8 #define O_NONBLOCK 0 /* no O_NONBLOCK on mingw */
9 #else
710 #define O_NONBLOCK O_NDELAY
11 #endif
12 #endif
13 #ifndef O_NOCTTY
14 #define O_NOCTTY 0
815 #endif
916 #ifndef O_DSYNC
1017 #define O_DSYNC 0
4141 "_POSIX_C_SOURCE 200809L";
4242 "_XOPEN_SOURCE 700";
4343 "_BSD_SOURCE";
44 "_DEFAULT_SOURCE";
4445 "_DARWIN_C_SOURCE";
4546 "_LARGEFILE64_SOURCE";
4647 "WIN32_LEAN_AND_MEAN";
284285 "EXECINFO", L[ I"execinfo.h"; S"backtrace"; S"backtrace_symbols"; ];
285286 "SETENV", L[ I"stdlib.h"; S"setenv"; S"unsetenv"; ];
286287 "CLEARENV", L[ I"stdlib.h"; S"clearenv"; ];
287 "MKDTEMP", L[ I"stdlib.h"; S"mkdtemp"; ];
288 "MKDTEMP", L[ I"stdlib.h"; I"unistd.h"; S"mkdtemp"; ];
288289 "TIMEGM", L[ I"time.h"; S"timegm"; ];
289290 "MALLOC_INFO", L[ I"malloc.h"; S"malloc_info"; ];
290291 "MALLOC_STATS", L[ I"malloc.h"; S"malloc_stats"; ];
291292 "MEMALIGN", L[ I "stdlib.h"; S"posix_memalign"; ];
292 "ENDIAN", L[ I "endian.h";
293 D"htobe16"; D"htole16"; D"be16toh"; D"le16toh";
294 D"htobe32"; D"htole32"; D"be32toh"; D"le32toh";
295 D"htobe64"; D"htole64"; D"be64toh"; D"le64toh"; ];
293 "ENDIAN", L[
294 I "endian.h";
295 D"htobe16"; D"htole16"; D"be16toh"; D"le16toh";
296 D"htobe32"; D"htole32"; D"be32toh"; D"le32toh";
297 D"htobe64"; D"htole64"; D"be64toh"; D"le64toh";
298 ];
296299 "READ_CREDENTIALS", L[ I"sys/types.h"; I"sys/socket.h"; D"SO_PEERCRED"; ];
297300 "FEXECVE", L[ I "unistd.h"; S"fexecve"; ];
298301 "SENDMSG", ANY[
303306 "PWRITE", L[ I "unistd.h"; S"pwrite"; ];
304307 "READ", L[ I "unistd.h"; S"read"; ];
305308 "WRITE", L[ I "unistd.h"; S"write"; ];
306 "MKSTEMPS", L[ I "stdlib.h"; S"mkstemps"; ];
307 "MKOSTEMPS", L[ I "stdlib.h"; S"mkostemps"; ];
309 "MKSTEMPS", L[ I "stdlib.h"; I "unistd.h"; S"mkstemps"; ];
310 "MKOSTEMPS", L[ I "stdlib.h"; I "unistd.h"; S"mkostemps"; ];
308311 "SETRESUID", L[ I"sys/types.h"; I"unistd.h"; S"setresuid"; S"setresgid" ];
309312 "SYSCONF", L[
310313 I "unistd.h";
322325 "TCP_KEEPCNT", L[I"netinet/in.h"; I"netinet/tcp.h";V"TCP_KEEPCNT"];
323326 "TCP_KEEPIDLE", L[I"netinet/in.h"; I"netinet/tcp.h";V"TCP_KEEPIDLE"];
324327 "TCP_KEEPINTVL", L[I"netinet/in.h"; I"netinet/tcp.h";V"TCP_KEEPINTVL"];
328 "SO_REUSEPORT", L[I"sys/socket.h"; V"SO_REUSEPORT"];
325329 "POLL", L[ I "poll.h"; S "poll"; D "POLLIN"; D "POLLOUT"; Z "POLLRDHUP" ];
326330 "SYSINFO", L[ I"sys/sysinfo.h"; S"sysinfo"; F ("sysinfo","mem_unit")];
327331 "MCHECK", L[ I"mcheck.h"; S"mtrace"; S"muntrace" ];
33 the corresponding man pages and/or system documentation for details.
44 *)
55
6 (** [Not_available "func"] may be raised by [ExtUnix.All.func]
7 if the wrapped C function is not available on this platform.
6 (** [Not_available "symbol"] may be raised by [ExtUnix.All.func]
7 if the wrapped C function or constant is not available on this platform.
88
99 [ExtUnix.Specific] includes only functions available on the current
1010 platform and will not raise [Not_available].
225225 only ever returns 0 on End-of-file. Continues the read operation
226226 on EINTR. Raises an Unix.Unix_error exception in all other
227227 cases. *)
228 external unsafe_all_pread: Unix.file_descr -> int -> string -> int -> int -> int = "caml_extunix_all_pread"
228 external unsafe_all_pread: Unix.file_descr -> int -> Bytes.t -> int -> int -> int = "caml_extunix_all_pread"
229229
230230 let all_pread fd off buf ofs len =
231 if off < 0 || ofs < 0 || len < 0 || ofs > String.length buf - len
231 if off < 0 || ofs < 0 || len < 0 || ofs > Bytes.length buf - len
232232 then invalid_arg "ExtUnix.all_pread"
233233 else unsafe_all_pread fd off buf ofs len
234234
239239
240240 [single_pread] attempts to read only once. Returns the number of
241241 characters read or raises an Unix.Unix_error exception. *)
242 external unsafe_single_pread: Unix.file_descr -> int -> string -> int -> int -> int = "caml_extunix_single_pread"
242 external unsafe_single_pread: Unix.file_descr -> int -> Bytes.t -> int -> int -> int = "caml_extunix_single_pread"
243243
244244 let single_pread fd off buf ofs len =
245 if off < 0 || ofs < 0 || len < 0 || ofs > String.length buf - len
245 if off < 0 || ofs < 0 || len < 0 || ofs > Bytes.length buf - len
246246 then invalid_arg "ExtUnix.single_pread"
247247 else unsafe_single_pread fd off buf ofs len
248248
255255 if 0 characters could be read before an error occurs. Continues
256256 the read operation on EINTR. Returns the number of characters
257257 written in all other cases. *)
258 external unsafe_pread: Unix.file_descr -> int -> string -> int -> int -> int = "caml_extunix_pread"
258 external unsafe_pread: Unix.file_descr -> int -> Bytes.t -> int -> int -> int = "caml_extunix_pread"
259259
260260 let pread fd off buf ofs len =
261 if off < 0 || ofs < 0 || len < 0 || ofs > String.length buf - len
261 if off < 0 || ofs < 0 || len < 0 || ofs > Bytes.length buf - len
262262 then invalid_arg "ExtUnix.pread"
263263 else unsafe_pread fd off buf ofs len
264264
271271 if 0 characters could be read before an error occurs. Does NOT
272272 continue on EINTR. Returns the number of characters written in all
273273 other cases. *)
274 external unsafe_intr_pread: Unix.file_descr -> int -> string -> int -> int -> int = "caml_extunix_intr_pread"
274 external unsafe_intr_pread: Unix.file_descr -> int -> Bytes.t -> int -> int -> int = "caml_extunix_intr_pread"
275275
276276 let intr_pread fd off buf ofs len =
277 if off < 0 || ofs < 0 || len < 0 || ofs > String.length buf - len
277 if off < 0 || ofs < 0 || len < 0 || ofs > Bytes.length buf - len
278278 then invalid_arg "ExtUnix.intr_pread"
279279 else unsafe_intr_pread fd off buf ofs len
280280 END
362362 only ever returns 0 on End-of-file. Continues the read operation
363363 on EINTR. Raises an Unix.Unix_error exception in all other
364364 cases. *)
365 external unsafe_all_read: Unix.file_descr -> string -> int -> int -> int = "caml_extunix_all_read"
365 external unsafe_all_read: Unix.file_descr -> Bytes.t -> int -> int -> int = "caml_extunix_all_read"
366366
367367 let all_read fd buf ofs len =
368 if ofs < 0 || len < 0 || ofs > String.length buf - len
368 if ofs < 0 || len < 0 || ofs > Bytes.length buf - len
369369 then invalid_arg "ExtUnix.all_read"
370370 else unsafe_all_read fd buf ofs len
371371
374374
375375 [single_read] attempts to read only once. Returns the number of
376376 characters read or raises an Unix.Unix_error exception. *)
377 external unsafe_single_read: Unix.file_descr -> string -> int -> int -> int = "caml_extunix_single_read"
377 external unsafe_single_read: Unix.file_descr -> Bytes.t -> int -> int -> int = "caml_extunix_single_read"
378378
379379 let single_read fd buf ofs len =
380 if ofs < 0 || len < 0 || ofs > String.length buf - len
380 if ofs < 0 || len < 0 || ofs > Bytes.length buf - len
381381 then invalid_arg "ExtUnix.single_read"
382382 else unsafe_single_read fd buf ofs len
383383
389389 if 0 characters could be read before an error occurs. Continues
390390 the read operation on EINTR. Returns the number of characters
391391 written in all other cases. *)
392 external unsafe_read: Unix.file_descr -> string -> int -> int -> int = "caml_extunix_read"
392 external unsafe_read: Unix.file_descr -> Bytes.t -> int -> int -> int = "caml_extunix_read"
393393
394394 let read fd buf ofs len =
395 if ofs < 0 || len < 0 || ofs > String.length buf - len
395 if ofs < 0 || len < 0 || ofs > Bytes.length buf - len
396396 then invalid_arg "ExtUnix.read"
397397 else unsafe_read fd buf ofs len
398398
404404 if 0 characters could be read before an error occurs. Does NOT
405405 continue on EINTR. Returns the number of characters written in all
406406 other cases. *)
407 external unsafe_intr_read: Unix.file_descr -> string -> int -> int -> int = "caml_extunix_intr_read"
407 external unsafe_intr_read: Unix.file_descr -> Bytes.t -> int -> int -> int = "caml_extunix_intr_read"
408408
409409 let intr_read fd buf ofs len =
410 if ofs < 0 || len < 0 || ofs > String.length buf - len
410 if ofs < 0 || len < 0 || ofs > Bytes.length buf - len
411411 then invalid_arg "ExtUnix.intr_read"
412412 else unsafe_intr_read fd buf ofs len
413413 END
500500 END
501501
502502 HAVE PREAD
503 external unsafe_all_pread: Unix.file_descr -> int64 -> string -> int -> int -> int = "caml_extunix_all_pread64"
503 external unsafe_all_pread: Unix.file_descr -> int64 -> Bytes.t -> int -> int -> int = "caml_extunix_all_pread64"
504504
505505 let all_pread fd off buf ofs len =
506506 if off < Int64.zero
507507 then invalid_arg "ExtUnix.LargeFile.all_pread"
508508 else unsafe_all_pread fd off buf ofs len
509509
510 external unsafe_single_pread: Unix.file_descr -> int64 -> string -> int -> int -> int = "caml_extunix_single_pread64"
510 external unsafe_single_pread: Unix.file_descr -> int64 -> Bytes.t -> int -> int -> int = "caml_extunix_single_pread64"
511511
512512 let single_pread fd off buf ofs len =
513513 if off < Int64.zero
514514 then invalid_arg "ExtUnix.LargeFile.single_pread"
515515 else unsafe_single_pread fd off buf ofs len
516516
517 external unsafe_pread: Unix.file_descr -> int64 -> string -> int -> int -> int = "caml_extunix_pread64"
517 external unsafe_pread: Unix.file_descr -> int64 -> Bytes.t -> int -> int -> int = "caml_extunix_pread64"
518518
519519 let pread fd off buf ofs len =
520520 if off < Int64.zero
521521 then invalid_arg "ExtUnix.LargeFile.pread"
522522 else unsafe_pread fd off buf ofs len
523523
524 external unsafe_intr_pread: Unix.file_descr -> int64 -> string -> int -> int -> int = "caml_extunix_intr_pread64"
524 external unsafe_intr_pread: Unix.file_descr -> int64 -> Bytes.t -> int -> int -> int = "caml_extunix_intr_pread64"
525525
526526 let intr_pread fd off buf ofs len =
527527 if off < Int64.zero
791791 mem_unit : int; (** Memory unit size in bytes *)
792792 }
793793
794 (** @retrun overall system statistics *)
794 (** @return overall system statistics *)
795795 external sysinfo : unit -> sysinfo = "caml_extunix_sysinfo"
796796
797797 (** @return seconds since boot *)
808808 END
809809
810810 HAVE SOCKOPT
811
812 type socket_int_option_ =
813 | TCP_KEEPCNT_
814 | TCP_KEEPIDLE_
815 | TCP_KEEPINTVL_
816 | SO_REUSEPORT_
817
818 let string_of_socket_int_option_ = function
819 | TCP_KEEPCNT_ -> "TCP_KEEPCNT"
820 | TCP_KEEPIDLE_ -> "TCP_KEEPIDLE"
821 | TCP_KEEPINTVL_ -> "TCP_KEEPINTVL"
822 | SO_REUSEPORT_ -> "SO_REUSEPORT"
823
824 external setsockopt_int : Unix.file_descr -> socket_int_option_ -> int -> unit = "caml_extunix_setsockopt_int"
825 external getsockopt_int : Unix.file_descr -> socket_int_option_ -> int = "caml_extunix_getsockopt_int"
826 external have_sockopt_int : socket_int_option_ -> bool = "caml_extunix_have_sockopt"
811827
812828 (** Extra socket options with integer value not covered in {!Unix} module.
813829 NB Not all options available on all platforms, use {!have_sockopt} to check at runtime
819835 keepalive probes, if the socket option SO_KEEPALIVE has been set on this socket *)
820836 | TCP_KEEPINTVL (** The time (in seconds) between individual keepalive probes *)
821837
822 (** raise [Not_available] if option is not supported, see {!have_sockopt} *)
823 external setsockopt_int : Unix.file_descr -> socket_int_option -> int -> unit = "caml_extunix_setsockopt_int"
824 external getsockopt_int : Unix.file_descr -> socket_int_option -> int = "caml_extunix_getsockopt_int"
825
826 external have_sockopt : socket_int_option -> bool = "caml_extunix_have_sockopt"
838 type socket_bool_option =
839 | SO_REUSEPORT (** Permits multiple AF_INET or AF_INET6 sockets to be bound to an identical socket address. *)
840
841 let make_socket_int_option = function
842 | TCP_KEEPCNT -> TCP_KEEPCNT_
843 | TCP_KEEPIDLE -> TCP_KEEPIDLE_
844 | TCP_KEEPINTVL -> TCP_KEEPINTVL_
845
846 let make_socket_bool_option = function
847 | SO_REUSEPORT -> SO_REUSEPORT_
848
849 let have_sockopt_bool x = have_sockopt_int (make_socket_bool_option x)
850 let have_sockopt_int x = have_sockopt_int (make_socket_int_option x)
851
852 (** obsolete, compatibility *)
853 let have_sockopt = have_sockopt_int
854
855 let setsockopt_int sock opt v = try setsockopt_int sock opt v with Not_found -> raise (Not_available ("setsockopt " ^ string_of_socket_int_option_ opt))
856 let getsockopt_int sock opt = try getsockopt_int sock opt with Not_found -> raise (Not_available ("getsockopt " ^ string_of_socket_int_option_ opt))
857
858 (** Set a boolean-valued option in the given socket *)
859 let setsockopt sock opt v = setsockopt_int sock (make_socket_bool_option opt) (if v then 1 else 0)
860
861 (** Get the current value for the boolean-valued option in the given socket *)
862 let getsockopt sock opt = 0 <> getsockopt_int sock (make_socket_bool_option opt)
827863
828864 (** Set an integer-valued option in the given socket *)
829 let setsockopt_int sock opt v =
830 try
831 setsockopt_int sock opt v
832 with
833 Not_found -> raise (Not_available "setsockopt_int")
865 let setsockopt_int sock opt v = setsockopt_int sock (make_socket_int_option opt) v
834866
835867 (** Get the current value for the integer-valued option in the given socket *)
836 let getsockopt_int sock opt =
837 try
838 getsockopt_int sock opt
839 with
840 Not_found -> raise (Not_available "getsockopt_int")
868 let getsockopt_int sock opt = getsockopt_int sock (make_socket_int_option opt)
869
841870
842871 END
843872
879908
880909 type t = int
881910 external poll_constants : unit -> (int*int*int*int*int*int*int) = "caml_extunix_poll_constants"
882 let (pollin,pollpri,pollout,pollerr,pollhup,pollnval,pollrdhup) = poll_constants ()
911 let (pollin,pollpri,pollout,pollerr,pollhup,pollnval,pollrdhup) = try poll_constants () with Not_available _ -> (0,0,0,0,0,0,0)
883912 let none = 0
884913
885914 let is_set xs x = xs land x = x
14131442 then raise (Invalid_argument "index out of bounds");
14141443 unsafe_get_int64 str off
14151444
1416 (** [unsafe_set_X str off v] stores the integer [v] as type [X] in
1417 string [str] starting at offset [off]. Bounds checking is not
1445 (** [unsafe_set_X buf off v] stores the integer [v] as type [X] in
1446 the buffer [buf] starting at offset [off]. Bounds checking is not
14181447 performed. Use with caution and only when the program logic
14191448 guarantees that the access is within bounds.
14201449
14231452 will be sign extended to 32bit first. Use with care.
14241453 Note: The same applies to 63bit functions.
14251454 *)
1426 external unsafe_set_uint8 : string -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1427 external unsafe_set_int8 : string -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1428 external unsafe_set_uint16 : string -> int -> int -> unit = "caml_extunix_set_b16" "noalloc"
1429 external unsafe_set_int16 : string -> int -> int -> unit = "caml_extunix_set_b16" "noalloc"
1430 external unsafe_set_uint31 : string -> int -> int -> unit = "caml_extunix_set_b31" "noalloc"
1431 external unsafe_set_int31 : string -> int -> int -> unit = "caml_extunix_set_b31" "noalloc"
1432 external unsafe_set_int32 : string -> int -> int32 -> unit = "caml_extunix_set_b32" "noalloc"
1433 external unsafe_set_uint63 : string -> int -> int -> unit = "caml_extunix_set_b63" "noalloc"
1434 external unsafe_set_int63 : string -> int -> int -> unit = "caml_extunix_set_b63" "noalloc"
1435 external unsafe_set_int64 : string -> int -> int64 -> unit = "caml_extunix_set_b64" "noalloc"
1436
1437 (** [set_X str off v] same as [unsafe_set_X] but with bounds checking. *)
1455 external unsafe_set_uint8 : Bytes.t -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1456 external unsafe_set_int8 : Bytes.t -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1457 external unsafe_set_uint16 : Bytes.t -> int -> int -> unit = "caml_extunix_set_b16" "noalloc"
1458 external unsafe_set_int16 : Bytes.t -> int -> int -> unit = "caml_extunix_set_b16" "noalloc"
1459 external unsafe_set_uint31 : Bytes.t -> int -> int -> unit = "caml_extunix_set_b31" "noalloc"
1460 external unsafe_set_int31 : Bytes.t -> int -> int -> unit = "caml_extunix_set_b31" "noalloc"
1461 external unsafe_set_int32 : Bytes.t -> int -> int32 -> unit = "caml_extunix_set_b32" "noalloc"
1462 external unsafe_set_uint63 : Bytes.t -> int -> int -> unit = "caml_extunix_set_b63" "noalloc"
1463 external unsafe_set_int63 : Bytes.t -> int -> int -> unit = "caml_extunix_set_b63" "noalloc"
1464 external unsafe_set_int64 : Bytes.t -> int -> int64 -> unit = "caml_extunix_set_b64" "noalloc"
1465
1466 (** [set_X buf off v] same as [unsafe_set_X] but with bounds checking. *)
14381467 let set_uint8 str off v =
1439 if off < 0 || off >= String.length str
1468 if off < 0 || off >= Bytes.length str
14401469 then raise (Invalid_argument "index out of bounds");
14411470 unsafe_set_uint8 str off v
14421471
14431472 let set_int8 str off v =
1444 if off < 0 || off >= String.length str
1473 if off < 0 || off >= Bytes.length str
14451474 then raise (Invalid_argument "index out of bounds");
14461475 unsafe_set_int8 str off v
14471476
14481477 let set_uint16 str off v =
1449 if off < 0 || off > String.length str - 2
1478 if off < 0 || off > Bytes.length str - 2
14501479 then raise (Invalid_argument "index out of bounds");
14511480 unsafe_set_uint16 str off v
14521481
14531482 let set_int16 str off v =
1454 if off < 0 || off > String.length str - 2
1483 if off < 0 || off > Bytes.length str - 2
14551484 then raise (Invalid_argument "index out of bounds");
14561485 unsafe_set_int16 str off v
14571486
14581487 let set_uint31 str off v =
1459 if off < 0 || off > String.length str - 4
1488 if off < 0 || off > Bytes.length str - 4
14601489 then raise (Invalid_argument "index out of bounds");
14611490 unsafe_set_uint31 str off v
14621491
14631492 let set_int31 str off v =
1464 if off < 0 || off > String.length str - 4
1493 if off < 0 || off > Bytes.length str - 4
14651494 then raise (Invalid_argument "index out of bounds");
14661495 unsafe_set_int31 str off v
14671496
14681497 let set_int32 str off v =
1469 if off < 0 || off > String.length str - 4
1498 if off < 0 || off > Bytes.length str - 4
14701499 then raise (Invalid_argument "index out of bounds");
14711500 unsafe_set_int32 str off v
14721501
14731502 let set_uint63 str off v =
1474 if off < 0 || off > String.length str - 8
1503 if off < 0 || off > Bytes.length str - 8
14751504 then raise (Invalid_argument "index out of bounds");
14761505 unsafe_set_uint63 str off v
14771506
14781507 let set_int63 str off v =
1479 if off < 0 || off > String.length str - 8
1508 if off < 0 || off > Bytes.length str - 8
14801509 then raise (Invalid_argument "index out of bounds");
14811510 unsafe_set_int63 str off v
14821511
14831512 let set_int64 str off v =
1484 if off < 0 || off > String.length str - 8
1513 if off < 0 || off > Bytes.length str - 8
14851514 then raise (Invalid_argument "index out of bounds");
14861515 unsafe_set_int64 str off v
14871516
16251654 then raise (Invalid_argument "index out of bounds");
16261655 unsafe_get_int64 str off
16271656
1628 (** [unsafe_set_X str off v] stores the integer [v] as type [X] in
1629 string [str] starting at offset [off]. Bounds checking is not
1657 (** [unsafe_set_X buf off v] stores the integer [v] as type [X] in
1658 the buffer [buf] starting at offset [off]. Bounds checking is not
16301659 performed. Use with caution and only when the program logic
16311660 guarantees that the access is within bounds.
16321661
16331662 Note: The 31bit functions store an ocaml int as 32bit
16341663 integer. On 32bit platforms ocaml integers are 31bit signed and
16351664 will be sign extended to 32bit first. Use with care. *)
1636 external unsafe_set_uint8 : string -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1637 external unsafe_set_int8 : string -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1638 external unsafe_set_uint16 : string -> int -> int -> unit = "caml_extunix_set_l16" "noalloc"
1639 external unsafe_set_int16 : string -> int -> int -> unit = "caml_extunix_set_l16" "noalloc"
1640 external unsafe_set_uint31 : string -> int -> int -> unit = "caml_extunix_set_l31" "noalloc"
1641 external unsafe_set_int31 : string -> int -> int -> unit = "caml_extunix_set_l31" "noalloc"
1642 external unsafe_set_int32 : string -> int -> int32 -> unit = "caml_extunix_set_l32" "noalloc"
1643 external unsafe_set_uint63 : string -> int -> int -> unit = "caml_extunix_set_l63" "noalloc"
1644 external unsafe_set_int63 : string -> int -> int -> unit = "caml_extunix_set_l63" "noalloc"
1645 external unsafe_set_int64 : string -> int -> int64 -> unit = "caml_extunix_set_l64" "noalloc"
1646
1647 (** [set_X str off v] same as [unsafe_set_X] but with bounds checking. *)
1665 external unsafe_set_uint8 : Bytes.t -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1666 external unsafe_set_int8 : Bytes.t -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1667 external unsafe_set_uint16 : Bytes.t -> int -> int -> unit = "caml_extunix_set_l16" "noalloc"
1668 external unsafe_set_int16 : Bytes.t -> int -> int -> unit = "caml_extunix_set_l16" "noalloc"
1669 external unsafe_set_uint31 : Bytes.t -> int -> int -> unit = "caml_extunix_set_l31" "noalloc"
1670 external unsafe_set_int31 : Bytes.t -> int -> int -> unit = "caml_extunix_set_l31" "noalloc"
1671 external unsafe_set_int32 : Bytes.t -> int -> int32 -> unit = "caml_extunix_set_l32" "noalloc"
1672 external unsafe_set_uint63 : Bytes.t -> int -> int -> unit = "caml_extunix_set_l63" "noalloc"
1673 external unsafe_set_int63 : Bytes.t -> int -> int -> unit = "caml_extunix_set_l63" "noalloc"
1674 external unsafe_set_int64 : Bytes.t -> int -> int64 -> unit = "caml_extunix_set_l64" "noalloc"
1675
1676 (** [set_X buf off v] same as [unsafe_set_X] but with bounds checking. *)
16481677 let set_uint8 str off v =
1649 if off < 0 || off >= String.length str
1678 if off < 0 || off >= Bytes.length str
16501679 then raise (Invalid_argument "index out of bounds");
16511680 unsafe_set_uint8 str off v
16521681
16531682 let set_int8 str off v =
1654 if off < 0 || off >= String.length str
1683 if off < 0 || off >= Bytes.length str
16551684 then raise (Invalid_argument "index out of bounds");
16561685 unsafe_set_int8 str off v
16571686
16581687 let set_uint16 str off v =
1659 if off < 0 || off > String.length str - 2
1688 if off < 0 || off > Bytes.length str - 2
16601689 then raise (Invalid_argument "index out of bounds");
16611690 unsafe_set_uint16 str off v
16621691
16631692 let set_int16 str off v =
1664 if off < 0 || off > String.length str - 2
1693 if off < 0 || off > Bytes.length str - 2
16651694 then raise (Invalid_argument "index out of bounds");
16661695 unsafe_set_int16 str off v
16671696
16681697 let set_uint31 str off v =
1669 if off < 0 || off > String.length str - 4
1698 if off < 0 || off > Bytes.length str - 4
16701699 then raise (Invalid_argument "index out of bounds");
16711700 unsafe_set_uint31 str off v
16721701
16731702 let set_int31 str off v =
1674 if off < 0 || off > String.length str - 4
1703 if off < 0 || off > Bytes.length str - 4
16751704 then raise (Invalid_argument "index out of bounds");
16761705 unsafe_set_int31 str off v
16771706
16781707 let set_int32 str off v =
1679 if off < 0 || off > String.length str - 4
1708 if off < 0 || off > Bytes.length str - 4
16801709 then raise (Invalid_argument "index out of bounds");
16811710 unsafe_set_int32 str off v
16821711
16831712 let set_uint63 str off v =
1684 if off < 0 || off > String.length str - 8
1713 if off < 0 || off > Bytes.length str - 8
16851714 then raise (Invalid_argument "index out of bounds");
16861715 unsafe_set_uint63 str off v
16871716
16881717 let set_int63 str off v =
1689 if off < 0 || off > String.length str - 8
1718 if off < 0 || off > Bytes.length str - 8
16901719 then raise (Invalid_argument "index out of bounds");
16911720 unsafe_set_int63 str off v
16921721
16931722 let set_int64 str off v =
1694 if off < 0 || off > String.length str - 8
1723 if off < 0 || off > Bytes.length str - 8
16951724 then raise (Invalid_argument "index out of bounds");
16961725 unsafe_set_int64 str off v
16971726
17781807 then raise (Invalid_argument "index out of bounds");
17791808 unsafe_get_int64 str off
17801809
1781 (** [unsafe_set_X str off v] stores the integer [v] as type [X] in
1782 string [str] starting at offset [off]. Bounds checking is not
1810 (** [unsafe_set_X buf off v] stores the integer [v] as type [X] in
1811 the buffer [buf] starting at offset [off]. Bounds checking is not
17831812 performed. Use with caution and only when the program logic
17841813 guarantees that the access is within bounds.
17851814
17881817 will be sign extended to 32bit first. Use with care.
17891818 Note: The same applies to 63bit functions.
17901819 *)
1791 external unsafe_set_uint8 : string -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1792 external unsafe_set_int8 : string -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1793 external unsafe_set_uint16 : string -> int -> int -> unit = "caml_extunix_set_h16" "noalloc"
1794 external unsafe_set_int16 : string -> int -> int -> unit = "caml_extunix_set_h16" "noalloc"
1795 external unsafe_set_uint31 : string -> int -> int -> unit = "caml_extunix_set_h31" "noalloc"
1796 external unsafe_set_int31 : string -> int -> int -> unit = "caml_extunix_set_h31" "noalloc"
1797 external unsafe_set_int32 : string -> int -> int32 -> unit = "caml_extunix_set_h32" "noalloc"
1798 external unsafe_set_uint63 : string -> int -> int -> unit = "caml_extunix_set_h63" "noalloc"
1799 external unsafe_set_int63 : string -> int -> int -> unit = "caml_extunix_set_h63" "noalloc"
1800 external unsafe_set_int64 : string -> int -> int64 -> unit = "caml_extunix_set_h64" "noalloc"
1801
1802 (** [set_X str off v] same as [unsafe_set_X] but with bounds checking. *)
1820 external unsafe_set_uint8 : Bytes.t -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1821 external unsafe_set_int8 : Bytes.t -> int -> int -> unit = "caml_extunix_set_8" "noalloc"
1822 external unsafe_set_uint16 : Bytes.t -> int -> int -> unit = "caml_extunix_set_h16" "noalloc"
1823 external unsafe_set_int16 : Bytes.t -> int -> int -> unit = "caml_extunix_set_h16" "noalloc"
1824 external unsafe_set_uint31 : Bytes.t -> int -> int -> unit = "caml_extunix_set_h31" "noalloc"
1825 external unsafe_set_int31 : Bytes.t -> int -> int -> unit = "caml_extunix_set_h31" "noalloc"
1826 external unsafe_set_int32 : Bytes.t -> int -> int32 -> unit = "caml_extunix_set_h32" "noalloc"
1827 external unsafe_set_uint63 : Bytes.t -> int -> int -> unit = "caml_extunix_set_h63" "noalloc"
1828 external unsafe_set_int63 : Bytes.t -> int -> int -> unit = "caml_extunix_set_h63" "noalloc"
1829 external unsafe_set_int64 : Bytes.t -> int -> int64 -> unit = "caml_extunix_set_h64" "noalloc"
1830
1831 (** [set_X buf off v] same as [unsafe_set_X] but with bounds checking. *)
18031832 let set_uint8 str off v =
1804 if off < 0 || off >= String.length str
1833 if off < 0 || off >= Bytes.length str
18051834 then raise (Invalid_argument "index out of bounds");
18061835 unsafe_set_uint8 str off v
18071836
18081837 let set_int8 str off v =
1809 if off < 0 || off >= String.length str
1838 if off < 0 || off >= Bytes.length str
18101839 then raise (Invalid_argument "index out of bounds");
18111840 unsafe_set_int8 str off v
18121841
18131842 let set_uint16 str off v =
1814 if off < 0 || off > String.length str - 2
1843 if off < 0 || off > Bytes.length str - 2
18151844 then raise (Invalid_argument "index out of bounds");
18161845 unsafe_set_uint16 str off v
18171846
18181847 let set_int16 str off v =
1819 if off < 0 || off > String.length str - 2
1848 if off < 0 || off > Bytes.length str - 2
18201849 then raise (Invalid_argument "index out of bounds");
18211850 unsafe_set_int16 str off v
18221851
18231852 let set_uint31 str off v =
1824 if off < 0 || off > String.length str - 4
1853 if off < 0 || off > Bytes.length str - 4
18251854 then raise (Invalid_argument "index out of bounds");
18261855 unsafe_set_uint31 str off v
18271856
18281857 let set_int31 str off v =
1829 if off < 0 || off > String.length str - 4
1858 if off < 0 || off > Bytes.length str - 4
18301859 then raise (Invalid_argument "index out of bounds");
18311860 unsafe_set_int31 str off v
18321861
18331862 let set_int32 str off v =
1834 if off < 0 || off > String.length str - 4
1863 if off < 0 || off > Bytes.length str - 4
18351864 then raise (Invalid_argument "index out of bounds");
18361865 unsafe_set_int32 str off v
18371866
18381867 let set_uint63 str off v =
1839 if off < 0 || off > String.length str - 8
1868 if off < 0 || off > Bytes.length str - 8
18401869 then raise (Invalid_argument "index out of bounds");
18411870 unsafe_set_uint63 str off v
18421871
18431872 let set_int63 str off v =
1844 if off < 0 || off > String.length str - 8
1873 if off < 0 || off > Bytes.length str - 8
18451874 then raise (Invalid_argument "index out of bounds");
18461875 unsafe_set_int63 str off v
18471876
18481877 let set_int64 str off v =
1849 if off < 0 || off > String.length str - 8
1878 if off < 0 || off > Bytes.length str - 8
18501879 then raise (Invalid_argument "index out of bounds");
18511880 unsafe_set_int64 str off v
18521881
22422271
22432272 (** [all_write fd buf] writes up to [size of buf] bytes from file
22442273 descriptor [fd] into the buffer [buf].
2245
2274
22462275 [all_write] repeats the write operation until all characters have
22472276 been written or an error occurs. Returns less than the number of
22482277 characters requested on EAGAIN, EWOULDBLOCK but never 0. Continues
00 # OASIS_START
1 # DO NOT EDIT (digest: fc1c3ad8ae85c37d2cd9583f1c6ef64c)
1 # DO NOT EDIT (digest: 9ea9c31e8eb66b0e02125ef2b1be7dbb)
22 eventfd.o
33 dirfd.o
44 fsync.o
2323 read_cred.o
2424 fexecve.o
2525 sendmsg.o
26 mktemp.o
2627 memalign.o
2728 endianba.o
2829 pread_pwrite_ba.o
0 #define EXTUNIX_WANT_MKDTEMP
1 #define EXTUNIX_WANT_MKSTEMPS
2 #define EXTUNIX_WANT_MKOSTEMPS
3
4 #include "config.h"
5
6 #if defined(EXTUNIX_HAVE_MKDTEMP)
7
8 CAMLprim value caml_extunix_mkdtemp(value v_path)
9 {
10 CAMLparam1(v_path);
11 char* path = strdup(String_val(v_path));
12 char *ret;
13 caml_enter_blocking_section();
14 ret = mkdtemp(path);
15 caml_leave_blocking_section();
16 if (NULL == ret)
17 {
18 free(path);
19 uerror("mkdtemp", v_path);
20 }
21 v_path = caml_copy_string(ret);
22 free(path);
23 CAMLreturn(v_path);
24 }
25
26 #endif
27
28 #if defined(EXTUNIX_HAVE_MKSTEMPS)
29
30 CAMLprim value caml_extunix_internal_mkstemps(value v_template, value v_suffixlen)
31 {
32 CAMLparam2(v_template, v_suffixlen);
33 char *template = String_val(v_template);
34 int suffixlen = Int_val(v_suffixlen);
35 int ret;
36
37 ret = mkstemps(template, suffixlen);
38 if (ret == -1)
39 {
40 uerror("mkstemps", v_template);
41 }
42 CAMLreturn(Val_int(ret));
43 }
44
45 #endif
46
47 #if defined(EXTUNIX_HAVE_MKOSTEMPS)
48
49 /* FIXME: also in atfile.c, move to common file */
50 #include <fcntl.h>
51
52 #ifndef O_CLOEXEC
53 # define O_CLOEXEC 0
54 #endif
55
56 CAMLprim value caml_extunix_internal_mkostemps(value v_template, value v_suffixlen, value v_flags)
57 {
58 CAMLparam3(v_template, v_suffixlen, v_flags);
59 char *template = String_val(v_template);
60 int flags = extunix_open_flags(v_flags) | O_CLOEXEC;
61 int suffixlen = Int_val(v_suffixlen);
62 int ret;
63
64 ret = mkostemps(template, suffixlen, flags);
65 if (ret == -1)
66 {
67 uerror("mkostemps", v_template);
68 }
69 CAMLreturn(Val_int(ret));
70 }
71
72 #endif
2323 ssize_t ret;
2424 char *buf;
2525
26 #if defined(CMSG_SPACE)
27 union {
28 struct cmsghdr cmsg; /* for alignment */
29 char control[CMSG_SPACE(sizeof(int))]; /* sizeof sendfd */
30 } control_un;
31 #endif
32
2633 memset(&msg, 0, sizeof msg);
2734
28 if (sendfd_val != Val_none) {
35 if (sendfd_val != Val_none)
36 {
2937 int sendfd = Int_val(Some_val(sendfd_val));
3038 #if defined(CMSG_SPACE)
31 union {
32 struct cmsghdr cmsg; /* for alignment */
33 char control[CMSG_SPACE(sizeof sendfd)];
34 } control_un;
3539 struct cmsghdr *cmsgp;
3640
3741 msg.msg_control = control_un.control;
1717 #define TCP_KEEPINTVL (-1)
1818 #endif
1919
20 static int tcp_options[] = {
21 TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL,
20 #ifndef SO_REUSEPORT
21 #define SO_REUSEPORT (-1)
22 #endif
23
24 struct option {
25 int opt;
26 int level;
27 };
28
29 static struct option tcp_options[] = {
30 { TCP_KEEPCNT, IPPROTO_TCP },
31 { TCP_KEEPIDLE, IPPROTO_TCP },
32 { TCP_KEEPINTVL, IPPROTO_TCP },
33 { SO_REUSEPORT, SOL_SOCKET },
2234 };
2335
2436 CAMLprim value caml_extunix_have_sockopt(value k)
2840 caml_invalid_argument("have_sockopt");
2941 }
3042
31 return Val_bool(tcp_options[Int_val(k)] != -1);
43 return Val_bool(tcp_options[Int_val(k)].opt != -1);
3244 }
3345
3446 CAMLprim value caml_extunix_setsockopt_int(value fd, value k, value v)
4153 caml_invalid_argument("setsockopt_int");
4254 }
4355
44 if (tcp_options[Int_val(k)] == -1)
56 if (tcp_options[Int_val(k)].opt == -1)
4557 {
4658 caml_raise_not_found();
4759 assert(0);
4860 }
4961
50 if (0 != setsockopt(Int_val(fd), IPPROTO_TCP, tcp_options[Int_val(k)], &optval, optlen))
62 if (0 != setsockopt(Int_val(fd), tcp_options[Int_val(k)].level, tcp_options[Int_val(k)].opt, &optval, optlen))
5163 {
5264 uerror("setsockopt_int", Nothing);
5365 }
6577 caml_invalid_argument("getsockopt_int");
6678 }
6779
68 if (tcp_options[Int_val(k)] == -1)
80 if (tcp_options[Int_val(k)].opt == -1)
6981 {
7082 caml_raise_not_found();
7183 assert(0);
7284 }
7385
74 if (0 != getsockopt(Int_val(fd), IPPROTO_TCP, tcp_options[Int_val(k)], &optval, &optlen))
86 if (0 != getsockopt(Int_val(fd), tcp_options[Int_val(k)].level, tcp_options[Int_val(k)].opt, &optval, &optlen))
7587 {
7688 uerror("getsockopt_int", Nothing);
7789 }
9494 }
9595
9696 #endif
97
98 #if defined(EXTUNIX_HAVE_MKDTEMP)
99
100 CAMLprim value caml_extunix_mkdtemp(value v_path)
101 {
102 CAMLparam1(v_path);
103 char* path = strdup(String_val(v_path));
104 char *ret;
105 caml_enter_blocking_section();
106 ret = mkdtemp(path);
107 caml_leave_blocking_section();
108 if (NULL == ret)
109 {
110 free(path);
111 uerror("mkdtemp", v_path);
112 }
113 v_path = caml_copy_string(ret);
114 free(path);
115 CAMLreturn(v_path);
116 }
117
118 #endif
119
120 #if defined(EXTUNIX_HAVE_MKSTEMPS)
121
122 CAMLprim value caml_extunix_internal_mkstemps(value v_template, value v_suffixlen)
123 {
124 CAMLparam2(v_template, v_suffixlen);
125 char *template = String_val(v_template);
126 int suffixlen = Int_val(v_suffixlen);
127 int ret;
128
129 ret = mkstemps(template, suffixlen);
130 if (ret == -1)
131 {
132 uerror("mkstemps", v_template);
133 }
134 CAMLreturn(Val_int(ret));
135 }
136
137 #endif
138
139 #if defined(EXTUNIX_HAVE_MKOSTEMPS)
140
141 /* FIXME: also in atfile.c, move to common file */
142 #include <fcntl.h>
143
144 #ifndef O_CLOEXEC
145 # define O_CLOEXEC 0
146 #endif
147
148 CAMLprim value caml_extunix_internal_mkostemps(value v_template, value v_suffixlen, value v_flags)
149 {
150 CAMLparam3(v_template, v_suffixlen, v_flags);
151 char *template = String_val(v_template);
152 int flags = extunix_open_flags(v_flags) | O_CLOEXEC;
153 int suffixlen = Int_val(v_suffixlen);
154 int ret;
155
156 ret = mkostemps(template, suffixlen, flags);
157 if (ret == -1)
158 {
159 uerror("mkostemps", v_template);
160 }
161 CAMLreturn(Val_int(ret));
162 }
163
164 #endif
165
8585
8686 #endif
8787
88 #if defined(EXTUNIX_WANT_TIMEZONE)
88 #if defined(EXTUNIX_HAVE_TIMEZONE)
8989
9090 CAMLprim value caml_extunix_timezone(value v_unit)
9191 {
185185 let name = ptsname master in
186186 let slave = Unix.openfile name [Unix.O_RDWR; Unix.O_NOCTTY] 0 in
187187 let test = "test" in
188 let len = Unix.write slave test 0 (String.length test) in
189 let str = String.create len in
190 ignore (Unix.read master str 0 len);
188 let len = Unix.write_substring slave test 0 (String.length test) in
189 let str =
190 let b = Bytes.create len in
191 assert_equal (Unix.read master b 0 len) len;
192 Bytes.unsafe_to_string b
193 in
191194 assert_equal str test;
192195 ()
193196
318321 assert_equal (L.get_uint63 src 10) (Int64.to_int 0x1032547698BADCFEL);
319322 assert_equal (L.get_int63 src 10) (Int64.to_int 0x1032547698BADCFEL);
320323 assert_equal (L.get_int63 src 10) (Int64.to_int (-0x6FCDAB8967452302L));
321 let b = " " in
324 let b = Bytes.create 18 in
322325 B.set_uint8 b 0 0xFF;
323326 B.set_int8 b 1 (-0x01);
324327 B.set_uint16 b 2 0xFEDC;
325328 B.set_uint16 b 4 (-0x0124);
326329 B.set_int32 b 6 (0xFEDCBA98l);
327330 B.set_int64 b 10 (0xFEDCBA9876543210L);
328 assert_equal b src;
329 let l = " " in
331 assert_equal (Bytes.unsafe_to_string b) src;
332 let l = Bytes.create 18 in
330333 L.set_uint8 l 0 0xFF;
331334 L.set_int8 l 1 (-0x01);
332335 L.set_uint16 l 2 0xDCFE;
333336 L.set_uint16 l 4 (-0x2302);
334337 L.set_int32 l 6 (0x98BADCFEl);
335338 L.set_int64 l 10 (0x1032547698BADCFEL);
336 assert_equal l src
337
339 assert_equal (Bytes.unsafe_to_string l) src
340
338341 let test_read_credentials () =
339342 require "read_credentials";
340343 let (_fd1, fd2) = Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0 in
355358 Unix.close s2;
356359 let wpid, _ = Unix.wait () in
357360 assert_equal wpid pid;
358 let str = String.create 7 in
359 ignore (Unix.read s1 str 0 7);
361 let str =
362 let b = Bytes.create 7 in
363 assert_equal (Unix.read s1 b 0 7) 7;
364 Bytes.unsafe_to_string b
365 in
360366 assert_equal "fexecve" str;
361367 Unix.close s1
362368
382388 assert_equal (int_of_string msg) st.Unix.st_ino;
383389 Unix.close fd
384390
385 let cmp_str str c text =
386 for i = 0 to String.length str - 1 do
387 if str.[i] <> c
391 let cmp_bytes str c text =
392 for i = 0 to Bytes.length str - 1 do
393 if Bytes.get str i <> c
388394 then assert_failure text;
389395 done
390396
397403 try
398404 let size = 65536 in (* Must be larger than UNIX_BUFFER_SIZE (16384) *)
399405 let s = String.make size 'x' in
400 assert_equal (Unix.write fd s 0 size) size;
401 let t = String.make size ' ' in
406 assert_equal (Unix.write_substring fd s 0 size) size;
407 let t = Bytes.make size ' ' in
402408 assert_equal (pread fd 0 t 0 size) size;
403 cmp_str t 'x' "pread read bad data";
404 ignore (single_pread fd 0 t 0 size);
405 let t = String.make size ' ' in
409 cmp_bytes t 'x' "pread read bad data";
410 assert_equal (single_pread fd 0 t 0 size) size;
411 cmp_bytes t 'x' "single_pread read bad data";
412 let t = Bytes.make size ' ' in
406413 assert_equal (LargeFile.pread fd Int64.zero t 0 size) size;
407 cmp_str t 'x' "Largefile.pread read bad data";
408 ignore (LargeFile.single_pread fd Int64.zero t 0 size);
414 cmp_bytes t 'x' "Largefile.pread read bad data";
415 assert_equal (LargeFile.single_pread fd Int64.zero t 0 size) size;
416 cmp_bytes t 'x' "Largefile.single_pread read bad data";
409417 Unix.close fd;
410418 Unix.unlink name
411419 with exn -> Unix.close fd; Unix.unlink name; raise exn
421429 let rec loop off = function
422430 | 0 -> ()
423431 | size ->
424 let len = Unix.read fd dst off size
425 in
426 loop (off + len) (size - len)
432 let len = Unix.read fd dst off size
433 in
434 loop (off + len) (size - len)
427435 in
428 loop 0 (String.length dst)
436 loop 0 (Bytes.length dst)
429437 in
430438 try
431439 let size = 65536 in (* Must be larger than UNIX_BUFFER_SIZE (16384) *)
432440 let s = String.make size 'x' in
433441 assert_equal (pwrite fd 0 s 0 size) size;
434 let t = String.make size ' ' in
442 let t = Bytes.make size ' ' in
435443 read t;
436 cmp_str t 'x' "pwrite wrote bad data";
437 ignore (single_pwrite fd 0 s 0 size);
444 cmp_bytes t 'x' "pwrite wrote bad data";
445 assert_equal (single_pwrite fd 0 s 0 size) size;
446 read t;
447 cmp_bytes t 'x' "single_pwrite wrote bad data";
438448 let s = String.make size 'y' in
439449 assert_equal (LargeFile.pwrite fd Int64.zero s 0 size) size;
450 let t = Bytes.make size ' ' in
440451 read t;
441 cmp_str t 'y' "Largefile.pwrite wrote bad data";
442 ignore (LargeFile.single_pwrite fd Int64.zero s 0 size);
452 cmp_bytes t 'y' "Largefile.pwrite wrote bad data";
453 assert_equal (LargeFile.single_pwrite fd Int64.zero s 0 size) size;
454 read t;
455 cmp_bytes t 'y' "Largefile.single_pwrite wrote bad data";
443456 Unix.close fd;
444457 Unix.unlink name
445458 with exn -> Unix.close fd; Unix.unlink name; raise exn
453466 try
454467 let size = 65536 in (* Must be larger than UNIX_BUFFER_SIZE (16384) *)
455468 let s = String.make size 'x' in
456 assert_equal (Unix.write fd s 0 size) size;
457 let t = String.make size ' ' in
469 assert_equal (Unix.write_substring fd s 0 size) size;
470 let t = Bytes.make size ' ' in
458471 assert_equal (Unix.lseek fd 0 Unix.SEEK_SET) 0;
459472 assert_equal (read fd t 0 size) size;
460 cmp_str t 'x' "read read bad data";
473 cmp_bytes t 'x' "read read bad data";
461474 assert_equal (Unix.lseek fd 0 Unix.SEEK_SET) 0;
462 ignore (single_read fd t 0 size);
475 assert_equal (single_read fd t 0 size) size;
476 cmp_bytes t 'x' "single_read read bad data";
463477 Unix.close fd;
464478 Unix.unlink name
465479 with exn -> Unix.close fd; Unix.unlink name; raise exn
475489 let rec loop off = function
476490 | 0 -> ()
477491 | size ->
478 let len = Unix.read fd dst off size
479 in
480 loop (off + len) (size - len)
492 let len = Unix.read fd dst off size
493 in
494 loop (off + len) (size - len)
481495 in
482 loop 0 (String.length dst)
496 loop 0 (Bytes.length dst)
483497 in
484498 try
485499 let size = 65536 in (* Must be larger than UNIX_BUFFER_SIZE (16384) *)
486500 let s = String.make size 'x' in
487501 assert_equal (write fd s 0 size) size;
488 let t = String.make size ' ' in
502 let t = Bytes.make size ' ' in
489503 read t;
490 cmp_str t 'x' "write wrote bad data";
491 ignore (single_write fd s 0 size);
504 cmp_bytes t 'x' "write wrote bad data";
505 assert_equal (single_write fd s 0 size) size;
506 read t;
507 cmp_bytes t 'x' "single_write wrote bad data";
492508 Unix.close fd;
493509 Unix.unlink name
494510 with exn -> Unix.close fd; Unix.unlink name; raise exn
106106 try
107107 let size = 65536 in
108108 let s = String.make size 'x' in
109 assert_equal (Unix.write fd s 0 size) size;
109 assert_equal (Unix.write_substring fd s 0 size) size;
110110 let t = Bigarray.Array1.create Bigarray.int8_unsigned Bigarray.c_layout size in
111111 assert_equal (pread fd 0 t) size;
112112 cmp_buf t 'x' "pread read bad data";
113 ignore (single_pread fd 0 t);
113 assert_equal (single_pread fd 0 t) size;
114 cmp_buf t 'x' "pread read bad data";
114115 let t = Bigarray.Array1.create Bigarray.int8_unsigned Bigarray.c_layout size in
115116 assert_equal (LargeFile.pread fd Int64.zero t) size;
116117 cmp_buf t 'x' "Largefile.pread read bad data";
117 ignore (LargeFile.single_pread fd Int64.zero t);
118 Unix.close fd;
119 Unix.unlink name
120 with exn -> Unix.close fd; Unix.unlink name; raise exn
121
122 let cmp_str str c text =
123 for i = 0 to String.length str - 1 do
124 if str.[i] <> c
118 assert_equal (LargeFile.single_pread fd Int64.zero t) size;
119 cmp_buf t 'x' "Largefile.single_pread read bad data";
120 Unix.close fd;
121 Unix.unlink name
122 with exn -> Unix.close fd; Unix.unlink name; raise exn
123
124 let cmp_bytes str c text =
125 for i = 0 to Bytes.length str - 1 do
126 if Bytes.get str i <> c
125127 then assert_failure text;
126128 done
127129
136138 let rec loop off = function
137139 | 0 -> ()
138140 | size ->
139 let len = Unix.read fd dst off size
140 in
141 loop (off + len) (size - len)
141 let len = Unix.read fd dst off size
142 in
143 loop (off + len) (size - len)
142144 in
143 loop 0 (String.length dst)
145 loop 0 (Bytes.length dst)
144146 in
145147 try
146148 let size = 65536 in (* Must be larger than UNIX_BUFFER_SIZE (16384) *)
149151 Bigarray.Array1.set s i (int_of_char 'x');
150152 done;
151153 assert_equal (pwrite fd 0 s) size;
152 let t = String.make size ' ' in
153 read t;
154 cmp_str t 'x' "pwrite wrote bad data";
155 ignore (single_pwrite fd 0 s);
154 let t = Bytes.make size ' ' in
155 read t;
156 cmp_bytes t 'x' "pwrite wrote bad data";
157 assert_equal (single_pwrite fd 0 s) size;
158 read t;
159 cmp_bytes t 'x' "single_pwrite wrote bad data";
156160 for i = 0 to size - 1 do
157161 Bigarray.Array1.set s i (int_of_char 'y');
158162 done;
159163 assert_equal (LargeFile.pwrite fd Int64.zero s) size;
160164 read t;
161 cmp_str t 'y' "Largefile.pwrite wrote bad data";
162 ignore (LargeFile.single_pwrite fd Int64.zero s);
165 cmp_bytes t 'y' "Largefile.pwrite wrote bad data";
166 assert_equal (LargeFile.single_pwrite fd Int64.zero s) size;
167 read t;
168 cmp_bytes t 'y' "Largefile.single_pwrite wrote bad data";
163169 Unix.close fd;
164170 Unix.unlink name
165171 with exn -> Unix.close fd; Unix.unlink name; raise exn
180186 try
181187 let size = 65536 in
182188 let s = String.make size 'x' in
183 assert_equal (Unix.write fd s 0 size) size;
189 assert_equal (Unix.write_substring fd s 0 size) size;
184190 let t = Bigarray.Array1.create Bigarray.int8_unsigned Bigarray.c_layout size in
185191 assert_equal (Unix.lseek fd 0 Unix.SEEK_SET) 0;
186192 assert_equal (read fd t) size;
187193 cmp_buf t 'x' "read read bad data";
188194 assert_equal (Unix.lseek fd 0 Unix.SEEK_SET) 0;
189 ignore (single_read fd t);
195 assert_equal (single_read fd t) size;
196 cmp_buf t 'x' "single_read read bad data";
190197 Unix.close fd;
191198 Unix.unlink name
192199 with exn -> Unix.close fd; Unix.unlink name; raise exn
202209 let rec loop off = function
203210 | 0 -> ()
204211 | size ->
205 let len = Unix.read fd dst off size
206 in
207 loop (off + len) (size - len)
212 let len = Unix.read fd dst off size
213 in
214 loop (off + len) (size - len)
208215 in
209 loop 0 (String.length dst)
216 loop 0 (Bytes.length dst)
210217 in
211218 try
212219 let size = 65536 in (* Must be larger than UNIX_BUFFER_SIZE (16384) *)
215222 Bigarray.Array1.set s i (int_of_char 'x');
216223 done;
217224 assert_equal (write fd s) size;
218 let t = String.make size ' ' in
219 read t;
220 cmp_str t 'x' "write wrote bad data";
221 ignore (single_write fd s);
225 let t = Bytes.make size ' ' in
226 read t;
227 cmp_bytes t 'x' "write wrote bad data";
228 assert_equal (single_write fd s) size;
229 read t;
230 cmp_bytes t 'x' "write wrote bad data";
222231 Unix.close fd;
223232 Unix.unlink name
224233 with exn -> Unix.close fd; Unix.unlink name; raise exn