diff options
author | Pearu Peterson <pearu.peterson@gmail.com> | 2006-10-05 16:44:52 +0000 |
---|---|---|
committer | Pearu Peterson <pearu.peterson@gmail.com> | 2006-10-05 16:44:52 +0000 |
commit | f0bfc449991703abef349b844764dc3f3abc9fef (patch) | |
tree | 7a182c17dc42649c1c610e62ec5f8a574275e9a1 /numpy/f2py | |
parent | 73eef3a9fc78c6f047af91eb6f86b8e3b7893240 (diff) | |
download | numpy-f0bfc449991703abef349b844764dc3f3abc9fef.tar.gz |
F2PY G3: added basic support for wrapping Fortran subprograms, scalar input only.
Diffstat (limited to 'numpy/f2py')
-rw-r--r-- | numpy/f2py/lib/generate_pyobj_tofrom_funcs.py | 6 | ||||
-rw-r--r-- | numpy/f2py/lib/main.py | 6 | ||||
-rw-r--r-- | numpy/f2py/lib/py_wrap.py | 9 | ||||
-rw-r--r-- | numpy/f2py/lib/py_wrap_subprogram.py | 89 | ||||
-rw-r--r-- | numpy/f2py/lib/py_wrap_type.py | 22 | ||||
-rw-r--r-- | numpy/f2py/lib/wrapper_base.py | 3 |
6 files changed, 116 insertions, 19 deletions
diff --git a/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py b/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py index f9dedb276..4b2c574ef 100644 --- a/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py +++ b/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py @@ -12,7 +12,7 @@ def pyobj_from_npy_int(ctype): dtype = ctype.upper() cls = 'Int'+ctype[7:] return '''\ -/* depends: SCALARS_IN_BITS.cpp */ +/* depends: SCALARS_IN_BITS2.cpp */ static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { PyObject* obj = PyArrayScalar_New(%(cls)s); if (obj==NULL) /* TODO: set exception */ return NULL; @@ -25,7 +25,7 @@ def pyobj_from_npy_float(ctype): dtype = ctype.upper() cls = 'Float'+ctype[9:] return '''\ -/* depends: SCALARS_IN_BITS.cpp */ +/* depends: SCALARS_IN_BITS2.cpp */ static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { PyObject* obj = PyArrayScalar_New(%(cls)s); if (obj==NULL) /* TODO: set exception */ return NULL; @@ -38,7 +38,7 @@ def pyobj_from_npy_complex(ctype): dtype = ctype.upper() cls = 'Complex'+ctype[11:] return '''\ -/* depends: SCALARS_IN_BITS.cpp */ +/* depends: SCALARS_IN_BITS2.cpp */ static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { PyObject* obj = PyArrayScalar_New(%(cls)s); if (obj==NULL) /* TODO: set exception */ return NULL; diff --git a/numpy/f2py/lib/main.py b/numpy/f2py/lib/main.py index f38469bfe..66a4ac049 100644 --- a/numpy/f2py/lib/main.py +++ b/numpy/f2py/lib/main.py @@ -175,7 +175,7 @@ def build_extension(sys_argv): """ modulename = get_option_value(sys_argv,'-m','untitled','unspecified') - build_dir = get_option_value('--build-dir','.',None) + build_dir = get_option_value(sys_argv,'--build-dir','.',None) if build_dir is None: build_dir = tempfile.mktemp() clean_build_dir = True @@ -271,8 +271,8 @@ def build_extension(sys_argv): wrapper.add(block) c_code = wrapper.c_code() f_code = wrapper.fortran_code() - c_fn = os.path.join(temp_dir,'%smodule.c' % (modulename)) - f_fn = os.path.join(temp_dir,'%s_f_wrappers_f2py.f' % (modulename)) + c_fn = os.path.join(build_dir,'%smodule.c' % (modulename)) + f_fn = os.path.join(build_dir,'%s_f_wrappers_f2py.f' % (modulename)) f = open(c_fn,'w') f.write(c_code) f.close() diff --git a/numpy/f2py/lib/py_wrap.py b/numpy/f2py/lib/py_wrap.py index f407e13f4..695057746 100644 --- a/numpy/f2py/lib/py_wrap.py +++ b/numpy/f2py/lib/py_wrap.py @@ -55,12 +55,13 @@ PyMODINIT_FUNC init%(modulename)s(void) { ''' main_fortran_template = '''\ -! -*- f90 -*- %(fortran_code_list)s ''' def __init__(self, modulename): WrapperBase.__init__(self) self.modulename = modulename + self.cname = 'f2py_' + modulename + self.header_list = [] self.typedef_list = [] @@ -91,10 +92,8 @@ PyMODINIT_FUNC init%(modulename)s(void) { elif isinstance(block, Module): for name,declblock in block.a.type_decls.items(): self.add(declblock) - elif isinstance(block, TypeDecl): - PythonCAPIDerivedType(self, block) - elif isinstance(block, tuple(declaration_type_spec)): - PythonCAPIIntrinsicType(self, block) + elif isinstance(block, tuple([TypeDecl]+declaration_type_spec)): + PythonCAPIType(self, block) else: raise NotImplementedError,`block.__class__.__name__` return diff --git a/numpy/f2py/lib/py_wrap_subprogram.py b/numpy/f2py/lib/py_wrap_subprogram.py index 3c203c317..3044b5a6b 100644 --- a/numpy/f2py/lib/py_wrap_subprogram.py +++ b/numpy/f2py/lib/py_wrap_subprogram.py @@ -4,20 +4,101 @@ __all__ = ['PythonCAPISubProgram'] import sys from wrapper_base import * +from py_wrap_type import * class PythonCAPISubProgram(WrapperBase): """ Fortran subprogram hooks. """ + + header_template = '''\ +#define %(name)s_f F_FUNC(%(name)s, %(NAME)s) +''' + typedef_template = '' + extern_template = '''\ +extern void %(name)s_f(); +''' + objdecl_template = '''\ +static char %(cname)s__doc[] = ""; +''' + module_init_template = '' + module_method_template = '''\ +{"%(name)s", (PyCFunction)%(cname)s, METH_VARARGS | METH_KEYWORDS, %(cname)s__doc},''' + c_code_template = '' + capi_code_template = '''\ +static PyObject* %(cname)s(PyObject *capi_self, PyObject *capi_args, PyObject *capi_keywds) { + PyObject * volatile capi_buildvalue = NULL; + volatile int f2py_success = 1; + %(decl_list)s + static char *capi_kwlist[] = {%(kw_clist+optkw_clist+extrakw_clist+["NULL"])s}; + if (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds, + "%(pyarg_format_elist)s", + %(["capi_kwlist"]+pyarg_obj_clist)s)) + return NULL; + %(frompyobj_list)s + %(call_list)s + f2py_success = !PyErr_Occurred(); + if (f2py_success) { + %(pyobjfrom_list)s + capi_buildvalue = Py_BuildValue("%(return_format_elist)s" + %(return_obj_list)s); + %(clean_pyobjfrom_list)s + } + %(clean_call_list)s + %(clean_frompyobj_list)s + return capi_buildvalue; +} +''' + fortran_code_template = '' + _defined = [] def __init__(self, parent, block): WrapperBase.__init__(self) self.name = name = block.name - if name in self._defined: + self.cname = cname = '%s_%s' % (parent.cname,name) + if cname in self._defined: return - self._defined.append(name) - self.info('Generating interface for %s: %s' % (block.__class__, name)) + self._defined.append(cname) + self.info('Generating interface for %s: %s' % (block.__class__, cname)) + + + self.decl_list = [] + self.kw_list = [] + self.optkw_list = [] + self.extrakw_list = [] + self.pyarg_format_list = [] + self.pyarg_obj_list = [] + self.frompyobj_list = [] + self.call_list = [] + self.pyobjfrom_list = [] + self.return_format_list = [] + self.return_obj_list = [] + self.buildvalue_list = [] + self.clean_pyobjfrom_list = [] + self.clean_call_list = [] + self.clean_frompyobj_list = [] + + args_f = [] + for argname in block.args: + var = block.a.variables[argname] + typedecl = var.get_typedecl() + PythonCAPIType(parent, typedecl) + ctype = typedecl.get_c_type() + self.decl_list.append('%s %s;' % (ctype, argname)) + self.kw_list.append('"%s"' % (argname)) + self.pyarg_format_list.append('O&') + self.pyarg_obj_list.append('\npyobj_to_%s, &%s' % (ctype, argname)) + if 1: # is_scalar + args_f.append('&'+argname) + else: + args_f.append(argname) + WrapperCPPMacro(parent, 'F_FUNC') + self.call_list.append('%s_f(%s);' % (name,', '.join(args_f))) - raise NotImplementedError,`name,block.__class__` + self.clean_pyobjfrom_list.reverse() + self.clean_call_list.reverse() + self.clean_frompyobj_list.reverse() + if self.return_obj_list: self.return_obj_list.insert(0,'') + parent.apply_templates(self) return diff --git a/numpy/f2py/lib/py_wrap_type.py b/numpy/f2py/lib/py_wrap_type.py index 7b468924c..1eb152305 100644 --- a/numpy/f2py/lib/py_wrap_type.py +++ b/numpy/f2py/lib/py_wrap_type.py @@ -1,8 +1,22 @@ -__all__ = ['PythonCAPIIntrinsicType', 'PythonCAPIDerivedType'] +__all__ = ['PythonCAPIType'] from wrapper_base import * -from parser.api import CHAR_BIT, Module +from parser.api import CHAR_BIT, Module, declaration_type_spec, TypeDecl + +class PythonCAPIType(WrapperBase): + """ + Fortran type hooks. + """ + def __init__(self, parent, typedecl): + WrapperBase.__init__(self) + if isinstance(typedecl, tuple(declaration_type_spec)): + PythonCAPIIntrinsicType(parent, typedecl) + elif isinstance(typedecl, TypeDecl): + PythonCAPIDerivedType(parent, typedecl) + else: + raise NotImplementedError,`self.__class__,typedecl.__class__` + return class PythonCAPIIntrinsicType(WrapperBase): """ @@ -21,6 +35,7 @@ class PythonCAPIIntrinsicType(WrapperBase): if ctype.startswith('npy_'): WrapperCCode(parent, 'pyobj_from_%s' % (ctype)) + WrapperCCode(parent, 'pyobj_to_%s' % (ctype)) return if not ctype.startswith('f2py_type_'): @@ -247,6 +262,7 @@ static PyObject * %(oname)s_repr(PyObject * self) { for n in typedecl.a.component_names: v = typedecl.a.components[n] t = v.get_typedecl() + PythonCAPIType(t) ct = t.get_c_type() on = 'f2py_' + t.name parent.add(t) @@ -262,9 +278,7 @@ if (!((void*)%(n)s_ptr >= self->data self->%(n)s_ptr = %(n)s_ptr; ''' % (locals())) self.attr_format_list.append('O&') - WrapperCCode(parent, 'pyobj_to_%s' % (ct)) self.attr_init_list.append('\npyobj_to_%s, self->%s_ptr' % (ct,n)) - WrapperCCode(parent, 'pyobj_from_%s' % (ct)) self.as_tuple_format_list.append('O&') self.as_tuple_arg_list.append('\npyobj_from_%s, self->%s_ptr' % (ct, n)) self.getset_func_list.append('''\ diff --git a/numpy/f2py/lib/wrapper_base.py b/numpy/f2py/lib/wrapper_base.py index bd82512d7..cd7a3a8b0 100644 --- a/numpy/f2py/lib/wrapper_base.py +++ b/numpy/f2py/lib/wrapper_base.py @@ -87,8 +87,11 @@ class WrapperBase: elif n.endswith('_elist'): joinsymbol = '' realname = realname[:-6] + '_list' + realname_lower = realname.lower() if hasattr(self, realname): attr = getattr(self, realname) + elif hasattr(self, realname_lower): + attr = getattr(self, realname_lower).upper() elif realname.startswith('['): attr = eval(realname) else: |