PageRenderTime 115ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 1ms

/setup.ml

https://github.com/heidi-ann/ocaml-re
OCaml | 6112 lines | 5163 code | 681 blank | 268 comment | 214 complexity | 819dd0d65f23b880bfc9d345798d7118 MD5 | raw file
Possible License(s): LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. (* setup.ml generated for the first time by OASIS v0.2.1~alpha1 *)
  2. (* OASIS_START *)
  3. (* DO NOT EDIT (digest: eccd7b71565885073005f0f309bb6a8a) *)
  4. (*
  5. Regenerated by OASIS v0.3.0
  6. Visit http://oasis.forge.ocamlcore.org for more information and
  7. documentation about functions used in this file.
  8. *)
  9. module OASISGettext = struct
  10. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISGettext.ml" *)
  11. let ns_ str =
  12. str
  13. let s_ str =
  14. str
  15. let f_ (str : ('a, 'b, 'c, 'd) format4) =
  16. str
  17. let fn_ fmt1 fmt2 n =
  18. if n = 1 then
  19. fmt1^^""
  20. else
  21. fmt2^^""
  22. let init =
  23. []
  24. end
  25. module OASISContext = struct
  26. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISContext.ml" *)
  27. open OASISGettext
  28. type level =
  29. [ `Debug
  30. | `Info
  31. | `Warning
  32. | `Error]
  33. type t =
  34. {
  35. quiet: bool;
  36. info: bool;
  37. debug: bool;
  38. ignore_plugins: bool;
  39. ignore_unknown_fields: bool;
  40. printf: level -> string -> unit;
  41. }
  42. let printf lvl str =
  43. let beg =
  44. match lvl with
  45. | `Error -> s_ "E: "
  46. | `Warning -> s_ "W: "
  47. | `Info -> s_ "I: "
  48. | `Debug -> s_ "D: "
  49. in
  50. prerr_endline (beg^str)
  51. let default =
  52. ref
  53. {
  54. quiet = false;
  55. info = false;
  56. debug = false;
  57. ignore_plugins = false;
  58. ignore_unknown_fields = false;
  59. printf = printf;
  60. }
  61. let quiet =
  62. {!default with quiet = true}
  63. let args () =
  64. ["-quiet",
  65. Arg.Unit (fun () -> default := {!default with quiet = true}),
  66. (s_ " Run quietly");
  67. "-info",
  68. Arg.Unit (fun () -> default := {!default with info = true}),
  69. (s_ " Display information message");
  70. "-debug",
  71. Arg.Unit (fun () -> default := {!default with debug = true}),
  72. (s_ " Output debug message")]
  73. end
  74. module OASISString = struct
  75. (* # 1 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISString.ml" *)
  76. (** Various string utilities.
  77. Mostly inspired by extlib and batteries ExtString and BatString libraries.
  78. @author Sylvain Le Gall
  79. *)
  80. let nsplitf str f =
  81. if str = "" then
  82. []
  83. else
  84. let buf = Buffer.create 13 in
  85. let lst = ref [] in
  86. let push () =
  87. lst := Buffer.contents buf :: !lst;
  88. Buffer.clear buf
  89. in
  90. let str_len = String.length str in
  91. for i = 0 to str_len - 1 do
  92. if f str.[i] then
  93. push ()
  94. else
  95. Buffer.add_char buf str.[i]
  96. done;
  97. push ();
  98. List.rev !lst
  99. (** [nsplit c s] Split the string [s] at char [c]. It doesn't include the
  100. separator.
  101. *)
  102. let nsplit str c =
  103. nsplitf str ((=) c)
  104. let find ~what ?(offset=0) str =
  105. let what_idx = ref 0 in
  106. let str_idx = ref offset in
  107. while !str_idx < String.length str &&
  108. !what_idx < String.length what do
  109. if str.[!str_idx] = what.[!what_idx] then
  110. incr what_idx
  111. else
  112. what_idx := 0;
  113. incr str_idx
  114. done;
  115. if !what_idx <> String.length what then
  116. raise Not_found
  117. else
  118. !str_idx - !what_idx
  119. let sub_start str len =
  120. let str_len = String.length str in
  121. if len >= str_len then
  122. ""
  123. else
  124. String.sub str len (str_len - len)
  125. let sub_end ?(offset=0) str len =
  126. let str_len = String.length str in
  127. if len >= str_len then
  128. ""
  129. else
  130. String.sub str 0 (str_len - len)
  131. let starts_with ~what ?(offset=0) str =
  132. let what_idx = ref 0 in
  133. let str_idx = ref offset in
  134. let ok = ref true in
  135. while !ok &&
  136. !str_idx < String.length str &&
  137. !what_idx < String.length what do
  138. if str.[!str_idx] = what.[!what_idx] then
  139. incr what_idx
  140. else
  141. ok := false;
  142. incr str_idx
  143. done;
  144. if !what_idx = String.length what then
  145. true
  146. else
  147. false
  148. let strip_starts_with ~what str =
  149. if starts_with ~what str then
  150. sub_start str (String.length what)
  151. else
  152. raise Not_found
  153. let ends_with ~what ?(offset=0) str =
  154. let what_idx = ref ((String.length what) - 1) in
  155. let str_idx = ref ((String.length str) - 1) in
  156. let ok = ref true in
  157. while !ok &&
  158. offset <= !str_idx &&
  159. 0 <= !what_idx do
  160. if str.[!str_idx] = what.[!what_idx] then
  161. decr what_idx
  162. else
  163. ok := false;
  164. decr str_idx
  165. done;
  166. if !what_idx = -1 then
  167. true
  168. else
  169. false
  170. let strip_ends_with ~what str =
  171. if ends_with ~what str then
  172. sub_end str (String.length what)
  173. else
  174. raise Not_found
  175. let replace_chars f s =
  176. let buf = String.make (String.length s) 'X' in
  177. for i = 0 to String.length s - 1 do
  178. buf.[i] <- f s.[i]
  179. done;
  180. buf
  181. end
  182. module OASISUtils = struct
  183. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISUtils.ml" *)
  184. open OASISGettext
  185. module MapString = Map.Make(String)
  186. let map_string_of_assoc assoc =
  187. List.fold_left
  188. (fun acc (k, v) -> MapString.add k v acc)
  189. MapString.empty
  190. assoc
  191. module SetString = Set.Make(String)
  192. let set_string_add_list st lst =
  193. List.fold_left
  194. (fun acc e -> SetString.add e acc)
  195. st
  196. lst
  197. let set_string_of_list =
  198. set_string_add_list
  199. SetString.empty
  200. let compare_csl s1 s2 =
  201. String.compare (String.lowercase s1) (String.lowercase s2)
  202. module HashStringCsl =
  203. Hashtbl.Make
  204. (struct
  205. type t = string
  206. let equal s1 s2 =
  207. (String.lowercase s1) = (String.lowercase s2)
  208. let hash s =
  209. Hashtbl.hash (String.lowercase s)
  210. end)
  211. let varname_of_string ?(hyphen='_') s =
  212. if String.length s = 0 then
  213. begin
  214. invalid_arg "varname_of_string"
  215. end
  216. else
  217. begin
  218. let buf =
  219. OASISString.replace_chars
  220. (fun c ->
  221. if ('a' <= c && c <= 'z')
  222. ||
  223. ('A' <= c && c <= 'Z')
  224. ||
  225. ('0' <= c && c <= '9') then
  226. c
  227. else
  228. hyphen)
  229. s;
  230. in
  231. let buf =
  232. (* Start with a _ if digit *)
  233. if '0' <= s.[0] && s.[0] <= '9' then
  234. "_"^buf
  235. else
  236. buf
  237. in
  238. String.lowercase buf
  239. end
  240. let varname_concat ?(hyphen='_') p s =
  241. let what = String.make 1 hyphen in
  242. let p =
  243. try
  244. OASISString.strip_ends_with ~what p
  245. with Not_found ->
  246. p
  247. in
  248. let s =
  249. try
  250. OASISString.strip_starts_with ~what s
  251. with Not_found ->
  252. s
  253. in
  254. p^what^s
  255. let is_varname str =
  256. str = varname_of_string str
  257. let failwithf fmt = Printf.ksprintf failwith fmt
  258. end
  259. module PropList = struct
  260. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/PropList.ml" *)
  261. open OASISGettext
  262. type name = string
  263. exception Not_set of name * string option
  264. exception No_printer of name
  265. exception Unknown_field of name * name
  266. let () =
  267. Printexc.register_printer
  268. (function
  269. | Not_set (nm, Some rsn) ->
  270. Some
  271. (Printf.sprintf (f_ "Field '%s' is not set: %s") nm rsn)
  272. | Not_set (nm, None) ->
  273. Some
  274. (Printf.sprintf (f_ "Field '%s' is not set") nm)
  275. | No_printer nm ->
  276. Some
  277. (Printf.sprintf (f_ "No default printer for value %s") nm)
  278. | Unknown_field (nm, schm) ->
  279. Some
  280. (Printf.sprintf (f_ "Field %s is not defined in schema %s") nm schm)
  281. | _ ->
  282. None)
  283. module Data =
  284. struct
  285. type t =
  286. (name, unit -> unit) Hashtbl.t
  287. let create () =
  288. Hashtbl.create 13
  289. let clear t =
  290. Hashtbl.clear t
  291. (* # 71 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/PropList.ml" *)
  292. end
  293. module Schema =
  294. struct
  295. type ('ctxt, 'extra) value =
  296. {
  297. get: Data.t -> string;
  298. set: Data.t -> ?context:'ctxt -> string -> unit;
  299. help: (unit -> string) option;
  300. extra: 'extra;
  301. }
  302. type ('ctxt, 'extra) t =
  303. {
  304. name: name;
  305. fields: (name, ('ctxt, 'extra) value) Hashtbl.t;
  306. order: name Queue.t;
  307. name_norm: string -> string;
  308. }
  309. let create ?(case_insensitive=false) nm =
  310. {
  311. name = nm;
  312. fields = Hashtbl.create 13;
  313. order = Queue.create ();
  314. name_norm =
  315. (if case_insensitive then
  316. String.lowercase
  317. else
  318. fun s -> s);
  319. }
  320. let add t nm set get extra help =
  321. let key =
  322. t.name_norm nm
  323. in
  324. if Hashtbl.mem t.fields key then
  325. failwith
  326. (Printf.sprintf
  327. (f_ "Field '%s' is already defined in schema '%s'")
  328. nm t.name);
  329. Hashtbl.add
  330. t.fields
  331. key
  332. {
  333. set = set;
  334. get = get;
  335. help = help;
  336. extra = extra;
  337. };
  338. Queue.add nm t.order
  339. let mem t nm =
  340. Hashtbl.mem t.fields nm
  341. let find t nm =
  342. try
  343. Hashtbl.find t.fields (t.name_norm nm)
  344. with Not_found ->
  345. raise (Unknown_field (nm, t.name))
  346. let get t data nm =
  347. (find t nm).get data
  348. let set t data nm ?context x =
  349. (find t nm).set
  350. data
  351. ?context
  352. x
  353. let fold f acc t =
  354. Queue.fold
  355. (fun acc k ->
  356. let v =
  357. find t k
  358. in
  359. f acc k v.extra v.help)
  360. acc
  361. t.order
  362. let iter f t =
  363. fold
  364. (fun () -> f)
  365. ()
  366. t
  367. let name t =
  368. t.name
  369. end
  370. module Field =
  371. struct
  372. type ('ctxt, 'value, 'extra) t =
  373. {
  374. set: Data.t -> ?context:'ctxt -> 'value -> unit;
  375. get: Data.t -> 'value;
  376. sets: Data.t -> ?context:'ctxt -> string -> unit;
  377. gets: Data.t -> string;
  378. help: (unit -> string) option;
  379. extra: 'extra;
  380. }
  381. let new_id =
  382. let last_id =
  383. ref 0
  384. in
  385. fun () -> incr last_id; !last_id
  386. let create ?schema ?name ?parse ?print ?default ?update ?help extra =
  387. (* Default value container *)
  388. let v =
  389. ref None
  390. in
  391. (* If name is not given, create unique one *)
  392. let nm =
  393. match name with
  394. | Some s -> s
  395. | None -> Printf.sprintf "_anon_%d" (new_id ())
  396. in
  397. (* Last chance to get a value: the default *)
  398. let default () =
  399. match default with
  400. | Some d -> d
  401. | None -> raise (Not_set (nm, Some (s_ "no default value")))
  402. in
  403. (* Get data *)
  404. let get data =
  405. (* Get value *)
  406. try
  407. (Hashtbl.find data nm) ();
  408. match !v with
  409. | Some x -> x
  410. | None -> default ()
  411. with Not_found ->
  412. default ()
  413. in
  414. (* Set data *)
  415. let set data ?context x =
  416. let x =
  417. match update with
  418. | Some f ->
  419. begin
  420. try
  421. f ?context (get data) x
  422. with Not_set _ ->
  423. x
  424. end
  425. | None ->
  426. x
  427. in
  428. Hashtbl.replace
  429. data
  430. nm
  431. (fun () -> v := Some x)
  432. in
  433. (* Parse string value, if possible *)
  434. let parse =
  435. match parse with
  436. | Some f ->
  437. f
  438. | None ->
  439. fun ?context s ->
  440. failwith
  441. (Printf.sprintf
  442. (f_ "Cannot parse field '%s' when setting value %S")
  443. nm
  444. s)
  445. in
  446. (* Set data, from string *)
  447. let sets data ?context s =
  448. set ?context data (parse ?context s)
  449. in
  450. (* Output value as string, if possible *)
  451. let print =
  452. match print with
  453. | Some f ->
  454. f
  455. | None ->
  456. fun _ -> raise (No_printer nm)
  457. in
  458. (* Get data, as a string *)
  459. let gets data =
  460. print (get data)
  461. in
  462. begin
  463. match schema with
  464. | Some t ->
  465. Schema.add t nm sets gets extra help
  466. | None ->
  467. ()
  468. end;
  469. {
  470. set = set;
  471. get = get;
  472. sets = sets;
  473. gets = gets;
  474. help = help;
  475. extra = extra;
  476. }
  477. let fset data t ?context x =
  478. t.set data ?context x
  479. let fget data t =
  480. t.get data
  481. let fsets data t ?context s =
  482. t.sets data ?context s
  483. let fgets data t =
  484. t.gets data
  485. end
  486. module FieldRO =
  487. struct
  488. let create ?schema ?name ?parse ?print ?default ?update ?help extra =
  489. let fld =
  490. Field.create ?schema ?name ?parse ?print ?default ?update ?help extra
  491. in
  492. fun data -> Field.fget data fld
  493. end
  494. end
  495. module OASISMessage = struct
  496. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISMessage.ml" *)
  497. open OASISGettext
  498. open OASISContext
  499. let generic_message ~ctxt lvl fmt =
  500. let cond =
  501. if ctxt.quiet then
  502. false
  503. else
  504. match lvl with
  505. | `Debug -> ctxt.debug
  506. | `Info -> ctxt.info
  507. | _ -> true
  508. in
  509. Printf.ksprintf
  510. (fun str ->
  511. if cond then
  512. begin
  513. ctxt.printf lvl str
  514. end)
  515. fmt
  516. let debug ~ctxt fmt =
  517. generic_message ~ctxt `Debug fmt
  518. let info ~ctxt fmt =
  519. generic_message ~ctxt `Info fmt
  520. let warning ~ctxt fmt =
  521. generic_message ~ctxt `Warning fmt
  522. let error ~ctxt fmt =
  523. generic_message ~ctxt `Error fmt
  524. end
  525. module OASISVersion = struct
  526. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISVersion.ml" *)
  527. open OASISGettext
  528. type s = string
  529. type t = string
  530. type comparator =
  531. | VGreater of t
  532. | VGreaterEqual of t
  533. | VEqual of t
  534. | VLesser of t
  535. | VLesserEqual of t
  536. | VOr of comparator * comparator
  537. | VAnd of comparator * comparator
  538. (* Range of allowed characters *)
  539. let is_digit c =
  540. '0' <= c && c <= '9'
  541. let is_alpha c =
  542. ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
  543. let is_special =
  544. function
  545. | '.' | '+' | '-' | '~' -> true
  546. | _ -> false
  547. let rec version_compare v1 v2 =
  548. if v1 <> "" || v2 <> "" then
  549. begin
  550. (* Compare ascii string, using special meaning for version
  551. * related char
  552. *)
  553. let val_ascii c =
  554. if c = '~' then -1
  555. else if is_digit c then 0
  556. else if c = '\000' then 0
  557. else if is_alpha c then Char.code c
  558. else (Char.code c) + 256
  559. in
  560. let len1 = String.length v1 in
  561. let len2 = String.length v2 in
  562. let p = ref 0 in
  563. (** Compare ascii part *)
  564. let compare_vascii () =
  565. let cmp = ref 0 in
  566. while !cmp = 0 &&
  567. !p < len1 && !p < len2 &&
  568. not (is_digit v1.[!p] && is_digit v2.[!p]) do
  569. cmp := (val_ascii v1.[!p]) - (val_ascii v2.[!p]);
  570. incr p
  571. done;
  572. if !cmp = 0 && !p < len1 && !p = len2 then
  573. val_ascii v1.[!p]
  574. else if !cmp = 0 && !p = len1 && !p < len2 then
  575. - (val_ascii v2.[!p])
  576. else
  577. !cmp
  578. in
  579. (** Compare digit part *)
  580. let compare_digit () =
  581. let extract_int v p =
  582. let start_p = !p in
  583. while !p < String.length v && is_digit v.[!p] do
  584. incr p
  585. done;
  586. let substr =
  587. String.sub v !p ((String.length v) - !p)
  588. in
  589. let res =
  590. match String.sub v start_p (!p - start_p) with
  591. | "" -> 0
  592. | s -> int_of_string s
  593. in
  594. res, substr
  595. in
  596. let i1, tl1 = extract_int v1 (ref !p) in
  597. let i2, tl2 = extract_int v2 (ref !p) in
  598. i1 - i2, tl1, tl2
  599. in
  600. match compare_vascii () with
  601. | 0 ->
  602. begin
  603. match compare_digit () with
  604. | 0, tl1, tl2 ->
  605. if tl1 <> "" && is_digit tl1.[0] then
  606. 1
  607. else if tl2 <> "" && is_digit tl2.[0] then
  608. -1
  609. else
  610. version_compare tl1 tl2
  611. | n, _, _ ->
  612. n
  613. end
  614. | n ->
  615. n
  616. end
  617. else
  618. begin
  619. 0
  620. end
  621. let version_of_string str = str
  622. let string_of_version t = t
  623. let chop t =
  624. try
  625. let pos =
  626. String.rindex t '.'
  627. in
  628. String.sub t 0 pos
  629. with Not_found ->
  630. t
  631. let rec comparator_apply v op =
  632. match op with
  633. | VGreater cv ->
  634. (version_compare v cv) > 0
  635. | VGreaterEqual cv ->
  636. (version_compare v cv) >= 0
  637. | VLesser cv ->
  638. (version_compare v cv) < 0
  639. | VLesserEqual cv ->
  640. (version_compare v cv) <= 0
  641. | VEqual cv ->
  642. (version_compare v cv) = 0
  643. | VOr (op1, op2) ->
  644. (comparator_apply v op1) || (comparator_apply v op2)
  645. | VAnd (op1, op2) ->
  646. (comparator_apply v op1) && (comparator_apply v op2)
  647. let rec string_of_comparator =
  648. function
  649. | VGreater v -> "> "^(string_of_version v)
  650. | VEqual v -> "= "^(string_of_version v)
  651. | VLesser v -> "< "^(string_of_version v)
  652. | VGreaterEqual v -> ">= "^(string_of_version v)
  653. | VLesserEqual v -> "<= "^(string_of_version v)
  654. | VOr (c1, c2) ->
  655. (string_of_comparator c1)^" || "^(string_of_comparator c2)
  656. | VAnd (c1, c2) ->
  657. (string_of_comparator c1)^" && "^(string_of_comparator c2)
  658. let rec varname_of_comparator =
  659. let concat p v =
  660. OASISUtils.varname_concat
  661. p
  662. (OASISUtils.varname_of_string
  663. (string_of_version v))
  664. in
  665. function
  666. | VGreater v -> concat "gt" v
  667. | VLesser v -> concat "lt" v
  668. | VEqual v -> concat "eq" v
  669. | VGreaterEqual v -> concat "ge" v
  670. | VLesserEqual v -> concat "le" v
  671. | VOr (c1, c2) ->
  672. (varname_of_comparator c1)^"_or_"^(varname_of_comparator c2)
  673. | VAnd (c1, c2) ->
  674. (varname_of_comparator c1)^"_and_"^(varname_of_comparator c2)
  675. let version_0_3_or_after t =
  676. comparator_apply t (VGreaterEqual (string_of_version "0.3"))
  677. end
  678. module OASISLicense = struct
  679. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISLicense.ml" *)
  680. (** License for _oasis fields
  681. @author Sylvain Le Gall
  682. *)
  683. type license = string
  684. type license_exception = string
  685. type license_version =
  686. | Version of OASISVersion.t
  687. | VersionOrLater of OASISVersion.t
  688. | NoVersion
  689. type license_dep_5_unit =
  690. {
  691. license: license;
  692. excption: license_exception option;
  693. version: license_version;
  694. }
  695. type license_dep_5 =
  696. | DEP5Unit of license_dep_5_unit
  697. | DEP5Or of license_dep_5 list
  698. | DEP5And of license_dep_5 list
  699. type t =
  700. | DEP5License of license_dep_5
  701. | OtherLicense of string (* URL *)
  702. end
  703. module OASISExpr = struct
  704. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISExpr.ml" *)
  705. open OASISGettext
  706. type test = string
  707. type flag = string
  708. type t =
  709. | EBool of bool
  710. | ENot of t
  711. | EAnd of t * t
  712. | EOr of t * t
  713. | EFlag of flag
  714. | ETest of test * string
  715. type 'a choices = (t * 'a) list
  716. let eval var_get t =
  717. let rec eval' =
  718. function
  719. | EBool b ->
  720. b
  721. | ENot e ->
  722. not (eval' e)
  723. | EAnd (e1, e2) ->
  724. (eval' e1) && (eval' e2)
  725. | EOr (e1, e2) ->
  726. (eval' e1) || (eval' e2)
  727. | EFlag nm ->
  728. let v =
  729. var_get nm
  730. in
  731. assert(v = "true" || v = "false");
  732. (v = "true")
  733. | ETest (nm, vl) ->
  734. let v =
  735. var_get nm
  736. in
  737. (v = vl)
  738. in
  739. eval' t
  740. let choose ?printer ?name var_get lst =
  741. let rec choose_aux =
  742. function
  743. | (cond, vl) :: tl ->
  744. if eval var_get cond then
  745. vl
  746. else
  747. choose_aux tl
  748. | [] ->
  749. let str_lst =
  750. if lst = [] then
  751. s_ "<empty>"
  752. else
  753. String.concat
  754. (s_ ", ")
  755. (List.map
  756. (fun (cond, vl) ->
  757. match printer with
  758. | Some p -> p vl
  759. | None -> s_ "<no printer>")
  760. lst)
  761. in
  762. match name with
  763. | Some nm ->
  764. failwith
  765. (Printf.sprintf
  766. (f_ "No result for the choice list '%s': %s")
  767. nm str_lst)
  768. | None ->
  769. failwith
  770. (Printf.sprintf
  771. (f_ "No result for a choice list: %s")
  772. str_lst)
  773. in
  774. choose_aux (List.rev lst)
  775. end
  776. module OASISTypes = struct
  777. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISTypes.ml" *)
  778. type name = string
  779. type package_name = string
  780. type url = string
  781. type unix_dirname = string
  782. type unix_filename = string
  783. type host_dirname = string
  784. type host_filename = string
  785. type prog = string
  786. type arg = string
  787. type args = string list
  788. type command_line = (prog * arg list)
  789. type findlib_name = string
  790. type findlib_full = string
  791. type compiled_object =
  792. | Byte
  793. | Native
  794. | Best
  795. type dependency =
  796. | FindlibPackage of findlib_full * OASISVersion.comparator option
  797. | InternalLibrary of name
  798. type tool =
  799. | ExternalTool of name
  800. | InternalExecutable of name
  801. type vcs =
  802. | Darcs
  803. | Git
  804. | Svn
  805. | Cvs
  806. | Hg
  807. | Bzr
  808. | Arch
  809. | Monotone
  810. | OtherVCS of url
  811. type plugin_kind =
  812. [ `Configure
  813. | `Build
  814. | `Doc
  815. | `Test
  816. | `Install
  817. | `Extra
  818. ]
  819. type plugin_data_purpose =
  820. [ `Configure
  821. | `Build
  822. | `Install
  823. | `Clean
  824. | `Distclean
  825. | `Install
  826. | `Uninstall
  827. | `Test
  828. | `Doc
  829. | `Extra
  830. | `Other of string
  831. ]
  832. type 'a plugin = 'a * name * OASISVersion.t option
  833. type all_plugin = plugin_kind plugin
  834. type plugin_data = (all_plugin * plugin_data_purpose * (unit -> unit)) list
  835. (* # 102 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISTypes.ml" *)
  836. type 'a conditional = 'a OASISExpr.choices
  837. type custom =
  838. {
  839. pre_command: (command_line option) conditional;
  840. post_command: (command_line option) conditional;
  841. }
  842. type common_section =
  843. {
  844. cs_name: name;
  845. cs_data: PropList.Data.t;
  846. cs_plugin_data: plugin_data;
  847. }
  848. type build_section =
  849. {
  850. bs_build: bool conditional;
  851. bs_install: bool conditional;
  852. bs_path: unix_dirname;
  853. bs_compiled_object: compiled_object;
  854. bs_build_depends: dependency list;
  855. bs_build_tools: tool list;
  856. bs_c_sources: unix_filename list;
  857. bs_data_files: (unix_filename * unix_filename option) list;
  858. bs_ccopt: args conditional;
  859. bs_cclib: args conditional;
  860. bs_dlllib: args conditional;
  861. bs_dllpath: args conditional;
  862. bs_byteopt: args conditional;
  863. bs_nativeopt: args conditional;
  864. }
  865. type library =
  866. {
  867. lib_modules: string list;
  868. lib_pack: bool;
  869. lib_internal_modules: string list;
  870. lib_findlib_parent: findlib_name option;
  871. lib_findlib_name: findlib_name option;
  872. lib_findlib_containers: findlib_name list;
  873. }
  874. type executable =
  875. {
  876. exec_custom: bool;
  877. exec_main_is: unix_filename;
  878. }
  879. type flag =
  880. {
  881. flag_description: string option;
  882. flag_default: bool conditional;
  883. }
  884. type source_repository =
  885. {
  886. src_repo_type: vcs;
  887. src_repo_location: url;
  888. src_repo_browser: url option;
  889. src_repo_module: string option;
  890. src_repo_branch: string option;
  891. src_repo_tag: string option;
  892. src_repo_subdir: unix_filename option;
  893. }
  894. type test =
  895. {
  896. test_type: [`Test] plugin;
  897. test_command: command_line conditional;
  898. test_custom: custom;
  899. test_working_directory: unix_filename option;
  900. test_run: bool conditional;
  901. test_tools: tool list;
  902. }
  903. type doc_format =
  904. | HTML of unix_filename
  905. | DocText
  906. | PDF
  907. | PostScript
  908. | Info of unix_filename
  909. | DVI
  910. | OtherDoc
  911. type doc =
  912. {
  913. doc_type: [`Doc] plugin;
  914. doc_custom: custom;
  915. doc_build: bool conditional;
  916. doc_install: bool conditional;
  917. doc_install_dir: unix_filename;
  918. doc_title: string;
  919. doc_authors: string list;
  920. doc_abstract: string option;
  921. doc_format: doc_format;
  922. doc_data_files: (unix_filename * unix_filename option) list;
  923. doc_build_tools: tool list;
  924. }
  925. type section =
  926. | Library of common_section * build_section * library
  927. | Executable of common_section * build_section * executable
  928. | Flag of common_section * flag
  929. | SrcRepo of common_section * source_repository
  930. | Test of common_section * test
  931. | Doc of common_section * doc
  932. type section_kind =
  933. [ `Library | `Executable | `Flag | `SrcRepo | `Test | `Doc ]
  934. type package =
  935. {
  936. oasis_version: OASISVersion.t;
  937. ocaml_version: OASISVersion.comparator option;
  938. findlib_version: OASISVersion.comparator option;
  939. name: package_name;
  940. version: OASISVersion.t;
  941. license: OASISLicense.t;
  942. license_file: unix_filename option;
  943. copyrights: string list;
  944. maintainers: string list;
  945. authors: string list;
  946. homepage: url option;
  947. synopsis: string;
  948. description: string option;
  949. categories: url list;
  950. conf_type: [`Configure] plugin;
  951. conf_custom: custom;
  952. build_type: [`Build] plugin;
  953. build_custom: custom;
  954. install_type: [`Install] plugin;
  955. install_custom: custom;
  956. uninstall_custom: custom;
  957. clean_custom: custom;
  958. distclean_custom: custom;
  959. files_ab: unix_filename list;
  960. sections: section list;
  961. plugins: [`Extra] plugin list;
  962. schema_data: PropList.Data.t;
  963. plugin_data: plugin_data;
  964. }
  965. end
  966. module OASISUnixPath = struct
  967. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISUnixPath.ml" *)
  968. type unix_filename = string
  969. type unix_dirname = string
  970. type host_filename = string
  971. type host_dirname = string
  972. let current_dir_name = "."
  973. let parent_dir_name = ".."
  974. let is_current_dir fn =
  975. fn = current_dir_name || fn = ""
  976. let concat f1 f2 =
  977. if is_current_dir f1 then
  978. f2
  979. else
  980. let f1' =
  981. try OASISString.strip_ends_with ~what:"/" f1 with Not_found -> f1
  982. in
  983. f1'^"/"^f2
  984. let make =
  985. function
  986. | hd :: tl ->
  987. List.fold_left
  988. (fun f p -> concat f p)
  989. hd
  990. tl
  991. | [] ->
  992. invalid_arg "OASISUnixPath.make"
  993. let dirname f =
  994. try
  995. String.sub f 0 (String.rindex f '/')
  996. with Not_found ->
  997. current_dir_name
  998. let basename f =
  999. try
  1000. let pos_start =
  1001. (String.rindex f '/') + 1
  1002. in
  1003. String.sub f pos_start ((String.length f) - pos_start)
  1004. with Not_found ->
  1005. f
  1006. let chop_extension f =
  1007. try
  1008. let last_dot =
  1009. String.rindex f '.'
  1010. in
  1011. let sub =
  1012. String.sub f 0 last_dot
  1013. in
  1014. try
  1015. let last_slash =
  1016. String.rindex f '/'
  1017. in
  1018. if last_slash < last_dot then
  1019. sub
  1020. else
  1021. f
  1022. with Not_found ->
  1023. sub
  1024. with Not_found ->
  1025. f
  1026. let capitalize_file f =
  1027. let dir = dirname f in
  1028. let base = basename f in
  1029. concat dir (String.capitalize base)
  1030. let uncapitalize_file f =
  1031. let dir = dirname f in
  1032. let base = basename f in
  1033. concat dir (String.uncapitalize base)
  1034. end
  1035. module OASISHostPath = struct
  1036. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISHostPath.ml" *)
  1037. open Filename
  1038. module Unix = OASISUnixPath
  1039. let make =
  1040. function
  1041. | [] ->
  1042. invalid_arg "OASISHostPath.make"
  1043. | hd :: tl ->
  1044. List.fold_left Filename.concat hd tl
  1045. let of_unix ufn =
  1046. if Sys.os_type = "Unix" then
  1047. ufn
  1048. else
  1049. make
  1050. (List.map
  1051. (fun p ->
  1052. if p = Unix.current_dir_name then
  1053. current_dir_name
  1054. else if p = Unix.parent_dir_name then
  1055. parent_dir_name
  1056. else
  1057. p)
  1058. (OASISString.nsplit ufn '/'))
  1059. end
  1060. module OASISSection = struct
  1061. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISSection.ml" *)
  1062. open OASISTypes
  1063. let section_kind_common =
  1064. function
  1065. | Library (cs, _, _) ->
  1066. `Library, cs
  1067. | Executable (cs, _, _) ->
  1068. `Executable, cs
  1069. | Flag (cs, _) ->
  1070. `Flag, cs
  1071. | SrcRepo (cs, _) ->
  1072. `SrcRepo, cs
  1073. | Test (cs, _) ->
  1074. `Test, cs
  1075. | Doc (cs, _) ->
  1076. `Doc, cs
  1077. let section_common sct =
  1078. snd (section_kind_common sct)
  1079. let section_common_set cs =
  1080. function
  1081. | Library (_, bs, lib) -> Library (cs, bs, lib)
  1082. | Executable (_, bs, exec) -> Executable (cs, bs, exec)
  1083. | Flag (_, flg) -> Flag (cs, flg)
  1084. | SrcRepo (_, src_repo) -> SrcRepo (cs, src_repo)
  1085. | Test (_, tst) -> Test (cs, tst)
  1086. | Doc (_, doc) -> Doc (cs, doc)
  1087. (** Key used to identify section
  1088. *)
  1089. let section_id sct =
  1090. let k, cs =
  1091. section_kind_common sct
  1092. in
  1093. k, cs.cs_name
  1094. let string_of_section sct =
  1095. let k, nm =
  1096. section_id sct
  1097. in
  1098. (match k with
  1099. | `Library -> "library"
  1100. | `Executable -> "executable"
  1101. | `Flag -> "flag"
  1102. | `SrcRepo -> "src repository"
  1103. | `Test -> "test"
  1104. | `Doc -> "doc")
  1105. ^" "^nm
  1106. let section_find id scts =
  1107. List.find
  1108. (fun sct -> id = section_id sct)
  1109. scts
  1110. module CSection =
  1111. struct
  1112. type t = section
  1113. let id = section_id
  1114. let compare t1 t2 =
  1115. compare (id t1) (id t2)
  1116. let equal t1 t2 =
  1117. (id t1) = (id t2)
  1118. let hash t =
  1119. Hashtbl.hash (id t)
  1120. end
  1121. module MapSection = Map.Make(CSection)
  1122. module SetSection = Set.Make(CSection)
  1123. end
  1124. module OASISBuildSection = struct
  1125. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISBuildSection.ml" *)
  1126. end
  1127. module OASISExecutable = struct
  1128. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISExecutable.ml" *)
  1129. open OASISTypes
  1130. let unix_exec_is (cs, bs, exec) is_native ext_dll suffix_program =
  1131. let dir =
  1132. OASISUnixPath.concat
  1133. bs.bs_path
  1134. (OASISUnixPath.dirname exec.exec_main_is)
  1135. in
  1136. let is_native_exec =
  1137. match bs.bs_compiled_object with
  1138. | Native -> true
  1139. | Best -> is_native ()
  1140. | Byte -> false
  1141. in
  1142. OASISUnixPath.concat
  1143. dir
  1144. (cs.cs_name^(suffix_program ())),
  1145. if not is_native_exec &&
  1146. not exec.exec_custom &&
  1147. bs.bs_c_sources <> [] then
  1148. Some (dir^"/dll"^cs.cs_name^"_stubs"^(ext_dll ()))
  1149. else
  1150. None
  1151. end
  1152. module OASISLibrary = struct
  1153. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISLibrary.ml" *)
  1154. open OASISTypes
  1155. open OASISUtils
  1156. open OASISGettext
  1157. open OASISSection
  1158. type library_name = name
  1159. type findlib_part_name = name
  1160. type 'a map_of_findlib_part_name = 'a OASISUtils.MapString.t
  1161. exception InternalLibraryNotFound of library_name
  1162. exception FindlibPackageNotFound of findlib_name
  1163. type group_t =
  1164. | Container of findlib_name * group_t list
  1165. | Package of (findlib_name *
  1166. common_section *
  1167. build_section *
  1168. library *
  1169. group_t list)
  1170. (* Look for a module file, considering capitalization or not. *)
  1171. let find_module source_file_exists (cs, bs, lib) modul =
  1172. let possible_base_fn =
  1173. List.map
  1174. (OASISUnixPath.concat bs.bs_path)
  1175. [modul;
  1176. OASISUnixPath.uncapitalize_file modul;
  1177. OASISUnixPath.capitalize_file modul]
  1178. in
  1179. (* TODO: we should be able to be able to determine the source for every
  1180. * files. Hence we should introduce a Module(source: fn) for the fields
  1181. * Modules and InternalModules
  1182. *)
  1183. List.fold_left
  1184. (fun acc base_fn ->
  1185. match acc with
  1186. | `No_sources _ ->
  1187. begin
  1188. let file_found =
  1189. List.fold_left
  1190. (fun acc ext ->
  1191. if source_file_exists (base_fn^ext) then
  1192. (base_fn^ext) :: acc
  1193. else
  1194. acc)
  1195. []
  1196. [".ml"; ".mli"; ".mll"; ".mly"]
  1197. in
  1198. match file_found with
  1199. | [] ->
  1200. acc
  1201. | lst ->
  1202. `Sources (base_fn, lst)
  1203. end
  1204. | `Sources _ ->
  1205. acc)
  1206. (`No_sources possible_base_fn)
  1207. possible_base_fn
  1208. let source_unix_files ~ctxt (cs, bs, lib) source_file_exists =
  1209. List.fold_left
  1210. (fun acc modul ->
  1211. match find_module source_file_exists (cs, bs, lib) modul with
  1212. | `Sources (base_fn, lst) ->
  1213. (base_fn, lst) :: acc
  1214. | `No_sources _ ->
  1215. OASISMessage.warning
  1216. ~ctxt
  1217. (f_ "Cannot find source file matching \
  1218. module '%s' in library %s")
  1219. modul cs.cs_name;
  1220. acc)
  1221. []
  1222. (lib.lib_modules @ lib.lib_internal_modules)
  1223. let generated_unix_files
  1224. ~ctxt
  1225. ~is_native
  1226. ~has_native_dynlink
  1227. ~ext_lib
  1228. ~ext_dll
  1229. ~source_file_exists
  1230. (cs, bs, lib) =
  1231. let find_modules lst ext =
  1232. let find_module modul =
  1233. match find_module source_file_exists (cs, bs, lib) modul with
  1234. | `Sources (base_fn, _) ->
  1235. [base_fn]
  1236. | `No_sources lst ->
  1237. OASISMessage.warning
  1238. ~ctxt
  1239. (f_ "Cannot find source file matching \
  1240. module '%s' in library %s")
  1241. modul cs.cs_name;
  1242. lst
  1243. in
  1244. List.map
  1245. (fun nm ->
  1246. List.map
  1247. (fun base_fn -> base_fn ^"."^ext)
  1248. (find_module nm))
  1249. lst
  1250. in
  1251. (* The headers that should be compiled along *)
  1252. let headers =
  1253. if lib.lib_pack then
  1254. []
  1255. else
  1256. find_modules
  1257. lib.lib_modules
  1258. "cmi"
  1259. in
  1260. (* The .cmx that be compiled along *)
  1261. let cmxs =
  1262. let should_be_built =
  1263. (not lib.lib_pack) && (* Do not install .cmx packed submodules *)
  1264. match bs.bs_compiled_object with
  1265. | Native -> true
  1266. | Best -> is_native
  1267. | Byte -> false
  1268. in
  1269. if should_be_built then
  1270. find_modules
  1271. (lib.lib_modules @ lib.lib_internal_modules)
  1272. "cmx"
  1273. else
  1274. []
  1275. in
  1276. let acc_nopath =
  1277. []
  1278. in
  1279. (* Compute what libraries should be built *)
  1280. let acc_nopath =
  1281. (* Add the packed header file if required *)
  1282. let add_pack_header acc =
  1283. if lib.lib_pack then
  1284. [cs.cs_name^".cmi"] :: acc
  1285. else
  1286. acc
  1287. in
  1288. let byte acc =
  1289. add_pack_header ([cs.cs_name^".cma"] :: acc)
  1290. in
  1291. let native acc =
  1292. let acc =
  1293. add_pack_header
  1294. (if has_native_dynlink then
  1295. [cs.cs_name^".cmxs"] :: acc
  1296. else acc)
  1297. in
  1298. [cs.cs_name^".cmxa"] :: [cs.cs_name^ext_lib] :: acc
  1299. in
  1300. match bs.bs_compiled_object with
  1301. | Native ->
  1302. byte (native acc_nopath)
  1303. | Best when is_native ->
  1304. byte (native acc_nopath)
  1305. | Byte | Best ->
  1306. byte acc_nopath
  1307. in
  1308. (* Add C library to be built *)
  1309. let acc_nopath =
  1310. if bs.bs_c_sources <> [] then
  1311. begin
  1312. ["lib"^cs.cs_name^"_stubs"^ext_lib]
  1313. ::
  1314. ["dll"^cs.cs_name^"_stubs"^ext_dll]
  1315. ::
  1316. acc_nopath
  1317. end
  1318. else
  1319. acc_nopath
  1320. in
  1321. (* All the files generated *)
  1322. List.rev_append
  1323. (List.rev_map
  1324. (List.rev_map
  1325. (OASISUnixPath.concat bs.bs_path))
  1326. acc_nopath)
  1327. (headers @ cmxs)
  1328. type data = common_section * build_section * library
  1329. type tree =
  1330. | Node of (data option) * (tree MapString.t)
  1331. | Leaf of data
  1332. let findlib_mapping pkg =
  1333. (* Map from library name to either full findlib name or parts + parent. *)
  1334. let fndlb_parts_of_lib_name =
  1335. let fndlb_parts cs lib =
  1336. let name =
  1337. match lib.lib_findlib_name with
  1338. | Some nm -> nm
  1339. | None -> cs.cs_name
  1340. in
  1341. let name =
  1342. String.concat "." (lib.lib_findlib_containers @ [name])
  1343. in
  1344. name
  1345. in
  1346. List.fold_left
  1347. (fun mp ->
  1348. function
  1349. | Library (cs, _, lib) ->
  1350. begin
  1351. let lib_name = cs.cs_name in
  1352. let fndlb_parts = fndlb_parts cs lib in
  1353. if MapString.mem lib_name mp then
  1354. failwithf
  1355. (f_ "The library name '%s' is used more than once.")
  1356. lib_name;
  1357. match lib.lib_findlib_parent with
  1358. | Some lib_name_parent ->
  1359. MapString.add
  1360. lib_name
  1361. (`Unsolved (lib_name_parent, fndlb_parts))
  1362. mp
  1363. | None ->
  1364. MapString.add
  1365. lib_name
  1366. (`Solved fndlb_parts)
  1367. mp
  1368. end
  1369. | Executable _ | Test _ | Flag _ | SrcRepo _ | Doc _ ->
  1370. mp)
  1371. MapString.empty
  1372. pkg.sections
  1373. in
  1374. (* Solve the above graph to be only library name to full findlib name. *)
  1375. let fndlb_name_of_lib_name =
  1376. let rec solve visited mp lib_name lib_name_child =
  1377. if SetString.mem lib_name visited then
  1378. failwithf
  1379. (f_ "Library '%s' is involved in a cycle \
  1380. with regard to findlib naming.")
  1381. lib_name;
  1382. let visited = SetString.add lib_name visited in
  1383. try
  1384. match MapString.find lib_name mp with
  1385. | `Solved fndlb_nm ->
  1386. fndlb_nm, mp
  1387. | `Unsolved (lib_nm_parent, post_fndlb_nm) ->
  1388. let pre_fndlb_nm, mp =
  1389. solve visited mp lib_nm_parent lib_name
  1390. in
  1391. let fndlb_nm = pre_fndlb_nm^"."^post_fndlb_nm in
  1392. fndlb_nm, MapString.add lib_name (`Solved fndlb_nm) mp
  1393. with Not_found ->
  1394. failwithf
  1395. (f_ "Library '%s', which is defined as the findlib parent of \
  1396. library '%s', doesn't exist.")
  1397. lib_name lib_name_child
  1398. in
  1399. let mp =
  1400. MapString.fold
  1401. (fun lib_name status mp ->
  1402. match status with
  1403. | `Solved _ ->
  1404. (* Solved initialy, no need to go further *)
  1405. mp
  1406. | `Unsolved _ ->
  1407. let _, mp = solve SetString.empty mp lib_name "<none>" in
  1408. mp)
  1409. fndlb_parts_of_lib_name
  1410. fndlb_parts_of_lib_name
  1411. in
  1412. MapString.map
  1413. (function
  1414. | `Solved fndlb_nm -> fndlb_nm
  1415. | `Unsolved _ -> assert false)
  1416. mp
  1417. in
  1418. (* Convert an internal library name to a findlib name. *)
  1419. let findlib_name_of_library_name lib_nm =
  1420. try
  1421. MapString.find lib_nm fndlb_name_of_lib_name
  1422. with Not_found ->
  1423. raise (InternalLibraryNotFound lib_nm)
  1424. in
  1425. (* Add a library to the tree.
  1426. *)
  1427. let add sct mp =
  1428. let fndlb_fullname =
  1429. let cs, _, _ = sct in
  1430. let lib_name = cs.cs_name in
  1431. findlib_name_of_library_name lib_name
  1432. in
  1433. let rec add_children nm_lst (children : tree MapString.t) =
  1434. match nm_lst with
  1435. | (hd :: tl) ->
  1436. begin
  1437. let node =
  1438. try
  1439. add_node tl (MapString.find hd children)
  1440. with Not_found ->
  1441. (* New node *)
  1442. new_node tl
  1443. in
  1444. MapString.add hd node children
  1445. end
  1446. | [] ->
  1447. (* Should not have a nameless library. *)
  1448. assert false
  1449. and add_node tl node =
  1450. if tl = [] then
  1451. begin
  1452. match node with
  1453. | Node (None, children) ->
  1454. Node (Some sct, children)
  1455. | Leaf (cs', _, _) | Node (Some (cs', _, _), _) ->
  1456. (* TODO: allow to merge Package, i.e.
  1457. * archive(byte) = "foo.cma foo_init.cmo"
  1458. *)
  1459. let cs, _, _ = sct in
  1460. failwithf
  1461. (f_ "Library '%s' and '%s' have the same findlib name '%s'")
  1462. cs.cs_name cs'.cs_name fndlb_fullname
  1463. end
  1464. else
  1465. begin
  1466. match node with
  1467. | Leaf data ->
  1468. Node (Some data, add_children tl MapString.empty)
  1469. | Node (data_opt, children) ->
  1470. Node (data_opt, add_children tl children)
  1471. end
  1472. and new_node =
  1473. function
  1474. | [] ->
  1475. Leaf sct
  1476. | hd :: tl ->
  1477. Node (None, MapString.add hd (new_node tl) MapString.empty)
  1478. in
  1479. add_children (OASISString.nsplit fndlb_fullname '.') mp
  1480. in
  1481. let rec group_of_tree mp =
  1482. MapString.fold
  1483. (fun nm node acc ->
  1484. let cur =
  1485. match node with
  1486. | Node (Some (cs, bs, lib), children) ->
  1487. Package (nm, cs, bs, lib, group_of_tree children)
  1488. | Node (None, children) ->
  1489. Container (nm, group_of_tree children)
  1490. | Leaf (cs, bs, lib) ->
  1491. Package (nm, cs, bs, lib, [])
  1492. in
  1493. cur :: acc)
  1494. mp []
  1495. in
  1496. let group_mp =
  1497. List.fold_left
  1498. (fun mp ->
  1499. function
  1500. | Library (cs, bs, lib) ->
  1501. add (cs, bs, lib) mp
  1502. | _ ->
  1503. mp)
  1504. MapString.empty
  1505. pkg.sections
  1506. in
  1507. let groups =
  1508. group_of_tree group_mp
  1509. in
  1510. let library_name_of_findlib_name =
  1511. Lazy.lazy_from_fun
  1512. (fun () ->
  1513. (* Revert findlib_name_of_library_name. *)
  1514. MapString.fold
  1515. (fun k v mp -> MapString.add v k mp)
  1516. fndlb_name_of_lib_name
  1517. MapString.empty)
  1518. in
  1519. let library_name_of_findlib_name fndlb_nm =
  1520. try
  1521. MapString.find fndlb_nm (Lazy.force library_name_of_findlib_name)
  1522. with Not_found ->
  1523. raise (FindlibPackageNotFound fndlb_nm)
  1524. in
  1525. groups,
  1526. findlib_name_of_library_name,
  1527. library_name_of_findlib_name
  1528. let findlib_of_group =
  1529. function
  1530. | Container (fndlb_nm, _)
  1531. | Package (fndlb_nm, _, _, _, _) -> fndlb_nm
  1532. let root_of_group grp =
  1533. let rec root_lib_aux =
  1534. (* We do a DFS in the group. *)
  1535. function
  1536. | Container (_, children) ->
  1537. List.fold_left
  1538. (fun res grp ->
  1539. if res = None then
  1540. root_lib_aux grp
  1541. else
  1542. res)
  1543. None
  1544. children
  1545. | Package (_, cs, bs, lib, _) ->
  1546. Some (cs, bs, lib)
  1547. in
  1548. match root_lib_aux grp with
  1549. | Some res ->
  1550. res
  1551. | None ->
  1552. failwithf
  1553. (f_ "Unable to determine root library of findlib library '%s'")
  1554. (findlib_of_group grp)
  1555. end
  1556. module OASISFlag = struct
  1557. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISFlag.ml" *)
  1558. end
  1559. module OASISPackage = struct
  1560. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISPackage.ml" *)
  1561. end
  1562. module OASISSourceRepository = struct
  1563. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISSourceRepository.ml" *)
  1564. end
  1565. module OASISTest = struct
  1566. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISTest.ml" *)
  1567. end
  1568. module OASISDocument = struct
  1569. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISDocument.ml" *)
  1570. end
  1571. module OASISExec = struct
  1572. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISExec.ml" *)
  1573. open OASISGettext
  1574. open OASISUtils
  1575. open OASISMessage
  1576. (* TODO: I don't like this quote, it is there because $(rm) foo expands to
  1577. * 'rm -f' foo...
  1578. *)
  1579. let run ~ctxt ?f_exit_code ?(quote=true) cmd args =
  1580. let cmd =
  1581. if quote then
  1582. if Sys.os_type = "Win32" then
  1583. if String.contains cmd ' ' then
  1584. (* Double the 1st double quote... win32... sigh *)
  1585. "\""^(Filename.quote cmd)
  1586. else
  1587. cmd
  1588. else
  1589. Filename.quote cmd
  1590. else
  1591. cmd
  1592. in
  1593. let cmdline =
  1594. String.concat " " (cmd :: args)
  1595. in
  1596. info ~ctxt (f_ "Running command '%s'") cmdline;
  1597. match f_exit_code, Sys.command cmdline with
  1598. | None, 0 -> ()
  1599. | None, i ->
  1600. failwithf
  1601. (f_ "Command '%s' terminated with error code %d")
  1602. cmdline i
  1603. | Some f, i ->
  1604. f i
  1605. let run_read_output ~ctxt ?f_exit_code cmd args =
  1606. let fn =
  1607. Filename.temp_file "oasis-" ".txt"
  1608. in
  1609. try
  1610. begin
  1611. let () =
  1612. run ~ctxt ?f_exit_code cmd (args @ [">"; Filename.quote fn])
  1613. in
  1614. let chn =
  1615. open_in fn
  1616. in
  1617. let routput =
  1618. ref []
  1619. in
  1620. begin
  1621. try
  1622. while true do
  1623. routput := (input_line chn) :: !routput
  1624. done
  1625. with End_of_file ->
  1626. ()
  1627. end;
  1628. close_in chn;
  1629. Sys.remove fn;
  1630. List.rev !routput
  1631. end
  1632. with e ->
  1633. (try Sys.remove fn with _ -> ());
  1634. raise e
  1635. let run_read_one_line ~ctxt ?f_exit_code cmd args =
  1636. match run_read_output ~ctxt ?f_exit_code cmd args with
  1637. | [fst] ->
  1638. fst
  1639. | lst ->
  1640. failwithf
  1641. (f_ "Command return unexpected output %S")
  1642. (String.concat "\n" lst)
  1643. end
  1644. module OASISFileUtil = struct
  1645. (* # 21 "/Users/avsm/.opam/system/build/oasis.0.3.0/src/oasis/OASISFileUtil.ml" *)
  1646. open OASISGettext
  1647. let file_exists_case fn =
  1648. let dirname = Filename.dirname fn in
  1649. let basename = Filename.basename fn in
  1650. if Sys.file_exists dirname then
  1651. if basename = Filename.current_dir_name then
  1652. true
  1653. else
  1654. List.mem
  1655. basename
  1656. (Array.to_list (Sys.readdir dirname))
  1657. else
  1658. false
  1659. let find_file ?(case_sensitive=true) paths exts =
  1660. (* Cardinal product of two list *)
  1661. let ( * ) lst1 lst2 =
  1662. List.flatten
  1663. (List.map
  1664. (fun a ->
  1665. List.map
  1666. (fun b -> a,b)
  1667. lst2)
  1668. lst1)
  1669. in
  1670. let rec combined_paths lst =
  1671. match lst with
  1672. | p1 :: p2 :: tl ->
  1673. let acc =
  1674. (List.map
  1675. (fun (a,b) -> Filename.concat a b)
  1676. (p1 * p2))
  1677. in
  1678. combined_paths (acc :: tl)
  1679. | [e] ->
  1680. e
  1681. | [] ->
  1682. []
  1683. in
  1684. let alternatives =
  1685. List.map
  1686. (fun (p,e) ->
  1687. if String.length e > 0 && e.[0] <> '.' then
  1688. p ^ "." ^ e
  1689. else
  1690. p ^ e)
  1691. ((combined_paths paths) * exts)
  1692. in
  1693. List.find
  1694. (if case_sensitive then
  1695. file_exists_case
  1696. else
  1697. Sys.file_exists)
  1698. alternat

Large files files are truncated, but you can click here to view the full file