Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 163 lines (148 sloc) 6.805 kB
#!/usr/bin/env python
import os
import 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()
Jump to Line
Something went wrong with that request. Please try again.