11#!/usr/bin/env python3
2- import sys , re
2+ import os , sys , re , subprocess
33
44if len (sys .argv ) < 7 :
55 print ("USAGE: /path/to/lightning.h /path/to/bindings/output /path/to/bindings/ /path/to/bindings/output.c debug lang" )
3333
3434consts = Consts (DEBUG , target = target )
3535
36+ local_git_version = os .getenv ("LDK_GARBAGECOLLECTED_GIT_OVERRIDE" )
37+ if local_git_version is None :
38+ local_git_version = subprocess .check_output (["git" , "describe" , '--tag' , '--dirty' ]).decode ("utf-8" ).strip ()
39+
3640from bindingstypes import *
3741
3842c_file = ""
@@ -121,6 +125,11 @@ def java_c_types(fn_arg, ret_arr_len):
121125 assert var_is_arr_regex .match (fn_arg [8 :])
122126 rust_obj = "LDKSignature"
123127 arr_access = "compact_form"
128+ elif fn_arg .startswith ("LDKRecoverableSignature" ):
129+ fn_arg = "uint8_t (*" + fn_arg [25 :] + ")[68]"
130+ assert var_is_arr_regex .match (fn_arg [8 :])
131+ rust_obj = "LDKRecoverableSignature"
132+ arr_access = "serialized_form"
124133 elif fn_arg .startswith ("LDKThreeBytes" ):
125134 fn_arg = "uint8_t (*" + fn_arg [14 :] + ")[3]"
126135 assert var_is_arr_regex .match (fn_arg [8 :])
@@ -136,6 +145,11 @@ def java_c_types(fn_arg, ret_arr_len):
136145 assert var_is_arr_regex .match (fn_arg [8 :])
137146 rust_obj = "LDKSixteenBytes"
138147 arr_access = "data"
148+ elif fn_arg .startswith ("LDKTwentyBytes" ):
149+ fn_arg = "uint8_t (*" + fn_arg [15 :] + ")[20]"
150+ assert var_is_arr_regex .match (fn_arg [8 :])
151+ rust_obj = "LDKTwentyBytes"
152+ arr_access = "data"
139153 elif fn_arg .startswith ("LDKTenBytes" ):
140154 fn_arg = "uint8_t (*" + fn_arg [12 :] + ")[10]"
141155 assert var_is_arr_regex .match (fn_arg [8 :])
@@ -210,6 +224,13 @@ def java_c_types(fn_arg, ret_arr_len):
210224 fn_ty_arg = "B"
211225 fn_arg = fn_arg [7 :].strip ()
212226 is_primitive = True
227+ elif fn_arg .startswith ("LDKu5" ):
228+ java_ty = consts .c_type_map ['uint8_t' ][0 ]
229+ java_hu_ty = "UInt5"
230+ rust_obj = "LDKu5"
231+ c_ty = "int8_t"
232+ fn_ty_arg = "B"
233+ fn_arg = fn_arg [6 :].strip ()
213234 elif fn_arg .startswith ("uint16_t" ):
214235 mapped_type = consts .c_type_map ['uint16_t' ]
215236 java_ty = mapped_type [0 ]
@@ -243,6 +264,7 @@ def java_c_types(fn_arg, ret_arr_len):
243264 fn_ty_arg = "Ljava/lang/String;"
244265 fn_arg = fn_arg [6 :].strip ()
245266 elif fn_arg .startswith ("LDKStr" ):
267+ rust_obj = "LDKStr"
246268 java_ty = "String"
247269 c_ty = "jstring"
248270 fn_ty_arg = "Ljava/lang/String;"
@@ -252,9 +274,11 @@ def java_c_types(fn_arg, ret_arr_len):
252274 else :
253275 ma = var_ty_regex .match (fn_arg )
254276 if ma .group (1 ).strip () in unitary_enums :
255- java_ty = ma .group (1 ).strip ()
277+ assert ma .group (1 ).strip ().startswith ("LDK" )
278+ java_ty = ma .group (1 ).strip ()[3 :]
279+ java_hu_ty = java_ty
256280 c_ty = consts .result_c_ty
257- fn_ty_arg = "Lorg/ldk/enums/" + ma . group ( 1 ). strip () + ";"
281+ fn_ty_arg = "Lorg/ldk/enums/" + java_ty + ";"
258282 fn_arg = ma .group (2 ).strip ()
259283 rust_obj = ma .group (1 ).strip ()
260284 elif ma .group (1 ).strip ().startswith ("LDKC2Tuple" ):
@@ -382,6 +406,7 @@ def java_c_types(fn_arg, ret_arr_len):
382406 def map_fn (line , re_match , ret_arr_len , c_call_string , doc_comment ):
383407 method_return_type = re_match .group (1 )
384408 method_name = re_match .group (2 )
409+ orig_method_name = str (method_name )
385410 method_comma_separated_arguments = re_match .group (3 )
386411 method_arguments = method_comma_separated_arguments .split (',' )
387412
@@ -391,17 +416,20 @@ def map_fn(line, re_match, ret_arr_len, c_call_string, doc_comment):
391416 else :
392417 struct_meth = method_name .split ("_" )[0 ]
393418
394- return_type_info = type_mapping_generator .map_type (method_return_type , True , ret_arr_len , False , False )
419+ return_type_info = type_mapping_generator .map_type (method_return_type . strip () + " ret" , True , ret_arr_len , False , False )
395420
396421 argument_types = []
397422 default_constructor_args = {}
398423 takes_self = False
424+ takes_self_ptr = False
399425 args_known = True
400426
401427 for argument_index , argument in enumerate (method_arguments ):
402428 argument_conversion_info = type_mapping_generator .map_type (argument , False , None , is_free , True )
403429 if argument_index == 0 and argument_conversion_info .java_hu_ty == struct_meth :
404430 takes_self = True
431+ if argument_conversion_info .ty_info .is_ptr :
432+ takes_self_ptr = True
405433 if argument_conversion_info .arg_conv is not None and "Warning" in argument_conversion_info .arg_conv :
406434 if argument_conversion_info .rust_obj in constructor_fns :
407435 assert not is_free
@@ -416,10 +444,14 @@ def map_fn(line, re_match, ret_arr_len, c_call_string, doc_comment):
416444 default_constructor_args [argument_conversion_info .arg_name ] = []
417445 default_constructor_args [argument_conversion_info .arg_name ].append (explode_arg_conv )
418446 argument_types .append (argument_conversion_info )
447+ if not takes_self and return_type_info .java_hu_ty != struct_meth :
448+ if not return_type_info .java_hu_ty .startswith ("Result_" + struct_meth ):
449+ method_name = orig_method_name
450+ struct_meth = ""
419451
420452 out_java .write ("\t // " + line )
421453 (out_java_delta , out_c_delta , out_java_struct_delta ) = \
422- consts .map_function (argument_types , c_call_string , method_name , return_type_info , struct_meth , default_constructor_args , takes_self , args_known , type_mapping_generator , doc_comment )
454+ consts .map_function (argument_types , c_call_string , method_name , return_type_info , struct_meth , default_constructor_args , takes_self , takes_self_ptr , args_known , type_mapping_generator , doc_comment )
423455 out_java .write (out_java_delta )
424456
425457 if is_free :
@@ -451,14 +483,23 @@ def map_fn(line, re_match, ret_arr_len, c_call_string, doc_comment):
451483 or expected_struct in complex_enums or expected_cstruct in complex_enums
452484 or expected_cstruct in result_types ) and not is_free :
453485 out_java_struct = open (f"{ sys .argv [3 ]} /structs/{ struct_meth } { consts .file_ext } " , "a" )
454- elif method_name .startswith ("C2Tuple_" ) and method_name .endswith ("_read" ):
455- struct_meth = method_name .rsplit ("_" , 1 )[0 ]
456- out_java_struct = open (f"{ sys .argv [3 ]} /structs/UtilMethods{ consts .file_ext } " , "a" )
457- if out_java_struct is not None :
458486 out_java_struct .write (out_java_struct_delta )
487+ elif (not is_free and not method_name .endswith ("_clone" ) and
488+ not method_name .startswith ("_" ) and
489+ method_name != "check_platform" and method_name != "Result_read" and
490+ not expected_struct in unitary_enums and
491+ ((not method_name .startswith ("C2Tuple_" ) and not method_name .startswith ("C3Tuple_" ))
492+ or method_name .endswith ("_read" ))):
493+ out_java_struct = open (f"{ sys .argv [3 ]} /structs/UtilMethods{ consts .file_ext } " , "a" )
494+ for line in out_java_struct_delta .splitlines ():
495+ if not line .strip ().startswith ("this." ):
496+ out_java_struct .write (line + "\n " )
497+ else :
498+ out_java_struct .write ("\t \t // " + line .strip () + "\n " )
459499
460500 def map_unitary_enum (struct_name , field_lines , enum_doc_comment ):
461- with open (f"{ sys .argv [3 ]} /enums/{ struct_name } { consts .file_ext } " , "w" ) as out_java_enum :
501+ assert struct_name .startswith ("LDK" )
502+ with open (f"{ sys .argv [3 ]} /enums/{ struct_name [3 :]} { consts .file_ext } " , "w" ) as out_java_enum :
462503 unitary_enums .add (struct_name )
463504 for idx , struct_line in enumerate (field_lines ):
464505 if idx == 0 :
@@ -469,7 +510,8 @@ def map_unitary_enum(struct_name, field_lines, enum_doc_comment):
469510 assert (struct_line == "} %s;" % struct_name )
470511 elif idx == len (field_lines ) - 1 :
471512 assert (struct_line == "" )
472- (c_out , native_file_out , native_out ) = consts .native_c_unitary_enum_map (struct_name , [x .strip ().strip ("," ) for x in field_lines [1 :- 3 ]], enum_doc_comment )
513+ assert struct_name .startswith ("LDK" )
514+ (c_out , native_file_out , native_out ) = consts .native_c_unitary_enum_map (struct_name [3 :], [x .strip ().strip ("," ) for x in field_lines [1 :- 3 ]], enum_doc_comment )
473515 write_c (c_out )
474516 out_java_enum .write (native_file_out )
475517 out_java .write (native_out )
@@ -495,7 +537,7 @@ def map_complex_enum(struct_name, union_enum_items, inline_enum_variants, enum_d
495537 if "LDK" + variant_name in union_enum_items :
496538 enum_var_lines = union_enum_items ["LDK" + variant_name ]
497539 for idx , field in enumerate (enum_var_lines ):
498- if idx != 0 and idx < len (enum_var_lines ) - 2 :
540+ if idx != 0 and idx < len (enum_var_lines ) - 2 and field . strip () != "" :
499541 fields .append (type_mapping_generator .map_type (field .strip (' ;' ), False , None , False , True ))
500542 enum_variants .append (ComplexEnumVariantInfo (variant_name , fields , False ))
501543 elif camel_to_snake (variant_name ) in inline_enum_variants :
@@ -528,7 +570,7 @@ def map_trait(struct_name, field_var_lines, trait_fn_lines, trait_doc_comment):
528570
529571 field_fns = []
530572 for fn_docs , fn_line in trait_fn_lines :
531- ret_ty_info = type_mapping_generator .map_type (fn_line .group (2 ), True , None , False , False )
573+ ret_ty_info = type_mapping_generator .map_type (fn_line .group (2 ). strip () + " ret" , True , None , False , False )
532574 is_const = fn_line .group (4 ) is not None
533575
534576 arg_tys = []
@@ -675,7 +717,7 @@ def map_tuple(struct_name, field_lines):
675717 write_c ("\t ret->" + e + " = " + e + ";\n " )
676718 if ty_info .arg_conv_cleanup is not None :
677719 write_c ("\t //TODO: Really need to call " + ty_info .arg_conv_cleanup + " here\n " )
678- write_c ("\t return (long )ret;\n " )
720+ write_c ("\t return (uint64_t )ret;\n " )
679721 write_c ("}\n " )
680722
681723 for idx , ty_info in enumerate (ty_list ):
@@ -691,7 +733,7 @@ def map_tuple(struct_name, field_lines):
691733 write_c ("\t return tuple->" + e + ";\n " )
692734 write_c ("}\n " )
693735
694- out_java .write (consts .bindings_header )
736+ out_java .write (consts .bindings_header . replace ( '<git_version_ldk_garbagecollected>' , local_git_version ) )
695737
696738 with open (f"{ sys .argv [3 ]} /structs/CommonBase{ consts .file_ext } " , "w" ) as out_java_struct :
697739 out_java_struct .write (consts .common_base )
@@ -835,7 +877,7 @@ def map_tuple(struct_name, field_lines):
835877 if cleanup is not None :
836878 write_c ("\t \t " + cleanup + ";\n " )
837879 write_c ("\t }\n " )
838- write_c ("\t return (long )ret;\n " )
880+ write_c ("\t return (uint64_t )ret;\n " )
839881 write_c ("}\n " )
840882
841883 if ty_info .is_native_primitive :
@@ -871,6 +913,8 @@ def map_tuple(struct_name, field_lines):
871913 line = line .strip ()
872914 if line .startswith ("struct " ):
873915 line = line [7 :]
916+ elif line .startswith ("enum " ):
917+ line = line [5 :]
874918 split = line .split (" " )
875919 assert len (split ) == 2
876920 tuple_variants [split [1 ].strip (";" )] = split [0 ]
@@ -948,7 +992,7 @@ def map_tuple(struct_name, field_lines):
948992 out_java_struct .write ("}\n " )
949993
950994with open (sys .argv [4 ], "w" ) as out_c :
951- out_c .write (consts .c_file_pfx )
995+ out_c .write (consts .c_file_pfx . replace ( '<git_version_ldk_garbagecollected>' , local_git_version ) )
952996 out_c .write (consts .init_str ())
953997 out_c .write (c_file )
954998with open (f"{ sys .argv [3 ]} /structs/UtilMethods{ consts .file_ext } " , "a" ) as util :
0 commit comments