def get_param_name(param): if type_manager.get_type(param.arg_type).has_default_value() \ or param.default_value is not None: fmt = '?{}' else: fmt = '{}' return fmt.format(param.ocaml_name)
def get_optioned_type(param): typ = type_manager.get_type(param.arg_type) if typ.has_default_value() or param.default_value is not None: return '?{}:{}'.format(param.ocaml_name, typ.get_ocaml_param_type()) else: return typ.get_ocaml_param_type()
def get_param_type(param): typ = type_manager.get_type(param.arg_type) typ_name = check_enclosing_module(typ.get_ocaml_param_type()) if typ.has_default_value() or param.default_value is not None: return '?{}:{}'.format(param.ocaml_name, typ_name) else: return typ_name
def get_param_name(param): typ = type_manager.get_type(param.arg_type) if param.default_value is not None: return '?({} = {} ())' \ .format(param.ocaml_name, param.get_default_val_ocaml_name(enclosing_module, function.ocaml_name)) elif typ.has_default_value(): return '?({} = {})'.format(param.ocaml_name, typ.get_default_value()) else: return param.ocaml_name
def is_optional_param(param): return type_manager.get_type(param.arg_type).has_default_value() \ or param.default_value is not None
def write_function(function, enclosing_module=None, mli_only=False): if not type_manager.has_type(function.return_type): print('Skipping {} because return type {} not in type map'.format( function.cpp_name, function.return_type)) missing_types.add(function.return_type) return for param in function.parameters: if not type_manager.has_type(param.arg_type): print( 'Skipping {} because param type {} not in type map'.format( function.cpp_name, param.arg_type)) missing_types.add(param.arg_type) return def check_enclosing_module(name): # return name[len(enclosing_module) + 1:] if enclosing_module is not None \ # and name.startswith(enclosing_module + '.') else name return name.replace('{}.t'.format(enclosing_module), 't') def pointerize_type(typ, cpp=False): fmt = '{} *' if typ.must_pass_pointer( ) and not typ.is_pointer() else '{}' return fmt.format(typ.get_cpp_type() if cpp else typ.get_c_type()) params_h = ', '.join([ '{} {}'.format( pointerize_type(type_manager.get_type(param.arg_type)), param.name) for param in function.parameters ]) stub = '{} {}({})'.format( pointerize_type(type_manager.get_type(function.return_type), cpp=True), function.c_name, params_h) if not mli_only: opencv_h.write('{};'.format(stub)) draw_in_out_mat_count = 0 # Keep track of number of default parameters. # If all of the parameters have default values, then we need # to add a unit to the end so that we can used properly (OCaml # functions where the last parameter is optional cannot be applied # without supplying that parameter) total_default_params = 0 # default parameters for param in function.parameters: arg_type = type_manager.get_type(param.arg_type) draw_in_out_mat_count += arg_type.is_draw_function() if param.default_value is not None: c_name = param.get_default_val_c_name(enclosing_module, function.c_name) ocaml_name = param.get_default_val_ocaml_name( enclosing_module, function.ocaml_name) cpp_type = arg_type.get_cpp_type() pointerized_type = pointerize_type(arg_type, cpp=True) # There are screwy things with autoboxing rules and whatnot, # so the easiest thing for us to do here is put the default # value as a default argument in a helper function and then # call that function - that way it is the same syntactic # class as the header file from which it is pulled. opencv_h.write('{} {}();'.format(pointerized_type, c_name)) opencv_cpp.write('{} _{}({} v = {}) {{'.format( cpp_type, c_name, cpp_type, param.default_value)) opencv_cpp.indent() opencv_cpp.write('return v;') opencv_cpp.unindent() opencv_cpp.write('}') opencv_cpp.write('{} {}() {{'.format(pointerized_type, c_name)) opencv_cpp.indent() if arg_type.must_pass_pointer() and not arg_type.is_pointer(): opencv_cpp.write('return new {}(_{}());'.format( cpp_type, c_name)) else: opencv_cpp.write('return _{}();'.format(c_name)) opencv_cpp.unindent() opencv_cpp.write('}') opencv_ml.write('let {} ='.format(ocaml_name)) opencv_ml.indent() opencv_ml.write( 'let f = foreign "{}" (void @-> returning ({})) in'.format( c_name, arg_type.get_ctypes_value())) opencv_ml.write('fun () -> let v = f () in {}'.format( arg_type.ctypes_to_ocaml('v'))) opencv_ml.unindent() total_default_params += 1 elif type_manager.get_type(param.arg_type).has_default_value(): total_default_params += 1 def pointerize_value(typ, val): fmt = '*({})' if typ.must_pass_pointer( ) and not typ.is_pointer() else '{}' return fmt.format(typ.c_to_cpp(val)) def depointerize_value(typ, val): pass params_cpp = ', '.join([ pointerize_value(type_manager.get_type(param.arg_type), param.name) for param in function.c_params ]) value = '{}({})'.format(function.cpp_name, params_cpp) ret_type = type_manager.get_type(function.return_type) if function.return_type == 'void': invoke_fmt = '{};' elif ret_type.must_pass_pointer() and not ret_type.is_pointer(): invoke_fmt = 'return new {} ({{}});'.format( ret_type.get_cpp_type()) else: invoke_fmt = 'return {};' if not mli_only: opencv_cpp.write('{} {{'.format(stub)) opencv_cpp.indent() opencv_cpp.write(invoke_fmt.format(ret_type.cpp_to_c(value))) opencv_cpp.unindent() opencv_cpp.write('}') def get_param_name(param): typ = type_manager.get_type(param.arg_type) if param.default_value is not None: return '?({} = {} ())' \ .format(param.ocaml_name, param.get_default_val_ocaml_name(enclosing_module, function.ocaml_name)) elif typ.has_default_value(): return '?({} = {})'.format(param.ocaml_name, typ.get_default_value()) else: return param.ocaml_name def is_optional_param(param): return type_manager.get_type(param.arg_type).has_default_value() \ or param.default_value is not None # move (float) optional params to the front to prevent un-erasable optional arguments # (basically optional arguments can't be the last parameter in OCaml) floated_params = list( sorted(function.parameters, key=lambda param: not is_optional_param(param))) optional_param_count = len( list(filter(is_optional_param, function.parameters))) # add extra parameters for optionally disabling cloning of cloneable params inserted_param_count = 0 for i, param in enumerate(floated_params.copy()): if type_manager.get_type(param.arg_type).is_cloneable(): floated_params.insert( i + inserted_param_count, Parameter('', '{}_recycle'.format(param.ocaml_name), '__recycle_flag', None, False)) inserted_param_count += 1 floated_param_names = list(map(get_param_name, floated_params)) param_names_prime = [ "{}'".format(param.ocaml_name) for param in function.parameters ] if len(function.parameters) <= total_default_params: floated_param_names.append('()') if len(function.parameters) == 0: param_names_prime.append('()') ctypes_sig_list = [ type_manager.get_type(param.arg_type).get_ctypes_value() for param in function.parameters ] if len(ctypes_sig_list) == 0: ctypes_sig_list.append('void') ctypes_sig_list.append('returning ({})'.format( type_manager.get_type(function.return_type).get_ctypes_value())) ctypes_sig = ' @-> '.join(ctypes_sig_list) returned_params = list( filter( lambda param: type_manager.get_type(param.arg_type). return_value('') is not None, function.parameters)) returned_values = list( map( lambda param: type_manager.get_type(param.arg_type). return_value(param.ocaml_name), returned_params)) returned_types = list( map( lambda param: check_enclosing_module( type_manager.get_type(param.arg_type).get_ocaml_type()), returned_params)) erase_return_unit = function.return_type == 'void' and len( returned_params) > 0 if not erase_return_unit: returned_values.append('res') returned_types.append( check_enclosing_module( type_manager.get_type( function.return_type).get_ocaml_type())) is_draw_function = draw_in_out_mat_count == 1 \ and function.return_type == 'void' \ and len(returned_params) == 0 \ and optional_param_count < len(floated_params) - 1 if not mli_only: opencv_ml.write('let __{} = foreign "{}" ({})'.format( function.ocaml_name, function.c_name, ctypes_sig)) opencv_ml.write('let {} {} ='.format( function.ocaml_name, ' '.join(floated_param_names))) opencv_ml.indent() for param in function.parameters: param_type = type_manager.get_type(param.arg_type) if param_type.is_cloneable(): fmt = "let {0} = if {0}_recycle then {0} else Cvdata.clone {0} in let {{}}' = {{}} in" \ .format(param.ocaml_name) else: fmt = "let {}' = {} in" opencv_ml.write( fmt.format(param.ocaml_name, param_type.ocaml_to_ctypes(param.ocaml_name))) opencv_ml.write('let {} = {} in'.format( '_' if erase_return_unit else 'res', type_manager.get_type(function.return_type).ctypes_to_ocaml( '__{} {}'.format(function.ocaml_name, ' '.join(param_names_prime))))) for param in function.parameters: post_func = type_manager.get_type(param.arg_type) \ .ocaml_to_ctypes(param.ocaml_name).post if post_func is not None: post = post_func(param.ocaml_name, "{}'".format(param.ocaml_name)) opencv_ml.write('{};'.format(post)) opencv_ml.write(', '.join(returned_values)) opencv_ml.unindent() def get_param_type(param): typ = type_manager.get_type(param.arg_type) typ_name = check_enclosing_module(typ.get_ocaml_param_type()) if typ.has_default_value() or param.default_value is not None: return '?{}:{}'.format(param.ocaml_name, typ_name) else: return typ_name ocaml_sig_list = list(map(get_param_type, floated_params)) if 0 < len(function.parameters) <= total_default_params: ocaml_sig_list.append('unit') if len(ocaml_sig_list) == 0: ocaml_sig_list.append('unit') ocaml_sig_list.append(' * '.join(returned_types)) ocaml_sig = ' -> '.join(ocaml_sig_list) opencv_mli.write() opencv_mli.write('(**') opencv_mli.write( sanitize_docs( function.docs, name=function.ocaml_name, params=floated_params, param_map=function.param_map, extra_unit=len(function.parameters) <= total_default_params)) opencv_mli.write('*)') opencv_mli.write('val {} : {}'.format(function.ocaml_name, ocaml_sig)) if is_draw_function: def is_draw_function_param(param): return type_manager.get_type(param.arg_type).is_draw_function() filtered_params = list( filter(lambda x: not is_draw_function_param(x), floated_params)) draw_function_param = list( filter(is_draw_function_param, floated_params))[0] draw_functions.append((function, floated_params, filtered_params, draw_function_param, enclosing_module))
def get_val_type(self): return type_manager.get_type(self.val_type_cpp_name)
def is_draw_function_param(param): return type_manager.get_type(param.arg_type).is_draw_function()