How to deal with C flags "bitwise ored" when using Cstubs enum?

I have a C function that return enums values. Previously I did the following bindings:

type flags =
  | Is_method
  | Is_constructor
  | Is_getter
  | Is_setter
  | Wraps_vfunc
  | Throws

let get_flags info =
  let get_flags_raw =
    foreign "g_function_info_get_flags"
      (ptr functioninfo @-> returning uint32_t)
    in
    let v = get_flags_raw info in
    let open Unsigned.UInt32 in
    let all_flags = [( 1, Is_method ); ( 2, Is_constructor ); ( 4 , Is_getter ); ( 8 , Is_setter ); ( 16 , Wraps_vfunc ); (32, Throws)]
    in
    let rec build_flags_list allf acc =
      match allf with
      | [] -> acc
      | (i, f) :: q -> if ((logand v (of_int i )) <> zero) then build_flags_list q (f :: acc)
         else build_flags_list q acc
    in build_flags_list all_flags []

Now I try to use the Cstubs bindings to generate the bindings for C enums, and I can create the enums bindings called Bindings.flags for example but I don’t know what type an OCaml function should return when the C function return a bitwise ored value.

Any ideas?

If you found an elegant solution, I am also interested.
I also use cstubs, and want to be able to pass flags OR’ed to my function or put them in a data structure.
On the ocaml side, would look like:

type severity = Verbose | Info | Warning | Error
let logger = setup_logger ~ignore:[ Verbose; Info ]

If we check how OCaml itself does it, it uses this function caml_convert_flag_list: ocaml/open_unix.c at 146766c352f02967cb98de6f57477618ff5f7c6f · ocaml/ocaml · GitHub

Which is declared here: ocaml/alloc.h at 2beaad2e3503eae9e67b5d4b6ed8680bca0c38ca · ocaml/ocaml · GitHub

This function seems to convert a list of flags into a single int XORed value.

1 Like