From 04e26a3fc35798d54a99c0bfba8af82d2c513141 Mon Sep 17 00:00:00 2001 From: xthirioux <xthirioux@041b043f-8d7c-46b2-b46e-ef0dd855326e> Date: Wed, 5 Mar 2014 15:32:51 +0000 Subject: [PATCH] answer to #feature 50: - arrows are now factorized out and become part of include as files arrow.h and arrow.c - no more arrows in generated code - compiling and linking arrow.c is only necessary in case of dynamic allocation - version now includes installation prefix (for the standard lib) and svn number git-svn-id: https://cavale.enseeiht.fr/svn/lustrec/lustre_compiler/trunk@180 041b043f-8d7c-46b2-b46e-ef0dd855326e --- _oasis | 4 +- _tags | 23 +- configure | 23 +- include/arrow.c | 10 + include/arrow.h | 20 + myocamlbuild.ml | 251 ++- setup.ml | 5045 ++++++++++++++++++++++++++-------------------- src/c_backend.ml | 88 +- svn_version.sh | 8 +- 9 files changed, 3106 insertions(+), 2366 deletions(-) create mode 100644 include/arrow.c create mode 100644 include/arrow.h diff --git a/_oasis b/_oasis index b420ac7b..17ad1b3b 100644 --- a/_oasis +++ b/_oasis @@ -6,8 +6,8 @@ Authors: License: LGPL-2.1 Plugins: DevFiles (0.2) # , Custom (0.2) -PreBuildCommand: ./svn_version.sh -PostInstallCommand: mkdir -p $(prefix)/include; cp -rf include $(prefix)/include/lustrec +PreBuildCommand: ./svn_version.sh $(prefix) +PostInstallCommand: mkdir -p $(prefix)/include/lustrec; cp -rf include/*.[ch] $(prefix)/include/lustrec; cp -rf include/*.java $(prefix)/include/lustrec Executable lustrec Path: src diff --git a/_tags b/_tags index e615d37c..6786ff52 100644 --- a/_tags +++ b/_tags @@ -1,10 +1,23 @@ # OASIS_START -# DO NOT EDIT (digest: 54aa7498411485980381101fb69226dd) +# DO NOT EDIT (digest: 98bcbc21d29d2f6266238c1025fff223) +# Ignore VCS directories, you can use the same kind of rule outside +# OASIS_START/STOP if you want to exclude directories that contains +# useless stuff for the build process +<**/.svn>: -traverse +<**/.svn>: not_hygienic +".bzr": -traverse +".bzr": not_hygienic +".hg": -traverse +".hg": not_hygienic +".git": -traverse +".git": not_hygienic +"_darcs": -traverse +"_darcs": not_hygienic # Executable lustrec -"src/main_lustre_compiler.native": pkg_unix -"src/main_lustre_compiler.native": pkg_str "src/main_lustre_compiler.native": pkg_ocamlgraph -<src/*.ml{,i}>: pkg_unix -<src/*.ml{,i}>: pkg_str +"src/main_lustre_compiler.native": pkg_str +"src/main_lustre_compiler.native": pkg_unix <src/*.ml{,i}>: pkg_ocamlgraph +<src/*.ml{,i}>: pkg_str +<src/*.ml{,i}>: pkg_unix # OASIS_STOP diff --git a/configure b/configure index 6719c7c3..97ed012e 100755 --- a/configure +++ b/configure @@ -1,8 +1,27 @@ #!/bin/sh # OASIS_START -# DO NOT EDIT (digest: ed33e59fe00e48bc31edf413bbc8b8d6) +# DO NOT EDIT (digest: 425187ed8bfdbdd207fd76392dd243a7) set -e -ocaml setup.ml -configure $* +FST=true +for i in "$@"; do + if $FST; then + set -- + FST=false + fi + + case $i in + --*=*) + ARG=${i%%=*} + VAL=${i##*=} + set -- "$@" "$ARG" "$VAL" + ;; + *) + set -- "$@" "$i" + ;; + esac +done + +ocaml setup.ml -configure "$@" # OASIS_STOP diff --git a/include/arrow.c b/include/arrow.c new file mode 100644 index 00000000..950b46a6 --- /dev/null +++ b/include/arrow.c @@ -0,0 +1,10 @@ +#include <stdlib.h> +#include <assert.h> +#include "arrow.h" + +struct _arrow_mem *arrow_alloc() { + struct _arrow_mem *_alloc; + _alloc = (struct _arrow_mem *) malloc(sizeof(struct _arrow_mem *)); + assert (_alloc); + return _alloc; +} diff --git a/include/arrow.h b/include/arrow.h new file mode 100644 index 00000000..f2fa3bf7 --- /dev/null +++ b/include/arrow.h @@ -0,0 +1,20 @@ + +#ifndef _ARROW +#define _ARROW + +struct _arrow_mem {struct _arrow_reg {_Bool _first; } _reg; }; + +extern struct _arrow_mem *arrow_alloc (); + +#define _arrow_DECLARE(inst)\ + struct _arrow_mem inst; + +#define _arrow_LINK(inst) do {\ + ;\ +} while (0) + +#define _arrow_step(x,y,output,self) ((self)->_reg._first?((self)->_reg._first=0,(*output = x)):(*output = y)) + +#define _arrow_reset(self) {(self)->_reg._first = 1;} + +#endif diff --git a/myocamlbuild.ml b/myocamlbuild.ml index 55d782fb..fed8e1f8 100644 --- a/myocamlbuild.ml +++ b/myocamlbuild.ml @@ -1,39 +1,39 @@ (* OASIS_START *) -(* DO NOT EDIT (digest: 7eabc0106cad87d67c960d9a2ff80b28) *) +(* DO NOT EDIT (digest: 00359f2e15a7ed8f31f1d7ce086345f9) *) module OASISGettext = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISGettext.ml" - - let ns_ str = +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISGettext.ml" *) + + let ns_ str = str - - let s_ str = + + let s_ str = str - + let f_ (str : ('a, 'b, 'c, 'd) format4) = str - + let fn_ fmt1 fmt2 n = if n = 1 then fmt1^^"" else fmt2^^"" - - let init = + + let init = [] - + end module OASISExpr = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISExpr.ml" - - - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISExpr.ml" *) + + + open OASISGettext - + type test = string - + type flag = string - + type t = | EBool of bool | ENot of t @@ -42,31 +42,31 @@ module OASISExpr = struct | EFlag of flag | ETest of test * string - + type 'a choices = (t * 'a) list - + let eval var_get t = - let rec eval' = + let rec eval' = function | EBool b -> b - - | ENot e -> + + | ENot e -> not (eval' e) - + | EAnd (e1, e2) -> (eval' e1) && (eval' e2) - - | EOr (e1, e2) -> + + | EOr (e1, e2) -> (eval' e1) || (eval' e2) - + | EFlag nm -> let v = var_get nm in assert(v = "true" || v = "false"); (v = "true") - + | ETest (nm, vl) -> let v = var_get nm @@ -74,21 +74,21 @@ module OASISExpr = struct (v = vl) in eval' t - + let choose ?printer ?name var_get lst = - let rec choose_aux = + let rec choose_aux = function | (cond, vl) :: tl -> - if eval var_get cond then - vl + if eval var_get cond then + vl else choose_aux tl | [] -> - let str_lst = + let str_lst = if lst = [] then s_ "<empty>" else - String.concat + String.concat (s_ ", ") (List.map (fun (cond, vl) -> @@ -97,10 +97,10 @@ module OASISExpr = struct | None -> s_ "<no printer>") lst) in - match name with + match name with | Some nm -> failwith - (Printf.sprintf + (Printf.sprintf (f_ "No result for the choice list '%s': %s") nm str_lst) | None -> @@ -110,22 +110,23 @@ module OASISExpr = struct str_lst) in choose_aux (List.rev lst) - + end +# 117 "myocamlbuild.ml" module BaseEnvLight = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseEnvLight.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseEnvLight.ml" *) + module MapString = Map.Make(String) - + type t = string MapString.t - + let default_filename = - Filename.concat + Filename.concat (Sys.getcwd ()) "setup.data" - + let load ?(allow_empty=false) ?(filename=default_filename) () = if Sys.file_exists filename then begin @@ -138,23 +139,23 @@ module BaseEnvLight = struct let line = ref 1 in - let st_line = + let st_line = Stream.from (fun _ -> try - match Stream.next st with + match Stream.next st with | '\n' -> incr line; Some '\n' | c -> Some c with Stream.Failure -> None) in - let lexer = + let lexer = Genlex.make_lexer ["="] st_line in let rec read_file mp = - match Stream.npeek 3 lexer with + match Stream.npeek 3 lexer with | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] -> - Stream.junk lexer; - Stream.junk lexer; + Stream.junk lexer; + Stream.junk lexer; Stream.junk lexer; read_file (MapString.add nm value mp) | [] -> @@ -177,43 +178,44 @@ module BaseEnvLight = struct end else begin - failwith - (Printf.sprintf + failwith + (Printf.sprintf "Unable to load environment, the file '%s' doesn't exist." filename) end - + let var_get name env = let rec var_expand str = let buff = Buffer.create ((String.length str) * 2) in - Buffer.add_substitute + Buffer.add_substitute buff - (fun var -> - try + (fun var -> + try var_expand (MapString.find var env) with Not_found -> - failwith - (Printf.sprintf + failwith + (Printf.sprintf "No variable %s defined when trying to expand %S." - var + var str)) str; Buffer.contents buff in var_expand (MapString.find name env) - - let var_choose lst env = + + let var_choose lst env = OASISExpr.choose (fun nm -> var_get nm env) lst end +# 215 "myocamlbuild.ml" module MyOCamlbuildFindlib = struct -# 21 "/build/buildd/oasis-0.2.0/src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *) + (** OCamlbuild extension, copied from * http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild * by N. Pouillard and others @@ -223,14 +225,14 @@ module MyOCamlbuildFindlib = struct * Modified by Sylvain Le Gall *) open Ocamlbuild_plugin - + (* these functions are not really officially exported *) let run_and_read = Ocamlbuild_pack.My_unix.run_and_read - + let blank_sep_strings = Ocamlbuild_pack.Lexers.blank_sep_strings - + let split s ch = let x = ref [] @@ -245,24 +247,24 @@ module MyOCamlbuildFindlib = struct try go s with Not_found -> !x - + let split_nl s = split s '\n' - + let before_space s = try String.before s (String.index s ' ') with Not_found -> s - + (* this lists all supported packages *) let find_packages () = List.map before_space (split_nl & run_and_read "ocamlfind list") - + (* this is supposed to list available syntaxes, but I don't know how to do it. *) let find_syntaxes () = ["camlp4o"; "camlp4r"] - + (* ocamlfind command *) let ocamlfind x = S[A"ocamlfind"; x] - + let dispatch = function | Before_options -> @@ -292,7 +294,7 @@ module MyOCamlbuildFindlib = struct flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S[A"-package"; A pkg]; end (find_packages ()); - + (* Like -package but for extensions syntax. Morover -syntax is useless * when linking. *) List.iter begin fun syntax -> @@ -301,7 +303,7 @@ module MyOCamlbuildFindlib = struct flag ["ocaml"; "doc"; "syntax_"^syntax] & S[A"-syntax"; A syntax]; flag ["ocaml"; "infer_interface"; "syntax_"^syntax] & S[A"-syntax"; A syntax]; end (find_syntaxes ()); - + (* The default "thread" tag is not compatible with ocamlfind. * Indeed, the default rules add the "threads.cma" or "threads.cmxa" * options when using this tag. When using the "-linkpkg" option with @@ -311,49 +313,61 @@ module MyOCamlbuildFindlib = struct * the "threads" package using the previous plugin. *) flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]); + flag ["ocaml"; "pkg_threads"; "doc"] (S[A "-I"; A "+threads"]); flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]); flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"]) - + | _ -> () - + end module MyOCamlbuildBase = struct -# 21 "/build/buildd/oasis-0.2.0/src/plugins/ocamlbuild/MyOCamlbuildBase.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *) + (** Base functions for writing myocamlbuild.ml @author Sylvain Le Gall *) - - - + + + open Ocamlbuild_plugin - + module OC = Ocamlbuild_pack.Ocaml_compiler + type dir = string type file = string type name = string type tag = string - -# 55 "/build/buildd/oasis-0.2.0/src/plugins/ocamlbuild/MyOCamlbuildBase.ml" - + +(* # 56 "/build/buildd/oasis-0.3.0/src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *) + type t = { lib_ocaml: (name * dir list) list; lib_c: (name * dir * file list) list; flags: (tag list * (spec OASISExpr.choices)) list; + (* Replace the 'dir: include' from _tags by a precise interdepends in + * directory. + *) + includes: (dir * dir list) list; } - + let env_filename = Pathname.basename BaseEnvLight.default_filename - + let dispatch_combine lst = fun e -> List.iter (fun dispatch -> dispatch e) lst - + + let tag_libstubs nm = + "use_lib"^nm^"_stubs" + + let nm_libstubs nm = + nm^"_stubs" + let dispatch t e = let env = BaseEnvLight.load @@ -380,53 +394,64 @@ module MyOCamlbuildBase = struct Options.ext_lib, "ext_lib"; Options.ext_dll, "ext_dll"; ] - + | After_rules -> (* Declare OCaml libraries *) List.iter (function - | lib, [] -> - ocaml_lib lib; - | lib, dir :: tl -> - ocaml_lib ~dir:dir lib; + | nm, [] -> + ocaml_lib nm + | nm, dir :: tl -> + ocaml_lib ~dir:dir (dir^"/"^nm); List.iter (fun dir -> - flag - ["ocaml"; "use_"^lib; "compile"] - (S[A"-I"; P dir])) + List.iter + (fun str -> + flag ["ocaml"; "use_"^nm; str] (S[A"-I"; P dir])) + ["compile"; "infer_interface"; "doc"]) tl) t.lib_ocaml; - + + (* Declare directories dependencies, replace "include" in _tags. *) + List.iter + (fun (dir, include_dirs) -> + Pathname.define_context dir include_dirs) + t.includes; + (* Declare C libraries *) List.iter (fun (lib, dir, headers) -> (* Handle C part of library *) - flag ["link"; "library"; "ocaml"; "byte"; "use_lib"^lib] - (S[A"-dllib"; A("-l"^lib); A"-cclib"; A("-l"^lib)]); - - flag ["link"; "library"; "ocaml"; "native"; "use_lib"^lib] - (S[A"-cclib"; A("-l"^lib)]); + flag ["link"; "library"; "ocaml"; "byte"; tag_libstubs lib] + (S[A"-dllib"; A("-l"^(nm_libstubs lib)); A"-cclib"; + A("-l"^(nm_libstubs lib))]); + + flag ["link"; "library"; "ocaml"; "native"; tag_libstubs lib] + (S[A"-cclib"; A("-l"^(nm_libstubs lib))]); - flag ["link"; "program"; "ocaml"; "byte"; "use_lib"^lib] - (S[A"-dllib"; A("dll"^lib)]); - + flag ["link"; "program"; "ocaml"; "byte"; tag_libstubs lib] + (S[A"-dllib"; A("dll"^(nm_libstubs lib))]); + (* When ocaml link something that use the C library, then one need that file to be up to date. *) - dep ["link"; "ocaml"; "use_lib"^lib] - [dir/"lib"^lib^"."^(!Options.ext_lib)]; - + dep ["link"; "ocaml"; "program"; tag_libstubs lib] + [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)]; + + dep ["compile"; "ocaml"; "program"; tag_libstubs lib] + [dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)]; + (* TODO: be more specific about what depends on headers *) (* Depends on .h files *) dep ["compile"; "c"] headers; - + (* Setup search path for lib *) flag ["link"; "ocaml"; "use_"^lib] (S[A"-I"; P(dir)]); ) t.lib_c; - + (* Add flags *) List.iter (fun (tags, cond_specs) -> @@ -437,23 +462,25 @@ module MyOCamlbuildBase = struct t.flags | _ -> () - + let dispatch_default t = dispatch_combine [ dispatch t; MyOCamlbuildFindlib.dispatch; ] - + end +# 476 "myocamlbuild.ml" open Ocamlbuild_plugin;; let package_default = - {MyOCamlbuildBase.lib_ocaml = []; lib_c = []; flags = []; } + {MyOCamlbuildBase.lib_ocaml = []; lib_c = []; flags = []; includes = []; } ;; let dispatch_default = MyOCamlbuildBase.dispatch_default package_default;; +# 485 "myocamlbuild.ml" (* OASIS_STOP *) Ocamlbuild_plugin.dispatch dispatch_default;; diff --git a/setup.ml b/setup.ml index 178ddc51..49132274 100644 --- a/setup.ml +++ b/setup.ml @@ -1,288 +1,363 @@ (* setup.ml generated for the first time by OASIS v0.2.0 *) (* OASIS_START *) -(* DO NOT EDIT (digest: 6666f62d55895fd4c2e5dbbf8e9d4998) *) +(* DO NOT EDIT (digest: 199ddf56e2399fc7ababf7124443bcc9) *) (* - Regenerated by OASIS v0.2.0 + Regenerated by OASIS v0.3.0 Visit http://oasis.forge.ocamlcore.org for more information and documentation about functions used in this file. *) module OASISGettext = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISGettext.ml" - - let ns_ str = +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISGettext.ml" *) + + let ns_ str = str - - let s_ str = + + let s_ str = str - + let f_ (str : ('a, 'b, 'c, 'd) format4) = str - + let fn_ fmt1 fmt2 n = if n = 1 then fmt1^^"" else fmt2^^"" - - let init = + + let init = [] - + end module OASISContext = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISContext.ml" - - open OASISGettext - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISContext.ml" *) + + open OASISGettext + type level = [ `Debug - | `Info + | `Info | `Warning | `Error] - + type t = { - verbose: bool; - debug: bool; - ignore_plugins: bool; - printf: level -> string -> unit; + quiet: bool; + info: bool; + debug: bool; + ignore_plugins: bool; + ignore_unknown_fields: bool; + printf: level -> string -> unit; } - - let printf lvl str = - let beg = - match lvl with + + let printf lvl str = + let beg = + match lvl with | `Error -> s_ "E: " | `Warning -> s_ "W: " | `Info -> s_ "I: " | `Debug -> s_ "D: " in - match lvl with - | `Error -> - prerr_endline (beg^str) - | _ -> - print_endline (beg^str) - + prerr_endline (beg^str) + let default = - ref + ref { - verbose = true; - debug = false; - ignore_plugins = false; - printf = printf; + quiet = false; + info = false; + debug = false; + ignore_plugins = false; + ignore_unknown_fields = false; + printf = printf; } - - let quiet = - {!default with - verbose = false; - debug = false; - } - - + + let quiet = + {!default with quiet = true} + + let args () = ["-quiet", - Arg.Unit (fun () -> default := {!default with verbose = false}), + Arg.Unit (fun () -> default := {!default with quiet = true}), (s_ " Run quietly"); - + + "-info", + Arg.Unit (fun () -> default := {!default with info = true}), + (s_ " Display information message"); + + "-debug", Arg.Unit (fun () -> default := {!default with debug = true}), (s_ " Output debug message")] end +module OASISString = struct +(* # 1 "/build/buildd/oasis-0.3.0/src/oasis/OASISString.ml" *) + + + + (** Various string utilities. + + Mostly inspired by extlib and batteries ExtString and BatString libraries. + + @author Sylvain Le Gall + *) + + let nsplitf str f = + if str = "" then + [] + else + let buf = Buffer.create 13 in + let lst = ref [] in + let push () = + lst := Buffer.contents buf :: !lst; + Buffer.clear buf + in + let str_len = String.length str in + for i = 0 to str_len - 1 do + if f str.[i] then + push () + else + Buffer.add_char buf str.[i] + done; + push (); + List.rev !lst + + (** [nsplit c s] Split the string [s] at char [c]. It doesn't include the + separator. + *) + let nsplit str c = + nsplitf str ((=) c) + + let find ~what ?(offset=0) str = + let what_idx = ref 0 in + let str_idx = ref offset in + while !str_idx < String.length str && + !what_idx < String.length what do + if str.[!str_idx] = what.[!what_idx] then + incr what_idx + else + what_idx := 0; + incr str_idx + done; + if !what_idx <> String.length what then + raise Not_found + else + !str_idx - !what_idx + + let sub_start str len = + let str_len = String.length str in + if len >= str_len then + "" + else + String.sub str len (str_len - len) + + let sub_end ?(offset=0) str len = + let str_len = String.length str in + if len >= str_len then + "" + else + String.sub str 0 (str_len - len) + + let starts_with ~what ?(offset=0) str = + let what_idx = ref 0 in + let str_idx = ref offset in + let ok = ref true in + while !ok && + !str_idx < String.length str && + !what_idx < String.length what do + if str.[!str_idx] = what.[!what_idx] then + incr what_idx + else + ok := false; + incr str_idx + done; + if !what_idx = String.length what then + true + else + false + + let strip_starts_with ~what str = + if starts_with ~what str then + sub_start str (String.length what) + else + raise Not_found + + let ends_with ~what ?(offset=0) str = + let what_idx = ref ((String.length what) - 1) in + let str_idx = ref ((String.length str) - 1) in + let ok = ref true in + while !ok && + offset <= !str_idx && + 0 <= !what_idx do + if str.[!str_idx] = what.[!what_idx] then + decr what_idx + else + ok := false; + decr str_idx + done; + if !what_idx = -1 then + true + else + false + + let strip_ends_with ~what str = + if ends_with ~what str then + sub_end str (String.length what) + else + raise Not_found + + let replace_chars f s = + let buf = String.make (String.length s) 'X' in + for i = 0 to String.length s - 1 do + buf.[i] <- f s.[i] + done; + buf + +end + module OASISUtils = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISUtils.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISUtils.ml" *) + + open OASISGettext + module MapString = Map.Make(String) - + let map_string_of_assoc assoc = List.fold_left (fun acc (k, v) -> MapString.add k v acc) MapString.empty assoc - + module SetString = Set.Make(String) - + let set_string_add_list st lst = - List.fold_left + List.fold_left (fun acc e -> SetString.add e acc) st lst - + let set_string_of_list = set_string_add_list SetString.empty - - - let compare_csl s1 s2 = + + + let compare_csl s1 s2 = String.compare (String.lowercase s1) (String.lowercase s2) - - module HashStringCsl = + + module HashStringCsl = Hashtbl.Make (struct type t = string - - let equal s1 s2 = + + let equal s1 s2 = (String.lowercase s1) = (String.lowercase s2) - + let hash s = Hashtbl.hash (String.lowercase s) end) - - let split sep str = - let str_len = - String.length str - in - let rec split_aux acc pos = - if pos < str_len then - ( - let pos_sep = - try - String.index_from str pos sep - with Not_found -> - str_len - in - let part = - String.sub str pos (pos_sep - pos) - in - let acc = - part :: acc - in - if pos_sep >= str_len then - ( - (* Nothing more in the string *) - List.rev acc - ) - else if pos_sep = (str_len - 1) then - ( - (* String end with a separator *) - List.rev ("" :: acc) - ) - else - ( - split_aux acc (pos_sep + 1) - ) - ) - else - ( - List.rev acc - ) - in - split_aux [] 0 - - - let varname_of_string ?(hyphen='_') s = + + let varname_of_string ?(hyphen='_') s = if String.length s = 0 then begin - invalid_arg "varname_of_string" + invalid_arg "varname_of_string" end else begin - let buff = - Buffer.create (String.length s) - in - (* Start with a _ if digit *) - if '0' <= s.[0] && s.[0] <= '9' then - Buffer.add_char buff hyphen; - - String.iter + let buf = + OASISString.replace_chars (fun c -> - if ('a' <= c && c <= 'z') - || - ('A' <= c && c <= 'Z') - || + if ('a' <= c && c <= 'z') + || + ('A' <= c && c <= 'Z') + || ('0' <= c && c <= '9') then - Buffer.add_char buff c + c else - Buffer.add_char buff hyphen) + hyphen) s; - - String.lowercase (Buffer.contents buff) + in + let buf = + (* Start with a _ if digit *) + if '0' <= s.[0] && s.[0] <= '9' then + "_"^buf + else + buf + in + String.lowercase buf end - - let varname_concat ?(hyphen='_') p s = - let p = - let p_len = - String.length p - in - if p_len > 0 && p.[p_len - 1] = hyphen then - String.sub p 0 (p_len - 1) - else - p + + let varname_concat ?(hyphen='_') p s = + let what = String.make 1 hyphen in + let p = + try + OASISString.strip_ends_with ~what p + with Not_found -> + p in - let s = - let s_len = - String.length s - in - if s_len > 0 && s.[0] = hyphen then - String.sub s 1 (s_len - 1) - else - s + let s = + try + OASISString.strip_starts_with ~what s + with Not_found -> + s in - Printf.sprintf "%s%c%s" p hyphen s - - - let is_varname str = + p^what^s + + + let is_varname str = str = varname_of_string str - - let failwithf1 fmt a = - failwith (Printf.sprintf fmt a) - - let failwithf2 fmt a b = - failwith (Printf.sprintf fmt a b) - - let failwithf3 fmt a b c = - failwith (Printf.sprintf fmt a b c) - - let failwithf4 fmt a b c d = - failwith (Printf.sprintf fmt a b c d) - - let failwithf5 fmt a b c d e = - failwith (Printf.sprintf fmt a b c d e) - + + let failwithf fmt = Printf.ksprintf failwith fmt + end module PropList = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/PropList.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/PropList.ml" *) + open OASISGettext - + type name = string - - exception Not_set of name * string option + + exception Not_set of name * string option exception No_printer of name exception Unknown_field of name * name - - let string_of_exception = - function - | Not_set (nm, Some rsn) -> - Printf.sprintf (f_ "Field '%s' is not set: %s") nm rsn - | Not_set (nm, None) -> - Printf.sprintf (f_ "Field '%s' is not set") nm - | No_printer nm -> - Printf.sprintf (f_ "No default printer for value %s") nm - | Unknown_field (nm, schm) -> - Printf.sprintf (f_ "Field %s is not defined in schema %s") nm schm - | e -> - raise e - + + let () = + Printexc.register_printer + (function + | Not_set (nm, Some rsn) -> + Some + (Printf.sprintf (f_ "Field '%s' is not set: %s") nm rsn) + | Not_set (nm, None) -> + Some + (Printf.sprintf (f_ "Field '%s' is not set") nm) + | No_printer nm -> + Some + (Printf.sprintf (f_ "No default printer for value %s") nm) + | Unknown_field (nm, schm) -> + Some + (Printf.sprintf (f_ "Field %s is not defined in schema %s") nm schm) + | _ -> + None) + module Data = struct - - type t = + + type t = (name, unit -> unit) Hashtbl.t - + let create () = Hashtbl.create 13 - + let clear t = Hashtbl.clear t - -# 59 "/build/buildd/oasis-0.2.0/src/oasis/PropList.ml" + +(* # 71 "/build/buildd/oasis-0.3.0/src/oasis/PropList.ml" *) end - - module Schema = + + module Schema = struct - + type ('ctxt, 'extra) value = { get: Data.t -> string; @@ -290,7 +365,7 @@ module PropList = struct help: (unit -> string) option; extra: 'extra; } - + type ('ctxt, 'extra) t = { name: name; @@ -298,81 +373,81 @@ module PropList = struct order: name Queue.t; name_norm: string -> string; } - - let create ?(case_insensitive=false) nm = + + let create ?(case_insensitive=false) nm = { name = nm; fields = Hashtbl.create 13; order = Queue.create (); - name_norm = - (if case_insensitive then + name_norm = + (if case_insensitive then String.lowercase else fun s -> s); } - - let add t nm set get extra help = - let key = + + let add t nm set get extra help = + let key = t.name_norm nm in - + if Hashtbl.mem t.fields key then failwith - (Printf.sprintf + (Printf.sprintf (f_ "Field '%s' is already defined in schema '%s'") nm t.name); - Hashtbl.add - t.fields - key + Hashtbl.add + t.fields + key { - set = set; - get = get; + set = set; + get = get; help = help; extra = extra; }; - Queue.add nm t.order - + Queue.add nm t.order + let mem t nm = - Hashtbl.mem t.fields nm - - let find t nm = + Hashtbl.mem t.fields nm + + let find t nm = try Hashtbl.find t.fields (t.name_norm nm) with Not_found -> raise (Unknown_field (nm, t.name)) - + let get t data nm = (find t nm).get data - + let set t data nm ?context x = - (find t nm).set - data - ?context + (find t nm).set + data + ?context x - + let fold f acc t = - Queue.fold + Queue.fold (fun acc k -> let v = find t k in f acc k v.extra v.help) - acc + acc t.order - + let iter f t = - fold + fold (fun () -> f) () t - - let name t = + + let name t = t.name end - + module Field = struct - + type ('ctxt, 'value, 'extra) t = { set: Data.t -> ?context:'ctxt -> 'value -> unit; @@ -382,52 +457,52 @@ module PropList = struct help: (unit -> string) option; extra: 'extra; } - - let new_id = + + let new_id = let last_id = ref 0 in fun () -> incr last_id; !last_id - + let create ?schema ?name ?parse ?print ?default ?update ?help extra = (* Default value container *) - let v = - ref None + let v = + ref None in - + (* If name is not given, create unique one *) - let nm = - match name with + let nm = + match name with | Some s -> s | None -> Printf.sprintf "_anon_%d" (new_id ()) in - + (* Last chance to get a value: the default *) - let default () = - match default with + let default () = + match default with | Some d -> d | None -> raise (Not_set (nm, Some (s_ "no default value"))) in - + (* Get data *) let get data = (* Get value *) - try + try (Hashtbl.find data nm) (); - match !v with - | Some x -> x + match !v with + | Some x -> x | None -> default () with Not_found -> default () in - + (* Set data *) - let set data ?context x = - let x = - match update with + let set data ?context x = + let x = + match update with | Some f -> begin - try + try f ?context (get data) x with Not_set _ -> x @@ -435,31 +510,31 @@ module PropList = struct | None -> x in - Hashtbl.replace - data - nm - (fun () -> v := Some x) + Hashtbl.replace + data + nm + (fun () -> v := Some x) in - + (* Parse string value, if possible *) let parse = - match parse with - | Some f -> + match parse with + | Some f -> f | None -> fun ?context s -> - failwith - (Printf.sprintf + failwith + (Printf.sprintf (f_ "Cannot parse field '%s' when setting value %S") nm s) in - + (* Set data, from string *) let sets data ?context s = set ?context data (parse ?context s) in - + (* Output value as string, if possible *) let print = match print with @@ -468,20 +543,20 @@ module PropList = struct | None -> fun _ -> raise (No_printer nm) in - + (* Get data, as a string *) let gets data = print (get data) in - - begin - match schema with + + begin + match schema with | Some t -> Schema.add t nm sets gets extra help | None -> () end; - + { set = set; get = get; @@ -490,94 +565,84 @@ module PropList = struct help = help; extra = extra; } - - let fset data t ?context x = + + let fset data t ?context x = t.set data ?context x - + let fget data t = t.get data - + let fsets data t ?context s = t.sets data ?context s - + let fgets data t = - t.gets data - + t.gets data + end - + module FieldRO = struct - + let create ?schema ?name ?parse ?print ?default ?update ?help extra = - let fld = + let fld = Field.create ?schema ?name ?parse ?print ?default ?update ?help extra in fun data -> Field.fget data fld - + end end module OASISMessage = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISMessage.ml" - - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISMessage.ml" *) + + open OASISGettext open OASISContext - + let generic_message ~ctxt lvl fmt = - let cond = - match lvl with - | `Debug -> ctxt.debug - | _ -> ctxt.verbose + let cond = + if ctxt.quiet then + false + else + match lvl with + | `Debug -> ctxt.debug + | `Info -> ctxt.info + | _ -> true in - Printf.ksprintf - (fun str -> + Printf.ksprintf + (fun str -> if cond then begin ctxt.printf lvl str end) fmt - + let debug ~ctxt fmt = generic_message ~ctxt `Debug fmt - - let info ~ctxt fmt = + + let info ~ctxt fmt = generic_message ~ctxt `Info fmt - + let warning ~ctxt fmt = generic_message ~ctxt `Warning fmt - + let error ~ctxt fmt = generic_message ~ctxt `Error fmt - - - let string_of_exception e = - try - PropList.string_of_exception e - with - | Failure s -> - s - | e -> - Printexc.to_string e - - (* TODO - let register_exn_printer f = - *) - + end module OASISVersion = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISVersion.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISVersion.ml" *) + open OASISGettext - - - + + + type s = string - + type t = string - - type comparator = + + type comparator = | VGreater of t | VGreaterEqual of t | VEqual of t @@ -586,77 +651,81 @@ module OASISVersion = struct | VOr of comparator * comparator | VAnd of comparator * comparator - + (* Range of allowed characters *) let is_digit c = '0' <= c && c <= '9' - + let is_alpha c = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') - + let is_special = - function + function | '.' | '+' | '-' | '~' -> true | _ -> false - + let rec version_compare v1 v2 = if v1 <> "" || v2 <> "" then begin - (* Compare ascii string, using special meaning for version + (* Compare ascii string, using special meaning for version * related char *) - let val_ascii c = + let val_ascii c = if c = '~' then -1 else if is_digit c then 0 else if c = '\000' then 0 else if is_alpha c then Char.code c else (Char.code c) + 256 in - + let len1 = String.length v1 in let len2 = String.length v2 in - + let p = ref 0 in - + (** Compare ascii part *) - let compare_vascii () = + let compare_vascii () = let cmp = ref 0 in - while !cmp = 0 && - !p < len1 && !p < len2 && - not (is_digit v1.[!p] && is_digit v2.[!p]) do + while !cmp = 0 && + !p < len1 && !p < len2 && + not (is_digit v1.[!p] && is_digit v2.[!p]) do cmp := (val_ascii v1.[!p]) - (val_ascii v2.[!p]); incr p done; if !cmp = 0 && !p < len1 && !p = len2 then - val_ascii v1.[!p] + val_ascii v1.[!p] else if !cmp = 0 && !p = len1 && !p < len2 then - (val_ascii v2.[!p]) else !cmp in - + (** Compare digit part *) - let compare_digit () = + let compare_digit () = let extract_int v p = let start_p = !p in - while !p < String.length v && is_digit v.[!p] do + while !p < String.length v && is_digit v.[!p] do incr p done; - match String.sub v start_p (!p - start_p) with - | "" -> 0, - v - | s -> int_of_string s, - String.sub v !p ((String.length v) - !p) + let substr = + String.sub v !p ((String.length v) - !p) + in + let res = + match String.sub v start_p (!p - start_p) with + | "" -> 0 + | s -> int_of_string s + in + res, substr in let i1, tl1 = extract_int v1 (ref !p) in let i2, tl2 = extract_int v2 (ref !p) in i1 - i2, tl1, tl2 in - + match compare_vascii () with | 0 -> begin - match compare_digit () with + match compare_digit () with | 0, tl1, tl2 -> if tl1 <> "" && is_digit tl1.[0] then 1 @@ -674,33 +743,21 @@ module OASISVersion = struct begin 0 end - - - let version_of_string str = - String.iter - (fun c -> - if is_alpha c || is_digit c || is_special c then - () - else - failwith - (Printf.sprintf - (f_ "Char %C is not allowed in version '%s'") - c str)) - str; - str - - let string_of_version t = - t - - let chop t = - try - let pos = - String.rindex t '.' + + + let version_of_string str = str + + let string_of_version t = t + + let chop t = + try + let pos = + String.rindex t '.' in String.sub t 0 pos with Not_found -> t - + let rec comparator_apply v op = match op with | VGreater cv -> @@ -717,27 +774,27 @@ module OASISVersion = struct (comparator_apply v op1) || (comparator_apply v op2) | VAnd (op1, op2) -> (comparator_apply v op1) && (comparator_apply v op2) - + let rec string_of_comparator = - function + function | VGreater v -> "> "^(string_of_version v) | VEqual v -> "= "^(string_of_version v) | VLesser v -> "< "^(string_of_version v) | VGreaterEqual v -> ">= "^(string_of_version v) | VLesserEqual v -> "<= "^(string_of_version v) - | VOr (c1, c2) -> + | VOr (c1, c2) -> (string_of_comparator c1)^" || "^(string_of_comparator c2) - | VAnd (c1, c2) -> + | VAnd (c1, c2) -> (string_of_comparator c1)^" && "^(string_of_comparator c2) - + let rec varname_of_comparator = - let concat p v = + let concat p v = OASISUtils.varname_concat - p - (OASISUtils.varname_of_string + p + (OASISUtils.varname_of_string (string_of_version v)) in - function + function | VGreater v -> concat "gt" v | VLesser v -> concat "lt" v | VEqual v -> concat "eq" v @@ -747,53 +804,63 @@ module OASISVersion = struct (varname_of_comparator c1)^"_or_"^(varname_of_comparator c2) | VAnd (c1, c2) -> (varname_of_comparator c1)^"_and_"^(varname_of_comparator c2) - + + let version_0_3_or_after t = + comparator_apply t (VGreaterEqual (string_of_version "0.3")) + end module OASISLicense = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISLicense.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISLicense.ml" *) + (** License for _oasis fields @author Sylvain Le Gall *) - - - + + + type license = string - + type license_exception = string - - type license_version = + + type license_version = | Version of OASISVersion.t | VersionOrLater of OASISVersion.t | NoVersion - - type license_dep_5 = - { - license: license; - exceptions: license_exception list; - version: license_version; - } - + + type license_dep_5_unit = + { + license: license; + excption: license_exception option; + version: license_version; + } + + + type license_dep_5 = + | DEP5Unit of license_dep_5_unit + | DEP5Or of license_dep_5 list + | DEP5And of license_dep_5 list + + type t = | DEP5License of license_dep_5 | OtherLicense of string (* URL *) - + end module OASISExpr = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISExpr.ml" - - - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISExpr.ml" *) + + + open OASISGettext - + type test = string - + type flag = string - + type t = | EBool of bool | ENot of t @@ -802,31 +869,31 @@ module OASISExpr = struct | EFlag of flag | ETest of test * string - + type 'a choices = (t * 'a) list - + let eval var_get t = - let rec eval' = + let rec eval' = function | EBool b -> b - - | ENot e -> + + | ENot e -> not (eval' e) - + | EAnd (e1, e2) -> (eval' e1) && (eval' e2) - - | EOr (e1, e2) -> + + | EOr (e1, e2) -> (eval' e1) || (eval' e2) - + | EFlag nm -> let v = var_get nm in assert(v = "true" || v = "false"); (v = "true") - + | ETest (nm, vl) -> let v = var_get nm @@ -834,21 +901,21 @@ module OASISExpr = struct (v = vl) in eval' t - + let choose ?printer ?name var_get lst = - let rec choose_aux = + let rec choose_aux = function | (cond, vl) :: tl -> - if eval var_get cond then - vl + if eval var_get cond then + vl else choose_aux tl | [] -> - let str_lst = + let str_lst = if lst = [] then s_ "<empty>" else - String.concat + String.concat (s_ ", ") (List.map (fun (cond, vl) -> @@ -857,10 +924,10 @@ module OASISExpr = struct | None -> s_ "<no printer>") lst) in - match name with + match name with | Some nm -> failwith - (Printf.sprintf + (Printf.sprintf (f_ "No result for the choice list '%s': %s") nm str_lst) | None -> @@ -870,15 +937,15 @@ module OASISExpr = struct str_lst) in choose_aux (List.rev lst) - + end module OASISTypes = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISTypes.ml" - - - - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISTypes.ml" *) + + + + type name = string type package_name = string type url = string @@ -890,47 +957,47 @@ module OASISTypes = struct type arg = string type args = string list type command_line = (prog * arg list) - + type findlib_name = string type findlib_full = string - + type compiled_object = | Byte | Native | Best - - type dependency = + + type dependency = | FindlibPackage of findlib_full * OASISVersion.comparator option | InternalLibrary of name - + type tool = | ExternalTool of name - | InternalExecutable of name + | InternalExecutable of name - - type vcs = - | Darcs - | Git - | Svn - | Cvs - | Hg - | Bzr - | Arch + + type vcs = + | Darcs + | Git + | Svn + | Cvs + | Hg + | Bzr + | Arch | Monotone | OtherVCS of url - - type plugin_kind = - [ `Configure - | `Build - | `Doc - | `Test - | `Install + + type plugin_kind = + [ `Configure + | `Build + | `Doc + | `Test + | `Install | `Extra ] - + type plugin_data_purpose = [ `Configure | `Build @@ -944,24 +1011,24 @@ module OASISTypes = struct | `Extra | `Other of string ] - + type 'a plugin = 'a * name * OASISVersion.t option - - type all_plugin = plugin_kind plugin - + + type all_plugin = plugin_kind plugin + type plugin_data = (all_plugin * plugin_data_purpose * (unit -> unit)) list - -# 102 "/build/buildd/oasis-0.2.0/src/oasis/OASISTypes.ml" - + +(* # 102 "/build/buildd/oasis-0.3.0/src/oasis/OASISTypes.ml" *) + type 'a conditional = 'a OASISExpr.choices - - type custom = + + type custom = { pre_command: (command_line option) conditional; - post_command: (command_line option) conditional; + post_command: (command_line option) conditional; } - + type common_section = { cs_name: name; @@ -969,7 +1036,7 @@ module OASISTypes = struct cs_plugin_data: plugin_data; } - + type build_section = { bs_build: bool conditional; @@ -988,29 +1055,30 @@ module OASISTypes = struct bs_nativeopt: args conditional; } - - type library = + + type library = { lib_modules: string list; + lib_pack: bool; lib_internal_modules: string list; lib_findlib_parent: findlib_name option; lib_findlib_name: findlib_name option; lib_findlib_containers: findlib_name list; } - - type executable = + + type executable = { exec_custom: bool; exec_main_is: unix_filename; } - - type flag = + + type flag = { flag_description: string option; flag_default: bool conditional; } - - type source_repository = + + type source_repository = { src_repo_type: vcs; src_repo_location: url; @@ -1020,8 +1088,8 @@ module OASISTypes = struct src_repo_tag: string option; src_repo_subdir: unix_filename option; } - - type test = + + type test = { test_type: [`Test] plugin; test_command: command_line conditional; @@ -1030,7 +1098,7 @@ module OASISTypes = struct test_run: bool conditional; test_tools: tool list; } - + type doc_format = | HTML of unix_filename | DocText @@ -1040,7 +1108,7 @@ module OASISTypes = struct | DVI | OtherDoc - + type doc = { doc_type: [`Doc] plugin; @@ -1055,7 +1123,7 @@ module OASISTypes = struct doc_data_files: (unix_filename * unix_filename option) list; doc_build_tools: tool list; } - + type section = | Library of common_section * build_section * library | Executable of common_section * build_section * executable @@ -1064,7 +1132,10 @@ module OASISTypes = struct | Test of common_section * test | Doc of common_section * doc - + + type section_kind = + [ `Library | `Executable | `Flag | `SrcRepo | `Test | `Doc ] + type package = { oasis_version: OASISVersion.t; @@ -1081,50 +1152,54 @@ module OASISTypes = struct synopsis: string; description: string option; categories: url list; - + conf_type: [`Configure] plugin; conf_custom: custom; - + build_type: [`Build] plugin; build_custom: custom; - + install_type: [`Install] plugin; install_custom: custom; uninstall_custom: custom; - + clean_custom: custom; distclean_custom: custom; - + files_ab: unix_filename list; sections: section list; plugins: [`Extra] plugin list; schema_data: PropList.Data.t; plugin_data: plugin_data; } - + end module OASISUnixPath = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISUnixPath.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISUnixPath.ml" *) + type unix_filename = string type unix_dirname = string - + type host_filename = string type host_dirname = string - + let current_dir_name = "." - + let parent_dir_name = ".." - - let concat f1 f2 = - if f1 = current_dir_name then + + let is_current_dir fn = + fn = current_dir_name || fn = "" + + let concat f1 f2 = + if is_current_dir f1 then f2 - else if f2 = current_dir_name then - f1 else - f1^"/"^f2 - + let f1' = + try OASISString.strip_ends_with ~what:"/" f1 with Not_found -> f1 + in + f1'^"/"^f2 + let make = function | hd :: tl -> @@ -1134,31 +1209,31 @@ module OASISUnixPath = struct tl | [] -> invalid_arg "OASISUnixPath.make" - + let dirname f = try String.sub f 0 (String.rindex f '/') with Not_found -> current_dir_name - + let basename f = - try + try let pos_start = (String.rindex f '/') + 1 in String.sub f pos_start ((String.length f) - pos_start) with Not_found -> f - + let chop_extension f = - try + try let last_dot = String.rindex f '.' in let sub = String.sub f 0 last_dot in - try + try let last_slash = String.rindex f '/' in @@ -1168,51 +1243,87 @@ module OASISUnixPath = struct f with Not_found -> sub - + with Not_found -> f - + + let capitalize_file f = + let dir = dirname f in + let base = basename f in + concat dir (String.capitalize base) + + let uncapitalize_file f = + let dir = dirname f in + let base = basename f in + concat dir (String.uncapitalize base) + +end + +module OASISHostPath = struct +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISHostPath.ml" *) + + + open Filename + + module Unix = OASISUnixPath + + let make = + function + | [] -> + invalid_arg "OASISHostPath.make" + | hd :: tl -> + List.fold_left Filename.concat hd tl + + let of_unix ufn = + if Sys.os_type = "Unix" then + ufn + else + make + (List.map + (fun p -> + if p = Unix.current_dir_name then + current_dir_name + else if p = Unix.parent_dir_name then + parent_dir_name + else + p) + (OASISString.nsplit ufn '/')) + + end module OASISSection = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISSection.ml" - - (** Manipulate section - @author Sylvain Le Gall - *) - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISSection.ml" *) + open OASISTypes - - type section_kind = - | KLibrary - | KExecutable - | KFlag - | KSrcRepo - | KTest - | KDoc - - (** Extract generic information - *) + let section_kind_common = function | Library (cs, _, _) -> - KLibrary, cs + `Library, cs | Executable (cs, _, _) -> - KExecutable, cs + `Executable, cs | Flag (cs, _) -> - KFlag, cs + `Flag, cs | SrcRepo (cs, _) -> - KSrcRepo, cs + `SrcRepo, cs | Test (cs, _) -> - KTest, cs + `Test, cs | Doc (cs, _) -> - KDoc, cs - - (** Common section of a section - *) + `Doc, cs + let section_common sct = snd (section_kind_common sct) - + + let section_common_set cs = + function + | Library (_, bs, lib) -> Library (cs, bs, lib) + | Executable (_, bs, exec) -> Executable (cs, bs, exec) + | Flag (_, flg) -> Flag (cs, flg) + | SrcRepo (_, src_repo) -> SrcRepo (cs, src_repo) + | Test (_, tst) -> Test (cs, tst) + | Doc (_, doc) -> Doc (cs, doc) + (** Key used to identify section *) let section_id sct = @@ -1220,32 +1331,56 @@ module OASISSection = struct section_kind_common sct in k, cs.cs_name - + let string_of_section sct = let k, nm = section_id sct in (match k with - | KLibrary -> "library" - | KExecutable -> "executable" - | KFlag -> "flag" - | KSrcRepo -> "src repository" - | KTest -> "test" - | KDoc -> "doc") + | `Library -> "library" + | `Executable -> "executable" + | `Flag -> "flag" + | `SrcRepo -> "src repository" + | `Test -> "test" + | `Doc -> "doc") ^" "^nm - + + let section_find id scts = + List.find + (fun sct -> id = section_id sct) + scts + + module CSection = + struct + type t = section + + let id = section_id + + let compare t1 t2 = + compare (id t1) (id t2) + + let equal t1 t2 = + (id t1) = (id t2) + + let hash t = + Hashtbl.hash (id t) + end + + module MapSection = Map.Make(CSection) + module SetSection = Set.Make(CSection) + end module OASISBuildSection = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISBuildSection.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISBuildSection.ml" *) + end module OASISExecutable = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISExecutable.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISExecutable.ml" *) + open OASISTypes - + let unix_exec_is (cs, bs, exec) is_native ext_dll suffix_program = let dir = OASISUnixPath.concat @@ -1258,321 +1393,765 @@ module OASISExecutable = struct | Best -> is_native () | Byte -> false in - + OASISUnixPath.concat dir (cs.cs_name^(suffix_program ())), - + if not is_native_exec && not exec.exec_custom && bs.bs_c_sources <> [] then - Some (dir^"/dll"^cs.cs_name^(ext_dll ())) + Some (dir^"/dll"^cs.cs_name^"_stubs"^(ext_dll ())) else None - + end module OASISLibrary = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISLibrary.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISLibrary.ml" *) + open OASISTypes open OASISUtils open OASISGettext - + open OASISSection + type library_name = name - - let generated_unix_files ~ctxt (cs, bs, lib) - source_file_exists is_native ext_lib ext_dll = - (* The headers that should be compiled along *) - let headers = + type findlib_part_name = name + type 'a map_of_findlib_part_name = 'a OASISUtils.MapString.t + + exception InternalLibraryNotFound of library_name + exception FindlibPackageNotFound of findlib_name + + type group_t = + | Container of findlib_name * group_t list + | Package of (findlib_name * + common_section * + build_section * + library * + group_t list) + + (* Look for a module file, considering capitalization or not. *) + let find_module source_file_exists (cs, bs, lib) modul = + let possible_base_fn = + List.map + (OASISUnixPath.concat bs.bs_path) + [modul; + OASISUnixPath.uncapitalize_file modul; + OASISUnixPath.capitalize_file modul] + in + (* TODO: we should be able to be able to determine the source for every + * files. Hence we should introduce a Module(source: fn) for the fields + * Modules and InternalModules + *) List.fold_left - (fun hdrs modul -> - try - let base_fn = - List.find - (fun fn -> - source_file_exists (fn^".ml") || - source_file_exists (fn^".mli") || - source_file_exists (fn^".mll") || - source_file_exists (fn^".mly")) - (List.map - (OASISUnixPath.concat bs.bs_path) - [modul; - String.uncapitalize modul; - String.capitalize modul]) - in - [base_fn^".cmi"] :: hdrs - with Not_found -> - OASISMessage.warning - ~ctxt - (f_ "Cannot find source file matching \ - module '%s' in library %s") - modul cs.cs_name; - (List.map (OASISUnixPath.concat bs.bs_path) - [modul^".cmi"; - String.uncapitalize modul ^ ".cmi"; - String.capitalize modul ^ ".cmi"]) - :: hdrs) + (fun acc base_fn -> + match acc with + | `No_sources _ -> + begin + let file_found = + List.fold_left + (fun acc ext -> + if source_file_exists (base_fn^ext) then + (base_fn^ext) :: acc + else + acc) + [] + [".ml"; ".mli"; ".mll"; ".mly"] + in + match file_found with + | [] -> + acc + | lst -> + `Sources (base_fn, lst) + end + | `Sources _ -> + acc) + (`No_sources possible_base_fn) + possible_base_fn + + let source_unix_files ~ctxt (cs, bs, lib) source_file_exists = + List.fold_left + (fun acc modul -> + match find_module source_file_exists (cs, bs, lib) modul with + | `Sources (base_fn, lst) -> + (base_fn, lst) :: acc + | `No_sources _ -> + OASISMessage.warning + ~ctxt + (f_ "Cannot find source file matching \ + module '%s' in library %s") + modul cs.cs_name; + acc) + [] + (lib.lib_modules @ lib.lib_internal_modules) + + let generated_unix_files + ~ctxt + ~is_native + ~has_native_dynlink + ~ext_lib + ~ext_dll + ~source_file_exists + (cs, bs, lib) = + + let find_modules lst ext = + let find_module modul = + match find_module source_file_exists (cs, bs, lib) modul with + | `Sources (base_fn, _) -> + [base_fn] + | `No_sources lst -> + OASISMessage.warning + ~ctxt + (f_ "Cannot find source file matching \ + module '%s' in library %s") + modul cs.cs_name; + lst + in + List.map + (fun nm -> + List.map + (fun base_fn -> base_fn ^"."^ext) + (find_module nm)) + lst + in + + (* The headers that should be compiled along *) + let headers = + if lib.lib_pack then [] - lib.lib_modules + else + find_modules + lib.lib_modules + "cmi" + in + + (* The .cmx that be compiled along *) + let cmxs = + let should_be_built = + (not lib.lib_pack) && (* Do not install .cmx packed submodules *) + match bs.bs_compiled_object with + | Native -> true + | Best -> is_native + | Byte -> false + in + if should_be_built then + find_modules + (lib.lib_modules @ lib.lib_internal_modules) + "cmx" + else + [] in - + let acc_nopath = [] in - + (* Compute what libraries should be built *) let acc_nopath = + (* Add the packed header file if required *) + let add_pack_header acc = + if lib.lib_pack then + [cs.cs_name^".cmi"] :: acc + else + acc + in let byte acc = - [cs.cs_name^".cma"] :: acc + add_pack_header ([cs.cs_name^".cma"] :: acc) in let native acc = - [cs.cs_name^".cmxa"] :: [cs.cs_name^(ext_lib ())] :: acc + let acc = + add_pack_header + (if has_native_dynlink then + [cs.cs_name^".cmxs"] :: acc + else acc) + in + [cs.cs_name^".cmxa"] :: [cs.cs_name^ext_lib] :: acc in - match bs.bs_compiled_object with + match bs.bs_compiled_object with | Native -> byte (native acc_nopath) - | Best when is_native () -> + | Best when is_native -> byte (native acc_nopath) | Byte | Best -> byte acc_nopath in - + (* Add C library to be built *) - let acc_nopath = + let acc_nopath = if bs.bs_c_sources <> [] then begin - ["lib"^cs.cs_name^(ext_lib ())] + ["lib"^cs.cs_name^"_stubs"^ext_lib] :: - ["dll"^cs.cs_name^(ext_dll ())] + ["dll"^cs.cs_name^"_stubs"^ext_dll] :: acc_nopath end else acc_nopath in - + (* All the files generated *) List.rev_append (List.rev_map (List.rev_map (OASISUnixPath.concat bs.bs_path)) acc_nopath) - headers - - - type group_t = - | Container of findlib_name * (group_t list) - | Package of (findlib_name * - common_section * - build_section * - library * - (group_t list)) - - let group_libs pkg = - (** Associate a name with its children *) - let children = + (headers @ cmxs) + + type data = common_section * build_section * library + type tree = + | Node of (data option) * (tree MapString.t) + | Leaf of data + + let findlib_mapping pkg = + (* Map from library name to either full findlib name or parts + parent. *) + let fndlb_parts_of_lib_name = + let fndlb_parts cs lib = + let name = + match lib.lib_findlib_name with + | Some nm -> nm + | None -> cs.cs_name + in + let name = + String.concat "." (lib.lib_findlib_containers @ [name]) + in + name + in + List.fold_left + (fun mp -> + function + | Library (cs, _, lib) -> + begin + let lib_name = cs.cs_name in + let fndlb_parts = fndlb_parts cs lib in + if MapString.mem lib_name mp then + failwithf + (f_ "The library name '%s' is used more than once.") + lib_name; + match lib.lib_findlib_parent with + | Some lib_name_parent -> + MapString.add + lib_name + (`Unsolved (lib_name_parent, fndlb_parts)) + mp + | None -> + MapString.add + lib_name + (`Solved fndlb_parts) + mp + end + + | Executable _ | Test _ | Flag _ | SrcRepo _ | Doc _ -> + mp) + MapString.empty + pkg.sections + in + + (* Solve the above graph to be only library name to full findlib name. *) + let fndlb_name_of_lib_name = + let rec solve visited mp lib_name lib_name_child = + if SetString.mem lib_name visited then + failwithf + (f_ "Library '%s' is involved in a cycle \ + with regard to findlib naming.") + lib_name; + let visited = SetString.add lib_name visited in + try + match MapString.find lib_name mp with + | `Solved fndlb_nm -> + fndlb_nm, mp + | `Unsolved (lib_nm_parent, post_fndlb_nm) -> + let pre_fndlb_nm, mp = + solve visited mp lib_nm_parent lib_name + in + let fndlb_nm = pre_fndlb_nm^"."^post_fndlb_nm in + fndlb_nm, MapString.add lib_name (`Solved fndlb_nm) mp + with Not_found -> + failwithf + (f_ "Library '%s', which is defined as the findlib parent of \ + library '%s', doesn't exist.") + lib_name lib_name_child + in + let mp = + MapString.fold + (fun lib_name status mp -> + match status with + | `Solved _ -> + (* Solved initialy, no need to go further *) + mp + | `Unsolved _ -> + let _, mp = solve SetString.empty mp lib_name "<none>" in + mp) + fndlb_parts_of_lib_name + fndlb_parts_of_lib_name + in + MapString.map + (function + | `Solved fndlb_nm -> fndlb_nm + | `Unsolved _ -> assert false) + mp + in + + (* Convert an internal library name to a findlib name. *) + let findlib_name_of_library_name lib_nm = + try + MapString.find lib_nm fndlb_name_of_lib_name + with Not_found -> + raise (InternalLibraryNotFound lib_nm) + in + + (* Add a library to the tree. + *) + let add sct mp = + let fndlb_fullname = + let cs, _, _ = sct in + let lib_name = cs.cs_name in + findlib_name_of_library_name lib_name + in + let rec add_children nm_lst (children : tree MapString.t) = + match nm_lst with + | (hd :: tl) -> + begin + let node = + try + add_node tl (MapString.find hd children) + with Not_found -> + (* New node *) + new_node tl + in + MapString.add hd node children + end + | [] -> + (* Should not have a nameless library. *) + assert false + and add_node tl node = + if tl = [] then + begin + match node with + | Node (None, children) -> + Node (Some sct, children) + | Leaf (cs', _, _) | Node (Some (cs', _, _), _) -> + (* TODO: allow to merge Package, i.e. + * archive(byte) = "foo.cma foo_init.cmo" + *) + let cs, _, _ = sct in + failwithf + (f_ "Library '%s' and '%s' have the same findlib name '%s'") + cs.cs_name cs'.cs_name fndlb_fullname + end + else + begin + match node with + | Leaf data -> + Node (Some data, add_children tl MapString.empty) + | Node (data_opt, children) -> + Node (data_opt, add_children tl children) + end + and new_node = + function + | [] -> + Leaf sct + | hd :: tl -> + Node (None, MapString.add hd (new_node tl) MapString.empty) + in + add_children (OASISString.nsplit fndlb_fullname '.') mp + in + + let rec group_of_tree mp = + MapString.fold + (fun nm node acc -> + let cur = + match node with + | Node (Some (cs, bs, lib), children) -> + Package (nm, cs, bs, lib, group_of_tree children) + | Node (None, children) -> + Container (nm, group_of_tree children) + | Leaf (cs, bs, lib) -> + Package (nm, cs, bs, lib, []) + in + cur :: acc) + mp [] + in + + let group_mp = List.fold_left (fun mp -> function | Library (cs, bs, lib) -> - begin - match lib.lib_findlib_parent with - | Some p_nm -> - begin - let children = - try - MapString.find p_nm mp - with Not_found -> - [] - in - MapString.add p_nm ((cs, bs, lib) :: children) mp - end - | None -> - mp - end + add (cs, bs, lib) mp | _ -> mp) MapString.empty pkg.sections in - - (* Compute findlib name of a single node *) - let findlib_name (cs, _, lib) = - match lib.lib_findlib_name with - | Some nm -> nm - | None -> cs.cs_name - in - - (** Build a package tree *) - let rec tree_of_library containers ((cs, bs, lib) as acc) = - match containers with - | hd :: tl -> - Container (hd, [tree_of_library tl acc]) - | [] -> - (* TODO: allow merging containers with the same - * name - *) - Package - (findlib_name acc, cs, bs, lib, - (try - List.rev_map - (fun ((_, _, child_lib) as child_acc) -> - tree_of_library - child_lib.lib_findlib_containers - child_acc) - (MapString.find cs.cs_name children) - with Not_found -> - [])) + + let groups = + group_of_tree group_mp in - - (* TODO: check that libraries are unique *) - List.fold_left - (fun acc -> - function - | Library (cs, bs, lib) when lib.lib_findlib_parent = None -> - (tree_of_library lib.lib_findlib_containers (cs, bs, lib)) :: acc - | _ -> - acc) - [] - pkg.sections - - (** Compute internal to findlib library matchings, including subpackage - and return a map of it. - *) - let findlib_name_map pkg = - - (* Compute names in a tree *) - let rec findlib_names_aux path mp grp = - let fndlb_nm, children, mp = - match grp with - | Container (fndlb_nm, children) -> - fndlb_nm, children, mp - - | Package (fndlb_nm, {cs_name = nm}, _, _, children) -> - fndlb_nm, children, (MapString.add nm (path, fndlb_nm) mp) - in - let fndlb_nm_full = - (match path with - | Some pth -> pth^"." - | None -> "")^ - fndlb_nm - in - List.fold_left - (findlib_names_aux (Some fndlb_nm_full)) - mp - children + + let library_name_of_findlib_name = + Lazy.lazy_from_fun + (fun () -> + (* Revert findlib_name_of_library_name. *) + MapString.fold + (fun k v mp -> MapString.add v k mp) + fndlb_name_of_lib_name + MapString.empty) in - - List.fold_left - (findlib_names_aux None) - MapString.empty - (group_libs pkg) - - - let findlib_of_name ?(recurse=false) map nm = - try - let (path, fndlb_nm) = - MapString.find nm map - in - match path with - | Some pth when recurse -> pth^"."^fndlb_nm - | _ -> fndlb_nm - - with Not_found -> - failwithf1 - (f_ "Unable to translate internal library '%s' to findlib name") - nm - - let name_findlib_map pkg = - let mp = - findlib_name_map pkg + let library_name_of_findlib_name fndlb_nm = + try + MapString.find fndlb_nm (Lazy.force library_name_of_findlib_name) + with Not_found -> + raise (FindlibPackageNotFound fndlb_nm) in - MapString.fold - (fun nm _ acc -> - let fndlb_nm_full = - findlib_of_name - ~recurse:true - mp - nm - in - MapString.add fndlb_nm_full nm acc) - mp - MapString.empty - - let findlib_of_group = + + groups, + findlib_name_of_library_name, + library_name_of_findlib_name + + let findlib_of_group = function - | Container (fndlb_nm, _) + | Container (fndlb_nm, _) | Package (fndlb_nm, _, _, _, _) -> fndlb_nm - + let root_of_group grp = let rec root_lib_aux = - function - | Container (_, children) -> - root_lib_lst children - | Package (_, cs, bs, lib, children) -> - if lib.lib_findlib_parent = None then - cs, bs, lib - else - root_lib_lst children - and root_lib_lst = + (* We do a DFS in the group. *) function - | [] -> - raise Not_found - | hd :: tl -> - try - root_lib_aux hd - with Not_found -> - root_lib_lst tl + | Container (_, children) -> + List.fold_left + (fun res grp -> + if res = None then + root_lib_aux grp + else + res) + None + children + | Package (_, cs, bs, lib, _) -> + Some (cs, bs, lib) in - try - root_lib_aux grp - with Not_found -> - failwithf1 - (f_ "Unable to determine root library of findlib library '%s'") - (findlib_of_group grp) - - + match root_lib_aux grp with + | Some res -> + res + | None -> + failwithf + (f_ "Unable to determine root library of findlib library '%s'") + (findlib_of_group grp) + end module OASISFlag = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISFlag.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISFlag.ml" *) + end module OASISPackage = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISPackage.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISPackage.ml" *) + end module OASISSourceRepository = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISSourceRepository.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISSourceRepository.ml" *) + end module OASISTest = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISTest.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISTest.ml" *) + end module OASISDocument = struct -# 21 "/build/buildd/oasis-0.2.0/src/oasis/OASISDocument.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISDocument.ml" *) + +end + +module OASISExec = struct +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISExec.ml" *) + + open OASISGettext + open OASISUtils + open OASISMessage + + (* TODO: I don't like this quote, it is there because $(rm) foo expands to + * 'rm -f' foo... + *) + let run ~ctxt ?f_exit_code ?(quote=true) cmd args = + let cmd = + if quote then + if Sys.os_type = "Win32" then + if String.contains cmd ' ' then + (* Double the 1st double quote... win32... sigh *) + "\""^(Filename.quote cmd) + else + cmd + else + Filename.quote cmd + else + cmd + in + let cmdline = + String.concat " " (cmd :: args) + in + info ~ctxt (f_ "Running command '%s'") cmdline; + match f_exit_code, Sys.command cmdline with + | None, 0 -> () + | None, i -> + failwithf + (f_ "Command '%s' terminated with error code %d") + cmdline i + | Some f, i -> + f i + + let run_read_output ~ctxt ?f_exit_code cmd args = + let fn = + Filename.temp_file "oasis-" ".txt" + in + try + begin + let () = + run ~ctxt ?f_exit_code cmd (args @ [">"; Filename.quote fn]) + in + let chn = + open_in fn + in + let routput = + ref [] + in + begin + try + while true do + routput := (input_line chn) :: !routput + done + with End_of_file -> + () + end; + close_in chn; + Sys.remove fn; + List.rev !routput + end + with e -> + (try Sys.remove fn with _ -> ()); + raise e + + let run_read_one_line ~ctxt ?f_exit_code cmd args = + match run_read_output ~ctxt ?f_exit_code cmd args with + | [fst] -> + fst + | lst -> + failwithf + (f_ "Command return unexpected output %S") + (String.concat "\n" lst) +end + +module OASISFileUtil = struct +(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISFileUtil.ml" *) + + open OASISGettext + + let file_exists_case fn = + let dirname = Filename.dirname fn in + let basename = Filename.basename fn in + if Sys.file_exists dirname then + if basename = Filename.current_dir_name then + true + else + List.mem + basename + (Array.to_list (Sys.readdir dirname)) + else + false + + let find_file ?(case_sensitive=true) paths exts = + + (* Cardinal product of two list *) + let ( * ) lst1 lst2 = + List.flatten + (List.map + (fun a -> + List.map + (fun b -> a,b) + lst2) + lst1) + in + + let rec combined_paths lst = + match lst with + | p1 :: p2 :: tl -> + let acc = + (List.map + (fun (a,b) -> Filename.concat a b) + (p1 * p2)) + in + combined_paths (acc :: tl) + | [e] -> + e + | [] -> + [] + in + + let alternatives = + List.map + (fun (p,e) -> + if String.length e > 0 && e.[0] <> '.' then + p ^ "." ^ e + else + p ^ e) + ((combined_paths paths) * exts) + in + List.find + (if case_sensitive then + file_exists_case + else + Sys.file_exists) + alternatives + + let which ~ctxt prg = + let path_sep = + match Sys.os_type with + | "Win32" -> + ';' + | _ -> + ':' + in + let path_lst = OASISString.nsplit (Sys.getenv "PATH") path_sep in + let exec_ext = + match Sys.os_type with + | "Win32" -> + "" :: (OASISString.nsplit (Sys.getenv "PATHEXT") path_sep) + | _ -> + [""] + in + find_file ~case_sensitive:false [path_lst; [prg]] exec_ext + + (**/**) + let rec fix_dir dn = + (* Windows hack because Sys.file_exists "src\\" = false when + * Sys.file_exists "src" = true + *) + let ln = + String.length dn + in + if Sys.os_type = "Win32" && ln > 0 && dn.[ln - 1] = '\\' then + fix_dir (String.sub dn 0 (ln - 1)) + else + dn + + let q = Filename.quote + (**/**) + + let cp ~ctxt ?(recurse=false) src tgt = + if recurse then + match Sys.os_type with + | "Win32" -> + OASISExec.run ~ctxt + "xcopy" [q src; q tgt; "/E"] + | _ -> + OASISExec.run ~ctxt + "cp" ["-r"; q src; q tgt] + else + OASISExec.run ~ctxt + (match Sys.os_type with + | "Win32" -> "copy" + | _ -> "cp") + [q src; q tgt] + + let mkdir ~ctxt tgt = + OASISExec.run ~ctxt + (match Sys.os_type with + | "Win32" -> "md" + | _ -> "mkdir") + [q tgt] + + let rec mkdir_parent ~ctxt f tgt = + let tgt = + fix_dir tgt + in + if Sys.file_exists tgt then + begin + if not (Sys.is_directory tgt) then + OASISUtils.failwithf + (f_ "Cannot create directory '%s', a file of the same name already \ + exists") + tgt + end + else + begin + mkdir_parent ~ctxt f (Filename.dirname tgt); + if not (Sys.file_exists tgt) then + begin + f tgt; + mkdir ~ctxt tgt + end + end + + let rmdir ~ctxt tgt = + if Sys.readdir tgt = [||] then + begin + match Sys.os_type with + | "Win32" -> + OASISExec.run ~ctxt "rd" [q tgt] + | _ -> + OASISExec.run ~ctxt "rm" ["-r"; q tgt] + end + + let glob ~ctxt fn = + let basename = + Filename.basename fn + in + if String.length basename >= 2 && + basename.[0] = '*' && + basename.[1] = '.' then + begin + let ext_len = + (String.length basename) - 2 + in + let ext = + String.sub basename 2 ext_len + in + let dirname = + Filename.dirname fn + in + Array.fold_left + (fun acc fn -> + try + let fn_ext = + String.sub + fn + ((String.length fn) - ext_len) + ext_len + in + if fn_ext = ext then + (Filename.concat dirname fn) :: acc + else + acc + with Invalid_argument _ -> + acc) + [] + (Sys.readdir dirname) + end + else + begin + if file_exists_case fn then + [fn] + else + [] + end end +# 2142 "setup.ml" module BaseEnvLight = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseEnvLight.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseEnvLight.ml" *) + module MapString = Map.Make(String) - + type t = string MapString.t - + let default_filename = - Filename.concat + Filename.concat (Sys.getcwd ()) "setup.data" - + let load ?(allow_empty=false) ?(filename=default_filename) () = if Sys.file_exists filename then begin @@ -1585,23 +2164,23 @@ module BaseEnvLight = struct let line = ref 1 in - let st_line = + let st_line = Stream.from (fun _ -> try - match Stream.next st with + match Stream.next st with | '\n' -> incr line; Some '\n' | c -> Some c with Stream.Failure -> None) in - let lexer = + let lexer = Genlex.make_lexer ["="] st_line in let rec read_file mp = - match Stream.npeek 3 lexer with + match Stream.npeek 3 lexer with | [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] -> - Stream.junk lexer; - Stream.junk lexer; + Stream.junk lexer; + Stream.junk lexer; Stream.junk lexer; read_file (MapString.add nm value mp) | [] -> @@ -1624,127 +2203,93 @@ module BaseEnvLight = struct end else begin - failwith - (Printf.sprintf + failwith + (Printf.sprintf "Unable to load environment, the file '%s' doesn't exist." filename) end - + let var_get name env = let rec var_expand str = let buff = Buffer.create ((String.length str) * 2) in - Buffer.add_substitute + Buffer.add_substitute buff - (fun var -> - try + (fun var -> + try var_expand (MapString.find var env) with Not_found -> - failwith - (Printf.sprintf + failwith + (Printf.sprintf "No variable %s defined when trying to expand %S." - var + var str)) str; Buffer.contents buff in var_expand (MapString.find name env) - - let var_choose lst env = + + let var_choose lst env = OASISExpr.choose (fun nm -> var_get nm env) lst end +# 2240 "setup.ml" module BaseContext = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseContext.ml" - - open OASISContext - - let args = args - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseContext.ml" *) + + open OASISContext + + let args = args + let default = default - + end module BaseMessage = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseMessage.ml" - - (** Message to user, overrid for Base +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseMessage.ml" *) + + (** Message to user, overrid for Base @author Sylvain Le Gall *) open OASISMessage open BaseContext - + let debug fmt = debug ~ctxt:!default fmt - + let info fmt = info ~ctxt:!default fmt - + let warning fmt = warning ~ctxt:!default fmt - + let error fmt = error ~ctxt:!default fmt - - let string_of_exception = string_of_exception - -end -module BaseFilePath = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseFilePath.ml" - - - open Filename - - module Unix = OASISUnixPath - - let make = - function - | [] -> - invalid_arg "BaseFilename.make" - | hd :: tl -> - List.fold_left Filename.concat hd tl - - let of_unix ufn = - if Sys.os_type = "Unix" then - ufn - else - make - (List.map - (fun p -> - if p = Unix.current_dir_name then - current_dir_name - else if p = Unix.parent_dir_name then - parent_dir_name - else - p) - (OASISUtils.split '/' ufn)) - end module BaseEnv = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseEnv.ml" - - open OASISTypes +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseEnv.ml" *) + open OASISGettext open OASISUtils open PropList - + module MapString = BaseEnvLight.MapString - - type origin_t = + + type origin_t = | ODefault | OGetEnv | OFileLoad | OCommandLine - + type cli_handle_t = | CLINone | CLIAuto | CLIWith | CLIEnable | CLIUser of (Arg.key * Arg.spec * Arg.doc) list - + type definition_t = { hide: bool; @@ -1753,45 +2298,45 @@ module BaseEnv = struct arg_help: string option; group: string option; } - + let schema = Schema.create "environment" - + (* Environment data *) - let env = + let env = Data.create () - + (* Environment data from file *) - let env_from_file = + let env_from_file = ref MapString.empty - + (* Lexer for var *) - let var_lxr = + let var_lxr = Genlex.make_lexer [] - + let rec var_expand str = let buff = Buffer.create ((String.length str) * 2) in - Buffer.add_substitute + Buffer.add_substitute buff - (fun var -> - try - (* TODO: this is a quick hack to allow calling Test.Command + (fun var -> + try + (* TODO: this is a quick hack to allow calling Test.Command * without defining executable name really. I.e. if there is * an exec Executable toto, then $(toto) should be replace * by its real name. It is however useful to have this function - * for other variable that depend on the host and should be + * for other variable that depend on the host and should be * written better than that. *) let st = var_lxr (Stream.of_string var) in - match Stream.npeek 3 st with + match Stream.npeek 3 st with | [Genlex.Ident "utoh"; Genlex.Ident nm] -> - BaseFilePath.of_unix (var_get nm) + OASISHostPath.of_unix (var_get nm) | [Genlex.Ident "utoh"; Genlex.String s] -> - BaseFilePath.of_unix s + OASISHostPath.of_unix s | [Genlex.Ident "ocaml_escaped"; Genlex.Ident nm] -> String.escaped (var_get nm) | [Genlex.Ident "ocaml_escaped"; Genlex.String s] -> @@ -1799,18 +2344,18 @@ module BaseEnv = struct | [Genlex.Ident nm] -> var_get nm | _ -> - failwithf2 + failwithf (f_ "Unknown expression '%s' in variable expansion of %s.") var str - with + with | Unknown_field (_, _) -> - failwithf2 + failwithf (f_ "No variable %s defined when trying to expand %S.") - var + var str - | Stream.Error e -> - failwithf3 + | Stream.Error e -> + failwithf (f_ "Syntax error when parsing '%s' when trying to \ expand %S: %s") var @@ -1818,59 +2363,59 @@ module BaseEnv = struct e) str; Buffer.contents buff - + and var_get name = - let vl = - try + let vl = + try Schema.get schema env name with Unknown_field _ as e -> begin - try + try MapString.find name !env_from_file with Not_found -> raise e end in var_expand vl - + let var_choose ?printer ?name lst = - OASISExpr.choose + OASISExpr.choose ?printer ?name - var_get + var_get lst - - let var_protect vl = - let buff = + + let var_protect vl = + let buff = Buffer.create (String.length vl) in String.iter - (function + (function | '$' -> Buffer.add_string buff "\\$" | c -> Buffer.add_char buff c) vl; Buffer.contents buff - - let var_define - ?(hide=false) - ?(dump=true) + + let var_define + ?(hide=false) + ?(dump=true) ?short_desc ?(cli=CLINone) ?arg_help - ?group + ?group name (* TODO: type constraint on the fact that name must be a valid OCaml id *) dflt = - + let default = [ - OFileLoad, lazy (MapString.find name !env_from_file); + OFileLoad, (fun () -> MapString.find name !env_from_file); ODefault, dflt; - OGetEnv, lazy (Sys.getenv name); + OGetEnv, (fun () -> Sys.getenv name); ] in - - let extra = + + let extra = { hide = hide; dump = dump; @@ -1879,17 +2424,17 @@ module BaseEnv = struct group = group; } in - - (* Try to find a value that can be defined + + (* Try to find a value that can be defined *) - let var_get_low lst = + let var_get_low lst = let errors, res = List.fold_left - (fun (errors, res) (_, v) -> + (fun (errors, res) (o, v) -> if res = None then begin - try - errors, Some (Lazy.force v) + try + errors, Some (v ()) with | Not_found -> errors, res @@ -1903,15 +2448,10 @@ module BaseEnv = struct ([], None) (List.sort (fun (o1, _) (o2, _) -> - if o1 < o2 then - 1 - else if o1 = o2 then - 0 - else - -1) + Pervasives.compare o2 o1) lst) in - match res, errors with + match res, errors with | Some v, _ -> v | None, [] -> @@ -1919,126 +2459,138 @@ module BaseEnv = struct | None, lst -> raise (Not_set (name, Some (String.concat (s_ ", ") lst))) in - + let help = - match short_desc with + match short_desc with | Some fs -> Some fs | None -> None in - - let var_get_lst = + + let var_get_lst = FieldRO.create ~schema ~name - ~parse:(fun ?(context=ODefault) s -> [context, lazy s]) + ~parse:(fun ?(context=ODefault) s -> [context, fun () -> s]) ~print:var_get_low ~default ~update:(fun ?context x old_x -> x @ old_x) ?help extra in - + fun () -> var_expand (var_get_low (var_get_lst env)) - - let var_redefine + + let var_redefine ?hide ?dump ?short_desc ?cli ?arg_help - ?group - name + ?group + name dflt = if Schema.mem schema name then begin - Schema.set schema env ~context:ODefault name (Lazy.force dflt); + (* TODO: look suspsicious, we want to memorize dflt not dflt () *) + Schema.set schema env ~context:ODefault name (dflt ()); fun () -> var_get name end else begin - var_define + var_define ?hide ?dump ?short_desc ?cli ?arg_help - ?group - name + ?group + name dflt end - - let var_ignore (e : unit -> string) = + + let var_ignore (e : unit -> string) = () - + let print_hidden = - var_define + var_define ~hide:true ~dump:false ~cli:CLIAuto ~arg_help:"Print even non-printable variable. (debug)" "print_hidden" - (lazy "false") - + (fun () -> "false") + let var_all () = List.rev (Schema.fold - (fun acc nm def _ -> + (fun acc nm def _ -> if not def.hide || bool_of_string (print_hidden ()) then nm :: acc else acc) [] schema) - + let default_filename = BaseEnvLight.default_filename - + let load ?allow_empty ?filename () = env_from_file := BaseEnvLight.load ?allow_empty ?filename () - - let unload () = - (* TODO: reset lazy values *) + + let unload () = env_from_file := MapString.empty; Data.clear env - - let dump ?(filename=default_filename) () = + + let dump ?(filename=default_filename) () = let chn = open_out_bin filename in - Schema.iter - (fun nm def _ -> + let output nm value = + Printf.fprintf chn "%s=%S\n" nm value + in + let mp_todo = + (* Dump data from schema *) + Schema.fold + (fun mp_todo nm def _ -> if def.dump then begin - try + try let value = - Schema.get - schema - env + Schema.get + schema + env nm in - Printf.fprintf chn "%s = %S\n" nm value + output nm value with Not_set _ -> () - end) - schema; + end; + MapString.remove nm mp_todo) + !env_from_file + schema + in + (* Dump data defined outside of schema *) + MapString.iter output mp_todo; + + (* End of the dump *) close_out chn - + let print () = let printable_vars = Schema.fold - (fun acc nm def short_descr_opt -> + (fun acc nm def short_descr_opt -> if not def.hide || bool_of_string (print_hidden ()) then begin - try - let value = - Schema.get + try + let value = + Schema.get schema env nm in - let txt = - match short_descr_opt with + let txt = + match short_descr_opt with | Some s -> s () | None -> nm in @@ -2051,7 +2603,7 @@ module BaseEnv = struct [] schema in - let max_length = + let max_length = List.fold_left max 0 (List.rev_map String.length (List.rev_map fst printable_vars)) @@ -2059,17 +2611,14 @@ module BaseEnv = struct let dot_pad str = String.make ((max_length - (String.length str)) + 3) '.' in - - print_newline (); - print_endline "Configuration: "; - print_newline (); - List.iter - (fun (name,value) -> - Printf.printf "%s: %s %s\n" name (dot_pad name) value) - printable_vars; - Printf.printf "%!"; - print_newline () - + + Printf.printf "\nConfiguration: \n"; + List.iter + (fun (name,value) -> + Printf.printf "%s: %s %s\n" name (dot_pad name) value) + (List.rev printable_vars); + Printf.printf "\n%!" + let args () = let arg_concat = OASISUtils.varname_concat ~hyphen:'-' @@ -2085,65 +2634,65 @@ module BaseEnv = struct [ Arg.Set_string rvr; Arg.Set_string rvl; - Arg.Unit - (fun () -> - Schema.set + Arg.Unit + (fun () -> + Schema.set schema env - ~context:OCommandLine + ~context:OCommandLine !rvr !rvl) ] ), "var+val Override any configuration variable."; - + ] @ - List.flatten + List.flatten (Schema.fold (fun acc name def short_descr_opt -> - let var_set s = - Schema.set + let var_set s = + Schema.set schema env - ~context:OCommandLine + ~context:OCommandLine name s in - - let arg_name = + + let arg_name = OASISUtils.varname_of_string ~hyphen:'-' name in - + let hlp = - match short_descr_opt with + match short_descr_opt with | Some txt -> txt () | None -> "" in - + let arg_hlp = - match def.arg_help with + match def.arg_help with | Some s -> s | None -> "str" in - - let default_value = - try - Printf.sprintf + + let default_value = + try + Printf.sprintf (f_ " [%s]") (Schema.get schema env name) - with Not_set _ -> + with Not_set _ -> "" in - - let args = - match def.cli with - | CLINone -> + + let args = + match def.cli with + | CLINone -> [] - | CLIAuto -> + | CLIAuto -> [ arg_concat "--" arg_name, Arg.String var_set, @@ -2156,23 +2705,21 @@ module BaseEnv = struct Printf.sprintf (f_ "%s %s%s") arg_hlp hlp default_value ] | CLIEnable -> - [ - arg_concat "--enable-" arg_name, - Arg.Unit (fun () -> var_set "true"), - Printf.sprintf (f_ " %s%s") hlp - (if default_value = " [true]" then - (s_ " [default]") - else - ""); - - arg_concat "--disable-" arg_name, - Arg.Unit (fun () -> var_set "false"), - Printf.sprintf (f_ " %s%s") hlp - (if default_value = " [false]" then - (s_ " [default]") - else - ""); - ] + let dflt = + if default_value = " [true]" then + s_ " [default: enabled]" + else + s_ " [default: disabled]" + in + [ + arg_concat "--enable-" arg_name, + Arg.Unit (fun () -> var_set "true"), + Printf.sprintf (f_ " %s%s") hlp dflt; + + arg_concat "--disable-" arg_name, + Arg.Unit (fun () -> var_set "false"), + Printf.sprintf (f_ " %s%s") hlp dflt + ] | CLIUser lst -> lst in @@ -2181,264 +2728,26 @@ module BaseEnv = struct schema) end -module BaseExec = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseExec.ml" - - open OASISGettext - open OASISUtils - open BaseMessage - - let run ?f_exit_code cmd args = - let cmdline = - String.concat " " (cmd :: args) - in - info (f_ "Running command '%s'") cmdline; - match f_exit_code, Sys.command cmdline with - | None, 0 -> () - | None, i -> - failwithf2 - (f_ "Command '%s' terminated with error code %d") - cmdline i - | Some f, i -> - f i - - let run_read_output cmd args = - let fn = - Filename.temp_file "oasis-" ".txt" - in - let () = - try - run cmd (args @ [">"; Filename.quote fn]) - with e -> - Sys.remove fn; - raise e - in - let chn = - open_in fn - in - let routput = - ref [] - in - ( - try - while true do - routput := (input_line chn) :: !routput - done - with End_of_file -> - () - ); - close_in chn; - Sys.remove fn; - List.rev !routput - - let run_read_one_line cmd args = - match run_read_output cmd args with - | [fst] -> - fst - | lst -> - failwithf1 - (f_ "Command return unexpected output %S") - (String.concat "\n" lst) -end - -module BaseFileUtil = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseFileUtil.ml" - - open OASISGettext - - let find_file paths exts = - - (* Cardinal product of two list *) - let ( * ) lst1 lst2 = - List.flatten - (List.map - (fun a -> - List.map - (fun b -> a,b) - lst2) - lst1) - in - - let rec combined_paths lst = - match lst with - | p1 :: p2 :: tl -> - let acc = - (List.map - (fun (a,b) -> Filename.concat a b) - (p1 * p2)) - in - combined_paths (acc :: tl) - | [e] -> - e - | [] -> - [] - in - - let alternatives = - List.map - (fun (p,e) -> - if String.length e > 0 && e.[0] <> '.' then - p ^ "." ^ e - else - p ^ e) - ((combined_paths paths) * exts) - in - List.find - Sys.file_exists - alternatives - - let which prg = - let path_sep = - match Sys.os_type with - | "Win32" -> - ';' - | _ -> - ':' - in - let path_lst = - OASISUtils.split - path_sep - (Sys.getenv "PATH") - in - let exec_ext = - match Sys.os_type with - | "Win32" -> - "" - :: - (OASISUtils.split - path_sep - (Sys.getenv "PATHEXT")) - | _ -> - [""] - in - find_file [path_lst; [prg]] exec_ext - - (**/**) - let rec fix_dir dn = - (* Windows hack because Sys.file_exists "src\\" = false when - * Sys.file_exists "src" = true - *) - let ln = - String.length dn - in - if Sys.os_type = "Win32" && ln > 0 && dn.[ln - 1] = '\\' then - fix_dir (String.sub dn 0 (ln - 1)) - else - dn - - let q = Filename.quote - (**/**) - - let cp src tgt = - BaseExec.run - (match Sys.os_type with - | "Win32" -> "copy" - | _ -> "cp") - [q src; q tgt] - - let mkdir tgt = - BaseExec.run - (match Sys.os_type with - | "Win32" -> "md" - | _ -> "mkdir") - [q tgt] - - let rec mkdir_parent f tgt = - let tgt = - fix_dir tgt - in - if Sys.file_exists tgt then - begin - if not (Sys.is_directory tgt) then - OASISUtils.failwithf1 - (f_ "Cannot create directory '%s', a file of the same name already \ - exists") - tgt - end - else - begin - mkdir_parent f (Filename.dirname tgt); - if not (Sys.file_exists tgt) then - begin - f tgt; - mkdir tgt - end - end - - let rmdir tgt = - if Sys.readdir tgt = [||] then - begin - match Sys.os_type with - | "Win32" -> - BaseExec.run "rd" [q tgt] - | _ -> - BaseExec.run "rm" ["-r"; q tgt] - end - - let glob fn = - let basename = - Filename.basename fn - in - if String.length basename >= 2 && - basename.[0] = '*' && - basename.[1] = '.' then - begin - let ext_len = - (String.length basename) - 2 - in - let ext = - String.sub basename 2 ext_len - in - let dirname = - Filename.dirname fn - in - Array.fold_left - (fun acc fn -> - try - let fn_ext = - String.sub - fn - ((String.length fn) - ext_len) - ext_len - in - if fn_ext = ext then - (Filename.concat dirname fn) :: acc - else - acc - with Invalid_argument _ -> - acc) - [] - (Sys.readdir dirname) - end - else - begin - if Sys.file_exists fn then - [fn] - else - [] - end -end - module BaseArgExt = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseArgExt.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseArgExt.ml" *) + open OASISUtils open OASISGettext - + let parse argv args = (* Simulate command line for Arg *) let current = ref 0 in - + try Arg.parse_argv ~current:current (Array.concat [[|"none"|]; argv]) (Arg.align args) - (failwithf1 (f_ "Don't know what to do with arguments: '%s'")) + (failwithf (f_ "Don't know what to do with arguments: '%s'")) (s_ "configure options:") - with + with | Arg.Help txt -> print_endline txt; exit 0 @@ -2448,106 +2757,106 @@ module BaseArgExt = struct end module BaseCheck = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseCheck.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseCheck.ml" *) + open BaseEnv open BaseMessage open OASISUtils open OASISGettext - + let prog_best prg prg_lst = var_redefine - prg - (lazy - (let alternate = - List.fold_left - (fun res e -> - match res with - | Some _ -> - res - | None -> - try - Some (BaseFileUtil.which e) - with Not_found -> - None) - None - prg_lst - in - match alternate with - | Some prg -> prg - | None -> raise Not_found)) - + prg + (fun () -> + let alternate = + List.fold_left + (fun res e -> + match res with + | Some _ -> + res + | None -> + try + Some (OASISFileUtil.which ~ctxt:!BaseContext.default e) + with Not_found -> + None) + None + prg_lst + in + match alternate with + | Some prg -> prg + | None -> raise Not_found) + let prog prg = prog_best prg [prg] - - let prog_opt prg = + + let prog_opt prg = prog_best prg [prg^".opt"; prg] - - let ocamlfind = + + let ocamlfind = prog "ocamlfind" - - let version - var_prefix + + let version + var_prefix cmp - fversion - () = + fversion + () = (* Really compare version provided *) - let var = + let var = var_prefix^"_version_"^(OASISVersion.varname_of_comparator cmp) in - var_redefine - ~hide:true + var_redefine + ~hide:true var - (lazy - (let version_str = - match fversion () with - | "[Distributed with OCaml]" -> - begin - try - (var_get "ocaml_version") - with Not_found -> - warning - (f_ "Variable ocaml_version not defined, fallback \ - to default"); - Sys.ocaml_version - end - | res -> - res - in - let version = - OASISVersion.version_of_string version_str - in - if OASISVersion.comparator_apply version cmp then - version_str - else - failwithf3 - (f_ "Cannot satisfy version constraint on %s: %s (version: %s)") - var_prefix - (OASISVersion.string_of_comparator cmp) - version_str)) + (fun () -> + let version_str = + match fversion () with + | "[Distributed with OCaml]" -> + begin + try + (var_get "ocaml_version") + with Not_found -> + warning + (f_ "Variable ocaml_version not defined, fallback \ + to default"); + Sys.ocaml_version + end + | res -> + res + in + let version = + OASISVersion.version_of_string version_str + in + if OASISVersion.comparator_apply version cmp then + version_str + else + failwithf + (f_ "Cannot satisfy version constraint on %s: %s (version: %s)") + var_prefix + (OASISVersion.string_of_comparator cmp) + version_str) () - + let package_version pkg = - BaseExec.run_read_one_line + OASISExec.run_read_one_line ~ctxt:!BaseContext.default (ocamlfind ()) ["query"; "-format"; "%v"; pkg] - + let package ?version_comparator pkg () = let var = - OASISUtils.varname_concat - "pkg_" + OASISUtils.varname_concat + "pkg_" (OASISUtils.varname_of_string pkg) in - let findlib_dir pkg = - let dir = - BaseExec.run_read_one_line + let findlib_dir pkg = + let dir = + OASISExec.run_read_one_line ~ctxt:!BaseContext.default (ocamlfind ()) ["query"; "-format"; "%d"; pkg] in if Sys.file_exists dir && Sys.is_directory dir then dir else - failwithf2 + failwithf (f_ "When looking for findlib package %s, \ directory %s return doesn't exist") pkg dir @@ -2555,62 +2864,62 @@ module BaseCheck = struct let vl = var_redefine var - (lazy (findlib_dir pkg)) + (fun () -> findlib_dir pkg) () in ( - match version_comparator with + match version_comparator with | Some ver_cmp -> ignore - (version + (version var ver_cmp (fun _ -> package_version pkg) ()) - | None -> + | None -> () ); vl end module BaseOCamlcConfig = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseOCamlcConfig.ml" - - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseOCamlcConfig.ml" *) + + open BaseEnv open OASISUtils open OASISGettext - + module SMap = Map.Make(String) - - let ocamlc = + + let ocamlc = BaseCheck.prog_opt "ocamlc" - + let ocamlc_config_map = - (* Map name to value for ocamlc -config output - (name ^": "^value) + (* Map name to value for ocamlc -config output + (name ^": "^value) *) - let rec split_field mp lst = - match lst with + let rec split_field mp lst = + match lst with | line :: tl -> let mp = try let pos_semicolon = String.index line ':' in - if pos_semicolon > 1 then + if pos_semicolon > 1 then ( let name = - String.sub line 0 pos_semicolon + String.sub line 0 pos_semicolon in let linelen = String.length line in let value = if linelen > pos_semicolon + 2 then - String.sub - line - (pos_semicolon + 2) + String.sub + line + (pos_semicolon + 2) (linelen - pos_semicolon - 2) else "" @@ -2630,100 +2939,128 @@ module BaseOCamlcConfig = struct | [] -> mp in - + + let cache = + lazy + (var_protect + (Marshal.to_string + (split_field + SMap.empty + (OASISExec.run_read_output + ~ctxt:!BaseContext.default + (ocamlc ()) ["-config"])) + [])) + in var_redefine "ocamlc_config_map" ~hide:true ~dump:false - (lazy - (var_protect - (Marshal.to_string - (split_field - SMap.empty - (BaseExec.run_read_output - (ocamlc ()) ["-config"])) - []))) - + (fun () -> + (* TODO: update if ocamlc change !!! *) + Lazy.force cache) + let var_define nm = (* Extract data from ocamlc -config *) - let avlbl_config_get () = - Marshal.from_string + let avlbl_config_get () = + Marshal.from_string (ocamlc_config_map ()) 0 in - let nm_config = - match nm with - | "ocaml_version" -> "version" - | _ -> nm + let chop_version_suffix s = + try + String.sub s 0 (String.index s '+') + with _ -> + s + in + + let nm_config, value_config = + match nm with + | "ocaml_version" -> + "version", chop_version_suffix + | _ -> nm, (fun x -> x) in var_redefine - nm - (lazy - (try - let map = - avlbl_config_get () - in - let value = - SMap.find nm_config map - in - value - with Not_found -> - failwithf2 - (f_ "Cannot find field '%s' in '%s -config' output") - nm - (ocamlc ()))) - + nm + (fun () -> + try + let map = + avlbl_config_get () + in + let value = + SMap.find nm_config map + in + value_config value + with Not_found -> + failwithf + (f_ "Cannot find field '%s' in '%s -config' output") + nm + (ocamlc ())) + end module BaseStandardVar = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseStandardVar.ml" - - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseStandardVar.ml" *) + + open OASISGettext open OASISTypes open OASISExpr open BaseCheck open BaseEnv - + let ocamlfind = BaseCheck.ocamlfind let ocamlc = BaseOCamlcConfig.ocamlc let ocamlopt = prog_opt "ocamlopt" let ocamlbuild = prog "ocamlbuild" - - + + (**/**) - let rpkg = + let rpkg = ref None - + let pkg_get () = - match !rpkg with + match !rpkg with | Some pkg -> pkg | None -> failwith (s_ "OASIS Package is not set") + + let var_cond = ref [] + + let var_define_cond ~since_version f dflt = + let holder = ref (fun () -> dflt) in + let since_version = + OASISVersion.VGreaterEqual (OASISVersion.version_of_string since_version) + in + var_cond := + (fun ver -> + if OASISVersion.comparator_apply ver since_version then + holder := f ()) :: !var_cond; + fun () -> !holder () + (**/**) - - let pkg_name = + + let pkg_name = var_define ~short_desc:(fun () -> s_ "Package name") "pkg_name" - (lazy (pkg_get ()).name) - + (fun () -> (pkg_get ()).name) + let pkg_version = var_define ~short_desc:(fun () -> s_ "Package version") "pkg_version" - (lazy + (fun () -> (OASISVersion.string_of_version (pkg_get ()).version)) - - let c = BaseOCamlcConfig.var_define - + + let c = BaseOCamlcConfig.var_define + let os_type = c "os_type" let system = c "system" let architecture = c "architecture" let ccomp_type = c "ccomp_type" let ocaml_version = c "ocaml_version" - + (* TODO: Check standard variable presence at runtime *) - + let standard_library_default = c "standard_library_default" let standard_library = c "standard_library" let standard_runtime = c "standard_runtime" @@ -2736,222 +3073,312 @@ module BaseStandardVar = struct let ext_dll = c "ext_dll" let default_executable_name = c "default_executable_name" let systhread_supported = c "systhread_supported" - - + + let flexlink = + BaseCheck.prog "flexlink" + + let flexdll_version = + var_define + ~short_desc:(fun () -> "FlexDLL version (Win32)") + "flexdll_version" + (fun () -> + let lst = + OASISExec.run_read_output ~ctxt:!BaseContext.default + (flexlink ()) ["-help"] + in + match lst with + | line :: _ -> + Scanf.sscanf line "FlexDLL version %s" (fun ver -> ver) + | [] -> + raise Not_found) + (**/**) - let p name hlp dflt = + let p name hlp dflt = var_define - ~short_desc:hlp - ~cli:CLIAuto - ~arg_help:"dir" - name - dflt - - let (/) a b = + ~short_desc:hlp + ~cli:CLIAuto + ~arg_help:"dir" + name + dflt + + let (/) a b = if os_type () = Sys.os_type then - Filename.concat a b + Filename.concat a b else if os_type () = "Unix" then - BaseFilePath.Unix.concat a b + OASISUnixPath.concat a b else - OASISUtils.failwithf1 - (f_ "Cannot handle os_type %s filename concat") + OASISUtils.failwithf (f_ "Cannot handle os_type %s filename concat") (os_type ()) (**/**) - - let prefix = + + let prefix = p "prefix" (fun () -> s_ "Install architecture-independent files dir") - (lazy - (match os_type () with - | "Win32" -> - let program_files = - Sys.getenv "PROGRAMFILES" - in - program_files/(pkg_name ()) - | _ -> - "/usr/local")) - - let exec_prefix = + (fun () -> + match os_type () with + | "Win32" -> + let program_files = + Sys.getenv "PROGRAMFILES" + in + program_files/(pkg_name ()) + | _ -> + "/usr/local") + + let exec_prefix = p "exec_prefix" (fun () -> s_ "Install architecture-dependent files in dir") - (lazy "$prefix") - + (fun () -> "$prefix") + let bindir = p "bindir" (fun () -> s_ "User executables") - (lazy ("$exec_prefix"/"bin")) - + (fun () -> "$exec_prefix"/"bin") + let sbindir = p "sbindir" (fun () -> s_ "System admin executables") - (lazy ("$exec_prefix"/"sbin")) - + (fun () -> "$exec_prefix"/"sbin") + let libexecdir = p "libexecdir" (fun () -> s_ "Program executables") - (lazy ("$exec_prefix"/"libexec")) - + (fun () -> "$exec_prefix"/"libexec") + let sysconfdir = p "sysconfdir" (fun () -> s_ "Read-only single-machine data") - (lazy ("$prefix"/"etc")) - + (fun () -> "$prefix"/"etc") + let sharedstatedir = p "sharedstatedir" (fun () -> s_ "Modifiable architecture-independent data") - (lazy ("$prefix"/"com")) - + (fun () -> "$prefix"/"com") + let localstatedir = p "localstatedir" (fun () -> s_ "Modifiable single-machine data") - (lazy ("$prefix"/"var")) - + (fun () -> "$prefix"/"var") + let libdir = p "libdir" (fun () -> s_ "Object code libraries") - (lazy ("$exec_prefix"/"lib")) - + (fun () -> "$exec_prefix"/"lib") + let datarootdir = p "datarootdir" (fun () -> s_ "Read-only arch-independent data root") - (lazy ("$prefix"/"share")) - + (fun () -> "$prefix"/"share") + let datadir = p "datadir" (fun () -> s_ "Read-only architecture-independent data") - (lazy ("$datarootdir")) - + (fun () -> "$datarootdir") + let infodir = p "infodir" (fun () -> s_ "Info documentation") - (lazy ("$datarootdir"/"info")) - + (fun () -> "$datarootdir"/"info") + let localedir = p "localedir" (fun () -> s_ "Locale-dependent data") - (lazy ("$datarootdir"/"locale")) - + (fun () -> "$datarootdir"/"locale") + let mandir = p "mandir" (fun () -> s_ "Man documentation") - (lazy ("$datarootdir"/"man")) - + (fun () -> "$datarootdir"/"man") + let docdir = p "docdir" (fun () -> s_ "Documentation root") - (lazy ("$datarootdir"/"doc"/"$pkg_name")) - + (fun () -> "$datarootdir"/"doc"/"$pkg_name") + let htmldir = p "htmldir" (fun () -> s_ "HTML documentation") - (lazy ("$docdir")) - + (fun () -> "$docdir") + let dvidir = p "dvidir" (fun () -> s_ "DVI documentation") - (lazy ("$docdir")) - + (fun () -> "$docdir") + let pdfdir = p "pdfdir" (fun () -> s_ "PDF documentation") - (lazy ("$docdir")) - + (fun () -> "$docdir") + let psdir = p "psdir" (fun () -> s_ "PS documentation") - (lazy ("$docdir")) - + (fun () -> "$docdir") + let destdir = p "destdir" (fun () -> s_ "Prepend a path when installing package") - (lazy - (raise - (PropList.Not_set - ("destdir", - Some (s_ "undefined by construct"))))) - + (fun () -> + raise + (PropList.Not_set + ("destdir", + Some (s_ "undefined by construct")))) + let findlib_version = var_define "findlib_version" - (lazy - (BaseCheck.package_version "findlib")) - + (fun () -> + BaseCheck.package_version "findlib") + let is_native = var_define "is_native" - (lazy - (try - let _s : string = - ocamlopt () - in - "true" - with PropList.Not_set _ -> - let _s : string = - ocamlc () - in - "false")) - + (fun () -> + try + let _s : string = + ocamlopt () + in + "true" + with PropList.Not_set _ -> + let _s : string = + ocamlc () + in + "false") + let ext_program = var_define "suffix_program" - (lazy - (match os_type () with - | "Win32" -> ".exe" - | _ -> "" - )) - + (fun () -> + match os_type () with + | "Win32" -> ".exe" + | _ -> "") + let rm = var_define ~short_desc:(fun () -> s_ "Remove a file.") "rm" - (lazy - (match os_type () with - | "Win32" -> "del" - | _ -> "rm -f")) - + (fun () -> + match os_type () with + | "Win32" -> "del" + | _ -> "rm -f") + let rmdir = var_define ~short_desc:(fun () -> s_ "Remove a directory.") "rmdir" - (lazy - (match os_type () with - | "Win32" -> "rd" - | _ -> "rm -rf")) - + (fun () -> + match os_type () with + | "Win32" -> "rd" + | _ -> "rm -rf") + let debug = var_define - ~short_desc:(fun () -> s_ "Compile with ocaml debug flag on.") + ~short_desc:(fun () -> s_ "Turn ocaml debug flag on") + ~cli:CLIEnable "debug" - (lazy "true") - + (fun () -> "true") + let profile = var_define - ~short_desc:(fun () -> s_ "Compile with ocaml profile flag on.") + ~short_desc:(fun () -> s_ "Turn ocaml profile flag on") + ~cli:CLIEnable "profile" - (lazy "false") - - let init pkg = - rpkg := Some pkg - + (fun () -> "false") + + let tests = + var_define_cond ~since_version:"0.3" + (fun () -> + var_define + ~short_desc:(fun () -> + s_ "Compile tests executable and library and run them") + ~cli:CLIEnable + "tests" + (fun () -> "false")) + "true" + + let docs = + var_define_cond ~since_version:"0.3" + (fun () -> + var_define + ~short_desc:(fun () -> s_ "Create documentations") + ~cli:CLIEnable + "docs" + (fun () -> "true")) + "true" + + let native_dynlink = + var_define + ~short_desc:(fun () -> s_ "Compiler support generation of .cmxs.") + ~cli:CLINone + "native_dynlink" + (fun () -> + let res = + let ocaml_lt_312 () = + OASISVersion.comparator_apply + (OASISVersion.version_of_string (ocaml_version ())) + (OASISVersion.VLesser + (OASISVersion.version_of_string "3.12.0")) + in + let flexdll_lt_030 () = + OASISVersion.comparator_apply + (OASISVersion.version_of_string (flexdll_version ())) + (OASISVersion.VLesser + (OASISVersion.version_of_string "0.30")) + in + let has_native_dynlink = + let ocamlfind = ocamlfind () in + try + let fn = + OASISExec.run_read_one_line + ~ctxt:!BaseContext.default + ocamlfind + ["query"; "-predicates"; "native"; "dynlink"; + "-format"; "%d/%a"] + in + Sys.file_exists fn + with _ -> + false + in + if not has_native_dynlink then + false + else if ocaml_lt_312 () then + false + else if (os_type () = "Win32" || os_type () = "Cygwin") + && flexdll_lt_030 () then + begin + BaseMessage.warning + (f_ ".cmxs generation disabled because FlexDLL needs to be \ + at least 0.30. Please upgrade FlexDLL from %s to 0.30.") + (flexdll_version ()); + false + end + else + true + in + string_of_bool res) + + let init pkg = + rpkg := Some pkg; + List.iter (fun f -> f pkg.oasis_version) !var_cond + end module BaseFileAB = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseFileAB.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseFileAB.ml" *) + open BaseEnv open OASISGettext open BaseMessage - + let to_filename fn = let fn = - BaseFilePath.of_unix fn + OASISHostPath.of_unix fn in if not (Filename.check_suffix fn ".ab") then - warning + warning (f_ "File '%s' doesn't have '.ab' extension") fn; Filename.chop_extension fn - + let replace fn_lst = let buff = Buffer.create 13 @@ -2959,7 +3386,7 @@ module BaseFileAB = struct List.iter (fun fn -> let fn = - BaseFilePath.of_unix fn + OASISHostPath.of_unix fn in let chn_in = open_in fn @@ -2984,42 +3411,42 @@ module BaseFileAB = struct end module BaseLog = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseLog.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseLog.ml" *) + open OASISUtils - + let default_filename = - Filename.concat + Filename.concat (Filename.dirname BaseEnv.default_filename) "setup.log" - + module SetTupleString = Set.Make - (struct + (struct type t = string * string - let compare (s11, s12) (s21, s22) = - match String.compare s11 s21 with + let compare (s11, s12) (s21, s22) = + match String.compare s11 s21 with | 0 -> String.compare s12 s22 | n -> n end) - - let load () = + + let load () = if Sys.file_exists default_filename then begin - let chn = + let chn = open_in default_filename in - let scbuf = + let scbuf = Scanf.Scanning.from_file default_filename in let rec read_aux (st, lst) = if not (Scanf.Scanning.end_of_input scbuf) then begin - let acc = - try - Scanf.bscanf scbuf "%S %S@\n" - (fun e d -> - let t = + let acc = + try + Scanf.bscanf scbuf "%S %S\n" + (fun e d -> + let t = e, d in if SetTupleString.mem t st then @@ -3028,9 +3455,9 @@ module BaseLog = struct SetTupleString.add t st, t :: lst) with Scanf.Scan_failure _ -> - failwith + failwith (Scanf.bscanf scbuf - "%l" + "%l" (fun line -> Printf.sprintf "Malformed log file '%s' at line %d" @@ -3051,18 +3478,18 @@ module BaseLog = struct begin [] end - + let register event data = let chn_out = open_out_gen [Open_append; Open_creat; Open_text] 0o644 default_filename in Printf.fprintf chn_out "%S %S\n" event data; close_out chn_out - + let unregister event data = if Sys.file_exists default_filename then begin - let lst = + let lst = load () in let chn_out = @@ -3071,7 +3498,7 @@ module BaseLog = struct let write_something = ref false in - List.iter + List.iter (fun (e, d) -> if e <> event || d <> data then begin @@ -3083,19 +3510,19 @@ module BaseLog = struct if not !write_something then Sys.remove default_filename end - + let filter events = let st_events = List.fold_left - (fun st e -> + (fun st e -> SetString.add e st) SetString.empty events in - List.filter + List.filter (fun (e, _) -> SetString.mem e st_events) (load ()) - + let exists event data = List.exists (fun v -> (event, data) = v) @@ -3103,47 +3530,47 @@ module BaseLog = struct end module BaseBuilt = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseBuilt.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseBuilt.ml" *) + open OASISTypes open OASISGettext open BaseStandardVar open BaseMessage - + type t = | BExec (* Executable *) | BExecLib (* Library coming with executable *) | BLib (* Library *) | BDoc (* Document *) - + let to_log_event_file t nm = "built_"^ - (match t with + (match t with | BExec -> "exec" | BExecLib -> "exec_lib" | BLib -> "lib" | BDoc -> "doc")^ "_"^nm - + let to_log_event_done t nm = "is_"^(to_log_event_file t nm) - - let register t nm lst = + + let register t nm lst = BaseLog.register (to_log_event_done t nm) "true"; List.iter (fun alt -> - let registered = + let registered = List.fold_left (fun registered fn -> - if Sys.file_exists fn then + if OASISFileUtil.file_exists_case fn then begin - BaseLog.register + BaseLog.register (to_log_event_file t nm) (if Filename.is_relative fn then Filename.concat (Sys.getcwd ()) fn - else + else fn); true end @@ -3157,31 +3584,31 @@ module BaseBuilt = struct (f_ "Cannot find an existing alternative files among: %s") (String.concat (s_ ", ") alt)) lst - + let unregister t nm = List.iter (fun (e, d) -> BaseLog.unregister e d) - (BaseLog.filter - [to_log_event_file t nm; + (BaseLog.filter + [to_log_event_file t nm; to_log_event_done t nm]) - - let fold t nm f acc = - List.fold_left + + let fold t nm f acc = + List.fold_left (fun acc (_, fn) -> - if Sys.file_exists fn then + if OASISFileUtil.file_exists_case fn then begin f acc fn end else begin - warning + warning (f_ "File '%s' has been marked as built \ for %s but doesn't exist") fn (Printf.sprintf - (match t with - | BExec | BExecLib -> + (match t with + | BExec | BExecLib -> (f_ "executable %s") | BLib -> (f_ "library %s") @@ -3193,29 +3620,29 @@ module BaseBuilt = struct acc (BaseLog.filter [to_log_event_file t nm]) - + let is_built t nm = List.fold_left (fun is_built (_, d) -> - (try + (try bool_of_string d with _ -> false)) false (BaseLog.filter [to_log_event_done t nm]) - - let of_executable ffn (cs, bs, exec) = - let unix_exec_is, unix_dll_opt = - OASISExecutable.unix_exec_is + + let of_executable ffn (cs, bs, exec) = + let unix_exec_is, unix_dll_opt = + OASISExecutable.unix_exec_is (cs, bs, exec) - (fun () -> - bool_of_string + (fun () -> + bool_of_string (is_native ())) ext_dll ext_program in - let evs = + let evs = (BExec, cs.cs_name, [[ffn unix_exec_is]]) :: (match unix_dll_opt with @@ -3227,18 +3654,18 @@ module BaseBuilt = struct evs, unix_exec_is, unix_dll_opt - - let of_library ffn (cs, bs, lib) = - let unix_lst = + + let of_library ffn (cs, bs, lib) = + let unix_lst = OASISLibrary.generated_unix_files ~ctxt:!BaseContext.default + ~source_file_exists:(fun fn -> + OASISFileUtil.file_exists_case (OASISHostPath.of_unix fn)) + ~is_native:(bool_of_string (is_native ())) + ~has_native_dynlink:(bool_of_string (native_dynlink ())) + ~ext_lib:(ext_lib ()) + ~ext_dll:(ext_dll ()) (cs, bs, lib) - (fun fn -> - Sys.file_exists (BaseFilePath.of_unix fn)) - (fun () -> - bool_of_string (is_native ())) - ext_lib - ext_dll in let evs = [BLib, @@ -3246,45 +3673,45 @@ module BaseBuilt = struct List.map (List.map ffn) unix_lst] in evs, unix_lst - + end module BaseCustom = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseCustom.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseCustom.ml" *) + open BaseEnv open BaseMessage open OASISTypes open OASISGettext - + let run cmd args extra_args = - BaseExec.run + OASISExec.run ~ctxt:!BaseContext.default ~quote:false (var_expand cmd) - (List.map + (List.map var_expand (args @ (Array.to_list extra_args))) - + let hook ?(failsafe=false) cstm f e = - let optional_command lst = + let optional_command lst = let printer = - function + function | Some (cmd, args) -> String.concat " " (cmd :: args) | None -> s_ "No command" in - match - var_choose + match + var_choose ~name:(s_ "Pre/Post Command") - ~printer - lst with + ~printer + lst with | Some (cmd, args) -> begin - try + try run cmd args [||] with e when failsafe -> - warning + warning (f_ "Command '%s' fail with error: %s") (String.concat " " (cmd :: args)) - (match e with + (match e with | Failure msg -> msg | e -> Printexc.to_string e) end @@ -3300,75 +3727,78 @@ module BaseCustom = struct end module BaseDynVar = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseDynVar.ml" - - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseDynVar.ml" *) + + open OASISTypes open OASISGettext open BaseEnv open BaseBuilt - + let init pkg = - List.iter + (* TODO: disambiguate exec vs other variable by adding exec_VARNAME. *) + (* TODO: provide compile option for library libary_byte_args_VARNAME... *) + List.iter (function | Executable (cs, bs, exec) -> - var_ignore - (var_redefine - (* We don't save this variable *) - ~dump:false - ~short_desc:(fun () -> - Printf.sprintf - (f_ "Filename of executable '%s'") - cs.cs_name) - cs.cs_name - (lazy - (let fn_opt = - fold - BExec cs.cs_name - (fun _ fn -> Some fn) - None - in - match fn_opt with - | Some fn -> fn - | None -> - raise - (PropList.Not_set - (cs.cs_name, - Some (Printf.sprintf - (f_ "Executable '%s' not yet built.") - cs.cs_name)))))) - + if var_choose bs.bs_build then + var_ignore + (var_redefine + (* We don't save this variable *) + ~dump:false + ~short_desc:(fun () -> + Printf.sprintf + (f_ "Filename of executable '%s'") + cs.cs_name) + (OASISUtils.varname_of_string cs.cs_name) + (fun () -> + let fn_opt = + fold + BExec cs.cs_name + (fun _ fn -> Some fn) + None + in + match fn_opt with + | Some fn -> fn + | None -> + raise + (PropList.Not_set + (cs.cs_name, + Some (Printf.sprintf + (f_ "Executable '%s' not yet built.") + cs.cs_name))))) + | Library _ | Flag _ | Test _ | SrcRepo _ | Doc _ -> ()) pkg.sections end module BaseTest = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseTest.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseTest.ml" *) + open BaseEnv open BaseMessage open OASISTypes open OASISExpr open OASISGettext - + let test lst pkg extra_args = - + let one_test (failure, n) (test_plugin, cs, test) = - if var_choose + if var_choose ~name:(Printf.sprintf (f_ "test %s run") cs.cs_name) ~printer:string_of_bool test.test_run then begin - let () = + let () = info (f_ "Running test '%s'") cs.cs_name in - let back_cwd = - match test.test_working_directory with - | Some dir -> - let cwd = + let back_cwd = + match test.test_working_directory with + | Some dir -> + let cwd = Sys.getcwd () in let chdir d = @@ -3377,16 +3807,16 @@ module BaseTest = struct in chdir dir; fun () -> chdir cwd - - | None -> + + | None -> fun () -> () in - try + try let failure_percent = - BaseCustom.hook + BaseCustom.hook test.test_custom (test_plugin pkg (cs, test)) - extra_args + extra_args in back_cwd (); (failure_percent +. failure, n + 1) @@ -3414,7 +3844,7 @@ module BaseTest = struct else failed /. (float_of_int n) in - let msg = + let msg = Printf.sprintf (f_ "Tests had a %.2f%% failure rate") (100. *. failure_percent) @@ -3422,23 +3852,31 @@ module BaseTest = struct if failure_percent > 0.0 then failwith msg else - info "%s" msg + info "%s" msg; + + (* Possible explanation why the tests where not run. *) + if OASISVersion.version_0_3_or_after pkg.oasis_version && + not (bool_of_string (BaseStandardVar.tests ())) && + lst <> [] then + BaseMessage.warning + "Tests are turned off, consider enabling with \ + 'ocaml setup.ml -configure --enable-tests'" end module BaseDoc = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseDoc.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseDoc.ml" *) + open BaseEnv open BaseMessage open OASISTypes open OASISGettext - + let doc lst pkg extra_args = - - let one_doc (doc_plugin, cs, doc) = - if var_choose - ~name:(Printf.sprintf - (f_ "documentation %s build") + + let one_doc (doc_plugin, cs, doc) = + if var_choose + ~name:(Printf.sprintf + (f_ "documentation %s build") cs.cs_name) ~printer:string_of_bool doc.doc_build then @@ -3450,129 +3888,156 @@ module BaseDoc = struct extra_args end in - List.iter - one_doc - lst + List.iter one_doc lst; + + if OASISVersion.version_0_3_or_after pkg.oasis_version && + not (bool_of_string (BaseStandardVar.docs ())) && + lst <> [] then + BaseMessage.warning + "Docs are turned off, consider enabling with \ + 'ocaml setup.ml -configure --enable-docs'" end module BaseSetup = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseSetup.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseSetup.ml" *) + open BaseEnv open BaseMessage open OASISTypes open OASISSection open OASISGettext open OASISUtils - - type std_args_fun = + + type std_args_fun = package -> string array -> unit - - type ('a, 'b) section_args_fun = + + type ('a, 'b) section_args_fun = name * (package -> (common_section * 'a) -> string array -> 'b) - + type t = { - configure: std_args_fun; - build: std_args_fun; - doc: ((doc, unit) section_args_fun) list; - test: ((test, float) section_args_fun) list; - install: std_args_fun; - uninstall: std_args_fun; - clean: std_args_fun list; - clean_doc: (doc, unit) section_args_fun list; - clean_test: (test, unit) section_args_fun list; - distclean: std_args_fun list; - distclean_doc: (doc, unit) section_args_fun list; - distclean_test: (test, unit) section_args_fun list; - package: package; - version: string; - } - + configure: std_args_fun; + build: std_args_fun; + doc: ((doc, unit) section_args_fun) list; + test: ((test, float) section_args_fun) list; + install: std_args_fun; + uninstall: std_args_fun; + clean: std_args_fun list; + clean_doc: (doc, unit) section_args_fun list; + clean_test: (test, unit) section_args_fun list; + distclean: std_args_fun list; + distclean_doc: (doc, unit) section_args_fun list; + distclean_test: (test, unit) section_args_fun list; + package: package; + oasis_fn: string option; + oasis_version: string; + oasis_digest: Digest.t option; + oasis_exec: string option; + oasis_setup_args: string list; + setup_update: bool; + } + (* Associate a plugin function with data from package *) let join_plugin_sections filter_map lst = List.rev (List.fold_left (fun acc sct -> - match filter_map sct with + match filter_map sct with | Some e -> e :: acc | None -> acc) [] lst) - + (* Search for plugin data associated with a section name *) let lookup_plugin_section plugin action nm lst = - try + try List.assoc nm lst with Not_found -> - failwithf3 + failwithf (f_ "Cannot find plugin %s matching section %s for %s action") plugin nm action - - let configure t args = + + let configure t args = (* Run configure *) - BaseCustom.hook + BaseCustom.hook t.package.conf_custom - (t.configure t.package) - args; - + (fun () -> + (* Reload if preconf has changed it *) + begin + try + unload (); + load (); + with _ -> + () + end; + + (* Run plugin's configure *) + t.configure t.package args; + + (* Dump to allow postconf to change it *) + dump ()) + (); + (* Reload environment *) unload (); load (); - + + (* Save environment *) + print (); + (* Replace data in file *) BaseFileAB.replace t.package.files_ab - + let build t args = BaseCustom.hook t.package.build_custom (t.build t.package) args - + let doc t args = BaseDoc.doc (join_plugin_sections - (function - | Doc (cs, e) -> - Some - (lookup_plugin_section - "documentation" + (function + | Doc (cs, e) -> + Some + (lookup_plugin_section + "documentation" (s_ "build") - cs.cs_name + cs.cs_name t.doc, cs, e) - | _ -> + | _ -> None) t.package.sections) t.package args - - let test t args = - BaseTest.test + + let test t args = + BaseTest.test (join_plugin_sections - (function - | Test (cs, e) -> - Some + (function + | Test (cs, e) -> + Some (lookup_plugin_section "test" (s_ "run") - cs.cs_name + cs.cs_name t.test, cs, e) - | _ -> + | _ -> None) t.package.sections) t.package args - + let all t args = - let rno_doc = + let rno_doc = ref false in let rno_test = @@ -3580,30 +4045,30 @@ module BaseSetup = struct in Arg.parse_argv ~current:(ref 0) - (Array.of_list - ((Sys.executable_name^" all") :: + (Array.of_list + ((Sys.executable_name^" all") :: (Array.to_list args))) [ "-no-doc", Arg.Set rno_doc, s_ "Don't run doc target"; - + "-no-test", Arg.Set rno_test, s_ "Don't run test target"; ] - (failwithf1 (f_ "Don't know what to do with '%s'")) + (failwithf (f_ "Don't know what to do with '%s'")) ""; - + info "Running configure step"; configure t [||]; - + info "Running build step"; build t [||]; - + (* Load setup.log dynamic variables *) BaseDynVar.init t.package; - + if not !rno_doc then begin info "Running doc step"; @@ -3613,7 +4078,7 @@ module BaseSetup = struct begin info "Skipping doc step" end; - + if not !rno_test then begin info "Running test step"; @@ -3623,36 +4088,36 @@ module BaseSetup = struct begin info "Skipping test step" end - + let install t args = BaseCustom.hook t.package.install_custom (t.install t.package) args - + let uninstall t args = BaseCustom.hook t.package.uninstall_custom (t.uninstall t.package) args - + let reinstall t args = uninstall t args; install t args - - let clean, distclean = + + let clean, distclean = let failsafe f a = - try + try f a with e -> - warning + warning (f_ "Action fail with error: %s") - (match e with + (match e with | Failure msg -> msg | e -> Printexc.to_string e) in - - let generic_clean t cstm mains docs tests args = + + let generic_clean t cstm mains docs tests args = BaseCustom.hook ~failsafe:true cstm @@ -3662,7 +4127,7 @@ module BaseSetup = struct (function | Test (cs, test) -> let f = - try + try List.assoc cs.cs_name tests with Not_found -> fun _ _ _ -> () @@ -3673,43 +4138,52 @@ module BaseSetup = struct | Doc (cs, doc) -> let f = try - List.assoc cs.cs_name docs + List.assoc cs.cs_name docs with Not_found -> fun _ _ _ -> () in - failsafe + failsafe (f t.package (cs, doc)) args - | Library _ + | Library _ | Executable _ - | Flag _ + | Flag _ | SrcRepo _ -> ()) t.package.sections; (* Clean whole package *) List.iter - (fun f -> + (fun f -> failsafe (f t.package) args) mains) () in - + let clean t args = - generic_clean - t + generic_clean + t t.package.clean_custom - t.clean - t.clean_doc - t.clean_test + t.clean + t.clean_doc + t.clean_test args in - + let distclean t args = (* Call clean *) clean t args; - + + (* Call distclean code *) + generic_clean + t + t.package.distclean_custom + t.distclean + t.distclean_doc + t.distclean_test + args; + (* Remove generated file *) List.iter (fun fn -> @@ -3718,251 +4192,324 @@ module BaseSetup = struct info (f_ "Remove '%s'") fn; Sys.remove fn end) - (BaseEnv.default_filename - :: + (BaseEnv.default_filename + :: BaseLog.default_filename :: - (List.rev_map BaseFileAB.to_filename t.package.files_ab)); - - (* Call distclean code *) - generic_clean - t - t.package.distclean_custom - t.distclean - t.distclean_doc - t.distclean_test - args + (List.rev_map BaseFileAB.to_filename t.package.files_ab)) + in + + clean, distclean + + let version t _ = + print_endline t.oasis_version + + let update_setup_ml, no_update_setup_ml_cli = + let b = ref true in + b, + ("-no-update-setup-ml", + Arg.Clear b, + s_ " Don't try to update setup.ml, even if _oasis has changed.") + + let update_setup_ml t = + let oasis_fn = + match t.oasis_fn with + | Some fn -> fn + | None -> "_oasis" + in + let oasis_exec = + match t.oasis_exec with + | Some fn -> fn + | None -> "oasis" + in + let ocaml = + Sys.executable_name + in + let setup_ml, args = + match Array.to_list Sys.argv with + | setup_ml :: args -> + setup_ml, args + | [] -> + failwith + (s_ "Expecting non-empty command line arguments.") + in + let ocaml, setup_ml = + if Sys.executable_name = Sys.argv.(0) then + (* We are not running in standard mode, probably the script + * is precompiled. + *) + "ocaml", "setup.ml" + else + ocaml, setup_ml + in + let no_update_setup_ml_cli, _, _ = no_update_setup_ml_cli in + let do_update () = + let oasis_exec_version = + OASISExec.run_read_one_line + ~ctxt:!BaseContext.default + ~f_exit_code: + (function + | 0 -> + () + | 1 -> + failwithf + (f_ "Executable '%s' is probably an old version \ + of oasis (< 0.3.0), please update to version \ + v%s.") + oasis_exec t.oasis_version + | 127 -> + failwithf + (f_ "Cannot find executable '%s', please install \ + oasis v%s.") + oasis_exec t.oasis_version + | n -> + failwithf + (f_ "Command '%s version' exited with code %d.") + oasis_exec n) + oasis_exec ["version"] + in + if OASISVersion.comparator_apply + (OASISVersion.version_of_string oasis_exec_version) + (OASISVersion.VGreaterEqual + (OASISVersion.version_of_string t.oasis_version)) then + begin + (* We have a version >= for the executable oasis, proceed with + * update. + *) + (* TODO: delegate this check to 'oasis setup'. *) + if Sys.os_type = "Win32" then + failwithf + (f_ "It is not possible to update the running script \ + setup.ml on Windows. Please update setup.ml by \ + running '%s'.") + (String.concat " " (oasis_exec :: "setup" :: t.oasis_setup_args)) + else + begin + OASISExec.run + ~ctxt:!BaseContext.default + ~f_exit_code: + (function + | 0 -> + () + | n -> + failwithf + (f_ "Unable to update setup.ml using '%s', \ + please fix the problem and retry.") + oasis_exec) + oasis_exec ("setup" :: t.oasis_setup_args); + OASISExec.run ~ctxt:!BaseContext.default ocaml (setup_ml :: args) + end + end + else + failwithf + (f_ "The version of '%s' (v%s) doesn't match the version of \ + oasis used to generate the %s file. Please install at \ + least oasis v%s.") + oasis_exec oasis_exec_version setup_ml t.oasis_version in - - clean, distclean - - let version t _ = - print_endline t.version - - let setup t = + + if !update_setup_ml then + begin + try + match t.oasis_digest with + | Some dgst -> + if Sys.file_exists oasis_fn && dgst <> Digest.file "_oasis" then + begin + do_update (); + true + end + else + false + | None -> + false + with e -> + error + (f_ "Error when updating setup.ml. If you want to avoid this error, \ + you can bypass the update of %s by running '%s %s %s %s'") + setup_ml ocaml setup_ml no_update_setup_ml_cli + (String.concat " " args); + raise e + end + else + false + + let setup t = let catch_exn = ref true in try let act_ref = - ref (fun _ -> - failwithf2 + ref (fun _ -> + failwithf (f_ "No action defined, run '%s %s -help'") Sys.executable_name Sys.argv.(0)) - + in let extra_args_ref = ref [] in - let allow_empty_env_ref = + let allow_empty_env_ref = ref false in let arg_handle ?(allow_empty_env=false) act = Arg.Tuple [ Arg.Rest (fun str -> extra_args_ref := str :: !extra_args_ref); - - Arg.Unit - (fun () -> + + Arg.Unit + (fun () -> allow_empty_env_ref := allow_empty_env; act_ref := act); ] in - - Arg.parse + + Arg.parse (Arg.align - [ + ([ "-configure", arg_handle ~allow_empty_env:true configure, s_ "[options*] Configure the whole build process."; - + "-build", arg_handle build, s_ "[options*] Build executables and libraries."; - + "-doc", arg_handle doc, s_ "[options*] Build documents."; - + "-test", arg_handle test, s_ "[options*] Run tests."; - + "-all", arg_handle ~allow_empty_env:true all, s_ "[options*] Run configure, build, doc and test targets."; - + "-install", arg_handle install, s_ "[options*] Install libraries, data, executables \ and documents."; - + "-uninstall", arg_handle uninstall, s_ "[options*] Uninstall libraries, data, executables \ and documents."; - + "-reinstall", arg_handle reinstall, s_ "[options*] Uninstall and install libraries, data, \ executables and documents."; - + "-clean", arg_handle ~allow_empty_env:true clean, s_ "[options*] Clean files generated by a build."; - + "-distclean", arg_handle ~allow_empty_env:true distclean, s_ "[options*] Clean files generated by a build and configure."; - + "-version", arg_handle ~allow_empty_env:true version, s_ " Display version of OASIS used to generate this setup.ml."; - + "-no-catch-exn", Arg.Clear catch_exn, s_ " Don't catch exception, useful for debugging."; - ] - @ (BaseContext.args ())) - (failwithf1 (f_ "Don't know what to do with '%s'")) + ] + @ + (if t.setup_update then + [no_update_setup_ml_cli] + else + []) + @ (BaseContext.args ()))) + (failwithf (f_ "Don't know what to do with '%s'")) (s_ "Setup and run build process current package\n"); - + (* Build initial environment *) load ~allow_empty:!allow_empty_env_ref (); - + (** Initialize flags *) List.iter (function - | Flag (cs, {flag_description = hlp; + | Flag (cs, {flag_description = hlp; flag_default = choices}) -> begin - let apply ?short_desc () = + let apply ?short_desc () = var_ignore (var_define ~cli:CLIEnable ?short_desc (OASISUtils.varname_of_string cs.cs_name) - (lazy (string_of_bool - (var_choose - ~name:(Printf.sprintf - (f_ "default value of flag %s") - cs.cs_name) - ~printer:string_of_bool - choices)))) + (fun () -> + string_of_bool + (var_choose + ~name:(Printf.sprintf + (f_ "default value of flag %s") + cs.cs_name) + ~printer:string_of_bool + choices))) in - match hlp with + match hlp with | Some hlp -> apply ~short_desc:(fun () -> hlp) () | None -> apply () end - | _ -> + | _ -> ()) t.package.sections; - + BaseStandardVar.init t.package; - + BaseDynVar.init t.package; - - !act_ref t (Array.of_list (List.rev !extra_args_ref)) - + + if t.setup_update && update_setup_ml t then + () + else + !act_ref t (Array.of_list (List.rev !extra_args_ref)) + with e when !catch_exn -> - error "%s" (string_of_exception e); + error "%s" (Printexc.to_string e); exit 1 - -end -module BaseDev = struct -# 21 "/build/buildd/oasis-0.2.0/src/base/BaseDev.ml" - - - - open OASISGettext - open BaseMessage - - type t = - { - oasis_cmd: string; - } - - let update_and_run t = - (* Command line to run setup-dev *) - let oasis_args = - "setup-dev" :: "-run" :: - Sys.executable_name :: - (Array.to_list Sys.argv) - in - - let exit_on_child_error = - function - | 0 -> () - | 2 -> - (* Bad CLI arguments *) - error - (f_ "The command '%s %s' exit with code 2. It often means that we \ - don't use the right command-line arguments, rerun \ - 'oasis setup-dev'.") - t.oasis_cmd - (String.concat " " oasis_args) - - | 127 -> - (* Cannot find OASIS *) - error - (f_ "Cannot find executable '%s', check where 'oasis' is located \ - and rerun 'oasis setup-dev'") - t.oasis_cmd - - | i -> - exit i - in - - let () = - (* Run OASIS to generate a temporary setup.ml - *) - BaseExec.run - ~f_exit_code:exit_on_child_error - t.oasis_cmd - oasis_args - in - - () - end +# 4480 "setup.ml" module InternalConfigurePlugin = struct -# 21 "/build/buildd/oasis-0.2.0/src/plugins/internal/InternalConfigurePlugin.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/internal/InternalConfigurePlugin.ml" *) + (** Configure using internal scheme @author Sylvain Le Gall *) - + open BaseEnv open OASISTypes open OASISUtils open OASISGettext open BaseMessage - + (** Configure build using provided series of check to be done * and then output corresponding file. *) let configure pkg argv = - let var_ignore_eval var = + let var_ignore_eval var = let _s : string = var () - in + in () in - - let errors = + + let errors = ref SetString.empty in - + let buff = Buffer.create 13 in - + let add_errors fmt = Printf.kbprintf (fun b -> @@ -3971,18 +4518,18 @@ module InternalConfigurePlugin = struct buff fmt in - + let warn_exception e = - warning "%s" (string_of_exception e) + warning "%s" (Printexc.to_string e) in - + (* Check tools *) let check_tools lst = - List.iter + List.iter (function - | ExternalTool tool -> + | ExternalTool tool -> begin - try + try var_ignore_eval (BaseCheck.prog tool) with e -> warn_exception e; @@ -3992,8 +4539,8 @@ module InternalConfigurePlugin = struct (* Check that matching tool is built *) List.iter (function - | Executable ({cs_name = nm2}, - {bs_build = build}, + | Executable ({cs_name = nm2}, + {bs_build = build}, _) when nm1 = nm2 -> if not (var_choose build) then add_errors @@ -4005,13 +4552,13 @@ module InternalConfigurePlugin = struct pkg.sections) lst in - + let build_checks sct bs = if var_choose bs.bs_build then begin if bs.bs_compiled_object = Native then begin - try + try var_ignore_eval BaseStandardVar.ocamlopt with e -> warn_exception e; @@ -4019,16 +4566,16 @@ module InternalConfigurePlugin = struct (f_ "Section %s requires native compilation") (OASISSection.string_of_section sct) end; - + (* Check tools *) check_tools bs.bs_build_tools; - + (* Check depends *) - List.iter + List.iter (function | FindlibPackage (findlib_pkg, version_comparator) -> begin - try + try var_ignore_eval (BaseCheck.package ?version_comparator findlib_pkg) with e -> @@ -4049,7 +4596,7 @@ module InternalConfigurePlugin = struct List.iter (function | Library ({cs_name = nm2}, - {bs_build = build}, + {bs_build = build}, _) when nm1 = nm2 -> if not (var_choose build) then add_errors @@ -4062,24 +4609,24 @@ module InternalConfigurePlugin = struct bs.bs_build_depends end in - + (* Parse command line *) BaseArgExt.parse argv (BaseEnv.args ()); - + (* OCaml version *) begin - match pkg.ocaml_version with + match pkg.ocaml_version with | Some ver_cmp -> begin - try + try var_ignore_eval - (BaseCheck.version - "ocaml" - ver_cmp + (BaseCheck.version + "ocaml" + ver_cmp BaseStandardVar.ocaml_version) with e -> warn_exception e; - add_errors + add_errors (f_ "OCaml version %s doesn't match version constraint %s") (BaseStandardVar.ocaml_version ()) (OASISVersion.string_of_comparator ver_cmp) @@ -4087,21 +4634,21 @@ module InternalConfigurePlugin = struct | None -> () end; - + (* Findlib version *) begin - match pkg.findlib_version with + match pkg.findlib_version with | Some ver_cmp -> begin - try + try var_ignore_eval - (BaseCheck.version - "findlib" - ver_cmp + (BaseCheck.version + "findlib" + ver_cmp BaseStandardVar.findlib_version) with e -> warn_exception e; - add_errors + add_errors (f_ "Findlib version %s doesn't match version constraint %s") (BaseStandardVar.findlib_version ()) (OASISVersion.string_of_comparator ver_cmp) @@ -4109,7 +4656,18 @@ module InternalConfigurePlugin = struct | None -> () end; - + + (* FlexDLL *) + if BaseStandardVar.os_type () = "Win32" || + BaseStandardVar.os_type () = "Cygwin" then + begin + try + var_ignore_eval BaseStandardVar.flexlink + with e -> + warn_exception e; + add_errors (f_ "Cannot find 'flexlink'") + end; + (* Check build depends *) List.iter (function @@ -4125,35 +4683,50 @@ module InternalConfigurePlugin = struct | _ -> ()) pkg.sections; - - (* Save and print environment *) - if SetString.empty = !errors then - begin - dump (); - print () - end - else + + (* Check if we need native dynlink (presence of libraries that compile to + * native) + *) + begin + let has_cmxa = + List.exists + (function + | Library (_, bs, _) -> + var_choose bs.bs_build && + (bs.bs_compiled_object = Native || + (bs.bs_compiled_object = Best && + bool_of_string (BaseStandardVar.is_native ()))) + | _ -> + false) + pkg.sections + in + if has_cmxa then + var_ignore_eval BaseStandardVar.native_dynlink + end; + + (* Check errors *) + if SetString.empty != !errors then begin List.iter (fun e -> error "%s" e) (SetString.elements !errors); - failwithf1 - (fn_ + failwithf + (fn_ "%d configuration error" "%d configuration errors" (SetString.cardinal !errors)) (SetString.cardinal !errors) end - + end module InternalInstallPlugin = struct -# 21 "/build/buildd/oasis-0.2.0/src/plugins/internal/InternalInstallPlugin.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/internal/InternalInstallPlugin.ml" *) + (** Install using internal scheme @author Sylvain Le Gall *) - + open BaseEnv open BaseStandardVar open BaseMessage @@ -4161,31 +4734,96 @@ module InternalInstallPlugin = struct open OASISLibrary open OASISGettext open OASISUtils - + let exec_hook = ref (fun (cs, bs, exec) -> cs, bs, exec) - + let lib_hook = ref (fun (cs, bs, lib) -> cs, bs, lib, []) - + let doc_hook = ref (fun (cs, doc) -> cs, doc) - - let install_file_ev = + + let install_file_ev = "install-file" - + let install_dir_ev = "install-dir" - + let install_findlib_ev = "install-findlib" - + + let win32_max_command_line_length = 8000 + + let split_install_command ocamlfind findlib_name meta files = + if Sys.os_type = "Win32" then + (* Arguments for the first command: *) + let first_args = ["install"; findlib_name; meta] in + (* Arguments for remaining commands: *) + let other_args = ["install"; findlib_name; "-add"] in + (* Extract as much files as possible from [files], [len] is + the current command line length: *) + let rec get_files len acc files = + match files with + | [] -> + (List.rev acc, []) + | file :: rest -> + let len = len + 1 + String.length file in + if len > win32_max_command_line_length then + (List.rev acc, files) + else + get_files len (file :: acc) rest + in + (* Split the command into several commands. *) + let rec split args files = + match files with + | [] -> + [] + | _ -> + (* Length of "ocamlfind install <lib> [META|-add]" *) + let len = + List.fold_left + (fun len arg -> + len + 1 (* for the space *) + String.length arg) + (String.length ocamlfind) + args + in + match get_files len [] files with + | ([], _) -> + failwith (s_ "Command line too long.") + | (firsts, others) -> + let cmd = args @ firsts in + (* Use -add for remaining commands: *) + let () = + let findlib_ge_132 = + OASISVersion.comparator_apply + (OASISVersion.version_of_string + (BaseStandardVar.findlib_version ())) + (OASISVersion.VGreaterEqual + (OASISVersion.version_of_string "1.3.2")) + in + if not findlib_ge_132 then + failwithf + (f_ "Installing the library %s require to use the flag \ + '-add' of ocamlfind because the command line is too \ + long. This flag is only available for findlib 1.3.2. \ + Please upgrade findlib from %s to 1.3.2") + findlib_name (BaseStandardVar.findlib_version ()) + in + let cmds = split other_args others in + cmd :: cmds + in + (* The first command does not use -add: *) + split first_args files + else + ["install" :: findlib_name :: meta :: files] + let install pkg argv = - + let in_destdir = - try + try let destdir = - destdir () + destdir () in (* Practically speaking destdir is prepended * at the beginning of the target filename @@ -4194,82 +4832,88 @@ module InternalInstallPlugin = struct with PropList.Not_set _ -> fun fn -> fn in - - let install_file src_file envdir = - let tgt_dir = + + let install_file ?tgt_fn src_file envdir = + let tgt_dir = in_destdir (envdir ()) in let tgt_file = - Filename.concat + Filename.concat tgt_dir - (Filename.basename src_file) + (match tgt_fn with + | Some fn -> + fn + | None -> + Filename.basename src_file) in (* Create target directory if needed *) - BaseFileUtil.mkdir_parent + OASISFileUtil.mkdir_parent + ~ctxt:!BaseContext.default (fun dn -> info (f_ "Creating directory '%s'") dn; BaseLog.register install_dir_ev dn) tgt_dir; - + (* Really install files *) info (f_ "Copying file '%s' to '%s'") src_file tgt_file; - BaseFileUtil.cp src_file tgt_file; + OASISFileUtil.cp ~ctxt:!BaseContext.default src_file tgt_file; BaseLog.register install_file_ev tgt_file in - + (* Install data into defined directory *) let install_data srcdir lst tgtdir = - let tgtdir = - BaseFilePath.of_unix (var_expand tgtdir) + let tgtdir = + OASISHostPath.of_unix (var_expand tgtdir) in List.iter (fun (src, tgt_opt) -> - let real_srcs = - BaseFileUtil.glob + let real_srcs = + OASISFileUtil.glob + ~ctxt:!BaseContext.default (Filename.concat srcdir src) in if real_srcs = [] then - failwithf1 + failwithf (f_ "Wildcard '%s' doesn't match any files") src; - List.iter - (fun fn -> - install_file - fn - (fun () -> - match tgt_opt with - | Some s -> - BaseFilePath.of_unix (var_expand s) - | None -> + List.iter + (fun fn -> + install_file + fn + (fun () -> + match tgt_opt with + | Some s -> + OASISHostPath.of_unix (var_expand s) + | None -> tgtdir)) real_srcs) lst - in - + in + (** Install all libraries *) let install_libs pkg = - - let files_of_library (f_data, acc) data_lib = + + let files_of_library (f_data, acc) data_lib = let cs, bs, lib, lib_extra = !lib_hook data_lib in - if var_choose bs.bs_install && + if var_choose bs.bs_install && BaseBuilt.is_built BaseBuilt.BLib cs.cs_name then begin - let acc = + let acc = (* Start with acc + lib_extra *) List.rev_append lib_extra acc in - let acc = + let acc = (* Add uncompiled header from the source tree *) - let path = - BaseFilePath.of_unix bs.bs_path + let path = + OASISHostPath.of_unix bs.bs_path in List.fold_left (fun acc modul -> - try + try List.find - Sys.file_exists + OASISFileUtil.file_exists_case (List.map (Filename.concat path) [modul^".mli"; @@ -4281,7 +4925,7 @@ module InternalInstallPlugin = struct :: acc with Not_found -> begin - warning + warning (f_ "Cannot find source header for module %s \ in library %s") modul cs.cs_name; @@ -4290,27 +4934,27 @@ module InternalInstallPlugin = struct acc lib.lib_modules in - - let acc = + + let acc = (* Get generated files *) - BaseBuilt.fold - BaseBuilt.BLib + BaseBuilt.fold + BaseBuilt.BLib cs.cs_name (fun acc fn -> fn :: acc) acc in - + let f_data () = (* Install data associated with the library *) install_data bs.bs_path bs.bs_data_files - (Filename.concat + (Filename.concat (datarootdir ()) pkg.name); f_data () in - + (f_data, acc) end else @@ -4318,13 +4962,13 @@ module InternalInstallPlugin = struct (f_data, acc) end in - + (* Install one group of library *) - let install_group_lib grp = + let install_group_lib grp = (* Iterate through all group nodes *) let rec install_group_lib_aux data_and_files grp = - let data_and_files, children = - match grp with + let data_and_files, children = + match grp with | Container (_, children) -> data_and_files, children | Package (_, cs, bs, lib, children) -> @@ -4335,24 +4979,24 @@ module InternalInstallPlugin = struct data_and_files children in - + (* Findlib name of the root library *) let findlib_name = findlib_of_group grp in - + (* Determine root library *) let root_lib = root_of_group grp in - + (* All files to install for this library *) let f_data, files = install_group_lib_aux (ignore, []) grp in - + (* Really install, if there is something to install *) - if files = [] then + if files = [] then begin warning (f_ "Nothing to install for findlib library '%s'") @@ -4360,42 +5004,80 @@ module InternalInstallPlugin = struct end else begin - let meta = + let meta = (* Search META file *) - let (_, bs, _) = + let (_, bs, _) = root_lib in - let res = + let res = Filename.concat bs.bs_path "META" in - if not (Sys.file_exists res) then - failwithf2 + if not (OASISFileUtil.file_exists_case res) then + failwithf (f_ "Cannot find file '%s' for findlib library %s") res findlib_name; res in - info + let files = + (* Make filename shorter to avoid hitting command max line length + * too early, esp. on Windows. + *) + let remove_prefix p n = + let plen = String.length p in + let nlen = String.length n in + if plen <= nlen && String.sub n 0 plen = p then + begin + let fn_sep = + if Sys.os_type = "Win32" then + '\\' + else + '/' + in + let cutpoint = plen + + (if plen < nlen && n.[plen] = fn_sep then + 1 + else + 0) + in + String.sub n cutpoint (nlen - cutpoint) + end + else + n + in + List.map (remove_prefix (Sys.getcwd ())) files + in + info (f_ "Installing findlib library '%s'") findlib_name; - BaseExec.run - (ocamlfind ()) - ("install" :: findlib_name :: meta :: files); - BaseLog.register install_findlib_ev findlib_name + let ocamlfind = ocamlfind () in + let commands = + split_install_command + ocamlfind + findlib_name + meta + files + in + List.iter + (OASISExec.run ~ctxt:!BaseContext.default ocamlfind) + commands; + BaseLog.register install_findlib_ev findlib_name end; - + (* Install data files *) f_data (); - + in - + + let group_libs, _, _ = + findlib_mapping pkg + in + (* We install libraries in groups *) - List.iter - install_group_lib - (group_libs pkg) + List.iter install_group_lib group_libs in - - let install_execs pkg = + + let install_execs pkg = let install_exec data_exec = let (cs, bs, exec) = !exec_hook data_exec @@ -4404,7 +5086,7 @@ module InternalInstallPlugin = struct BaseBuilt.is_built BaseBuilt.BExec cs.cs_name then begin let exec_libdir () = - Filename.concat + Filename.concat (libdir ()) pkg.name in @@ -4413,6 +5095,7 @@ module InternalInstallPlugin = struct cs.cs_name (fun () fn -> install_file + ~tgt_fn:(cs.cs_name ^ ext_program ()) fn bindir) (); @@ -4427,7 +5110,7 @@ module InternalInstallPlugin = struct install_data bs.bs_path bs.bs_data_files - (Filename.concat + (Filename.concat (datarootdir ()) pkg.name) end @@ -4440,8 +5123,8 @@ module InternalInstallPlugin = struct ()) pkg.sections in - - let install_docs pkg = + + let install_docs pkg = let install_doc data = let (cs, doc) = !doc_hook data @@ -4450,14 +5133,14 @@ module InternalInstallPlugin = struct BaseBuilt.is_built BaseBuilt.BDoc cs.cs_name then begin let tgt_dir = - BaseFilePath.of_unix (var_expand doc.doc_install_dir) + OASISHostPath.of_unix (var_expand doc.doc_install_dir) in BaseBuilt.fold BaseBuilt.BDoc cs.cs_name (fun () fn -> - install_file - fn + install_file + fn (fun () -> tgt_dir)) (); install_data @@ -4474,18 +5157,18 @@ module InternalInstallPlugin = struct ()) pkg.sections in - + install_libs pkg; install_execs pkg; install_docs pkg - + (* Uninstall already installed data *) let uninstall _ argv = - List.iter + List.iter (fun (ev, data) -> if ev = install_file_ev then begin - if Sys.file_exists data then + if OASISFileUtil.file_exists_case data then begin info (f_ "Removing file '%s'") @@ -4498,7 +5181,7 @@ module InternalInstallPlugin = struct (f_ "File '%s' doesn't exist anymore") data end - end + end else if ev = install_dir_ev then begin if Sys.file_exists data && Sys.is_directory data then @@ -4508,20 +5191,20 @@ module InternalInstallPlugin = struct info (f_ "Removing directory '%s'") data; - BaseFileUtil.rmdir data + OASISFileUtil.rmdir ~ctxt:!BaseContext.default data end else begin - warning + warning (f_ "Directory '%s' is not empty (%s)") data - (String.concat - ", " - (Array.to_list + (String.concat + ", " + (Array.to_list (Sys.readdir data))) end end - else + else begin warning (f_ "Directory '%s' doesn't exist anymore") @@ -4531,78 +5214,80 @@ module InternalInstallPlugin = struct else if ev = install_findlib_ev then begin info (f_ "Removing findlib library '%s'") data; - BaseExec.run (ocamlfind ()) ["remove"; data] + OASISExec.run ~ctxt:!BaseContext.default + (ocamlfind ()) ["remove"; data] end else - failwithf1 (f_ "Unknown log event '%s'") ev; + failwithf (f_ "Unknown log event '%s'") ev; BaseLog.unregister ev data) (* We process event in reverse order *) - (List.rev - (BaseLog.filter - [install_file_ev; + (List.rev + (BaseLog.filter + [install_file_ev; install_dir_ev; install_findlib_ev;])) - + end +# 5233 "setup.ml" module OCamlbuildCommon = struct -# 21 "/build/buildd/oasis-0.2.0/src/plugins/ocamlbuild/OCamlbuildCommon.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/ocamlbuild/OCamlbuildCommon.ml" *) + (** Functions common to OCamlbuild build and doc plugin *) - + open OASISGettext open BaseEnv open BaseStandardVar - + let ocamlbuild_clean_ev = "ocamlbuild-clean" - + let ocamlbuildflags = var_define ~short_desc:(fun () -> "OCamlbuild additional flags") "ocamlbuildflags" - (lazy "") - + (fun () -> "") + (** Fix special arguments depending on environment *) let fix_args args extra_argv = List.flatten [ if (os_type ()) = "Win32" then [ - "-classic-display"; - "-no-log"; + "-classic-display"; + "-no-log"; "-no-links"; - "-install-lib-dir"; + "-install-lib-dir"; (Filename.concat (standard_library ()) "ocamlbuild") - ] + ] else []; - + if not (bool_of_string (is_native ())) || (os_type ()) = "Win32" then [ - "-byte-plugin" + "-byte-plugin" ] else []; args; - + if bool_of_string (debug ()) then ["-tag"; "debug"] else []; - + if bool_of_string (profile ()) then ["-tag"; "profile"] else []; - - OASISUtils.split ' ' (ocamlbuildflags ()); - + + OASISString.nsplit (ocamlbuildflags ()) ' '; + Array.to_list extra_argv; ] - + (** Run 'ocamlbuild -clean' if not already done *) let run_clean extra_argv = let extra_cli = @@ -4611,26 +5296,28 @@ module OCamlbuildCommon = struct (* Run if never called with these args *) if not (BaseLog.exists ocamlbuild_clean_ev extra_cli) then begin - BaseExec.run (ocamlbuild ()) (fix_args ["-clean"] extra_argv); + OASISExec.run ~ctxt:!BaseContext.default + (ocamlbuild ()) (fix_args ["-clean"] extra_argv); BaseLog.register ocamlbuild_clean_ev extra_cli; - at_exit + at_exit (fun () -> - try + try BaseLog.unregister ocamlbuild_clean_ev extra_cli with _ -> ()) end - + (** Run ocamlbuild, unregister all clean events *) let run_ocamlbuild args extra_argv = (* TODO: enforce that target in args must be UNIX encoded i.e. toto/index.html *) - BaseExec.run (ocamlbuild ()) (fix_args args extra_argv); + OASISExec.run ~ctxt:!BaseContext.default + (ocamlbuild ()) (fix_args args extra_argv); (* Remove any clean event, we must run it again *) List.iter (fun (e, d) -> BaseLog.unregister e d) (BaseLog.filter [ocamlbuild_clean_ev]) - + (** Determine real build directory *) let build_dir extra_argv = let rec search_args dir = @@ -4639,20 +5326,20 @@ module OCamlbuildCommon = struct search_args dir tl | _ :: tl -> search_args dir tl - | [] -> + | [] -> dir in search_args "_build" (fix_args [] extra_argv) - + end module OCamlbuildPlugin = struct -# 21 "/build/buildd/oasis-0.2.0/src/plugins/ocamlbuild/OCamlbuildPlugin.ml" - - (** Build using ocamlbuild +(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/ocamlbuild/OCamlbuildPlugin.ml" *) + + (** Build using ocamlbuild @author Sylvain Le Gall *) - + open OASISTypes open OASISGettext open OASISUtils @@ -4660,107 +5347,100 @@ module OCamlbuildPlugin = struct open OCamlbuildCommon open BaseStandardVar open BaseMessage - - type target = - | Std of string list - | StdRename of string * string - + let cond_targets_hook = ref (fun lst -> lst) - + let build pkg argv = - + (* Return the filename in build directory *) let in_build_dir fn = - Filename.concat - (build_dir argv) + Filename.concat + (build_dir argv) fn in - + (* Return the unix filename in host build directory *) let in_build_dir_of_unix fn = - in_build_dir (BaseFilePath.of_unix fn) + in_build_dir (OASISHostPath.of_unix fn) in - + let cond_targets = List.fold_left (fun acc -> - function + function | Library (cs, bs, lib) when var_choose bs.bs_build -> begin let evs, unix_files = - BaseBuilt.of_library + BaseBuilt.of_library in_build_dir_of_unix (cs, bs, lib) in - + let ends_with nd fn = let nd_len = String.length nd in (String.length fn >= nd_len) && - (String.sub + (String.sub fn (String.length fn - nd_len) nd_len) = nd in - + let tgts = - List.filter - (fun l -> l <> []) - (List.map - (List.filter - (fun fn -> - ends_with ".cma" fn || - ends_with ".cmxa" fn || - ends_with (ext_lib ()) fn || - ends_with (ext_dll ()) fn)) - unix_files) + List.flatten + (List.filter + (fun l -> l <> []) + (List.map + (List.filter + (fun fn -> + ends_with ".cma" fn + || ends_with ".cmxs" fn + || ends_with ".cmxa" fn + || ends_with (ext_lib ()) fn + || ends_with (ext_dll ()) fn)) + unix_files)) in - - match tgts with - | hd :: tl -> - (evs, Std hd) - :: - (List.map (fun tgts -> [], Std tgts) tl) - @ - acc + + match tgts with + | _ :: _ -> + (evs, tgts) :: acc | [] -> - failwithf2 - (f_ "No possible ocamlbuild targets \ - in generated files %s for library %s") - (String.concat (s_ ", " ) (List.map (String.concat (s_ ", ")) tgts)) + failwithf + (f_ "No possible ocamlbuild targets for library %s") cs.cs_name end - + | Executable (cs, bs, exec) when var_choose bs.bs_build -> begin let evs, unix_exec_is, unix_dll_opt = - BaseBuilt.of_executable + BaseBuilt.of_executable in_build_dir_of_unix (cs, bs, exec) in - - let host_exec_is = - in_build_dir_of_unix unix_exec_is - in - + let target ext = - let unix_tgt = - (BaseFilePath.Unix.concat + let unix_tgt = + (OASISUnixPath.concat bs.bs_path - (BaseFilePath.Unix.chop_extension + (OASISUnixPath.chop_extension exec.exec_main_is))^ext in - - evs, - (if unix_tgt = unix_exec_is then - Std [unix_tgt] - else - StdRename (unix_tgt, host_exec_is)) + let evs = + (* Fix evs, we want to use the unix_tgt, without copying *) + List.map + (function + | BaseBuilt.BExec, nm, lst when nm = cs.cs_name -> + BaseBuilt.BExec, nm, [[in_build_dir_of_unix unix_tgt]] + | ev -> + ev) + evs + in + evs, [unix_tgt] in - + (* Add executable *) let acc = match bs.bs_compiled_object with @@ -4774,107 +5454,44 @@ module OCamlbuildPlugin = struct in acc end - - | Library _ | Executable _ | Test _ + + | Library _ | Executable _ | Test _ | SrcRepo _ | Flag _ | Doc _ -> acc) [] (* Keep the pkg.sections ordered *) (List.rev pkg.sections); in - + (* Check and register built files *) - let check_and_register (bt, bnm, lst) = + let check_and_register (bt, bnm, lst) = List.iter (fun fns -> - if not (List.exists Sys.file_exists fns) then - failwithf1 + if not (List.exists OASISFileUtil.file_exists_case fns) then + failwithf (f_ "No one of expected built files %s exists") (String.concat (s_ ", ") (List.map (Printf.sprintf "'%s'") fns))) lst; - (BaseBuilt.register bt bnm lst) + (BaseBuilt.register bt bnm lst) in - - (* Run a list of target + post process *) - let run_ocamlbuild rtargets = + + let cond_targets = + (* Run the hook *) + !cond_targets_hook cond_targets + in + + (* Run a list of target... *) run_ocamlbuild - (List.rev_map snd rtargets) + (List.flatten + (List.map snd cond_targets)) argv; + (* ... and register events *) List.iter check_and_register - (List.flatten (List.rev_map fst rtargets)) - in - - (* Compare two files, return true if they differ *) - let diff fn1 fn2 = - if Sys.file_exists fn1 && Sys.file_exists fn2 then - begin - let chn1 = open_in fn1 in - let chn2 = open_in fn2 in - let res = - if in_channel_length chn1 = in_channel_length chn2 then - begin - let len = - 4096 - in - let str1 = - String.make len '\000' - in - let str2 = - String.copy str1 - in - try - while (String.compare str1 str2) = 0 do - really_input chn1 str1 0 len; - really_input chn2 str2 0 len - done; - true - with End_of_file -> - false - end - else - true - in - close_in chn1; close_in chn2; - res - end - else - true - in - - let last_rtargets = - List.fold_left - (fun acc (built, tgt) -> - match tgt with - | Std nms -> - (built, List.hd nms) :: acc - | StdRename (src, tgt) -> - begin - (* We run with a fake list for event registering *) - run_ocamlbuild (([], src) :: acc); - - (* And then copy and register *) - begin - let src_fn = - in_build_dir_of_unix src - in - if diff src_fn tgt then - BaseFileUtil.cp src_fn tgt - else - info - (f_ "No need to copy file '%s' to '%s', same content") - src_fn tgt - end; - List.iter check_and_register built; - [] - end) - [] - (!cond_targets_hook cond_targets) - in - if last_rtargets <> [] then - run_ocamlbuild last_rtargets - - let clean pkg extra_args = + (List.flatten (List.map fst cond_targets)) + + + let clean pkg extra_args = run_clean extra_args; List.iter (function @@ -4886,27 +5503,27 @@ module OCamlbuildPlugin = struct | _ -> ()) pkg.sections - + end module OCamlbuildDocPlugin = struct -# 21 "/build/buildd/oasis-0.2.0/src/plugins/ocamlbuild/OCamlbuildDocPlugin.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/ocamlbuild/OCamlbuildDocPlugin.ml" *) + (* Create documentation using ocamlbuild .odocl files @author Sylvain Le Gall *) - + open OASISTypes open OASISGettext open OASISMessage open OCamlbuildCommon open BaseStandardVar - - - + + + let doc_build path pkg (cs, doc) argv = let index_html = - BaseFilePath.Unix.make + OASISUnixPath.make [ path; cs.cs_name^".docdir"; @@ -4914,10 +5531,10 @@ module OCamlbuildDocPlugin = struct ] in let tgt_dir = - BaseFilePath.make + OASISHostPath.make [ build_dir argv; - BaseFilePath.of_unix path; + OASISHostPath.of_unix path; cs.cs_name^".docdir"; ] in @@ -4927,39 +5544,40 @@ module OCamlbuildDocPlugin = struct BaseBuilt.register BaseBuilt.BDoc cs.cs_name - [BaseFileUtil.glob + [OASISFileUtil.glob ~ctxt:!BaseContext.default (Filename.concat tgt_dir glb)]) ["*.html"; "*.css"] - + let doc_clean t pkg (cs, doc) argv = run_clean argv; BaseBuilt.unregister BaseBuilt.BDoc cs.cs_name - + end +# 5558 "setup.ml" module CustomPlugin = struct -# 21 "/build/buildd/oasis-0.2.0/src/plugins/custom/CustomPlugin.ml" - +(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/custom/CustomPlugin.ml" *) + (** Generate custom configure/build/doc/test/install system @author *) - + open BaseEnv open OASISGettext open OASISTypes - - - + + + type t = { cmd_main: command_line conditional; cmd_clean: (command_line option) conditional; cmd_distclean: (command_line option) conditional; } - + let run = BaseCustom.run - + let main t _ extra_args = let cmd, args = var_choose @@ -4967,21 +5585,21 @@ module CustomPlugin = struct t.cmd_main in run cmd args extra_args - + let clean t pkg extra_args = match var_choose t.cmd_clean with | Some (cmd, args) -> run cmd args extra_args | _ -> () - + let distclean t pkg extra_args = match var_choose t.cmd_distclean with | Some (cmd, args) -> run cmd args extra_args | _ -> () - + module Build = struct let main t pkg extra_args = @@ -4994,7 +5612,7 @@ module CustomPlugin = struct begin let evs, _ = BaseBuilt.of_library - BaseFilePath.of_unix + OASISHostPath.of_unix (cs, bs, lib) in evs @@ -5003,7 +5621,7 @@ module CustomPlugin = struct begin let evs, _, _ = BaseBuilt.of_executable - BaseFilePath.of_unix + OASISHostPath.of_unix (cs, bs, exec) in evs @@ -5015,7 +5633,7 @@ module CustomPlugin = struct (fun (bt, bnm, lst) -> BaseBuilt.register bt bnm lst) evs) pkg.sections - + let clean t pkg extra_args = clean t pkg extra_args; (* TODO: this seems to be pretty generic (at least wrt to ocamlbuild @@ -5031,11 +5649,11 @@ module CustomPlugin = struct | _ -> ()) pkg.sections - + let distclean t pkg extra_args = distclean t pkg extra_args end - + module Test = struct let main t pkg (cs, test) extra_args = @@ -5048,31 +5666,32 @@ module CustomPlugin = struct cs.cs_name s; 1.0 - + let clean t pkg (cs, test) extra_args = clean t pkg extra_args - + let distclean t pkg (cs, test) extra_args = distclean t pkg extra_args end - + module Doc = struct let main t pkg (cs, _) extra_args = main t pkg extra_args; BaseBuilt.register BaseBuilt.BDoc cs.cs_name [] - + let clean t pkg (cs, _) extra_args = clean t pkg extra_args; BaseBuilt.unregister BaseBuilt.BDoc cs.cs_name - + let distclean t pkg (cs, _) extra_args = distclean t pkg extra_args end - + end +# 5694 "setup.ml" open OASISTypes;; let setup_t = @@ -5128,11 +5747,12 @@ let setup_t = version = "1.2"; license = OASISLicense.DEP5License - { - OASISLicense.license = "LGPL"; - exceptions = []; - version = OASISLicense.Version "2.1"; - }; + (OASISLicense.DEP5Unit + { + OASISLicense.license = "LGPL"; + excption = None; + version = OASISLicense.Version "2.1"; + }); license_file = None; copyrights = []; maintainers = []; @@ -5141,20 +5761,23 @@ let setup_t = synopsis = "Lustre compiler C and Java backends"; description = None; categories = []; - conf_type = (`Configure, "internal", Some "0.2"); + conf_type = (`Configure, "internal", Some "0.3"); conf_custom = { pre_command = [(OASISExpr.EBool true, None)]; post_command = [(OASISExpr.EBool true, None)]; }; - build_type = (`Build, "ocamlbuild", Some "0.2"); + build_type = (`Build, "ocamlbuild", Some "0.3"); build_custom = { pre_command = - [(OASISExpr.EBool true, Some (("./svn_version.sh", [])))]; + [ + (OASISExpr.EBool true, + Some (("./svn_version.sh", ["$(prefix)"]))) + ]; post_command = [(OASISExpr.EBool true, None)]; }; - install_type = (`Install, "internal", Some "0.2"); + install_type = (`Install, "internal", Some "0.3"); install_custom = { pre_command = [(OASISExpr.EBool true, None)]; @@ -5165,10 +5788,14 @@ let setup_t = (("mkdir", [ "-p"; - "$(prefix)/include;"; + "$(prefix)/include/lustrec;"; + "cp"; + "-rf"; + "include/*.[ch]"; + "$(prefix)/include/lustrec;"; "cp"; "-rf"; - "include"; + "include/*.java"; "$(prefix)/include/lustrec" ]))) ]; @@ -5246,10 +5873,16 @@ let setup_t = schema_data = PropList.Data.create (); plugin_data = []; }; - version = "0.2.0"; + oasis_fn = Some "_oasis"; + oasis_version = "0.3.0"; + oasis_digest = Some "^\201\165\144\189\n\251D\168\165\229o\014u\145\241"; + oasis_exec = None; + oasis_setup_args = []; + setup_update = false; };; let setup () = BaseSetup.setup setup_t;; +# 5887 "setup.ml" (* OASIS_STOP *) let () = setup ();; diff --git a/src/c_backend.ml b/src/c_backend.ml index 7496d308..c67382d1 100644 --- a/src/c_backend.ml +++ b/src/c_backend.ml @@ -547,6 +547,9 @@ let print_prototype fmt decl = | _ -> () (* We don't do anything here *) *) +let print_import_standard fmt = + fprintf fmt "#include \"%s/include/lustrec/arrow.h\"@.@." Version.prefix + let print_prototype fmt decl = match decl.top_decl_desc with | Open m -> fprintf fmt "#include \"%s.h\"@," m @@ -562,12 +565,16 @@ let pp_registers_struct fmt m = () let print_machine_struct fmt m = - (* Define struct *) - fprintf fmt "@[%a {@[%a%a%t@]};@]@." - pp_machine_memtype_name m.mname.node_id - pp_registers_struct m - (Utils.fprintf_list ~sep:"; " pp_c_decl_instance_var) m.minstances - (Utils.pp_final_char_if_non_empty "; " m.minstances) + if m.mname.node_id != arrow_id + then ( + (* We don't print arrow function *) + (* Define struct *) + fprintf fmt "@[%a {@[%a%a%t@]};@]@." + pp_machine_memtype_name m.mname.node_id + pp_registers_struct m + (Utils.fprintf_list ~sep:"; " pp_c_decl_instance_var) m.minstances + (Utils.pp_final_char_if_non_empty "; " m.minstances) + ) (* let pp_static_array_instance fmt m (v, m) = @@ -631,24 +638,22 @@ let print_static_alloc_macro fmt m = pp_machine_static_link_name m.mname.node_id let print_machine_decl fmt m = - (* Static allocation *) - if !Options.static_mem then ( - fprintf fmt "%a@.%a@.%a@." - print_static_declare_macro m - print_static_link_macro m - print_static_alloc_macro m; - ) - else ( + if m.mname.node_id <> arrow_id + then ( + (* We don't print arrow function *) + (* Static allocation *) + if !Options.static_mem + then ( + fprintf fmt "%a@.%a@.%a@." + print_static_declare_macro m + print_static_link_macro m + print_static_alloc_macro m + ) + else ( (* Dynamic allocation *) - fprintf fmt "extern %a;@.@." - print_alloc_prototype (m.mname.node_id, m.mstatic); - ); - if m.mname.node_id = arrow_id then ( - (* Arrow will be defined by a #define macro because of polymorphism *) - fprintf fmt "#define _arrow_step(x,y,output,self) ((self)->_reg._first?((self)->_reg._first=0,(*output = x)):(*output = y))@.@."; - fprintf fmt "#define _arrow_reset(self) {(self)->_reg._first = 1;}@.@." - ) - else ( + fprintf fmt "extern %a;@.@." + print_alloc_prototype (m.mname.node_id, m.mstatic) + ); let self = mk_self m in fprintf fmt "extern %a;@.@." (print_reset_prototype self) (m.mname.node_id, m.mstatic); @@ -736,14 +741,16 @@ let print_step_code fmt m self = (fun fmt -> fprintf fmt "return;") let print_machine fmt m = + if m.mname.node_id <> arrow_id + then ( + (* We don't print arrow function *) (* Alloc function, only if non static mode *) - if (not !Options.static_mem) then - ( - fprintf fmt "@[<v 2>%a {@,%a@]@,}@.@." - print_alloc_prototype (m.mname.node_id, m.mstatic) - print_alloc_code m; - ); - if m.mname.node_id = arrow_id then () else ( (* We don't print arrow function *) + if (not !Options.static_mem) then + ( + fprintf fmt "@[<v 2>%a {@,%a@]@,}@.@." + print_alloc_prototype (m.mname.node_id, m.mstatic) + print_alloc_code m; + ); let self = mk_self m in (* Reset function *) fprintf fmt "@[<v 2>%a {@,%a%treturn;@]@,}@.@." @@ -835,31 +842,31 @@ let print_main_fun machines m fmt = fprintf fmt "@]@ }@." let print_main_header fmt = - fprintf fmt "#include <stdio.h>@.#include <unistd.h>@.#include \"io_frontend.h\"@." + fprintf fmt "#include <stdio.h>@.#include <unistd.h>@.#include \"%s/include/lustrec/io_frontend.h\"@." Version.prefix -let rec pp_c_type_decl cpt var fmt tdecl = +let rec pp_c_type_decl filename cpt var fmt tdecl = match tdecl with | Tydec_any -> assert false | Tydec_int -> fprintf fmt "int %s" var | Tydec_real -> fprintf fmt "double %s" var | Tydec_float -> fprintf fmt "float %s" var | Tydec_bool -> fprintf fmt "_Bool %s" var - | Tydec_clock ty -> pp_c_type_decl cpt var fmt ty + | Tydec_clock ty -> pp_c_type_decl filename cpt var fmt ty | Tydec_const c -> fprintf fmt "%s %s" c var - | Tydec_array (d, ty) -> fprintf fmt "%a[%a]" (pp_c_type_decl cpt var) ty pp_c_dimension d + | Tydec_array (d, ty) -> fprintf fmt "%a[%a]" (pp_c_type_decl filename cpt var) ty pp_c_dimension d | Tydec_enum tl -> begin incr cpt; - fprintf fmt "enum _enum_%d { %a } %s" !cpt (Utils.fprintf_list ~sep:", " pp_print_string) tl var + fprintf fmt "enum _enum_%s_%d { %a } %s" filename !cpt (Utils.fprintf_list ~sep:", " pp_print_string) tl var end -let print_type_definitions fmt = +let print_type_definitions fmt filename = let cpt_type = ref 0 in Hashtbl.iter (fun typ def -> match typ with | Tydec_const var -> fprintf fmt "typedef %a;@.@." - (pp_c_type_decl cpt_type var) def + (pp_c_type_decl filename cpt_type var) def | _ -> ()) type_table let print_makefile basename nodename dependencies fmt = @@ -898,9 +905,14 @@ let translate_to_c header_fmt source_fmt makefile_fmt spec_fmt_opt basename prog print_version header_fmt; fprintf header_fmt "#ifndef _%s@.#define _%s@." baseNAME baseNAME; pp_print_newline header_fmt (); + fprintf header_fmt "/* Imports standard library */@."; + (* imports standard library definitions (arrow) *) + print_import_standard header_fmt; + pp_print_newline header_fmt (); fprintf header_fmt "/* Types definitions */@."; (* Print the type definitions from the type table *) - print_type_definitions header_fmt; + print_type_definitions header_fmt basename; + pp_print_newline header_fmt (); (* Print the global constant declarations. *) fprintf header_fmt "/* Global constant (declarations, definitions are in C file) */@."; List.iter (fun c -> print_const_decl header_fmt c) (get_consts prog); diff --git a/svn_version.sh b/svn_version.sh index 097d053c..47f1e440 100755 --- a/svn_version.sh +++ b/svn_version.sh @@ -3,10 +3,16 @@ version=`svn info | awk -v ver="UNKNOWN" -F ":" '/R?vision/ { ver=$2 } END { print ver }' | tr -d " "` filename=version.ml +prefix=$1 -echo "Generating version number in file \"${filename}\" ..." +echo "Generating version information in file \"${filename}\" ..." echo "" > src/${filename} echo "(* Version file generated by Oasis *)" >> src/${filename} echo "" >> src/${filename} echo "let number = \"${version}\"" >> src/${filename} +echo "version number: ${version}" +echo "" >> src/${filename} +echo "let prefix = \"${prefix}\"" >> src/${filename} +echo "installation path prefix: ${prefix}" +echo "... done" \ No newline at end of file -- GitLab