mirror of
https://github.com/c-cube/moonpool.git
synced 2025-12-18 08:36:43 -05:00
17 lines
No EOL
20 KiB
HTML
17 lines
No EOL
20 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Magic_number (ocaml.Misc.Magic_number)</title><link rel="stylesheet" href="../../../_odoc-theme/odoc.css"/><meta charset="utf-8"/><meta name="generator" content="odoc 2.2.1"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="../../../highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="../index.html">Up</a> – <a href="../../index.html">ocaml</a> » <a href="../index.html">Misc</a> » Magic_number</nav><header class="odoc-preamble"><h1>Module <code><span>Misc.Magic_number</span></code></h1><p>a typical magic number is "Caml1999I011"; it is formed of an alphanumeric prefix, here Caml1990I, followed by a version, here 011. The prefix identifies the kind of the versioned data: here the I indicates that it is the magic number for .cmi files.</p><p>All magic numbers have the same byte length, <code>magic_length</code>, and this is important for users as it gives them the number of bytes to read to obtain the byte sequence that should be a magic number. Typical user code will look like:</p><pre class="language-ocaml"><code>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 -> ...</code></pre><p>A given compiler version expects one specific version for each kind of object file, and will fail if given an unsupported version. Because versions grow monotonically, you can compare the parsed version with the expected "current version" for a kind, to tell whether the wrong-magic object file comes from the past or from the future.</p><p>An example of code block that expects the "currently supported version" of a given kind of magic numbers, here <code>Cmxa</code>, is as follows:</p><pre class="language-ocaml"><code>let ic = open_in_bin path in
|
||
begin
|
||
try Magic_number.(expect_current Cmxa (get_info ic)) with
|
||
| Parse_error error -> ...
|
||
| Unexpected error -> ...
|
||
end;
|
||
...</code></pre><p>Parse errors distinguish inputs that are <code>Not_a_magic_number str</code>, which are likely to come from the file being completely different, and <code>Truncated str</code>, raised by headers that are the (possibly empty) prefix of a valid magic number.</p><p>Unexpected errors correspond to valid magic numbers that are not the one expected, either because it corresponds to a different kind, or to a newer or older version.</p><p>The helper functions <code>explain_parse_error</code> and <code>explain_unexpected_error</code> will generate a textual explanation of each error, for use in error messages.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.11.0</li></ul></header><nav class="odoc-toc"><ul><li><a href="#parsing-magic-numbers">Parsing magic numbers</a></li><li><a href="#checking-that-magic-numbers-are-current">Checking that magic numbers are current</a></li><li><a href="#information-on-magic-numbers">Information on magic numbers</a></li><li><a href="#raw-representations">Raw representations</a></li></ul></nav><div class="odoc-content"><div class="odoc-spec"><div class="spec type anchored" id="type-native_obj_config"><a href="#type-native_obj_config" class="anchor"></a><code><span><span class="keyword">type</span> native_obj_config</span><span> = </span><span>{</span></code><ol><li id="type-native_obj_config.flambda" class="def record field anchored"><a href="#type-native_obj_config.flambda" class="anchor"></a><code><span>flambda : bool;</span></code></li></ol><code><span>}</span></code></div><div class="spec-doc"><p>native object files have a format and magic number that depend on certain native-compiler configuration parameters. This configuration space is expressed by the <code>native_obj_config</code> type.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-native_obj_config"><a href="#val-native_obj_config" class="anchor"></a><code><span><span class="keyword">val</span> native_obj_config : <a href="#type-native_obj_config">native_obj_config</a></span></code></div><div class="spec-doc"><p>the native object file configuration of the active/configured compiler.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-version"><a href="#type-version" class="anchor"></a><code><span><span class="keyword">type</span> version</span><span> = int</span></code></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-kind"><a href="#type-kind" class="anchor"></a><code><span><span class="keyword">type</span> kind</span><span> = </span></code><ol><li id="type-kind.Exec" class="def variant constructor anchored"><a href="#type-kind.Exec" class="anchor"></a><code><span>| </span><span><span class="constructor">Exec</span></span></code></li><li id="type-kind.Cmi" class="def variant constructor anchored"><a href="#type-kind.Cmi" class="anchor"></a><code><span>| </span><span><span class="constructor">Cmi</span></span></code></li><li id="type-kind.Cmo" class="def variant constructor anchored"><a href="#type-kind.Cmo" class="anchor"></a><code><span>| </span><span><span class="constructor">Cmo</span></span></code></li><li id="type-kind.Cma" class="def variant constructor anchored"><a href="#type-kind.Cma" class="anchor"></a><code><span>| </span><span><span class="constructor">Cma</span></span></code></li><li id="type-kind.Cmx" class="def variant constructor anchored"><a href="#type-kind.Cmx" class="anchor"></a><code><span>| </span><span><span class="constructor">Cmx</span> <span class="keyword">of</span> <a href="#type-native_obj_config">native_obj_config</a></span></code></li><li id="type-kind.Cmxa" class="def variant constructor anchored"><a href="#type-kind.Cmxa" class="anchor"></a><code><span>| </span><span><span class="constructor">Cmxa</span> <span class="keyword">of</span> <a href="#type-native_obj_config">native_obj_config</a></span></code></li><li id="type-kind.Cmxs" class="def variant constructor anchored"><a href="#type-kind.Cmxs" class="anchor"></a><code><span>| </span><span><span class="constructor">Cmxs</span></span></code></li><li id="type-kind.Cmt" class="def variant constructor anchored"><a href="#type-kind.Cmt" class="anchor"></a><code><span>| </span><span><span class="constructor">Cmt</span></span></code></li><li id="type-kind.Ast_impl" class="def variant constructor anchored"><a href="#type-kind.Ast_impl" class="anchor"></a><code><span>| </span><span><span class="constructor">Ast_impl</span></span></code></li><li id="type-kind.Ast_intf" class="def variant constructor anchored"><a href="#type-kind.Ast_intf" class="anchor"></a><code><span>| </span><span><span class="constructor">Ast_intf</span></span></code></li></ol></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-info"><a href="#type-info" class="anchor"></a><code><span><span class="keyword">type</span> info</span><span> = </span><span>{</span></code><ol><li id="type-info.kind" class="def record field anchored"><a href="#type-info.kind" class="anchor"></a><code><span>kind : <a href="#type-kind">kind</a>;</span></code></li><li id="type-info.version" class="def record field anchored"><a href="#type-info.version" class="anchor"></a><code><span>version : <a href="#type-version">version</a>;</span></code><div class="def-doc"><span class="comment-delim">(*</span><p>Note: some versions of the compiler use the same <code>version</code> suffix for all kinds, but others use different versions counters for different kinds. We may only assume that versions are growing monotonically (not necessarily always by one) between compiler versions.</p><span class="comment-delim">*)</span></div></li></ol><code><span>}</span></code></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-raw"><a href="#type-raw" class="anchor"></a><code><span><span class="keyword">type</span> raw</span><span> = string</span></code></div><div class="spec-doc"><p>the type of raw magic numbers, such as "Caml1999A027" for the .cma files of OCaml 4.10</p></div></div><h4 id="parsing-magic-numbers"><a href="#parsing-magic-numbers" class="anchor"></a>Parsing magic numbers</h4><div class="odoc-spec"><div class="spec type anchored" id="type-parse_error"><a href="#type-parse_error" class="anchor"></a><code><span><span class="keyword">type</span> parse_error</span><span> = </span></code><ol><li id="type-parse_error.Truncated" class="def variant constructor anchored"><a href="#type-parse_error.Truncated" class="anchor"></a><code><span>| </span><span><span class="constructor">Truncated</span> <span class="keyword">of</span> string</span></code></li><li id="type-parse_error.Not_a_magic_number" class="def variant constructor anchored"><a href="#type-parse_error.Not_a_magic_number" class="anchor"></a><code><span>| </span><span><span class="constructor">Not_a_magic_number</span> <span class="keyword">of</span> string</span></code></li></ol></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-explain_parse_error"><a href="#val-explain_parse_error" class="anchor"></a><code><span><span class="keyword">val</span> explain_parse_error : <span><span><a href="#type-kind">kind</a> option</span> <span class="arrow">-></span></span> <span><a href="#type-parse_error">parse_error</a> <span class="arrow">-></span></span> string</span></code></div><div class="spec-doc"><p>Produces an explanation for a parse error. If no kind is provided, we use an unspecific formulation suggesting that any compiler-produced object file would have been satisfying.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-parse"><a href="#val-parse" class="anchor"></a><code><span><span class="keyword">val</span> parse : <span><a href="#type-raw">raw</a> <span class="arrow">-></span></span> <span><span>(<a href="#type-info">info</a>, <a href="#type-parse_error">parse_error</a>)</span> <a href="../../Stdlib/index.html#type-result">result</a></span></span></code></div><div class="spec-doc"><p>Parses a raw magic number</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-read_info"><a href="#val-read_info" class="anchor"></a><code><span><span class="keyword">val</span> read_info : <span><a href="../../Stdlib/index.html#type-in_channel">in_channel</a> <span class="arrow">-></span></span> <span><span>(<a href="#type-info">info</a>, <a href="#type-parse_error">parse_error</a>)</span> <a href="../../Stdlib/index.html#type-result">result</a></span></span></code></div><div class="spec-doc"><p>Read a raw magic number from an input channel.</p><p>If the data read <code>str</code> is not a valid magic number, it can be recovered from the <code>Truncated str | Not_a_magic_number str</code> payload of the <code>Error parse_error</code> case.</p><p>If parsing succeeds with an <code>Ok info</code> result, we know that exactly <code>magic_length</code> bytes have been consumed from the input_channel.</p><p>If you also wish to enforce that the magic number is at the current version, see <a href="#val-read_current_info"><code>read_current_info</code></a> below.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-magic_length"><a href="#val-magic_length" class="anchor"></a><code><span><span class="keyword">val</span> magic_length : int</span></code></div><div class="spec-doc"><p>all magic numbers take the same number of bytes</p></div></div><h4 id="checking-that-magic-numbers-are-current"><a href="#checking-that-magic-numbers-are-current" class="anchor"></a>Checking that magic numbers are current</h4><div class="odoc-spec"><div class="spec type anchored" id="type-unexpected"><a href="#type-unexpected" class="anchor"></a><code><span><span class="keyword">type</span> <span>'a unexpected</span></span><span> = </span><span>{</span></code><ol><li id="type-unexpected.expected" class="def record field anchored"><a href="#type-unexpected.expected" class="anchor"></a><code><span>expected : <span class="type-var">'a</span>;</span></code></li><li id="type-unexpected.actual" class="def record field anchored"><a href="#type-unexpected.actual" class="anchor"></a><code><span>actual : <span class="type-var">'a</span>;</span></code></li></ol><code><span>}</span></code></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-unexpected_error"><a href="#type-unexpected_error" class="anchor"></a><code><span><span class="keyword">type</span> unexpected_error</span><span> = </span></code><ol><li id="type-unexpected_error.Kind" class="def variant constructor anchored"><a href="#type-unexpected_error.Kind" class="anchor"></a><code><span>| </span><span><span class="constructor">Kind</span> <span class="keyword">of</span> <span><a href="#type-kind">kind</a> <a href="#type-unexpected">unexpected</a></span></span></code></li><li id="type-unexpected_error.Version" class="def variant constructor anchored"><a href="#type-unexpected_error.Version" class="anchor"></a><code><span>| </span><span><span class="constructor">Version</span> <span class="keyword">of</span> <a href="#type-kind">kind</a> * <span><a href="#type-version">version</a> <a href="#type-unexpected">unexpected</a></span></span></code></li></ol></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-check_current"><a href="#val-check_current" class="anchor"></a><code><span><span class="keyword">val</span> check_current : <span><a href="#type-kind">kind</a> <span class="arrow">-></span></span> <span><a href="#type-info">info</a> <span class="arrow">-></span></span> <span><span>(unit, <a href="#type-unexpected_error">unexpected_error</a>)</span> <a href="../../Stdlib/index.html#type-result">result</a></span></span></code></div><div class="spec-doc"><p><code>check_current kind info</code> checks that the provided magic <code>info</code> is the current version of <code>kind</code>'s magic header.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-explain_unexpected_error"><a href="#val-explain_unexpected_error" class="anchor"></a><code><span><span class="keyword">val</span> explain_unexpected_error : <span><a href="#type-unexpected_error">unexpected_error</a> <span class="arrow">-></span></span> string</span></code></div><div class="spec-doc"><p>Provides an explanation of the <code>unexpected_error</code>.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-error"><a href="#type-error" class="anchor"></a><code><span><span class="keyword">type</span> error</span><span> = </span></code><ol><li id="type-error.Parse_error" class="def variant constructor anchored"><a href="#type-error.Parse_error" class="anchor"></a><code><span>| </span><span><span class="constructor">Parse_error</span> <span class="keyword">of</span> <a href="#type-parse_error">parse_error</a></span></code></li><li id="type-error.Unexpected_error" class="def variant constructor anchored"><a href="#type-error.Unexpected_error" class="anchor"></a><code><span>| </span><span><span class="constructor">Unexpected_error</span> <span class="keyword">of</span> <a href="#type-unexpected_error">unexpected_error</a></span></code></li></ol></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-read_current_info"><a href="#val-read_current_info" class="anchor"></a><code><span><span class="keyword">val</span> read_current_info :
|
||
<span>expected_kind:<span><a href="#type-kind">kind</a> option</span> <span class="arrow">-></span></span>
|
||
<span><a href="../../Stdlib/index.html#type-in_channel">in_channel</a> <span class="arrow">-></span></span>
|
||
<span><span>(<a href="#type-info">info</a>, <a href="#type-error">error</a>)</span> <a href="../../Stdlib/index.html#type-result">result</a></span></span></code></div><div class="spec-doc"><p>Read a magic number as <code>read_info</code>, and check that it is the current version as its kind. If the <code>expected_kind</code> argument is <code>None</code>, any kind is accepted.</p></div></div><h4 id="information-on-magic-numbers"><a href="#information-on-magic-numbers" class="anchor"></a>Information on magic numbers</h4><div class="odoc-spec"><div class="spec value anchored" id="val-string_of_kind"><a href="#val-string_of_kind" class="anchor"></a><code><span><span class="keyword">val</span> string_of_kind : <span><a href="#type-kind">kind</a> <span class="arrow">-></span></span> string</span></code></div><div class="spec-doc"><p>a user-printable string for a kind, eg. "exec" or "cmo", to use in error messages.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-human_name_of_kind"><a href="#val-human_name_of_kind" class="anchor"></a><code><span><span class="keyword">val</span> human_name_of_kind : <span><a href="#type-kind">kind</a> <span class="arrow">-></span></span> string</span></code></div><div class="spec-doc"><p>a user-meaningful name for a kind, eg. "executable file" or "bytecode object file", to use in error messages.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-current_raw"><a href="#val-current_raw" class="anchor"></a><code><span><span class="keyword">val</span> current_raw : <span><a href="#type-kind">kind</a> <span class="arrow">-></span></span> <a href="#type-raw">raw</a></span></code></div><div class="spec-doc"><p>the current magic number of each kind</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-current_version"><a href="#val-current_version" class="anchor"></a><code><span><span class="keyword">val</span> current_version : <span><a href="#type-kind">kind</a> <span class="arrow">-></span></span> <a href="#type-version">version</a></span></code></div><div class="spec-doc"><p>the current version of each kind</p></div></div><h4 id="raw-representations"><a href="#raw-representations" class="anchor"></a>Raw representations</h4><p>Mainly for internal usage and testing.</p><div class="odoc-spec"><div class="spec type anchored" id="type-raw_kind"><a href="#type-raw_kind" class="anchor"></a><code><span><span class="keyword">type</span> raw_kind</span><span> = string</span></code></div><div class="spec-doc"><p>the type of raw magic numbers kinds, such as "Caml1999A" for .cma files</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-parse_kind"><a href="#val-parse_kind" class="anchor"></a><code><span><span class="keyword">val</span> parse_kind : <span><a href="#type-raw_kind">raw_kind</a> <span class="arrow">-></span></span> <span><a href="#type-kind">kind</a> option</span></span></code></div><div class="spec-doc"><p>parse a raw kind into a kind</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-raw_kind"><a href="#val-raw_kind" class="anchor"></a><code><span><span class="keyword">val</span> raw_kind : <span><a href="#type-kind">kind</a> <span class="arrow">-></span></span> <a href="#type-raw_kind">raw_kind</a></span></code></div><div class="spec-doc"><p>the current raw representation of a kind.</p><p>In some cases the raw representation of a kind has changed over compiler versions, so other files of the same kind may have different raw kinds. Note that all currently known cases are parsed correctly by <code>parse_kind</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-raw"><a href="#val-raw" class="anchor"></a><code><span><span class="keyword">val</span> raw : <span><a href="#type-info">info</a> <span class="arrow">-></span></span> <a href="#type-raw">raw</a></span></code></div><div class="spec-doc"><p>A valid raw representation of the magic number.</p><p>Due to past and future changes in the string representation of magic numbers, we cannot guarantee that the raw strings returned for past and future versions actually match the expectations of those compilers. The representation is accurate for current versions, and it is correctly parsed back into the desired version by the parsing functions above.</p></div></div></div></body></html> |