File: interface_gen.py

package info (click to toggle)
python-scipy 0.7.2%2Bdfsg1-1%2Bdeb6u1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze-lts
  • size: 28,572 kB
  • ctags: 36,183
  • sloc: cpp: 216,880; fortran: 76,016; python: 71,833; ansic: 62,118; makefile: 243; sh: 17
file content (169 lines) | stat: -rwxr-xr-x 6,925 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
165
166
167
168
169
## Automatically adapted for scipy Oct 18, 2005 by

#!/usr/bin/env python

import os
import sys

if sys.version[:3]>='2.3':
    import re
else:
    import pre as re
from distutils.dir_util import mkpath

def all_subroutines(interface_in):
    # remove comments
    comment_block_exp = re.compile(r'/\*(?:\s|.)*?\*/')
    subroutine_exp = re.compile(r'subroutine (?:\s|.)*?end subroutine.*')
    function_exp = re.compile(r'function (?:\s|.)*?end function.*')

    interface = comment_block_exp.sub('',interface_in)
    subroutine_list = subroutine_exp.findall(interface)
    function_list = function_exp.findall(interface)
    subroutine_list = subroutine_list + function_list
    subroutine_list = map(lambda x: x.strip(),subroutine_list)
    return subroutine_list

def real_convert(val_string):
    return val_string

def complex_convert(val_string):
    return '(' + val_string + ',0.)'

def convert_types(interface_in,converter):
    regexp = re.compile(r'<type_convert=(.*?)>')
    interface = interface_in[:]
    while 1:
        sub = regexp.search(interface)
        if sub is None: break
        converted = converter(sub.group(1))
        interface = interface.replace(sub.group(),converted)
    return interface

def generic_expand(generic_interface,skip_names=[]):
    generic_types ={'s' :('real',            'real', real_convert,
                          'real'),
                    'd' :('double precision','double precision',real_convert,
                          'double precision'),
                    'c' :('complex',         'complex',complex_convert,
                          'real'),
                    'z' :('double complex',  'double complex',complex_convert,
                          'double precision'),
                    'cs':('complex',         'real',complex_convert,
                          'real'),
                    'zd':('double complex',  'double precision',complex_convert,
                          'double precision'),
                    'sc':('real',            'complex',real_convert,
                          'real'),
                    'dz':('double precision','double complex', real_convert,
                          'double precision')}
    generic_c_types = {'real':'float',
                       'double precision':'double',
                       'complex':'complex_float',
                       'double complex':'complex_double'}
    # cc_types is specific in ATLAS C BLAS, in particular, for complex arguments
    generic_cc_types = {'real':'float',
                       'double precision':'double',
                       'complex':'void',
                       'double complex':'void'}
    #2. get all subroutines
    subs = all_subroutines(generic_interface)
    print len(subs)
    #loop through the subs
    type_exp = re.compile(r'<tchar=(.*?)>')
    TYPE_EXP = re.compile(r'<TCHAR=(.*?)>')
    routine_name = re.compile(r'(subroutine|function)\s*(?P<name>\w+)\s*\(')
    interface = ''
    for sub in subs:
        #3. Find the typecodes to use:
        m = type_exp.search(sub)
        if m is None:
            interface = interface + '\n\n' + sub
            continue
        type_chars = m.group(1)
        # get rid of spaces
        type_chars = type_chars.replace(' ','')
        # get a list of the characters (or character pairs)
        type_chars = type_chars.split(',')
        # Now get rid of the special tag that contained the types
        sub = re.sub(type_exp,'<tchar>',sub)
        m = TYPE_EXP.search(sub)
        if m is not None:
            sub = re.sub(TYPE_EXP,'<TCHAR>',sub)
        sub_generic = sub.strip()
        for char in type_chars:
            type_in,type_out,converter, rtype_in = generic_types[char]
            sub = convert_types(sub_generic,converter)
            function_def = sub.replace('<tchar>',char)
            function_def = function_def.replace('<TCHAR>',char.upper())
            function_def = function_def.replace('<type_in>',type_in)
            function_def = function_def.replace('<type_in_c>',
                                          generic_c_types[type_in])
            function_def = function_def.replace('<type_in_cc>',
                                          generic_cc_types[type_in])
            function_def = function_def.replace('<rtype_in>',rtype_in)
            function_def = function_def.replace('<rtype_in_c>',
                                          generic_c_types[rtype_in])
            function_def = function_def.replace('<type_out>',type_out)
            function_def = function_def.replace('<type_out_c>',
                                          generic_c_types[type_out])
            m = routine_name.match(function_def)
            if m:
                if m.group('name') in skip_names:
                    print 'Skipping',m.group('name')
                    continue
            else:
                print 'Possible bug: Failed to determine routines name'
            interface = interface + '\n\n' + function_def

    return interface

#def interface_to_module(interface_in,module_name,include_list,sdir='.'):
def interface_to_module(interface_in,module_name):
    pre_prefix = "!%f90 -*- f90 -*-\n"
    # heading and tail of the module definition.
    file_prefix = "\npython module " + module_name +" ! in\n" \
                  "!usercode '''#include \"cblas.h\"\n"\
                  "!'''\n"\
                  "    interface  \n"
    file_suffix = "\n    end interface\n" \
             "end module %s" % module_name
    return  pre_prefix + file_prefix + interface_in + file_suffix

def process_includes(interface_in,sdir='.'):
    include_exp = re.compile(r'\n\s*[^!]\s*<include_file=(.*?)>')
    include_files = include_exp.findall(interface_in)
    for filename in include_files:
        f = open(os.path.join(sdir,filename))
        interface_in = interface_in.replace('<include_file=%s>'%filename,
                                      f.read())
        f.close()
    return interface_in

def generate_interface(module_name,src_file,target_file,skip_names=[]):
    print "generating",module_name,"interface"
    f = open(src_file)
    generic_interface = f.read()
    f.close()
    sdir = os.path.dirname(src_file)
    generic_interface = process_includes(generic_interface,sdir)
    generic_interface = generic_expand(generic_interface,skip_names)
    module_def = interface_to_module(generic_interface,module_name)
    mkpath(os.path.dirname(target_file))
    f = open(target_file,'w')
    user_routines = os.path.join(sdir,module_name+"_user_routines.pyf")
    if os.path.exists(user_routines):
        f2 = open(user_routines)
        f.write(f2.read())
        f2.close()
    f.write(module_def)
    f.close()

def process_all():
    # process the standard files.
    for name in ['fblas','cblas','clapack','flapack']:
        generate_interface(name,'generic_%s.pyf'%(name),name+'.pyf')


if __name__ == "__main__":
    process_all()