summaryrefslogtreecommitdiff
path: root/numpy/f2py/f2py2e.py
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2006-01-04 17:26:31 +0000
committerTravis Oliphant <oliphant@enthought.com>2006-01-04 17:26:31 +0000
commit8e2654541c6eae0f308908f501cccbc86b2f9101 (patch)
treebfcfe3b282c8fb659832bf86a841ce76852094ad /numpy/f2py/f2py2e.py
parentddaed649c23bbd0ad36cdafdfe9cd92397ce69e3 (diff)
downloadnumpy-8e2654541c6eae0f308908f501cccbc86b2f9101.tar.gz
Moved scipy directory to numpy
Diffstat (limited to 'numpy/f2py/f2py2e.py')
-rwxr-xr-xnumpy/f2py/f2py2e.py555
1 files changed, 555 insertions, 0 deletions
diff --git a/numpy/f2py/f2py2e.py b/numpy/f2py/f2py2e.py
new file mode 100755
index 000000000..6230590d1
--- /dev/null
+++ b/numpy/f2py/f2py2e.py
@@ -0,0 +1,555 @@
+#!/usr/bin/env python
+"""
+
+f2py2e - Fortran to Python C/API generator. 2nd Edition.
+ See __usage__ below.
+
+Copyright 1999--2005 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@cens.ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the LGPL. See http://www.fsf.org
+
+NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+$Date: 2005/05/06 08:31:19 $
+Pearu Peterson
+"""
+__version__ = "$Revision: 1.90 $"[10:-1]
+
+import __version__
+f2py_version = __version__.version
+
+import sys,os,string,pprint,shutil,types,re
+errmess=sys.stderr.write
+#outmess=sys.stdout.write
+show=pprint.pprint
+
+import crackfortran
+import rules
+import cb_rules
+import common_rules
+import auxfuncs
+import cfuncs
+import capi_maps
+import func2subr
+import f90mod_rules
+
+outmess = auxfuncs.outmess
+
+try:
+ from scipy import __core_version__ as scipy_core_version
+except ImportError:
+ scipy_distutils_version = 'N/A'
+
+__usage__ = """\
+Usage:
+
+1) To construct extension module sources:
+
+ f2py [<options>] <fortran files> [[[only:]||[skip:]] \\
+ <fortran functions> ] \\
+ [: <fortran files> ...]
+
+2) To compile fortran files and build extension modules:
+
+ f2py -c [<options>, <build_flib options>, <extra options>] <fortran files>
+
+3) To generate signature files:
+
+ f2py -h <filename.pyf> ...< same options as in (1) >
+
+Description: This program generates a Python C/API file (<modulename>module.c)
+ that contains wrappers for given fortran functions so that they
+ can be called from Python. With the -c option the corresponding
+ extension modules are built.
+
+Options:
+
+ -h <filename> Write signatures of the fortran routines to file <filename>
+ and exit. You can then edit <filename> and use it instead
+ of <fortran files>. If <filename>==stdout then the
+ signatures are printed to stdout.
+ <fortran functions> Names of fortran routines for which Python C/API
+ functions will be generated. Default is all that are found
+ in <fortran files>.
+ <fortran files> Paths to fortran/signature files that will be scanned for
+ <fortran functions> in order to determine their signatures.
+ skip: Ignore fortran functions that follow until `:'.
+ only: Use only fortran functions that follow until `:'.
+ : Get back to <fortran files> mode.
+
+ -m <modulename> Name of the module; f2py generates a Python/C API
+ file <modulename>module.c or extension module <modulename>.
+ Default is 'untitled'.
+
+ --[no-]lower Do [not] lower the cases in <fortran files>. By default,
+ --lower is assumed with -h key, and --no-lower without -h key.
+
+ --build-dir <dirname> All f2py generated files are created in <dirname>.
+ Default is tempfile.mktemp().
+
+ --overwrite-signature Overwrite existing signature file.
+
+ --[no-]latex-doc Create (or not) <modulename>module.tex.
+ Default is --no-latex-doc.
+ --short-latex Create 'incomplete' LaTeX document (without commands
+ \\documentclass, \\tableofcontents, and \\begin{document},
+ \\end{document}).
+
+ --[no-]rest-doc Create (or not) <modulename>module.rst.
+ Default is --no-rest-doc.
+
+ --debug-capi Create C/API code that reports the state of the wrappers
+ during runtime. Useful for debugging.
+
+ --[no-]wrap-functions Create Fortran subroutine wrappers to Fortran 77
+ functions. --wrap-functions is default because it ensures
+ maximum portability/compiler independence.
+
+ --include_paths <path1>:<path2>:... Search include files from the given
+ directories.
+
+ --help-link [..] List system resources found by system_info.py. See also
+ --link-<resource> switch below. [..] is optional list
+ of resources names. E.g. try 'f2py --help-link lapack_opt'.
+
+ --quiet Run quietly.
+ --verbose Run with extra verbosity.
+ -v Print f2py version ID and exit.
+
+
+scipy.distutils options (only effective with -c):
+
+ --fcompiler= Specify Fortran compiler type by vendor
+ --compiler= Specify C compiler type (as defined by distutils)
+
+ --help-fcompiler List available Fortran compilers and exit
+ --f77exec= Specify the path to F77 compiler
+ --f90exec= Specify the path to F90 compiler
+ --f77flags= Specify F77 compiler flags
+ --f90flags= Specify F90 compiler flags
+ --opt= Specify optimization flags
+ --arch= Specify architecture specific optimization flags
+ --noopt Compile without optimization
+ --noarch Compile without arch-dependent optimization
+ --debug Compile with debugging information
+
+Extra options (only effective with -c):
+
+ --link-<resource> Link extension module with <resource> as defined
+ by scipy.distutils/system_info.py. E.g. to link
+ with optimized LAPACK libraries (vecLib on MacOSX,
+ ATLAS elsewhere), use --link-lapack_opt.
+ See also --help-link switch.
+
+ -L/path/to/lib/ -l<libname>
+ -D<define> -U<name>
+ -I/path/to/include/
+ <filename>.o <filename>.so <filename>.a
+
+ Using the following macros may be required with non-gcc Fortran
+ compilers:
+ -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN
+ -DUNDERSCORE_G77
+
+ When using -DF2PY_REPORT_ATEXIT, a performance report of F2PY
+ interface is printed out at exit (platforms: Linux).
+
+ When using -DF2PY_REPORT_ON_ARRAY_COPY=<int>, a message is
+ sent to stderr whenever F2PY interface makes a copy of an
+ array. Integer <int> sets the threshold for array sizes when
+ a message should be shown.
+
+Version: %s
+scipy_core Version: %s
+Requires: Python 2.3 or higher.
+License: LGPL (see http://www.fsf.org)
+Copyright 1999 - 2005 Pearu Peterson all rights reserved.
+http://cens.ioc.ee/projects/f2py2e/"""%(f2py_version, scipy_core_version)
+
+
+def scaninputline(inputline):
+ files,funcs,skipfuncs,onlyfuncs,debug=[],[],[],[],[]
+ f,f2,f3,f4,f5,f6,f7=1,0,0,0,0,0,0
+ verbose = 1
+ dolc=-1
+ dolatexdoc = 0
+ dorestdoc = 0
+ wrapfuncs = 1
+ buildpath = '.'
+ include_paths = []
+ signsfile,modulename=None,None
+ options = {'buildpath':buildpath}
+ for l in inputline:
+ if l=='': pass
+ elif l=='only:': f=0
+ elif l=='skip:': f=-1
+ elif l==':': f=1;f4=0
+ elif l[:8]=='--debug-': debug.append(l[8:])
+ elif l=='--lower': dolc=1
+ elif l=='--build-dir': f6=1
+ elif l=='--no-lower': dolc=0
+ elif l=='--quiet': verbose = 0
+ elif l=='--verbose': verbose += 1
+ elif l=='--latex-doc': dolatexdoc=1
+ elif l=='--no-latex-doc': dolatexdoc=0
+ elif l=='--rest-doc': dorestdoc=1
+ elif l=='--no-rest-doc': dorestdoc=0
+ elif l=='--wrap-functions': wrapfuncs=1
+ elif l=='--no-wrap-functions': wrapfuncs=0
+ elif l=='--short-latex': options['shortlatex']=1
+ elif l=='--overwrite-signature': options['h-overwrite']=1
+ elif l=='-h': f2=1
+ elif l=='-m': f3=1
+ elif l[:2]=='-v':
+ print f2py_version
+ sys.exit()
+ elif l=='--show-compilers':
+ f5=1
+ elif l[:8]=='-include':
+ cfuncs.outneeds['userincludes'].append(l[9:-1])
+ cfuncs.userincludes[l[9:-1]]='#include '+l[8:]
+ elif l[:15]=='--include_paths':
+ f7=1
+ elif l[0]=='-':
+ errmess('Unknown option %s\n'%`l`)
+ sys.exit()
+ elif f2: f2=0;signsfile=l
+ elif f3: f3=0;modulename=l
+ elif f6: f6=0;buildpath=l
+ elif f7: f7=0;include_paths.extend(l.split(os.pathsep))
+ elif f==1:
+ try:
+ open(l).close()
+ files.append(l)
+ except IOError,detail:
+ errmess('IOError: %s. Skipping file "%s".\n'%(str(detail),l))
+ elif f==-1: skipfuncs.append(l)
+ elif f==0: onlyfuncs.append(l)
+ if not f5 and not files and not modulename:
+ print __usage__
+ sys.exit()
+ if not os.path.isdir(buildpath):
+ if not verbose:
+ outmess('Creating build directory %s'%(buildpath))
+ os.mkdir(buildpath)
+ if signsfile:
+ signsfile = os.path.join(buildpath,signsfile)
+ if signsfile and os.path.isfile(signsfile) and not options.has_key('h-overwrite'):
+ errmess('Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n'%(signsfile))
+ sys.exit()
+
+ options['debug']=debug
+ options['verbose']=verbose
+ if dolc==-1 and not signsfile: options['do-lower']=0
+ else: options['do-lower']=dolc
+ if modulename: options['module']=modulename
+ if signsfile: options['signsfile']=signsfile
+ if onlyfuncs: options['onlyfuncs']=onlyfuncs
+ if skipfuncs: options['skipfuncs']=skipfuncs
+ options['dolatexdoc'] = dolatexdoc
+ options['dorestdoc'] = dorestdoc
+ options['wrapfuncs'] = wrapfuncs
+ options['buildpath']=buildpath
+ options['include_paths']=include_paths
+ return files,options
+
+def callcrackfortran(files,options):
+ rules.options=options
+ funcs=[]
+ crackfortran.debug=options['debug']
+ crackfortran.verbose=options['verbose']
+ if options.has_key('module'):
+ crackfortran.f77modulename=options['module']
+ if options.has_key('skipfuncs'):
+ crackfortran.skipfuncs=options['skipfuncs']
+ if options.has_key('onlyfuncs'):
+ crackfortran.onlyfuncs=options['onlyfuncs']
+ crackfortran.include_paths[:]=options['include_paths']
+ crackfortran.dolowercase=options['do-lower']
+ postlist=crackfortran.crackfortran(files)
+ if options.has_key('signsfile'):
+ outmess('Saving signatures to file "%s"\n'%(options['signsfile']))
+ pyf=crackfortran.crack2fortran(postlist)
+ if options['signsfile'][-6:]=='stdout':
+ sys.stdout.write(pyf)
+ else:
+ f=open(options['signsfile'],'w')
+ f.write(pyf)
+ f.close()
+ return postlist
+
+def buildmodules(list):
+ cfuncs.buildcfuncs()
+ outmess('Building modules...\n')
+ modules,mnames,isusedby=[],[],{}
+ for i in range(len(list)):
+ if string.find(list[i]['name'],'__user__')>=0:
+ cb_rules.buildcallbacks(list[i])
+ else:
+ if list[i].has_key('use'):
+ for u in list[i]['use'].keys():
+ if not isusedby.has_key(u): isusedby[u]=[]
+ isusedby[u].append(list[i]['name'])
+ modules.append(list[i])
+ mnames.append(list[i]['name'])
+ ret = {}
+ for i in range(len(mnames)):
+ if isusedby.has_key(mnames[i]):
+ outmess('\tSkipping module "%s" which is used by %s.\n'%(mnames[i],string.join(map(lambda s:'"%s"'%s,isusedby[mnames[i]]),',')))
+ else:
+ um=[]
+ if modules[i].has_key('use'):
+ for u in modules[i]['use'].keys():
+ if isusedby.has_key(u) and u in mnames:
+ um.append(modules[mnames.index(u)])
+ else:
+ outmess('\tModule "%s" uses nonexisting "%s" which will be ignored.\n'%(mnames[i],u))
+ ret[mnames[i]] = {}
+ dict_append(ret[mnames[i]],rules.buildmodule(modules[i],um))
+ return ret
+
+def dict_append(d_out,d_in):
+ for (k,v) in d_in.items():
+ if not d_out.has_key(k):
+ d_out[k] = []
+ if type(v) is types.ListType:
+ d_out[k] = d_out[k] + v
+ else:
+ d_out[k].append(v)
+
+def run_main(comline_list):
+ """Run f2py as if string.join(comline_list,' ') is used as a command line.
+ In case of using -h flag, return None.
+ """
+ reload(crackfortran)
+ f2pydir=os.path.dirname(os.path.abspath(cfuncs.__file__))
+ fobjhsrc = os.path.join(f2pydir,'src','fortranobject.h')
+ fobjcsrc = os.path.join(f2pydir,'src','fortranobject.c')
+ files,options=scaninputline(comline_list)
+ auxfuncs.options=options
+ postlist=callcrackfortran(files,options)
+ isusedby={}
+ for i in range(len(postlist)):
+ if postlist[i].has_key('use'):
+ for u in postlist[i]['use'].keys():
+ if not isusedby.has_key(u): isusedby[u]=[]
+ isusedby[u].append(postlist[i]['name'])
+ for i in range(len(postlist)):
+ if postlist[i]['block']=='python module' and string.find(postlist[i]['name'],'__user__')<0:
+ if isusedby.has_key(postlist[i]['name']):
+ #if not quiet:
+ outmess('Skipping Makefile build for module "%s" which is used by %s\n'%(postlist[i]['name'],string.join(map(lambda s:'"%s"'%s,isusedby[postlist[i]['name']]),',')))
+ if options.has_key('signsfile'):
+ if options['verbose']>1:
+ outmess('Stopping. Edit the signature file and then run f2py on the signature file: ')
+ outmess('%s %s\n'%(os.path.basename(sys.argv[0]),options['signsfile']))
+ return
+ for i in range(len(postlist)):
+ if postlist[i]['block']!='python module':
+ if not options.has_key('python module'):
+ errmess('Tip: If your original code is Fortran 77 then you must use -m option.\n')
+ raise TypeError,'All blocks must be module blocks but got %s'%(`postlist[i]['block']`)
+ auxfuncs.debugoptions=options['debug']
+ f90mod_rules.options=options
+ auxfuncs.wrapfuncs=options['wrapfuncs']
+
+ ret=buildmodules(postlist)
+
+ for mn in ret.keys():
+ dict_append(ret[mn],{'csrc':fobjcsrc,'h':fobjhsrc})
+ return ret
+
+def filter_files(prefix,suffix,files,remove_prefix=None):
+ """
+ Filter files by prefix and suffix.
+ """
+ filtered,rest = [],[]
+ match = re.compile(prefix+r'.*'+suffix+r'\Z').match
+ if remove_prefix:
+ ind = len(prefix)
+ else:
+ ind = 0
+ for file in map(string.strip,files):
+ if match(file): filtered.append(file[ind:])
+ else: rest.append(file)
+ return filtered,rest
+
+def get_prefix(module):
+ p = os.path.dirname(os.path.dirname(module.__file__))
+ return p
+
+def run_compile():
+ """
+ Do it all in one call!
+ """
+ import tempfile,os,shutil
+
+ i = sys.argv.index('-c')
+ del sys.argv[i]
+
+ remove_build_dir = 0
+ try: i = sys.argv.index('--build-dir')
+ except ValueError: i=None
+ if i is not None:
+ build_dir = sys.argv[i+1]
+ del sys.argv[i+1]
+ del sys.argv[i]
+ else:
+ remove_build_dir = 1
+ build_dir = os.path.join(tempfile.mktemp())
+
+ sysinfo_flags = filter(re.compile(r'[-][-]link[-]').match,sys.argv[1:])
+ sys.argv = filter(lambda a,flags=sysinfo_flags:a not in flags,sys.argv)
+ if sysinfo_flags:
+ sysinfo_flags = [f[7:] for f in sysinfo_flags]
+
+ f2py_flags = filter(re.compile(r'[-][-]((no[-]|)(wrap[-]functions|lower)|debug[-]capi|quiet)|[-]include').match,sys.argv[1:])
+ sys.argv = filter(lambda a,flags=f2py_flags:a not in flags,sys.argv)
+ f2py_flags2 = []
+ fl = 0
+ for a in sys.argv[1:]:
+ if a in ['only:','skip:']:
+ fl = 1
+ elif a==':':
+ fl = 0
+ if fl or a==':':
+ f2py_flags2.append(a)
+ if f2py_flags2 and f2py_flags2[-1]!=':':
+ f2py_flags2.append(':')
+ f2py_flags.extend(f2py_flags2)
+
+ sys.argv = filter(lambda a,flags=f2py_flags2:a not in flags,sys.argv)
+
+ flib_flags = filter(re.compile(r'[-][-]((f(90)?compiler([-]exec|)|compiler)=|help[-]compiler)').match,sys.argv[1:])
+ sys.argv = filter(lambda a,flags=flib_flags:a not in flags,sys.argv)
+ fc_flags = filter(re.compile(r'[-][-]((f(77|90)(flags|exec)|opt|arch)=|(debug|noopt|noarch|help[-]fcompiler))').match,sys.argv[1:])
+ sys.argv = filter(lambda a,flags=fc_flags:a not in flags,sys.argv)
+
+ if 1:
+ del_list = []
+ for s in flib_flags:
+ v = '--fcompiler='
+ if s[:len(v)]==v:
+ from scipy.distutils import fcompiler
+ allowed_keys = fcompiler.fcompiler_class.keys()
+ nv = ov = s[len(v):].lower()
+ if ov not in allowed_keys:
+ vmap = {} # XXX
+ try:
+ nv = vmap[ov]
+ except KeyError:
+ if ov not in vmap.values():
+ print 'Unknown vendor: "%s"' % (s[len(v):])
+ nv = ov
+ i = flib_flags.index(s)
+ flib_flags[i] = '--fcompiler=' + nv
+ continue
+ for s in del_list:
+ i = flib_flags.index(s)
+ del flib_flags[i]
+ assert len(flib_flags)<=2,`flib_flags`
+ setup_flags = filter(re.compile(r'[-][-](verbose)').match,sys.argv[1:])
+ sys.argv = filter(lambda a,flags=setup_flags:a not in flags,sys.argv)
+ if '--quiet' in f2py_flags:
+ setup_flags.append('--quiet')
+
+ modulename = 'untitled'
+ sources = sys.argv[1:]
+ if '-m' in sys.argv:
+ i = sys.argv.index('-m')
+ modulename = sys.argv[i+1]
+ del sys.argv[i+1],sys.argv[i]
+ sources = sys.argv[1:]
+ else:
+ from scipy.distutils.command.build_src import get_f2py_modulename
+ pyf_files,sources = filter_files('','[.]pyf([.]src|)',sources)
+ sources = pyf_files + sources
+ for f in pyf_files:
+ modulename = get_f2py_modulename(f)
+ if modulename:
+ break
+
+ extra_objects, sources = filter_files('','[.](o|a|so)',sources)
+ include_dirs, sources = filter_files('-I','',sources,remove_prefix=1)
+ library_dirs, sources = filter_files('-L','',sources,remove_prefix=1)
+ libraries, sources = filter_files('-l','',sources,remove_prefix=1)
+ undef_macros, sources = filter_files('-U','',sources,remove_prefix=1)
+ define_macros, sources = filter_files('-D','',sources,remove_prefix=1)
+ using_numarray = 0
+ using_numeric = 0
+ for i in range(len(define_macros)):
+ name_value = string.split(define_macros[i],'=',1)
+ if len(name_value)==1:
+ name_value.append(None)
+ if len(name_value)==2:
+ define_macros[i] = tuple(name_value)
+ else:
+ print 'Invalid use of -D:',name_value
+
+ from scipy.distutils.system_info import get_info
+
+ num_include_dir = None
+ num_info = {}
+ #import scipy
+ #n = 'scipy'
+ #p = get_prefix(scipy)
+ #from scipy.distutils.misc_util import get_scipy_include_dirs
+ #num_info = {'include_dirs': get_scipy_include_dirs()}
+
+ if num_info:
+ include_dirs.extend(num_info.get('include_dirs',[]))
+
+ from scipy.distutils.core import setup,Extension
+ ext_args = {'name':modulename,'sources':sources,
+ 'include_dirs': include_dirs,
+ 'library_dirs': library_dirs,
+ 'libraries': libraries,
+ 'define_macros': define_macros,
+ 'undef_macros': undef_macros,
+ 'extra_objects': extra_objects,
+ 'f2py_options': f2py_flags,
+ }
+
+ if sysinfo_flags:
+ from scipy.distutils.misc_util import dict_append
+ for n in sysinfo_flags:
+ i = get_info(n)
+ if not i:
+ outmess('No %s resources found in system'\
+ ' (try `f2py --help-link`)\n' % (`n`))
+ dict_append(ext_args,**i)
+
+ ext = Extension(**ext_args)
+ sys.argv = [sys.argv[0]] + setup_flags
+ sys.argv.extend(['build',
+ '--build-temp',build_dir,
+ '--build-base',build_dir,
+ '--build-platlib','.'])
+ if fc_flags:
+ sys.argv.extend(['config_fc']+fc_flags)
+ if flib_flags:
+ sys.argv.extend(['build_ext']+flib_flags)
+
+ setup(ext_modules = [ext])
+
+ if remove_build_dir and os.path.exists(build_dir):
+ outmess('Removing build directory %s\n'%(build_dir))
+ shutil.rmtree(build_dir)
+
+def main():
+ if '--help-link' in sys.argv[1:]:
+ sys.argv.remove('--help-link')
+ from scipy.distutils.system_info import show_all
+ show_all()
+ return
+ if '-c' in sys.argv[1:]:
+ run_compile()
+ else:
+ run_main(sys.argv[1:])
+
+#if __name__ == "__main__":
+# main()
+
+
+# EOF
+