Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/scripts/wrap/python.py @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 ''' | |
| 2 Things for generating Python-specific output. | |
| 3 ''' | |
| 4 | |
| 5 import jlib | |
| 6 | |
| 7 from . import cpp | |
| 8 from . import parse | |
| 9 from . import rename | |
| 10 from . import state | |
| 11 from . import util | |
| 12 | |
| 13 | |
| 14 def make_outparam_helper_python( | |
| 15 tu, | |
| 16 cursor, | |
| 17 fnname, | |
| 18 fnname_wrapper, | |
| 19 generated, | |
| 20 main_name, | |
| 21 ): | |
| 22 # Write python wrapper. | |
| 23 return_void = cursor.result_type.spelling == 'void' | |
| 24 generated.swig_python.write('') | |
| 25 generated.swig_python.write(f'def {main_name}(') | |
| 26 sep = '' | |
| 27 for arg in parse.get_args( tu, cursor): | |
| 28 if arg.out_param: | |
| 29 continue | |
| 30 generated.swig_python.write(f'{sep}{arg.name_python}') | |
| 31 sep = ', ' | |
| 32 generated.swig_python.write('):\n') | |
| 33 generated.swig_python.write(f' """\n') | |
| 34 generated.swig_python.write(f' Wrapper for out-params of {cursor.spelling}().\n') | |
| 35 sep = '' | |
| 36 generated.swig_python.write(f' Returns: ') | |
| 37 sep = '' | |
| 38 if not return_void: | |
| 39 generated.swig_python.write( f'{cursor.result_type.spelling}') | |
| 40 sep = ', ' | |
| 41 for arg in parse.get_args( tu, cursor): | |
| 42 if arg.out_param: | |
| 43 generated.swig_python.write(f'{sep}{cpp.declaration_text(arg.cursor.type.get_pointee(), arg.name_python)}') | |
| 44 sep = ', ' | |
| 45 generated.swig_python.write(f'\n') | |
| 46 generated.swig_python.write(f' """\n') | |
| 47 generated.swig_python.write(f' outparams = {main_name}_outparams()\n') | |
| 48 generated.swig_python.write(f' ret = {main_name}_outparams_fn(') | |
| 49 sep = '' | |
| 50 for arg in parse.get_args( tu, cursor): | |
| 51 if arg.out_param: | |
| 52 continue | |
| 53 generated.swig_python.write(f'{sep}{arg.name_python}') | |
| 54 sep = ', ' | |
| 55 generated.swig_python.write(f'{sep}outparams)\n') | |
| 56 generated.swig_python.write(f' return ') | |
| 57 sep = '' | |
| 58 if not return_void: | |
| 59 generated.swig_python.write(f'ret') | |
| 60 sep = ', ' | |
| 61 for arg in parse.get_args( tu, cursor): | |
| 62 if arg.out_param: | |
| 63 generated.swig_python.write(f'{sep}outparams.{arg.name_python}') | |
| 64 sep = ', ' | |
| 65 generated.swig_python.write('\n') | |
| 66 generated.swig_python.write('\n') | |
| 67 | |
| 68 | |
| 69 def cppyy_add_outparams_wrapper( | |
| 70 tu, | |
| 71 fn_name, | |
| 72 fn_cursor, | |
| 73 state_, | |
| 74 generated, | |
| 75 ): | |
| 76 | |
| 77 parse.find_wrappable_function_with_arg0_type_cache_populate( tu) | |
| 78 | |
| 79 def get_ctype_name( arg): | |
| 80 type_name = state.get_name_canonical( arg.cursor.type.get_pointee()).spelling | |
| 81 if type_name in ( | |
| 82 'char', | |
| 83 'double', | |
| 84 'float', | |
| 85 'int', | |
| 86 'long', | |
| 87 'short', | |
| 88 ): | |
| 89 return f'ctypes.c_{type_name}' | |
| 90 elif type_name == 'unsigned long': return 'ctypes.c_ulong' | |
| 91 elif type_name == 'unsigned short': return 'ctypes.c_ushort' | |
| 92 elif type_name == 'unsigned int': return 'ctypes.c_uint' | |
| 93 else: | |
| 94 return None | |
| 95 num_out_params = 0 | |
| 96 arg0 = None | |
| 97 for arg in parse.get_args( tu, fn_cursor): | |
| 98 if arg0 is None: | |
| 99 arg0 = arg | |
| 100 if arg.out_param: | |
| 101 if not get_ctype_name( arg): | |
| 102 #jlib.log( 'Not creating cppyy out-param wrapper for {fn_name}() because cannot handle {arg.cursor.type.spelling=}') | |
| 103 return | |
| 104 num_out_params += 1 | |
| 105 if num_out_params: | |
| 106 return_void = fn_cursor.result_type.spelling == 'void' | |
| 107 text = '' | |
| 108 text += f'# Patch mupdf.m{fn_name} to return out-params directly.\n' | |
| 109 text += f'mupdf_m{fn_name}_original = cppyy.gbl.mupdf.m{fn_name}\n' | |
| 110 text += f'def mupdf_m{fn_name}( ' | |
| 111 sep = '' | |
| 112 for arg in parse.get_args( tu, fn_cursor): | |
| 113 if arg.out_param: | |
| 114 pass | |
| 115 else: | |
| 116 text += f'{sep}{arg.name_python}' | |
| 117 sep = ', ' | |
| 118 text += f'):\n' | |
| 119 for arg in parse.get_args( tu, fn_cursor): | |
| 120 if arg.out_param: | |
| 121 ctype_name = get_ctype_name( arg) | |
| 122 text += f' {arg.name_python} = {ctype_name}()\n' | |
| 123 text += f' ret = mupdf_m{fn_name}_original( ' | |
| 124 sep = '' | |
| 125 for arg in parse.get_args( tu, fn_cursor): | |
| 126 if arg.out_param: | |
| 127 text += f'{sep}ctypes.pointer( {arg.name_python})' | |
| 128 else: | |
| 129 text += f'{sep}{arg.name_python}' | |
| 130 sep = ', ' | |
| 131 text += f')\n' | |
| 132 sep = ' ' | |
| 133 text += f' return' | |
| 134 if not return_void: | |
| 135 text += ' ret' | |
| 136 sep = ', ' | |
| 137 for arg in parse.get_args( tu, fn_cursor): | |
| 138 if arg.out_param: | |
| 139 text += f'{sep}{arg.name_python}.value' | |
| 140 sep = ', ' | |
| 141 text += f'\n' | |
| 142 text += f'cppyy.gbl.mupdf.m{fn_name} = mupdf_m{fn_name}\n' | |
| 143 | |
| 144 # Look for class method that will use mupdf.m<fn_name>. | |
| 145 #Generated | |
| 146 struct_name = parse.find_class_for_wrappable_function( fn_name) | |
| 147 if struct_name: | |
| 148 class_name = rename.class_( struct_name) | |
| 149 method_name = rename.method( struct_name, fn_name) | |
| 150 text += f'# Also patch Python version of {fn_name}() in class wrapper for {struct_name} method {class_name}::{method_name}()\n' | |
| 151 text += f'cppyy.gbl.mupdf.{class_name}.{method_name}_original = cppyy.gbl.mupdf.{class_name}.{method_name}\n' | |
| 152 text += f'cppyy.gbl.mupdf.{class_name}.{method_name} = mupdf_m{fn_name}\n' | |
| 153 else: | |
| 154 pass | |
| 155 #jlib.log( 'Not a method of a class: {fn_name=}') | |
| 156 | |
| 157 text += f'\n' | |
| 158 | |
| 159 generated.cppyy_extra += text | |
| 160 | |
| 161 if 0: | |
| 162 jlib.log( 'parse.fnname_to_method_structname [{len(parse.fnname_to_method_structname)}]:') | |
| 163 for fn_name, struct_name in parse.fnname_to_method_structname.items(): | |
| 164 jlib.log( ' {fn_name}: {struct_name}') |
