blob: 0fafd1f2b95b74cea7ae8e67d4f324ef7a8c37d2 (
plain) (
blame)
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
|
module OI = Colitur_kernel.Overlay_ini
type t = {
lang : string option;
overlays : string list;
template : string option;
format : string option;
unknown_keys : string list;
unknown_sections : string list;
}
let empty =
{ lang = None; overlays = []; template = None; format = None; unknown_keys = [];
unknown_sections = [] }
let lang t = t.lang
let overlays t = t.overlays
let template t = t.template
let format t = t.format
let unknown_keys t = t.unknown_keys
let unknown_sections t = t.unknown_sections
let of_string text =
match OI.parse_sections text with
| Error e -> Error e
| Ok sections ->
(* Any section that is not [defaults] is unrecognised -- including a
plain typo such as [deafults] -- and must be REPORTED, never
silently dropped: that is precisely the failure this feature exists
to surface. *)
let unknown_sections =
List.filter_map
(fun (s : OI.section) -> if s.OI.name = "defaults" then None else Some s.OI.name)
sections
in
let acc =
match List.find_opt (fun (s : OI.section) -> s.OI.name = "defaults") sections with
| None -> empty
| Some s ->
(* Cons then reverse once at the end, not `@ [v]` per line: the
latter is O(n^2) over the field count, a real hang on a
machine-generated file with many overlay lines. *)
let acc =
List.fold_left
(fun acc (k, v) ->
match k with
| "lang" -> { acc with lang = Some v }
| "template" -> { acc with template = Some v }
| "format" -> { acc with format = Some v }
(* accumulates: a user has more than one overlay *)
| "overlay" -> { acc with overlays = v :: acc.overlays }
| other -> { acc with unknown_keys = other :: acc.unknown_keys })
empty s.OI.fields
in
{ acc with overlays = List.rev acc.overlays; unknown_keys = List.rev acc.unknown_keys }
in
Ok { acc with unknown_sections }
let resolve ~flag ~config ~default =
match flag with
| Some v -> (v, "flag")
| None -> ( match config with Some v -> (v, "config") | None -> (default, "default"))
|