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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
type modname = string
type filename = string
type file_prefix = string
type t = {
source_file: filename;
prefix: file_prefix;
modname: modname;
}
let source_file (x: t) = x.source_file
let modname (x: t) = x.modname
let prefix (x: t) = x.prefix
let basename_chop_extensions basename =
match String.index basename '.' with
| dot_pos -> String.sub basename 0 dot_pos
| exception Not_found -> basename
let modulize s = String.capitalize_ascii s
let normalize = Misc.normalized_unit_filename
let modname_from_source source_file =
source_file |> Filename.basename |> basename_chop_extensions |> modulize
let start_char = function
| 'A' .. 'Z' -> true
| _ -> false
let is_identchar_latin1 = function
| 'A'..'Z' | 'a'..'z' | '_' | '\192'..'\214' | '\216'..'\246'
| '\248'..'\255' | '\'' | '0'..'9' -> true
| _ -> false
let is_unit_name name =
String.length name > 0
&& start_char name.[0]
&& String.for_all is_identchar_latin1 name
let check_unit_name file =
if not (is_unit_name (modname file)) then
Location.prerr_warning (Location.in_file (source_file file))
(Warnings.Bad_module_name (modname file))
let make ?(check_modname=true) ~source_file prefix =
let modname = modname_from_source prefix in
let p = { modname; prefix; source_file } in
if check_modname then check_unit_name p;
p
module Artifact = struct
type t =
{
source_file: filename option;
filename: filename;
modname: modname;
}
let source_file x = x.source_file
let filename x = x.filename
let modname x = x.modname
let prefix x = Filename.remove_extension (filename x)
let from_filename filename =
let modname = modname_from_source filename in
{ modname; filename; source_file = None }
end
let mk_artifact ext u =
{
Artifact.filename = u.prefix ^ ext;
modname = u.modname;
source_file = Some u.source_file;
}
let companion_artifact ext x =
{ x with Artifact.filename = Artifact.prefix x ^ ext }
let cmi f = mk_artifact ".cmi" f
let cmo f = mk_artifact ".cmo" f
let cmx f = mk_artifact ".cmx" f
let obj f = mk_artifact Config.ext_obj f
let cmt f = mk_artifact ".cmt" f
let cmti f = mk_artifact ".cmti" f
let annot f = mk_artifact ".annot" f
let companion_obj f = companion_artifact Config.ext_obj f
let companion_cmt f = companion_artifact ".cmt" f
let companion_cmi f =
let prefix = Misc.chop_extensions f.Artifact.filename in
{ f with Artifact.filename = prefix ^ ".cmi"}
let mli_from_artifact f = Artifact.prefix f ^ !Config.interface_suffix
let mli_from_source u =
let prefix = Filename.remove_extension (source_file u) in
prefix ^ !Config.interface_suffix
let is_cmi f = Filename.check_suffix (Artifact.filename f) ".cmi"
let find_normalized_cmi f =
let filename = modname f ^ ".cmi" in
let filename = Load_path.find_normalized filename in
{ Artifact.filename; modname = modname f; source_file = Some f.source_file }