(*
 * Copyright (c) 2014 Jeremy Yallop.
 *
 * This file is distributed under the terms of the MIT License.
 * See the file LICENSE for details.
 *)

(** Operations for exposing OCaml code as C libraries. *)

module type INTERNAL =
sig
  (* Expose type definitions to C.

     The types are printed to the header file generated by [write_c_header]. *)
  val enum : (string * int64) list -> 'a Ctypes.typ -> unit
  val structure : _ Ctypes.structure Ctypes.typ -> unit
  val union : _ Ctypes.union Ctypes.typ -> unit
  val typedef : _ Ctypes.typ -> string -> unit

  val internal : ?runtime_lock:bool -> string -> ('a -> 'b) Ctypes.fn -> ('a -> 'b) -> unit
end

module type BINDINGS = functor (F : INTERNAL) -> sig end

val write_c : Format.formatter -> prefix:string -> (module BINDINGS) -> unit
(** [write_c fmt ~prefix bindings] generates C stubs for the functions bound
    with [internal] in [bindings].  The stubs are intended to be used in
    conjunction with the ML code generated by {!write_ml}.

    The generated code uses definitions exposed in the header file
    [cstubs_internals.h].
*)

val write_c_header : Format.formatter -> prefix:string -> (module BINDINGS) -> unit
(** [write_c_header fmt ~prefix bindings] generates a C header file
    for the functions bound with [internal] in [bindings].  The stubs
    are intended to be used in conjunction with the C code generated
    by {!write_c}.
*)

val write_ml : Format.formatter -> prefix:string -> (module BINDINGS) -> unit
(** [write_ml fmt ~prefix bindings] generates ML bindings for the functions
    bound with [internal] in [bindings].  The generated code conforms to the
    {!INTERNAL} interface.

    The generated code uses definitions exposed in the module
    [Cstubs_internals]. *)
