summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/f2py/lib/parser/typedecl_statements.py2
-rw-r--r--numpy/f2py/lib/py_wrap_type.py120
-rw-r--r--numpy/f2py/lib/test_scalar_in_out.py150
3 files changed, 270 insertions, 2 deletions
diff --git a/numpy/f2py/lib/parser/typedecl_statements.py b/numpy/f2py/lib/parser/typedecl_statements.py
index 17b48c549..b038bbf2d 100644
--- a/numpy/f2py/lib/parser/typedecl_statements.py
+++ b/numpy/f2py/lib/parser/typedecl_statements.py
@@ -438,7 +438,7 @@ class Logical(TypeDeclarationStatement):
return ".FALSE."
def get_c_type(self):
- return 'npy_int%s' % (self.get_bit_size())
+ return 'f2py_bool%s' % (self.get_bit_size())
class Character(TypeDeclarationStatement):
match = re.compile(r'character\b',re.I).match
diff --git a/numpy/f2py/lib/py_wrap_type.py b/numpy/f2py/lib/py_wrap_type.py
index f9c426a3a..605ea5fa9 100644
--- a/numpy/f2py/lib/py_wrap_type.py
+++ b/numpy/f2py/lib/py_wrap_type.py
@@ -140,7 +140,105 @@ static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) {
return return_value;
}
'''
-
+
+ capi_code_template_logical_scalar = '''
+static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) {
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+ fprintf(stderr,"pyobj_from_%(ctype)s(value=%%"%(ICTYPE)s_FMT")\\n",*value);
+#endif
+ if (*value) {
+ PyArrayScalar_RETURN_TRUE;
+ } else {
+ PyArrayScalar_RETURN_FALSE;
+ }
+}
+static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) {
+ int return_value = 0;
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+ fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj))));
+#endif
+ if (obj==NULL) ;
+ else if (PyArray_IsScalar(obj,Bool)) {
+ *value = PyArrayScalar_VAL(obj,Bool);
+ return_value = 1;
+ } else {
+ switch (PyObject_IsTrue(obj)) {
+ case 0: *value = 0; return_value = 1; break;
+ case -1: break;
+ default: *value = 1; return_value = 1;
+ }
+ }
+ if (!return_value && !PyErr_Occurred()) {
+ PyObject* r = PyString_FromString("Failed to convert ");
+ PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj)));
+ PyString_ConcatAndDel(&r, PyString_FromString(" to C %(ctype)s"));
+ PyErr_SetObject(PyExc_TypeError,r);
+ }
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+ if (PyErr_Occurred()) {
+ if (return_value)
+ fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred());
+ else
+ fprintf(stderr,"pyobj_to_%(ctype)s: PyErr_Occurred()=%%p\\n", PyErr_Occurred());
+ } else {
+ if (return_value)
+ fprintf(stderr,"pyobj_to_%(ctype)s: value=%%"%(ICTYPE)s_FMT"\\n", *value);
+ else
+ fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred());
+ }
+#endif
+ return return_value;
+}
+'''
+ capi_code_template_string_scalar = '''
+static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) {
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+ fprintf(stderr,"pyobj_from_%(ctype)s(value->data=\'%%s\')\\n",value->data);
+#endif
+ PyArray_Descr* descr = PyArray_DescrNewFromType(NPY_STRING);
+ descr->elsize = %(bytes)s;
+ PyObject* obj = PyArray_Scalar(value->data, descr, NULL);
+ if (obj==NULL) /* TODO: set exception */ return NULL;
+ return obj;
+}
+
+static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) {
+ int return_value = 0;
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+ fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj))));
+#endif
+ if (PyString_Check(obj)) {
+ int s = PyString_GET_SIZE(obj);
+ memset(value->data, (int)\' \',%(bytes)s);
+ return_value = !! strncpy(value->data,PyString_AS_STRING(obj),%(bytes)s);
+ if (return_value && s<%(bytes)s) {
+ memset(value->data + s, (int)\' \',%(bytes)s-s);
+ }
+ } else {
+ return_value = pyobj_to_%(ctype)s(PyObject_Str(obj), value);
+ }
+ if (!return_value && !PyErr_Occurred()) {
+ PyObject* r = PyString_FromString("Failed to convert ");
+ PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj)));
+ PyString_ConcatAndDel(&r, PyString_FromString(" to C %(ctype)s"));
+ PyErr_SetObject(PyExc_TypeError,r);
+ }
+#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
+ if (PyErr_Occurred()) {
+ if (return_value)
+ fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred());
+ else
+ fprintf(stderr,"pyobj_to_%(ctype)s: PyErr_Occurred()=%%p\\n", PyErr_Occurred());
+ } else {
+ if (return_value)
+ fprintf(stderr,"pyobj_to_%(ctype)s: value->data=\'%%s\'\\n", value->data);
+ else
+ fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred());
+ }
+#endif
+ return return_value;
+}
+'''
_defined = []
def __init__(self, parent, typedecl):
WrapperBase.__init__(self)
@@ -160,8 +258,28 @@ static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) {
bits = int(ctype[11:])
self.fctype = 'npy_float%s' % (bits/2)
self.capi_code_template = self.capi_code_template_complex_scalar
+ else:
+ raise NotImplementedError,`name,ctype`
parent.apply_templates(self)
return
+ if ctype.startswith('f2py_'):
+ if ctype.startswith('f2py_bool'):
+ bits = int(ctype[9:])
+ self.ictype = 'npy_int%s' % (bits)
+ self.header_template = '#define %(ctype)s %(ictype)s'
+ self.capi_code_template = self.capi_code_template_logical_scalar
+ parent.apply_templates(self)
+ return
+ if ctype.startswith('f2py_string'):
+ self.bits = bits = int(ctype[11:])
+ self.bytes = bits/CHAR_BIT
+ self.header_template = '''
+#include <string.h>
+typedef struct { char data[%(bytes)s] } %(ctype)s;
+'''
+ self.capi_code_template = self.capi_code_template_string_scalar
+ parent.apply_templates(self)
+ return
raise NotImplementedError,`name,ctype`
class PythonCAPIDerivedType(WrapperBase):
diff --git a/numpy/f2py/lib/test_scalar_in_out.py b/numpy/f2py/lib/test_scalar_in_out.py
index 37fd5ffb9..954e3e90c 100644
--- a/numpy/f2py/lib/test_scalar_in_out.py
+++ b/numpy/f2py/lib/test_scalar_in_out.py
@@ -70,6 +70,36 @@ fortran_code = '''
!f2py intent(in,out) a
a = a + 1.0d0
end
+ subroutine foobool1(a)
+ logical*1 a
+!f2py intent(in,out) a
+ a = .not. a
+ end
+ subroutine foobool2(a)
+ logical*2 a
+!f2py intent(in,out) a
+ a = .not. a
+ end
+ subroutine foobool4(a)
+ logical*4 a
+!f2py intent(in,out) a
+ a = .not. a
+ end
+ subroutine foobool8(a)
+ logical*8 a
+!f2py intent(in,out) a
+ a = .not. a
+ end
+ subroutine foostring1(a)
+ character*1 a
+!f2py intent(in,out) a
+ a = "1"
+ end
+ subroutine foostring5(a)
+ character*5 a
+!f2py intent(in,out) a
+ a(1:2) = "12"
+ end
'''
# tester note: set rebuild=True when changing fortan_code and for SVN
@@ -369,5 +399,125 @@ class test_m(NumpyTestCase):
self.assertRaises(TypeError,lambda :func([2,1,3]))
self.assertRaises(TypeError,lambda :func({}))
+ def check_foo_bool1(self, level=1):
+ i = bool8(True)
+ e = bool8(False)
+ func = m.foobool1
+ assert isinstance(i,bool8),`type(i)`
+ r = func(i)
+ assert isinstance(r,bool8),`type(r)`
+ assert i is not r,`id(i),id(r)`
+ assert_equal(r,e)
+
+ for tv in [1,2,2.1,-1j,[0],True]:
+ r = func(tv)
+ assert isinstance(r,bool8),`type(r)`
+ assert_equal(r,e)
+
+ for fv in [0,0.0,0j,False,(),{},[]]:
+ r = func(fv)
+ assert isinstance(r,bool8),`type(r)`
+ assert_equal(r,not e)
+
+ def check_foo_bool2(self, level=1):
+ i = bool8(True)
+ e = bool8(False)
+ func = m.foobool2
+ assert isinstance(i,bool8),`type(i)`
+ r = func(i)
+ assert isinstance(r,bool8),`type(r)`
+ assert i is not r,`id(i),id(r)`
+ assert_equal(r,e)
+
+ for tv in [1,2,2.1,-1j,[0],True]:
+ r = func(tv)
+ assert isinstance(r,bool8),`type(r)`
+ assert_equal(r,e)
+
+ for fv in [0,0.0,0j,False,(),{},[]]:
+ r = func(fv)
+ assert isinstance(r,bool8),`type(r)`
+ assert_equal(r,not e)
+
+ def check_foo_bool4(self, level=1):
+ i = bool8(True)
+ e = bool8(False)
+ func = m.foobool4
+ assert isinstance(i,bool8),`type(i)`
+ r = func(i)
+ assert isinstance(r,bool8),`type(r)`
+ assert i is not r,`id(i),id(r)`
+ assert_equal(r,e)
+
+ for tv in [1,2,2.1,-1j,[0],True]:
+ r = func(tv)
+ assert isinstance(r,bool8),`type(r)`
+ assert_equal(r,e)
+
+ for fv in [0,0.0,0j,False,(),{},[]]:
+ r = func(fv)
+ assert isinstance(r,bool8),`type(r)`
+ assert_equal(r,not e)
+
+ def check_foo_bool8(self, level=1):
+ i = bool8(True)
+ e = bool8(False)
+ func = m.foobool8
+ assert isinstance(i,bool8),`type(i)`
+ r = func(i)
+ assert isinstance(r,bool8),`type(r)`
+ assert i is not r,`id(i),id(r)`
+ assert_equal(r,e)
+
+ for tv in [1,2,2.1,-1j,[0],True]:
+ r = func(tv)
+ assert isinstance(r,bool8),`type(r)`
+ assert_equal(r,e)
+
+ for fv in [0,0.0,0j,False,(),{},[]]:
+ r = func(fv)
+ assert isinstance(r,bool8),`type(r)`
+ assert_equal(r,not e)
+
+ def check_foo_string1(self, level=1):
+ i = string0('a')
+ e = string0('1')
+ func = m.foostring1
+ assert isinstance(i,string0),`type(i)`
+ r = func(i)
+ assert isinstance(r,string0),`type(r)`
+ assert i is not r,`id(i),id(r)`
+ assert_equal(r,e)
+
+ r = func('ab')
+ assert isinstance(r,string0),`type(r)`
+ assert_equal(r,e)
+
+ r = func('')
+ assert isinstance(r,string0),`type(r)`
+ assert_equal(r,e)
+
+ def check_foo_string5(self, level=1):
+ i = string0('abcde')
+ e = string0('12cde')
+ func = m.foostring5
+ assert isinstance(i,string0),`type(i)`
+ r = func(i)
+ assert isinstance(r,string0),`type(r)`
+ assert i is not r,`id(i),id(r)`
+ assert_equal(r,e)
+
+ r = func('abc')
+ assert isinstance(r,string0),`type(r)`
+ assert_equal(r,'12c ')
+
+ r = func('abcdefghi')
+ assert isinstance(r,string0),`type(r)`
+ assert_equal(r,'12cde')
+
+ r = func([1])
+ assert isinstance(r,string0),`type(r)`
+ assert_equal(r,'12] ')
+
if __name__ == "__main__":
NumpyTest().run()