[Numpy-svn] r3260 - trunk/numpy/f2py/lib

numpy-svn at scipy.org numpy-svn at scipy.org
Thu Oct 5 11:45:04 CDT 2006


Author: pearu
Date: 2006-10-05 11:44:52 -0500 (Thu, 05 Oct 2006)
New Revision: 3260

Modified:
   trunk/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py
   trunk/numpy/f2py/lib/main.py
   trunk/numpy/f2py/lib/py_wrap.py
   trunk/numpy/f2py/lib/py_wrap_subprogram.py
   trunk/numpy/f2py/lib/py_wrap_type.py
   trunk/numpy/f2py/lib/wrapper_base.py
Log:
F2PY G3: added basic support for wrapping Fortran subprograms, scalar input only.

Modified: trunk/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py
===================================================================
--- trunk/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py	2006-10-05 16:05:00 UTC (rev 3259)
+++ trunk/numpy/f2py/lib/generate_pyobj_tofrom_funcs.py	2006-10-05 16:44:52 UTC (rev 3260)
@@ -12,7 +12,7 @@
     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 @@
     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 @@
     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;

Modified: trunk/numpy/f2py/lib/main.py
===================================================================
--- trunk/numpy/f2py/lib/main.py	2006-10-05 16:05:00 UTC (rev 3259)
+++ trunk/numpy/f2py/lib/main.py	2006-10-05 16:44:52 UTC (rev 3260)
@@ -175,7 +175,7 @@
     """
     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 @@
                 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()

Modified: trunk/numpy/f2py/lib/py_wrap.py
===================================================================
--- trunk/numpy/f2py/lib/py_wrap.py	2006-10-05 16:05:00 UTC (rev 3259)
+++ trunk/numpy/f2py/lib/py_wrap.py	2006-10-05 16:44:52 UTC (rev 3260)
@@ -55,12 +55,13 @@
 '''
 
     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 @@
         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

Modified: trunk/numpy/f2py/lib/py_wrap_subprogram.py
===================================================================
--- trunk/numpy/f2py/lib/py_wrap_subprogram.py	2006-10-05 16:05:00 UTC (rev 3259)
+++ trunk/numpy/f2py/lib/py_wrap_subprogram.py	2006-10-05 16:44:52 UTC (rev 3260)
@@ -4,20 +4,101 @@
 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))
 
 
-        raise NotImplementedError,`name,block.__class__`
+        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)))
+
+        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

Modified: trunk/numpy/f2py/lib/py_wrap_type.py
===================================================================
--- trunk/numpy/f2py/lib/py_wrap_type.py	2006-10-05 16:05:00 UTC (rev 3259)
+++ trunk/numpy/f2py/lib/py_wrap_type.py	2006-10-05 16:44:52 UTC (rev 3260)
@@ -1,9 +1,23 @@
 
-__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):
     """
     Fortran intrinsic type hooks.
@@ -21,6 +35,7 @@
 
         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 @@
         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 @@
 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('''\

Modified: trunk/numpy/f2py/lib/wrapper_base.py
===================================================================
--- trunk/numpy/f2py/lib/wrapper_base.py	2006-10-05 16:05:00 UTC (rev 3259)
+++ trunk/numpy/f2py/lib/wrapper_base.py	2006-10-05 16:44:52 UTC (rev 3260)
@@ -87,8 +87,11 @@
                 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:



More information about the Numpy-svn mailing list