lustrec / setup.ml @ 690196d8
History | View | Annotate | Download (153 KB)
1 | 22fe1c93 | ploc | (* setup.ml generated for the first time by OASIS v0.2.0 *) |
---|---|---|---|
2 | |||
3 | (* OASIS_START *) |
||
4 | d1baac41 | xthirioux | (* DO NOT EDIT (digest: cbef9780a942e499729218b6c22c21f0) *) |
5 | 22fe1c93 | ploc | (* |
6 | d1baac41 | xthirioux | Regenerated by OASIS v0.3.0 |
7 | 22fe1c93 | ploc | Visit http://oasis.forge.ocamlcore.org for more information and |
8 | documentation about functions used in this file. |
||
9 | *) |
||
10 | module OASISGettext = struct |
||
11 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISGettext.ml" *) |
12 | 04e26a3f | xthirioux | |
13 | let ns_ str = |
||
14 | 22fe1c93 | ploc | str |
15 | 04e26a3f | xthirioux | |
16 | let s_ str = |
||
17 | 22fe1c93 | ploc | str |
18 | 04e26a3f | xthirioux | |
19 | d1baac41 | xthirioux | let f_ (str : ('a, 'b, 'c, 'd) format4) = |
20 | 22fe1c93 | ploc | str |
21 | 04e26a3f | xthirioux | |
22 | 22fe1c93 | ploc | let fn_ fmt1 fmt2 n = |
23 | if n = 1 then |
||
24 | fmt1^^"" |
||
25 | else |
||
26 | fmt2^^"" |
||
27 | 04e26a3f | xthirioux | |
28 | let init = |
||
29 | 22fe1c93 | ploc | [] |
30 | 04e26a3f | xthirioux | |
31 | 22fe1c93 | ploc | end |
32 | |||
33 | module OASISContext = struct |
||
34 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISContext.ml" *) |
35 | 04e26a3f | xthirioux | |
36 | open OASISGettext |
||
37 | |||
38 | 22fe1c93 | ploc | type level = |
39 | [ `Debug |
||
40 | 04e26a3f | xthirioux | | `Info |
41 | 22fe1c93 | ploc | | `Warning |
42 | | `Error] |
||
43 | 04e26a3f | xthirioux | |
44 | 22fe1c93 | ploc | type t = |
45 | { |
||
46 | 04e26a3f | xthirioux | quiet: bool; |
47 | info: bool; |
||
48 | debug: bool; |
||
49 | ignore_plugins: bool; |
||
50 | ignore_unknown_fields: bool; |
||
51 | printf: level -> string -> unit; |
||
52 | 22fe1c93 | ploc | } |
53 | 04e26a3f | xthirioux | |
54 | let printf lvl str = |
||
55 | let beg = |
||
56 | match lvl with |
||
57 | 22fe1c93 | ploc | | `Error -> s_ "E: " |
58 | | `Warning -> s_ "W: " |
||
59 | | `Info -> s_ "I: " |
||
60 | | `Debug -> s_ "D: " |
||
61 | in |
||
62 | 04e26a3f | xthirioux | prerr_endline (beg^str) |
63 | |||
64 | 22fe1c93 | ploc | let default = |
65 | 04e26a3f | xthirioux | ref |
66 | 22fe1c93 | ploc | { |
67 | 04e26a3f | xthirioux | quiet = false; |
68 | info = false; |
||
69 | debug = false; |
||
70 | ignore_plugins = false; |
||
71 | ignore_unknown_fields = false; |
||
72 | printf = printf; |
||
73 | 22fe1c93 | ploc | } |
74 | 04e26a3f | xthirioux | |
75 | let quiet = |
||
76 | {!default with quiet = true} |
||
77 | |||
78 | |||
79 | d1baac41 | xthirioux | let args () = |
80 | 22fe1c93 | ploc | ["-quiet", |
81 | 04e26a3f | xthirioux | Arg.Unit (fun () -> default := {!default with quiet = true}), |
82 | d1baac41 | xthirioux | (s_ " Run quietly"); |
83 | 04e26a3f | xthirioux | |
84 | "-info", |
||
85 | Arg.Unit (fun () -> default := {!default with info = true}), |
||
86 | d1baac41 | xthirioux | (s_ " Display information message"); |
87 | 04e26a3f | xthirioux | |
88 | |||
89 | 22fe1c93 | ploc | "-debug", |
90 | Arg.Unit (fun () -> default := {!default with debug = true}), |
||
91 | d1baac41 | xthirioux | (s_ " Output debug message")] |
92 | 22fe1c93 | ploc | end |
93 | |||
94 | 04e26a3f | xthirioux | module OASISString = struct |
95 | d1baac41 | xthirioux | (* # 1 "src/oasis/OASISString.ml" *) |
96 | 04e26a3f | xthirioux | |
97 | 719f9992 | xthirioux | |
98 | 9603460e | xthirioux | |
99 | d1baac41 | xthirioux | (** Various string utilities. |
100 | |||
101 | 04e26a3f | xthirioux | Mostly inspired by extlib and batteries ExtString and BatString libraries. |
102 | |||
103 | @author Sylvain Le Gall |
||
104 | *) |
||
105 | |||
106 | let nsplitf str f = |
||
107 | if str = "" then |
||
108 | [] |
||
109 | else |
||
110 | let buf = Buffer.create 13 in |
||
111 | let lst = ref [] in |
||
112 | let push () = |
||
113 | lst := Buffer.contents buf :: !lst; |
||
114 | Buffer.clear buf |
||
115 | in |
||
116 | let str_len = String.length str in |
||
117 | for i = 0 to str_len - 1 do |
||
118 | if f str.[i] then |
||
119 | push () |
||
120 | else |
||
121 | Buffer.add_char buf str.[i] |
||
122 | done; |
||
123 | push (); |
||
124 | List.rev !lst |
||
125 | |||
126 | (** [nsplit c s] Split the string [s] at char [c]. It doesn't include the |
||
127 | separator. |
||
128 | *) |
||
129 | let nsplit str c = |
||
130 | nsplitf str ((=) c) |
||
131 | |||
132 | let find ~what ?(offset=0) str = |
||
133 | let what_idx = ref 0 in |
||
134 | d1baac41 | xthirioux | let str_idx = ref offset in |
135 | while !str_idx < String.length str && |
||
136 | 04e26a3f | xthirioux | !what_idx < String.length what do |
137 | if str.[!str_idx] = what.[!what_idx] then |
||
138 | incr what_idx |
||
139 | else |
||
140 | what_idx := 0; |
||
141 | incr str_idx |
||
142 | done; |
||
143 | if !what_idx <> String.length what then |
||
144 | raise Not_found |
||
145 | d1baac41 | xthirioux | else |
146 | 04e26a3f | xthirioux | !str_idx - !what_idx |
147 | |||
148 | d1baac41 | xthirioux | let sub_start str len = |
149 | 04e26a3f | xthirioux | let str_len = String.length str in |
150 | if len >= str_len then |
||
151 | "" |
||
152 | else |
||
153 | String.sub str len (str_len - len) |
||
154 | |||
155 | let sub_end ?(offset=0) str len = |
||
156 | let str_len = String.length str in |
||
157 | if len >= str_len then |
||
158 | "" |
||
159 | else |
||
160 | String.sub str 0 (str_len - len) |
||
161 | |||
162 | let starts_with ~what ?(offset=0) str = |
||
163 | let what_idx = ref 0 in |
||
164 | let str_idx = ref offset in |
||
165 | let ok = ref true in |
||
166 | while !ok && |
||
167 | d1baac41 | xthirioux | !str_idx < String.length str && |
168 | 04e26a3f | xthirioux | !what_idx < String.length what do |
169 | if str.[!str_idx] = what.[!what_idx] then |
||
170 | incr what_idx |
||
171 | else |
||
172 | ok := false; |
||
173 | incr str_idx |
||
174 | done; |
||
175 | if !what_idx = String.length what then |
||
176 | true |
||
177 | d1baac41 | xthirioux | else |
178 | 04e26a3f | xthirioux | false |
179 | |||
180 | let strip_starts_with ~what str = |
||
181 | if starts_with ~what str then |
||
182 | sub_start str (String.length what) |
||
183 | else |
||
184 | raise Not_found |
||
185 | |||
186 | let ends_with ~what ?(offset=0) str = |
||
187 | let what_idx = ref ((String.length what) - 1) in |
||
188 | let str_idx = ref ((String.length str) - 1) in |
||
189 | let ok = ref true in |
||
190 | while !ok && |
||
191 | d1baac41 | xthirioux | offset <= !str_idx && |
192 | 04e26a3f | xthirioux | 0 <= !what_idx do |
193 | if str.[!str_idx] = what.[!what_idx] then |
||
194 | decr what_idx |
||
195 | else |
||
196 | ok := false; |
||
197 | decr str_idx |
||
198 | done; |
||
199 | if !what_idx = -1 then |
||
200 | true |
||
201 | d1baac41 | xthirioux | else |
202 | 04e26a3f | xthirioux | false |
203 | |||
204 | let strip_ends_with ~what str = |
||
205 | if ends_with ~what str then |
||
206 | sub_end str (String.length what) |
||
207 | else |
||
208 | raise Not_found |
||
209 | |||
210 | let replace_chars f s = |
||
211 | let buf = String.make (String.length s) 'X' in |
||
212 | for i = 0 to String.length s - 1 do |
||
213 | buf.[i] <- f s.[i] |
||
214 | done; |
||
215 | buf |
||
216 | |||
217 | end |
||
218 | |||
219 | 22fe1c93 | ploc | module OASISUtils = struct |
220 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISUtils.ml" *) |
221 | 04e26a3f | xthirioux | |
222 | open OASISGettext |
||
223 | |||
224 | d1baac41 | xthirioux | module MapString = Map.Make(String) |
225 | 04e26a3f | xthirioux | |
226 | d1baac41 | xthirioux | let map_string_of_assoc assoc = |
227 | List.fold_left |
||
228 | (fun acc (k, v) -> MapString.add k v acc) |
||
229 | MapString.empty |
||
230 | assoc |
||
231 | 9603460e | xthirioux | |
232 | d1baac41 | xthirioux | module SetString = Set.Make(String) |
233 | 9603460e | xthirioux | |
234 | d1baac41 | xthirioux | let set_string_add_list st lst = |
235 | List.fold_left |
||
236 | (fun acc e -> SetString.add e acc) |
||
237 | st |
||
238 | lst |
||
239 | 9603460e | xthirioux | |
240 | d1baac41 | xthirioux | let set_string_of_list = |
241 | set_string_add_list |
||
242 | SetString.empty |
||
243 | 04e26a3f | xthirioux | |
244 | |||
245 | let compare_csl s1 s2 = |
||
246 | 22fe1c93 | ploc | String.compare (String.lowercase s1) (String.lowercase s2) |
247 | 04e26a3f | xthirioux | |
248 | module HashStringCsl = |
||
249 | 22fe1c93 | ploc | Hashtbl.Make |
250 | (struct |
||
251 | type t = string |
||
252 | 04e26a3f | xthirioux | |
253 | let equal s1 s2 = |
||
254 | 22fe1c93 | ploc | (String.lowercase s1) = (String.lowercase s2) |
255 | 04e26a3f | xthirioux | |
256 | 22fe1c93 | ploc | let hash s = |
257 | Hashtbl.hash (String.lowercase s) |
||
258 | end) |
||
259 | 04e26a3f | xthirioux | |
260 | let varname_of_string ?(hyphen='_') s = |
||
261 | 22fe1c93 | ploc | if String.length s = 0 then |
262 | begin |
||
263 | 04e26a3f | xthirioux | invalid_arg "varname_of_string" |
264 | 22fe1c93 | ploc | end |
265 | else |
||
266 | begin |
||
267 | 04e26a3f | xthirioux | let buf = |
268 | OASISString.replace_chars |
||
269 | 22fe1c93 | ploc | (fun c -> |
270 | 04e26a3f | xthirioux | if ('a' <= c && c <= 'z') |
271 | || |
||
272 | ('A' <= c && c <= 'Z') |
||
273 | || |
||
274 | 22fe1c93 | ploc | ('0' <= c && c <= '9') then |
275 | 04e26a3f | xthirioux | c |
276 | 22fe1c93 | ploc | else |
277 | 04e26a3f | xthirioux | hyphen) |
278 | 22fe1c93 | ploc | s; |
279 | 04e26a3f | xthirioux | in |
280 | let buf = |
||
281 | (* Start with a _ if digit *) |
||
282 | if '0' <= s.[0] && s.[0] <= '9' then |
||
283 | "_"^buf |
||
284 | else |
||
285 | buf |
||
286 | in |
||
287 | String.lowercase buf |
||
288 | 22fe1c93 | ploc | end |
289 | 04e26a3f | xthirioux | |
290 | let varname_concat ?(hyphen='_') p s = |
||
291 | let what = String.make 1 hyphen in |
||
292 | let p = |
||
293 | try |
||
294 | OASISString.strip_ends_with ~what p |
||
295 | with Not_found -> |
||
296 | p |
||
297 | 22fe1c93 | ploc | in |
298 | 04e26a3f | xthirioux | let s = |
299 | try |
||
300 | OASISString.strip_starts_with ~what s |
||
301 | with Not_found -> |
||
302 | s |
||
303 | 22fe1c93 | ploc | in |
304 | 04e26a3f | xthirioux | p^what^s |
305 | |||
306 | |||
307 | let is_varname str = |
||
308 | 22fe1c93 | ploc | str = varname_of_string str |
309 | 04e26a3f | xthirioux | |
310 | let failwithf fmt = Printf.ksprintf failwith fmt |
||
311 | |||
312 | 22fe1c93 | ploc | end |
313 | |||
314 | module PropList = struct |
||
315 | d1baac41 | xthirioux | (* # 21 "src/oasis/PropList.ml" *) |
316 | 04e26a3f | xthirioux | |
317 | 22fe1c93 | ploc | open OASISGettext |
318 | 04e26a3f | xthirioux | |
319 | 22fe1c93 | ploc | type name = string |
320 | 04e26a3f | xthirioux | |
321 | exception Not_set of name * string option |
||
322 | 22fe1c93 | ploc | exception No_printer of name |
323 | exception Unknown_field of name * name |
||
324 | 04e26a3f | xthirioux | |
325 | let () = |
||
326 | Printexc.register_printer |
||
327 | (function |
||
328 | | Not_set (nm, Some rsn) -> |
||
329 | d1baac41 | xthirioux | Some |
330 | 04e26a3f | xthirioux | (Printf.sprintf (f_ "Field '%s' is not set: %s") nm rsn) |
331 | | Not_set (nm, None) -> |
||
332 | d1baac41 | xthirioux | Some |
333 | 04e26a3f | xthirioux | (Printf.sprintf (f_ "Field '%s' is not set") nm) |
334 | | No_printer nm -> |
||
335 | Some |
||
336 | (Printf.sprintf (f_ "No default printer for value %s") nm) |
||
337 | | Unknown_field (nm, schm) -> |
||
338 | d1baac41 | xthirioux | Some |
339 | (Printf.sprintf (f_ "Field %s is not defined in schema %s") nm schm) |
||
340 | 04e26a3f | xthirioux | | _ -> |
341 | None) |
||
342 | |||
343 | 22fe1c93 | ploc | module Data = |
344 | struct |
||
345 | d1baac41 | xthirioux | |
346 | 04e26a3f | xthirioux | type t = |
347 | 22fe1c93 | ploc | (name, unit -> unit) Hashtbl.t |
348 | 04e26a3f | xthirioux | |
349 | 22fe1c93 | ploc | let create () = |
350 | Hashtbl.create 13 |
||
351 | 04e26a3f | xthirioux | |
352 | 22fe1c93 | ploc | let clear t = |
353 | Hashtbl.clear t |
||
354 | 04e26a3f | xthirioux | |
355 | d1baac41 | xthirioux | (* # 71 "src/oasis/PropList.ml" *) |
356 | 22fe1c93 | ploc | end |
357 | 04e26a3f | xthirioux | |
358 | module Schema = |
||
359 | 22fe1c93 | ploc | struct |
360 | d1baac41 | xthirioux | |
361 | 22fe1c93 | ploc | type ('ctxt, 'extra) value = |
362 | { |
||
363 | get: Data.t -> string; |
||
364 | set: Data.t -> ?context:'ctxt -> string -> unit; |
||
365 | help: (unit -> string) option; |
||
366 | extra: 'extra; |
||
367 | } |
||
368 | 04e26a3f | xthirioux | |
369 | 22fe1c93 | ploc | type ('ctxt, 'extra) t = |
370 | { |
||
371 | name: name; |
||
372 | fields: (name, ('ctxt, 'extra) value) Hashtbl.t; |
||
373 | order: name Queue.t; |
||
374 | name_norm: string -> string; |
||
375 | } |
||
376 | 04e26a3f | xthirioux | |
377 | let create ?(case_insensitive=false) nm = |
||
378 | 22fe1c93 | ploc | { |
379 | name = nm; |
||
380 | fields = Hashtbl.create 13; |
||
381 | order = Queue.create (); |
||
382 | 04e26a3f | xthirioux | name_norm = |
383 | (if case_insensitive then |
||
384 | 22fe1c93 | ploc | String.lowercase |
385 | else |
||
386 | fun s -> s); |
||
387 | } |
||
388 | 04e26a3f | xthirioux | |
389 | let add t nm set get extra help = |
||
390 | let key = |
||
391 | 22fe1c93 | ploc | t.name_norm nm |
392 | in |
||
393 | 04e26a3f | xthirioux | |
394 | 22fe1c93 | ploc | if Hashtbl.mem t.fields key then |
395 | failwith |
||
396 | 04e26a3f | xthirioux | (Printf.sprintf |
397 | 22fe1c93 | ploc | (f_ "Field '%s' is already defined in schema '%s'") |
398 | nm t.name); |
||
399 | 04e26a3f | xthirioux | Hashtbl.add |
400 | t.fields |
||
401 | key |
||
402 | 22fe1c93 | ploc | { |
403 | 04e26a3f | xthirioux | set = set; |
404 | get = get; |
||
405 | 22fe1c93 | ploc | help = help; |
406 | extra = extra; |
||
407 | }; |
||
408 | 04e26a3f | xthirioux | Queue.add nm t.order |
409 | |||
410 | 22fe1c93 | ploc | let mem t nm = |
411 | 04e26a3f | xthirioux | Hashtbl.mem t.fields nm |
412 | |||
413 | let find t nm = |
||
414 | 22fe1c93 | ploc | try |
415 | Hashtbl.find t.fields (t.name_norm nm) |
||
416 | with Not_found -> |
||
417 | raise (Unknown_field (nm, t.name)) |
||
418 | 04e26a3f | xthirioux | |
419 | 22fe1c93 | ploc | let get t data nm = |
420 | (find t nm).get data |
||
421 | 04e26a3f | xthirioux | |
422 | 22fe1c93 | ploc | let set t data nm ?context x = |
423 | 04e26a3f | xthirioux | (find t nm).set |
424 | data |
||
425 | ?context |
||
426 | 22fe1c93 | ploc | x |
427 | 04e26a3f | xthirioux | |
428 | 22fe1c93 | ploc | let fold f acc t = |
429 | 04e26a3f | xthirioux | Queue.fold |
430 | 22fe1c93 | ploc | (fun acc k -> |
431 | let v = |
||
432 | find t k |
||
433 | in |
||
434 | f acc k v.extra v.help) |
||
435 | 04e26a3f | xthirioux | acc |
436 | 22fe1c93 | ploc | t.order |
437 | 04e26a3f | xthirioux | |
438 | 22fe1c93 | ploc | let iter f t = |
439 | 04e26a3f | xthirioux | fold |
440 | 22fe1c93 | ploc | (fun () -> f) |
441 | () |
||
442 | t |
||
443 | 04e26a3f | xthirioux | |
444 | let name t = |
||
445 | 22fe1c93 | ploc | t.name |
446 | end |
||
447 | 04e26a3f | xthirioux | |
448 | 22fe1c93 | ploc | module Field = |
449 | struct |
||
450 | d1baac41 | xthirioux | |
451 | 22fe1c93 | ploc | type ('ctxt, 'value, 'extra) t = |
452 | { |
||
453 | set: Data.t -> ?context:'ctxt -> 'value -> unit; |
||
454 | get: Data.t -> 'value; |
||
455 | sets: Data.t -> ?context:'ctxt -> string -> unit; |
||
456 | gets: Data.t -> string; |
||
457 | help: (unit -> string) option; |
||
458 | extra: 'extra; |
||
459 | } |
||
460 | 04e26a3f | xthirioux | |
461 | let new_id = |
||
462 | 22fe1c93 | ploc | let last_id = |
463 | ref 0 |
||
464 | in |
||
465 | fun () -> incr last_id; !last_id |
||
466 | 04e26a3f | xthirioux | |
467 | 22fe1c93 | ploc | let create ?schema ?name ?parse ?print ?default ?update ?help extra = |
468 | (* Default value container *) |
||
469 | 04e26a3f | xthirioux | let v = |
470 | ref None |
||
471 | 22fe1c93 | ploc | in |
472 | 04e26a3f | xthirioux | |
473 | 22fe1c93 | ploc | (* If name is not given, create unique one *) |
474 | 04e26a3f | xthirioux | let nm = |
475 | match name with |
||
476 | 22fe1c93 | ploc | | Some s -> s |
477 | | None -> Printf.sprintf "_anon_%d" (new_id ()) |
||
478 | in |
||
479 | 04e26a3f | xthirioux | |
480 | 22fe1c93 | ploc | (* Last chance to get a value: the default *) |
481 | 04e26a3f | xthirioux | let default () = |
482 | match default with |
||
483 | 22fe1c93 | ploc | | Some d -> d |
484 | | None -> raise (Not_set (nm, Some (s_ "no default value"))) |
||
485 | in |
||
486 | 04e26a3f | xthirioux | |
487 | 22fe1c93 | ploc | (* Get data *) |
488 | let get data = |
||
489 | (* Get value *) |
||
490 | 04e26a3f | xthirioux | try |
491 | 22fe1c93 | ploc | (Hashtbl.find data nm) (); |
492 | 04e26a3f | xthirioux | match !v with |
493 | | Some x -> x |
||
494 | 22fe1c93 | ploc | | None -> default () |
495 | with Not_found -> |
||
496 | default () |
||
497 | in |
||
498 | 04e26a3f | xthirioux | |
499 | 22fe1c93 | ploc | (* Set data *) |
500 | 04e26a3f | xthirioux | let set data ?context x = |
501 | let x = |
||
502 | match update with |
||
503 | 22fe1c93 | ploc | | Some f -> |
504 | begin |
||
505 | 04e26a3f | xthirioux | try |
506 | 22fe1c93 | ploc | f ?context (get data) x |
507 | with Not_set _ -> |
||
508 | x |
||
509 | end |
||
510 | | None -> |
||
511 | x |
||
512 | in |
||
513 | 04e26a3f | xthirioux | Hashtbl.replace |
514 | data |
||
515 | nm |
||
516 | (fun () -> v := Some x) |
||
517 | 22fe1c93 | ploc | in |
518 | 04e26a3f | xthirioux | |
519 | 22fe1c93 | ploc | (* Parse string value, if possible *) |
520 | let parse = |
||
521 | 04e26a3f | xthirioux | match parse with |
522 | | Some f -> |
||
523 | 22fe1c93 | ploc | f |
524 | | None -> |
||
525 | fun ?context s -> |
||
526 | 04e26a3f | xthirioux | failwith |
527 | (Printf.sprintf |
||
528 | 22fe1c93 | ploc | (f_ "Cannot parse field '%s' when setting value %S") |
529 | nm |
||
530 | s) |
||
531 | in |
||
532 | 04e26a3f | xthirioux | |
533 | 22fe1c93 | ploc | (* Set data, from string *) |
534 | let sets data ?context s = |
||
535 | set ?context data (parse ?context s) |
||
536 | in |
||
537 | 04e26a3f | xthirioux | |
538 | 22fe1c93 | ploc | (* Output value as string, if possible *) |
539 | let print = |
||
540 | match print with |
||
541 | | Some f -> |
||
542 | f |
||
543 | | None -> |
||
544 | fun _ -> raise (No_printer nm) |
||
545 | in |
||
546 | 04e26a3f | xthirioux | |
547 | 22fe1c93 | ploc | (* Get data, as a string *) |
548 | let gets data = |
||
549 | print (get data) |
||
550 | in |
||
551 | 04e26a3f | xthirioux | |
552 | begin |
||
553 | match schema with |
||
554 | 22fe1c93 | ploc | | Some t -> |
555 | Schema.add t nm sets gets extra help |
||
556 | | None -> |
||
557 | () |
||
558 | end; |
||
559 | 04e26a3f | xthirioux | |
560 | 22fe1c93 | ploc | { |
561 | set = set; |
||
562 | get = get; |
||
563 | sets = sets; |
||
564 | gets = gets; |
||
565 | help = help; |
||
566 | extra = extra; |
||
567 | } |
||
568 | 04e26a3f | xthirioux | |
569 | let fset data t ?context x = |
||
570 | 22fe1c93 | ploc | t.set data ?context x |
571 | 04e26a3f | xthirioux | |
572 | 22fe1c93 | ploc | let fget data t = |
573 | t.get data |
||
574 | 04e26a3f | xthirioux | |
575 | 22fe1c93 | ploc | let fsets data t ?context s = |
576 | t.sets data ?context s |
||
577 | 04e26a3f | xthirioux | |
578 | 22fe1c93 | ploc | let fgets data t = |
579 | 04e26a3f | xthirioux | t.gets data |
580 | 719f9992 | xthirioux | |
581 | d1baac41 | xthirioux | end |
582 | 9603460e | xthirioux | |
583 | 22fe1c93 | ploc | module FieldRO = |
584 | struct |
||
585 | d1baac41 | xthirioux | |
586 | 22fe1c93 | ploc | let create ?schema ?name ?parse ?print ?default ?update ?help extra = |
587 | 04e26a3f | xthirioux | let fld = |
588 | 22fe1c93 | ploc | Field.create ?schema ?name ?parse ?print ?default ?update ?help extra |
589 | in |
||
590 | fun data -> Field.fget data fld |
||
591 | d1baac41 | xthirioux | |
592 | 22fe1c93 | ploc | end |
593 | end |
||
594 | |||
595 | module OASISMessage = struct |
||
596 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISMessage.ml" *) |
597 | 04e26a3f | xthirioux | |
598 | |||
599 | 22fe1c93 | ploc | open OASISGettext |
600 | open OASISContext |
||
601 | 04e26a3f | xthirioux | |
602 | 22fe1c93 | ploc | let generic_message ~ctxt lvl fmt = |
603 | 04e26a3f | xthirioux | let cond = |
604 | if ctxt.quiet then |
||
605 | false |
||
606 | else |
||
607 | match lvl with |
||
608 | | `Debug -> ctxt.debug |
||
609 | | `Info -> ctxt.info |
||
610 | | _ -> true |
||
611 | 22fe1c93 | ploc | in |
612 | 04e26a3f | xthirioux | Printf.ksprintf |
613 | (fun str -> |
||
614 | 22fe1c93 | ploc | if cond then |
615 | begin |
||
616 | ctxt.printf lvl str |
||
617 | end) |
||
618 | fmt |
||
619 | 04e26a3f | xthirioux | |
620 | 22fe1c93 | ploc | let debug ~ctxt fmt = |
621 | generic_message ~ctxt `Debug fmt |
||
622 | 04e26a3f | xthirioux | |
623 | let info ~ctxt fmt = |
||
624 | 22fe1c93 | ploc | generic_message ~ctxt `Info fmt |
625 | 04e26a3f | xthirioux | |
626 | 22fe1c93 | ploc | let warning ~ctxt fmt = |
627 | generic_message ~ctxt `Warning fmt |
||
628 | 04e26a3f | xthirioux | |
629 | 22fe1c93 | ploc | let error ~ctxt fmt = |
630 | generic_message ~ctxt `Error fmt |
||
631 | 04e26a3f | xthirioux | |
632 | 22fe1c93 | ploc | end |
633 | |||
634 | module OASISVersion = struct |
||
635 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISVersion.ml" *) |
636 | 04e26a3f | xthirioux | |
637 | 22fe1c93 | ploc | open OASISGettext |
638 | 04e26a3f | xthirioux | |
639 | |||
640 | |||
641 | 22fe1c93 | ploc | type s = string |
642 | 04e26a3f | xthirioux | |
643 | d1baac41 | xthirioux | type t = string |
644 | 04e26a3f | xthirioux | |
645 | type comparator = |
||
646 | 22fe1c93 | ploc | | VGreater of t |
647 | | VGreaterEqual of t |
||
648 | | VEqual of t |
||
649 | | VLesser of t |
||
650 | | VLesserEqual of t |
||
651 | | VOr of comparator * comparator |
||
652 | | VAnd of comparator * comparator |
||
653 | d1baac41 | xthirioux | |
654 | 04e26a3f | xthirioux | |
655 | 22fe1c93 | ploc | (* Range of allowed characters *) |
656 | let is_digit c = |
||
657 | '0' <= c && c <= '9' |
||
658 | 04e26a3f | xthirioux | |
659 | 22fe1c93 | ploc | let is_alpha c = |
660 | ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') |
||
661 | 04e26a3f | xthirioux | |
662 | 22fe1c93 | ploc | let is_special = |
663 | 04e26a3f | xthirioux | function |
664 | 22fe1c93 | ploc | | '.' | '+' | '-' | '~' -> true |
665 | | _ -> false |
||
666 | 04e26a3f | xthirioux | |
667 | 22fe1c93 | ploc | let rec version_compare v1 v2 = |
668 | if v1 <> "" || v2 <> "" then |
||
669 | begin |
||
670 | 04e26a3f | xthirioux | (* Compare ascii string, using special meaning for version |
671 | 22fe1c93 | ploc | * related char |
672 | *) |
||
673 | 04e26a3f | xthirioux | let val_ascii c = |
674 | 22fe1c93 | ploc | if c = '~' then -1 |
675 | else if is_digit c then 0 |
||
676 | else if c = '\000' then 0 |
||
677 | else if is_alpha c then Char.code c |
||
678 | else (Char.code c) + 256 |
||
679 | in |
||
680 | 04e26a3f | xthirioux | |
681 | 22fe1c93 | ploc | let len1 = String.length v1 in |
682 | let len2 = String.length v2 in |
||
683 | 04e26a3f | xthirioux | |
684 | 22fe1c93 | ploc | let p = ref 0 in |
685 | 04e26a3f | xthirioux | |
686 | 22fe1c93 | ploc | (** Compare ascii part *) |
687 | 04e26a3f | xthirioux | let compare_vascii () = |
688 | 22fe1c93 | ploc | let cmp = ref 0 in |
689 | 04e26a3f | xthirioux | while !cmp = 0 && |
690 | !p < len1 && !p < len2 && |
||
691 | not (is_digit v1.[!p] && is_digit v2.[!p]) do |
||
692 | 22fe1c93 | ploc | cmp := (val_ascii v1.[!p]) - (val_ascii v2.[!p]); |
693 | incr p |
||
694 | done; |
||
695 | if !cmp = 0 && !p < len1 && !p = len2 then |
||
696 | 04e26a3f | xthirioux | val_ascii v1.[!p] |
697 | 22fe1c93 | ploc | else if !cmp = 0 && !p = len1 && !p < len2 then |
698 | - (val_ascii v2.[!p]) |
||
699 | else |
||
700 | !cmp |
||
701 | in |
||
702 | 04e26a3f | xthirioux | |
703 | 22fe1c93 | ploc | (** Compare digit part *) |
704 | 04e26a3f | xthirioux | let compare_digit () = |
705 | 22fe1c93 | ploc | let extract_int v p = |
706 | let start_p = !p in |
||
707 | 04e26a3f | xthirioux | while !p < String.length v && is_digit v.[!p] do |
708 | 22fe1c93 | ploc | incr p |
709 | done; |
||
710 | d1baac41 | xthirioux | let substr = |
711 | 04e26a3f | xthirioux | String.sub v !p ((String.length v) - !p) |
712 | d1baac41 | xthirioux | in |
713 | let res = |
||
714 | match String.sub v start_p (!p - start_p) with |
||
715 | 04e26a3f | xthirioux | | "" -> 0 |
716 | | s -> int_of_string s |
||
717 | in |
||
718 | res, substr |
||
719 | 22fe1c93 | ploc | in |
720 | let i1, tl1 = extract_int v1 (ref !p) in |
||
721 | let i2, tl2 = extract_int v2 (ref !p) in |
||
722 | i1 - i2, tl1, tl2 |
||
723 | in |
||
724 | 04e26a3f | xthirioux | |
725 | 22fe1c93 | ploc | match compare_vascii () with |
726 | | 0 -> |
||
727 | begin |
||
728 | 04e26a3f | xthirioux | match compare_digit () with |
729 | 22fe1c93 | ploc | | 0, tl1, tl2 -> |
730 | if tl1 <> "" && is_digit tl1.[0] then |
||
731 | 1 |
||
732 | else if tl2 <> "" && is_digit tl2.[0] then |
||
733 | -1 |
||
734 | else |
||
735 | version_compare tl1 tl2 |
||
736 | | n, _, _ -> |
||
737 | n |
||
738 | end |
||
739 | | n -> |
||
740 | n |
||
741 | end |
||
742 | else |
||
743 | begin |
||
744 | 0 |
||
745 | end |
||
746 | 04e26a3f | xthirioux | |
747 | |||
748 | let version_of_string str = str |
||
749 | |||
750 | let string_of_version t = t |
||
751 | |||
752 | let chop t = |
||
753 | try |
||
754 | let pos = |
||
755 | String.rindex t '.' |
||
756 | 22fe1c93 | ploc | in |
757 | String.sub t 0 pos |
||
758 | with Not_found -> |
||
759 | t |
||
760 | 04e26a3f | xthirioux | |
761 | 22fe1c93 | ploc | let rec comparator_apply v op = |
762 | match op with |
||
763 | | VGreater cv -> |
||
764 | (version_compare v cv) > 0 |
||
765 | | VGreaterEqual cv -> |
||
766 | (version_compare v cv) >= 0 |
||
767 | | VLesser cv -> |
||
768 | (version_compare v cv) < 0 |
||
769 | | VLesserEqual cv -> |
||
770 | (version_compare v cv) <= 0 |
||
771 | | VEqual cv -> |
||
772 | (version_compare v cv) = 0 |
||
773 | | VOr (op1, op2) -> |
||
774 | (comparator_apply v op1) || (comparator_apply v op2) |
||
775 | | VAnd (op1, op2) -> |
||
776 | (comparator_apply v op1) && (comparator_apply v op2) |
||
777 | 04e26a3f | xthirioux | |
778 | 22fe1c93 | ploc | let rec string_of_comparator = |
779 | 04e26a3f | xthirioux | function |
780 | 22fe1c93 | ploc | | VGreater v -> "> "^(string_of_version v) |
781 | | VEqual v -> "= "^(string_of_version v) |
||
782 | | VLesser v -> "< "^(string_of_version v) |
||
783 | | VGreaterEqual v -> ">= "^(string_of_version v) |
||
784 | | VLesserEqual v -> "<= "^(string_of_version v) |
||
785 | 04e26a3f | xthirioux | | VOr (c1, c2) -> |
786 | 22fe1c93 | ploc | (string_of_comparator c1)^" || "^(string_of_comparator c2) |
787 | 04e26a3f | xthirioux | | VAnd (c1, c2) -> |
788 | 22fe1c93 | ploc | (string_of_comparator c1)^" && "^(string_of_comparator c2) |
789 | 04e26a3f | xthirioux | |
790 | 22fe1c93 | ploc | let rec varname_of_comparator = |
791 | 04e26a3f | xthirioux | let concat p v = |
792 | 22fe1c93 | ploc | OASISUtils.varname_concat |
793 | 04e26a3f | xthirioux | p |
794 | (OASISUtils.varname_of_string |
||
795 | 22fe1c93 | ploc | (string_of_version v)) |
796 | in |
||
797 | 04e26a3f | xthirioux | function |
798 | 22fe1c93 | ploc | | VGreater v -> concat "gt" v |
799 | | VLesser v -> concat "lt" v |
||
800 | | VEqual v -> concat "eq" v |
||
801 | | VGreaterEqual v -> concat "ge" v |
||
802 | | VLesserEqual v -> concat "le" v |
||
803 | | VOr (c1, c2) -> |
||
804 | (varname_of_comparator c1)^"_or_"^(varname_of_comparator c2) |
||
805 | | VAnd (c1, c2) -> |
||
806 | (varname_of_comparator c1)^"_and_"^(varname_of_comparator c2) |
||
807 | 04e26a3f | xthirioux | |
808 | d1baac41 | xthirioux | let version_0_3_or_after t = |
809 | comparator_apply t (VGreaterEqual (string_of_version "0.3")) |
||
810 | 04e26a3f | xthirioux | |
811 | 22fe1c93 | ploc | end |
812 | |||
813 | module OASISLicense = struct |
||
814 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISLicense.ml" *) |
815 | 04e26a3f | xthirioux | |
816 | 22fe1c93 | ploc | (** License for _oasis fields |
817 | @author Sylvain Le Gall |
||
818 | *) |
||
819 | 04e26a3f | xthirioux | |
820 | |||
821 | |||
822 | d1baac41 | xthirioux | type license = string |
823 | 04e26a3f | xthirioux | |
824 | d1baac41 | xthirioux | type license_exception = string |
825 | 04e26a3f | xthirioux | |
826 | type license_version = |
||
827 | 22fe1c93 | ploc | | Version of OASISVersion.t |
828 | | VersionOrLater of OASISVersion.t |
||
829 | | NoVersion |
||
830 | d1baac41 | xthirioux | |
831 | 04e26a3f | xthirioux | |
832 | type license_dep_5_unit = |
||
833 | { |
||
834 | license: license; |
||
835 | excption: license_exception option; |
||
836 | version: license_version; |
||
837 | } |
||
838 | d1baac41 | xthirioux | |
839 | 04e26a3f | xthirioux | |
840 | type license_dep_5 = |
||
841 | | DEP5Unit of license_dep_5_unit |
||
842 | | DEP5Or of license_dep_5 list |
||
843 | | DEP5And of license_dep_5 list |
||
844 | d1baac41 | xthirioux | |
845 | 04e26a3f | xthirioux | |
846 | 22fe1c93 | ploc | type t = |
847 | | DEP5License of license_dep_5 |
||
848 | | OtherLicense of string (* URL *) |
||
849 | d1baac41 | xthirioux | |
850 | 04e26a3f | xthirioux | |
851 | 22fe1c93 | ploc | end |
852 | |||
853 | module OASISExpr = struct |
||
854 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISExpr.ml" *) |
855 | 04e26a3f | xthirioux | |
856 | |||
857 | |||
858 | 22fe1c93 | ploc | open OASISGettext |
859 | 04e26a3f | xthirioux | |
860 | d1baac41 | xthirioux | type test = string |
861 | 04e26a3f | xthirioux | |
862 | d1baac41 | xthirioux | type flag = string |
863 | 04e26a3f | xthirioux | |
864 | 22fe1c93 | ploc | type t = |
865 | | EBool of bool |
||
866 | | ENot of t |
||
867 | | EAnd of t * t |
||
868 | | EOr of t * t |
||
869 | | EFlag of flag |
||
870 | | ETest of test * string |
||
871 | d1baac41 | xthirioux | |
872 | 04e26a3f | xthirioux | |
873 | d1baac41 | xthirioux | type 'a choices = (t * 'a) list |
874 | 04e26a3f | xthirioux | |
875 | 22fe1c93 | ploc | let eval var_get t = |
876 | 04e26a3f | xthirioux | let rec eval' = |
877 | 22fe1c93 | ploc | function |
878 | | EBool b -> |
||
879 | b |
||
880 | 04e26a3f | xthirioux | |
881 | | ENot e -> |
||
882 | 22fe1c93 | ploc | not (eval' e) |
883 | 04e26a3f | xthirioux | |
884 | 22fe1c93 | ploc | | EAnd (e1, e2) -> |
885 | (eval' e1) && (eval' e2) |
||
886 | 04e26a3f | xthirioux | |
887 | | EOr (e1, e2) -> |
||
888 | 22fe1c93 | ploc | (eval' e1) || (eval' e2) |
889 | 04e26a3f | xthirioux | |
890 | 22fe1c93 | ploc | | EFlag nm -> |
891 | let v = |
||
892 | var_get nm |
||
893 | in |
||
894 | assert(v = "true" || v = "false"); |
||
895 | (v = "true") |
||
896 | 04e26a3f | xthirioux | |
897 | 22fe1c93 | ploc | | ETest (nm, vl) -> |
898 | let v = |
||
899 | var_get nm |
||
900 | in |
||
901 | (v = vl) |
||
902 | in |
||
903 | eval' t |
||
904 | 04e26a3f | xthirioux | |
905 | 22fe1c93 | ploc | let choose ?printer ?name var_get lst = |
906 | 04e26a3f | xthirioux | let rec choose_aux = |
907 | 22fe1c93 | ploc | function |
908 | | (cond, vl) :: tl -> |
||
909 | 04e26a3f | xthirioux | if eval var_get cond then |
910 | vl |
||
911 | 22fe1c93 | ploc | else |
912 | choose_aux tl |
||
913 | | [] -> |
||
914 | 04e26a3f | xthirioux | let str_lst = |
915 | 22fe1c93 | ploc | if lst = [] then |
916 | s_ "<empty>" |
||
917 | else |
||
918 | 04e26a3f | xthirioux | String.concat |
919 | 22fe1c93 | ploc | (s_ ", ") |
920 | (List.map |
||
921 | (fun (cond, vl) -> |
||
922 | match printer with |
||
923 | | Some p -> p vl |
||
924 | | None -> s_ "<no printer>") |
||
925 | lst) |
||
926 | in |
||
927 | 04e26a3f | xthirioux | match name with |
928 | 22fe1c93 | ploc | | Some nm -> |
929 | failwith |
||
930 | 04e26a3f | xthirioux | (Printf.sprintf |
931 | 22fe1c93 | ploc | (f_ "No result for the choice list '%s': %s") |
932 | nm str_lst) |
||
933 | | None -> |
||
934 | failwith |
||
935 | (Printf.sprintf |
||
936 | (f_ "No result for a choice list: %s") |
||
937 | str_lst) |
||
938 | in |
||
939 | choose_aux (List.rev lst) |
||
940 | 04e26a3f | xthirioux | |
941 | 22fe1c93 | ploc | end |
942 | |||
943 | module OASISTypes = struct |
||
944 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISTypes.ml" *) |
945 | 9603460e | xthirioux | |
946 | 719f9992 | xthirioux | |
947 | |||
948 | 04e26a3f | xthirioux | |
949 | d1baac41 | xthirioux | type name = string |
950 | type package_name = string |
||
951 | type url = string |
||
952 | type unix_dirname = string |
||
953 | type unix_filename = string |
||
954 | type host_dirname = string |
||
955 | type host_filename = string |
||
956 | type prog = string |
||
957 | type arg = string |
||
958 | type args = string list |
||
959 | type command_line = (prog * arg list) |
||
960 | 04e26a3f | xthirioux | |
961 | d1baac41 | xthirioux | type findlib_name = string |
962 | type findlib_full = string |
||
963 | 04e26a3f | xthirioux | |
964 | 22fe1c93 | ploc | type compiled_object = |
965 | | Byte |
||
966 | | Native |
||
967 | | Best |
||
968 | d1baac41 | xthirioux | |
969 | 04e26a3f | xthirioux | |
970 | type dependency = |
||
971 | 22fe1c93 | ploc | | FindlibPackage of findlib_full * OASISVersion.comparator option |
972 | | InternalLibrary of name |
||
973 | d1baac41 | xthirioux | |
974 | 04e26a3f | xthirioux | |
975 | 22fe1c93 | ploc | type tool = |
976 | | ExternalTool of name |
||
977 | 04e26a3f | xthirioux | | InternalExecutable of name |
978 | d1baac41 | xthirioux | |
979 | 04e26a3f | xthirioux | |
980 | type vcs = |
||
981 | | Darcs |
||
982 | | Git |
||
983 | | Svn |
||
984 | | Cvs |
||
985 | | Hg |
||
986 | | Bzr |
||
987 | | Arch |
||
988 | 22fe1c93 | ploc | | Monotone |
989 | | OtherVCS of url |
||
990 | d1baac41 | xthirioux | |
991 | 04e26a3f | xthirioux | |
992 | type plugin_kind = |
||
993 | [ `Configure |
||
994 | | `Build |
||
995 | | `Doc |
||
996 | | `Test |
||
997 | | `Install |
||
998 | 22fe1c93 | ploc | | `Extra |
999 | ] |
||
1000 | 04e26a3f | xthirioux | |
1001 | 22fe1c93 | ploc | type plugin_data_purpose = |
1002 | [ `Configure |
||
1003 | | `Build |
||
1004 | | `Install |
||
1005 | | `Clean |
||
1006 | | `Distclean |
||
1007 | | `Install |
||
1008 | | `Uninstall |
||
1009 | | `Test |
||
1010 | | `Doc |
||
1011 | | `Extra |
||
1012 | | `Other of string |
||
1013 | ] |
||
1014 | 04e26a3f | xthirioux | |
1015 | d1baac41 | xthirioux | type 'a plugin = 'a * name * OASISVersion.t option |
1016 | 04e26a3f | xthirioux | |
1017 | type all_plugin = plugin_kind plugin |
||
1018 | |||
1019 | 22fe1c93 | ploc | type plugin_data = (all_plugin * plugin_data_purpose * (unit -> unit)) list |
1020 | 04e26a3f | xthirioux | |
1021 | d1baac41 | xthirioux | (* # 102 "src/oasis/OASISTypes.ml" *) |
1022 | 04e26a3f | xthirioux | |
1023 | d1baac41 | xthirioux | type 'a conditional = 'a OASISExpr.choices |
1024 | 04e26a3f | xthirioux | |
1025 | type custom = |
||
1026 | 22fe1c93 | ploc | { |
1027 | pre_command: (command_line option) conditional; |
||
1028 | 04e26a3f | xthirioux | post_command: (command_line option) conditional; |
1029 | 22fe1c93 | ploc | } |
1030 | d1baac41 | xthirioux | |
1031 | 04e26a3f | xthirioux | |
1032 | 22fe1c93 | ploc | type common_section = |
1033 | { |
||
1034 | cs_name: name; |
||
1035 | cs_data: PropList.Data.t; |
||
1036 | cs_plugin_data: plugin_data; |
||
1037 | } |
||
1038 | d1baac41 | xthirioux | |
1039 | 04e26a3f | xthirioux | |
1040 | 22fe1c93 | ploc | type build_section = |
1041 | { |
||
1042 | bs_build: bool conditional; |
||
1043 | bs_install: bool conditional; |
||
1044 | bs_path: unix_dirname; |
||
1045 | bs_compiled_object: compiled_object; |
||
1046 | bs_build_depends: dependency list; |
||
1047 | bs_build_tools: tool list; |
||
1048 | bs_c_sources: unix_filename list; |
||
1049 | bs_data_files: (unix_filename * unix_filename option) list; |
||
1050 | bs_ccopt: args conditional; |
||
1051 | bs_cclib: args conditional; |
||
1052 | bs_dlllib: args conditional; |
||
1053 | bs_dllpath: args conditional; |
||
1054 | bs_byteopt: args conditional; |
||
1055 | bs_nativeopt: args conditional; |
||
1056 | } |
||
1057 | d1baac41 | xthirioux | |
1058 | 04e26a3f | xthirioux | |
1059 | type library = |
||
1060 | 22fe1c93 | ploc | { |
1061 | lib_modules: string list; |
||
1062 | 04e26a3f | xthirioux | lib_pack: bool; |
1063 | 22fe1c93 | ploc | lib_internal_modules: string list; |
1064 | lib_findlib_parent: findlib_name option; |
||
1065 | lib_findlib_name: findlib_name option; |
||
1066 | lib_findlib_containers: findlib_name list; |
||
1067 | d1baac41 | xthirioux | } |
1068 | 04e26a3f | xthirioux | |
1069 | type executable = |
||
1070 | 22fe1c93 | ploc | { |
1071 | exec_custom: bool; |
||
1072 | exec_main_is: unix_filename; |
||
1073 | d1baac41 | xthirioux | } |
1074 | 04e26a3f | xthirioux | |
1075 | type flag = |
||
1076 | 22fe1c93 | ploc | { |
1077 | flag_description: string option; |
||
1078 | flag_default: bool conditional; |
||
1079 | d1baac41 | xthirioux | } |
1080 | 04e26a3f | xthirioux | |
1081 | type source_repository = |
||
1082 | 22fe1c93 | ploc | { |
1083 | src_repo_type: vcs; |
||
1084 | src_repo_location: url; |
||
1085 | src_repo_browser: url option; |
||
1086 | src_repo_module: string option; |
||
1087 | src_repo_branch: string option; |
||
1088 | src_repo_tag: string option; |
||
1089 | src_repo_subdir: unix_filename option; |
||
1090 | d1baac41 | xthirioux | } |
1091 | 04e26a3f | xthirioux | |
1092 | type test = |
||
1093 | 22fe1c93 | ploc | { |
1094 | test_type: [`Test] plugin; |
||
1095 | test_command: command_line conditional; |
||
1096 | test_custom: custom; |
||
1097 | test_working_directory: unix_filename option; |
||
1098 | test_run: bool conditional; |
||
1099 | test_tools: tool list; |
||
1100 | d1baac41 | xthirioux | } |
1101 | 04e26a3f | xthirioux | |
1102 | 22fe1c93 | ploc | type doc_format = |
1103 | | HTML of unix_filename |
||
1104 | | DocText |
||
1105 | |||
1106 | | PostScript |
||
1107 | | Info of unix_filename |
||
1108 | | DVI |
||
1109 | | OtherDoc |
||
1110 | d1baac41 | xthirioux | |
1111 | 04e26a3f | xthirioux | |
1112 | 22fe1c93 | ploc | type doc = |
1113 | d1baac41 | xthirioux | { |
1114 | doc_type: [`Doc] plugin; |
||
1115 | doc_custom: custom; |
||
1116 | doc_build: bool conditional; |
||
1117 | doc_install: bool conditional; |
||
1118 | doc_install_dir: unix_filename; |
||
1119 | doc_title: string; |
||
1120 | doc_authors: string list; |
||
1121 | doc_abstract: string option; |
||
1122 | doc_format: doc_format; |
||
1123 | doc_data_files: (unix_filename * unix_filename option) list; |
||
1124 | doc_build_tools: tool list; |
||
1125 | } |
||
1126 | 719f9992 | xthirioux | |
1127 | d1baac41 | xthirioux | type section = |
1128 | | Library of common_section * build_section * library |
||
1129 | | Executable of common_section * build_section * executable |
||
1130 | | Flag of common_section * flag |
||
1131 | | SrcRepo of common_section * source_repository |
||
1132 | | Test of common_section * test |
||
1133 | | Doc of common_section * doc |
||
1134 | |||
1135 | 9603460e | xthirioux | |
1136 | d1baac41 | xthirioux | type section_kind = |
1137 | [ `Library | `Executable | `Flag | `SrcRepo | `Test | `Doc ] |
||
1138 | 9603460e | xthirioux | |
1139 | d1baac41 | xthirioux | type package = |
1140 | { |
||
1141 | oasis_version: OASISVersion.t; |
||
1142 | ocaml_version: OASISVersion.comparator option; |
||
1143 | findlib_version: OASISVersion.comparator option; |
||
1144 | name: package_name; |
||
1145 | version: OASISVersion.t; |
||
1146 | license: OASISLicense.t; |
||
1147 | license_file: unix_filename option; |
||
1148 | copyrights: string list; |
||
1149 | maintainers: string list; |
||
1150 | authors: string list; |
||
1151 | homepage: url option; |
||
1152 | synopsis: string; |
||
1153 | description: string option; |
||
1154 | categories: url list; |
||
1155 | |||
1156 | conf_type: [`Configure] plugin; |
||
1157 | conf_custom: custom; |
||
1158 | |||
1159 | build_type: [`Build] plugin; |
||
1160 | build_custom: custom; |
||
1161 | |||
1162 | install_type: [`Install] plugin; |
||
1163 | install_custom: custom; |
||
1164 | uninstall_custom: custom; |
||
1165 | |||
1166 | clean_custom: custom; |
||
1167 | distclean_custom: custom; |
||
1168 | |||
1169 | files_ab: unix_filename list; |
||
1170 | sections: section list; |
||
1171 | plugins: [`Extra] plugin list; |
||
1172 | schema_data: PropList.Data.t; |
||
1173 | plugin_data: plugin_data; |
||
1174 | } |
||
1175 | 9603460e | xthirioux | |
1176 | 22fe1c93 | ploc | end |
1177 | |||
1178 | module OASISUnixPath = struct |
||
1179 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISUnixPath.ml" *) |
1180 | 04e26a3f | xthirioux | |
1181 | 22fe1c93 | ploc | type unix_filename = string |
1182 | type unix_dirname = string |
||
1183 | 04e26a3f | xthirioux | |
1184 | 22fe1c93 | ploc | type host_filename = string |
1185 | type host_dirname = string |
||
1186 | 04e26a3f | xthirioux | |
1187 | 22fe1c93 | ploc | let current_dir_name = "." |
1188 | 04e26a3f | xthirioux | |
1189 | 22fe1c93 | ploc | let parent_dir_name = ".." |
1190 | 04e26a3f | xthirioux | |
1191 | let is_current_dir fn = |
||
1192 | fn = current_dir_name || fn = "" |
||
1193 | |||
1194 | let concat f1 f2 = |
||
1195 | if is_current_dir f1 then |
||
1196 | 22fe1c93 | ploc | f2 |
1197 | else |
||
1198 | 04e26a3f | xthirioux | let f1' = |
1199 | try OASISString.strip_ends_with ~what:"/" f1 with Not_found -> f1 |
||
1200 | in |
||
1201 | f1'^"/"^f2 |
||
1202 | |||
1203 | 22fe1c93 | ploc | let make = |
1204 | function |
||
1205 | | hd :: tl -> |
||
1206 | List.fold_left |
||
1207 | (fun f p -> concat f p) |
||
1208 | hd |
||
1209 | tl |
||
1210 | | [] -> |
||
1211 | invalid_arg "OASISUnixPath.make" |
||
1212 | 04e26a3f | xthirioux | |
1213 | 22fe1c93 | ploc | let dirname f = |
1214 | try |
||
1215 | String.sub f 0 (String.rindex f '/') |
||
1216 | with Not_found -> |
||
1217 | current_dir_name |
||
1218 | 04e26a3f | xthirioux | |
1219 | 22fe1c93 | ploc | let basename f = |
1220 | 04e26a3f | xthirioux | try |
1221 | 22fe1c93 | ploc | let pos_start = |
1222 | (String.rindex f '/') + 1 |
||
1223 | in |
||
1224 | String.sub f pos_start ((String.length f) - pos_start) |
||
1225 | with Not_found -> |
||
1226 | f |
||
1227 | 04e26a3f | xthirioux | |
1228 | 22fe1c93 | ploc | let chop_extension f = |
1229 | 04e26a3f | xthirioux | try |
1230 | 22fe1c93 | ploc | let last_dot = |
1231 | String.rindex f '.' |
||
1232 | in |
||
1233 | let sub = |
||
1234 | String.sub f 0 last_dot |
||
1235 | in |
||
1236 | 04e26a3f | xthirioux | try |
1237 | 22fe1c93 | ploc | let last_slash = |
1238 | String.rindex f '/' |
||
1239 | in |
||
1240 | if last_slash < last_dot then |
||
1241 | sub |
||
1242 | else |
||
1243 | f |
||
1244 | with Not_found -> |
||
1245 | sub |
||
1246 | 04e26a3f | xthirioux | |
1247 | 22fe1c93 | ploc | with Not_found -> |
1248 | f |
||
1249 | 04e26a3f | xthirioux | |
1250 | let capitalize_file f = |
||
1251 | let dir = dirname f in |
||
1252 | let base = basename f in |
||
1253 | concat dir (String.capitalize base) |
||
1254 | |||
1255 | let uncapitalize_file f = |
||
1256 | let dir = dirname f in |
||
1257 | let base = basename f in |
||
1258 | concat dir (String.uncapitalize base) |
||
1259 | |||
1260 | end |
||
1261 | |||
1262 | module OASISHostPath = struct |
||
1263 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISHostPath.ml" *) |
1264 | 04e26a3f | xthirioux | |
1265 | |||
1266 | open Filename |
||
1267 | |||
1268 | module Unix = OASISUnixPath |
||
1269 | |||
1270 | let make = |
||
1271 | function |
||
1272 | | [] -> |
||
1273 | invalid_arg "OASISHostPath.make" |
||
1274 | | hd :: tl -> |
||
1275 | List.fold_left Filename.concat hd tl |
||
1276 | |||
1277 | let of_unix ufn = |
||
1278 | if Sys.os_type = "Unix" then |
||
1279 | ufn |
||
1280 | else |
||
1281 | make |
||
1282 | (List.map |
||
1283 | (fun p -> |
||
1284 | if p = Unix.current_dir_name then |
||
1285 | current_dir_name |
||
1286 | else if p = Unix.parent_dir_name then |
||
1287 | parent_dir_name |
||
1288 | else |
||
1289 | p) |
||
1290 | (OASISString.nsplit ufn '/')) |
||
1291 | |||
1292 | |||
1293 | 22fe1c93 | ploc | end |
1294 | |||
1295 | module OASISSection = struct |
||
1296 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISSection.ml" *) |
1297 | 04e26a3f | xthirioux | |
1298 | 22fe1c93 | ploc | open OASISTypes |
1299 | 04e26a3f | xthirioux | |
1300 | d1baac41 | xthirioux | let section_kind_common = |
1301 | 22fe1c93 | ploc | function |
1302 | d1baac41 | xthirioux | | Library (cs, _, _) -> |
1303 | 04e26a3f | xthirioux | `Library, cs |
1304 | 22fe1c93 | ploc | | Executable (cs, _, _) -> |
1305 | 04e26a3f | xthirioux | `Executable, cs |
1306 | 22fe1c93 | ploc | | Flag (cs, _) -> |
1307 | 04e26a3f | xthirioux | `Flag, cs |
1308 | 22fe1c93 | ploc | | SrcRepo (cs, _) -> |
1309 | 04e26a3f | xthirioux | `SrcRepo, cs |
1310 | 22fe1c93 | ploc | | Test (cs, _) -> |
1311 | 04e26a3f | xthirioux | `Test, cs |
1312 | 22fe1c93 | ploc | | Doc (cs, _) -> |
1313 | 04e26a3f | xthirioux | `Doc, cs |
1314 | |||
1315 | 22fe1c93 | ploc | let section_common sct = |
1316 | snd (section_kind_common sct) |
||
1317 | 04e26a3f | xthirioux | |
1318 | let section_common_set cs = |
||
1319 | function |
||
1320 | | Library (_, bs, lib) -> Library (cs, bs, lib) |
||
1321 | | Executable (_, bs, exec) -> Executable (cs, bs, exec) |
||
1322 | | Flag (_, flg) -> Flag (cs, flg) |
||
1323 | | SrcRepo (_, src_repo) -> SrcRepo (cs, src_repo) |
||
1324 | | Test (_, tst) -> Test (cs, tst) |
||
1325 | | Doc (_, doc) -> Doc (cs, doc) |
||
1326 | |||
1327 | 22fe1c93 | ploc | (** Key used to identify section |
1328 | *) |
||
1329 | d1baac41 | xthirioux | let section_id sct = |
1330 | let k, cs = |
||
1331 | 22fe1c93 | ploc | section_kind_common sct |
1332 | in |
||
1333 | k, cs.cs_name |
||
1334 | 04e26a3f | xthirioux | |
1335 | 22fe1c93 | ploc | let string_of_section sct = |
1336 | let k, nm = |
||
1337 | section_id sct |
||
1338 | in |
||
1339 | (match k with |
||
1340 | d1baac41 | xthirioux | | `Library -> "library" |
1341 | 04e26a3f | xthirioux | | `Executable -> "executable" |
1342 | | `Flag -> "flag" |
||
1343 | | `SrcRepo -> "src repository" |
||
1344 | | `Test -> "test" |
||
1345 | | `Doc -> "doc") |
||
1346 | 22fe1c93 | ploc | ^" "^nm |
1347 | 04e26a3f | xthirioux | |
1348 | let section_find id scts = |
||
1349 | List.find |
||
1350 | (fun sct -> id = section_id sct) |
||
1351 | scts |
||
1352 | |||
1353 | module CSection = |
||
1354 | struct |
||
1355 | type t = section |
||
1356 | |||
1357 | let id = section_id |
||
1358 | |||
1359 | d1baac41 | xthirioux | let compare t1 t2 = |
1360 | 04e26a3f | xthirioux | compare (id t1) (id t2) |
1361 | d1baac41 | xthirioux | |
1362 | 04e26a3f | xthirioux | let equal t1 t2 = |
1363 | (id t1) = (id t2) |
||
1364 | |||
1365 | let hash t = |
||
1366 | Hashtbl.hash (id t) |
||
1367 | end |
||
1368 | |||
1369 | module MapSection = Map.Make(CSection) |
||
1370 | module SetSection = Set.Make(CSection) |
||
1371 | |||
1372 | 22fe1c93 | ploc | end |
1373 | |||
1374 | module OASISBuildSection = struct |
||
1375 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISBuildSection.ml" *) |
1376 | 04e26a3f | xthirioux | |
1377 | 22fe1c93 | ploc | end |
1378 | |||
1379 | module OASISExecutable = struct |
||
1380 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISExecutable.ml" *) |
1381 | 04e26a3f | xthirioux | |
1382 | 22fe1c93 | ploc | open OASISTypes |
1383 | 04e26a3f | xthirioux | |
1384 | d1baac41 | xthirioux | let unix_exec_is (cs, bs, exec) is_native ext_dll suffix_program = |
1385 | let dir = |
||
1386 | 22fe1c93 | ploc | OASISUnixPath.concat |
1387 | bs.bs_path |
||
1388 | (OASISUnixPath.dirname exec.exec_main_is) |
||
1389 | in |
||
1390 | d1baac41 | xthirioux | let is_native_exec = |
1391 | 22fe1c93 | ploc | match bs.bs_compiled_object with |
1392 | | Native -> true |
||
1393 | | Best -> is_native () |
||
1394 | | Byte -> false |
||
1395 | in |
||
1396 | 04e26a3f | xthirioux | |
1397 | 22fe1c93 | ploc | OASISUnixPath.concat |
1398 | dir |
||
1399 | (cs.cs_name^(suffix_program ())), |
||
1400 | 04e26a3f | xthirioux | |
1401 | d1baac41 | xthirioux | if not is_native_exec && |
1402 | not exec.exec_custom && |
||
1403 | 22fe1c93 | ploc | bs.bs_c_sources <> [] then |
1404 | 04e26a3f | xthirioux | Some (dir^"/dll"^cs.cs_name^"_stubs"^(ext_dll ())) |
1405 | 22fe1c93 | ploc | else |
1406 | None |
||
1407 | 04e26a3f | xthirioux | |
1408 | 22fe1c93 | ploc | end |
1409 | |||
1410 | module OASISLibrary = struct |
||
1411 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISLibrary.ml" *) |
1412 | 04e26a3f | xthirioux | |
1413 | 22fe1c93 | ploc | open OASISTypes |
1414 | open OASISUtils |
||
1415 | open OASISGettext |
||
1416 | 04e26a3f | xthirioux | open OASISSection |
1417 | |||
1418 | d1baac41 | xthirioux | type library_name = name |
1419 | type findlib_part_name = name |
||
1420 | type 'a map_of_findlib_part_name = 'a OASISUtils.MapString.t |
||
1421 | |||
1422 | exception InternalLibraryNotFound of library_name |
||
1423 | exception FindlibPackageNotFound of findlib_name |
||
1424 | |||
1425 | type group_t = |
||
1426 | | Container of findlib_name * group_t list |
||
1427 | | Package of (findlib_name * |
||
1428 | common_section * |
||
1429 | build_section * |
||
1430 | library * |
||
1431 | group_t list) |
||
1432 | 04e26a3f | xthirioux | |
1433 | (* Look for a module file, considering capitalization or not. *) |
||
1434 | d1baac41 | xthirioux | let find_module source_file_exists (cs, bs, lib) modul = |
1435 | 04e26a3f | xthirioux | let possible_base_fn = |
1436 | List.map |
||
1437 | (OASISUnixPath.concat bs.bs_path) |
||
1438 | [modul; |
||
1439 | OASISUnixPath.uncapitalize_file modul; |
||
1440 | OASISUnixPath.capitalize_file modul] |
||
1441 | in |
||
1442 | (* TODO: we should be able to be able to determine the source for every |
||
1443 | * files. Hence we should introduce a Module(source: fn) for the fields |
||
1444 | * Modules and InternalModules |
||
1445 | *) |
||
1446 | 22fe1c93 | ploc | List.fold_left |
1447 | 04e26a3f | xthirioux | (fun acc base_fn -> |
1448 | match acc with |
||
1449 | | `No_sources _ -> |
||
1450 | begin |
||
1451 | let file_found = |
||
1452 | List.fold_left |
||
1453 | (fun acc ext -> |
||
1454 | if source_file_exists (base_fn^ext) then |
||
1455 | (base_fn^ext) :: acc |
||
1456 | else |
||
1457 | acc) |
||
1458 | [] |
||
1459 | [".ml"; ".mli"; ".mll"; ".mly"] |
||
1460 | in |
||
1461 | match file_found with |
||
1462 | | [] -> |
||
1463 | acc |
||
1464 | | lst -> |
||
1465 | `Sources (base_fn, lst) |
||
1466 | end |
||
1467 | | `Sources _ -> |
||
1468 | acc) |
||
1469 | (`No_sources possible_base_fn) |
||
1470 | possible_base_fn |
||
1471 | |||
1472 | let source_unix_files ~ctxt (cs, bs, lib) source_file_exists = |
||
1473 | List.fold_left |
||
1474 | (fun acc modul -> |
||
1475 | d1baac41 | xthirioux | match find_module source_file_exists (cs, bs, lib) modul with |
1476 | 04e26a3f | xthirioux | | `Sources (base_fn, lst) -> |
1477 | (base_fn, lst) :: acc |
||
1478 | | `No_sources _ -> |
||
1479 | OASISMessage.warning |
||
1480 | ~ctxt |
||
1481 | (f_ "Cannot find source file matching \ |
||
1482 | module '%s' in library %s") |
||
1483 | modul cs.cs_name; |
||
1484 | acc) |
||
1485 | [] |
||
1486 | (lib.lib_modules @ lib.lib_internal_modules) |
||
1487 | |||
1488 | let generated_unix_files |
||
1489 | ~ctxt |
||
1490 | ~is_native |
||
1491 | ~has_native_dynlink |
||
1492 | ~ext_lib |
||
1493 | ~ext_dll |
||
1494 | ~source_file_exists |
||
1495 | (cs, bs, lib) = |
||
1496 | |||
1497 | d1baac41 | xthirioux | let find_modules lst ext = |
1498 | 04e26a3f | xthirioux | let find_module modul = |
1499 | d1baac41 | xthirioux | match find_module source_file_exists (cs, bs, lib) modul with |
1500 | 04e26a3f | xthirioux | | `Sources (base_fn, _) -> |
1501 | d1baac41 | xthirioux | [base_fn] |
1502 | 04e26a3f | xthirioux | | `No_sources lst -> |
1503 | OASISMessage.warning |
||
1504 | ~ctxt |
||
1505 | (f_ "Cannot find source file matching \ |
||
1506 | module '%s' in library %s") |
||
1507 | modul cs.cs_name; |
||
1508 | d1baac41 | xthirioux | lst |
1509 | 04e26a3f | xthirioux | in |
1510 | d1baac41 | xthirioux | List.map |
1511 | (fun nm -> |
||
1512 | List.map |
||
1513 | (fun base_fn -> base_fn ^"."^ext) |
||
1514 | (find_module nm)) |
||
1515 | 04e26a3f | xthirioux | lst |
1516 | in |
||
1517 | |||
1518 | (* The headers that should be compiled along *) |
||
1519 | let headers = |
||
1520 | if lib.lib_pack then |
||
1521 | 22fe1c93 | ploc | [] |
1522 | 04e26a3f | xthirioux | else |
1523 | find_modules |
||
1524 | lib.lib_modules |
||
1525 | "cmi" |
||
1526 | in |
||
1527 | |||
1528 | (* The .cmx that be compiled along *) |
||
1529 | let cmxs = |
||
1530 | let should_be_built = |
||
1531 | d1baac41 | xthirioux | (not lib.lib_pack) && (* Do not install .cmx packed submodules *) |
1532 | 04e26a3f | xthirioux | match bs.bs_compiled_object with |
1533 | | Native -> true |
||
1534 | | Best -> is_native |
||
1535 | | Byte -> false |
||
1536 | in |
||
1537 | if should_be_built then |
||
1538 | d1baac41 | xthirioux | find_modules |
1539 | (lib.lib_modules @ lib.lib_internal_modules) |
||
1540 | "cmx" |
||
1541 | 04e26a3f | xthirioux | else |
1542 | [] |
||
1543 | 22fe1c93 | ploc | in |
1544 | 04e26a3f | xthirioux | |
1545 | 22fe1c93 | ploc | let acc_nopath = |
1546 | [] |
||
1547 | in |
||
1548 | 04e26a3f | xthirioux | |
1549 | 22fe1c93 | ploc | (* Compute what libraries should be built *) |
1550 | let acc_nopath = |
||
1551 | 04e26a3f | xthirioux | (* Add the packed header file if required *) |
1552 | let add_pack_header acc = |
||
1553 | if lib.lib_pack then |
||
1554 | [cs.cs_name^".cmi"] :: acc |
||
1555 | else |
||
1556 | acc |
||
1557 | in |
||
1558 | 22fe1c93 | ploc | let byte acc = |
1559 | 04e26a3f | xthirioux | add_pack_header ([cs.cs_name^".cma"] :: acc) |
1560 | 22fe1c93 | ploc | in |
1561 | let native acc = |
||
1562 | d1baac41 | xthirioux | let acc = |
1563 | 04e26a3f | xthirioux | add_pack_header |
1564 | (if has_native_dynlink then |
||
1565 | [cs.cs_name^".cmxs"] :: acc |
||
1566 | else acc) |
||
1567 | in |
||
1568 | [cs.cs_name^".cmxa"] :: [cs.cs_name^ext_lib] :: acc |
||
1569 | 22fe1c93 | ploc | in |
1570 | 04e26a3f | xthirioux | match bs.bs_compiled_object with |
1571 | 22fe1c93 | ploc | | Native -> |
1572 | byte (native acc_nopath) |
||
1573 | 04e26a3f | xthirioux | | Best when is_native -> |
1574 | 22fe1c93 | ploc | byte (native acc_nopath) |
1575 | | Byte | Best -> |
||
1576 | byte acc_nopath |
||
1577 | in |
||
1578 | 04e26a3f | xthirioux | |
1579 | 22fe1c93 | ploc | (* Add C library to be built *) |
1580 | 04e26a3f | xthirioux | let acc_nopath = |
1581 | 22fe1c93 | ploc | if bs.bs_c_sources <> [] then |
1582 | begin |
||
1583 | 04e26a3f | xthirioux | ["lib"^cs.cs_name^"_stubs"^ext_lib] |
1584 | 22fe1c93 | ploc | :: |
1585 | 04e26a3f | xthirioux | ["dll"^cs.cs_name^"_stubs"^ext_dll] |
1586 | 22fe1c93 | ploc | :: |
1587 | acc_nopath |
||
1588 | end |
||
1589 | else |
||
1590 | acc_nopath |
||
1591 | in |
||
1592 | 04e26a3f | xthirioux | |
1593 | 22fe1c93 | ploc | (* All the files generated *) |
1594 | List.rev_append |
||
1595 | (List.rev_map |
||
1596 | (List.rev_map |
||
1597 | (OASISUnixPath.concat bs.bs_path)) |
||
1598 | acc_nopath) |
||
1599 | 04e26a3f | xthirioux | (headers @ cmxs) |
1600 | |||
1601 | d1baac41 | xthirioux | type data = common_section * build_section * library |
1602 | 04e26a3f | xthirioux | type tree = |
1603 | | Node of (data option) * (tree MapString.t) |
||
1604 | | Leaf of data |
||
1605 | |||
1606 | let findlib_mapping pkg = |
||
1607 | (* Map from library name to either full findlib name or parts + parent. *) |
||
1608 | let fndlb_parts_of_lib_name = |
||
1609 | let fndlb_parts cs lib = |
||
1610 | let name = |
||
1611 | match lib.lib_findlib_name with |
||
1612 | | Some nm -> nm |
||
1613 | | None -> cs.cs_name |
||
1614 | in |
||
1615 | let name = |
||
1616 | String.concat "." (lib.lib_findlib_containers @ [name]) |
||
1617 | in |
||
1618 | name |
||
1619 | in |
||
1620 | List.fold_left |
||
1621 | (fun mp -> |
||
1622 | function |
||
1623 | | Library (cs, _, lib) -> |
||
1624 | begin |
||
1625 | let lib_name = cs.cs_name in |
||
1626 | let fndlb_parts = fndlb_parts cs lib in |
||
1627 | if MapString.mem lib_name mp then |
||
1628 | failwithf |
||
1629 | (f_ "The library name '%s' is used more than once.") |
||
1630 | lib_name; |
||
1631 | match lib.lib_findlib_parent with |
||
1632 | | Some lib_name_parent -> |
||
1633 | MapString.add |
||
1634 | lib_name |
||
1635 | (`Unsolved (lib_name_parent, fndlb_parts)) |
||
1636 | mp |
||
1637 | | None -> |
||
1638 | MapString.add |
||
1639 | lib_name |
||
1640 | (`Solved fndlb_parts) |
||
1641 | mp |
||
1642 | end |
||
1643 | |||
1644 | | Executable _ | Test _ | Flag _ | SrcRepo _ | Doc _ -> |
||
1645 | mp) |
||
1646 | MapString.empty |
||
1647 | pkg.sections |
||
1648 | in |
||
1649 | |||
1650 | (* Solve the above graph to be only library name to full findlib name. *) |
||
1651 | let fndlb_name_of_lib_name = |
||
1652 | let rec solve visited mp lib_name lib_name_child = |
||
1653 | if SetString.mem lib_name visited then |
||
1654 | failwithf |
||
1655 | (f_ "Library '%s' is involved in a cycle \ |
||
1656 | with regard to findlib naming.") |
||
1657 | lib_name; |
||
1658 | let visited = SetString.add lib_name visited in |
||
1659 | try |
||
1660 | match MapString.find lib_name mp with |
||
1661 | | `Solved fndlb_nm -> |
||
1662 | fndlb_nm, mp |
||
1663 | | `Unsolved (lib_nm_parent, post_fndlb_nm) -> |
||
1664 | let pre_fndlb_nm, mp = |
||
1665 | solve visited mp lib_nm_parent lib_name |
||
1666 | in |
||
1667 | let fndlb_nm = pre_fndlb_nm^"."^post_fndlb_nm in |
||
1668 | fndlb_nm, MapString.add lib_name (`Solved fndlb_nm) mp |
||
1669 | with Not_found -> |
||
1670 | failwithf |
||
1671 | (f_ "Library '%s', which is defined as the findlib parent of \ |
||
1672 | library '%s', doesn't exist.") |
||
1673 | lib_name lib_name_child |
||
1674 | in |
||
1675 | let mp = |
||
1676 | MapString.fold |
||
1677 | (fun lib_name status mp -> |
||
1678 | match status with |
||
1679 | | `Solved _ -> |
||
1680 | (* Solved initialy, no need to go further *) |
||
1681 | mp |
||
1682 | | `Unsolved _ -> |
||
1683 | let _, mp = solve SetString.empty mp lib_name "<none>" in |
||
1684 | mp) |
||
1685 | fndlb_parts_of_lib_name |
||
1686 | fndlb_parts_of_lib_name |
||
1687 | in |
||
1688 | MapString.map |
||
1689 | (function |
||
1690 | | `Solved fndlb_nm -> fndlb_nm |
||
1691 | | `Unsolved _ -> assert false) |
||
1692 | mp |
||
1693 | in |
||
1694 | |||
1695 | (* Convert an internal library name to a findlib name. *) |
||
1696 | let findlib_name_of_library_name lib_nm = |
||
1697 | try |
||
1698 | MapString.find lib_nm fndlb_name_of_lib_name |
||
1699 | with Not_found -> |
||
1700 | raise (InternalLibraryNotFound lib_nm) |
||
1701 | in |
||
1702 | |||
1703 | (* Add a library to the tree. |
||
1704 | *) |
||
1705 | let add sct mp = |
||
1706 | let fndlb_fullname = |
||
1707 | let cs, _, _ = sct in |
||
1708 | let lib_name = cs.cs_name in |
||
1709 | findlib_name_of_library_name lib_name |
||
1710 | in |
||
1711 | d1baac41 | xthirioux | let rec add_children nm_lst (children : tree MapString.t) = |
1712 | 04e26a3f | xthirioux | match nm_lst with |
1713 | | (hd :: tl) -> |
||
1714 | begin |
||
1715 | let node = |
||
1716 | try |
||
1717 | add_node tl (MapString.find hd children) |
||
1718 | with Not_found -> |
||
1719 | (* New node *) |
||
1720 | new_node tl |
||
1721 | in |
||
1722 | MapString.add hd node children |
||
1723 | end |
||
1724 | | [] -> |
||
1725 | (* Should not have a nameless library. *) |
||
1726 | assert false |
||
1727 | and add_node tl node = |
||
1728 | if tl = [] then |
||
1729 | begin |
||
1730 | match node with |
||
1731 | | Node (None, children) -> |
||
1732 | Node (Some sct, children) |
||
1733 | | Leaf (cs', _, _) | Node (Some (cs', _, _), _) -> |
||
1734 | (* TODO: allow to merge Package, i.e. |
||
1735 | * archive(byte) = "foo.cma foo_init.cmo" |
||
1736 | *) |
||
1737 | let cs, _, _ = sct in |
||
1738 | failwithf |
||
1739 | (f_ "Library '%s' and '%s' have the same findlib name '%s'") |
||
1740 | cs.cs_name cs'.cs_name fndlb_fullname |
||
1741 | end |
||
1742 | else |
||
1743 | begin |
||
1744 | match node with |
||
1745 | | Leaf data -> |
||
1746 | Node (Some data, add_children tl MapString.empty) |
||
1747 | | Node (data_opt, children) -> |
||
1748 | Node (data_opt, add_children tl children) |
||
1749 | end |
||
1750 | and new_node = |
||
1751 | function |
||
1752 | | [] -> |
||
1753 | Leaf sct |
||
1754 | | hd :: tl -> |
||
1755 | Node (None, MapString.add hd (new_node tl) MapString.empty) |
||
1756 | in |
||
1757 | add_children (OASISString.nsplit fndlb_fullname '.') mp |
||
1758 | in |
||
1759 | |||
1760 | let rec group_of_tree mp = |
||
1761 | MapString.fold |
||
1762 | (fun nm node acc -> |
||
1763 | let cur = |
||
1764 | match node with |
||
1765 | | Node (Some (cs, bs, lib), children) -> |
||
1766 | Package (nm, cs, bs, lib, group_of_tree children) |
||
1767 | | Node (None, children) -> |
||
1768 | Container (nm, group_of_tree children) |
||
1769 | | Leaf (cs, bs, lib) -> |
||
1770 | Package (nm, cs, bs, lib, []) |
||
1771 | in |
||
1772 | cur :: acc) |
||
1773 | mp [] |
||
1774 | in |
||
1775 | |||
1776 | let group_mp = |
||
1777 | 22fe1c93 | ploc | List.fold_left |
1778 | (fun mp -> |
||
1779 | function |
||
1780 | | Library (cs, bs, lib) -> |
||
1781 | d1baac41 | xthirioux | add (cs, bs, lib) mp |
1782 | 22fe1c93 | ploc | | _ -> |
1783 | mp) |
||
1784 | MapString.empty |
||
1785 | pkg.sections |
||
1786 | in |
||
1787 | 04e26a3f | xthirioux | |
1788 | let groups = |
||
1789 | group_of_tree group_mp |
||
1790 | 22fe1c93 | ploc | in |
1791 | 04e26a3f | xthirioux | |
1792 | let library_name_of_findlib_name = |
||
1793 | Lazy.lazy_from_fun |
||
1794 | (fun () -> |
||
1795 | (* Revert findlib_name_of_library_name. *) |
||
1796 | MapString.fold |
||
1797 | (fun k v mp -> MapString.add v k mp) |
||
1798 | fndlb_name_of_lib_name |
||
1799 | MapString.empty) |
||
1800 | 22fe1c93 | ploc | in |
1801 | 04e26a3f | xthirioux | let library_name_of_findlib_name fndlb_nm = |
1802 | try |
||
1803 | MapString.find fndlb_nm (Lazy.force library_name_of_findlib_name) |
||
1804 | with Not_found -> |
||
1805 | raise (FindlibPackageNotFound fndlb_nm) |
||
1806 | 22fe1c93 | ploc | in |
1807 | 04e26a3f | xthirioux | |
1808 | groups, |
||
1809 | findlib_name_of_library_name, |
||
1810 | library_name_of_findlib_name |
||
1811 | |||
1812 | let findlib_of_group = |
||
1813 | 22fe1c93 | ploc | function |
1814 | 04e26a3f | xthirioux | | Container (fndlb_nm, _) |
1815 | 22fe1c93 | ploc | | Package (fndlb_nm, _, _, _, _) -> fndlb_nm |
1816 | 04e26a3f | xthirioux | |
1817 | 22fe1c93 | ploc | let root_of_group grp = |
1818 | let rec root_lib_aux = |
||
1819 | 04e26a3f | xthirioux | (* We do a DFS in the group. *) |
1820 | 22fe1c93 | ploc | function |
1821 | 04e26a3f | xthirioux | | Container (_, children) -> |
1822 | List.fold_left |
||
1823 | (fun res grp -> |
||
1824 | if res = None then |
||
1825 | root_lib_aux grp |
||
1826 | else |
||
1827 | res) |
||
1828 | None |
||
1829 | children |
||
1830 | | Package (_, cs, bs, lib, _) -> |
||
1831 | Some (cs, bs, lib) |
||
1832 | 22fe1c93 | ploc | in |
1833 | 04e26a3f | xthirioux | match root_lib_aux grp with |
1834 | | Some res -> |
||
1835 | res |
||
1836 | | None -> |
||
1837 | failwithf |
||
1838 | (f_ "Unable to determine root library of findlib library '%s'") |
||
1839 | (findlib_of_group grp) |
||
1840 | |||
1841 | 22fe1c93 | ploc | end |
1842 | |||
1843 | module OASISFlag = struct |
||
1844 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISFlag.ml" *) |
1845 | 04e26a3f | xthirioux | |
1846 | 22fe1c93 | ploc | end |
1847 | |||
1848 | module OASISPackage = struct |
||
1849 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISPackage.ml" *) |
1850 | 04e26a3f | xthirioux | |
1851 | 22fe1c93 | ploc | end |
1852 | |||
1853 | module OASISSourceRepository = struct |
||
1854 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISSourceRepository.ml" *) |
1855 | 04e26a3f | xthirioux | |
1856 | 22fe1c93 | ploc | end |
1857 | |||
1858 | module OASISTest = struct |
||
1859 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISTest.ml" *) |
1860 | 04e26a3f | xthirioux | |
1861 | 22fe1c93 | ploc | end |
1862 | |||
1863 | module OASISDocument = struct |
||
1864 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISDocument.ml" *) |
1865 | 04e26a3f | xthirioux | |
1866 | end |
||
1867 | |||
1868 | module OASISExec = struct |
||
1869 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISExec.ml" *) |
1870 | 04e26a3f | xthirioux | |
1871 | open OASISGettext |
||
1872 | open OASISUtils |
||
1873 | open OASISMessage |
||
1874 | |||
1875 | (* TODO: I don't like this quote, it is there because $(rm) foo expands to |
||
1876 | * 'rm -f' foo... |
||
1877 | *) |
||
1878 | let run ~ctxt ?f_exit_code ?(quote=true) cmd args = |
||
1879 | let cmd = |
||
1880 | if quote then |
||
1881 | if Sys.os_type = "Win32" then |
||
1882 | if String.contains cmd ' ' then |
||
1883 | (* Double the 1st double quote... win32... sigh *) |
||
1884 | "\""^(Filename.quote cmd) |
||
1885 | else |
||
1886 | cmd |
||
1887 | else |
||
1888 | Filename.quote cmd |
||
1889 | else |
||
1890 | cmd |
||
1891 | in |
||
1892 | let cmdline = |
||
1893 | String.concat " " (cmd :: args) |
||
1894 | in |
||
1895 | info ~ctxt (f_ "Running command '%s'") cmdline; |
||
1896 | match f_exit_code, Sys.command cmdline with |
||
1897 | | None, 0 -> () |
||
1898 | | None, i -> |
||
1899 | failwithf |
||
1900 | (f_ "Command '%s' terminated with error code %d") |
||
1901 | cmdline i |
||
1902 | | Some f, i -> |
||
1903 | f i |
||
1904 | |||
1905 | let run_read_output ~ctxt ?f_exit_code cmd args = |
||
1906 | let fn = |
||
1907 | Filename.temp_file "oasis-" ".txt" |
||
1908 | in |
||
1909 | try |
||
1910 | begin |
||
1911 | let () = |
||
1912 | run ~ctxt ?f_exit_code cmd (args @ [">"; Filename.quote fn]) |
||
1913 | in |
||
1914 | let chn = |
||
1915 | open_in fn |
||
1916 | in |
||
1917 | let routput = |
||
1918 | ref [] |
||
1919 | in |
||
1920 | begin |
||
1921 | try |
||
1922 | while true do |
||
1923 | routput := (input_line chn) :: !routput |
||
1924 | done |
||
1925 | with End_of_file -> |
||
1926 | () |
||
1927 | end; |
||
1928 | close_in chn; |
||
1929 | Sys.remove fn; |
||
1930 | List.rev !routput |
||
1931 | end |
||
1932 | with e -> |
||
1933 | (try Sys.remove fn with _ -> ()); |
||
1934 | raise e |
||
1935 | |||
1936 | let run_read_one_line ~ctxt ?f_exit_code cmd args = |
||
1937 | match run_read_output ~ctxt ?f_exit_code cmd args with |
||
1938 | | [fst] -> |
||
1939 | fst |
||
1940 | | lst -> |
||
1941 | failwithf |
||
1942 | (f_ "Command return unexpected output %S") |
||
1943 | (String.concat "\n" lst) |
||
1944 | end |
||
1945 | |||
1946 | module OASISFileUtil = struct |
||
1947 | d1baac41 | xthirioux | (* # 21 "src/oasis/OASISFileUtil.ml" *) |
1948 | 04e26a3f | xthirioux | |
1949 | open OASISGettext |
||
1950 | |||
1951 | let file_exists_case fn = |
||
1952 | let dirname = Filename.dirname fn in |
||
1953 | let basename = Filename.basename fn in |
||
1954 | if Sys.file_exists dirname then |
||
1955 | if basename = Filename.current_dir_name then |
||
1956 | true |
||
1957 | else |
||
1958 | List.mem |
||
1959 | basename |
||
1960 | (Array.to_list (Sys.readdir dirname)) |
||
1961 | else |
||
1962 | false |
||
1963 | |||
1964 | let find_file ?(case_sensitive=true) paths exts = |
||
1965 | |||
1966 | (* Cardinal product of two list *) |
||
1967 | let ( * ) lst1 lst2 = |
||
1968 | List.flatten |
||
1969 | (List.map |
||
1970 | (fun a -> |
||
1971 | List.map |
||
1972 | d1baac41 | xthirioux | (fun b -> a,b) |
1973 | 04e26a3f | xthirioux | lst2) |
1974 | lst1) |
||
1975 | in |
||
1976 | |||
1977 | let rec combined_paths lst = |
||
1978 | match lst with |
||
1979 | | p1 :: p2 :: tl -> |
||
1980 | let acc = |
||
1981 | (List.map |
||
1982 | d1baac41 | xthirioux | (fun (a,b) -> Filename.concat a b) |
1983 | 04e26a3f | xthirioux | (p1 * p2)) |
1984 | in |
||
1985 | combined_paths (acc :: tl) |
||
1986 | | [e] -> |
||
1987 | e |
||
1988 | | [] -> |
||
1989 | [] |
||
1990 | in |
||
1991 | |||
1992 | let alternatives = |
||
1993 | List.map |
||
1994 | d1baac41 | xthirioux | (fun (p,e) -> |
1995 | 04e26a3f | xthirioux | if String.length e > 0 && e.[0] <> '.' then |
1996 | p ^ "." ^ e |
||
1997 | else |
||
1998 | p ^ e) |
||
1999 | ((combined_paths paths) * exts) |
||
2000 | in |
||
2001 | d1baac41 | xthirioux | List.find |
2002 | 04e26a3f | xthirioux | (if case_sensitive then |
2003 | d1baac41 | xthirioux | file_exists_case |
2004 | 04e26a3f | xthirioux | else |
2005 | d1baac41 | xthirioux | Sys.file_exists) |
2006 | alternatives |
||
2007 | 04e26a3f | xthirioux | |
2008 | let which ~ctxt prg = |
||
2009 | let path_sep = |
||
2010 | match Sys.os_type with |
||
2011 | | "Win32" -> |
||
2012 | ';' |
||
2013 | | _ -> |
||
2014 | ':' |
||
2015 | in |
||
2016 | let path_lst = OASISString.nsplit (Sys.getenv "PATH") path_sep in |
||
2017 | let exec_ext = |
||
2018 | match Sys.os_type with |
||
2019 | | "Win32" -> |
||
2020 | "" :: (OASISString.nsplit (Sys.getenv "PATHEXT") path_sep) |
||
2021 | | _ -> |
||
2022 | [""] |
||
2023 | in |
||
2024 | find_file ~case_sensitive:false [path_lst; [prg]] exec_ext |
||
2025 | |||
2026 | (**/**) |
||
2027 | let rec fix_dir dn = |
||
2028 | (* Windows hack because Sys.file_exists "src\\" = false when |
||
2029 | * Sys.file_exists "src" = true |
||
2030 | *) |
||
2031 | let ln = |
||
2032 | String.length dn |
||
2033 | in |
||
2034 | if Sys.os_type = "Win32" && ln > 0 && dn.[ln - 1] = '\\' then |
||
2035 | fix_dir (String.sub dn 0 (ln - 1)) |
||
2036 | else |
||
2037 | dn |
||
2038 | |||
2039 | let q = Filename.quote |
||
2040 | (**/**) |
||
2041 | |||
2042 | let cp ~ctxt ?(recurse=false) src tgt = |
||
2043 | if recurse then |
||
2044 | match Sys.os_type with |
||
2045 | | "Win32" -> |
||
2046 | OASISExec.run ~ctxt |
||
2047 | "xcopy" [q src; q tgt; "/E"] |
||
2048 | | _ -> |
||
2049 | OASISExec.run ~ctxt |
||
2050 | "cp" ["-r"; q src; q tgt] |
||
2051 | else |
||
2052 | OASISExec.run ~ctxt |
||
2053 | (match Sys.os_type with |
||
2054 | | "Win32" -> "copy" |
||
2055 | | _ -> "cp") |
||
2056 | [q src; q tgt] |
||
2057 | |||
2058 | let mkdir ~ctxt tgt = |
||
2059 | OASISExec.run ~ctxt |
||
2060 | (match Sys.os_type with |
||
2061 | | "Win32" -> "md" |
||
2062 | | _ -> "mkdir") |
||
2063 | [q tgt] |
||
2064 | |||
2065 | let rec mkdir_parent ~ctxt f tgt = |
||
2066 | let tgt = |
||
2067 | fix_dir tgt |
||
2068 | in |
||
2069 | if Sys.file_exists tgt then |
||
2070 | begin |
||
2071 | if not (Sys.is_directory tgt) then |
||
2072 | OASISUtils.failwithf |
||
2073 | (f_ "Cannot create directory '%s', a file of the same name already \ |
||
2074 | exists") |
||
2075 | tgt |
||
2076 | end |
||
2077 | else |
||
2078 | begin |
||
2079 | mkdir_parent ~ctxt f (Filename.dirname tgt); |
||
2080 | if not (Sys.file_exists tgt) then |
||
2081 | begin |
||
2082 | f tgt; |
||
2083 | mkdir ~ctxt tgt |
||
2084 | end |
||
2085 | end |
||
2086 | |||
2087 | let rmdir ~ctxt tgt = |
||
2088 | d1baac41 | xthirioux | if Sys.readdir tgt = [||] then |
2089 | begin |
||
2090 | match Sys.os_type with |
||
2091 | | "Win32" -> |
||
2092 | OASISExec.run ~ctxt "rd" [q tgt] |
||
2093 | | _ -> |
||
2094 | OASISExec.run ~ctxt "rm" ["-r"; q tgt] |
||
2095 | end |
||
2096 | 04e26a3f | xthirioux | |
2097 | let glob ~ctxt fn = |
||
2098 | let basename = |
||
2099 | Filename.basename fn |
||
2100 | in |
||
2101 | if String.length basename >= 2 && |
||
2102 | basename.[0] = '*' && |
||
2103 | basename.[1] = '.' then |
||
2104 | begin |
||
2105 | let ext_len = |
||
2106 | (String.length basename) - 2 |
||
2107 | in |
||
2108 | let ext = |
||
2109 | String.sub basename 2 ext_len |
||
2110 | in |
||
2111 | let dirname = |
||
2112 | Filename.dirname fn |
||
2113 | in |
||
2114 | Array.fold_left |
||
2115 | (fun acc fn -> |
||
2116 | try |
||
2117 | let fn_ext = |
||
2118 | String.sub |
||
2119 | fn |
||
2120 | ((String.length fn) - ext_len) |
||
2121 | ext_len |
||
2122 | in |
||
2123 | if fn_ext = ext then |
||
2124 | (Filename.concat dirname fn) :: acc |
||
2125 | else |
||
2126 | acc |
||
2127 | with Invalid_argument _ -> |
||
2128 | acc) |
||
2129 | [] |
||
2130 | (Sys.readdir dirname) |
||
2131 | end |
||
2132 | else |
||
2133 | begin |
||
2134 | if file_exists_case fn then |
||
2135 | [fn] |
||
2136 | else |
||
2137 | [] |
||
2138 | end |
||
2139 | 22fe1c93 | ploc | end |
2140 | |||
2141 | |||
2142 | d1baac41 | xthirioux | # 2142 "setup.ml" |
2143 | 22fe1c93 | ploc | module BaseEnvLight = struct |
2144 | d1baac41 | xthirioux | (* # 21 "src/base/BaseEnvLight.ml" *) |
2145 | 04e26a3f | xthirioux | |
2146 | 22fe1c93 | ploc | module MapString = Map.Make(String) |
2147 | 04e26a3f | xthirioux | |
2148 | 22fe1c93 | ploc | type t = string MapString.t |
2149 | 04e26a3f | xthirioux | |
2150 | 22fe1c93 | ploc | let default_filename = |
2151 | 04e26a3f | xthirioux | Filename.concat |
2152 | 22fe1c93 | ploc | (Sys.getcwd ()) |
2153 | "setup.data" |
||
2154 | 04e26a3f | xthirioux | |
2155 | 22fe1c93 | ploc | let load ?(allow_empty=false) ?(filename=default_filename) () = |
2156 | if Sys.file_exists filename then |
||
2157 | begin |
||
2158 | let chn = |
||
2159 | open_in_bin filename |
||
2160 | in |
||
2161 | let st = |
||
2162 | Stream.of_channel chn |
||
2163 | in |
||
2164 | let line = |
||
2165 | ref 1 |
||
2166 | in |
||
2167 | 04e26a3f | xthirioux | let st_line = |
2168 | 22fe1c93 | ploc | Stream.from |
2169 | (fun _ -> |
||
2170 | try |
||
2171 | 04e26a3f | xthirioux | match Stream.next st with |
2172 | 22fe1c93 | ploc | | '\n' -> incr line; Some '\n' |
2173 | | c -> Some c |
||
2174 | with Stream.Failure -> None) |
||
2175 | in |
||
2176 | 04e26a3f | xthirioux | let lexer = |
2177 | 22fe1c93 | ploc | Genlex.make_lexer ["="] st_line |
2178 | in |
||
2179 | let rec read_file mp = |
||
2180 | 04e26a3f | xthirioux | match Stream.npeek 3 lexer with |
2181 | 22fe1c93 | ploc | | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] -> |
2182 | 04e26a3f | xthirioux | Stream.junk lexer; |
2183 | Stream.junk lexer; |
||
2184 | 22fe1c93 | ploc | Stream.junk lexer; |
2185 | read_file (MapString.add nm value mp) |
||
2186 | | [] -> |
||
2187 | mp |
||
2188 | | _ -> |
||
2189 | failwith |
||
2190 | (Printf.sprintf |
||
2191 | "Malformed data file '%s' line %d" |
||
2192 | filename !line) |
||
2193 | in |
||
2194 | let mp = |
||
2195 | read_file MapString.empty |
||
2196 | in |
||
2197 | close_in chn; |
||
2198 | mp |
||
2199 | end |
||
2200 | else if allow_empty then |
||
2201 | begin |
||
2202 | MapString.empty |
||
2203 | end |
||
2204 | else |
||
2205 | begin |
||
2206 | 04e26a3f | xthirioux | failwith |
2207 | (Printf.sprintf |
||
2208 | 22fe1c93 | ploc | "Unable to load environment, the file '%s' doesn't exist." |
2209 | filename) |
||
2210 | end |
||
2211 | 04e26a3f | xthirioux | |
2212 | 9603460e | xthirioux | let var_get name env = |
2213 | d1baac41 | xthirioux | let rec var_expand str = |
2214 | let buff = |
||
2215 | Buffer.create ((String.length str) * 2) |
||
2216 | in |
||
2217 | Buffer.add_substitute |
||
2218 | buff |
||
2219 | (fun var -> |
||
2220 | try |
||
2221 | var_expand (MapString.find var env) |
||
2222 | with Not_found -> |
||
2223 | failwith |
||
2224 | (Printf.sprintf |
||
2225 | "No variable %s defined when trying to expand %S." |
||
2226 | var |
||
2227 | str)) |
||
2228 | str; |
||
2229 | Buffer.contents buff |
||
2230 | in |
||
2231 | var_expand (MapString.find name env) |
||
2232 | 04e26a3f | xthirioux | |
2233 | let var_choose lst env = |
||
2234 | 22fe1c93 | ploc | OASISExpr.choose |
2235 | (fun nm -> var_get nm env) |
||
2236 | lst |
||
2237 | end |
||
2238 | |||
2239 | |||
2240 | d1baac41 | xthirioux | # 2240 "setup.ml" |
2241 | 22fe1c93 | ploc | module BaseContext = struct |
2242 | d1baac41 | xthirioux | (* # 21 "src/base/BaseContext.ml" *) |
2243 | 04e26a3f | xthirioux | |
2244 | open OASISContext |
||
2245 | |||
2246 | d1baac41 | xthirioux | let args = args |
2247 | 04e26a3f | xthirioux | |
2248 | 22fe1c93 | ploc | let default = default |
2249 | 04e26a3f | xthirioux | |
2250 | 22fe1c93 | ploc | end |
2251 | |||
2252 | module BaseMessage = struct |
||
2253 | d1baac41 | xthirioux | (* # 21 "src/base/BaseMessage.ml" *) |
2254 | 04e26a3f | xthirioux | |
2255 | (** Message to user, overrid for Base |
||
2256 | 22fe1c93 | ploc | @author Sylvain Le Gall |
2257 | *) |
||
2258 | open OASISMessage |
||
2259 | open BaseContext |
||
2260 | 04e26a3f | xthirioux | |
2261 | 22fe1c93 | ploc | let debug fmt = debug ~ctxt:!default fmt |
2262 | 04e26a3f | xthirioux | |
2263 | 22fe1c93 | ploc | let info fmt = info ~ctxt:!default fmt |
2264 | 04e26a3f | xthirioux | |
2265 | 22fe1c93 | ploc | let warning fmt = warning ~ctxt:!default fmt |
2266 | 04e26a3f | xthirioux | |
2267 | 22fe1c93 | ploc | let error fmt = error ~ctxt:!default fmt |
2268 | |||
2269 | end |
||
2270 | |||
2271 | module BaseEnv = struct |
||
2272 | d1baac41 | xthirioux | (* # 21 "src/base/BaseEnv.ml" *) |
2273 | 04e26a3f | xthirioux | |
2274 | 22fe1c93 | ploc | open OASISGettext |
2275 | open OASISUtils |
||
2276 | open PropList |
||
2277 | 04e26a3f | xthirioux | |
2278 | 22fe1c93 | ploc | module MapString = BaseEnvLight.MapString |
2279 | 04e26a3f | xthirioux | |
2280 | type origin_t = |
||
2281 | 22fe1c93 | ploc | | ODefault |
2282 | | OGetEnv |
||
2283 | | OFileLoad |
||
2284 | | OCommandLine |
||
2285 | 04e26a3f | xthirioux | |
2286 | 22fe1c93 | ploc | type cli_handle_t = |
2287 | | CLINone |
||
2288 | | CLIAuto |
||
2289 | | CLIWith |
||
2290 | | CLIEnable |
||
2291 | | CLIUser of (Arg.key * Arg.spec * Arg.doc) list |
||
2292 | 04e26a3f | xthirioux | |
2293 | 22fe1c93 | ploc | type definition_t = |
2294 | { |
||
2295 | hide: bool; |
||
2296 | dump: bool; |
||
2297 | cli: cli_handle_t; |
||
2298 | arg_help: string option; |
||
2299 | group: string option; |
||
2300 | } |
||
2301 | 04e26a3f | xthirioux | |
2302 | 22fe1c93 | ploc | let schema = |
2303 | Schema.create "environment" |
||
2304 | 04e26a3f | xthirioux | |
2305 | 22fe1c93 | ploc | (* Environment data *) |
2306 | 04e26a3f | xthirioux | let env = |
2307 | 22fe1c93 | ploc | Data.create () |
2308 | 04e26a3f | xthirioux | |
2309 | 22fe1c93 | ploc | (* Environment data from file *) |
2310 | 04e26a3f | xthirioux | let env_from_file = |
2311 | 22fe1c93 | ploc | ref MapString.empty |
2312 | 04e26a3f | xthirioux | |
2313 | 22fe1c93 | ploc | (* Lexer for var *) |
2314 | 04e26a3f | xthirioux | let var_lxr = |
2315 | 22fe1c93 | ploc | Genlex.make_lexer [] |
2316 | 04e26a3f | xthirioux | |
2317 | 22fe1c93 | ploc | let rec var_expand str = |
2318 | let buff = |
||
2319 | Buffer.create ((String.length str) * 2) |
||
2320 | in |
||
2321 | 04e26a3f | xthirioux | Buffer.add_substitute |
2322 | 22fe1c93 | ploc | buff |
2323 | 04e26a3f | xthirioux | (fun var -> |
2324 | try |
||
2325 | (* TODO: this is a quick hack to allow calling Test.Command |
||
2326 | 22fe1c93 | ploc | * without defining executable name really. I.e. if there is |
2327 | * an exec Executable toto, then $(toto) should be replace |
||
2328 | * by its real name. It is however useful to have this function |
||
2329 | 04e26a3f | xthirioux | * for other variable that depend on the host and should be |
2330 | 22fe1c93 | ploc | * written better than that. |
2331 | *) |
||
2332 | let st = |
||
2333 | var_lxr (Stream.of_string var) |
||
2334 | in |
||
2335 | 04e26a3f | xthirioux | match Stream.npeek 3 st with |
2336 | 22fe1c93 | ploc | | [Genlex.Ident "utoh"; Genlex.Ident nm] -> |
2337 | 04e26a3f | xthirioux | OASISHostPath.of_unix (var_get nm) |
2338 | 22fe1c93 | ploc | | [Genlex.Ident "utoh"; Genlex.String s] -> |
2339 | 04e26a3f | xthirioux | OASISHostPath.of_unix s |
2340 | 22fe1c93 | ploc | | [Genlex.Ident "ocaml_escaped"; Genlex.Ident nm] -> |
2341 | String.escaped (var_get nm) |
||
2342 | | [Genlex.Ident "ocaml_escaped"; Genlex.String s] -> |
||
2343 | String.escaped s |
||
2344 | | [Genlex.Ident nm] -> |
||
2345 | var_get nm |
||
2346 | | _ -> |
||
2347 | 04e26a3f | xthirioux | failwithf |
2348 | 22fe1c93 | ploc | (f_ "Unknown expression '%s' in variable expansion of %s.") |
2349 | var |
||
2350 | str |
||
2351 | 04e26a3f | xthirioux | with |
2352 | 22fe1c93 | ploc | | Unknown_field (_, _) -> |
2353 | 04e26a3f | xthirioux | failwithf |
2354 | 22fe1c93 | ploc | (f_ "No variable %s defined when trying to expand %S.") |
2355 | 04e26a3f | xthirioux | var |
2356 | 22fe1c93 | ploc | str |
2357 | 04e26a3f | xthirioux | | Stream.Error e -> |
2358 | failwithf |
||
2359 | 22fe1c93 | ploc | (f_ "Syntax error when parsing '%s' when trying to \ |
2360 | expand %S: %s") |
||
2361 | var |
||
2362 | str |
||
2363 | e) |
||
2364 | str; |
||
2365 | Buffer.contents buff |
||
2366 | 04e26a3f | xthirioux | |
2367 | 22fe1c93 | ploc | and var_get name = |
2368 | 04e26a3f | xthirioux | let vl = |
2369 | try |
||
2370 | 22fe1c93 | ploc | Schema.get schema env name |
2371 | with Unknown_field _ as e -> |
||
2372 | begin |
||
2373 | 04e26a3f | xthirioux | try |
2374 | 22fe1c93 | ploc | MapString.find name !env_from_file |
2375 | with Not_found -> |
||
2376 | raise e |
||
2377 | end |
||
2378 | in |
||
2379 | var_expand vl |
||
2380 | 04e26a3f | xthirioux | |
2381 | 22fe1c93 | ploc | let var_choose ?printer ?name lst = |
2382 | 04e26a3f | xthirioux | OASISExpr.choose |
2383 | 22fe1c93 | ploc | ?printer |
2384 | ?name |
||
2385 | 04e26a3f | xthirioux | var_get |
2386 | 22fe1c93 | ploc | lst |
2387 | 04e26a3f | xthirioux | |
2388 | let var_protect vl = |
||
2389 | let buff = |
||
2390 | 22fe1c93 | ploc | Buffer.create (String.length vl) |
2391 | in |
||
2392 | String.iter |
||
2393 | 04e26a3f | xthirioux | (function |
2394 | 22fe1c93 | ploc | | '$' -> Buffer.add_string buff "\\$" |
2395 | | c -> Buffer.add_char buff c) |
||
2396 | vl; |
||
2397 | Buffer.contents buff |
||
2398 | 04e26a3f | xthirioux | |
2399 | let var_define |
||
2400 | ?(hide=false) |
||
2401 | ?(dump=true) |
||
2402 | 22fe1c93 | ploc | ?short_desc |
2403 | ?(cli=CLINone) |
||
2404 | ?arg_help |
||
2405 | 04e26a3f | xthirioux | ?group |
2406 | 22fe1c93 | ploc | name (* TODO: type constraint on the fact that name must be a valid OCaml |
2407 | id *) |
||
2408 | dflt = |
||
2409 | 04e26a3f | xthirioux | |
2410 | 22fe1c93 | ploc | let default = |
2411 | [ |
||
2412 | 04e26a3f | xthirioux | OFileLoad, (fun () -> MapString.find name !env_from_file); |
2413 | 22fe1c93 | ploc | ODefault, dflt; |
2414 | 04e26a3f | xthirioux | OGetEnv, (fun () -> Sys.getenv name); |
2415 | 22fe1c93 | ploc | ] |
2416 | in |
||
2417 | 04e26a3f | xthirioux | |
2418 | let extra = |
||
2419 | 22fe1c93 | ploc | { |
2420 | hide = hide; |
||
2421 | dump = dump; |
||
2422 | cli = cli; |
||
2423 | arg_help = arg_help; |
||
2424 | group = group; |
||
2425 | } |
||
2426 | in |
||
2427 | 04e26a3f | xthirioux | |
2428 | (* Try to find a value that can be defined |
||
2429 | 22fe1c93 | ploc | *) |
2430 | 04e26a3f | xthirioux | let var_get_low lst = |
2431 | 22fe1c93 | ploc | let errors, res = |
2432 | List.fold_left |
||
2433 | 04e26a3f | xthirioux | (fun (errors, res) (o, v) -> |
2434 | 22fe1c93 | ploc | if res = None then |
2435 | begin |
||
2436 | 04e26a3f | xthirioux | try |
2437 | errors, Some (v ()) |
||
2438 | 22fe1c93 | ploc | with |
2439 | | Not_found -> |
||
2440 | errors, res |
||
2441 | | Failure rsn -> |
||
2442 | (rsn :: errors), res |
||
2443 | | e -> |
||
2444 | (Printexc.to_string e) :: errors, res |
||
2445 | end |
||
2446 | else |
||
2447 | errors, res) |
||
2448 | ([], None) |
||
2449 | (List.sort |
||
2450 | (fun (o1, _) (o2, _) -> |
||
2451 | 04e26a3f | xthirioux | Pervasives.compare o2 o1) |
2452 | 22fe1c93 | ploc | lst) |
2453 | in |
||
2454 | 04e26a3f | xthirioux | match res, errors with |
2455 | 22fe1c93 | ploc | | Some v, _ -> |
2456 | v |
||
2457 | | None, [] -> |
||
2458 | raise (Not_set (name, None)) |
||
2459 | | None, lst -> |
||
2460 | raise (Not_set (name, Some (String.concat (s_ ", ") lst))) |
||
2461 | in |
||
2462 | 04e26a3f | xthirioux | |
2463 | 22fe1c93 | ploc | let help = |
2464 | 04e26a3f | xthirioux | match short_desc with |
2465 | 22fe1c93 | ploc | | Some fs -> Some fs |
2466 | | None -> None |
||
2467 | in |
||
2468 | 04e26a3f | xthirioux | |
2469 | let var_get_lst = |
||
2470 | 22fe1c93 | ploc | FieldRO.create |
2471 | ~schema |
||
2472 | ~name |
||
2473 | 04e26a3f | xthirioux | ~parse:(fun ?(context=ODefault) s -> [context, fun () -> s]) |
2474 | 22fe1c93 | ploc | ~print:var_get_low |
2475 | ~default |
||
2476 | ~update:(fun ?context x old_x -> x @ old_x) |
||
2477 | ?help |
||
2478 | extra |
||
2479 | in |
||
2480 | 04e26a3f | xthirioux | |
2481 | 22fe1c93 | ploc | fun () -> |
2482 | var_expand (var_get_low (var_get_lst env)) |
||
2483 | 04e26a3f | xthirioux | |
2484 | let var_redefine |
||
2485 | 22fe1c93 | ploc | ?hide |
2486 | ?dump |
||
2487 | ?short_desc |
||
2488 | ?cli |
||
2489 | ?arg_help |
||
2490 | 04e26a3f | xthirioux | ?group |
2491 | name |
||
2492 | 22fe1c93 | ploc | dflt = |
2493 | if Schema.mem schema name then |
||
2494 | begin |
||
2495 | 04e26a3f | xthirioux | (* TODO: look suspsicious, we want to memorize dflt not dflt () *) |
2496 | Schema.set schema env ~context:ODefault name (dflt ()); |
||
2497 | 22fe1c93 | ploc | fun () -> var_get name |
2498 | end |
||
2499 | else |
||
2500 | begin |
||
2501 | 04e26a3f | xthirioux | var_define |
2502 | 22fe1c93 | ploc | ?hide |
2503 | ?dump |
||
2504 | ?short_desc |
||
2505 | ?cli |
||
2506 | ?arg_help |
||
2507 | 04e26a3f | xthirioux | ?group |
2508 | name |
||
2509 | 22fe1c93 | ploc | dflt |
2510 | end |
||
2511 | 04e26a3f | xthirioux | |
2512 | d1baac41 | xthirioux | let var_ignore (e : unit -> string) = |
2513 | () |
||
2514 | 04e26a3f | xthirioux | |
2515 | 22fe1c93 | ploc | let print_hidden = |
2516 | 04e26a3f | xthirioux | var_define |
2517 | 22fe1c93 | ploc | ~hide:true |
2518 | ~dump:false |
||
2519 | ~cli:CLIAuto |
||
2520 | ~arg_help:"Print even non-printable variable. (debug)" |
||
2521 | "print_hidden" |
||
2522 | 04e26a3f | xthirioux | (fun () -> "false") |
2523 | |||
2524 | 22fe1c93 | ploc | let var_all () = |
2525 | List.rev |
||
2526 | (Schema.fold |
||
2527 | 04e26a3f | xthirioux | (fun acc nm def _ -> |
2528 | 22fe1c93 | ploc | if not def.hide || bool_of_string (print_hidden ()) then |
2529 | nm :: acc |
||
2530 | else |
||
2531 | acc) |
||
2532 | [] |
||
2533 | schema) |
||
2534 | 04e26a3f | xthirioux | |
2535 | 22fe1c93 | ploc | let default_filename = |
2536 | BaseEnvLight.default_filename |
||
2537 | 04e26a3f | xthirioux | |
2538 | 22fe1c93 | ploc | let load ?allow_empty ?filename () = |
2539 | env_from_file := BaseEnvLight.load ?allow_empty ?filename () |
||
2540 | 04e26a3f | xthirioux | |
2541 | let unload () = |
||
2542 | 22fe1c93 | ploc | env_from_file := MapString.empty; |
2543 | Data.clear env |
||
2544 | 04e26a3f | xthirioux | |
2545 | let dump ?(filename=default_filename) () = |
||
2546 | 22fe1c93 | ploc | let chn = |
2547 | open_out_bin filename |
||
2548 | in |
||
2549 | d1baac41 | xthirioux | let output nm value = |
2550 | 04e26a3f | xthirioux | Printf.fprintf chn "%s=%S\n" nm value |
2551 | in |
||
2552 | d1baac41 | xthirioux | let mp_todo = |
2553 | 04e26a3f | xthirioux | (* Dump data from schema *) |
2554 | Schema.fold |
||
2555 | (fun mp_todo nm def _ -> |
||
2556 | 22fe1c93 | ploc | if def.dump then |
2557 | begin |
||
2558 | 04e26a3f | xthirioux | try |
2559 | 22fe1c93 | ploc | let value = |
2560 | 04e26a3f | xthirioux | Schema.get |
2561 | schema |
||
2562 | env |
||
2563 | 22fe1c93 | ploc | nm |
2564 | in |
||
2565 | 04e26a3f | xthirioux | output nm value |
2566 | 22fe1c93 | ploc | with Not_set _ -> |
2567 | () |
||
2568 | 04e26a3f | xthirioux | end; |
2569 | MapString.remove nm mp_todo) |
||
2570 | !env_from_file |
||
2571 | schema |
||
2572 | in |
||
2573 | (* Dump data defined outside of schema *) |
||
2574 | MapString.iter output mp_todo; |
||
2575 | |||
2576 | (* End of the dump *) |
||
2577 | 22fe1c93 | ploc | close_out chn |
2578 | 04e26a3f | xthirioux | |
2579 | 22fe1c93 | ploc | let print () = |
2580 | let printable_vars = |
||
2581 | Schema.fold |
||
2582 | 04e26a3f | xthirioux | (fun acc nm def short_descr_opt -> |
2583 | 22fe1c93 | ploc | if not def.hide || bool_of_string (print_hidden ()) then |
2584 | begin |
||
2585 | 04e26a3f | xthirioux | try |
2586 | let value = |
||
2587 | Schema.get |
||
2588 | 22fe1c93 | ploc | schema |
2589 | env |
||
2590 | nm |
||
2591 | in |
||
2592 | 04e26a3f | xthirioux | let txt = |
2593 | match short_descr_opt with |
||
2594 | 22fe1c93 | ploc | | Some s -> s () |
2595 | | None -> nm |
||
2596 | in |
||
2597 | (txt, value) :: acc |
||
2598 | with Not_set _ -> |
||
2599 | acc |
||
2600 | end |
||
2601 | else |
||
2602 | acc) |
||
2603 | [] |
||
2604 | schema |
||
2605 | in |
||
2606 | 04e26a3f | xthirioux | let max_length = |
2607 | 22fe1c93 | ploc | List.fold_left max 0 |
2608 | (List.rev_map String.length |
||
2609 | (List.rev_map fst printable_vars)) |
||
2610 | in |
||
2611 | let dot_pad str = |
||
2612 | String.make ((max_length - (String.length str)) + 3) '.' |
||
2613 | in |
||
2614 | 04e26a3f | xthirioux | |
2615 | Printf.printf "\nConfiguration: \n"; |
||
2616 | List.iter |
||
2617 | d1baac41 | xthirioux | (fun (name,value) -> |
2618 | 04e26a3f | xthirioux | Printf.printf "%s: %s %s\n" name (dot_pad name) value) |
2619 | (List.rev printable_vars); |
||
2620 | Printf.printf "\n%!" |
||
2621 | |||
2622 | 22fe1c93 | ploc | let args () = |
2623 | let arg_concat = |
||
2624 | OASISUtils.varname_concat ~hyphen:'-' |
||
2625 | in |
||
2626 | [ |
||
2627 | "--override", |
||
2628 | Arg.Tuple |
||
2629 | ( |
||
2630 | let rvr = ref "" |
||
2631 | in |
||
2632 | let rvl = ref "" |
||
2633 | in |
||
2634 | [ |
||
2635 | Arg.Set_string rvr; |
||
2636 | Arg.Set_string rvl; |
||
2637 | 04e26a3f | xthirioux | Arg.Unit |
2638 | (fun () -> |
||
2639 | Schema.set |
||
2640 | 22fe1c93 | ploc | schema |
2641 | env |
||
2642 | 04e26a3f | xthirioux | ~context:OCommandLine |
2643 | 22fe1c93 | ploc | !rvr |
2644 | !rvl) |
||
2645 | ] |
||
2646 | ), |
||
2647 | "var+val Override any configuration variable."; |
||
2648 | 04e26a3f | xthirioux | |
2649 | 22fe1c93 | ploc | ] |
2650 | @ |
||
2651 | 04e26a3f | xthirioux | List.flatten |
2652 | 22fe1c93 | ploc | (Schema.fold |
2653 | (fun acc name def short_descr_opt -> |
||
2654 | 04e26a3f | xthirioux | let var_set s = |
2655 | Schema.set |
||
2656 | 22fe1c93 | ploc | schema |
2657 | env |
||
2658 | 04e26a3f | xthirioux | ~context:OCommandLine |
2659 | 22fe1c93 | ploc | name |
2660 | s |
||
2661 | in |
||
2662 | 04e26a3f | xthirioux | |
2663 | let arg_name = |
||
2664 | 22fe1c93 | ploc | OASISUtils.varname_of_string ~hyphen:'-' name |
2665 | in |
||
2666 | 04e26a3f | xthirioux | |
2667 | 22fe1c93 | ploc | let hlp = |
2668 | 04e26a3f | xthirioux | match short_descr_opt with |
2669 | 22fe1c93 | ploc | | Some txt -> txt () |
2670 | | None -> "" |
||
2671 | in |
||
2672 | 04e26a3f | xthirioux | |
2673 | 22fe1c93 | ploc | let arg_hlp = |
2674 | 04e26a3f | xthirioux | match def.arg_help with |
2675 | 22fe1c93 | ploc | | Some s -> s |
2676 | | None -> "str" |
||
2677 | in |
||
2678 | 04e26a3f | xthirioux | |
2679 | let default_value = |
||
2680 | try |
||
2681 | Printf.sprintf |
||
2682 | 22fe1c93 | ploc | (f_ " [%s]") |
2683 | (Schema.get |
||
2684 | schema |
||
2685 | env |
||
2686 | name) |
||
2687 | 04e26a3f | xthirioux | with Not_set _ -> |
2688 | 22fe1c93 | ploc | "" |
2689 | in |
||
2690 | 04e26a3f | xthirioux | |
2691 | let args = |
||
2692 | match def.cli with |
||
2693 | | CLINone -> |
||
2694 | 22fe1c93 | ploc | [] |
2695 | 04e26a3f | xthirioux | | CLIAuto -> |
2696 | 22fe1c93 | ploc | [ |
2697 | arg_concat "--" arg_name, |
||
2698 | Arg.String var_set, |
||
2699 | Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value |
||
2700 | ] |
||
2701 | | CLIWith -> |
||
2702 | [ |
||
2703 | arg_concat "--with-" arg_name, |
||
2704 | Arg.String var_set, |
||
2705 | Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value |
||
2706 | ] |
||
2707 | | CLIEnable -> |
||
2708 | 04e26a3f | xthirioux | let dflt = |
2709 | if default_value = " [true]" then |
||
2710 | s_ " [default: enabled]" |
||
2711 | else |
||
2712 | s_ " [default: disabled]" |
||
2713 | in |
||
2714 | [ |
||
2715 | arg_concat "--enable-" arg_name, |
||
2716 | Arg.Unit (fun () -> var_set "true"), |
||
2717 | Printf.sprintf (f_ " %s%s") hlp dflt; |
||
2718 | |||
2719 | arg_concat "--disable-" arg_name, |
||
2720 | Arg.Unit (fun () -> var_set "false"), |
||
2721 | Printf.sprintf (f_ " %s%s") hlp dflt |
||
2722 | ] |
||
2723 | 22fe1c93 | ploc | | CLIUser lst -> |
2724 | lst |
||
2725 | in |
||
2726 | args :: acc) |
||
2727 | [] |
||
2728 | schema) |
||
2729 | end |
||
2730 | |||
2731 | module BaseArgExt = struct |
||
2732 | d1baac41 | xthirioux | (* # 21 "src/base/BaseArgExt.ml" *) |
2733 | 04e26a3f | xthirioux | |
2734 | 22fe1c93 | ploc | open OASISUtils |
2735 | open OASISGettext |
||
2736 | 04e26a3f | xthirioux | |
2737 | 22fe1c93 | ploc | let parse argv args = |
2738 | (* Simulate command line for Arg *) |
||
2739 | let current = |
||
2740 | ref 0 |
||
2741 | in |
||
2742 | 04e26a3f | xthirioux | |
2743 | 22fe1c93 | ploc | try |
2744 | Arg.parse_argv |
||
2745 | ~current:current |
||
2746 | (Array.concat [[|"none"|]; argv]) |
||
2747 | (Arg.align args) |
||
2748 | 04e26a3f | xthirioux | (failwithf (f_ "Don't know what to do with arguments: '%s'")) |
2749 | 22fe1c93 | ploc | (s_ "configure options:") |
2750 | 04e26a3f | xthirioux | with |
2751 | 22fe1c93 | ploc | | Arg.Help txt -> |
2752 | print_endline txt; |
||
2753 | exit 0 |
||
2754 | | Arg.Bad txt -> |
||
2755 | prerr_endline txt; |
||
2756 | exit 1 |
||
2757 | end |
||
2758 | |||
2759 | module BaseCheck = struct |
||
2760 | d1baac41 | xthirioux | (* # 21 "src/base/BaseCheck.ml" *) |
2761 | 04e26a3f | xthirioux | |
2762 | 22fe1c93 | ploc | open BaseEnv |
2763 | open BaseMessage |
||
2764 | open OASISUtils |
||
2765 | open OASISGettext |
||
2766 | 04e26a3f | xthirioux | |
2767 | 22fe1c93 | ploc | let prog_best prg prg_lst = |
2768 | var_redefine |
||
2769 | 04e26a3f | xthirioux | prg |
2770 | (fun () -> |
||
2771 | let alternate = |
||
2772 | List.fold_left |
||
2773 | (fun res e -> |
||
2774 | match res with |
||
2775 | | Some _ -> |
||
2776 | res |
||
2777 | | None -> |
||
2778 | try |
||
2779 | Some (OASISFileUtil.which ~ctxt:!BaseContext.default e) |
||
2780 | with Not_found -> |
||
2781 | None) |
||
2782 | None |
||
2783 | prg_lst |
||
2784 | in |
||
2785 | match alternate with |
||
2786 | | Some prg -> prg |
||
2787 | | None -> raise Not_found) |
||
2788 | |||
2789 | 22fe1c93 | ploc | let prog prg = |
2790 | prog_best prg [prg] |
||
2791 | 04e26a3f | xthirioux | |
2792 | let prog_opt prg = |
||
2793 | 22fe1c93 | ploc | prog_best prg [prg^".opt"; prg] |
2794 | 04e26a3f | xthirioux | |
2795 | let ocamlfind = |
||
2796 | 22fe1c93 | ploc | prog "ocamlfind" |
2797 | 04e26a3f | xthirioux | |
2798 | let version |
||
2799 | var_prefix |
||
2800 | 22fe1c93 | ploc | cmp |
2801 | 04e26a3f | xthirioux | fversion |
2802 | () = |
||
2803 | 22fe1c93 | ploc | (* Really compare version provided *) |
2804 | 04e26a3f | xthirioux | let var = |
2805 | 22fe1c93 | ploc | var_prefix^"_version_"^(OASISVersion.varname_of_comparator cmp) |
2806 | in |
||
2807 | 04e26a3f | xthirioux | var_redefine |
2808 | ~hide:true |
||
2809 | 22fe1c93 | ploc | var |
2810 | 04e26a3f | xthirioux | (fun () -> |
2811 | let version_str = |
||
2812 | match fversion () with |
||
2813 | | "[Distributed with OCaml]" -> |
||
2814 | begin |
||
2815 | try |
||
2816 | (var_get "ocaml_version") |
||
2817 | with Not_found -> |
||
2818 | warning |
||
2819 | (f_ "Variable ocaml_version not defined, fallback \ |
||
2820 | to default"); |
||
2821 | Sys.ocaml_version |
||
2822 | end |
||
2823 | | res -> |
||
2824 | res |
||
2825 | in |
||
2826 | let version = |
||
2827 | OASISVersion.version_of_string version_str |
||
2828 | in |
||
2829 | if OASISVersion.comparator_apply version cmp then |
||
2830 | version_str |
||
2831 | else |
||
2832 | failwithf |
||
2833 | (f_ "Cannot satisfy version constraint on %s: %s (version: %s)") |
||
2834 | var_prefix |
||
2835 | (OASISVersion.string_of_comparator cmp) |
||
2836 | version_str) |
||
2837 | 22fe1c93 | ploc | () |
2838 | 04e26a3f | xthirioux | |
2839 | 22fe1c93 | ploc | let package_version pkg = |
2840 | 04e26a3f | xthirioux | OASISExec.run_read_one_line ~ctxt:!BaseContext.default |
2841 | 22fe1c93 | ploc | (ocamlfind ()) |
2842 | ["query"; "-format"; "%v"; pkg] |
||
2843 | 04e26a3f | xthirioux | |
2844 | 22fe1c93 | ploc | let package ?version_comparator pkg () = |
2845 | let var = |
||
2846 | 04e26a3f | xthirioux | OASISUtils.varname_concat |
2847 | "pkg_" |
||
2848 | 22fe1c93 | ploc | (OASISUtils.varname_of_string pkg) |
2849 | in |
||
2850 | 04e26a3f | xthirioux | let findlib_dir pkg = |
2851 | let dir = |
||
2852 | OASISExec.run_read_one_line ~ctxt:!BaseContext.default |
||
2853 | 22fe1c93 | ploc | (ocamlfind ()) |
2854 | ["query"; "-format"; "%d"; pkg] |
||
2855 | in |
||
2856 | if Sys.file_exists dir && Sys.is_directory dir then |
||
2857 | dir |
||
2858 | else |
||
2859 | 04e26a3f | xthirioux | failwithf |
2860 | 22fe1c93 | ploc | (f_ "When looking for findlib package %s, \ |
2861 | directory %s return doesn't exist") |
||
2862 | pkg dir |
||
2863 | in |
||
2864 | let vl = |
||
2865 | var_redefine |
||
2866 | var |
||
2867 | 04e26a3f | xthirioux | (fun () -> findlib_dir pkg) |
2868 | 22fe1c93 | ploc | () |
2869 | in |
||
2870 | ( |
||
2871 | 04e26a3f | xthirioux | match version_comparator with |
2872 | 22fe1c93 | ploc | | Some ver_cmp -> |
2873 | ignore |
||
2874 | 04e26a3f | xthirioux | (version |
2875 | 22fe1c93 | ploc | var |
2876 | ver_cmp |
||
2877 | (fun _ -> package_version pkg) |
||
2878 | ()) |
||
2879 | 04e26a3f | xthirioux | | None -> |
2880 | 22fe1c93 | ploc | () |
2881 | ); |
||
2882 | vl |
||
2883 | end |
||
2884 | |||
2885 | module BaseOCamlcConfig = struct |
||
2886 | d1baac41 | xthirioux | (* # 21 "src/base/BaseOCamlcConfig.ml" *) |
2887 | 04e26a3f | xthirioux | |
2888 | |||
2889 | 22fe1c93 | ploc | open BaseEnv |
2890 | open OASISUtils |
||
2891 | open OASISGettext |
||
2892 | 04e26a3f | xthirioux | |
2893 | 22fe1c93 | ploc | module SMap = Map.Make(String) |
2894 | 04e26a3f | xthirioux | |
2895 | let ocamlc = |
||
2896 | 22fe1c93 | ploc | BaseCheck.prog_opt "ocamlc" |
2897 | 04e26a3f | xthirioux | |
2898 | 22fe1c93 | ploc | let ocamlc_config_map = |
2899 | 04e26a3f | xthirioux | (* Map name to value for ocamlc -config output |
2900 | (name ^": "^value) |
||
2901 | 22fe1c93 | ploc | *) |
2902 | 04e26a3f | xthirioux | let rec split_field mp lst = |
2903 | match lst with |
||
2904 | 22fe1c93 | ploc | | line :: tl -> |
2905 | let mp = |
||
2906 | try |
||
2907 | let pos_semicolon = |
||
2908 | String.index line ':' |
||
2909 | in |
||
2910 | 04e26a3f | xthirioux | if pos_semicolon > 1 then |
2911 | 22fe1c93 | ploc | ( |
2912 | let name = |
||
2913 | 04e26a3f | xthirioux | String.sub line 0 pos_semicolon |
2914 | 22fe1c93 | ploc | in |
2915 | let linelen = |
||
2916 | String.length line |
||
2917 | in |
||
2918 | let value = |
||
2919 | if linelen > pos_semicolon + 2 then |
||
2920 | 04e26a3f | xthirioux | String.sub |
2921 | line |
||
2922 | (pos_semicolon + 2) |
||
2923 | 22fe1c93 | ploc | (linelen - pos_semicolon - 2) |
2924 | else |
||
2925 | "" |
||
2926 | in |
||
2927 | SMap.add name value mp |
||
2928 | ) |
||
2929 | else |
||
2930 | ( |
||
2931 | mp |
||
2932 | ) |
||
2933 | with Not_found -> |
||
2934 | ( |
||
2935 | mp |
||
2936 | ) |
||
2937 | in |
||
2938 | split_field mp tl |
||
2939 | | [] -> |
||
2940 | mp |
||
2941 | in |
||
2942 | 04e26a3f | xthirioux | |
2943 | d1baac41 | xthirioux | let cache = |
2944 | 04e26a3f | xthirioux | lazy |
2945 | (var_protect |
||
2946 | (Marshal.to_string |
||
2947 | (split_field |
||
2948 | SMap.empty |
||
2949 | (OASISExec.run_read_output |
||
2950 | ~ctxt:!BaseContext.default |
||
2951 | (ocamlc ()) ["-config"])) |
||
2952 | [])) |
||
2953 | in |
||
2954 | 22fe1c93 | ploc | var_redefine |
2955 | "ocamlc_config_map" |
||
2956 | ~hide:true |
||
2957 | ~dump:false |
||
2958 | 04e26a3f | xthirioux | (fun () -> |
2959 | (* TODO: update if ocamlc change !!! *) |
||
2960 | Lazy.force cache) |
||
2961 | |||
2962 | 22fe1c93 | ploc | let var_define nm = |
2963 | (* Extract data from ocamlc -config *) |
||
2964 | 04e26a3f | xthirioux | let avlbl_config_get () = |
2965 | Marshal.from_string |
||
2966 | 22fe1c93 | ploc | (ocamlc_config_map ()) |
2967 | 0 |
||
2968 | in |
||
2969 | 04e26a3f | xthirioux | let chop_version_suffix s = |
2970 | d1baac41 | xthirioux | try |
2971 | 04e26a3f | xthirioux | String.sub s 0 (String.index s '+') |
2972 | d1baac41 | xthirioux | with _ -> |
2973 | 04e26a3f | xthirioux | s |
2974 | in |
||
2975 | |||
2976 | let nm_config, value_config = |
||
2977 | match nm with |
||
2978 | d1baac41 | xthirioux | | "ocaml_version" -> |
2979 | 04e26a3f | xthirioux | "version", chop_version_suffix |
2980 | | _ -> nm, (fun x -> x) |
||
2981 | 22fe1c93 | ploc | in |
2982 | var_redefine |
||
2983 | 04e26a3f | xthirioux | nm |
2984 | (fun () -> |
||
2985 | try |
||
2986 | let map = |
||
2987 | avlbl_config_get () |
||
2988 | in |
||
2989 | let value = |
||
2990 | SMap.find nm_config map |
||
2991 | in |
||
2992 | value_config value |
||
2993 | with Not_found -> |
||
2994 | failwithf |
||
2995 | (f_ "Cannot find field '%s' in '%s -config' output") |
||
2996 | nm |
||
2997 | (ocamlc ())) |
||
2998 | |||
2999 | 22fe1c93 | ploc | end |
3000 | |||
3001 | module BaseStandardVar = struct |
||
3002 | d1baac41 | xthirioux | (* # 21 "src/base/BaseStandardVar.ml" *) |
3003 | 04e26a3f | xthirioux | |
3004 | |||
3005 | 22fe1c93 | ploc | open OASISGettext |
3006 | open OASISTypes |
||
3007 | open OASISExpr |
||
3008 | open BaseCheck |
||
3009 | open BaseEnv |
||
3010 | 04e26a3f | xthirioux | |
3011 | 22fe1c93 | ploc | let ocamlfind = BaseCheck.ocamlfind |
3012 | let ocamlc = BaseOCamlcConfig.ocamlc |
||
3013 | let ocamlopt = prog_opt "ocamlopt" |
||
3014 | let ocamlbuild = prog "ocamlbuild" |
||
3015 | 04e26a3f | xthirioux | |
3016 | |||
3017 | 22fe1c93 | ploc | (**/**) |
3018 | 04e26a3f | xthirioux | let rpkg = |
3019 | 22fe1c93 | ploc | ref None |
3020 | 04e26a3f | xthirioux | |
3021 | 22fe1c93 | ploc | let pkg_get () = |
3022 | 04e26a3f | xthirioux | match !rpkg with |
3023 | 22fe1c93 | ploc | | Some pkg -> pkg |
3024 | | None -> failwith (s_ "OASIS Package is not set") |
||
3025 | 04e26a3f | xthirioux | |
3026 | let var_cond = ref [] |
||
3027 | |||
3028 | let var_define_cond ~since_version f dflt = |
||
3029 | let holder = ref (fun () -> dflt) in |
||
3030 | let since_version = |
||
3031 | OASISVersion.VGreaterEqual (OASISVersion.version_of_string since_version) |
||
3032 | in |
||
3033 | var_cond := |
||
3034 | (fun ver -> |
||
3035 | if OASISVersion.comparator_apply ver since_version then |
||
3036 | holder := f ()) :: !var_cond; |
||
3037 | fun () -> !holder () |
||
3038 | |||
3039 | 22fe1c93 | ploc | (**/**) |
3040 | 04e26a3f | xthirioux | |
3041 | let pkg_name = |
||
3042 | 22fe1c93 | ploc | var_define |
3043 | ~short_desc:(fun () -> s_ "Package name") |
||
3044 | "pkg_name" |
||
3045 | 04e26a3f | xthirioux | (fun () -> (pkg_get ()).name) |
3046 | |||
3047 | 22fe1c93 | ploc | let pkg_version = |
3048 | var_define |
||
3049 | ~short_desc:(fun () -> s_ "Package version") |
||
3050 | "pkg_version" |
||
3051 | 04e26a3f | xthirioux | (fun () -> |
3052 | 22fe1c93 | ploc | (OASISVersion.string_of_version (pkg_get ()).version)) |
3053 | 04e26a3f | xthirioux | |
3054 | let c = BaseOCamlcConfig.var_define |
||
3055 | |||
3056 | 22fe1c93 | ploc | let os_type = c "os_type" |
3057 | let system = c "system" |
||
3058 | let architecture = c "architecture" |
||
3059 | let ccomp_type = c "ccomp_type" |
||
3060 | let ocaml_version = c "ocaml_version" |
||
3061 | 04e26a3f | xthirioux | |
3062 | 22fe1c93 | ploc | (* TODO: Check standard variable presence at runtime *) |
3063 | 04e26a3f | xthirioux | |
3064 | 22fe1c93 | ploc | let standard_library_default = c "standard_library_default" |
3065 | let standard_library = c "standard_library" |
||
3066 | let standard_runtime = c "standard_runtime" |
||
3067 | let bytecomp_c_compiler = c "bytecomp_c_compiler" |
||
3068 | let native_c_compiler = c "native_c_compiler" |
||
3069 | let model = c "model" |
||
3070 | let ext_obj = c "ext_obj" |
||
3071 | let ext_asm = c "ext_asm" |
||
3072 | let ext_lib = c "ext_lib" |
||
3073 | let ext_dll = c "ext_dll" |
||
3074 | let default_executable_name = c "default_executable_name" |
||
3075 | let systhread_supported = c "systhread_supported" |
||
3076 | 04e26a3f | xthirioux | |
3077 | d1baac41 | xthirioux | let flexlink = |
3078 | 04e26a3f | xthirioux | BaseCheck.prog "flexlink" |
3079 | |||
3080 | let flexdll_version = |
||
3081 | var_define |
||
3082 | ~short_desc:(fun () -> "FlexDLL version (Win32)") |
||
3083 | "flexdll_version" |
||
3084 | (fun () -> |
||
3085 | d1baac41 | xthirioux | let lst = |
3086 | 04e26a3f | xthirioux | OASISExec.run_read_output ~ctxt:!BaseContext.default |
3087 | (flexlink ()) ["-help"] |
||
3088 | in |
||
3089 | d1baac41 | xthirioux | match lst with |
3090 | 04e26a3f | xthirioux | | line :: _ -> |
3091 | Scanf.sscanf line "FlexDLL version %s" (fun ver -> ver) |
||
3092 | | [] -> |
||
3093 | raise Not_found) |
||
3094 | |||
3095 | 22fe1c93 | ploc | (**/**) |
3096 | 04e26a3f | xthirioux | let p name hlp dflt = |
3097 | 22fe1c93 | ploc | var_define |
3098 | 04e26a3f | xthirioux | ~short_desc:hlp |
3099 | ~cli:CLIAuto |
||
3100 | ~arg_help:"dir" |
||
3101 | name |
||
3102 | dflt |
||
3103 | |||
3104 | let (/) a b = |
||
3105 | 22fe1c93 | ploc | if os_type () = Sys.os_type then |
3106 | 04e26a3f | xthirioux | Filename.concat a b |
3107 | 22fe1c93 | ploc | else if os_type () = "Unix" then |
3108 | 04e26a3f | xthirioux | OASISUnixPath.concat a b |
3109 | 22fe1c93 | ploc | else |
3110 | 04e26a3f | xthirioux | OASISUtils.failwithf (f_ "Cannot handle os_type %s filename concat") |
3111 | 22fe1c93 | ploc | (os_type ()) |
3112 | (**/**) |
||
3113 | 04e26a3f | xthirioux | |
3114 | let prefix = |
||
3115 | 22fe1c93 | ploc | p "prefix" |
3116 | (fun () -> s_ "Install architecture-independent files dir") |
||
3117 | 04e26a3f | xthirioux | (fun () -> |
3118 | match os_type () with |
||
3119 | | "Win32" -> |
||
3120 | let program_files = |
||
3121 | Sys.getenv "PROGRAMFILES" |
||
3122 | in |
||
3123 | program_files/(pkg_name ()) |
||
3124 | | _ -> |
||
3125 | "/usr/local") |
||
3126 | |||
3127 | let exec_prefix = |
||
3128 | 22fe1c93 | ploc | p "exec_prefix" |
3129 | (fun () -> s_ "Install architecture-dependent files in dir") |
||
3130 | 04e26a3f | xthirioux | (fun () -> "$prefix") |
3131 | |||
3132 | 22fe1c93 | ploc | let bindir = |
3133 | p "bindir" |
||
3134 | (fun () -> s_ "User executables") |
||
3135 | 04e26a3f | xthirioux | (fun () -> "$exec_prefix"/"bin") |
3136 | |||
3137 | 22fe1c93 | ploc | let sbindir = |
3138 | p "sbindir" |
||
3139 | (fun () -> s_ "System admin executables") |
||
3140 | 04e26a3f | xthirioux | (fun () -> "$exec_prefix"/"sbin") |
3141 | |||
3142 | 22fe1c93 | ploc | let libexecdir = |
3143 | p "libexecdir" |
||
3144 | (fun () -> s_ "Program executables") |
||
3145 | 04e26a3f | xthirioux | (fun () -> "$exec_prefix"/"libexec") |
3146 | |||
3147 | 22fe1c93 | ploc | let sysconfdir = |
3148 | p "sysconfdir" |
||
3149 | (fun () -> s_ "Read-only single-machine data") |
||
3150 | 04e26a3f | xthirioux | (fun () -> "$prefix"/"etc") |
3151 | |||
3152 | 22fe1c93 | ploc | let sharedstatedir = |
3153 | p "sharedstatedir" |
||
3154 | (fun () -> s_ "Modifiable architecture-independent data") |
||
3155 | 04e26a3f | xthirioux | (fun () -> "$prefix"/"com") |
3156 | |||
3157 | 22fe1c93 | ploc | let localstatedir = |
3158 | p "localstatedir" |
||
3159 | (fun () -> s_ "Modifiable single-machine data") |
||
3160 | 04e26a3f | xthirioux | (fun () -> "$prefix"/"var") |
3161 | |||
3162 | 22fe1c93 | ploc | let libdir = |
3163 | p "libdir" |
||
3164 | (fun () -> s_ "Object code libraries") |
||
3165 | 04e26a3f | xthirioux | (fun () -> "$exec_prefix"/"lib") |
3166 | |||
3167 | 22fe1c93 | ploc | let datarootdir = |
3168 | p "datarootdir" |
||
3169 | (fun () -> s_ "Read-only arch-independent data root") |
||
3170 | 04e26a3f | xthirioux | (fun () -> "$prefix"/"share") |
3171 | |||
3172 | 22fe1c93 | ploc | let datadir = |
3173 | p "datadir" |
||
3174 | (fun () -> s_ "Read-only architecture-independent data") |
||
3175 | 04e26a3f | xthirioux | (fun () -> "$datarootdir") |
3176 | |||
3177 | 22fe1c93 | ploc | let infodir = |
3178 | p "infodir" |
||
3179 | (fun () -> s_ "Info documentation") |
||
3180 | 04e26a3f | xthirioux | (fun () -> "$datarootdir"/"info") |
3181 | |||
3182 | 22fe1c93 | ploc | let localedir = |
3183 | p "localedir" |
||
3184 | (fun () -> s_ "Locale-dependent data") |
||
3185 | 04e26a3f | xthirioux | (fun () -> "$datarootdir"/"locale") |
3186 | |||
3187 | 22fe1c93 | ploc | let mandir = |
3188 | p "mandir" |
||
3189 | (fun () -> s_ "Man documentation") |
||
3190 | 04e26a3f | xthirioux | (fun () -> "$datarootdir"/"man") |
3191 | |||
3192 | 22fe1c93 | ploc | let docdir = |
3193 | p "docdir" |
||
3194 | (fun () -> s_ "Documentation root") |
||
3195 | 04e26a3f | xthirioux | (fun () -> "$datarootdir"/"doc"/"$pkg_name") |
3196 | |||
3197 | 22fe1c93 | ploc | let htmldir = |
3198 | p "htmldir" |
||
3199 | (fun () -> s_ "HTML documentation") |
||
3200 | 04e26a3f | xthirioux | (fun () -> "$docdir") |
3201 | |||
3202 | 22fe1c93 | ploc | let dvidir = |
3203 | p "dvidir" |
||
3204 | (fun () -> s_ "DVI documentation") |
||
3205 | 04e26a3f | xthirioux | (fun () -> "$docdir") |
3206 | |||
3207 | 22fe1c93 | ploc | let pdfdir = |
3208 | p "pdfdir" |
||
3209 |