try_finally work ~always ~exceptionally is designed to run code in work that may fail with an exception, and has two kind of cleanup routines: always, that must be run after any execution of the function (typically, freeing system resources), and exceptionally, that should be run only if work or always failed with an exception (typically, undoing user-visible state changes that would only make sense if the function completes correctly). For example:
let objfile = outputprefix ^ ".cmo" in
let oc = open_out_bin objfile in
Misc.try_finally
(fun () ->
bytecode
++ Timings.(accumulate_time (Generate sourcefile))
(Emitcode.to_file oc modulename objfile);
Warnings.check_fatal ())
~always:(fun () -> close_out oc)
~exceptionally:(fun _exn -> remove_file objfile);
If exceptionally fail with an exception, it is propagated as usual.
If always or exceptionally use exceptions internally for control-flow but do not raise, then try_finally is careful to preserve any exception backtrace coming from work or always for easier debugging.
expand_directory alt file eventually expands a + at the beginning of file into alt (an alternate root directory)
Sourceval split_path_contents : ?sep:char ->string ->string list
split_path_contents ?sep s interprets s as the value of a "PATH"-like variable and returns the corresponding list of directories. s is split using the platform-specific delimiter, or ~sep if it is passed.
Produce output in temporary file, then rename it (as atomically as possible) to the desired output file name. output_to_file_via_temporary filename fn opens a temporary file which is passed to fn (name + output channel). When fn returns, the channel is closed and the temporary file is renamed to filename.
Open the given filename for writing (in binary mode), pass the out_channel to the given function, then close the channel. If the function raises an exception then filename will be removed.
Return the given file name without its extensions. The extensions is the longest suffix starting with a period and not including a directory separator, .xyz.uvw for instance.
Return the given name if it does not contain an extension.
find_first_mono p takes an integer predicate p : int -> bool that we assume: 1. is monotonic on natural numbers: if a <= b then p a implies p b, 2. is satisfied for some natural numbers in range 0; max_int (this is equivalent to: p max_int = true).
find_first_mono p is the smallest natural number N that satisfies p, computed in O(log(N)) calls to p.
Our implementation supports two cases where the preconditions on p are not respected:
If p is always false, we silently return max_int instead of looping or crashing.
If p is non-monotonic but eventually true, we return some satisfying value.
String operations
Sourceval search_substring : string ->string ->int -> int
search_substring pat str start returns the position of the first occurrence of string pat in string str. Search starts at offset start in str. Raise Not_found if pat does not occur.
String.cut_at s c returns a pair containing the sub-string before the first occurrence of c in s, and the sub-string after the first occurrence of c in s. let (before, after) = String.cut_at s c in before ^ String.make 1 c ^ after is the identity if s contains c.
Raise Not_found if the character does not appear in the string
ordinal_suffix n is the appropriate suffix to append to the numeral n as an ordinal number: 1 -> "st", 2 -> "nd", 3 -> "rd", 4 -> "th", and so on. Handles larger numbers (e.g., 42 -> "nd") and the numbers 11--13 (which all get "th") correctly.
normalise_eol s returns a fresh copy of s with any '\r' characters removed. Intended for pre-processing text which will subsequently be printed on a channel which performs EOL transformations (i.e. Windows)
protect_refs l f temporarily sets r to v for each R (r, v) in l while executing f. The previous contents of the references is restored even if f raises an exception, without altering the exception backtrace.
edit_distance a b cutoff computes the edit distance between strings a and b. To help efficiency, it uses a cutoff: if the distance d is smaller than cutoff, it returns Some d, else None.
The distance algorithm currently used is Damerau-Levenshtein: it computes the number of insertion, deletion, substitution of letters, or swapping of adjacent letters to go from one word to the other. The particular algorithm may change in the future.
Sourceval spellcheck : string list->string ->string list
spellcheck env name takes a list of names env that exist in the current environment and an erroneous name, and returns a list of suggestions taken from env, that are close enough to name that it may be a typo for one of them.
aligned_hint main hint vertically aligns a main message and a hint message. The vertical alignment is controlled by the use of @{<ralign> ... @} boxes: the start of one box, in either the hint or the main message, will be shifted on the left to ensure that the end of the two boxes are vertically aligned, taking in account a pre-existing prefix before the main message. For instance,
let main, sub =
align_hint
~prefix:"Error: "
(doc_printf "@{<ralign>The value @}%a is not an instance variable"
Style.inline_code "foobar"
)
(doc_printf
"@{<ralign>Did you mean @}%a" Style.inline_code "foobaz"
) in
printf "Error: %a%a" pp_doc main pp_doc sub
produces the following text:
Error: The value "foobaz" is not an instance variable
Hint: Did you mean "foobar"?
where the main message has been shifted to the left to align "foobaz" and "foobar".
aligned_hint ~prefix fmt ... hint align the potential hint with the main error message generated by the format string fmt before printing the two message.
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.
Minimal support for Unicode characters in identifiers
Characters allowed in identifiers are, currently:
ASCII letters A-Z a-z
Latin-1 letters (U+00C0 - U+00FF except U+00D7 and U+00F7)
Character sequences which normalize to the above character under NFC