summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/f2py/lib/main.py165
-rw-r--r--numpy/f2py/lib/py_wrap.py2
-rw-r--r--numpy/f2py/lib/py_wrap_subprogram.py19
-rw-r--r--numpy/f2py/lib/py_wrap_type.py4
4 files changed, 115 insertions, 75 deletions
diff --git a/numpy/f2py/lib/main.py b/numpy/f2py/lib/main.py
index 076fbb9bd..d246196ba 100644
--- a/numpy/f2py/lib/main.py
+++ b/numpy/f2py/lib/main.py
@@ -221,13 +221,83 @@ def dump_signature(sys_argv):
output_stream.close()
return
-def build_extension(sys_argv):
+def construct_extension_sources(modulename, parse_files, include_dirs, build_dir):
+ """
+ Construct wrapper sources.
+ """
+ from py_wrap import PythonWrapperModule
+
+ f90_modules = []
+ external_subprograms = []
+ for filename in parse_files:
+ if not os.path.isfile(filename):
+ sys.stderr.write('No or not a file %r. Skipping.\n' % (filename))
+ continue
+ sys.stderr.write('Parsing %r..\n' % (filename))
+ for block in parse(filename, include_dirs=include_dirs).content:
+ if isinstance(block, Module):
+ f90_modules.append(block)
+ elif isinstance(block, (Subroutine, Function)):
+ external_subprograms.append(block)
+ else:
+ sys.stderr.write("Unhandled structure: %r\n" % (block.__class__))
+
+ module_infos = []
+
+ for block in f90_modules:
+ wrapper = PythonWrapperModule(block.name)
+ wrapper.add(block)
+ c_code = wrapper.c_code()
+ f_code = '! -*- f90 -*-\n' + wrapper.fortran_code()
+ c_fn = os.path.join(build_dir,'%smodule.c' % (block.name))
+ f_fn = os.path.join(build_dir,'%s_f_wrappers_f2py.f90' % (block.name))
+ f = open(c_fn,'w')
+ f.write(c_code)
+ f.close()
+ f = open(f_fn,'w')
+ f.write(f_code)
+ f.close()
+ f_lib = '%s_f_wrappers_f2py' % (block.name)
+ module_info = {'name':block.name, 'c_sources':[c_fn],
+ 'f_sources':[f_fn], 'language':'f90'}
+ module_infos.append(module_info)
+
+ if external_subprograms:
+ wrapper = PythonWrapperModule(modulename)
+ for block in external_subprograms:
+ wrapper.add(block)
+ c_code = wrapper.c_code()
+ f_code = wrapper.fortran_code()
+ c_fn = os.path.join(build_dir,'%smodule.c' % (modulename))
+ ext = '.f'
+ language = 'f77'
+ if wrapper.isf90:
+ f_code = '! -*- f90 -*-\n' + f_code
+ ext = '.f90'
+ language = 'f90'
+ f_fn = os.path.join(build_dir,'%s_f_wrappers_f2py%s' % (modulename, ext))
+ f = open(c_fn,'w')
+ f.write(c_code)
+ f.close()
+ f = open(f_fn,'w')
+ f.write(f_code)
+ f.close()
+ module_info = {'name':modulename, 'c_sources':[c_fn],
+ 'f_sources':[f_fn], 'language':language}
+ module_infos.append(module_info)
+
+ return module_infos
+
+def build_extension(sys_argv, sources_only = False):
"""
Build wrappers to Fortran 90 modules and external subprograms.
"""
modulename = get_option_value(sys_argv,'-m','untitled','unspecified')
- build_dir = get_option_value(sys_argv,'--build-dir','.',None)
+ if sources_only:
+ build_dir = get_option_value(sys_argv,'--build-dir','.','')
+ else:
+ build_dir = get_option_value(sys_argv,'--build-dir','.',None)
if build_dir is None:
build_dir = tempfile.mktemp()
clean_build_dir = True
@@ -267,23 +337,11 @@ def build_extension(sys_argv):
else:
parse_files = fortran_files + c_files
- f90_modules = []
- external_subprograms = []
+ module_infos = construct_extension_sources(modulename, parse_files, include_dirs, build_dir)
- for filename in parse_files:
- if not os.path.isfile(filename):
- sys.stderr.write('No or not a file %r. Skipping.\n' % (filename))
- continue
- sys.stderr.write('Parsing %r..\n' % (filename))
- for block in parse(filename, include_dirs=include_dirs).content:
- if isinstance(block, Module):
- f90_modules.append(block)
- elif isinstance(block, (Subroutine, Function)):
- external_subprograms.append(block)
- else:
- sys.stderr.write("Unhandled structure: %r\n" % (block.__class__))
+ if sources_only:
+ return
- from py_wrap import PythonWrapperModule
def configuration(parent_package='', top_path=None):
from numpy.distutils.misc_util import Configuration
config = Configuration('',parent_package,top_path)
@@ -293,62 +351,25 @@ def build_extension(sys_argv):
sources = fortran_files)
libraries.insert(0,flibname)
- for block in f90_modules:
- wrapper = PythonWrapperModule(block.name)
- wrapper.add(block)
- c_code = wrapper.c_code()
- f_code = '! -*- f90 -*-\n' + wrapper.fortran_code()
- c_fn = os.path.join(build_dir,'%smodule.c' % (block.name))
- f_fn = os.path.join(build_dir,'%s_f_wrappers_f2py.f90' % (block.name))
- f = open(c_fn,'w')
- f.write(c_code)
- f.close()
- f = open(f_fn,'w')
- f.write(f_code)
- f.close()
- f_lib = '%s_f_wrappers_f2py' % (block.name)
- config.add_library(f_lib,
- sources = [f_fn])
- config.add_extension(block.name,
- sources=[c_fn] + c_files,
- libraries = [f_lib] + libraries,
- define_macros = define_macros,
- undef_macros = undef_macros,
- include_dirs = include_dirs,
- extra_objects = extra_objects,
- language = 'f90',
- )
- if external_subprograms:
- wrapper = PythonWrapperModule(modulename)
- for block in external_subprograms:
- wrapper.add(block)
- c_code = wrapper.c_code()
- f_code = wrapper.fortran_code()
- c_fn = os.path.join(build_dir,'%smodule.c' % (modulename))
- ext = '.f'
- language = 'f77'
- if wrapper.isf90:
- f_code = '! -*- f90 -*-\n' + f_code
- ext = '.f90'
- language = 'f90'
- f_fn = os.path.join(build_dir,'%s_f_wrappers_f2py%s' % (modulename, ext))
- f = open(c_fn,'w')
- f.write(c_code)
- f.close()
- f = open(f_fn,'w')
- f.write(f_code)
- f.close()
- f_lib = '%s_f_wrappers_f2py' % (modulename)
- config.add_library(f_lib,
- sources = [f_fn])
- config.add_extension(modulename,
- sources=[c_fn] + c_files,
- libraries = [f_lib] + libraries,
+ for module_info in module_infos:
+ name = module_info['name']
+ c_sources = module_info['c_sources']
+ f_sources = module_info['f_sources']
+ language = module_info['language']
+ if f_sources:
+ f_lib = '%s_f_wrappers_f2py' % (name)
+ config.add_library(f_lib, sources = f_sources)
+ libs = [f_lib] + libraries
+ else:
+ libs = libraries
+ config.add_extension(name,
+ sources=c_sources + c_files,
+ libraries = libs,
define_macros = define_macros,
undef_macros = undef_macros,
include_dirs = include_dirs,
extra_objects = extra_objects,
- language = language
+ language = language,
)
return config
@@ -390,4 +411,8 @@ def main(sys_argv = None):
if '-h' in sys_argv:
dump_signature(sys_argv)
return
- print >> sys.stdout, __usage__
+ if not sys_argv or '--help' in sys_argv:
+ print >> sys.stdout, __usage__
+
+ build_extension(sys_argv, sources_only = True)
+ return
diff --git a/numpy/f2py/lib/py_wrap.py b/numpy/f2py/lib/py_wrap.py
index b35e4452c..e8734ec08 100644
--- a/numpy/f2py/lib/py_wrap.py
+++ b/numpy/f2py/lib/py_wrap.py
@@ -45,7 +45,7 @@ PyMODINIT_FUNC init%(modulename)s(void) {
import_array();
if (PyErr_Occurred()) {
PyErr_SetString(PyExc_ImportError, "failed to load array module.");
- return;
+ goto capi_err;
}
%(module_init_list)s
return;
diff --git a/numpy/f2py/lib/py_wrap_subprogram.py b/numpy/f2py/lib/py_wrap_subprogram.py
index 24bd07e1b..45ccad034 100644
--- a/numpy/f2py/lib/py_wrap_subprogram.py
+++ b/numpy/f2py/lib/py_wrap_subprogram.py
@@ -16,7 +16,7 @@ class PythonCAPISubProgram(WrapperBase):
#define %(name)s_f F_FUNC(%(name)s, %(NAME)s)
'''
extern_template_f77 = '''\
-extern void %(name)s_f();
+extern void %(name)s_f(%(ctype_args_f_clist)s);
'''
objdecl_template_doc = '''\
static char %(cname)s__doc[] = "";
@@ -54,10 +54,11 @@ static PyObject* %(cname)s(PyObject *capi_self, PyObject *capi_args, PyObject *c
#define %(init_func)s_f F_FUNC(%(init_func)s, %(INIT_FUNC)s)
'''
typedef_template_module = '''
-typedef void (*%(name)s_functype)();
+typedef void (*%(name)s_functype)(%(ctype_args_f_clist)s);
+typedef void (*%(init_func)s_c_functype)(%(name)s_functype);
'''
extern_template_module = '''\
-extern void %(init_func)s_f( %(name)s_functype);
+extern void %(init_func)s_f(%(init_func)s_c_functype);
static %(name)s_functype %(name)s_func_ptr;
'''
objdecl_template_module = '''
@@ -139,6 +140,8 @@ static void %(init_func)s_c(%(name)s_functype func_ptr) {
args_f = []
extra_args_f = []
+ ctype_args_f = []
+ extra_ctype_args_f = []
argindex = -1
for argname in block.args:
argindex += 1
@@ -160,6 +163,7 @@ static void %(init_func)s_c(%(name)s_functype func_ptr) {
self.clean_frompyobj_list.append('Py_DECREF(%s);' % (argname))
self.decl_list.append('%s* %s = NULL;' % (ti.otype, argname))
args_f.append('%s->data' % (argname)) # is_scalar
+ ctype_args_f.append(ti.ctype)
else:
if var.is_intent_in():
self.pyarg_format_list.append('O&')
@@ -170,13 +174,15 @@ static void %(init_func)s_c(%(name)s_functype func_ptr) {
assert not var.is_intent_out(),'intent(out) not implemented for "%s"' % (var)
self.decl_list.append('%s %s = {NULL,0};' % (ti.ctype, argname))
args_f.append('%s.data' % argname) # is_scalar
+ ctype_args_f.append('char*')
+ extra_ctype_args_f.append('int')
extra_args_f.append('%s.len' % argname)
self.clean_frompyobj_list.append(\
'if (%s.len) free(%s.data);' % (argname,argname))
else:
self.decl_list.append('%s %s;' % (ti.ctype, argname))
args_f.append('&'+argname) # is_scalar
-
+ ctype_args_f.append(ti.ctype+'*')
if var.is_intent_out(): # and is_scalar
if isinstance(typedecl, TypeStmt):
self.return_format_list.append('N')
@@ -188,6 +194,11 @@ static void %(init_func)s_c(%(name)s_functype func_ptr) {
self.call_list.append('%s_f(%s);' % (name,', '.join(args_f+extra_args_f)))
+ self.ctype_args_f_list = ctype_args_f + extra_ctype_args_f
+ if not self.ctype_args_f_list:
+ self.ctype_args_f_list.append('void')
+
+
self.clean_pyobjfrom_list.reverse()
self.clean_call_list.reverse()
self.clean_frompyobj_list.reverse()
diff --git a/numpy/f2py/lib/py_wrap_type.py b/numpy/f2py/lib/py_wrap_type.py
index 9211c488c..d8a48b0e1 100644
--- a/numpy/f2py/lib/py_wrap_type.py
+++ b/numpy/f2py/lib/py_wrap_type.py
@@ -390,6 +390,7 @@ typedef struct {
%(ptrstruct_list)s
%(ctype)s data;
} %(otype)s;
+typedef void (*%(init_func)s_c_functype)(%(init_func_c_ctype_arg_clist)s);
'''
typedef_template_importer = '''\
@@ -409,6 +410,7 @@ typedef PyObject* (*pyobj_from_%(ctype)s_functype)(%(ctype)s*);
extern_template_wrapper = '''\
static PyTypeObject %(otype)sType;
+extern void %(init_func)s_f(%(init_func)s_c_functype, void*, %(ctype)s);
'''
objdecl_template_wrapper = '''\
@@ -674,6 +676,7 @@ static PyObject * %(otype)s_repr(PyObject * self) {
self.init_func_f_arg_list = ['self']
self.init_func_c_arg_list = ['%s *self' % (otype)]
+ self.init_func_c_ctype_arg_list = ['%s *' % (otype)]
self.init_func_c_body_list = []
self.ptrstruct_list = []
self.attr_decl_list = []
@@ -693,6 +696,7 @@ static PyObject * %(otype)s_repr(PyObject * self) {
self.ptrstruct_list.append('%s* %s_ptr;' % (ct, n))
self.init_func_f_arg_list.append('obj %% %s' % (n))
self.init_func_c_arg_list.append('\n%s * %s_ptr' % (ct, n))
+ self.init_func_c_ctype_arg_list.append('\n%s *' % (ct))
self.init_func_c_body_list.append('''\
if (!((void*)%(n)s_ptr >= self->data
&& (void*)%(n)s_ptr < self->data + %(bytes)s ))