模組 Misc.Magic_number

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_errorexplain_unexpected_error 將會產生每個錯誤的文字說明,以便在錯誤訊息中使用。

type native_obj_config = {
   flambda : bool;
}

原生物件檔案的格式和魔術數字取決於某些原生編譯器組態參數。此組態空間由 native_obj_config 類型表示。

val native_obj_config : native_obj_config

活動/已組態編譯器的原生物件檔案組態。

type version = int 
type kind = 
| Exec
| Cmi
| Cmo
| Cma
| Cmx of native_obj_config
| Cmxa of native_obj_config
| Cmxs
| Cmt
| Ast_impl
| Ast_intf
type info = {
   kind : kind;
   version : version; (*

注意:某些版本的編譯器對所有種類都使用相同的 version 後綴,但其他版本則對不同的種類使用不同的版本計數器。我們只能假設版本在編譯器版本之間是單調遞增的(不一定總是加一)。

*)
}
type raw = string 

原始魔術數字的類型,例如 OCaml 4.10 的 .cma 檔案的 "Caml1999A027"

解析魔術數字

type parse_error = 
| Truncated of string
| Not_a_magic_number of string
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 : 'a;
   actual : 'a;
}
type unexpected_error = 
| Kind of kind unexpected
| Version of kind
* version unexpected
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 parse_error
| Unexpected_error of unexpected_error
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

使用者有意義的種類名稱,例如 "executable file" 或 "bytecode object file",用於錯誤訊息中。

val current_raw : kind -> raw

每種類型的目前魔術數字

val current_version : kind -> version

每種類型的目前版本

原始表示法

主要用於內部使用和測試。

type raw_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