X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=genbindings.py;h=12649658afe476ce32405a95c0d44f139f931cda;hb=20ee8c36407f25547ac60339007cbf6fbe61deee;hp=124a76bac1e2688b9fbdc3ea1d29a7db645986f8;hpb=51b99938ad39a1215696f57e37c8ee79307c1086;p=ldk-java diff --git a/genbindings.py b/genbindings.py index 124a76ba..12649658 100755 --- a/genbindings.py +++ b/genbindings.py @@ -88,6 +88,7 @@ def java_c_types(fn_arg, ret_arr_len): fn_arg = fn_arg[7:] if fn_arg.startswith("enum "): fn_arg = fn_arg[5:] + nonnull_ptr = "NONNULL_PTR" in fn_arg fn_arg = fn_arg.replace("NONNULL_PTR", "") is_ptr = False @@ -172,11 +173,13 @@ def java_c_types(fn_arg, ret_arr_len): res.pass_by_ref = True 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 + "[]", - java_fn_ty_arg="[" + res.java_fn_ty_arg, c_ty=res.c_ty + "Array", passed_as_ptr=False, is_ptr=is_ptr, is_const=is_const, + 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 + "[]", - java_fn_ty_arg="[" + res.java_fn_ty_arg, c_ty=consts.ptr_arr, passed_as_ptr=False, is_ptr=is_ptr, is_const=is_const, + 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) is_primitive = False @@ -296,7 +299,7 @@ def java_c_types(fn_arg, ret_arr_len): else: c_ty = consts.ptr_c_ty java_ty = consts.ptr_native_ty - java_hu_ty = ma.group(1).strip().replace("LDKCResult", "Result").replace("LDK", "") + java_hu_ty = ma.group(1).strip().replace("LDKCOption", "Option").replace("LDKCResult", "Result").replace("LDK", "") fn_ty_arg = "J" fn_arg = ma.group(2).strip() rust_obj = ma.group(1).strip() @@ -322,14 +325,16 @@ def java_c_types(fn_arg, ret_arr_len): 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, var_name="arg", arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False) + passed_as_ptr=False, is_ptr=False, nonnull_ptr=nonnull_ptr, var_name="arg", + arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False) 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, var_name=var_is_arr.group(1), arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False) + passed_as_ptr=False, is_ptr=False, nonnull_ptr=nonnull_ptr, var_name=var_is_arr.group(1), + arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False) 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, var_name=fn_arg, arr_len=arr_len, arr_access=arr_access, is_native_primitive=is_primitive) + 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) fn_ptr_regex = re.compile("^extern const ([A-Za-z_0-9\* ]*) \(\*(.*)\)\((.*)\);$") fn_ret_arr_regex = re.compile("(.*) \(\*(.*)\((.*)\)\)\[([0-9]*)\];$") @@ -376,7 +381,10 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: method_arguments = method_comma_separated_arguments.split(',') is_free = method_name.endswith("_free") - struct_meth = method_name.split("_")[0] + if method_name.startswith("COption") or method_name.startswith("CResult"): + struct_meth = method_name.rsplit("Z", 1)[0][1:] + "Z" + else: + struct_meth = method_name.split("_")[0] return_type_info = type_mapping_generator.map_type(method_return_type, True, ret_arr_len, False, False) @@ -432,7 +440,11 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: write_c(out_c_delta) out_java_struct = None - if ("LDK" + struct_meth in opaque_structs or "LDK" + struct_meth in trait_structs) and not is_free: + expected_struct = "LDK" + struct_meth + expected_cstruct = "LDKC" + struct_meth + if (expected_struct in opaque_structs or expected_struct in trait_structs + or expected_struct in complex_enums or expected_cstruct in complex_enums + or expected_cstruct in result_types) and not is_free: out_java_struct = open(f"{sys.argv[3]}/structs/{struct_meth}{consts.file_ext}", "a") elif method_name.startswith("C2Tuple_") and method_name.endswith("_read"): struct_meth = method_name.rsplit("_", 1)[0] @@ -457,8 +469,8 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: out_java_enum.write(native_file_out) out_java.write(native_out) - def map_complex_enum(struct_name, union_enum_items, enum_doc_comment): - java_hu_type = struct_name.replace("LDK", "") + def map_complex_enum(struct_name, union_enum_items, inline_enum_variants, enum_doc_comment): + java_hu_type = struct_name.replace("LDK", "").replace("COption", "Option") complex_enums.add(struct_name) enum_variants = [] @@ -480,13 +492,12 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: for idx, field in enumerate(enum_var_lines): if idx != 0 and idx < len(enum_var_lines) - 2: fields.append(type_mapping_generator.map_type(field.strip(' ;'), False, None, False, True)) - else: - # TODO: Assert line format - pass + enum_variants.append(ComplexEnumVariantInfo(variant_name, fields, False)) + elif camel_to_snake(variant_name) in inline_enum_variants: + fields.append(type_mapping_generator.map_type(inline_enum_variants[camel_to_snake(variant_name)] + " " + camel_to_snake(variant_name), False, None, False, True)) + enum_variants.append(ComplexEnumVariantInfo(variant_name, fields, True)) else: - # TODO: Assert line format - pass - enum_variants.append(ComplexEnumVariantInfo(variant_name, fields)) + enum_variants.append(ComplexEnumVariantInfo(variant_name, fields, True)) with open(f"{sys.argv[3]}/structs/{java_hu_type}{consts.file_ext}", "w") as out_java_enum: (out_java_addendum, out_java_enum_addendum, out_c_addendum) = consts.map_complex_enum(struct_name, enum_variants, camel_to_snake, enum_doc_comment) @@ -527,7 +538,7 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: # For now, just disable enabling the _call_log - we don't know how to inverse-map String is_log = fn_line.group(3) == "log" and struct_name == "LDKLogger" if fn_line.group(3) != "free" and fn_line.group(3) != "clone" and fn_line.group(3) != "eq" and not is_log: - dummy_line = fn_line.group(2) + struct_name.replace("LDK", "") + "_" + fn_line.group(3) + " " + struct_name + "* this_arg" + fn_line.group(5) + "\n" + dummy_line = fn_line.group(2) + struct_name.replace("LDK", "") + "_" + fn_line.group(3) + " " + struct_name + " *NONNULL_PTR this_arg" + fn_line.group(5) + "\n" map_fn(dummy_line, re.compile("([A-Za-z_0-9]*) *([A-Za-z_0-9]*) *(.*)").match(dummy_line), None, "(this_arg_conv->" + fn_line.group(3) + ")(this_arg_conv->this_arg", fn_docs) for idx, var_line in enumerate(field_var_lines): if var_line.group(1) not in trait_structs: @@ -536,7 +547,7 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: write_c("\t\tthis_arg->set_" + var_line.group(2) + "(this_arg);\n") write_c("\treturn this_arg->" + var_line.group(2) + ";\n") write_c("}\n") - dummy_line = var_line.group(1) + " " + struct_name.replace("LDK", "") + "_get_" + var_line.group(2) + " " + struct_name + "* this_arg" + fn_line.group(5) + "\n" + dummy_line = var_line.group(1) + " " + struct_name.replace("LDK", "") + "_get_" + var_line.group(2) + " " + struct_name + " *NONNULL_PTR this_arg" + fn_line.group(5) + "\n" map_fn(dummy_line, re.compile("([A-Za-z_0-9]*) *([A-Za-z_0-9]*) *(.*)").match(dummy_line), None, struct_name + "_set_get_" + var_line.group(2) + "(this_arg_conv", fn_docs) def map_result(struct_name, res_ty, err_ty): @@ -595,17 +606,7 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: else: out_java_struct.write("\t\t\tthis.res = bindings." + struct_name + "_get_ok(ptr);\n") out_java_struct.write("\t\t}\n") - if struct_name.startswith("LDKCResult_None"): - out_java_struct.write("\t\tpublic " + human_ty + "_OK() {\n\t\t\tthis(null, bindings.C" + human_ty + "_ok());\n") - else: - out_java_struct.write("\t\tpublic " + human_ty + "_OK(" + res_map.java_hu_ty + " res) {\n") - if res_map.from_hu_conv is not None: - out_java_struct.write("\t\t\tthis(null, bindings.C" + human_ty + "_ok(" + res_map.from_hu_conv[0] + "));\n") - if res_map.from_hu_conv[1] != "": - out_java_struct.write("\t\t\t" + res_map.from_hu_conv[1].replace("\n", "\n\t\t\t") + ";\n") - else: - out_java_struct.write("\t\t\tthis(null, bindings.C" + human_ty + "_ok(res));\n") - out_java_struct.write("\t\t}\n\t}\n\n") + out_java_struct.write("\t}\n\n") out_java.write("\tpublic static native " + err_map.java_ty + " " + struct_name + "_get_err(long arg);\n") write_c(consts.c_fn_ty_pfx + err_map.c_ty + " " + consts.c_fn_name_define_pfx(struct_name + "_get_err", True) + consts.ptr_c_ty + " arg) {\n") @@ -633,17 +634,7 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: out_java_struct.write("\t\t\tthis.err = bindings." + struct_name + "_get_err(ptr);\n") out_java_struct.write("\t\t}\n") - if struct_name.endswith("NoneZ"): - out_java_struct.write("\t\tpublic " + human_ty + "_Err() {\n\t\t\tthis(null, bindings.C" + human_ty + "_err());\n") - else: - out_java_struct.write("\t\tpublic " + human_ty + "_Err(" + err_map.java_hu_ty + " err) {\n") - if err_map.from_hu_conv is not None: - out_java_struct.write("\t\t\tthis(null, bindings.C" + human_ty + "_err(" + err_map.from_hu_conv[0] + "));\n") - if err_map.from_hu_conv[1] != "": - out_java_struct.write("\t\t\t" + err_map.from_hu_conv[1].replace("\n", "\n\t\t\t") + ";\n") - else: - out_java_struct.write("\t\t\tthis(null, bindings.C" + human_ty + "_err(err));\n") - out_java_struct.write("\t\t}\n\t}\n}\n") + out_java_struct.write("\t}\n\n") def map_tuple(struct_name, field_lines): out_java.write("\tpublic static native long " + struct_name + "_new(") @@ -859,7 +850,25 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: enum_var_name = struct_name.split("_") union_enum_items[enum_var_name[0]][enum_var_name[1]] = field_lines elif struct_name in union_enum_items: - map_complex_enum(struct_name, union_enum_items[struct_name], last_block_comment) + tuple_variants = {} + elem_items = -1 + for line in field_lines: + if line == " struct {": + elem_items = 0 + elif line == " };": + elem_items = -1 + elif elem_items > -1: + line = line.strip() + if line.startswith("struct "): + line = line[7:] + split = line.split(" ") + assert len(split) == 2 + tuple_variants[split[1].strip(";")] = split[0] + elem_items += 1 + if elem_items > 1: + # We don't currently support tuple variant with more than one element + assert False + map_complex_enum(struct_name, union_enum_items[struct_name], tuple_variants, last_block_comment) last_block_comment = None elif is_unitary_enum: map_unitary_enum(struct_name, field_lines, last_block_comment) @@ -922,6 +931,12 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java: for struct_name in trait_structs: with open(f"{sys.argv[3]}/structs/{struct_name.replace('LDK', '')}{consts.file_ext}", "a") as out_java_struct: out_java_struct.write("}\n") + for struct_name in complex_enums: + with open(f"{sys.argv[3]}/structs/{struct_name.replace('LDK', '').replace('COption', 'Option')}{consts.file_ext}", "a") as out_java_struct: + out_java_struct.write("}\n") + for struct_name in result_types: + with open(f"{sys.argv[3]}/structs/{struct_name.replace('LDKCResult', 'Result')}{consts.file_ext}", "a") as out_java_struct: + out_java_struct.write("}\n") with open(sys.argv[4], "w") as out_c: out_c.write(consts.c_file_pfx)