]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.10/Objects/enumobject.c
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Objects / enumobject.c
CommitLineData
53b2ba57
DM
1/* enumerate object */\r
2\r
3#include "Python.h"\r
4\r
5typedef struct {\r
6 PyObject_HEAD\r
7 Py_ssize_t en_index; /* current index of enumeration */\r
8 PyObject* en_sit; /* secondary iterator of enumeration */\r
9 PyObject* en_result; /* result tuple */\r
10 PyObject* en_longindex; /* index for sequences >= PY_SSIZE_T_MAX */\r
11} enumobject;\r
12\r
13static PyObject *\r
14enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
15{\r
16 enumobject *en;\r
17 PyObject *seq = NULL;\r
18 PyObject *start = NULL;\r
19 static char *kwlist[] = {"sequence", "start", 0};\r
20\r
21 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist,\r
22 &seq, &start))\r
23 return NULL;\r
24\r
25 en = (enumobject *)type->tp_alloc(type, 0);\r
26 if (en == NULL)\r
27 return NULL;\r
28 if (start != NULL) {\r
29 start = PyNumber_Index(start);\r
30 if (start == NULL) {\r
31 Py_DECREF(en);\r
32 return NULL;\r
33 }\r
34 assert(PyInt_Check(start) || PyLong_Check(start));\r
35 en->en_index = PyInt_AsSsize_t(start);\r
36 if (en->en_index == -1 && PyErr_Occurred()) {\r
37 PyErr_Clear();\r
38 en->en_index = PY_SSIZE_T_MAX;\r
39 en->en_longindex = start;\r
40 } else {\r
41 en->en_longindex = NULL;\r
42 Py_DECREF(start);\r
43 }\r
44 } else {\r
45 en->en_index = 0;\r
46 en->en_longindex = NULL;\r
47 }\r
48 en->en_sit = PyObject_GetIter(seq);\r
49 if (en->en_sit == NULL) {\r
50 Py_DECREF(en);\r
51 return NULL;\r
52 }\r
53 en->en_result = PyTuple_Pack(2, Py_None, Py_None);\r
54 if (en->en_result == NULL) {\r
55 Py_DECREF(en);\r
56 return NULL;\r
57 }\r
58 return (PyObject *)en;\r
59}\r
60\r
61static void\r
62enum_dealloc(enumobject *en)\r
63{\r
64 PyObject_GC_UnTrack(en);\r
65 Py_XDECREF(en->en_sit);\r
66 Py_XDECREF(en->en_result);\r
67 Py_XDECREF(en->en_longindex);\r
68 Py_TYPE(en)->tp_free(en);\r
69}\r
70\r
71static int\r
72enum_traverse(enumobject *en, visitproc visit, void *arg)\r
73{\r
74 Py_VISIT(en->en_sit);\r
75 Py_VISIT(en->en_result);\r
76 Py_VISIT(en->en_longindex);\r
77 return 0;\r
78}\r
79\r
80static PyObject *\r
81enum_next_long(enumobject *en, PyObject* next_item)\r
82{\r
83 static PyObject *one = NULL;\r
84 PyObject *result = en->en_result;\r
85 PyObject *next_index;\r
86 PyObject *stepped_up;\r
87\r
88 if (en->en_longindex == NULL) {\r
89 en->en_longindex = PyInt_FromSsize_t(PY_SSIZE_T_MAX);\r
90 if (en->en_longindex == NULL)\r
91 return NULL;\r
92 }\r
93 if (one == NULL) {\r
94 one = PyInt_FromLong(1);\r
95 if (one == NULL)\r
96 return NULL;\r
97 }\r
98 next_index = en->en_longindex;\r
99 assert(next_index != NULL);\r
100 stepped_up = PyNumber_Add(next_index, one);\r
101 if (stepped_up == NULL)\r
102 return NULL;\r
103 en->en_longindex = stepped_up;\r
104\r
105 if (result->ob_refcnt == 1) {\r
106 Py_INCREF(result);\r
107 Py_DECREF(PyTuple_GET_ITEM(result, 0));\r
108 Py_DECREF(PyTuple_GET_ITEM(result, 1));\r
109 } else {\r
110 result = PyTuple_New(2);\r
111 if (result == NULL) {\r
112 Py_DECREF(next_index);\r
113 Py_DECREF(next_item);\r
114 return NULL;\r
115 }\r
116 }\r
117 PyTuple_SET_ITEM(result, 0, next_index);\r
118 PyTuple_SET_ITEM(result, 1, next_item);\r
119 return result;\r
120}\r
121\r
122static PyObject *\r
123enum_next(enumobject *en)\r
124{\r
125 PyObject *next_index;\r
126 PyObject *next_item;\r
127 PyObject *result = en->en_result;\r
128 PyObject *it = en->en_sit;\r
129\r
130 next_item = (*Py_TYPE(it)->tp_iternext)(it);\r
131 if (next_item == NULL)\r
132 return NULL;\r
133\r
134 if (en->en_index == PY_SSIZE_T_MAX)\r
135 return enum_next_long(en, next_item);\r
136\r
137 next_index = PyInt_FromSsize_t(en->en_index);\r
138 if (next_index == NULL) {\r
139 Py_DECREF(next_item);\r
140 return NULL;\r
141 }\r
142 en->en_index++;\r
143\r
144 if (result->ob_refcnt == 1) {\r
145 Py_INCREF(result);\r
146 Py_DECREF(PyTuple_GET_ITEM(result, 0));\r
147 Py_DECREF(PyTuple_GET_ITEM(result, 1));\r
148 } else {\r
149 result = PyTuple_New(2);\r
150 if (result == NULL) {\r
151 Py_DECREF(next_index);\r
152 Py_DECREF(next_item);\r
153 return NULL;\r
154 }\r
155 }\r
156 PyTuple_SET_ITEM(result, 0, next_index);\r
157 PyTuple_SET_ITEM(result, 1, next_item);\r
158 return result;\r
159}\r
160\r
161PyDoc_STRVAR(enum_doc,\r
162"enumerate(iterable[, start]) -> iterator for index, value of iterable\n"\r
163"\n"\r
164"Return an enumerate object. iterable must be another object that supports\n"\r
165"iteration. The enumerate object yields pairs containing a count (from\n"\r
166"start, which defaults to zero) and a value yielded by the iterable argument.\n"\r
167"enumerate is useful for obtaining an indexed list:\n"\r
168" (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");\r
169\r
170PyTypeObject PyEnum_Type = {\r
171 PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
172 "enumerate", /* tp_name */\r
173 sizeof(enumobject), /* tp_basicsize */\r
174 0, /* tp_itemsize */\r
175 /* methods */\r
176 (destructor)enum_dealloc, /* tp_dealloc */\r
177 0, /* tp_print */\r
178 0, /* tp_getattr */\r
179 0, /* tp_setattr */\r
180 0, /* tp_compare */\r
181 0, /* tp_repr */\r
182 0, /* tp_as_number */\r
183 0, /* tp_as_sequence */\r
184 0, /* tp_as_mapping */\r
185 0, /* tp_hash */\r
186 0, /* tp_call */\r
187 0, /* tp_str */\r
188 PyObject_GenericGetAttr, /* tp_getattro */\r
189 0, /* tp_setattro */\r
190 0, /* tp_as_buffer */\r
191 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
192 Py_TPFLAGS_BASETYPE, /* tp_flags */\r
193 enum_doc, /* tp_doc */\r
194 (traverseproc)enum_traverse, /* tp_traverse */\r
195 0, /* tp_clear */\r
196 0, /* tp_richcompare */\r
197 0, /* tp_weaklistoffset */\r
198 PyObject_SelfIter, /* tp_iter */\r
199 (iternextfunc)enum_next, /* tp_iternext */\r
200 0, /* tp_methods */\r
201 0, /* tp_members */\r
202 0, /* tp_getset */\r
203 0, /* tp_base */\r
204 0, /* tp_dict */\r
205 0, /* tp_descr_get */\r
206 0, /* tp_descr_set */\r
207 0, /* tp_dictoffset */\r
208 0, /* tp_init */\r
209 PyType_GenericAlloc, /* tp_alloc */\r
210 enum_new, /* tp_new */\r
211 PyObject_GC_Del, /* tp_free */\r
212};\r
213\r
214/* Reversed Object ***************************************************************/\r
215\r
216typedef struct {\r
217 PyObject_HEAD\r
218 Py_ssize_t index;\r
219 PyObject* seq;\r
220} reversedobject;\r
221\r
222static PyObject *\r
223reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
224{\r
225 Py_ssize_t n;\r
226 PyObject *seq, *reversed_meth;\r
227 static PyObject *reversed_cache = NULL;\r
228 reversedobject *ro;\r
229\r
230 if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))\r
231 return NULL;\r
232\r
233 if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )\r
234 return NULL;\r
235\r
236 if (PyInstance_Check(seq)) {\r
237 reversed_meth = PyObject_GetAttrString(seq, "__reversed__");\r
238 if (reversed_meth == NULL) {\r
239 if (PyErr_ExceptionMatches(PyExc_AttributeError))\r
240 PyErr_Clear();\r
241 else\r
242 return NULL;\r
243 }\r
244 }\r
245 else {\r
246 reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__",\r
247 &reversed_cache);\r
248 if (reversed_meth == NULL && PyErr_Occurred())\r
249 return NULL;\r
250 }\r
251 if (reversed_meth != NULL) {\r
252 PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL);\r
253 Py_DECREF(reversed_meth);\r
254 return res;\r
255 }\r
256\r
257 if (!PySequence_Check(seq)) {\r
258 PyErr_SetString(PyExc_TypeError,\r
259 "argument to reversed() must be a sequence");\r
260 return NULL;\r
261 }\r
262\r
263 n = PySequence_Size(seq);\r
264 if (n == -1)\r
265 return NULL;\r
266\r
267 ro = (reversedobject *)type->tp_alloc(type, 0);\r
268 if (ro == NULL)\r
269 return NULL;\r
270\r
271 ro->index = n-1;\r
272 Py_INCREF(seq);\r
273 ro->seq = seq;\r
274 return (PyObject *)ro;\r
275}\r
276\r
277static void\r
278reversed_dealloc(reversedobject *ro)\r
279{\r
280 PyObject_GC_UnTrack(ro);\r
281 Py_XDECREF(ro->seq);\r
282 Py_TYPE(ro)->tp_free(ro);\r
283}\r
284\r
285static int\r
286reversed_traverse(reversedobject *ro, visitproc visit, void *arg)\r
287{\r
288 Py_VISIT(ro->seq);\r
289 return 0;\r
290}\r
291\r
292static PyObject *\r
293reversed_next(reversedobject *ro)\r
294{\r
295 PyObject *item;\r
296 Py_ssize_t index = ro->index;\r
297\r
298 if (index >= 0) {\r
299 item = PySequence_GetItem(ro->seq, index);\r
300 if (item != NULL) {\r
301 ro->index--;\r
302 return item;\r
303 }\r
304 if (PyErr_ExceptionMatches(PyExc_IndexError) ||\r
305 PyErr_ExceptionMatches(PyExc_StopIteration))\r
306 PyErr_Clear();\r
307 }\r
308 ro->index = -1;\r
309 Py_CLEAR(ro->seq);\r
310 return NULL;\r
311}\r
312\r
313PyDoc_STRVAR(reversed_doc,\r
314"reversed(sequence) -> reverse iterator over values of the sequence\n"\r
315"\n"\r
316"Return a reverse iterator");\r
317\r
318static PyObject *\r
319reversed_len(reversedobject *ro)\r
320{\r
321 Py_ssize_t position, seqsize;\r
322\r
323 if (ro->seq == NULL)\r
324 return PyInt_FromLong(0);\r
325 seqsize = PySequence_Size(ro->seq);\r
326 if (seqsize == -1)\r
327 return NULL;\r
328 position = ro->index + 1;\r
329 return PyInt_FromSsize_t((seqsize < position) ? 0 : position);\r
330}\r
331\r
332PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");\r
333\r
334static PyMethodDef reversediter_methods[] = {\r
335 {"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc},\r
336 {NULL, NULL} /* sentinel */\r
337};\r
338\r
339PyTypeObject PyReversed_Type = {\r
340 PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
341 "reversed", /* tp_name */\r
342 sizeof(reversedobject), /* tp_basicsize */\r
343 0, /* tp_itemsize */\r
344 /* methods */\r
345 (destructor)reversed_dealloc, /* tp_dealloc */\r
346 0, /* tp_print */\r
347 0, /* tp_getattr */\r
348 0, /* tp_setattr */\r
349 0, /* tp_compare */\r
350 0, /* tp_repr */\r
351 0, /* tp_as_number */\r
352 0, /* tp_as_sequence */\r
353 0, /* tp_as_mapping */\r
354 0, /* tp_hash */\r
355 0, /* tp_call */\r
356 0, /* tp_str */\r
357 PyObject_GenericGetAttr, /* tp_getattro */\r
358 0, /* tp_setattro */\r
359 0, /* tp_as_buffer */\r
360 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
361 Py_TPFLAGS_BASETYPE, /* tp_flags */\r
362 reversed_doc, /* tp_doc */\r
363 (traverseproc)reversed_traverse,/* tp_traverse */\r
364 0, /* tp_clear */\r
365 0, /* tp_richcompare */\r
366 0, /* tp_weaklistoffset */\r
367 PyObject_SelfIter, /* tp_iter */\r
368 (iternextfunc)reversed_next, /* tp_iternext */\r
369 reversediter_methods, /* tp_methods */\r
370 0, /* tp_members */\r
371 0, /* tp_getset */\r
372 0, /* tp_base */\r
373 0, /* tp_dict */\r
374 0, /* tp_descr_get */\r
375 0, /* tp_descr_set */\r
376 0, /* tp_dictoffset */\r
377 0, /* tp_init */\r
378 PyType_GenericAlloc, /* tp_alloc */\r
379 reversed_new, /* tp_new */\r
380 PyObject_GC_Del, /* tp_free */\r
381};\r