X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=genbindings.py;h=7ff9069b25d36b8ec0109e1a0dd7af1d36ccff6d;hb=7cbcc5ef17b8036b2e99980e227c7ca0d44dba7f;hp=34c3fe1904ec2610eb3cd43c4762b20d4e39604d;hpb=8fbb9c1f80dbb3d3f5bd3472f2fa8053a8437141;p=ldk-java diff --git a/genbindings.py b/genbindings.py index 34c3fe19..7ff9069b 100755 --- a/genbindings.py +++ b/genbindings.py @@ -124,7 +124,17 @@ def java_c_types(fn_arg, ret_arr_len): rust_obj = None arr_access = None java_hu_ty = None - if fn_arg.startswith("LDKThirtyTwoBytes"): + if fn_arg.startswith("LDKPaymentPreimage") or fn_arg.startswith("LDKPaymentSecret") or fn_arg.startswith("LDKPaymentHash"): + if fn_arg.startswith("LDKPaymentPreimage"): + fn_arg = "uint8_t (*" + fn_arg[19:] + ")[32]" + elif fn_arg.startswith("LDKPaymentSecret"): + fn_arg = "uint8_t (*" + fn_arg[17:] + ")[32]" + elif fn_arg.startswith("LDKPaymentHash"): + fn_arg = "uint8_t (*" + fn_arg[15:] + ")[32]" + assert var_is_arr_regex.match(fn_arg[8:]) + rust_obj = "LDKThirtyTwoBytes" + arr_access = "data" + elif fn_arg.startswith("LDKThirtyTwoBytes"): fn_arg = "uint8_t (*" + fn_arg[18:] + ")[32]" assert var_is_arr_regex.match(fn_arg[8:]) rust_obj = "LDKThirtyTwoBytes" @@ -214,13 +224,14 @@ def java_c_types(fn_arg, ret_arr_len): return None if is_ptr: res.pass_by_ref = True + java_ty = consts.java_arr_ty_str(res.java_ty) if res.is_native_primitive or res.passed_as_ptr: - return TypeInfo(rust_obj=fn_arg.split(" ")[0], java_ty=res.java_ty + "[]", java_hu_ty=res.java_hu_ty + "[]", + return TypeInfo(rust_obj=fn_arg.split(" ")[0], java_ty=java_ty, java_hu_ty=res.java_hu_ty + "[]", java_fn_ty_arg="[" + res.java_fn_ty_arg, c_ty=res.c_ty + "Array", passed_as_ptr=False, is_ptr=is_ptr, nonnull_ptr=nonnull_ptr, is_const=is_const, var_name=res.var_name, arr_len="datalen", arr_access="data", subty=res, is_native_primitive=False) else: - return TypeInfo(rust_obj=fn_arg.split(" ")[0], java_ty=res.java_ty + "[]", java_hu_ty=res.java_hu_ty + "[]", + return TypeInfo(rust_obj=fn_arg.split(" ")[0], java_ty=java_ty, java_hu_ty=res.java_hu_ty + "[]", java_fn_ty_arg="[" + res.java_fn_ty_arg, c_ty=consts.ptr_arr, passed_as_ptr=False, is_ptr=is_ptr, nonnull_ptr=nonnull_ptr, is_const=is_const, var_name=res.var_name, arr_len="datalen", arr_access="data", subty=res, is_native_primitive=False) @@ -230,6 +241,7 @@ def java_c_types(fn_arg, ret_arr_len): arr_len = None mapped_type = [] java_type_plural = None + arr_ty = None if fn_arg.startswith("void"): java_ty = "void" c_ty = "void" @@ -240,6 +252,7 @@ def java_c_types(fn_arg, ret_arr_len): java_ty = "boolean" c_ty = "jboolean" fn_ty_arg = "Z" + arr_ty = "bool" fn_arg = fn_arg[4:].strip() is_primitive = True elif fn_arg.startswith("uint8_t"): @@ -247,19 +260,27 @@ def java_c_types(fn_arg, ret_arr_len): java_ty = mapped_type[0] c_ty = "int8_t" fn_ty_arg = "B" + arr_ty = "uint8_t" fn_arg = fn_arg[7:].strip() is_primitive = True - elif fn_arg.startswith("LDKu5"): + elif fn_arg.startswith("LDKu5") or fn_arg.startswith("LDKWitnessVersion"): java_ty = consts.c_type_map['uint8_t'][0] - java_hu_ty = "UInt5" - rust_obj = "LDKu5" + if fn_arg.startswith("LDKu5"): + java_hu_ty = "UInt5" + rust_obj = "LDKu5" + fn_arg = fn_arg[6:].strip() + else: + java_hu_ty = "WitnessVersion" + rust_obj = "LDKWitnessVersion" + fn_arg = fn_arg[18:].strip() c_ty = "int8_t" + arr_ty = "uint8_t" fn_ty_arg = "B" - fn_arg = fn_arg[6:].strip() elif fn_arg.startswith("uint16_t"): mapped_type = consts.c_type_map['uint16_t'] java_ty = mapped_type[0] c_ty = "int16_t" + arr_ty = "uint16_t" fn_ty_arg = "S" fn_arg = fn_arg[8:].strip() is_primitive = True @@ -267,6 +288,7 @@ def java_c_types(fn_arg, ret_arr_len): mapped_type = consts.c_type_map['uint32_t'] java_ty = mapped_type[0] c_ty = "int32_t" + arr_ty = "uint32_t" fn_ty_arg = "I" fn_arg = fn_arg[8:].strip() is_primitive = True @@ -277,28 +299,43 @@ def java_c_types(fn_arg, ret_arr_len): fn_ty_arg = "J" if fn_arg.startswith("uint64_t"): c_ty = "int64_t" + arr_ty = "uint64_t" fn_arg = fn_arg[8:].strip() else: - java_ty = consts.ptr_native_ty - c_ty = "int64_t" + java_ty = consts.usize_native_ty + c_ty = consts.usize_c_ty + arr_ty = "uintptr_t" rust_obj = "uintptr_t" fn_arg = fn_arg[9:].strip() is_primitive = True elif is_const and fn_arg.startswith("char *"): - java_ty = "String" + java_ty = consts.java_type_map["String"] + java_hu_ty = consts.java_hu_type_map["String"] c_ty = "const char*" + arr_ty = "LDKStr" fn_ty_arg = "Ljava/lang/String;" fn_arg = fn_arg[6:].strip() elif fn_arg.startswith("LDKStr"): rust_obj = "LDKStr" - java_ty = "String" + arr_ty = "LDKStr" + java_ty = consts.java_type_map["String"] + java_hu_ty = consts.java_hu_type_map["String"] c_ty = "jstring" fn_ty_arg = "Ljava/lang/String;" fn_arg = fn_arg[6:].strip() arr_access = "chars" arr_len = "len" + elif fn_arg.startswith("LDKError ") or fn_arg == "LDKError": + java_ty = consts.c_type_map['uint32_t'][0] + java_hu_ty = "UnqualifiedError" + rust_obj = "LDKError" + c_ty = "int32_t" + arr_ty = "uint32_t" + fn_ty_arg = "I" + fn_arg = fn_arg[8:].strip() else: ma = var_ty_regex.match(fn_arg) + arr_ty = ma.group(1).strip() if ma.group(1).strip() in unitary_enums: assert ma.group(1).strip().startswith("LDK") java_ty = ma.group(1).strip()[3:] @@ -333,29 +370,40 @@ def java_c_types(fn_arg, ret_arr_len): fn_ty_arg = "J" var_is_arr = var_is_arr_regex.match(fn_arg) + subty = None if var_is_arr is not None or ret_arr_len is not None: assert(not take_by_ptr) assert(not is_ptr) # is there a special case for plurals? - if len(mapped_type) == 2: + if len(mapped_type) == 3: java_ty = mapped_type[1] + java_hu_ty = mapped_type[2] else: java_ty = java_ty + "[]" + java_hu_ty = java_ty c_ty = c_ty + "Array" + + subty = java_c_types(arr_ty, None) + if subty is None: + assert java_c_types_none_allowed + return None + if is_ptr: + subty.pass_by_ref = True + if var_is_arr is not None: if var_is_arr.group(1) == "": - return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_hu_ty=java_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, is_const=is_const, - passed_as_ptr=False, is_ptr=False, nonnull_ptr=nonnull_ptr, var_name="arg", + return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_hu_ty=java_hu_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, is_const=is_const, + passed_as_ptr=False, is_ptr=False, nonnull_ptr=nonnull_ptr, var_name="arg", subty=subty, arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False, contains_trait=contains_trait) - return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_hu_ty=java_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, is_const=is_const, - passed_as_ptr=False, is_ptr=False, nonnull_ptr=nonnull_ptr, var_name=var_is_arr.group(1), + return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_hu_ty=java_hu_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, is_const=is_const, + passed_as_ptr=False, is_ptr=False, nonnull_ptr=nonnull_ptr, var_name=var_is_arr.group(1), subty=subty, arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False, contains_trait=contains_trait) if java_hu_ty is None: java_hu_ty = java_ty return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_hu_ty=java_hu_ty, java_fn_ty_arg=fn_ty_arg, c_ty=c_ty, passed_as_ptr=is_ptr or take_by_ptr, is_const=is_const, is_ptr=is_ptr, nonnull_ptr=nonnull_ptr, var_name=fn_arg, arr_len=arr_len, arr_access=arr_access, is_native_primitive=is_primitive, - contains_trait=contains_trait) + contains_trait=contains_trait, subty=subty) fn_ptr_regex = re.compile("^extern const ([A-Za-z_0-9\* ]*) \(\*(.*)\)\((.*)\);$") fn_ret_arr_regex = re.compile("(.*) \(\*(.*)\((.*)\)\)\[([0-9]*)\];$") @@ -386,7 +434,66 @@ with open(sys.argv[1]) as in_h: # Define some manual clones... clone_fns.add("ThirtyTwoBytes_clone") -write_c("static inline struct LDKThirtyTwoBytes ThirtyTwoBytes_clone(const struct LDKThirtyTwoBytes *orig) { struct LDKThirtyTwoBytes ret; memcpy(ret.data, orig->data, 32); return ret; }\n") +write_c("static inline struct LDKThirtyTwoBytes ThirtyTwoBytes_clone(const struct LDKThirtyTwoBytes *orig) { struct LDKThirtyTwoBytes ret; memcpy(ret.data, orig->data, 32); return ret; }\n\n") + + +write_c("static inline void* untag_ptr(uint64_t ptr) {\n") +write_c("\tif (ptr < 4096) return (void*)ptr;\n") +write_c("\tif (sizeof(void*) == 4) {\n") +write_c("\t\t// For 32-bit systems, store pointers as 64-bit ints and use the 31st bit\n") +write_c("\t\treturn (void*)(uintptr_t)ptr;\n") +write_c("\t} else {\n") +write_c("\t\t// For 64-bit systems, assume the top byte is used for tagging, then\n") +write_c("\t\t// use bit 9 ^ bit 10.\n") +write_c("\t\tuint64_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n") +write_c("\t\tuintptr_t p = (ptr & ~(1ULL << 55)) | (tenth_bit << 55);\n") +write_c("#ifdef LDK_DEBUG_BUILD\n") +write_c("\t\t// On debug builds we also use the 11th bit as a debug flag\n") +write_c("\t\tuintptr_t eleventh_bit = (((uintptr_t)ptr) & (1ULL << 53)) >> 53;\n") +write_c("\t\tCHECK(tenth_bit != eleventh_bit);\n") +write_c("\t\tp ^= 1ULL << 53;\n") +write_c("#endif\n") +write_c("\t\treturn (void*)p;\n") +write_c("\t}\n") +write_c("}\n") + +write_c("static inline bool ptr_is_owned(uint64_t ptr) {\n") +write_c("\tif(ptr < 4096) return true;\n") +write_c("\tif (sizeof(void*) == 4) {\n") +write_c("\t\treturn ptr & (1ULL << 32);\n") +write_c("\t} else {\n") +write_c("\t\tuintptr_t ninth_bit = (((uintptr_t)ptr) & (1ULL << 55)) >> 55;\n") +write_c("\t\tuintptr_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n") +write_c("#ifdef LDK_DEBUG_BUILD\n") +write_c("\t\t// On debug builds we also use the 11th bit as a debug flag\n") +write_c("\t\tuintptr_t eleventh_bit = (((uintptr_t)ptr) & (1ULL << 53)) >> 53;\n") +write_c("\t\tCHECK(tenth_bit != eleventh_bit);\n") +write_c("#endif\n") +write_c("\t\treturn (ninth_bit ^ tenth_bit) ? true : false;\n") +write_c("\t}\n") +write_c("}\n") + +write_c("static inline uint64_t tag_ptr(const void* ptr, bool is_owned) {\n") +write_c("\tif ((uintptr_t)ptr < 4096) return (uint64_t)ptr;\n") +write_c("\tif (sizeof(void*) == 4) {\n") +write_c("\t\treturn (((uint64_t)ptr) | ((is_owned ? 1ULL : 0) << 32));\n") +write_c("\t} else {\n") +write_c("\t\tCHECK(sizeof(uintptr_t) == 8);\n") +write_c("\t\tuintptr_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n") +write_c("\t\tuintptr_t t = (((uintptr_t)ptr) | (((is_owned ? 1ULL : 0ULL) ^ tenth_bit) << 55));\n") +write_c("#ifdef LDK_DEBUG_BUILD\n") +write_c("\t\tuintptr_t ninth_bit = (((uintptr_t)ptr) & (1ULL << 55)) >> 55;\n") +write_c("\t\tuintptr_t eleventh_bit = (((uintptr_t)ptr) & (1ULL << 53)) >> 53;\n") +write_c("\t\tCHECK(ninth_bit == tenth_bit);\n") +write_c("\t\tCHECK(ninth_bit == eleventh_bit);\n") +write_c("\t\tt ^= 1ULL << 53;\n") +write_c("#endif\n") +write_c("\t\tCHECK(ptr_is_owned(t) == is_owned);\n") +write_c("\t\tCHECK(untag_ptr(t) == ptr);\n") +#write_c("\t\tCHECK(untag_ptr((uintptr_t)untag_ptr(t)) == ptr);\n") +write_c("\t\treturn t;\n") +write_c("\t}\n") +write_c("}\n\n") java_c_types_none_allowed = False # C structs created by cbindgen are declared in dependency order @@ -432,13 +539,13 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", return_type_info = type_mapping_generator.map_type(method_return_type.strip() + " ret", True, ret_arr_len, False, force_holds_ref) if method_name.endswith("_clone") and expected_struct not in unitary_enums: - meth_line = "uintptr_t " + expected_struct.replace("LDK", "") + "_clone_ptr(" + expected_struct + " *NONNULL_PTR arg)" + meth_line = "uint64_t " + expected_struct.replace("LDK", "") + "_clone_ptr(" + expected_struct + " *NONNULL_PTR arg)" write_c("static inline " + meth_line + " {\n") write_c("\t" + return_type_info.ret_conv[0].replace("\n", "\n\t")) write_c(method_name + "(arg)") - write_c(return_type_info.ret_conv[1]) + write_c(return_type_info.ret_conv[1].replace("\n", "\n\t")) write_c("\n\treturn " + return_type_info.ret_conv_name + ";\n}\n") - map_fn(meth_line + ";\n", re.compile("(uintptr_t) ([A-Za-z_0-9]*)\((.*)\)").match(meth_line), None, None, None) + map_fn(meth_line + ";\n", re.compile("(uint64_t) ([A-Za-z_0-9]*)\((.*)\)").match(meth_line), None, None, None) argument_types = [] default_constructor_args = {} @@ -456,7 +563,7 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", takes_self_ptr = True elif arg_ty.var_name in params_nullable: argument_conversion_info = type_mapping_generator.map_type_with_info(arg_ty, False, None, is_free, True, True) - if argument_conversion_info.arg_conv is not None and "Warning" in argument_conversion_info.arg_conv: + if argument_conversion_info.arg_conv is not None and "WARNING" in argument_conversion_info.arg_conv: arg_ty_info = java_c_types(argument, None) print("WARNING: Remapping argument " + arg_ty_info.var_name + " of function " + method_name + " to a reference") print(" The argument appears to require a move, or not clonable, and is nullable.") @@ -471,11 +578,11 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", arg_ty_info.requires_clone = False argument_conversion_info = type_mapping_generator.map_type_with_info(arg_ty_info, False, None, is_free, True, True) assert argument_conversion_info.nullable - assert argument_conversion_info.arg_conv is not None and "Warning" not in argument_conversion_info.arg_conv + assert argument_conversion_info.arg_conv is not None and "WARNING" not in argument_conversion_info.arg_conv else: argument_conversion_info = type_mapping_generator.map_type_with_info(arg_ty, False, None, is_free, True, False) - if argument_conversion_info.arg_conv is not None and "Warning" in argument_conversion_info.arg_conv: + if argument_conversion_info.arg_conv is not None and "WARNING" in argument_conversion_info.arg_conv: if argument_conversion_info.rust_obj in constructor_fns: assert not is_free for explode_arg in constructor_fns[argument_conversion_info.rust_obj].split(','): @@ -489,12 +596,34 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", default_constructor_args[argument_conversion_info.arg_name] = [] default_constructor_args[argument_conversion_info.arg_name].append(explode_arg_conv) argument_types.append(argument_conversion_info) + if not takes_self and return_type_info.java_hu_ty != struct_meth: if not return_type_info.java_hu_ty.startswith("Result_" + struct_meth): struct_meth_name = method_name struct_meth = "" expected_struct = "" + impl_on_struct = (expected_struct in opaque_structs or expected_struct in trait_structs or + expected_struct in complex_enums or expected_struct in complex_enums or + expected_struct in result_types or expected_struct in tuple_types) and not is_free + impl_on_utils = not impl_on_struct and (not is_free and not method_name.endswith("_clone") and + not method_name.startswith("TxOut") and + not method_name.startswith("_") and + method_name != "check_platform" and method_name != "Result_read" and + not expected_struct in unitary_enums and + ((not method_name.startswith("C2Tuple_") and not method_name.startswith("C3Tuple_")) + or method_name.endswith("_read"))) + + # If we're adding a static method, and it returns a primitive or an array of primitives, + # and a variable conversion adds a reference on the return type (via `this`), skip the + # variable's conversion reference-add (as we obviously cannot need a reference). + if impl_on_utils and (return_type_info.is_native_primitive or + (return_type_info.ty_info.subty is not None and return_type_info.ty_info.subty.is_native_primitive)): + for arg in argument_types: + if arg.from_hu_conv is not None and arg.from_hu_conv[1] != "": + if "this" in arg.from_hu_conv[1]: + arg.from_hu_conv = (arg.from_hu_conv[0], "") + out_java.write("\t// " + line) (out_java_delta, out_c_delta, out_java_struct_delta) = \ consts.map_function(argument_types, c_call_string, method_name, struct_meth_name, return_type_info, struct_meth, default_constructor_args, takes_self, takes_self_ptr, args_known, type_mapping_generator, doc_comment) @@ -505,7 +634,7 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", assert return_type_info.c_ty == "void" write_c(consts.c_fn_ty_pfx + "void " + consts.c_fn_name_define_pfx(method_name, True) + argument_types[0].c_ty + " " + argument_types[0].ty_info.var_name + ") {\n") if argument_types[0].ty_info.passed_as_ptr and not argument_types[0].ty_info.rust_obj in opaque_structs: - write_c("\tif ((" + argument_types[0].ty_info.var_name + " & 1) != 0) return;\n") + write_c("\tif (!ptr_is_owned(" + argument_types[0].ty_info.var_name + ")) return;\n") for info in argument_types: if info.arg_conv is not None: @@ -523,24 +652,13 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", write_c(out_c_delta) out_java_struct = None - if (expected_struct in opaque_structs or expected_struct in trait_structs - or expected_struct in complex_enums or expected_struct in complex_enums - or expected_struct in result_types or expected_struct in tuple_types) and not is_free: + if impl_on_struct: out_java_struct = open(f"{sys.argv[3]}/structs/{struct_meth}{consts.file_ext}", "a") out_java_struct.write(out_java_struct_delta) - elif (not is_free and not method_name.endswith("_clone") and - not method_name.startswith("TxOut") and - not method_name.startswith("_") and - method_name != "check_platform" and method_name != "Result_read" and - not expected_struct in unitary_enums and - ((not method_name.startswith("C2Tuple_") and not method_name.startswith("C3Tuple_")) - or method_name.endswith("_read"))): + elif impl_on_utils: out_java_struct = open(f"{sys.argv[3]}/structs/UtilMethods{consts.file_ext}", "a") for line in out_java_struct_delta.splitlines(): - if "this" not in line: - out_java_struct.write(line + "\n") - else: - out_java_struct.write("\t\t// " + line.strip() + "\n") + out_java_struct.write(line + "\n") def map_unitary_enum(struct_name, field_lines, enum_doc_comment): assert struct_name.startswith("LDK") @@ -594,7 +712,13 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", elif camel_to_snake(variant_name) in inline_enum_variants: # TODO: If we ever have a rust enum Variant(Option) we need to pipe # docs through to there, and then potentially mark the field nullable. - mapped = type_mapping_generator.map_type(inline_enum_variants[camel_to_snake(variant_name)] + " " + camel_to_snake(variant_name), False, None, False, True) + (variant_info, variant_field_docs) = inline_enum_variants[camel_to_snake(variant_name)] + variant_ty_text = variant_info + " " + camel_to_snake(variant_name) + variant_ty_info = type_mapping_generator.java_c_types(variant_ty_text, None) + if variant_field_docs is not None and doc_to_field_nullable(variant_field_docs): + mapped = type_mapping_generator.map_type_with_info(variant_ty_info, False, None, False, True, True) + else: + mapped = type_mapping_generator.map_type_with_info(variant_ty_info, False, None, False, True, False) contains_trait |= mapped.ty_info.contains_trait fields.append((mapped, None)) enum_variants.append(ComplexEnumVariantInfo(variant_name, variant_docs, fields, True)) @@ -868,7 +992,7 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", write_c("\tmemcpy(ret.data, orig->data, sizeof(" + ty_info.c_ty + ") * ret.datalen);\n") write_c("\treturn ret;\n}\n") elif (ty_info.rust_obj.replace("LDK", "") + "_clone") in clone_fns: - ty_name = "CVec_" + ty_info.rust_obj.replace("LDK", "") + "Z"; + ty_name = struct_name.replace("LDK", "") clone_fns.add(ty_name + "_clone") write_c("static inline " + struct_name + " " + ty_name + "_clone(const " + struct_name + " *orig) {\n") write_c("\t" + struct_name + " ret = { .data = MALLOC(sizeof(" + ty_info.rust_obj + ") * orig->datalen, \"" + struct_name + " clone bytes\"), .datalen = orig->datalen };\n") @@ -885,7 +1009,7 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", elif struct_name in union_enum_items: tuple_variants = {} elem_items = -1 - for line, _ in field_lines: + for line, field_block_comment in field_lines: if line == " struct {": elem_items = 0 elif line == " };": @@ -898,7 +1022,7 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", line = line[5:] split = line.split(" ") assert len(split) == 2 - tuple_variants[split[1].strip(";")] = split[0] + tuple_variants[split[1].strip(";")] = (split[0], field_block_comment) elem_items += 1 if elem_items > 1: # We don't currently support tuple variant with more than one element