forked from ocaml/ocaml
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathconfiguration.ml
96 lines (79 loc) · 3.31 KB
/
configuration.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
(***********************************************************************)
(* *)
(* ocamlbuild *)
(* *)
(* Nicolas Pouillard, Berke Durak, projet Gallium, INRIA Rocquencourt *)
(* *)
(* Copyright 2007 Institut National de Recherche en Informatique et *)
(* en Automatique. All rights reserved. This file is distributed *)
(* under the terms of the GNU Library General Public License, with *)
(* the special exception on linking described in file ../LICENSE. *)
(* *)
(***********************************************************************)
(* Original author: Nicolas Pouillard *)
open My_std
open Log
open Lexers
type t = Lexers.conf
let acknowledge_config source config =
let ack (tag, loc) = Param_tags.acknowledge source (Some loc) tag in
List.iter (fun (_, config) -> List.iter ack config.plus_tags) config
let cache = Hashtbl.create 107
let (configs, add_config) =
let configs = ref [] in
(fun () -> !configs),
(fun source config ->
acknowledge_config source config;
configs := config :: !configs;
Hashtbl.clear cache)
let parse_lexbuf ?dir source lexbuf =
let conf = Lexers.conf_lines dir source lexbuf in
add_config source conf
let parse_string ?source s =
let source = match source with
| Some source -> source
| None -> Const.Source.configuration
in
parse_lexbuf source (lexbuf_of_string s)
let parse_file ?dir file =
with_input_file file begin fun ic ->
let lexbuf = Lexing.from_channel ic in
set_lexbuf_fname file lexbuf;
parse_lexbuf ?dir Const.Source.file lexbuf
end
let key_match = Glob.eval
let apply_config s (config : t) init =
let add (tag, _loc) = Tags.add tag in
let remove (tag, _loc) = Tags.remove tag in
List.fold_left begin fun tags (key, v) ->
if key_match key s then
List.fold_right add v.plus_tags (List.fold_right remove v.minus_tags tags)
else tags
end init config
let apply_configs s = List.fold_right (apply_config s) (configs ()) Tags.empty
let tags_of_filename s =
try Hashtbl.find cache s
with Not_found ->
let res = apply_configs s in
let () = Hashtbl.replace cache s res in
res
let global_tags () = tags_of_filename ""
let has_tag tag = Tags.mem tag (global_tags ())
let tag_file file tags =
if tags <> [] then parse_string (Printf.sprintf "%S: %s" file (String.concat ", " tags));;
let tag_any tags =
if tags <> [] then parse_string (Printf.sprintf "true: %s" (String.concat ", " tags));;
let check_tags_usage useful_tags =
let check_tag (tag, loc) =
if not (Tags.mem tag useful_tags) then
Log.eprintf "%aWarning: the tag %S is not used in any flag or dependency \
declaration, so it will have no effect; it may be a typo. \
Otherwise you can use `mark_tag_used` in your myocamlbuild.ml \
to disable this warning."
Loc.print_loc loc tag
in
let check_conf (_, values) =
List.iter check_tag values.plus_tags;
List.iter check_tag values.minus_tags;
in
List.iter (List.iter check_conf) (configs ())