These files are a subset of the python-2.7.2.tgz distribution from python.org. Changed files from PyMod-2.7.2 have been copied into the corresponding directories of this tree, replacing the original files in the distribution. Signed-off-by: daryl.mcdaniel@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13197 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			362 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			362 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
Written by Jim Hugunin and Chris Chase.
 | 
						|
 | 
						|
This includes both the singular ellipsis object and slice objects.
 | 
						|
 | 
						|
Guido, feel free to do whatever you want in the way of copyrights
 | 
						|
for this file.
 | 
						|
*/
 | 
						|
 | 
						|
/*
 | 
						|
Py_Ellipsis encodes the '...' rubber index token. It is similar to
 | 
						|
the Py_NoneStruct in that there is no way to create other objects of
 | 
						|
this type and there is exactly one in existence.
 | 
						|
*/
 | 
						|
 | 
						|
#include "Python.h"
 | 
						|
#include "structmember.h"
 | 
						|
 | 
						|
static PyObject *
 | 
						|
ellipsis_repr(PyObject *op)
 | 
						|
{
 | 
						|
    return PyString_FromString("Ellipsis");
 | 
						|
}
 | 
						|
 | 
						|
PyTypeObject PyEllipsis_Type = {
 | 
						|
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
 | 
						|
    "ellipsis",                         /* tp_name */
 | 
						|
    0,                                  /* tp_basicsize */
 | 
						|
    0,                                  /* tp_itemsize */
 | 
						|
    0, /*never called*/                 /* tp_dealloc */
 | 
						|
    0,                                  /* tp_print */
 | 
						|
    0,                                  /* tp_getattr */
 | 
						|
    0,                                  /* tp_setattr */
 | 
						|
    0,                                  /* tp_compare */
 | 
						|
    ellipsis_repr,                      /* tp_repr */
 | 
						|
    0,                                  /* tp_as_number */
 | 
						|
    0,                                  /* tp_as_sequence */
 | 
						|
    0,                                  /* tp_as_mapping */
 | 
						|
    0,                                  /* tp_hash */
 | 
						|
    0,                                  /* tp_call */
 | 
						|
    0,                                  /* tp_str */
 | 
						|
    PyObject_GenericGetAttr,            /* tp_getattro */
 | 
						|
    0,                                  /* tp_setattro */
 | 
						|
    0,                                  /* tp_as_buffer */
 | 
						|
    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
 | 
						|
};
 | 
						|
 | 
						|
PyObject _Py_EllipsisObject = {
 | 
						|
    _PyObject_EXTRA_INIT
 | 
						|
    1, &PyEllipsis_Type
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/* Slice object implementation
 | 
						|
 | 
						|
   start, stop, and step are python objects with None indicating no
 | 
						|
   index is present.
 | 
						|
*/
 | 
						|
 | 
						|
PyObject *
 | 
						|
PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
 | 
						|
{
 | 
						|
    PySliceObject *obj = PyObject_New(PySliceObject, &PySlice_Type);
 | 
						|
 | 
						|
    if (obj == NULL)
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    if (step == NULL) step = Py_None;
 | 
						|
    Py_INCREF(step);
 | 
						|
    if (start == NULL) start = Py_None;
 | 
						|
    Py_INCREF(start);
 | 
						|
    if (stop == NULL) stop = Py_None;
 | 
						|
    Py_INCREF(stop);
 | 
						|
 | 
						|
    obj->step = step;
 | 
						|
    obj->start = start;
 | 
						|
    obj->stop = stop;
 | 
						|
 | 
						|
    return (PyObject *) obj;
 | 
						|
}
 | 
						|
 | 
						|
PyObject *
 | 
						|
_PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop)
 | 
						|
{
 | 
						|
    PyObject *start, *end, *slice;
 | 
						|
    start = PyInt_FromSsize_t(istart);
 | 
						|
    if (!start)
 | 
						|
        return NULL;
 | 
						|
    end = PyInt_FromSsize_t(istop);
 | 
						|
    if (!end) {
 | 
						|
        Py_DECREF(start);
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    slice = PySlice_New(start, end, NULL);
 | 
						|
    Py_DECREF(start);
 | 
						|
    Py_DECREF(end);
 | 
						|
    return slice;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,
 | 
						|
                   Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
 | 
						|
{
 | 
						|
    /* XXX support long ints */
 | 
						|
    if (r->step == Py_None) {
 | 
						|
        *step = 1;
 | 
						|
    } else {
 | 
						|
        if (!PyInt_Check(r->step) && !PyLong_Check(r->step)) return -1;
 | 
						|
        *step = PyInt_AsSsize_t(r->step);
 | 
						|
    }
 | 
						|
    if (r->start == Py_None) {
 | 
						|
        *start = *step < 0 ? length-1 : 0;
 | 
						|
    } else {
 | 
						|
        if (!PyInt_Check(r->start) && !PyLong_Check(r->step)) return -1;
 | 
						|
        *start = PyInt_AsSsize_t(r->start);
 | 
						|
        if (*start < 0) *start += length;
 | 
						|
    }
 | 
						|
    if (r->stop == Py_None) {
 | 
						|
        *stop = *step < 0 ? -1 : length;
 | 
						|
    } else {
 | 
						|
        if (!PyInt_Check(r->stop) && !PyLong_Check(r->step)) return -1;
 | 
						|
        *stop = PyInt_AsSsize_t(r->stop);
 | 
						|
        if (*stop < 0) *stop += length;
 | 
						|
    }
 | 
						|
    if (*stop > length) return -1;
 | 
						|
    if (*start >= length) return -1;
 | 
						|
    if (*step == 0) return -1;
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length,
 | 
						|
                     Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
 | 
						|
{
 | 
						|
    /* this is harder to get right than you might think */
 | 
						|
 | 
						|
    Py_ssize_t defstart, defstop;
 | 
						|
 | 
						|
    if (r->step == Py_None) {
 | 
						|
        *step = 1;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        if (!_PyEval_SliceIndex(r->step, step)) return -1;
 | 
						|
        if (*step == 0) {
 | 
						|
            PyErr_SetString(PyExc_ValueError,
 | 
						|
                            "slice step cannot be zero");
 | 
						|
            return -1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    defstart = *step < 0 ? length-1 : 0;
 | 
						|
    defstop = *step < 0 ? -1 : length;
 | 
						|
 | 
						|
    if (r->start == Py_None) {
 | 
						|
        *start = defstart;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        if (!_PyEval_SliceIndex(r->start, start)) return -1;
 | 
						|
        if (*start < 0) *start += length;
 | 
						|
        if (*start < 0) *start = (*step < 0) ? -1 : 0;
 | 
						|
        if (*start >= length)
 | 
						|
            *start = (*step < 0) ? length - 1 : length;
 | 
						|
    }
 | 
						|
 | 
						|
    if (r->stop == Py_None) {
 | 
						|
        *stop = defstop;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        if (!_PyEval_SliceIndex(r->stop, stop)) return -1;
 | 
						|
        if (*stop < 0) *stop += length;
 | 
						|
        if (*stop < 0) *stop = (*step < 0) ? -1 : 0;
 | 
						|
        if (*stop >= length)
 | 
						|
            *stop = (*step < 0) ? length - 1 : length;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((*step < 0 && *stop >= *start)
 | 
						|
        || (*step > 0 && *start >= *stop)) {
 | 
						|
        *slicelength = 0;
 | 
						|
    }
 | 
						|
    else if (*step < 0) {
 | 
						|
        *slicelength = (*stop-*start+1)/(*step)+1;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        *slicelength = (*stop-*start-1)/(*step)+1;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
slice_new(PyTypeObject *type, PyObject *args, PyObject *kw)
 | 
						|
{
 | 
						|
    PyObject *start, *stop, *step;
 | 
						|
 | 
						|
    start = stop = step = NULL;
 | 
						|
 | 
						|
    if (!_PyArg_NoKeywords("slice()", kw))
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    if (!PyArg_UnpackTuple(args, "slice", 1, 3, &start, &stop, &step))
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    /* This swapping of stop and start is to maintain similarity with
 | 
						|
       range(). */
 | 
						|
    if (stop == NULL) {
 | 
						|
        stop = start;
 | 
						|
        start = NULL;
 | 
						|
    }
 | 
						|
    return PySlice_New(start, stop, step);
 | 
						|
}
 | 
						|
 | 
						|
PyDoc_STRVAR(slice_doc,
 | 
						|
"slice([start,] stop[, step])\n\
 | 
						|
\n\
 | 
						|
Create a slice object.  This is used for extended slicing (e.g. a[0:10:2]).");
 | 
						|
 | 
						|
static void
 | 
						|
slice_dealloc(PySliceObject *r)
 | 
						|
{
 | 
						|
    Py_DECREF(r->step);
 | 
						|
    Py_DECREF(r->start);
 | 
						|
    Py_DECREF(r->stop);
 | 
						|
    PyObject_Del(r);
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
slice_repr(PySliceObject *r)
 | 
						|
{
 | 
						|
    PyObject *s, *comma;
 | 
						|
 | 
						|
    s = PyString_FromString("slice(");
 | 
						|
    comma = PyString_FromString(", ");
 | 
						|
    PyString_ConcatAndDel(&s, PyObject_Repr(r->start));
 | 
						|
    PyString_Concat(&s, comma);
 | 
						|
    PyString_ConcatAndDel(&s, PyObject_Repr(r->stop));
 | 
						|
    PyString_Concat(&s, comma);
 | 
						|
    PyString_ConcatAndDel(&s, PyObject_Repr(r->step));
 | 
						|
    PyString_ConcatAndDel(&s, PyString_FromString(")"));
 | 
						|
    Py_DECREF(comma);
 | 
						|
    return s;
 | 
						|
}
 | 
						|
 | 
						|
static PyMemberDef slice_members[] = {
 | 
						|
    {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY},
 | 
						|
    {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY},
 | 
						|
    {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY},
 | 
						|
    {0}
 | 
						|
};
 | 
						|
 | 
						|
static PyObject*
 | 
						|
slice_indices(PySliceObject* self, PyObject* len)
 | 
						|
{
 | 
						|
    Py_ssize_t ilen, start, stop, step, slicelength;
 | 
						|
 | 
						|
    ilen = PyNumber_AsSsize_t(len, PyExc_OverflowError);
 | 
						|
 | 
						|
    if (ilen == -1 && PyErr_Occurred()) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    if (PySlice_GetIndicesEx(self, ilen, &start, &stop,
 | 
						|
                             &step, &slicelength) < 0) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    return Py_BuildValue("(nnn)", start, stop, step);
 | 
						|
}
 | 
						|
 | 
						|
PyDoc_STRVAR(slice_indices_doc,
 | 
						|
"S.indices(len) -> (start, stop, stride)\n\
 | 
						|
\n\
 | 
						|
Assuming a sequence of length len, calculate the start and stop\n\
 | 
						|
indices, and the stride length of the extended slice described by\n\
 | 
						|
S. Out of bounds indices are clipped in a manner consistent with the\n\
 | 
						|
handling of normal slices.");
 | 
						|
 | 
						|
static PyObject *
 | 
						|
slice_reduce(PySliceObject* self)
 | 
						|
{
 | 
						|
    return Py_BuildValue("O(OOO)", Py_TYPE(self), self->start, self->stop, self->step);
 | 
						|
}
 | 
						|
 | 
						|
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
 | 
						|
 | 
						|
static PyMethodDef slice_methods[] = {
 | 
						|
    {"indices",         (PyCFunction)slice_indices,
 | 
						|
     METH_O,            slice_indices_doc},
 | 
						|
    {"__reduce__",      (PyCFunction)slice_reduce,
 | 
						|
     METH_NOARGS,       reduce_doc},
 | 
						|
    {NULL, NULL}
 | 
						|
};
 | 
						|
 | 
						|
static int
 | 
						|
slice_compare(PySliceObject *v, PySliceObject *w)
 | 
						|
{
 | 
						|
    int result = 0;
 | 
						|
 | 
						|
    if (v == w)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    if (PyObject_Cmp(v->start, w->start, &result) < 0)
 | 
						|
        return -2;
 | 
						|
    if (result != 0)
 | 
						|
        return result;
 | 
						|
    if (PyObject_Cmp(v->stop, w->stop, &result) < 0)
 | 
						|
        return -2;
 | 
						|
    if (result != 0)
 | 
						|
        return result;
 | 
						|
    if (PyObject_Cmp(v->step, w->step, &result) < 0)
 | 
						|
        return -2;
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
static long
 | 
						|
slice_hash(PySliceObject *v)
 | 
						|
{
 | 
						|
    PyErr_SetString(PyExc_TypeError, "unhashable type");
 | 
						|
    return -1L;
 | 
						|
}
 | 
						|
 | 
						|
PyTypeObject PySlice_Type = {
 | 
						|
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
 | 
						|
    "slice",                    /* Name of this type */
 | 
						|
    sizeof(PySliceObject),      /* Basic object size */
 | 
						|
    0,                          /* Item size for varobject */
 | 
						|
    (destructor)slice_dealloc,                  /* tp_dealloc */
 | 
						|
    0,                                          /* tp_print */
 | 
						|
    0,                                          /* tp_getattr */
 | 
						|
    0,                                          /* tp_setattr */
 | 
						|
    (cmpfunc)slice_compare,                     /* tp_compare */
 | 
						|
    (reprfunc)slice_repr,                       /* tp_repr */
 | 
						|
    0,                                          /* tp_as_number */
 | 
						|
    0,                                          /* tp_as_sequence */
 | 
						|
    0,                                          /* tp_as_mapping */
 | 
						|
    (hashfunc)slice_hash,                       /* tp_hash */
 | 
						|
    0,                                          /* tp_call */
 | 
						|
    0,                                          /* tp_str */
 | 
						|
    PyObject_GenericGetAttr,                    /* tp_getattro */
 | 
						|
    0,                                          /* tp_setattro */
 | 
						|
    0,                                          /* tp_as_buffer */
 | 
						|
    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
 | 
						|
    slice_doc,                                  /* tp_doc */
 | 
						|
    0,                                          /* tp_traverse */
 | 
						|
    0,                                          /* tp_clear */
 | 
						|
    0,                                          /* tp_richcompare */
 | 
						|
    0,                                          /* tp_weaklistoffset */
 | 
						|
    0,                                          /* tp_iter */
 | 
						|
    0,                                          /* tp_iternext */
 | 
						|
    slice_methods,                              /* tp_methods */
 | 
						|
    slice_members,                              /* tp_members */
 | 
						|
    0,                                          /* tp_getset */
 | 
						|
    0,                                          /* tp_base */
 | 
						|
    0,                                          /* tp_dict */
 | 
						|
    0,                                          /* tp_descr_get */
 | 
						|
    0,                                          /* tp_descr_set */
 | 
						|
    0,                                          /* tp_dictoffset */
 | 
						|
    0,                                          /* tp_init */
 | 
						|
    0,                                          /* tp_alloc */
 | 
						|
    slice_new,                                  /* tp_new */
 | 
						|
};
 |