yallop / ocaml-ctypes

Library for binding to C libraries using pure OCaml
MIT License
369 stars 95 forks source link

Support for typedef enums? #702

Closed joelburget closed 2 years ago

joelburget commented 2 years ago

I'm working on bindings for the tree-sitter library (https://github.com/tree-sitter/tree-sitter/blob/master/lib/include/tree_sitter/api.h). They use typedefs for "anonymous" types both for structs and enums. I was able to use the typedef function to create stubs for the structs, however I'm stuck with the enums. Here's one for example:

typedef enum {
  TSInputEncodingUTF8,
  TSInputEncodingUTF16,
} TSInputEncoding;

I would like to be able to write this:

  module TSInputEncoding = struct
    type t =
      | TSInputEncodingUTF8
      | TSInputEncodingUTF16

    let t =
      enum
        "TSInputEncoding"
        [ TSInputEncodingUTF8, constant "TSInputEncodingUTF8" int64_t
        ; TSInputEncodingUTF16, constant "TSInputEncodingUTF16" int64_t
        ]
    ;;
  end
Output ``` ********** NEW BUILD ********** bash stubgen/bindings_stubs_gen.exe (exit 1) (cd _build/default/stubgen && /usr/local/bin/bash -e -u -o pipefail -c 'cc -O2 -fno-strict-aliasing -fwrapv -pthread bindings_stubs_gen.c -I `dirname /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_cstubs_internals.h` -I /Users/joel/.opam/4.13.1/lib/ocaml -o bindings_stubs_gen.exe') bindings_stubs_gen.c:147:44: error: cast to incomplete type 'enum TSInputEncoding' ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum TSInputEncoding))); ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:151:35: note: expanded from macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE' ctypes_classify_arithmetic_type(CTYPES_ARITHMETIC_TYPEINFO(TYPENAME)) ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:148:47: note: expanded from macro 'CTYPES_ARITHMETIC_TYPEINFO' #define CTYPES_ARITHMETIC_TYPEINFO(TYPENAME) (CTYPES_CLASSIFY(TYPENAME) \ ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:146:36: note: expanded from macro 'CTYPES_CLASSIFY' #define CTYPES_CLASSIFY(TYPENAME) (CTYPES_CHECK_FLOATING(TYPENAME) \ ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:143:16: note: expanded from macro 'CTYPES_CHECK_FLOATING' ((unsigned)(((TYPENAME) 0.5) != 0) << CTYPES_FLOATING_FLAG_BIT) ^ bindings_stubs_gen.c:147:81: note: forward declaration of 'enum TSInputEncoding' ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum TSInputEncoding))); ^ bindings_stubs_gen.c:147:44: error: cast to incomplete type 'enum TSInputEncoding' ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum TSInputEncoding))); ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:151:35: note: expanded from macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE' ctypes_classify_arithmetic_type(CTYPES_ARITHMETIC_TYPEINFO(TYPENAME)) ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:148:47: note: expanded from macro 'CTYPES_ARITHMETIC_TYPEINFO' #define CTYPES_ARITHMETIC_TYPEINFO(TYPENAME) (CTYPES_CLASSIFY(TYPENAME) \ ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:147:36: note: expanded from macro 'CTYPES_CLASSIFY' | CTYPES_CHECK_UNSIGNED(TYPENAME)) ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:145:16: note: expanded from macro 'CTYPES_CHECK_UNSIGNED' ((unsigned)(((TYPENAME) -1) > 0) << CTYPES_UNSIGNED_FLAG_BIT) ^ bindings_stubs_gen.c:147:81: note: forward declaration of 'enum TSInputEncoding' ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum TSInputEncoding))); ^ bindings_stubs_gen.c:147:44: error: invalid application of 'sizeof' to an incomplete type 'enum TSInputEncoding' ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum TSInputEncoding))); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:151:35: note: expanded from macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE' ctypes_classify_arithmetic_type(CTYPES_ARITHMETIC_TYPEINFO(TYPENAME)) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:149:47: note: expanded from macro 'CTYPES_ARITHMETIC_TYPEINFO' | sizeof(TYPENAME)) ^ ~~~~~~~~~~ bindings_stubs_gen.c:147:81: note: forward declaration of 'enum TSInputEncoding' ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum TSInputEncoding))); ^ 3 errors generated. ```

I also tried:

    let t =
      enum
        {|{
          TSInputEncodingUTF8,
          TSInputEncodingUTF16,
        }|}
        [ TSInputEncodingUTF8, constant "TSInputEncodingUTF8" int64_t
        ; TSInputEncodingUTF16, constant "TSInputEncodingUTF16" int64_t
        ]
Output ``` ********** NEW BUILD ********** bash stubgen/bindings_stubs_gen.exe (exit 1) (cd _build/default/stubgen && /usr/local/bin/bash -e -u -o pipefail -c 'cc -O2 -fno-strict-aliasing -fwrapv -pthread bindings_stubs_gen.c -I `dirname /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_cstubs_internals.h` -I /Users/joel/.opam/4.13.1/lib/ocaml -o bindings_stubs_gen.exe') bindings_stubs_gen.c:149:11: error: too many arguments provided to function-like macro invocation TSInputEncodingUTF16, ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:150:9: note: macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE' defined here #define CTYPES_CLASSIFY_ARITHMETIC_TYPE(TYPENAME) \ ^ bindings_stubs_gen.c:147:44: note: parentheses are required around macro argument containing braced initializer list ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum { ^ ( bindings_stubs_gen.c:147:44: error: expected expression ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum { ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:151:35: note: expanded from macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE' ctypes_classify_arithmetic_type(CTYPES_ARITHMETIC_TYPEINFO(TYPENAME)) ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:148:47: note: expanded from macro 'CTYPES_ARITHMETIC_TYPEINFO' #define CTYPES_ARITHMETIC_TYPEINFO(TYPENAME) (CTYPES_CLASSIFY(TYPENAME) \ ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:146:36: note: expanded from macro 'CTYPES_CLASSIFY' #define CTYPES_CLASSIFY(TYPENAME) (CTYPES_CHECK_FLOATING(TYPENAME) \ ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:143:25: note: expanded from macro 'CTYPES_CHECK_FLOATING' ((unsigned)(((TYPENAME) 0.5) != 0) << CTYPES_FLOATING_FLAG_BIT) ^ bindings_stubs_gen.c:148:11: error: redefinition of enumerator 'TSInputEncodingUTF8' TSInputEncodingUTF8, ^ bindings_stubs_gen.c:148:11: note: previous definition is here bindings_stubs_gen.c:149:11: error: redefinition of enumerator 'TSInputEncodingUTF16' TSInputEncodingUTF16, ^ bindings_stubs_gen.c:149:11: note: previous definition is here bindings_stubs_gen.c:147:44: error: expected expression ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum { ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:151:35: note: expanded from macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE' ctypes_classify_arithmetic_type(CTYPES_ARITHMETIC_TYPEINFO(TYPENAME)) ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:148:47: note: expanded from macro 'CTYPES_ARITHMETIC_TYPEINFO' #define CTYPES_ARITHMETIC_TYPEINFO(TYPENAME) (CTYPES_CLASSIFY(TYPENAME) \ ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:147:36: note: expanded from macro 'CTYPES_CLASSIFY' | CTYPES_CHECK_UNSIGNED(TYPENAME)) ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:145:25: note: expanded from macro 'CTYPES_CHECK_UNSIGNED' ((unsigned)(((TYPENAME) -1) > 0) << CTYPES_UNSIGNED_FLAG_BIT) ^ bindings_stubs_gen.c:148:11: error: redefinition of enumerator 'TSInputEncodingUTF8' TSInputEncodingUTF8, ^ bindings_stubs_gen.c:148:11: note: previous definition is here bindings_stubs_gen.c:149:11: error: redefinition of enumerator 'TSInputEncodingUTF16' TSInputEncodingUTF16, ^ bindings_stubs_gen.c:149:11: note: previous definition is here bindings_stubs_gen.c:147:44: error: expected expression ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum { ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:151:35: note: expanded from macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE' ctypes_classify_arithmetic_type(CTYPES_ARITHMETIC_TYPEINFO(TYPENAME)) ^ /Users/joel/.opam/4.13.1/lib/ctypes/ctypes_primitives.h:149:62: note: expanded from macro 'CTYPES_ARITHMETIC_TYPEINFO' | sizeof(TYPENAME)) ^ 8 errors generated. ```

Is there some way that I'm missing to do this?

yallop commented 2 years ago

Does passing ~typedef:true to enum help?

joelburget commented 2 years ago

Thanks @yallop, that's exactly what I needed!