Ejemplo n.º 1
1
static
PyArrayObject* array_from_pyobj(const int type_num,
				int *dims,
				const int rank,
				const int intent,
				PyObject *obj) {
  /* Note about reference counting
     -----------------------------
     If the caller returns the array to Python, it must be done with
     Py_BuildValue("N",arr).
     Otherwise, if obj!=arr then the caller must call Py_DECREF(arr).
  */

/*   f2py_show_args(type_num,dims,rank,intent); */

  if (intent & F2PY_INTENT_CACHE) {
    /* Don't expect correct storage order or anything reasonable when
       returning cache array. */
    if ((intent & F2PY_INTENT_HIDE)
	|| (obj==Py_None)) {
      PyArrayObject *arr = NULL;
      CHECK_DIMS_DEFINED(rank,dims,"optional,intent(cache) must"
			 " have defined dimensions.\n");
      arr = (PyArrayObject *)PyArray_FromDims(rank,dims,type_num);
      ARR_IS_NULL(arr,"FromDims failed: optional,intent(cache)\n");
      if (intent & F2PY_INTENT_OUT)
	Py_INCREF(arr);
      return arr;
    }
    if (PyArray_Check(obj)
	&& ISCONTIGUOUS((PyArrayObject *)obj)
	&& HAS_PROPER_ELSIZE((PyArrayObject *)obj,type_num)
	) {
      if (check_and_fix_dimensions((PyArrayObject *)obj,rank,dims))
	return NULL; /*XXX: set exception */
      if (intent & F2PY_INTENT_OUT)
	Py_INCREF(obj);
      return (PyArrayObject *)obj;
    }
    ARR_IS_NULL(NULL,"intent(cache) must be contiguous array with a proper elsize.\n");
  }

  if (intent & F2PY_INTENT_HIDE) {
    PyArrayObject *arr = NULL;
    CHECK_DIMS_DEFINED(rank,dims,"intent(hide) must have defined dimensions.\n");
    arr = (PyArrayObject *)PyArray_FromDims(rank,dims,type_num);
    ARR_IS_NULL(arr,"FromDims failed: intent(hide)\n");
    if (intent & F2PY_INTENT_OUT) {
      if ((!(intent & F2PY_INTENT_C)) && (rank>1)) {
	lazy_transpose(arr);
	arr->flags &= ~NPY_CONTIGUOUS;
      }
      Py_INCREF(arr);
    }
    return arr;
  }

  if (PyArray_Check(obj)) { /* here we have always intent(in) or
			       intent(inout) */

    PyArrayObject *arr = (PyArrayObject *)obj;
    int is_cont = (intent & F2PY_INTENT_C) ?
      (ISCONTIGUOUS(arr)) : (array_has_column_major_storage(arr));

    if (check_and_fix_dimensions(arr,rank,dims))
      return NULL; /*XXX: set exception */

    if ((intent & F2PY_INTENT_COPY)
	|| (! (is_cont
	       && HAS_PROPER_ELSIZE(arr,type_num)
	       && PyArray_CanCastSafely(arr->descr->type_num,type_num)))) {
      PyArrayObject *tmp_arr = NULL;
      if (intent & F2PY_INTENT_INOUT) {
	ARR_IS_NULL(NULL,"intent(inout) array must be contiguous and"
		    " with a proper type and size.\n")
	  }
      if ((rank>1) && (! (intent & F2PY_INTENT_C)))
	lazy_transpose(arr);
      if (PyArray_CanCastSafely(arr->descr->type_num,type_num)) {
	tmp_arr = (PyArrayObject *)PyArray_CopyFromObject(obj,type_num,0,0);
	ARR_IS_NULL(arr,"CopyFromObject failed: array.\n");
      } else {
	tmp_arr = (PyArrayObject *)PyArray_FromDims(arr->nd,
						    arr->dimensions,
						    type_num);
	ARR_IS_NULL(tmp_arr,"FromDims failed: array with unsafe cast.\n");
	if (copy_ND_array(arr,tmp_arr))
	  ARR_IS_NULL(NULL,"copy_ND_array failed: array with unsafe cast.\n");
      }
      if ((rank>1) && (! (intent & F2PY_INTENT_C))) {
	lazy_transpose(arr);
	lazy_transpose(tmp_arr);
	tmp_arr->flags &= ~NPY_CONTIGUOUS;
      }
      arr = tmp_arr;
    }
    if (intent & F2PY_INTENT_OUT)
      Py_INCREF(arr);
      return arr;
  }
Ejemplo n.º 2
0
static double*
coerce_ndarray_double(PyArrayObject *in, PyArrayObject **out)
{
        int pcm_type = PyArray_TYPE(in);
        if (pcm_type==NPY_DOUBLE)
                return ((double *) PyArray_DATA(in));
        else if (PyArray_CanCastSafely(pcm_type, NPY_DOUBLE)) {
                *out = (PyArrayObject*)PyArray_Cast(in, NPY_DOUBLE);
                return ((double *) PyArray_DATA(*out));
        }
        else
                return NULL;
}