module Magic_number:sig
..end
一个典型的魔数是 "Caml1999I011";它由一个字母数字前缀(此处为 Caml1990I)和一个版本号(此处为 011)组成。前缀标识版本化数据的类型:此处 I 表示它是 .cmi 文件的魔数。
所有魔数都具有相同的字节长度,magic_length
,这对用户来说非常重要,因为它告诉他们需要读取多少个字节才能获取应该作为魔数的字节序列。典型的用户代码如下所示
let ic = open_in_bin path in
let magic =
try really_input_string ic Magic_number.magic_length
with End_of_file -> ... in
match Magic_number.parse magic with
| Error parse_error -> ...
| Ok info -> ...
给定的编译器版本期望每种类型的目标文件都使用一个特定的版本,如果给定不支持的版本,则会失败。由于版本单调递增,因此您可以将解析的版本与某种类型的预期“当前版本”进行比较,以判断错误魔数的目标文件来自过去还是未来。
以下是一个代码块示例,该代码块期望给定类型的魔数的“当前支持版本”,此处为 Cmxa
:
let ic = open_in_bin path in
begin
try Magic_number.(expect_current Cmxa (get_info ic)) with
| Parse_error error -> ...
| Unexpected error -> ...
end;
...
解析错误区分输入是 Not_a_magic_number str
(这可能是由于文件完全不同造成的)和 Truncated str
(由作为有效魔数的前缀(可能是空前缀)的头文件引发)。
意外错误对应于不是预期魔数的有效魔数,这可能是因为它们对应于不同的类型,或者对应于更新或旧的版本。
辅助函数 explain_parse_error
和 explain_unexpected_error
将生成每个错误的文本解释,供错误消息使用。
type
native_obj_config = {
|
flambda : |
}
原生目标文件的格式和魔数取决于某些原生编译器配置参数。此配置空间由 native_obj_config
类型表示。
val native_obj_config : native_obj_config
活动/已配置编译器的原生目标文件配置。
typeversion =
int
type
kind =
| |
Exec |
| |
Cmi |
| |
Cmo |
| |
Cma |
| |
Cmx of |
| |
Cmxa of |
| |
Cmxs |
| |
Cmt |
| |
Ast_impl |
| |
Ast_intf |
type
info = {
|
kind : |
|||
|
version : |
(* | 注意:某些版本的编译器对所有类型使用相同的 | *) |
}
typeraw =
string
原始魔数的类型,例如 OCaml 4.10 的 .cma 文件的 "Caml1999A027"
type
parse_error =
| |
Truncated of |
| |
Not_a_magic_number of |
val explain_parse_error : kind option -> parse_error -> string
生成解析错误的解释。如果没有提供类型,我们将使用一种不特定的表述,表明任何编译器生成的输出文件都应该能够满足要求。
val parse : raw ->
(info, parse_error) result
解析原始魔数
val read_info : in_channel ->
(info, parse_error) result
从输入通道读取原始魔数。
如果读取的数据 str
不是有效的魔数,则可以从 Truncated str | Not_a_magic_number str
负载的 Error parse_error
案例中恢复它。
如果解析成功并得到 Ok info
结果,我们知道已从 input_channel 中消耗了正好 magic_length
个字节。
如果您还想强制魔数处于当前版本,请参阅下面的 Misc.Magic_number.read_current_info
。
val magic_length : int
所有魔数都占用相同数量的字节
type 'a
unexpected = {
|
expected : |
|
actual : |
}
type
unexpected_error =
| |
Kind of |
| |
Version of |
val check_current : kind ->
info ->
(unit, unexpected_error) result
check_current kind info
检查提供的魔数 info
是否为 kind
的魔数头的当前版本。
val explain_unexpected_error : unexpected_error -> string
提供 unexpected_error
的解释。
type
error =
| |
Parse_error of |
| |
Unexpected_error of |
val read_current_info : expected_kind:kind option ->
in_channel ->
(info, error) result
将魔数读取为 read_info
,并检查它是否为其类型的当前版本。如果 expected_kind
参数为 None
,则接受任何类型。
val string_of_kind : kind -> string
类型的用户可打印字符串,例如 "exec" 或 "cmo",用于错误消息。
val human_name_of_kind : kind -> string
类型的用户友好的名称,例如 "可执行文件" 或 "字节码目标文件",用于错误消息。
val current_raw : kind -> raw
每种类型的当前魔数
val current_version : kind -> version
每种类型的当前版本
主要用于内部使用和测试。
typeraw_kind =
string
原始魔数类型的类型,例如 .cma 文件的 "Caml1999A"
val parse_kind : raw_kind -> kind option
将原始类型解析为类型。
val raw_kind : kind -> raw_kind
类型的当前原始表示。
在某些情况下,类型的原始表示在编译器版本之间发生了变化,因此相同类型的其他文件可能具有不同的原始类型。请注意,所有当前已知的案例都由 parse_kind
正确解析。
val raw : info -> raw
魔数的有效原始表示。
由于魔数字符串表示形式的过去和未来更改,我们无法保证为过去和未来版本返回的原始字符串是否实际与这些编译器的期望相匹配。该表示对于当前版本是准确的,并且通过上述解析函数可以将其正确地解析回所需的版本。
val all_kinds : kind list