(* $Id$ * ---------------------------------------------------------------------- * *) (** Parses META files *) open Fl_metatoken type formal_pred = [ `Pred of string (** Positive occurrence of a formal predicate var *) | `NegPred of string (** Negative occurrence of a formal predicate var *) ] type flavour = [ `BaseDef | `Appendix ] (** [`BaseDef] refers to META definitions using the "=" operator, * and [`Appendix] refers to definitions using the "+=" operator. *) type pkg_definition = { def_var : string; (** The name of the defined variable *) def_flav : flavour; (** The flavour of the definition *) def_preds : formal_pred list; (** The formal predicates of the def *) def_value : string; (** The value assigned to the variable *) } (** A [pkg_definition] is expressed by the syntax * {[ var(p1,p2,...) = "value" ]} (flavour `BaseDef), * or the syntax * {[ var(p1,p2,...) += "value" ]} (flavour `Appendix) * in the META file. The list of predicates may be omitted. Predicates * may be negated by using "-", e.g. "-x". *) type pkg_expr = { pkg_defs : pkg_definition list; pkg_children : (string * pkg_expr) list; } (** A value of type [pkg_expr] denotes the contents of a META file. * The component [pkg_defs] are the variable definitions. * The component [pkg_children] contains * the definitions of the subpackages. *) exception Error of string val parse : in_channel -> pkg_expr (** [parse ch:] * scans and parses the file connected with channel [ch]. The file must * have a syntax compatible with the META format. The return value * contains the found definitions for the package and all subpackages. * * [exception Error of string:] is * raised on syntax errors. The string explains the error. *) val parse_lexing : Lexing.lexbuf -> pkg_expr val print_def : out_channel -> pkg_definition -> unit (** [print_def ch def]: * Outputs the definition to a channel. *) val print : out_channel -> pkg_expr -> unit (** [print ch expr]: * Outputs the package expression to a channel. *) val lookup : string -> string list -> pkg_definition list -> string (** [lookup variable_name predicate_list def]: * * Returns the value of [variable_name] in [def] under the assumption * that the predicates in [predicate_list] hold, but no other predicates. * * The rules are as follows: In the step (A), only the [`BaseDef] * definitions are considered. The first base definition is determined where * all predicates are satisfied and that has the longest predicate list. * In the step (B) only the [`Appendix] definitions are considered. * All definitions are determined where all predicates are satisfied. * The final result is the concatenation of the single result of (A) * and all results of (B) (in the order they are defined). A space * character is inserted between two concatenated strings. * * When step (A) does not find any matching definition, the exception * [Not_found] is raised. *) val lookup_2 : string -> string list -> pkg_definition list -> string * formal_pred list (** Like [lookup], but also returns the list of predicates that had to be considered to select the particular variable definition. *) val predicate_exists : string -> pkg_definition list -> bool (** [predicate_exists variable_name def]: Whether [variable_name] is explicitly mentioned in [def]. *)