File:  [CENS] / python / pyGiNaC / wrappers / slice.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Apr 17 22:41:36 2001 UTC (16 years, 7 months ago) by pearu
Branches: MAIN
CVS tags: HEAD
*** empty log message ***


#include <Python.h>

/* The following functions are copied from arrayobject.c of the
   Numerical Python package http://numpy.sourceforge.net/

                                      Legal Notice

   *** Legal Notice for all LLNL-contributed files ***
   Copyright (c) 1996. The Regents of the University of California. All rights
   reserved.

   Permission to use, copy, modify, and distribute this software for any purpose
   without fee is hereby granted, provided that this entire notice is included
   in all copies of any software which is or includes a copy or modification of
   this software and in all copies of the supporting documentation for such
   software.

   This work was produced at the University of California, Lawrence Livermore
   National Laboratory under contract no. W-7405-ENG-48 between the U.S.
   Department of Energy and The Regents of the University of California for the
   operation of UC LLNL.

DISCLAIMER

   This software was prepared as an account of work sponsored by an agency of
   the United States Government. Neither the United States Government nor the
   University of California nor any of their employees, makes any warranty,
   express or implied, or assumes any liability or responsibility for the
   accuracy, completeness, or usefulness of any information, apparatus, product,
   or process disclosed, or represents that its use would not infringe
   privately-owned rights. Reference herein to any specific commercial products,
   process, or service by trade name, trademark, manufacturer, or otherwise,
   does not necessarily constitute or imply its endorsement, recommendation, or
   favoring by the United States Government or the University of California. The
   views and opinions of authors expressed herein do not necessarily state or
   reflect those of the United States Government or the University of
   California, and shall not be used for advertising or product endorsement
   purposes.
*/

#define PseudoIndex -1
#define RubberIndex -2
#define SingleIndex -3

static int slice_GetIndices(PySliceObject *r, int length, 
                            int *start, int *stop, int *step)
{
    if (r->step == Py_None) {
        *step = 1;
    } else {
        if (!PyInt_Check(r->step)) return -1;
        *step = PyInt_AsLong(r->step);
    }
    if (r->start == Py_None) {
        *start = *step < 0 ? length-1 : 0;
    } else {
        if (!PyInt_Check(r->start)) return -1;
        *start = PyInt_AsLong(r->start);
        if (*start < 0) *start += length;
    }
    if (r->stop == Py_None) {
        *stop = *step < 0 ? -1 : length;
    } else {
        if (!PyInt_Check(r->stop)) return -1;
        *stop = PyInt_AsLong(r->stop);
        if (*stop < 0) *stop += length;
    }

    if (*start > (length-1)) *start = length;
    if (*start < 0) *start = 0;
    if (*stop < -1) *stop = -1;
    else if (*stop > length) *stop = length;
    return 0;
}

static int get_slice(PyObject *op, int max, int *np, int *sp) {
    int start, stop, step;
        
    if (PySlice_Check(op)) {
        if (slice_GetIndices((PySliceObject *)op, max, 
                             &start, &stop, &step) == -1) return -1;
                
        if (step != 0) {
            if (step < 0) *np = (stop-start+1+step)/step;
            else *np = (stop-start-1+step)/step;
        } else {
            if (stop == start) {
                *np = 0; step = 1;
            }
            else return -1;
        }
        if (*np < 0) *np = 0;
        *sp = step;
        return start;
    }  
    return -1;
}

int parse_subindex(PyObject *op, int *step_size, int *n_steps, int max) {
    int i, tmp;
        
    if (op == Py_None) {
        *n_steps = PseudoIndex;
        return 0;
    }
        
    if (op == Py_Ellipsis) {
        *n_steps = RubberIndex;
        return 0;
    }
        
    if (PySlice_Check(op)) {
        if ((i = get_slice(op, max, n_steps, step_size)) >= 0) {
            return i;
        } else {
            PyErr_SetString(PyExc_IndexError, "invalid slice");
            return -1;
        }
    }
        
    if (PyInt_Check(op)) {
        *n_steps=SingleIndex;
        *step_size=0;
        tmp = PyInt_AsLong(op);
        if (tmp < 0) tmp += max;
        if (tmp >= max || tmp < 0) {
            PyErr_SetString(PyExc_IndexError, "invalid index");
            return -1;
        }
        return tmp;
    } 
    PyErr_SetString(PyExc_IndexError, 
                    "each subindex must be either a slice, an integer, Ellipsis, or NewAxis");
    return -1;
}

/* EOF copy from arrayobject.c */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>