summaryrefslogtreecommitdiff
path: root/numpy/f2py
diff options
context:
space:
mode:
authorPearu Peterson <pearu.peterson@gmail.com>2006-10-05 16:44:52 +0000
committerPearu Peterson <pearu.peterson@gmail.com>2006-10-05 16:44:52 +0000
commitf0bfc449991703abef349b844764dc3f3abc9fef (patch)
tree7a182c17dc42649c1c610e62ec5f8a574275e9a1 /numpy/f2py
parent73eef3a9fc78c6f047af91eb6f86b8e3b7893240 (diff)
downloadnumpy-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.py6
-rw-r--r--numpy/f2py/lib/main.py6
-rw-r--r--numpy/f2py/lib/py_wrap.py9
-rw-r--r--numpy/f2py/lib/py_wrap_subprogram.py89
-rw-r--r--numpy/f2py/lib/py_wrap_type.py22
-rw-r--r--numpy/f2py/lib/wrapper_base.py3
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: