diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/f2py/lib/main.py | 165 | ||||
-rw-r--r-- | numpy/f2py/lib/py_wrap.py | 2 | ||||
-rw-r--r-- | numpy/f2py/lib/py_wrap_subprogram.py | 19 | ||||
-rw-r--r-- | numpy/f2py/lib/py_wrap_type.py | 4 |
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 )) |