File: python.py

package info (click to toggle)
mupdf 1.27.0%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 29,224 kB
  • sloc: ansic: 335,320; python: 20,906; java: 7,520; javascript: 2,213; makefile: 1,152; xml: 675; cpp: 639; sh: 513; cs: 307; awk: 10; sed: 7; lisp: 3
file content (164 lines) | stat: -rw-r--r-- 5,800 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
'''
Things for generating Python-specific output.
'''

import jlib

from . import cpp
from . import parse
from . import rename
from . import state
from . import util


def make_outparam_helper_python(
        tu,
        cursor,
        fnname,
        fnname_wrapper,
        generated,
        main_name,
        ):
    # Write python wrapper.
    return_void = cursor.result_type.spelling == 'void'
    generated.swig_python.write('')
    generated.swig_python.write(f'def {main_name}(')
    sep = ''
    for arg in parse.get_args( tu, cursor):
        if arg.out_param:
            continue
        generated.swig_python.write(f'{sep}{arg.name_python}')
        sep = ', '
    generated.swig_python.write('):\n')
    generated.swig_python.write(f'    """\n')
    generated.swig_python.write(f'    Wrapper for out-params of {cursor.spelling}().\n')
    sep = ''
    generated.swig_python.write(f'    Returns: ')
    sep = ''
    if not return_void:
        generated.swig_python.write( f'{cursor.result_type.spelling}')
        sep = ', '
    for arg in parse.get_args( tu, cursor):
        if arg.out_param:
            generated.swig_python.write(f'{sep}{cpp.declaration_text(arg.cursor.type.get_pointee(), arg.name_python)}')
            sep = ', '
    generated.swig_python.write(f'\n')
    generated.swig_python.write(f'    """\n')
    generated.swig_python.write(f'    outparams = {main_name}_outparams()\n')
    generated.swig_python.write(f'    ret = {main_name}_outparams_fn(')
    sep = ''
    for arg in parse.get_args( tu, cursor):
        if arg.out_param:
            continue
        generated.swig_python.write(f'{sep}{arg.name_python}')
        sep = ', '
    generated.swig_python.write(f'{sep}outparams)\n')
    generated.swig_python.write(f'    return ')
    sep = ''
    if not return_void:
        generated.swig_python.write(f'ret')
        sep = ', '
    for arg in parse.get_args( tu, cursor):
        if arg.out_param:
            generated.swig_python.write(f'{sep}outparams.{arg.name_python}')
            sep = ', '
    generated.swig_python.write('\n')
    generated.swig_python.write('\n')


def cppyy_add_outparams_wrapper(
        tu,
        fn_name,
        fn_cursor,
        state_,
        generated,
        ):

    parse.find_wrappable_function_with_arg0_type_cache_populate( tu)

    def get_ctype_name( arg):
        type_name = state.get_name_canonical( arg.cursor.type.get_pointee()).spelling
        if type_name in (
                'char',
                'double',
                'float',
                'int',
                'long',
                'short',
                ):
            return f'ctypes.c_{type_name}'
        elif type_name == 'unsigned long':  return 'ctypes.c_ulong'
        elif type_name == 'unsigned short': return 'ctypes.c_ushort'
        elif type_name == 'unsigned int':   return 'ctypes.c_uint'
        else:
            return None
    num_out_params = 0
    arg0 = None
    for arg in parse.get_args( tu, fn_cursor):
        if arg0 is None:
            arg0 = arg
        if arg.out_param:
            if not get_ctype_name( arg):
                #jlib.log( 'Not creating cppyy out-param wrapper for {fn_name}() because cannot handle {arg.cursor.type.spelling=}')
                return
            num_out_params += 1
    if num_out_params:
        return_void = fn_cursor.result_type.spelling == 'void'
        text = ''
        text += f'# Patch mupdf.m{fn_name} to return out-params directly.\n'
        text += f'mupdf_m{fn_name}_original = cppyy.gbl.mupdf.m{fn_name}\n'
        text += f'def mupdf_m{fn_name}( '
        sep = ''
        for arg in parse.get_args( tu, fn_cursor):
            if arg.out_param:
                pass
            else:
                text += f'{sep}{arg.name_python}'
                sep = ', '
        text += f'):\n'
        for arg in parse.get_args( tu, fn_cursor):
            if arg.out_param:
                ctype_name = get_ctype_name( arg)
                text += f'    {arg.name_python} = {ctype_name}()\n'
        text += f'    ret = mupdf_m{fn_name}_original( '
        sep = ''
        for arg in parse.get_args( tu, fn_cursor):
            if arg.out_param:
                text += f'{sep}ctypes.pointer( {arg.name_python})'
            else:
                text += f'{sep}{arg.name_python}'
            sep = ', '
        text += f')\n'
        sep = ' '
        text += f'    return'
        if not return_void:
            text += ' ret'
            sep = ', '
        for arg in parse.get_args( tu, fn_cursor):
            if arg.out_param:
                text += f'{sep}{arg.name_python}.value'
                sep = ', '
        text += f'\n'
        text += f'cppyy.gbl.mupdf.m{fn_name} = mupdf_m{fn_name}\n'

        # Look for class method that will use mupdf.m<fn_name>.
        #Generated
        struct_name = parse.find_class_for_wrappable_function( fn_name)
        if struct_name:
            class_name = rename.class_( struct_name)
            method_name = rename.method( struct_name, fn_name)
            text += f'# Also patch Python version of {fn_name}() in class wrapper for {struct_name} method {class_name}::{method_name}()\n'
            text += f'cppyy.gbl.mupdf.{class_name}.{method_name}_original = cppyy.gbl.mupdf.{class_name}.{method_name}\n'
            text += f'cppyy.gbl.mupdf.{class_name}.{method_name} = mupdf_m{fn_name}\n'
        else:
            pass
            #jlib.log( 'Not a method of a class: {fn_name=}')

        text += f'\n'

        generated.cppyy_extra += text

    if 0:
        jlib.log( 'parse.fnname_to_method_structname [{len(parse.fnname_to_method_structname)}]:')
        for fn_name, struct_name in parse.fnname_to_method_structname.items():
            jlib.log( '    {fn_name}: {struct_name}')