summaryrefslogtreecommitdiff
path: root/numpy/f2py/lib/py_wrap_subprogram.py
blob: 32853512db6a709268a832b2d6c2b66720c85325 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

__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_clist)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
        self.cname = cname = '%s_%s' % (parent.cname,name)
        if cname in self._defined:
            return
        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)
            if var.is_intent_out(): # and is_scalar
                self.return_format_list.append('O&')
                self.return_obj_list.append('\npyobj_from_%s, &%s' % (ctype, 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