jon.recoil.org

Module Ocaml_utils.MiscSource

Miscellaneous useful types and functions

Warning: this module is unstable and part of compiler-libs.

Reporting fatal errors

Sourceval fatal_error : string -> 'a

Raise the Fatal_error exception with the given string.

Sourceval fatal_errorf : ('a, Format.formatter, unit, 'b) format4 -> 'a

Format the arguments according to the given format string and raise Fatal_error with the resulting string.

Sourceval fatal_errorf_doc : ('a, Format_doc.formatter, unit, 'b) format4 -> 'a

Like fatal_errorf but using Format_doc.

Sourceexception Fatal_error of string * Printexc.raw_backtrace

Exceptions and finalization

Sourceval try_finally : ?always:(unit -> unit) -> ?exceptionally:(unit -> unit) -> (unit -> 'a) -> 'a

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.

Sourceval reraise_preserving_backtrace : exn -> (unit -> unit) -> 'a

reraise_preserving_backtrace e f is (f (); raise e) except that the current backtrace is preserved, even if f uses exceptions internally.

List operations

Sourceval map_end : ('a -> 'b) -> 'a list -> 'b list -> 'b list

map_end f l t is map f l @ t, just more efficient.

Sourceval rev_map_end : ('a -> 'b) -> 'a list -> 'b list -> 'b list

rev_map_end f l t is map f (rev l) @ t, just more efficient.

Sourceval map_left_right : ('a -> 'b) -> 'a list -> 'b list

Like List.map, with guaranteed left-to-right evaluation order

Sourceval for_all2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool

Same as List.for_all but for a binary predicate. In addition, this for_all2 never fails: given two lists with different lengths, it returns false.

Sourceval replicate_list : 'a -> int -> 'a list

replicate_list elem n is the list with n elements all identical to elem.

Sourceval list_remove : 'a -> 'a list -> 'a list

list_remove x l returns a copy of l with the first element equal to x removed.

Sourceval split_last : 'a list -> 'a list * 'a

Return the last element and the other elements of the given list.

Sourceval last : 'a list -> 'a option

Return the last element of a list if it's nonempty

Sourceval repeated_label : (string option * 'a) list -> string option

Detects a repeated label - for use with labeled tuples.

Hash table operations

Sourceval create_hashtable : int -> ('a * 'b) list -> ('a, 'b) Hashtbl.t

Create a hashtable with the given initial size and fills it with the given bindings.

Extensions to the standard library

Sourcemodule Stdlib : sig ... end

Operations on files and file paths

Sourceval find_in_path : string list -> string -> string

Search a file in a list of directories.

Sourceval find_in_path_rel : string list -> string -> string

Search a relative file in a list of directories.

Sourceval normalized_unit_filename : string -> string

Normalize file name Foo.ml to foo.ml

Sourceval find_in_path_normalized : ?fallback:string -> string list -> string -> string

Same as find_in_path_rel , but search also for normalized unit filename, i.e. if name is Foo.ml, allow /path/Foo.ml and /path/foo.ml to match.

Sourceval remove_file : string -> unit

Delete the given file if it exists and is a regular file. Does nothing for other kinds of files. Never raises an error.

Sourceval remove_dir : string -> unit

Delete the given directory if it exists, is a directory, and is empty. Never raises an error.

Sourceval remove_dir_contents : string -> unit

Delete all files in the given directory, then delete the directory itself. Only handles flat directories (no subdirectories). Never raises an error.

Sourceval expand_directory : string -> string -> string

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.

Returns the empty list if s is empty.

Sourceval copy_file : in_channel -> out_channel -> unit

copy_file ic oc reads the contents of file ic and copies them to oc. It stops when encountering EOF on ic.

Sourceval copy_file_chunk : in_channel -> out_channel -> int -> unit

copy_file_chunk ic oc n reads n bytes from ic and copies them to oc. It raises End_of_file when encountering EOF on ic.

Sourceval string_of_file : in_channel -> string

string_of_file ic reads the contents of file ic and copies them to a string. It stops when encountering EOF on ic.

Sourceval output_to_file_via_temporary : ?mode:open_flag list -> string -> (string -> out_channel -> 'a) -> 'a

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.

Sourceval protect_output_to_file : string -> (out_channel -> 'a) -> 'a

Open the given filename for binary writing, pass the out_channel to the given function, then close the channel. If the function raises an exception, then filename will be removed and the backtrace is printed; otherwise, the file name is recorded, and the file can still be retroactively removed by remove_successful_output_files.

Sourceval remove_successful_output_files : unit -> unit

Remove all successful writes done by protect_output_to_file.

Sourceval mk_temp_dir : ?perms:int -> string -> string -> string

Create a temporary directory with a random number in the name.

Sourceval concat_null_terminated : string list -> string

concat_null_terminated [x1;x2; ... xn] is x1 ^ "\000" ^ x2 ^ "\000" ^ ... ^ xn ^ "\000"

Sourceval split_null_terminated : string -> string list

split_null_terminated s is similar String.split_on_char '\000' but ignores the trailing separator, if any

Sourceval chop_extensions : string -> string

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.

Integer operations

Sourceval log2 : int -> int

log2 n returns s such that n = 1 lsl s if n is a power of 2

Sourceval log2_nativeint : nativeint -> int

log2_nativeint n computes floor (log2 n) when n > 0 . If n is also a power of 2, the result s satisfies n = Nativeint.shift_left 1n s

Sourceval power : base:int -> int -> int

power ~base x computes base**x.

Sourceval align : int -> int -> int

align n a rounds n upwards to a multiple of a (a power of 2).

Sourceval no_overflow_add : int -> int -> bool

no_overflow_add n1 n2 returns true if the computation of n1 + n2 does not overflow.

Sourceval no_overflow_sub : int -> int -> bool

no_overflow_sub n1 n2 returns true if the computation of n1 - n2 does not overflow.

Sourceval no_overflow_mul : int -> int -> bool

no_overflow_mul n1 n2 returns true if the computation of n1 * n2 does not overflow.

Sourceval no_overflow_lsl : int -> int -> bool

no_overflow_lsl n k returns true if the computation of n lsl k does not overflow.

Sourceval no_overflow_add_int64 : int64 -> int64 -> bool

no_overflow_add_int64 n1 n2 returns true if the computation of Int64.add n1 n2 does not overflow.

Sourceval no_overflow_sub_int64 : int64 -> int64 -> bool

no_overflow_sub_int64 n1 n2 returns true if the computation of Int64.sub n1 n2 does not overflow.

Sourceval letter_of_int : int -> string
Sourcemodule Int_literal_converter : sig ... end
Sourceval find_first_mono : (int -> bool) -> int

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.

Sourceval replace_substring : before:string -> after:string -> string -> string

replace_substring ~before ~after str replaces all occurrences of before with after in str and returns the resulting string.

Sourceval rev_split_words : string -> string list

rev_split_words s splits s in blank-separated words, and returns the list of words in reverse order.

Sourceval cut_at : string -> char -> string * string

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

  • since 4.01
Sourceval ordinal_suffix : int -> 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.

Sourceval format_as_unboxed_literal : string -> string

format_as_unboxed_literal constant_literal converts constant_literal to its corresponding unboxed literal by either adding "#" in front or changing "-" to "-#".

Examples:

0.1 to #0.1 -3 to -#3 0xa.cp-1 to #0xa.cp-1

Sourceval normalise_eol : string -> string

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)

Sourceval delete_eol_spaces : string -> string

delete_eol_spaces s returns a fresh copy of s with any end of line spaces removed. Intended to normalize the output of the toplevel for tests.

Operations on references

Sourcetype ref_and_value =
  1. | R : 'a ref * 'a -> ref_and_value
Sourceval protect_refs : ref_and_value list -> (unit -> 'a) -> 'a

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.

Sourceval get_ref : 'a list ref -> 'a list

get_ref lr returns the content of the list reference lr and reset its content to the empty list.

Sourceval set_or_ignore : ('a -> 'b option) -> 'b option ref -> 'a -> unit

set_or_ignore f opt x sets opt to f x if it returns Some _, or leaves it unmodified if it returns None.

Operations on triples and quadruples

Sourceval fst3 : ('a * 'b * 'c) -> 'a
Sourceval snd3 : ('a * 'b * 'c) -> 'b
Sourceval thd3 : ('a * 'b * 'c) -> 'c
Sourceval fst4 : ('a * 'b * 'c * 'd) -> 'a
Sourceval snd4 : ('a * 'b * 'c * 'd) -> 'b
Sourceval thd4 : ('a * 'b * 'c * 'd) -> 'c
Sourceval for4 : ('a * 'b * 'c * 'd) -> 'd

Spell checking and ``did you mean'' suggestions

Sourceval edit_distance : string -> string -> int -> int option

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.

Sourceval did_you_mean : Format_doc.formatter -> (unit -> string list) -> unit

did_you_mean ppf get_choices hints that the user may have meant one of the option returned by calling get_choices. It does nothing if the returned list is empty.

The unit -> ... thunking is meant to delay any potentially-slow computation (typically computing edit-distance with many things from the current environment) to when the hint message is to be printed. You should print an understandable error message before calling did_you_mean, so that users get a clear notification of the failure even if producing the hint is slow.

Sourcemodule Color : sig ... end

Styling handling for terminal output

Sourcemodule Style : sig ... end
Sourcemodule Error_style : sig ... end

Formatted output

Sourceval print_if : Format.formatter -> bool ref -> (Format.formatter -> 'a -> unit) -> 'a -> 'a

print_if ppf flag fmt x prints x with fmt on ppf if flag is true.

Sourceval pp_two_columns : ?sep:string -> ?max_lines:int -> Format.formatter -> (string * string) list -> unit

pp_two_columns ?sep ?max_lines ppf l prints the lines in l as two columns separated by sep ("|" by default). max_lines can be used to indicate a maximum number of lines to print -- an ellipsis gets inserted at the middle if the input has too many lines.

Example:

pp_two_columns ~max_lines:3 Format.std_formatter [
  "abc", "hello";
  "def", "zzz";
  "a"  , "bllbl";
  "bb" , "dddddd";
]

prints

abc | hello
...
bb  | dddddd
Sourceval pp_table : Format.formatter -> (string * string list) list -> unit

pp_table ppf l prints the table l, a list of columns with their header. The function fails with a fatal error if the columns have different length.

Sourceval pp_parens_if : bool -> (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a -> unit

pp_parens_if bool formatter ppf arg prints formatter ppf arg, wrapping it with () if bool is true.

Sourceval pp_nested_list : nested:bool -> pp_element:(nested:bool -> Format.formatter -> 'a -> unit) -> pp_sep:(Format.formatter -> unit -> unit) -> Format.formatter -> 'a list -> unit

pp_nested_list ~nested ~pp_element ~pp_sep ppf args prints the list args with pp_element on ppf. The elements are separated by pp_sep. If ~nested is true, the list is wrapped in parens. The element printer is always called with nested:true, indicating that any inner lists are nested and need parens.

Sourceval print_see_manual : int list Format_doc.printer

See manual section

Sourceval output_of_print : (Format.formatter -> 'a -> unit) -> out_channel -> 'a -> unit

output_of_print print produces an output function from a pretty printer. Note that naively using Format.formatter_of_out_channel typechecks but doesn't work because it fails to flush the formatter.

Sourceval output_of_doc_print : (Format_doc.formatter -> 'a -> unit) -> out_channel -> 'a -> unit

Like output_of_print but for Format_doc printers.

Sourceval is_print_longer_than : int -> (Format.formatter -> unit) -> bool

Returns true if the printed string is longer than the given integer. Stops early if so. Spaces and newlines are counted, but indentation is not.

Sourceval to_string_of_print : (Format.formatter -> 'a -> unit) -> 'a -> string

to_string_of_print print produces a string conversion function from a pretty printer. This is similar but preferable to Format.asprintf "%a" when the output may be large, since to_string functions don't usually return embedded newlines.

Displaying configuration variables

Sourceval show_config_and_exit : unit -> unit

Display the values of all compiler configuration variables from module Config, then exit the program with code 0.

Sourceval show_config_variable_and_exit : string -> unit

Display the value of the given configuration variable, then exit the program with code 0.

Handling of build maps

Build maps cause the compiler to normalize file names embedded in object files, thus leading to more reproducible builds.

Sourceval get_build_path_prefix_map : unit -> Build_path_prefix_map.map option

Returns the map encoded in the BUILD_PATH_PREFIX_MAP environment variable.

Sourceval debug_prefix_map_flags : unit -> string list

Returns the list of debug-prefix-map flags to be passed to the assembler, built from the BUILD_PATH_PREFIX_MAP environment variable.

Sourcemodule Bitmap : sig ... end

Handling of magic numbers

Sourcemodule Le_result : sig ... end

The result of a less-than-or-equal comparison

Sourcetype (_, _) eq =
  1. | Refl : ('a, 'a) eq

Propositional equality

Sourcetype (_, _) is_eq =
  1. | Is_eq : ('a, 'a) is_eq
  2. | Is_not_eq : ('a, 'b) is_eq

Propositional equality test

Sourcemodule type T = sig ... end

Utilities for module-level programming

Sourcemodule type T1 = sig ... end
Sourcemodule type T2 = sig ... end
Sourcemodule type T3 = sig ... end
Sourcemodule type T4 = sig ... end

Miscellaneous type aliases

Sourcetype filepath = string
Sourcetype alerts = string Stdlib.String.Map.t
Sourceval remove_double_underscores : string -> string
Sourcemodule Json : sig ... end
Sourcemodule Nonempty_list : sig ... end

Non-empty lists

Sourcemodule Maybe_bounded : sig ... end

A bounded non-negative integer. The possible ranges are 0 ..< n, represented by Bounded { bound = n} and 0 ..< ∞ represented by Unbounded.

Merlin

These functions are specific to merlin.

Sourceval exact_file_exists : dirname:string -> basename:string -> bool
Sourceval canonicalize_filename : ?cwd:string -> string -> string
Sourceval expand_glob : ?filter:(string -> bool) -> string -> string list -> string list
Sourceval split_path : string -> string list