Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for unknown integer types. #652

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile.tests
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ test-enums-struct-stubs: $$(LIB_TARGETS)
test-enums-stubs.dir = tests/test-enums/stubs
test-enums-stubs.threads = yes
test-enums-stubs.extra_mls = generated_struct_bindings.ml
test-enums-stubs.deps = integers
test-enums-stubs.subproject_deps = ctypes \
test-enums-struct-stubs \
test-enums-struct-stubs-generator \
Expand Down
60 changes: 57 additions & 3 deletions src/cstubs/cstubs_structs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ sig
type 'a const
val constant : string -> 'a typ -> 'a const

module type signed = sig include Signed.S val t : t typ end
val signed : string -> (module signed)

module type unsigned = sig include Unsigned.S val t : t typ end
val unsigned : string -> (module unsigned)

val enum : string -> ?typedef:bool -> ?unexpected:(int64 -> 'a) -> ('a * int64 const) list -> 'a typ
end

Expand Down Expand Up @@ -233,22 +239,59 @@ let write_enums fmt enums =
[" | s ->";
" failwith (\"unmatched enum: \"^ s)"]

let write_signeds fmt signeds =
let case name =
printf1 fmt
(Format.sprintf
" | %S -> \n Cstubs_internals.build_signed_type %S Ctypes_static.%%s\n" name name)
(fun fmt ->
Format.fprintf fmt
"ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(%s))" name)
in
cases fmt signeds
["";
"module type signed = sig include Signed.S val t : t typ end";
"let signed (type a) name = match name with"]
~case
[" | s -> failwith (\"unmatched signed type: \"^ s)"]

let write_unsigneds fmt unsigneds =
let case name =
printf1 fmt
(Format.sprintf
" | %S -> \n Cstubs_internals.build_unsigned_type %S Ctypes_static.%%s\n" name name)
(fun fmt ->
Format.fprintf fmt
"ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(%s))" name)
in
cases fmt unsigneds
["";
"module type unsigned = sig include Unsigned.S val t : t typ end";
"let unsigned (type a) name = match name with"]
~case
[" | s -> failwith (\"unmatched unsigned type: \"^ s)"]


let write_ml fmt fields structures consts enums =
let write_ml fmt fields structures consts enums signeds unsigneds =
List.iter (puts fmt) mlprologue;
write_field fmt fields;
write_seal fmt structures;
write_consts fmt consts;
write_enums fmt enums
write_enums fmt enums;
write_signeds fmt signeds;
write_unsigneds fmt unsigneds


let gen_c () =
let fields = ref []
and structures = ref []
and consts = ref []
and enums = ref []
and signeds = ref []
and unsigneds = ref []
in
let finally fmt = write_c fmt (fun fmt ->
write_ml fmt !fields !structures !consts !enums) in
write_ml fmt !fields !structures !consts !enums !signeds !unsigneds) in
let m =
(module struct
include Ctypes
Expand Down Expand Up @@ -281,6 +324,17 @@ let gen_c () =

type _ const = unit
let constant name ty = consts := (name, Ctypes_static.BoxedType ty) :: !consts

module type signed = sig include Signed.S val t : t typ end
let signed name : (module signed) =
let () = signeds := name :: !signeds in
(module struct include Signed.Int32 let t = int32_t end) (* arbitrary *)

module type unsigned = sig include Unsigned.S val t : t typ end
let unsigned name : (module unsigned) =
let () = unsigneds := name :: !unsigneds in
(module struct include Unsigned.UInt32 let t = uint32_t end) (* arbitrary *)

let enum name ?(typedef=false) ?unexpected alist =
let () = enums := (name, typedef) :: !enums in
let format_typ k fmt = Format.fprintf fmt "%s%s%t"
Expand Down
6 changes: 6 additions & 0 deletions src/cstubs/cstubs_structs.mli
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ sig
type 'a const
val constant : string -> 'a typ -> 'a const

module type signed = sig include Signed.S val t : t typ end
val signed : string -> (module signed)

module type unsigned = sig include Unsigned.S val t : t typ end
val unsigned : string -> (module unsigned)

val enum : string -> ?typedef:bool -> ?unexpected:(int64 -> 'a) -> ('a * int64 const) list -> 'a typ
end

Expand Down
31 changes: 31 additions & 0 deletions src/ctypes/cstubs_internals.ml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,37 @@ let int64_of_uint32 x = Int64.of_string (Unsigned.UInt32.to_string x)
let uint64_of_int64 = Unsigned.UInt64.of_int64
let int64_of_uint64 = Unsigned.UInt64.to_int64

module type signed = sig include Signed.S val t : t typ end
let build_signed_type name underlying : (module signed) =
let wrong kind =
Printf.ksprintf failwith "Signed type detected as %s type: %s" kind name
in
match underlying with
Ctypes_static.Uint8 -> wrong "unsigned"
| Ctypes_static.Uint16 -> wrong "unsigned"
| Ctypes_static.Uint32 -> wrong "unsigned"
| Ctypes_static.Uint64 -> wrong "unsigned"
| Ctypes_static.Int8 -> (module struct include Signed.Int let t = Ctypes.int8_t end)
| Ctypes_static.Int16 -> (module struct include Signed.Int let t = Ctypes.int16_t end)
| Ctypes_static.Int32 -> (module struct include Signed.Int32 let t = Ctypes.int32_t end)
| Ctypes_static.Int64 -> (module struct include Signed.Int64 let t = Ctypes.int64_t end)
| Ctypes_static.Float | Ctypes_static.Double -> wrong "floating"


module type unsigned = sig include Unsigned.S val t : t typ end
let build_unsigned_type name underlying : (module unsigned) =
match underlying with
Ctypes_static.Int8 -> (module struct include Signed.Int let t = Ctypes.int8_t end)
| Ctypes_static.Int16 -> (module struct include Signed.Int let t = Ctypes.int16_t end)
| Ctypes_static.Int32 -> (module struct include Signed.Int32 let t = Ctypes.int32_t end)
| Ctypes_static.Int64 -> (module struct include Signed.Int64 let t = Ctypes.int64_t end)
| Ctypes_static.Uint8 -> (module struct include Unsigned.UInt8 let t = Ctypes.uint8_t end)
| Ctypes_static.Uint16 -> (module struct include Unsigned.UInt16 let t = Ctypes.uint16_t end)
| Ctypes_static.Uint32 -> (module struct include Unsigned.UInt32 let t = Ctypes.uint32_t end)
| Ctypes_static.Uint64 -> (module struct include Unsigned.UInt64 let t = Ctypes.uint64_t end)
| Ctypes_static.Float | Ctypes_static.Double ->
Printf.ksprintf failwith "Unsigned type detected as floating type: %s" name

let build_enum_type name underlying ?(typedef=false) ?unexpected alist =
let build_view t coerce uncoerce =
let unexpected = match unexpected with
Expand Down
8 changes: 8 additions & 0 deletions src/ctypes/cstubs_internals.mli
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ type 'a prim = 'a Ctypes_primitive_types.prim =
| Complex64 : Complex.t prim
| Complexld : ComplexL.t prim

module type signed = sig include Signed.S val t : t typ end
val build_signed_type :
string -> Ctypes_static.arithmetic -> (module signed)

module type unsigned = sig include Unsigned.S val t : t typ end
val build_unsigned_type :
string -> Ctypes_static.arithmetic -> (module unsigned)

val build_enum_type :
string -> Ctypes_static.arithmetic -> ?typedef:bool ->
?unexpected:(int64 -> 'a) -> ('a * int64) list -> 'a typ
Expand Down
8 changes: 8 additions & 0 deletions src/ctypes/ctypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ sig

type 'a const
val constant : string -> 'a typ -> 'a const

module type signed = sig include Signed.S val t : t typ end
val signed : string -> (module signed)

module type unsigned = sig include Unsigned.S val t : t typ end
val unsigned : string -> (module unsigned)

val enum : string -> ?typedef:bool ->
?unexpected:(int64 -> 'a) -> ('a * int64 const) list -> 'a typ
end

6 changes: 6 additions & 0 deletions src/ctypes/ctypes.mli
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,12 @@ sig

warning: overflow in implicit constant conversion *)

module type signed = sig include Signed.S val t : t typ end
val signed : string -> (module signed)

module type unsigned = sig include Unsigned.S val t : t typ end
val unsigned : string -> (module unsigned)

val enum : string -> ?typedef:bool ->
?unexpected:(int64 -> 'a) -> ('a * int64 const) list -> 'a typ
(** [enum name ?unexpected alist] builds a type representation for the
Expand Down