Move version information out of git into new files
[ldk-java] / genbindings.py
index fb3d8cb6cdf2bbe34cf43d2fb81665498810bc97..3733d540bc06f95e65e2221a9b458e83be29a862 100755 (executable)
@@ -424,7 +424,7 @@ java_c_types_none_allowed = False # C structs created by cbindgen are declared i
 with open(f"{sys.argv[3]}/structs/UtilMethods{consts.file_ext}", "a") as util:
     util.write(consts.util_fn_pfx)
 
-with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
+with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", "w") as out_java:
     # Map a top-level function
     def map_fn(line, re_match, ret_arr_len, c_call_string, doc_comment):
         method_return_type = re_match.group(1)
@@ -459,8 +459,23 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
                     takes_self_ptr = True
             elif argument_conversion_info.arg_name in params_nullable:
                 argument_conversion_info.nullable = True
+                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.")
+                    print("    Normally for arguments that require a move and are not clonable, we split")
+                    print("    the argument into the type's constructor's arguments and just use those to")
+                    print("    construct a new object on the fly.")
+                    print("    However, because the object is nullable, doing so would mean we can no")
+                    print("    longer allow the user to pass null, as we now have an argument list instead.")
+                    print("    Thus, we blindly assume its really an Option<&Type> instead of an Option<Type>.")
+                    print("    It may or may not actually be a reference, but its the simplest mapping option")
+                    print("    and also the only use of this code today.")
+                    arg_ty_info.requires_clone = False
+                    argument_conversion_info = type_mapping_generator.map_type_with_info(arg_ty_info, False, None, is_free, True)
+                    assert argument_conversion_info.arg_conv is not None and "Warning" not in argument_conversion_info.arg_conv
+
             if argument_conversion_info.arg_conv is not None and "Warning" in argument_conversion_info.arg_conv:
-                assert not argument_conversion_info.arg_name in params_nullable
                 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(','):
@@ -515,6 +530,7 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
             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
@@ -782,7 +798,9 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
                 write_c("\treturn tuple->" + e + ";\n")
             write_c("}\n")
 
-    out_java.write(consts.bindings_header.replace('<git_version_ldk_garbagecollected>', local_git_version))
+    out_java.write(consts.bindings_header)
+    with open(f"{sys.argv[2]}/version{consts.file_ext}", "w") as out_java_version:
+        out_java_version.write(consts.bindings_version_file.replace('<git_version_ldk_garbagecollected>', local_git_version))
 
     with open(f"{sys.argv[3]}/structs/CommonBase{consts.file_ext}", "w") as out_java_struct:
         out_java_struct.write(consts.common_base)
@@ -988,15 +1006,39 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
                     with open(f"{sys.argv[3]}/structs/TxOut{consts.file_ext}", "w") as out_java_struct:
                         out_java_struct.write(consts.hu_struct_file_prefix)
                         out_java_struct.write("public class TxOut extends CommonBase{\n")
-                        out_java_struct.write("\tTxOut(java.lang.Object _dummy, long ptr) { super(ptr); }\n")
-                        out_java_struct.write("\tlong to_c_ptr() { return 0; }\n")
+                        out_java_struct.write("\t/** The script_pubkey in this output */\n")
+                        out_java_struct.write("\tpublic final byte[] script_pubkey;\n")
+                        out_java_struct.write("\t/** The value, in satoshis, of this output */\n")
+                        out_java_struct.write("\tpublic final long value;\n")
+                        out_java_struct.write("\n")
+                        out_java_struct.write("\tTxOut(java.lang.Object _dummy, long ptr) {\n")
+                        out_java_struct.write("\t\tsuper(ptr);\n")
+                        out_java_struct.write("\t\tthis.script_pubkey = bindings.TxOut_get_script_pubkey(ptr);\n")
+                        out_java_struct.write("\t\tthis.value = bindings.TxOut_get_value(ptr);\n")
+                        out_java_struct.write("\t}\n")
+                        out_java_struct.write("\tpublic TxOut(long value, byte[] script_pubkey) {\n")
+                        out_java_struct.write("\t\tsuper(bindings.TxOut_new(script_pubkey, value));\n")
+                        out_java_struct.write("\t\tthis.script_pubkey = bindings.TxOut_get_script_pubkey(ptr);\n")
+                        out_java_struct.write("\t\tthis.value = bindings.TxOut_get_value(ptr);\n")
+                        out_java_struct.write("\t}\n")
+                        out_java_struct.write("\n")
                         out_java_struct.write("\t@Override @SuppressWarnings(\"deprecation\")\n")
                         out_java_struct.write("\tprotected void finalize() throws Throwable {\n")
                         out_java_struct.write("\t\tsuper.finalize();\n")
                         out_java_struct.write("\t\tif (ptr != 0) { bindings.TxOut_free(ptr); }\n")
                         out_java_struct.write("\t}\n")
-                        # TODO: TxOut body
+                        out_java_struct.write("\n")
                         out_java_struct.write("}")
+                        fn_line = "struct LDKCVec_u8Z TxOut_get_script_pubkey (struct LDKTxOut* thing)"
+                        write_c(fn_line + " {")
+                        write_c("\treturn CVec_u8Z_clone(&thing->script_pubkey);")
+                        write_c("}")
+                        map_fn(fn_line + "\n", re.compile("(.*) (TxOut_get_script_pubkey) \((.*)\)").match(fn_line), None, None, None)
+                        fn_line = "uint64_t TxOut_get_value (struct LDKTxOut* thing)"
+                        write_c(fn_line + " {")
+                        write_c("\treturn thing->value;")
+                        write_c("}")
+                        map_fn(fn_line + "\n", re.compile("(.*) (TxOut_get_value) \((.*)\)").match(fn_line), None, None, None)
                 else:
                     pass # Everything remaining is a byte[] or some form
                 cur_block_obj = None
@@ -1046,9 +1088,11 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
         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.replace('<git_version_ldk_garbagecollected>', local_git_version))
+with open(f"{sys.argv[4]}/bindings.c.body", "w") as out_c:
+    out_c.write(consts.c_file_pfx)
     out_c.write(consts.init_str())
     out_c.write(c_file)
+with open(f"{sys.argv[4]}/version.c", "w") as out_c:
+    out_c.write(consts.c_version_file.replace('<git_version_ldk_garbagecollected>', local_git_version))
 with open(f"{sys.argv[3]}/structs/UtilMethods{consts.file_ext}", "a") as util:
     util.write(consts.util_fn_sfx)