rules.py :  » Math » Numerical-Python » numpy » numpy » f2py » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Math » Numerical Python 
Numerical Python » numpy » numpy » f2py » rules.py
#!/usr/bin/env python
"""

Rules for building C/API module with f2py2e.

Here is a skeleton of a new wrapper function (13Dec2001):

wrapper_function(args)
  declarations
  get_python_arguments, say, `a' and `b'

  get_a_from_python
  if (successful) {

    get_b_from_python
    if (successful) {

      callfortran
      if (succesful) {

        put_a_to_python
        if (succesful) {

          put_b_to_python
          if (succesful) {

            buildvalue = ...

          }

        }

      }

    }
    cleanup_b

  }
  cleanup_a

  return buildvalue
"""
"""
Copyright 1999,2000 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License.

NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
$Date: 2005/08/30 08:58:42 $
Pearu Peterson
"""

__version__ = "$Revision: 1.129 $"[10:-1]

import __version__
f2py_version = __version__.version

import pprint
import sys
import time
import types
import copy
errmess=sys.stderr.write
outmess=sys.stdout.write
show=pprint.pprint

from auxfuncs import *
import capi_maps
from capi_maps import *
import cfuncs
import common_rules
import use_rules
import f90mod_rules
import func2subr
options={}

sepdict={}
#for k in ['need_cfuncs']: sepdict[k]=','
for k in ['decl',
          'frompyobj',
          'cleanupfrompyobj',
          'topyarr','method',
          'pyobjfrom','closepyobjfrom',
          'freemem',
          'userincludes',
          'includes0','includes','typedefs','typedefs_generated',
          'cppmacros','cfuncs','callbacks',
          'latexdoc',
          'restdoc',
          'routine_defs','externroutines',
          'initf2pywraphooks',
          'commonhooks','initcommonhooks',
          'f90modhooks','initf90modhooks']:
    sepdict[k]='\n'

#################### Rules for C/API module #################

module_rules={
    'modulebody':"""\
/* File: #modulename#module.c
 * This file is auto-generated with f2py (version:#f2py_version#).
 * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition,
 * written by Pearu Peterson <pearu@cens.ioc.ee>.
 * See http://cens.ioc.ee/projects/f2py2e/
 * Generation date: """+time.asctime(time.localtime(time.time()))+"""
 * $R"""+"""evision:$
 * $D"""+"""ate:$
 * Do not edit this file directly unless you know what you are doing!!!
 */
#ifdef __cplusplus
extern \"C\" {
#endif

"""+gentitle("See f2py2e/cfuncs.py: includes")+"""
#includes#
#includes0#

"""+gentitle("See f2py2e/rules.py: mod_rules['modulebody']")+"""
static PyObject *#modulename#_error;
static PyObject *#modulename#_module;

"""+gentitle("See f2py2e/cfuncs.py: typedefs")+"""
#typedefs#

"""+gentitle("See f2py2e/cfuncs.py: typedefs_generated")+"""
#typedefs_generated#

"""+gentitle("See f2py2e/cfuncs.py: cppmacros")+"""
#cppmacros#

"""+gentitle("See f2py2e/cfuncs.py: cfuncs")+"""
#cfuncs#

"""+gentitle("See f2py2e/cfuncs.py: userincludes")+"""
#userincludes#

"""+gentitle("See f2py2e/capi_rules.py: usercode")+"""
#usercode#

/* See f2py2e/rules.py */
#externroutines#

"""+gentitle("See f2py2e/capi_rules.py: usercode1")+"""
#usercode1#

"""+gentitle("See f2py2e/cb_rules.py: buildcallback")+"""
#callbacks#

"""+gentitle("See f2py2e/rules.py: buildapi")+"""
#body#

"""+gentitle("See f2py2e/f90mod_rules.py: buildhooks")+"""
#f90modhooks#

"""+gentitle("See f2py2e/rules.py: module_rules['modulebody']")+"""

"""+gentitle("See f2py2e/common_rules.py: buildhooks")+"""
#commonhooks#

"""+gentitle("See f2py2e/rules.py")+"""

static FortranDataDef f2py_routine_defs[] = {
#routine_defs#
\t{NULL}
};

static PyMethodDef f2py_module_methods[] = {
#pymethoddef#
\t{NULL,NULL}
};

#if PY_VERSION_HEX >= 0x03000000
static struct PyModuleDef moduledef = {
\tPyModuleDef_HEAD_INIT,
\t"#modulename#",
\tNULL,
\t-1,
\tf2py_module_methods,
\tNULL,
\tNULL,
\tNULL,
\tNULL
};
#endif

#if PY_VERSION_HEX >= 0x03000000
#define RETVAL m
PyObject *PyInit_#modulename#(void) {
#else
#define RETVAL
PyMODINIT_FUNC init#modulename#(void) {
#endif
\tint i;
\tPyObject *m,*d, *s;
#if PY_VERSION_HEX >= 0x03000000
\tm = #modulename#_module = PyModule_Create(&moduledef);
#else
\tm = #modulename#_module = Py_InitModule(\"#modulename#\", f2py_module_methods);
#endif
\tPy_TYPE(&PyFortran_Type) = &PyType_Type;
\timport_array();
\tif (PyErr_Occurred())
\t\t{PyErr_SetString(PyExc_ImportError, \"can't initialize module #modulename# (failed to import numpy)\"); return RETVAL;}
\td = PyModule_GetDict(m);
\ts = PyString_FromString(\"$R"""+"""evision: $\");
\tPyDict_SetItemString(d, \"__version__\", s);
#if PY_VERSION_HEX >= 0x03000000
\ts = PyUnicode_FromString(
#else
\ts = PyString_FromString(
#endif
\t\t\"This module '#modulename#' is auto-generated with f2py (version:#f2py_version#).\\nFunctions:\\n\"\n#docs#\".\");
\tPyDict_SetItemString(d, \"__doc__\", s);
\t#modulename#_error = PyErr_NewException (\"#modulename#.error\", NULL, NULL);
\tPy_DECREF(s);
\tfor(i=0;f2py_routine_defs[i].name!=NULL;i++)
\t\tPyDict_SetItemString(d, f2py_routine_defs[i].name,PyFortranObject_NewAsAttr(&f2py_routine_defs[i]));
#initf2pywraphooks#
#initf90modhooks#
#initcommonhooks#
#interface_usercode#

#ifdef F2PY_REPORT_ATEXIT
\tif (! PyErr_Occurred())
\t\ton_exit(f2py_report_on_exit,(void*)\"#modulename#\");
#endif

\treturn RETVAL;
}
#ifdef __cplusplus
}
#endif
""",
    'separatorsfor':{'latexdoc':'\n\n',
                     'restdoc':'\n\n'},
    'latexdoc':['\\section{Module \\texttt{#texmodulename#}}\n',
                '#modnote#\n',
                '#latexdoc#'],
    'restdoc':['Module #modulename#\n'+'='*80,
               '\n#restdoc#']
    }

defmod_rules=[
    {'body':'/*eof body*/',
     'method':'/*eof method*/',
     'externroutines':'/*eof externroutines*/',
     'routine_defs':'/*eof routine_defs*/',
     'initf90modhooks':'/*eof initf90modhooks*/',
     'initf2pywraphooks':'/*eof initf2pywraphooks*/',
     'initcommonhooks':'/*eof initcommonhooks*/',
     'latexdoc':'',
     'restdoc':'',
     'modnote':{hasnote:'#note#',l_not(hasnote):''},
     }
    ]

routine_rules={
    'separatorsfor':sepdict,
    'body':"""
#begintitle#
static char doc_#apiname#[] = \"\\\nFunction signature:\\n\\\n\t#docreturn##name#(#docsignatureshort#)\\n\\\n#docstrsigns#\";
/* #declfortranroutine# */
static PyObject *#apiname#(const PyObject *capi_self,
                           PyObject *capi_args,
                           PyObject *capi_keywds,
                           #functype# (*f2py_func)(#callprotoargument#)) {
\tPyObject * volatile capi_buildvalue = NULL;
\tvolatile int f2py_success = 1;
#decl#
\tstatic char *capi_kwlist[] = {#kwlist##kwlistopt##kwlistxa#NULL};
#usercode#
#routdebugenter#
#ifdef F2PY_REPORT_ATEXIT
f2py_start_clock();
#endif
\tif (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\\
\t\t\"#argformat##keyformat##xaformat#:#pyname#\",\\
\t\tcapi_kwlist#args_capi##keys_capi##keys_xa#))\n\t\treturn NULL;
#frompyobj#
/*end of frompyobj*/
#ifdef F2PY_REPORT_ATEXIT
f2py_start_call_clock();
#endif
#callfortranroutine#
if (PyErr_Occurred())
  f2py_success = 0;
#ifdef F2PY_REPORT_ATEXIT
f2py_stop_call_clock();
#endif
/*end of callfortranroutine*/
\t\tif (f2py_success) {
#pyobjfrom#
/*end of pyobjfrom*/
\t\tCFUNCSMESS(\"Building return value.\\n\");
\t\tcapi_buildvalue = Py_BuildValue(\"#returnformat#\"#return#);
/*closepyobjfrom*/
#closepyobjfrom#
\t\t} /*if (f2py_success) after callfortranroutine*/
/*cleanupfrompyobj*/
#cleanupfrompyobj#
\tif (capi_buildvalue == NULL) {
#routdebugfailure#
\t} else {
#routdebugleave#
\t}
\tCFUNCSMESS(\"Freeing memory.\\n\");
#freemem#
#ifdef F2PY_REPORT_ATEXIT
f2py_stop_clock();
#endif
\treturn capi_buildvalue;
}
#endtitle#
""",
    'routine_defs':'#routine_def#',
    'initf2pywraphooks':'#initf2pywraphook#',
    'externroutines':'#declfortranroutine#',
    'doc':'#docreturn##name#(#docsignature#)',
    'docshort':'#docreturn##name#(#docsignatureshort#)',
    'docs':'"\t#docreturn##name#(#docsignature#)\\n"\n',
    'need':['arrayobject.h','CFUNCSMESS','MINMAX'],
    'cppmacros':{debugcapi:'#define DEBUGCFUNCS'},
    'latexdoc':['\\subsection{Wrapper function \\texttt{#texname#}}\n',
                """
\\noindent{{}\\verb@#docreturn##name#@{}}\\texttt{(#latexdocsignatureshort#)}
#routnote#

#latexdocstrsigns#
"""],
    'restdoc':['Wrapped function ``#name#``\n'+'-'*80,

               ]
    }

################## Rules for C/API function ##############

rout_rules=[
    { # Init
    'separatorsfor': {'callfortranroutine':'\n','routdebugenter':'\n','decl':'\n',
                      'routdebugleave':'\n','routdebugfailure':'\n',
                      'setjmpbuf':' || ',
                      'docstrreq':'\n','docstropt':'\n','docstrout':'\n',
                      'docstrcbs':'\n','docstrsigns':'\\n"\n"',
                      'latexdocstrsigns':'\n',
                      'latexdocstrreq':'\n','latexdocstropt':'\n',
                      'latexdocstrout':'\n','latexdocstrcbs':'\n',
                      },
    'kwlist':'','kwlistopt':'','callfortran':'','callfortranappend':'',
    'docsign':'','docsignopt':'','decl':'/*decl*/',
    'freemem':'/*freemem*/',
    'docsignshort':'','docsignoptshort':'',
    'docstrsigns':'','latexdocstrsigns':'',
    'docstrreq':'Required arguments:',
    'docstropt':'Optional arguments:',
    'docstrout':'Return objects:',
    'docstrcbs':'Call-back functions:',
    'latexdocstrreq':'\\noindent Required arguments:',
    'latexdocstropt':'\\noindent Optional arguments:',
    'latexdocstrout':'\\noindent Return objects:',
    'latexdocstrcbs':'\\noindent Call-back functions:',
    'args_capi':'','keys_capi':'','functype':'',
    'frompyobj':'/*frompyobj*/',
    'cleanupfrompyobj':['/*end of cleanupfrompyobj*/'], #this list will be reversed
    'pyobjfrom':'/*pyobjfrom*/',
    'closepyobjfrom':['/*end of closepyobjfrom*/'], #this list will be reversed
    'topyarr':'/*topyarr*/','routdebugleave':'/*routdebugleave*/',
    'routdebugenter':'/*routdebugenter*/',
    'routdebugfailure':'/*routdebugfailure*/',
    'callfortranroutine':'/*callfortranroutine*/',
    'argformat':'','keyformat':'','need_cfuncs':'',
    'docreturn':'','return':'','returnformat':'','rformat':'',
    'kwlistxa':'','keys_xa':'','xaformat':'','docsignxa':'','docsignxashort':'',
    'initf2pywraphook':'',
    'routnote':{hasnote:'--- #note#',l_not(hasnote):''},
    },{
        'apiname':'f2py_rout_#modulename#_#name#',
        'pyname':'#modulename#.#name#',
        'decl':'',
        '_check':l_not(ismoduleroutine)
    },{
        'apiname':'f2py_rout_#modulename#_#f90modulename#_#name#',
        'pyname':'#modulename#.#f90modulename#.#name#',
        'decl':'',
        '_check':ismoduleroutine
    },{ # Subroutine
    'functype':'void',
    'declfortranroutine':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
                          l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'extern void #fortranname#(#callprotoargument#);',
                          ismoduleroutine:'',
                          isdummyroutine:''
                          },
    'routine_def':{l_not(l_or(ismoduleroutine,isintent_c,isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
                   l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},',
                   l_and(l_not(ismoduleroutine),isdummyroutine):'\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
                   },
    'need':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'F_FUNC'},
    'callfortranroutine':[
        {debugcapi:["""\tfprintf(stderr,\"debug-capi:Fortran subroutine `#fortranname#(#callfortran#)\'\\n\");"""]},
        {hasexternals:"""\
\t\tif (#setjmpbuf#) {
\t\t\tf2py_success = 0;
\t\t} else {"""},
        {isthreadsafe:'\t\t\tPy_BEGIN_ALLOW_THREADS'},
        {hascallstatement:'''\t\t\t\t#callstatement#;
\t\t\t\t/*(*f2py_func)(#callfortran#);*/'''},
        {l_not(l_or(hascallstatement,isdummyroutine)):'\t\t\t\t(*f2py_func)(#callfortran#);'},
        {isthreadsafe:'\t\t\tPy_END_ALLOW_THREADS'},
        {hasexternals:"""\t\t}"""}
         ],
    '_check':issubroutine,
    },{ # Wrapped function
    'functype':'void',
    'declfortranroutine':{l_not(l_or(ismoduleroutine,isdummyroutine)):'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);',
                          isdummyroutine:'',
                          },

    'routine_def':{l_not(l_or(ismoduleroutine,isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#F_WRAPPEDFUNC#(#name_lower#,#NAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
                   isdummyroutine:'\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
                   },
    'initf2pywraphook':{l_not(l_or(ismoduleroutine,isdummyroutine)):'''
    {
      extern #ctype# #F_FUNC#(#name_lower#,#NAME#)(void);
      PyObject* o = PyDict_GetItemString(d,"#name#");
      PyObject_SetAttrString(o,"_cpointer", F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL));
#if PY_VERSION_HEX >= 0x03000000
      PyObject_SetAttrString(o,"__name__", PyUnicode_FromString("#name#"));
#else
      PyObject_SetAttrString(o,"__name__", PyString_FromString("#name#"));
#endif
    }
    '''},
    'need':{l_not(l_or(ismoduleroutine,isdummyroutine)):['F_WRAPPEDFUNC','F_FUNC']},
    'callfortranroutine':[
    {debugcapi:["""\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]},
    {hasexternals:"""\
\tif (#setjmpbuf#) {
\t\tf2py_success = 0;
\t} else {"""},
    {isthreadsafe:'\tPy_BEGIN_ALLOW_THREADS'},
    {l_not(l_or(hascallstatement,isdummyroutine)):'\t(*f2py_func)(#callfortran#);'},
    {hascallstatement:'\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'},
    {isthreadsafe:'\tPy_END_ALLOW_THREADS'},
    {hasexternals:'\t}'}
    ],
    '_check':isfunction_wrap,
    },{ # Function
    'functype':'#ctype#',
    'docreturn':{l_not(isintent_hide):'#rname#,'},
    'docstrout':'\t#pydocsignout#',
    'latexdocstrout':['\\item[]{{}\\verb@#pydocsignout#@{}}',
                      {hasresultnote:'--- #resultnote#'}],
    'callfortranroutine':[{l_and(debugcapi,isstringfunction):"""\
#ifdef USESCOMPAQFORTRAN
\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callcompaqfortran#)\\n\");
#else
\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\");
#endif
"""},
                          {l_and(debugcapi,l_not(isstringfunction)):"""\
\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\");
"""}
                          ],
    '_check':l_and(isfunction,l_not(isfunction_wrap))
    },{ # Scalar function
    'declfortranroutine':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'extern #ctype# #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
                          l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'extern #ctype# #fortranname#(#callprotoargument#);',
                          isdummyroutine:''
                          },
    'routine_def':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
                   l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},',
                   isdummyroutine:'\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
                   },
    'decl':[{iscomplexfunction_warn:'\t#ctype# #name#_return_value={0,0};',
             l_not(iscomplexfunction):'\t#ctype# #name#_return_value=0;'},
            {iscomplexfunction:'\tPyObject *#name#_return_value_capi = Py_None;'}
            ],
    'callfortranroutine':[
        {hasexternals:"""\
\tif (#setjmpbuf#) {
\t\tf2py_success = 0;
\t} else {"""},
        {isthreadsafe:'\tPy_BEGIN_ALLOW_THREADS'},
        {hascallstatement:'''\t#callstatement#;
/*\t#name#_return_value = (*f2py_func)(#callfortran#);*/
'''},
        {l_not(l_or(hascallstatement,isdummyroutine)):'\t#name#_return_value = (*f2py_func)(#callfortran#);'},
        {isthreadsafe:'\tPy_END_ALLOW_THREADS'},
        {hasexternals:'\t}'},
        {l_and(debugcapi,iscomplexfunction):'\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value.r,#name#_return_value.i);'},
        {l_and(debugcapi,l_not(iscomplexfunction)):'\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value);'}],
    'pyobjfrom':{iscomplexfunction:'\t#name#_return_value_capi = pyobj_from_#ctype#1(#name#_return_value);'},
    'need':[{l_not(isdummyroutine):'F_FUNC'},
    {iscomplexfunction:'pyobj_from_#ctype#1'},
    {islong_longfunction:'long_long'},
    {islong_doublefunction:'long_double'}],
    'returnformat':{l_not(isintent_hide):'#rformat#'},
    'return':{iscomplexfunction:',#name#_return_value_capi',
    l_not(l_or(iscomplexfunction,isintent_hide)):',#name#_return_value'},
    '_check':l_and(isfunction,l_not(isstringfunction),l_not(isfunction_wrap))
    },{ # String function # in use for --no-wrap
    'declfortranroutine':'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
    'routine_def':{l_not(l_or(ismoduleroutine,isintent_c)):
#        '\t{\"#name#\",-1,{{-1}},0,(char *)F_FUNC(#fortranname#,#FORTRANNAME#),(void *)#apiname#,doc_#apiname#},',
        '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
        l_and(l_not(ismoduleroutine),isintent_c):
#            '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(void *)#apiname#,doc_#apiname#},'
            '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},'
                   },
    'decl':['\t#ctype# #name#_return_value = NULL;',
            '\tint #name#_return_value_len = 0;'],
    'callfortran':'#name#_return_value,#name#_return_value_len,',
    'callfortranroutine':['\t#name#_return_value_len = #rlength#;',
                          '\tif ((#name#_return_value = (string)malloc(sizeof(char)*(#name#_return_value_len+1))) == NULL) {',
                          '\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");',
                          '\t\tf2py_success = 0;',
                          '\t} else {',
                          "\t\t(#name#_return_value)[#name#_return_value_len] = '\\0';",
                          '\t}',
                          '\tif (f2py_success) {',
                          {hasexternals:"""\
\t\tif (#setjmpbuf#) {
\t\t\tf2py_success = 0;
\t\t} else {"""},
                          {isthreadsafe:'\t\tPy_BEGIN_ALLOW_THREADS'},
                          """\
#ifdef USESCOMPAQFORTRAN
\t\t(*f2py_func)(#callcompaqfortran#);
#else
\t\t(*f2py_func)(#callfortran#);
#endif
""",
                          {isthreadsafe:'\t\tPy_END_ALLOW_THREADS'},
                          {hasexternals:'\t\t}'},
                          {debugcapi:'\t\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value_len,#name#_return_value);'},
                          '\t} /* if (f2py_success) after (string)malloc */',
                          ],
    'returnformat':'#rformat#',
    'return':',#name#_return_value',
    'freemem':'\tSTRINGFREE(#name#_return_value);',
    'need':['F_FUNC','#ctype#','STRINGFREE'],
    '_check':l_and(isstringfunction,l_not(isfunction_wrap)) # ???obsolete
    },
    { # Debugging
    'routdebugenter':'\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#(#docsignature#)\\n");',
    'routdebugleave':'\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: successful.\\n");',
    'routdebugfailure':'\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: failure.\\n");',
    '_check':debugcapi
    }
    ]

################ Rules for arguments ##################

typedef_need_dict = {islong_long:'long_long',
                     islong_double:'long_double',
                     islong_complex:'complex_long_double',
                     isunsigned_char:'unsigned_char',
                     isunsigned_short:'unsigned_short',
                     isunsigned:'unsigned',
                     isunsigned_long_long:'unsigned_long_long',
                     isunsigned_chararray:'unsigned_char',
                     isunsigned_shortarray:'unsigned_short',
                     isunsigned_long_longarray:'unsigned_long_long',
                     issigned_long_longarray:'long_long',
                     }

aux_rules=[
    {
    'separatorsfor':sepdict
    },
    { # Common
    'frompyobj':['\t/* Processing auxiliary variable #varname# */',
                 {debugcapi:'\tfprintf(stderr,"#vardebuginfo#\\n");'},],
    'cleanupfrompyobj':'\t/* End of cleaning variable #varname# */',
    'need':typedef_need_dict,
    },
# Scalars (not complex)
    { # Common
    'decl':'\t#ctype# #varname# = 0;',
    'need':{hasinitvalue:'math.h'},
    'frompyobj':{hasinitvalue:'\t#varname# = #init#;'},
    '_check':l_and(isscalar,l_not(iscomplex)),
    },
    {
    'return':',#varname#',
    'docstrout':'\t#pydocsignout#',
    'docreturn':'#outvarname#,',
    'returnformat':'#varrformat#',
    '_check':l_and(isscalar,l_not(iscomplex),isintent_out),
    },
# Complex scalars
    { # Common
    'decl':'\t#ctype# #varname#;',
    'frompyobj': {hasinitvalue:'\t#varname#.r = #init.r#, #varname#.i = #init.i#;'},
    '_check':iscomplex
    },
# String
    { # Common
    'decl':['\t#ctype# #varname# = NULL;',
            '\tint slen(#varname#);',
            ],
    'need':['len..'],
    '_check':isstring
    },
# Array
    { # Common
    'decl':['\t#ctype# *#varname# = NULL;',
            '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};',
            '\tconst int #varname#_Rank = #rank#;',
            ],
    'need':['len..',{hasinitvalue:'forcomb'},{hasinitvalue:'CFUNCSMESS'}],
    '_check':isarray
    },
# Scalararray
    { # Common
    '_check':l_and(isarray,l_not(iscomplexarray))
    },{ # Not hidden
    '_check':l_and(isarray,l_not(iscomplexarray),isintent_nothide)
    },
# Integer*1 array
    {'need':'#ctype#',
     '_check':isint1array,
     '_depend':''
     },
# Integer*-1 array
    {'need':'#ctype#',
     '_check':isunsigned_chararray,
     '_depend':''
     },
# Integer*-2 array
    {'need':'#ctype#',
     '_check':isunsigned_shortarray,
     '_depend':''
     },
# Integer*-8 array
    {'need':'#ctype#',
     '_check':isunsigned_long_longarray,
     '_depend':''
     },
# Complexarray
    {'need':'#ctype#',
     '_check':iscomplexarray,
     '_depend':''
     },
# Stringarray
     {
     'callfortranappend':{isarrayofstrings:'flen(#varname#),'},
     'need':'string',
     '_check':isstringarray
     }
    ]

arg_rules=[
    {
    'separatorsfor':sepdict
    },
    { # Common
    'frompyobj':['\t/* Processing variable #varname# */',
                 {debugcapi:'\tfprintf(stderr,"#vardebuginfo#\\n");'},],
    'cleanupfrompyobj':'\t/* End of cleaning variable #varname# */',
    '_depend':'',
    'need':typedef_need_dict,
    },
# Doc signatures
    {
    'docstropt':{l_and(isoptional,isintent_nothide):'\t#pydocsign#'},
    'docstrreq':{l_and(isrequired,isintent_nothide):'\t#pydocsign#'},
    'docstrout':{isintent_out:'\t#pydocsignout#'},
    'latexdocstropt':{l_and(isoptional,isintent_nothide):['\\item[]{{}\\verb@#pydocsign#@{}}',
                                                          {hasnote:'--- #note#'}]},
    'latexdocstrreq':{l_and(isrequired,isintent_nothide):['\\item[]{{}\\verb@#pydocsign#@{}}',
                                                          {hasnote:'--- #note#'}]},
    'latexdocstrout':{isintent_out:['\\item[]{{}\\verb@#pydocsignout#@{}}',
                                    {l_and(hasnote,isintent_hide):'--- #note#',
                                     l_and(hasnote,isintent_nothide):'--- See above.'}]},
    'depend':''
    },
# Required/Optional arguments
    {
    'kwlist':'"#varname#",',
    'docsign':'#varname#,',
    '_check':l_and(isintent_nothide,l_not(isoptional))
    },
    {
    'kwlistopt':'"#varname#",',
    'docsignopt':'#varname#=#showinit#,',
    'docsignoptshort':'#varname#,',
    '_check':l_and(isintent_nothide,isoptional)
    },
# Docstring/BuildValue
    {
    'docreturn':'#outvarname#,',
    'returnformat':'#varrformat#',
    '_check':isintent_out
    },
# Externals (call-back functions)
    { # Common
    'docsignxa':{isintent_nothide:'#varname#_extra_args=(),'},
    'docsignxashort':{isintent_nothide:'#varname#_extra_args,'},
    'docstropt':{isintent_nothide:'\t#varname#_extra_args := () input tuple'},
    'docstrcbs':'#cbdocstr#',
    'latexdocstrcbs':'\\item[] #cblatexdocstr#',
    'latexdocstropt':{isintent_nothide:'\\item[]{{}\\verb@#varname#_extra_args := () input tuple@{}} --- Extra arguments for call-back function {{}\\verb@#varname#@{}}.'},
    'decl':['\tPyObject *#varname#_capi = Py_None;',
            '\tPyTupleObject *#varname#_xa_capi = NULL;',
            '\tPyTupleObject *#varname#_args_capi = NULL;',
            '\tint #varname#_nofargs_capi = 0;',
            {l_not(isintent_callback):'\t#cbname#_typedef #varname#_cptr;'}
            ],
    'kwlistxa':{isintent_nothide:'"#varname#_extra_args",'},
    'argformat':{isrequired:'O'},
    'keyformat':{isoptional:'O'},
    'xaformat':{isintent_nothide:'O!'},
    'args_capi':{isrequired:',&#varname#_capi'},
    'keys_capi':{isoptional:',&#varname#_capi'},
    'keys_xa':',&PyTuple_Type,&#varname#_xa_capi',
    'setjmpbuf':'(setjmp(#cbname#_jmpbuf))',
    'callfortran':{l_not(isintent_callback):'#varname#_cptr,'},
    'need':['#cbname#','setjmp.h'],
    '_check':isexternal
    },
    {
    'frompyobj':[{l_not(isintent_callback):"""\
if(F2PyCapsule_Check(#varname#_capi)) {
  #varname#_cptr = F2PyCapsule_AsVoidPtr(#varname#_capi);
} else {
  #varname#_cptr = #cbname#;
}
"""},{isintent_callback:"""\
if (#varname#_capi==Py_None) {
  #varname#_capi = PyObject_GetAttrString(#modulename#_module,\"#varname#\");
  if (#varname#_capi) {
    if (#varname#_xa_capi==NULL) {
      if (PyObject_HasAttrString(#modulename#_module,\"#varname#_extra_args\")) {
        PyObject* capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#varname#_extra_args\");
        if (capi_tmp)
          #varname#_xa_capi = (PyTupleObject *)PySequence_Tuple(capi_tmp);
        else
          #varname#_xa_capi = (PyTupleObject *)Py_BuildValue(\"()\");
        if (#varname#_xa_capi==NULL) {
          PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#varname#_extra_args to tuple.\\n\");
          return NULL;
        }
      }
    }
  }
  if (#varname#_capi==NULL) {
    PyErr_SetString(#modulename#_error,\"Callback #varname# not defined (as an argument or module #modulename# attribute).\\n\");
    return NULL;
  }
}
"""},
##    {l_not(isintent_callback):"""\
## if (#varname#_capi==Py_None) {
## printf(\"hoi\\n\");
## }
## """},
"""\
\t#varname#_nofargs_capi = #cbname#_nofargs;
\tif (create_cb_arglist(#varname#_capi,#varname#_xa_capi,#maxnofargs#,#nofoptargs#,&#cbname#_nofargs,&#varname#_args_capi,\"failed in processing argument list for call-back #varname#.\")) {
\t\tjmp_buf #varname#_jmpbuf;""",
{debugcapi:["""\
\t\tfprintf(stderr,\"debug-capi:Assuming %d arguments; at most #maxnofargs#(-#nofoptargs#) is expected.\\n\",#cbname#_nofargs);
\t\tCFUNCSMESSPY(\"for #varname#=\",#cbname#_capi);""",
{l_not(isintent_callback):"""\t\tfprintf(stderr,\"#vardebugshowvalue# (call-back in C).\\n\",#cbname#);"""}]},
          """\
\t\tCFUNCSMESS(\"Saving jmpbuf for `#varname#`.\\n\");
\t\tSWAP(#varname#_capi,#cbname#_capi,PyObject);
\t\tSWAP(#varname#_args_capi,#cbname#_args_capi,PyTupleObject);
\t\tmemcpy(&#varname#_jmpbuf,&#cbname#_jmpbuf,sizeof(jmp_buf));""",
          ],
'cleanupfrompyobj':
"""\
\t\tCFUNCSMESS(\"Restoring jmpbuf for `#varname#`.\\n\");
\t\t#cbname#_capi = #varname#_capi;
\t\tPy_DECREF(#cbname#_args_capi);
\t\t#cbname#_args_capi = #varname#_args_capi;
\t\t#cbname#_nofargs = #varname#_nofargs_capi;
\t\tmemcpy(&#cbname#_jmpbuf,&#varname#_jmpbuf,sizeof(jmp_buf));
\t}""",
    'need':['SWAP','create_cb_arglist'],
    '_check':isexternal,
    '_depend':''
    },
# Scalars (not complex)
    { # Common
    'decl':'\t#ctype# #varname# = 0;',
    'pyobjfrom':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'},
    'callfortran':{isintent_c:'#varname#,',l_not(isintent_c):'&#varname#,'},
    'return':{isintent_out:',#varname#'},
    '_check':l_and(isscalar,l_not(iscomplex))
    },{
    'need':{hasinitvalue:'math.h'},
    '_check':l_and(isscalar,l_not(iscomplex)),
    #'_depend':''
    },{ # Not hidden
    'decl':'\tPyObject *#varname#_capi = Py_None;',
    'argformat':{isrequired:'O'},
    'keyformat':{isoptional:'O'},
    'args_capi':{isrequired:',&#varname#_capi'},
    'keys_capi':{isoptional:',&#varname#_capi'},
    'pyobjfrom':{isintent_inout:"""\
\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#);
\tif (f2py_success) {"""},
    'closepyobjfrom':{isintent_inout:"\t} /*if (f2py_success) of #varname# pyobjfrom*/"},
    'need':{isintent_inout:'try_pyarr_from_#ctype#'},
    '_check':l_and(isscalar,l_not(iscomplex),isintent_nothide)
    },{
    'frompyobj':[
# hasinitvalue...
#   if pyobj is None:
#     varname = init
#   else
#     from_pyobj(varname)
#
# isoptional and noinitvalue...
#   if pyobj is not None:
#     from_pyobj(varname)
#   else:
#     varname is uninitialized
#
# ...
#   from_pyobj(varname)
#
    {hasinitvalue:'\tif (#varname#_capi == Py_None) #varname# = #init#; else',
     '_depend':''},
    {l_and(isoptional,l_not(hasinitvalue)):'\tif (#varname#_capi != Py_None)',
     '_depend':''},
    {l_not(islogical):'''\
\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");
\tif (f2py_success) {'''},
    {islogical:'''\
\t\t#varname# = (#ctype#)PyObject_IsTrue(#varname#_capi);
\t\tf2py_success = 1;
\tif (f2py_success) {'''},
     ],
    'cleanupfrompyobj':'\t} /*if (f2py_success) of #varname#*/',
    'need':{l_not(islogical):'#ctype#_from_pyobj'},
    '_check':l_and(isscalar,l_not(iscomplex),isintent_nothide),
    '_depend':''
#    },{ # Hidden
#    '_check':l_and(isscalar,l_not(iscomplex),isintent_hide)
    },{ # Hidden
    'frompyobj':{hasinitvalue:'\t#varname# = #init#;'},
    'need':typedef_need_dict,
    '_check':l_and(isscalar,l_not(iscomplex),isintent_hide),
    '_depend':''
    },{ # Common
    'frompyobj':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'},
    '_check':l_and(isscalar,l_not(iscomplex)),
    '_depend':''
    },
# Complex scalars
    { # Common
    'decl':'\t#ctype# #varname#;',
    'callfortran':{isintent_c:'#varname#,',l_not(isintent_c):'&#varname#,'},
    'pyobjfrom':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'},
    'return':{isintent_out:',#varname#_capi'},
    '_check':iscomplex
    },{ # Not hidden
    'decl':'\tPyObject *#varname#_capi = Py_None;',
    'argformat':{isrequired:'O'},
    'keyformat':{isoptional:'O'},
    'args_capi':{isrequired:',&#varname#_capi'},
    'keys_capi':{isoptional:',&#varname#_capi'},
    'need':{isintent_inout:'try_pyarr_from_#ctype#'},
    'pyobjfrom':{isintent_inout:"""\
\t\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#);
\t\tif (f2py_success) {"""},
    'closepyobjfrom':{isintent_inout:"\t\t} /*if (f2py_success) of #varname# pyobjfrom*/"},
    '_check':l_and(iscomplex,isintent_nothide)
    },{
    'frompyobj':[{hasinitvalue:'\tif (#varname#_capi==Py_None) {#varname#.r = #init.r#, #varname#.i = #init.i#;} else'},
                 {l_and(isoptional,l_not(hasinitvalue)):'\tif (#varname#_capi != Py_None)'},
#                 '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\\n");'
                 '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");'
                 '\n\tif (f2py_success) {'],
    'cleanupfrompyobj':'\t}  /*if (f2py_success) of #varname# frompyobj*/',
    'need':['#ctype#_from_pyobj'],
    '_check':l_and(iscomplex,isintent_nothide),
    '_depend':''
    },{ # Hidden
    'decl':{isintent_out:'\tPyObject *#varname#_capi = Py_None;'},
    '_check':l_and(iscomplex,isintent_hide)
    },{
    'frompyobj': {hasinitvalue:'\t#varname#.r = #init.r#, #varname#.i = #init.i#;'},
    '_check':l_and(iscomplex,isintent_hide),
    '_depend':''
    },{ # Common
    'pyobjfrom':{isintent_out:'\t#varname#_capi = pyobj_from_#ctype#1(#varname#);'},
    'need':['pyobj_from_#ctype#1'],
    '_check':iscomplex
    },{
    'frompyobj':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'},
    '_check':iscomplex,
    '_depend':''
    },
# String
    { # Common
    'decl':['\t#ctype# #varname# = NULL;',
            '\tint slen(#varname#);',
            '\tPyObject *#varname#_capi = Py_None;'],
    'callfortran':'#varname#,',
    'callfortranappend':'slen(#varname#),',
    'pyobjfrom':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
#    'freemem':'\tSTRINGFREE(#varname#);',
    'return':{isintent_out:',#varname#'},
    'need':['len..'],#'STRINGFREE'],
    '_check':isstring
    },{ # Common
    'frompyobj':"""\
\tslen(#varname#) = #length#;
\tf2py_success = #ctype#_from_pyobj(&#varname#,&slen(#varname#),#init#,#varname#_capi,\"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\");
\tif (f2py_success) {""",
    'cleanupfrompyobj':"""\
\t\tSTRINGFREE(#varname#);
\t}  /*if (f2py_success) of #varname#*/""",
    'need':['#ctype#_from_pyobj','len..','STRINGFREE'],
    '_check':isstring,
    '_depend':''
    },{ # Not hidden
    'argformat':{isrequired:'O'},
    'keyformat':{isoptional:'O'},
    'args_capi':{isrequired:',&#varname#_capi'},
    'keys_capi':{isoptional:',&#varname#_capi'},
    'pyobjfrom':{isintent_inout:'''\
\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,#varname#);
\tif (f2py_success) {'''},
    'closepyobjfrom':{isintent_inout:'\t} /*if (f2py_success) of #varname# pyobjfrom*/'},
    'need':{isintent_inout:'try_pyarr_from_#ctype#'},
    '_check':l_and(isstring,isintent_nothide)
    },{ # Hidden
    '_check':l_and(isstring,isintent_hide)
    },{
    'frompyobj':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
    '_check':isstring,
    '_depend':''
    },
# Array
    { # Common
    'decl':['\t#ctype# *#varname# = NULL;',
            '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};',
            '\tconst int #varname#_Rank = #rank#;',
            '\tPyArrayObject *capi_#varname#_tmp = NULL;',
            '\tint capi_#varname#_intent = 0;',
            ],
    'callfortran':'#varname#,',
    'return':{isintent_out:',capi_#varname#_tmp'},
    'need':'len..',
    '_check':isarray
    },{ # intent(overwrite) array
    'decl':'\tint capi_overwrite_#varname# = 1;',
    'kwlistxa':'"overwrite_#varname#",',
    'xaformat':'i',
    'keys_xa':',&capi_overwrite_#varname#',
    'docsignxa':'overwrite_#varname#=1,',
    'docsignxashort':'overwrite_#varname#,',
    'docstropt':'\toverwrite_#varname# := 1 input int',
    '_check':l_and(isarray,isintent_overwrite),
    },{
    'frompyobj':'\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);',
    '_check':l_and(isarray,isintent_overwrite),
    '_depend':'',
    },
    { # intent(copy) array
    'decl':'\tint capi_overwrite_#varname# = 0;',
     'kwlistxa':'"overwrite_#varname#",',
     'xaformat':'i',
     'keys_xa':',&capi_overwrite_#varname#',
     'docsignxa':'overwrite_#varname#=0,',
     'docsignxashort':'overwrite_#varname#,',
     'docstropt':'\toverwrite_#varname# := 0 input int',
     '_check':l_and(isarray,isintent_copy),
     },{
     'frompyobj':'\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);',
     '_check':l_and(isarray,isintent_copy),
     '_depend':'',
    },{
    'need':[{hasinitvalue:'forcomb'},{hasinitvalue:'CFUNCSMESS'}],
    '_check':isarray,
    '_depend':''
    },{ # Not hidden
    'decl':'\tPyObject *#varname#_capi = Py_None;',
    'argformat':{isrequired:'O'},
    'keyformat':{isoptional:'O'},
    'args_capi':{isrequired:',&#varname#_capi'},
    'keys_capi':{isoptional:',&#varname#_capi'},
#     'pyobjfrom':{isintent_inout:"""\
# /* Partly because of the following hack, intent(inout) is depreciated,
#    Use intent(in,out) instead.

# \tif ((#varname#_capi != Py_None) && PyArray_Check(#varname#_capi) \\
# \t\t&& (#varname#_capi != (PyObject *)capi_#varname#_tmp)) {
# \t\tif (((PyArrayObject *)#varname#_capi)->nd != capi_#varname#_tmp->nd) {
# \t\t\tif (#varname#_capi != capi_#varname#_tmp->base)
# \t\t\t\tcopy_ND_array((PyArrayObject *)capi_#varname#_tmp->base,(PyArrayObject *)#varname#_capi);
# \t\t} else
# \t\t\tcopy_ND_array(capi_#varname#_tmp,(PyArrayObject *)#varname#_capi);
# \t}
# */
# """},
#     'need':{isintent_inout:'copy_ND_array'},
    '_check':l_and(isarray,isintent_nothide)
    },{
    'frompyobj':['\t#setdims#;',
                 '\tcapi_#varname#_intent |= #intent#;',
                 {isintent_hide:'\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,Py_None);'},
                 {isintent_nothide:'\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,#varname#_capi);'},
                 """\
\tif (capi_#varname#_tmp == NULL) {
\t\tif (!PyErr_Occurred())
\t\t\tPyErr_SetString(#modulename#_error,\"failed in converting #nth# `#varname#\' of #pyname# to C/Fortran array\" );
\t} else {
\t\t#varname# = (#ctype# *)(capi_#varname#_tmp->data);
""",
{hasinitvalue:[
    {isintent_nothide:'\tif (#varname#_capi == Py_None) {'},
    {isintent_hide:'\t{'},
    {iscomplexarray:'\t\t#ctype# capi_c;'},
    """\
\t\tint *_i,capi_i=0;
\t\tCFUNCSMESS(\"#name#: Initializing #varname#=#init#\\n\");
\t\tif (initforcomb(capi_#varname#_tmp->dimensions,capi_#varname#_tmp->nd,1)) {
\t\t\twhile ((_i = nextforcomb()))
\t\t\t\t#varname#[capi_i++] = #init#; /* fortran way */
\t\t} else {
\t\t\tif (!PyErr_Occurred())
\t\t\t\tPyErr_SetString(#modulename#_error,\"Initialization of #nth# #varname# failed (initforcomb).\");
\t\t\tf2py_success = 0;
\t\t}
\t}
\tif (f2py_success) {"""]},
                 ],
    'cleanupfrompyobj':[ # note that this list will be reversed
    '\t}  /*if (capi_#varname#_tmp == NULL) ... else of #varname#*/',
    {l_not(l_or(isintent_out,isintent_hide)):"""\
\tif((PyObject *)capi_#varname#_tmp!=#varname#_capi) {
\t\tPy_XDECREF(capi_#varname#_tmp); }"""},
    {l_and(isintent_hide,l_not(isintent_out)):"""\t\tPy_XDECREF(capi_#varname#_tmp);"""},
    {hasinitvalue:'\t}  /*if (f2py_success) of #varname# init*/'},
    ],
    '_check':isarray,
    '_depend':''
    },
#    { # Hidden
#    'freemem':{l_not(isintent_out):'\tPy_XDECREF(capi_#varname#_tmp);'},
#    '_check':l_and(isarray,isintent_hide)
#    },
# Scalararray
    { # Common
    '_check':l_and(isarray,l_not(iscomplexarray))
    },{ # Not hidden
    '_check':l_and(isarray,l_not(iscomplexarray),isintent_nothide)
    },
# Integer*1 array
    {'need':'#ctype#',
     '_check':isint1array,
     '_depend':''
     },
# Integer*-1 array
    {'need':'#ctype#',
     '_check':isunsigned_chararray,
     '_depend':''
     },
# Integer*-2 array
    {'need':'#ctype#',
     '_check':isunsigned_shortarray,
     '_depend':''
     },
# Integer*-8 array
    {'need':'#ctype#',
     '_check':isunsigned_long_longarray,
     '_depend':''
     },
# Complexarray
    {'need':'#ctype#',
     '_check':iscomplexarray,
     '_depend':''
     },
# Stringarray
     {
     'callfortranappend':{isarrayofstrings:'flen(#varname#),'},
     'need':'string',
     '_check':isstringarray
     }
    ]

################# Rules for checking ###############

check_rules=[
    {
    'frompyobj':{debugcapi:'\tfprintf(stderr,\"debug-capi:Checking `#check#\'\\n\");'},
    'need':'len..'
    },{
    'frompyobj':'\tCHECKSCALAR(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {',
    'cleanupfrompyobj':'\t} /*CHECKSCALAR(#check#)*/',
    'need':'CHECKSCALAR',
    '_check':l_and(isscalar,l_not(iscomplex)),
    '_break':''
    },{
    'frompyobj':'\tCHECKSTRING(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {',
    'cleanupfrompyobj':'\t} /*CHECKSTRING(#check#)*/',
    'need':'CHECKSTRING',
    '_check':isstring,
    '_break':''
    },{
    'need':'CHECKARRAY',
    'frompyobj':'\tCHECKARRAY(#check#,\"#check#\",\"#nth# #varname#\") {',
    'cleanupfrompyobj':'\t} /*CHECKARRAY(#check#)*/',
    '_check':isarray,
    '_break':''
    },{
    'need':'CHECKGENERIC',
    'frompyobj':'\tCHECKGENERIC(#check#,\"#check#\",\"#nth# #varname#\") {',
    'cleanupfrompyobj':'\t} /*CHECKGENERIC(#check#)*/',
    }
]

########## Applying the rules. No need to modify what follows #############

#################### Build C/API module #######################

def buildmodule(m,um):
    """
    Return
    """
    global f2py_version,options
    outmess('\tBuilding module "%s"...\n'%(m['name']))
    ret = {}
    mod_rules=defmod_rules[:]
    vrd=modsign2map(m)
    rd=dictappend({'f2py_version':f2py_version},vrd)
    funcwrappers = []
    funcwrappers2 = [] # F90 codes
    for n in m['interfaced']:
        nb=None
        for bi in m['body']:
            if not bi['block']=='interface':
                errmess('buildmodule: Expected interface block. Skipping.\n')
                continue
            for b in bi['body']:
                if b['name']==n: nb=b;break

        if not nb:
            errmess('buildmodule: Could not found the body of interfaced routine "%s". Skipping.\n'%(n))
            continue
        nb_list = [nb]
        if 'entry' in nb:
            for k,a in nb['entry'].items():
                nb1 = copy.deepcopy(nb)
                del nb1['entry']
                nb1['name'] = k
                nb1['args'] = a
                nb_list.append(nb1)
        for nb in nb_list:
            api,wrap=buildapi(nb)
            if wrap:
                if ismoduleroutine(nb):
                    funcwrappers2.append(wrap)
                else:
                    funcwrappers.append(wrap)
            ar=applyrules(api,vrd)
            rd=dictappend(rd,ar)

    # Construct COMMON block support
    cr,wrap = common_rules.buildhooks(m)
    if wrap:
        funcwrappers.append(wrap)
    ar=applyrules(cr,vrd)
    rd=dictappend(rd,ar)

    # Construct F90 module support
    mr,wrap = f90mod_rules.buildhooks(m)
    if wrap:
        funcwrappers2.append(wrap)
    ar=applyrules(mr,vrd)
    rd=dictappend(rd,ar)

    for u in um:
        ar=use_rules.buildusevars(u,m['use'][u['name']])
        rd=dictappend(rd,ar)

    needs=cfuncs.get_needs()
    code={}
    for n in needs.keys():
        code[n]=[]
        for k in needs[n]:
            c=''
            if k in cfuncs.includes0:
                c=cfuncs.includes0[k]
            elif k in cfuncs.includes:
                c=cfuncs.includes[k]
            elif k in cfuncs.userincludes:
                c=cfuncs.userincludes[k]
            elif k in cfuncs.typedefs:
                c=cfuncs.typedefs[k]
            elif k in cfuncs.typedefs_generated:
                c=cfuncs.typedefs_generated[k]
            elif k in cfuncs.cppmacros:
                c=cfuncs.cppmacros[k]
            elif k in cfuncs.cfuncs:
                c=cfuncs.cfuncs[k]
            elif k in cfuncs.callbacks:
                c=cfuncs.callbacks[k]
            elif k in cfuncs.f90modhooks:
                c=cfuncs.f90modhooks[k]
            elif k in cfuncs.commonhooks:
                c=cfuncs.commonhooks[k]
            else:
                errmess('buildmodule: unknown need %s.\n'%(`k`));continue
            code[n].append(c)
    mod_rules.append(code)
    for r in mod_rules:
        if ('_check' in r and r['_check'](m)) or ('_check' not in r):
            ar=applyrules(r,vrd,m)
            rd=dictappend(rd,ar)
    ar=applyrules(module_rules,rd)

    fn = os.path.join(options['buildpath'],vrd['modulename']+'module.c')
    ret['csrc'] = fn
    f=open(fn,'w')
    f.write(ar['modulebody'].replace('\t',2*' '))
    f.close()
    outmess('\tWrote C/API module "%s" to file "%s/%smodule.c"\n'%(m['name'],options['buildpath'],vrd['modulename']))

    if options['dorestdoc']:
        fn = os.path.join(options['buildpath'],vrd['modulename']+'module.rest')
        f=open(fn,'w')
        f.write('.. -*- rest -*-\n')
        f.write('\n'.join(ar['restdoc']))
        f.close()
        outmess('\tReST Documentation is saved to file "%s/%smodule.rest"\n'%(options['buildpath'],vrd['modulename']))
    if options['dolatexdoc']:
        fn = os.path.join(options['buildpath'],vrd['modulename']+'module.tex')
        ret['ltx'] = fn
        f=open(fn,'w')
        f.write('%% This file is auto-generated with f2py (version:%s)\n'%(f2py_version))
        if 'shortlatex' not in options:
            f.write('\\documentclass{article}\n\\usepackage{a4wide}\n\\begin{document}\n\\tableofcontents\n\n')
        f.write('\n'.join(ar['latexdoc']))
        if 'shortlatex' not in options:
            f.write('\\end{document}')
        f.close()
        outmess('\tDocumentation is saved to file "%s/%smodule.tex"\n'%(options['buildpath'],vrd['modulename']))
    if funcwrappers:
        wn = os.path.join(options['buildpath'],'%s-f2pywrappers.f'%(vrd['modulename']))
        ret['fsrc'] = wn
        f=open(wn,'w')
        f.write('C     -*- fortran -*-\n')
        f.write('C     This file is autogenerated with f2py (version:%s)\n'%(f2py_version))
        f.write('C     It contains Fortran 77 wrappers to fortran functions.\n')
        lines = []
        for l in ('\n\n'.join(funcwrappers)+'\n').split('\n'):
            if l and l[0]==' ':
                while len(l)>=66:
                    lines.append(l[:66]+'\n     &')
                    l = l[66:]
                lines.append(l+'\n')
            else: lines.append(l+'\n')
        lines = ''.join(lines).replace('\n     &\n','\n')
        f.write(lines)
        f.close()
        outmess('\tFortran 77 wrappers are saved to "%s"\n'%(wn))
    if funcwrappers2:
        wn = os.path.join(options['buildpath'],'%s-f2pywrappers2.f90'%(vrd['modulename']))
        ret['fsrc'] = wn
        f=open(wn,'w')
        f.write('!     -*- f90 -*-\n')
        f.write('!     This file is autogenerated with f2py (version:%s)\n'%(f2py_version))
        f.write('!     It contains Fortran 90 wrappers to fortran functions.\n')
        lines = []
        for l in ('\n\n'.join(funcwrappers2)+'\n').split('\n'):
            if len(l)>72 and l[0]==' ':
                lines.append(l[:72]+'&\n     &')
                l = l[72:]
                while len(l)>66:
                    lines.append(l[:66]+'&\n     &')
                    l = l[66:]
                lines.append(l+'\n')
            else: lines.append(l+'\n')
        lines = ''.join(lines).replace('\n     &\n','\n')
        f.write(lines)
        f.close()
        outmess('\tFortran 90 wrappers are saved to "%s"\n'%(wn))
    return ret

################## Build C/API function #############

stnd={1:'st',2:'nd',3:'rd',4:'th',5:'th',6:'th',7:'th',8:'th',9:'th',0:'th'}
def buildapi(rout):
    rout,wrap = func2subr.assubr(rout)
    args,depargs=getargs2(rout)
    capi_maps.depargs=depargs
    var=rout['vars']
    auxvars = [a for a in var.keys() if isintent_aux(var[a])]

    if ismoduleroutine(rout):
        outmess('\t\t\tConstructing wrapper function "%s.%s"...\n'%(rout['modulename'],rout['name']))
    else:
        outmess('\t\tConstructing wrapper function "%s"...\n'%(rout['name']))
    # Routine
    vrd=routsign2map(rout)
    rd=dictappend({},vrd)
    for r in rout_rules:
        if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
            ar=applyrules(r,vrd,rout)
            rd=dictappend(rd,ar)

    # Args
    nth,nthk=0,0
    savevrd={}
    for a in args:
        vrd=sign2map(a,var[a])
        if isintent_aux(var[a]):
            _rules = aux_rules
        else:
            _rules = arg_rules
            if not isintent_hide(var[a]):
                if not isoptional(var[a]):
                    nth=nth+1
                    vrd['nth']=`nth`+stnd[nth%10]+' argument'
                else:
                    nthk=nthk+1
                    vrd['nth']=`nthk`+stnd[nthk%10]+' keyword'
            else: vrd['nth']='hidden'
        savevrd[a]=vrd
        for r in _rules:
            if '_depend' in r:
                continue
            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
                ar=applyrules(r,vrd,var[a])
                rd=dictappend(rd,ar)
                if '_break' in r:
                    break
    for a in depargs:
        if isintent_aux(var[a]):
            _rules = aux_rules
        else:
            _rules = arg_rules
        vrd=savevrd[a]
        for r in _rules:
            if '_depend' not in r:
                continue
            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
                ar=applyrules(r,vrd,var[a])
                rd=dictappend(rd,ar)
                if '_break' in r:
                    break
        if 'check' in var[a]:
            for c in var[a]['check']:
                vrd['check']=c
                ar=applyrules(check_rules,vrd,var[a])
                rd=dictappend(rd,ar)
    if type(rd['cleanupfrompyobj']) is types.ListType:
        rd['cleanupfrompyobj'].reverse()
    if type(rd['closepyobjfrom']) is types.ListType:
        rd['closepyobjfrom'].reverse()
    rd['docsignature']=stripcomma(replace('#docsign##docsignopt##docsignxa#',
                                          {'docsign':rd['docsign'],
                                           'docsignopt':rd['docsignopt'],
                                           'docsignxa':rd['docsignxa']}))
    optargs=stripcomma(replace('#docsignopt##docsignxa#',
                               {'docsignxa':rd['docsignxashort'],
                                'docsignopt':rd['docsignoptshort']}
                               ))
    if optargs=='':
        rd['docsignatureshort']=stripcomma(replace('#docsign#',{'docsign':rd['docsign']}))
    else:
        rd['docsignatureshort']=replace('#docsign#[#docsignopt#]',
                                        {'docsign':rd['docsign'],
                                         'docsignopt':optargs,
                                         })
    rd['latexdocsignatureshort']=rd['docsignatureshort'].replace('_','\\_')
    rd['latexdocsignatureshort']=rd['latexdocsignatureshort'].replace(',',', ')
    cfs=stripcomma(replace('#callfortran##callfortranappend#',{'callfortran':rd['callfortran'],'callfortranappend':rd['callfortranappend']}))
    if len(rd['callfortranappend'])>1:
        rd['callcompaqfortran']=stripcomma(replace('#callfortran# 0,#callfortranappend#',{'callfortran':rd['callfortran'],'callfortranappend':rd['callfortranappend']}))
    else:
        rd['callcompaqfortran']=cfs
    rd['callfortran']=cfs
    if type(rd['docreturn'])==types.ListType:
        rd['docreturn']=stripcomma(replace('#docreturn#',{'docreturn':rd['docreturn']}))+' = '
    rd['docstrsigns']=[]
    rd['latexdocstrsigns']=[]
    for k in ['docstrreq','docstropt','docstrout','docstrcbs']:
        if k in rd and type(rd[k])==types.ListType:
            rd['docstrsigns']=rd['docstrsigns']+rd[k]
        k='latex'+k
        if k in rd and type(rd[k])==types.ListType:
            rd['latexdocstrsigns']=rd['latexdocstrsigns']+rd[k][0:1]+\
                                    ['\\begin{description}']+rd[k][1:]+\
                                    ['\\end{description}']

    # Workaround for Python 2.6, 2.6.1 bug: http://bugs.python.org/issue4720
    if rd['keyformat'] or rd['xaformat']:
        argformat = rd['argformat']
        if isinstance(argformat, list):
            argformat.append('|')
        else:
            assert isinstance(argformat, str),repr((argformat, type(argformat)))
            rd['argformat'] += '|'

    ar=applyrules(routine_rules,rd)
    if ismoduleroutine(rout):
        outmess('\t\t\t  %s\n'%(ar['docshort']))
    else:
        outmess('\t\t  %s\n'%(ar['docshort']))
    return ar,wrap


#################### EOF rules.py #######################
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.