Docs GODI Archive
Projects Blog Link DB

Search GODI:


More options
File lib/ocaml/pkg-lib/godi-script/godi_script.mli GODI Package godi-tools
Library godi-script
 
   Godi_script.html    godi_script.cmi_pretty    godi_script.mli    Sources  
(* $Id: godi_script.mli 679 2007-02-25 17:19:09Z gerd $ *)

(** This module contains library functions for GODI configuration scripts
 * written in OCaml. This is mainly intended for the conf-foo packages.
 *
 * In order to activate such a script, define the following variables in
 * the driver Makefile of conf-foo:
 *
 * - [CONF_SCRIPT]: The name of the script, usually [configure.gcs]
 *   (gcs = GODI configuration script). The suffix "gcs" enables a special
 *   calling convention that automatically finds the O'Caml interpreter
 *   and that loads the libraries [str] and [unix], and, of course,
 *   [godi_script].
 * - [CONF_SCRIPT_ARGS]: Arguments to be passed to the script.
 *
 * A number of environment variables are automatically passed to this
 * script:
 *
 * - [LOCALBASE]: The GODI prefix of this installation
 * - [CC]: The name of the C compiler
 * - [CFLAGS]: General flags for C compiling
 * - [LDFLAGS]: General flags for linking
 * - [CREATE_SHLIBS]: Whether C libraries must be shared ("yes") or not
 * - [SHLIB_TYPE]: The type of shared libraries used by the OS
 * - [ELF_RPATH]: Whether to use RPATH at all ("yes") or not
 * - [ELF_RPATH_FLAG]: The name of the RPATH flag, if any.
 * - [SEARCH_LIBS]: The list of standard library locations
 * - [MAKE]: The name of the [make] program to use for upstream Makefiles
 * - Furthermore, a number of programs like [RM], [CP], ...
 *
*)

(** {1 Primitives} *)

val runcmd : string -> int
  (** Starts the command, waits for its completion, and returns the exit
   * code. Similar to [Sys.command], but preferable. 
   *)

val runcmdf : ('a, unit, string, int) format4 -> 'a
  (** Same as [runcmd], but accepts a [printf]-like format string. *)

val findcmd : ?path:string list -> string -> string
  (** Returns the absolute location of a command, or raises [Not_found].
   * The command is searched in the locations enumerated by the environment
   * variable [PATH], by default, or in the locations passed by the
   * [path] argument.
   *)

val system_path : unit -> string list
  (** Returns the locations enumerated by the environment
   * variable [PATH]
   *)

val search_libs_path : unit -> string list
  (** Returns the (command) locations enumerated by the environment
   * variable [SEARCH_LIBS]
   *)

val read_file : string -> string
  (** Reads the file into memory, and returns it as string *)

val write_file : string -> string -> unit
  (** Writes to the file whose name is passed as first argument the
   * 0contents passed as second argument.
   *)

val read_from_cmd : string -> (int * string)
  (** Starts the command, reads its output (stdout), waits for its
   * completion, and returns both the exit code and the output.
   *)

val read_from_cmdf : ('a, unit, string, int * string) format4 -> 'a
  (** Same as [read_from_cmd], but accepts a [printf]-like format string. *)

val env : string -> string
  (** Returns the named environment variable, or [""] if the variable does
   * not exist.
   *)

val env_req : string -> string
  (** Returns the named environment variable, or fails if the variable
   * does not exist {b or is empty}.
   *)

val env_opt : string -> string option
  (** Returns the named environment variable, or [None] if the variable
   * is empty or does not exist.
   *)


(** {1 Commandlets} *)

(** A "commandlet" is a command function that takes a state variable as
 * input and that returns the possibly modified state variable as output.
 * The state variable contains the exit code of the last executed shell
 * command, and optionally a further result value.
 *
 * Remember that the exit code 0 means that the command was successful.
 *)

type 'a cmdstate
  (** The state with further values of type ['a] *)

val code : 'a cmdstate -> int
  (** The current exit code *)

val result : 'a cmdstate -> 'a option
  (** The current result value *)

val return_code : int -> 'a cmdstate -> 'a cmdstate
  (** Returns the modified state where the code is set to the int *)

val return_result : 'a option -> 'a cmdstate -> 'a cmdstate
  (** Returns the modified state where the result is set *)

val initial_state : unit -> 'a cmdstate
  (** The initial state has code 0, and no result value *)


type 'a cmdlet = 'a cmdstate -> 'a cmdstate
  (** A commandlet is a function taking state and returning state *)

val cmd : string -> 'a cmdlet
  (** The commandlet that executes the passed command (as string). The
   * exit code is set in the resulting state.
   *)

val cmdf : ('a, unit, string, 'b cmdlet) format4 -> 'a
  (** Same as [cmd] but accepts a [printf]-like format string *)

val cmd_output : string -> string cmdlet
  (** The commandlet that executes the passed command (as string), and
   * reads the output of the command (stdout). The exit code is set in the
   * resulting state, and the output is returned as result value.
   *)

val cmdf_output : ('a, unit, string, string cmdlet) format4 -> 'a
  (** Same as [cmd_output] but accepts a [printf]-like format string *)

val set_code : int -> 'a cmdlet
  (** The commandlet that sets the exit code to the passed integer *)

val set_code_from : ('a cmdstate -> int) -> 'a cmdlet
  (** The commandlet that calls the function, and sets the exit code
   * from the integer result of the function.
   *)

val set_bool_code : bool -> 'a cmdlet
  (** The commandlet that sets the exit code to 0 if the boolean is
   * [true], and to 1 if the boolean is [false].
   *)

val set_bool_code_from : ('a cmdstate -> bool) -> 'a cmdlet
  (** The commandlet that calls the function, and sets the exit code
   * from the boolean result of the function (as [set_code_bool]).
   *
   * This function is useful to call non-commandlets from a sequence
   * of commandlets. For instace, to just print messages:
   *
   * {[ 
   * cmd1 &- 
   * set_bool_code_from (fun _ -> printf "Here I am\n"; true) &-
   * cmd2 
   * ]}
   *)

val ( &- ) : 'a cmdlet -> 'a cmdlet -> 'a cmdlet
  (** Conditional sequencing: If the first commandlet returns the exit
   * code 0, the second commandlet is also executed (like the "&&" shell
   * operator).
   *)

val ( |- ) : 'a cmdlet -> 'a cmdlet -> 'a cmdlet
  (** Conditional sequencing: If the first commandlet returns a non-zero exit
   * code, the second commandlet is also executed (like the "||" shell
   * operator).
   *)

val ignore_code : 'a cmdlet -> 'a cmdlet
  (** Executes the commandlet, and ignores the exit code, i.e. sets it
   * always to 0.
   *)

val eval : 'a cmdlet -> 'a option
  (** Evaluates a commandlet, and returns the result value. Note that
   * [None] is always returned if the exit code is non-zero, regardless of
   * whether there is a result value or not.
   *)

val eval_test : 'a cmdlet -> bool
  (** Evaluates a commandlet, and returns [true] if the exit code is 0,
   * and [false] if the exit code is non-zero.
   *)


(** Example: This piece of code returns the file listing of "/a" if
 * readable, or otherwise the file listing of "/b":
 *
 * {[ 
 * eval (cmd_output "ls /a" |- cmd_output "ls /b")
 * ]}
 *
 * Loops should be programmed with recursion, or by folding:
 *
 * {[
 * eval
 *   (List.fold_left
 *     (fun acc x ->
 *        acc |- cmdf_output "ls %s" (Filename.quote x))
 *     (set_bool_code true)
 *     [ "/a"; "/b"; "/c" ]
 *   )
 * ]}
 *)


(** {1 Logging} *)

(** Logging outputs to "script.log" in the cwd. *)

val log : string -> unit
  (** Appends the string to the log file. *)

val logf : ('b, unit, string, unit) format4 -> 'b
  (** Same as [log], but accepts a [printf]-like format string *)


(** {1 The conf-*.mk files} *)

(** In general, the conf-*.mk files have [make] syntax. However, these
 * files should only contain [name=value] settings, and not more.
 * The values should not contain any references to other variables
 * ("$\{name\}"), and the dollar character must be written [$$].
 *)

val print_conf_file : string -> (string * string) list -> unit
  (** Writes to [file] the list of variable settings *)

val parse_conf_file : string -> (string * string) list
  (** Parses [file] *)

(** {1 Finding libraries} *)

type lang_env =
    [ `C of c_env ]
  (** Environment to compile and link programs for a certain language. *)

and c_env = 
  { c_env_file : (string * string) option; 
      (** The file this record was parsed from. The first string is the
        * absolute file name, and the second string is the name prefix used
        * in this file
        *)
    c_incdirs : string list;  (** List of directories for "#include"