Skip to content

Commit

Permalink
Merge pull request #510 from yallop/enum-typedef
Browse files Browse the repository at this point in the history
Add support for tagless enums.
  • Loading branch information
yallop authored Apr 28, 2017
2 parents 368e162 + 05204e3 commit 8b887fc
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
15 changes: 13 additions & 2 deletions src/cstubs/cstubs.mli
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ sig
warning: overflow in implicit constant conversion *)

val enum : string -> ?unexpected:(int64 -> 'a) -> ('a * int64 const) list -> 'a typ
val enum : string -> ?typedef:bool ->
?unexpected:(int64 -> 'a) -> ('a * int64 const) list -> 'a typ
(** [enum name ?unexpected alist] builds a type representation for the
enum named [name]. The size and alignment are retrieved so that the
resulting type can be used everywhere an integer type can be used: as
Expand Down Expand Up @@ -64,7 +65,17 @@ sig
The [unexpected] function specifies the value to return in the case
that some unexpected value is encountered -- for example, if a
function with the return type 'enum letters' actually returns the
value [-1]. *)
value [-1].
The optional flag [typedef] specifies whether the first argument,
[name], indicates an tag or an alias. If [typedef] is [false] (the
default) then [name] is treated as an enumeration tag:
enum letters { ... }
If [typedef] is [true] then [name] is instead treated as an alias:
typedef enum { ... } letters *)
end

module type BINDINGS = functor (F : TYPE) -> sig end
Expand Down
16 changes: 9 additions & 7 deletions src/cstubs/cstubs_structs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ sig
type 'a const
val constant : string -> 'a typ -> 'a const

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

module type BINDINGS = functor (F : TYPE) -> sig end
Expand Down Expand Up @@ -217,20 +217,21 @@ let write_consts fmt consts =


let write_enums fmt enums =
let case name =
let case (name, typedef) =
printf1 fmt
(Format.sprintf
" | %S -> \n Cstubs_internals.build_enum_type %S Ctypes_static.%%s ?unexpected alist\n"
name
name)
(fun fmt ->
Format.fprintf fmt
"ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum %s))"
"ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(%s%s))"
(if typedef then "" else "enum ")
name)
in
cases fmt enums
["";
"let enum (type a) name ?unexpected (alist : (a * int64) list) =";
"let enum (type a) name ?typedef ?unexpected (alist : (a * int64) list) =";
" match name with"]
~case
[" | s ->";
Expand Down Expand Up @@ -284,9 +285,10 @@ let gen_c () =

type _ const = unit
let constant name ty = consts := (name, Ctypes_static.BoxedType ty) :: !consts
let enum name ?unexpected alist =
let () = enums := name :: !enums in
let format_typ k fmt = Format.fprintf fmt "enum %s%t" name k in
let enum name ?(typedef=false) ?unexpected alist =
let () = enums := (name, typedef) :: !enums in
let format_typ k fmt = Format.fprintf fmt "%s%s%t"
(if typedef then "" else "enum ") name k in
(* a dummy value of type 'a typ, mostly unusable *)
view void
~format_typ
Expand Down
2 changes: 1 addition & 1 deletion src/cstubs/cstubs_structs.mli
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ sig
type 'a const
val constant : string -> 'a typ -> 'a const

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

module type BINDINGS = functor (F : TYPE) -> sig end
Expand Down

0 comments on commit 8b887fc

Please sign in to comment.